From ff8aba65d463b144db7c081181b5ccf6eaaf1af4 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sat, 1 Nov 2025 13:25:42 -0400 Subject: [PATCH] Fix contrib/ltree's subpath() with negative offset. 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 Reviewed-by: Tom Lane Discussion: https://postgr.es/m/CAAUGV_SvBO9gWYbaejb9nhe-mS9FkNP4QADNTdM3wdRhvLobwA@mail.gmail.com --- contrib/ltree/expected/ltree.out | 2 ++ contrib/ltree/ltree_op.c | 14 +++----------- contrib/ltree/sql/ltree.sql | 1 + 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/contrib/ltree/expected/ltree.out b/contrib/ltree/expected/ltree.out index c8eac3f6b21..d2a56628475 100644 --- a/contrib/ltree/expected/ltree.out +++ b/contrib/ltree/expected/ltree.out @@ -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 ------- diff --git a/contrib/ltree/ltree_op.c b/contrib/ltree/ltree_op.c index ce9f4caad4f..e3a84db37ff 100644 --- a/contrib/ltree/ltree_op.c +++ b/contrib/ltree/ltree_op.c @@ -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); diff --git a/contrib/ltree/sql/ltree.sql b/contrib/ltree/sql/ltree.sql index dd705d9d7ca..77e6958c62a 100644 --- a/contrib/ltree/sql/ltree.sql +++ b/contrib/ltree/sql/ltree.sql @@ -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'); -- 2.39.5