Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 70dc4c5

Browse files
committed
Fix lquery's NOT handling, and add ability to quantify non-'*' items.
The existing implementation of the ltree ~ lquery match operator is sufficiently complex and undocumented that it's hard to tell exactly what it does. But one thing it clearly gets wrong is the combination of NOT symbols (!) and '*' symbols. A pattern such as '*.!foo.*' should, by any ordinary understanding of regular expression behavior, match any ltree that has at least one label that's not "foo". As best we can tell by experimentation, what it's actually matching is any ltree in which *no* label is "foo". That's surprising, and not at all what the documentation says. Now, that's arguably a useful behavior, so if we rewrite to fix the bug we should provide some other way to get it. To do so, add the ability to attach lquery quantifiers to non-'*' items as well as '*'s. Then the pattern '!foo{,}' expresses "any ltree in which no label is foo". For backwards compatibility, the default quantifier for non-'*' items has to be "{1}", although the default for '*' items is '{,}'. I wouldn't have done it like that in a green field, but it's not totally horrible. Armed with that, rewrite checkCond() from scratch. Treating '*' and non-'*' items alike makes it simpler, not more complicated, so that the function actually gets a lot shorter than it was. Filip Rembiałkowski, Tom Lane, Nikita Glukhov, per a very ancient bug report from M. Palm Discussion: https://postgr.es/m/CAP_rww=waX2Oo6q+MbMSiZ9ktdj6eaJj0cQzNu=Ry2cCDij5fw@mail.gmail.com
1 parent e07e2a4 commit 70dc4c5

File tree

6 files changed

+262
-260
lines changed

6 files changed

+262
-260
lines changed

contrib/ltree/expected/ltree.out

Lines changed: 94 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,12 @@ SELECT '1.*.4|3|2.*{1}'::lquery;
445445
1.*.4|3|2.*{1}
446446
(1 row)
447447

448+
SELECT 'foo.bar{,}.!a*|b{1,}.c{,44}.d{3,4}'::lquery;
449+
lquery
450+
------------------------------------
451+
foo.bar{,}.!a*|b{1,}.c{,44}.d{3,4}
452+
(1 row)
453+
448454
SELECT 'qwerty%@*.tu'::lquery;
449455
lquery
450456
--------------
@@ -727,7 +733,7 @@ SELECT 'a.b.c.d.e'::ltree ~ '*.a.*.d.*';
727733
SELECT 'a.b.c.d.e'::ltree ~ '*.!d.*';
728734
?column?
729735
----------
730-
f
736+
t
731737
(1 row)
732738

733739
SELECT 'a.b.c.d.e'::ltree ~ '*.!d';
@@ -757,7 +763,7 @@ SELECT 'a.b.c.d.e'::ltree ~ '*.!e';
757763
SELECT 'a.b.c.d.e'::ltree ~ '*.!e.*';
758764
?column?
759765
----------
760-
f
766+
t
761767
(1 row)
762768

763769
SELECT 'a.b.c.d.e'::ltree ~ 'a.*.!e';
@@ -775,7 +781,7 @@ SELECT 'a.b.c.d.e'::ltree ~ 'a.*.!d';
775781
SELECT 'a.b.c.d.e'::ltree ~ 'a.*.!d.*';
776782
?column?
777783
----------
778-
f
784+
t
779785
(1 row)
780786

781787
SELECT 'a.b.c.d.e'::ltree ~ 'a.*.!f.*';
@@ -793,7 +799,7 @@ SELECT 'a.b.c.d.e'::ltree ~ '*.a.*.!f.*';
793799
SELECT 'a.b.c.d.e'::ltree ~ '*.a.*.!d.*';
794800
?column?
795801
----------
796-
f
802+
t
797803
(1 row)
798804

799805
SELECT 'a.b.c.d.e'::ltree ~ '*.a.!d.*';
@@ -817,13 +823,13 @@ SELECT 'a.b.c.d.e'::ltree ~ 'a.!d.*';
817823
SELECT 'a.b.c.d.e'::ltree ~ '*.a.*.!d.*';
818824
?column?
819825
----------
820-
f
826+
t
821827
(1 row)
822828

823829
SELECT 'a.b.c.d.e'::ltree ~ '*.!b.*';
824830
?column?
825831
----------
826-
f
832+
t
827833
(1 row)
828834

829835
SELECT 'a.b.c.d.e'::ltree ~ '*.!b.c.*';
@@ -835,7 +841,7 @@ SELECT 'a.b.c.d.e'::ltree ~ '*.!b.c.*';
835841
SELECT 'a.b.c.d.e'::ltree ~ '*.!b.*.c.*';
836842
?column?
837843
----------
838-
f
844+
t
839845
(1 row)
840846

841847
SELECT 'a.b.c.d.e'::ltree ~ '!b.*.c.*';
@@ -883,31 +889,31 @@ SELECT 'a.b.c.d.e'::ltree ~ '*{1}.!b.*.!c.*.e';
883889
SELECT 'a.b.c.d.e'::ltree ~ '*{1}.!b.*{1}.!c.*.e';
884890
?column?
885891
----------
886-
t
892+
f
887893
(1 row)
888894

889895
SELECT 'a.b.c.d.e'::ltree ~ 'a.!b.*{1}.!c.*.e';
890896
?column?
891897
----------
892-
t
898+
f
893899
(1 row)
894900

895901
SELECT 'a.b.c.d.e'::ltree ~ '!b.*{1}.!c.*.e';
896902
?column?
897903
----------
898-
t
904+
f
899905
(1 row)
900906

901907
SELECT 'a.b.c.d.e'::ltree ~ '*.!b.*{1}.!c.*.e';
902908
?column?
903909
----------
904-
t
910+
f
905911
(1 row)
906912

907913
SELECT 'a.b.c.d.e'::ltree ~ '*.!b.*.!c.*.e';
908914
?column?
909915
----------
910-
f
916+
t
911917
(1 row)
912918

913919
SELECT 'a.b.c.d.e'::ltree ~ '!b.!c.*';
@@ -937,19 +943,19 @@ SELECT 'a.b.c.d.e'::ltree ~ '*{1}.!b.*.!c.*';
937943
SELECT 'a.b.c.d.e'::ltree ~ '*{1}.!b.*{1}.!c.*';
938944
?column?
939945
----------
940-
t
946+
f
941947
(1 row)
942948

943949
SELECT 'a.b.c.d.e'::ltree ~ 'a.!b.*{1}.!c.*';
944950
?column?
945951
----------
946-
t
952+
f
947953
(1 row)
948954

949955
SELECT 'a.b.c.d.e'::ltree ~ '!b.*{1}.!c.*';
950956
?column?
951957
----------
952-
t
958+
f
953959
(1 row)
954960

955961
SELECT 'a.b.c.d.e'::ltree ~ '*.!b.*{1}.!c.*';
@@ -961,7 +967,7 @@ SELECT 'a.b.c.d.e'::ltree ~ '*.!b.*{1}.!c.*';
961967
SELECT 'a.b.c.d.e'::ltree ~ '*.!b.*.!c.*';
962968
?column?
963969
----------
964-
f
970+
t
965971
(1 row)
966972

967973
SELECT 'a.b.c.d.e'::ltree ~ 'a.*{2}.*{2}';
@@ -988,6 +994,78 @@ SELECT 'a.b.c.d.e'::ltree ~ 'a.*{5}.*';
988994
f
989995
(1 row)
990996

997+
SELECT '5.0.1.0'::ltree ~ '5.!0.!0.0';
998+
?column?
999+
----------
1000+
f
1001+
(1 row)
1002+
1003+
SELECT 'a.b'::ltree ~ '!a.!a';
1004+
?column?
1005+
----------
1006+
f
1007+
(1 row)
1008+
1009+
SELECT 'a.b.c.d.e'::ltree ~ 'a{,}';
1010+
?column?
1011+
----------
1012+
f
1013+
(1 row)
1014+
1015+
SELECT 'a.b.c.d.e'::ltree ~ 'a{1,}.*';
1016+
?column?
1017+
----------
1018+
t
1019+
(1 row)
1020+
1021+
SELECT 'a.b.c.d.e'::ltree ~ 'a{,}.!a{,}';
1022+
?column?
1023+
----------
1024+
t
1025+
(1 row)
1026+
1027+
SELECT 'a.b.c.d.a'::ltree ~ 'a{,}.!a{,}';
1028+
?column?
1029+
----------
1030+
f
1031+
(1 row)
1032+
1033+
SELECT 'a.b.c.d.a'::ltree ~ 'a{,2}.!a{1,}';
1034+
?column?
1035+
----------
1036+
f
1037+
(1 row)
1038+
1039+
SELECT 'a.b.c.d.e'::ltree ~ 'a{,2}.!a{1,}';
1040+
?column?
1041+
----------
1042+
t
1043+
(1 row)
1044+
1045+
SELECT 'a.b.c.d.e'::ltree ~ '!x{,}';
1046+
?column?
1047+
----------
1048+
t
1049+
(1 row)
1050+
1051+
SELECT 'a.b.c.d.e'::ltree ~ '!c{,}';
1052+
?column?
1053+
----------
1054+
f
1055+
(1 row)
1056+
1057+
SELECT 'a.b.c.d.e'::ltree ~ '!c{0,3}.!a{2,}';
1058+
?column?
1059+
----------
1060+
t
1061+
(1 row)
1062+
1063+
SELECT 'a.b.c.d.e'::ltree ~ '!c{0,3}.!d{2,}.*';
1064+
?column?
1065+
----------
1066+
t
1067+
(1 row)
1068+
9911069
SELECT 'QWER_TY'::ltree ~ 'q%@*';
9921070
?column?
9931071
----------

0 commit comments

Comments
 (0)