]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Fix contrib/ltree's subpath() with negative offset.
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 1 Nov 2025 17:25:42 +0000 (13:25 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 1 Nov 2025 17:25:42 +0000 (13:25 -0400)
subpath(ltree,offset,len) now correctly errors when given an offset
less than -n, where n is the number of labels in the given ltree.
There was a duplicate block of code that allowed an offset as low
as -2n.  The documentation says no such thing, so this must have
been a copy-and-paste error in the original ltree patch.

While here, avoid redundant calculation of "end" and write
LTREE_MAX_LEVELS rather than its hard-coded value.

Author: Marcus Gartner <m.a.gartner@gmail.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CAAUGV_SvBO9gWYbaejb9nhe-mS9FkNP4QADNTdM3wdRhvLobwA@mail.gmail.com

contrib/ltree/expected/ltree.out
contrib/ltree/ltree_op.c
contrib/ltree/sql/ltree.sql

index c8eac3f6b21bcaddeb801cb0821cf235b0e40ae4..d2a566284755b46aa7d6c597549f3fa4bcf738f1 100644 (file)
@@ -128,6 +128,8 @@ SELECT subpath('Top.Child1.Child2',1);
  Child1.Child2
 (1 row)
 
+SELECT subpath('Top.Child1.Child2',-4);  -- error
+ERROR:  invalid positions
 SELECT index('1.2.3.4.5.6','1.2');
  index 
 -------
index ce9f4caad4feb145313f55561dd90382b5575753..e3a84db37ff8280841a6ba5dde474c45e32b14c6 100644 (file)
@@ -316,23 +316,15 @@ subpath(PG_FUNCTION_ARGS)
        int32           end;
        ltree      *res;
 
-       end = start + len;
-
-       if (start < 0)
-       {
-               start = t->numlevel + start;
-               end = start + len;
-       }
        if (start < 0)
-       {                                                       /* start > t->numlevel */
                start = t->numlevel + start;
-               end = start + len;
-       }
 
        if (len < 0)
                end = t->numlevel + len;
        else if (len == 0)
-               end = (fcinfo->nargs == 3) ? start : 0xffff;
+               end = (fcinfo->nargs == 3) ? start : LTREE_MAX_LEVELS;
+       else
+               end = start + len;
 
        res = inner_subltree(t, start, end);
 
index dd705d9d7ca00136dd6b291c1204e41e2c3e2264..77e6958c62a7bdd25b81511005d3c558e3877478 100644 (file)
@@ -34,6 +34,7 @@ SELECT subpath('Top.Child1.Child2',0,0);
 SELECT subpath('Top.Child1.Child2',1,0);
 SELECT subpath('Top.Child1.Child2',0);
 SELECT subpath('Top.Child1.Child2',1);
+SELECT subpath('Top.Child1.Child2',-4);  -- error
 
 
 SELECT index('1.2.3.4.5.6','1.2');