Commit 17ca0679 authored by Tom Lane's avatar Tom Lane

Clean up parsing of ltree and lquery some more.

Fix lquery parsing to handle repeated flag characters correctly,
and to enforce the max label length correctly in some cases where
it did not before, and to detect empty labels in some cases where
it did not before.

In a more cosmetic vein, use a switch rather than if-then chains to
handle the different states, and avoid unnecessary checks on charlen
when looking for ASCII characters, and factor out multiple copies of
the label length checking code.

Tom Lane and Dmitry Belyavsky

Discussion: https://postgr.es/m/CADqLbzLVkBuPX0812o+z=c3i6honszsZZ6VQOSKR3VPbB56P3w@mail.gmail.com
parent 949a9f04
......@@ -31,6 +31,29 @@ SELECT '1.2._3'::ltree;
1.2._3
(1 row)
-- empty labels not allowed
SELECT '.2.3'::ltree;
ERROR: ltree syntax error at character 1
LINE 1: SELECT '.2.3'::ltree;
^
SELECT '1..3'::ltree;
ERROR: ltree syntax error at character 3
LINE 1: SELECT '1..3'::ltree;
^
SELECT '1.2.'::ltree;
ERROR: ltree syntax error
LINE 1: SELECT '1.2.'::ltree;
^
DETAIL: Unexpected end of input.
SELECT repeat('x', 255)::ltree;
repeat
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
(1 row)
SELECT repeat('x', 256)::ltree;
ERROR: label string is too long
DETAIL: Label length is 256, must be at most 255, at character 257.
SELECT ltree2text('1.2.3.34.sdf');
ltree2text
--------------
......@@ -451,12 +474,81 @@ SELECT 'foo.bar{,}.!a*|b{1,}.c{,44}.d{3,4}'::lquery;
foo.bar{,}.!a*|b{1,}.c{,44}.d{3,4}
(1 row)
SELECT 'foo*@@*'::lquery;
lquery
--------
foo@*
(1 row)
SELECT 'qwerty%@*.tu'::lquery;
lquery
--------------
qwerty%@*.tu
(1 row)
-- empty labels not allowed
SELECT '.2.3'::lquery;
ERROR: lquery syntax error at character 1
LINE 1: SELECT '.2.3'::lquery;
^
SELECT '1..3'::lquery;
ERROR: lquery syntax error at character 3
LINE 1: SELECT '1..3'::lquery;
^
SELECT '1.2.'::lquery;
ERROR: lquery syntax error
LINE 1: SELECT '1.2.'::lquery;
^
DETAIL: Unexpected end of input.
SELECT '@.2.3'::lquery;
ERROR: lquery syntax error at character 1
LINE 1: SELECT '@.2.3'::lquery;
^
SELECT '1.@.3'::lquery;
ERROR: lquery syntax error at character 3
LINE 1: SELECT '1.@.3'::lquery;
^
SELECT '1.2.@'::lquery;
ERROR: lquery syntax error at character 5
LINE 1: SELECT '1.2.@'::lquery;
^
SELECT '!.2.3'::lquery;
ERROR: lquery syntax error at character 2
LINE 1: SELECT '!.2.3'::lquery;
^
DETAIL: Empty labels are not allowed.
SELECT '1.!.3'::lquery;
ERROR: lquery syntax error at character 4
LINE 1: SELECT '1.!.3'::lquery;
^
DETAIL: Empty labels are not allowed.
SELECT '1.2.!'::lquery;
ERROR: lquery syntax error at character 6
LINE 1: SELECT '1.2.!'::lquery;
^
DETAIL: Empty labels are not allowed.
SELECT '1.2.3|@.4'::lquery;
ERROR: lquery syntax error at character 7
LINE 1: SELECT '1.2.3|@.4'::lquery;
^
SELECT (repeat('x', 255) || '*@@*')::lquery;
lquery
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx@*
(1 row)
SELECT (repeat('x', 256) || '*@@*')::lquery;
ERROR: label string is too long
DETAIL: Label length is 256, must be at most 255, at character 257.
SELECT ('!' || repeat('x', 255))::lquery;
lquery
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
!xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
(1 row)
SELECT ('!' || repeat('x', 256))::lquery;
ERROR: label string is too long
DETAIL: Label length is 256, must be at most 255, at character 258.
SELECT nlevel('1.2.3.4');
nlevel
--------
......@@ -1072,6 +1164,12 @@ SELECT 'QWER_TY'::ltree ~ 'q%@*';
t
(1 row)
SELECT 'QWER_TY'::ltree ~ 'q%@*%@*';
?column?
----------
t
(1 row)
SELECT 'QWER_TY'::ltree ~ 'Q_t%@*';
?column?
----------
......
This diff is collapsed.
......@@ -10,6 +10,14 @@ SELECT '1'::ltree;
SELECT '1.2'::ltree;
SELECT '1.2._3'::ltree;
-- empty labels not allowed
SELECT '.2.3'::ltree;
SELECT '1..3'::ltree;
SELECT '1.2.'::ltree;
SELECT repeat('x', 255)::ltree;
SELECT repeat('x', 256)::ltree;
SELECT ltree2text('1.2.3.34.sdf');
SELECT text2ltree('1.2.3.34.sdf');
......@@ -88,8 +96,26 @@ SELECT '1.*.4|3|2.*{,4}'::lquery;
SELECT '1.*.4|3|2.*{1,}'::lquery;
SELECT '1.*.4|3|2.*{1}'::lquery;
SELECT 'foo.bar{,}.!a*|b{1,}.c{,44}.d{3,4}'::lquery;
SELECT 'foo*@@*'::lquery;
SELECT 'qwerty%@*.tu'::lquery;
-- empty labels not allowed
SELECT '.2.3'::lquery;
SELECT '1..3'::lquery;
SELECT '1.2.'::lquery;
SELECT '@.2.3'::lquery;
SELECT '1.@.3'::lquery;
SELECT '1.2.@'::lquery;
SELECT '!.2.3'::lquery;
SELECT '1.!.3'::lquery;
SELECT '1.2.!'::lquery;
SELECT '1.2.3|@.4'::lquery;
SELECT (repeat('x', 255) || '*@@*')::lquery;
SELECT (repeat('x', 256) || '*@@*')::lquery;
SELECT ('!' || repeat('x', 255))::lquery;
SELECT ('!' || repeat('x', 256))::lquery;
SELECT nlevel('1.2.3.4');
SELECT nlevel(('1' || repeat('.1', 65534))::ltree);
SELECT nlevel(('1' || repeat('.1', 65535))::ltree);
......@@ -200,6 +226,7 @@ SELECT 'a.b.c.d.e'::ltree ~ '!c{0,3}.!a{2,}';
SELECT 'a.b.c.d.e'::ltree ~ '!c{0,3}.!d{2,}.*';
SELECT 'QWER_TY'::ltree ~ 'q%@*';
SELECT 'QWER_TY'::ltree ~ 'q%@*%@*';
SELECT 'QWER_TY'::ltree ~ 'Q_t%@*';
SELECT 'QWER_GY'::ltree ~ 'q_t%@*';
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment