Skip to content

Commit 6661030

Browse files
author
Richard Guo
committed
Fix Assert failure in XMLTABLE parser
In an XMLTABLE expression, columns can be marked NOT NULL, and the parser internally fabricates an option named "is_not_null" to represent this. However, the parser also allows users to specify arbitrary option names. This creates a conflict: a user can explicitly use "is_not_null" as an option name and assign it a non-Boolean value, which violates internal assumptions and triggers an assertion failure. To fix, this patch checks whether a user-supplied name collides with the internally reserved option name and raises an error if so. Additionally, the internal name is renamed to "__pg__is_not_null" to further reduce the risk of collision with user-defined names. Reported-by: Евгений Горбанев <gorbanyoves@basealt.ru> Author: Richard Guo <guofenglinux@gmail.com> Reviewed-by: Alvaro Herrera <alvherre@kurilemu.de> Discussion: https://postgr.es/m/6bac9886-65bf-4cec-96bd-e304159f28db@basealt.ru Backpatch-through: 15
1 parent 7f1da18 commit 6661030

File tree

5 files changed

+25
-4
lines changed

5 files changed

+25
-4
lines changed

src/backend/parser/gram.y

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13820,7 +13820,7 @@ xmltable_column_el:
1382013820
parser_errposition(defel->location)));
1382113821
fc->colexpr = defel->arg;
1382213822
}
13823-
else if (strcmp(defel->defname, "is_not_null") == 0)
13823+
else if (strcmp(defel->defname, "__pg__is_not_null") == 0)
1382413824
{
1382513825
if (nullability_seen)
1382613826
ereport(ERROR,
@@ -13863,13 +13863,20 @@ xmltable_column_option_list:
1386313863

1386413864
xmltable_column_option_el:
1386513865
IDENT b_expr
13866-
{ $$ = makeDefElem($1, $2, @1); }
13866+
{
13867+
if (strcmp($1, "__pg__is_not_null") == 0)
13868+
ereport(ERROR,
13869+
(errcode(ERRCODE_SYNTAX_ERROR),
13870+
errmsg("option name \"%s\" cannot be used in XMLTABLE", $1),
13871+
parser_errposition(@1)));
13872+
$$ = makeDefElem($1, $2, @1);
13873+
}
1386713874
| DEFAULT b_expr
1386813875
{ $$ = makeDefElem("default", $2, @1); }
1386913876
| NOT NULL_P
13870-
{ $$ = makeDefElem("is_not_null", (Node *) makeBoolean(true), @1); }
13877+
{ $$ = makeDefElem("__pg__is_not_null", (Node *) makeBoolean(true), @1); }
1387113878
| NULL_P
13872-
{ $$ = makeDefElem("is_not_null", (Node *) makeBoolean(false), @1); }
13879+
{ $$ = makeDefElem("__pg__is_not_null", (Node *) makeBoolean(false), @1); }
1387313880
;
1387413881

1387513882
xml_namespace_list:

src/test/regress/expected/xml.out

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1139,6 +1139,10 @@ EXPLAIN (COSTS OFF, VERBOSE) SELECT * FROM xmltableview1;
11391139
-- errors
11401140
SELECT * FROM XMLTABLE (ROW () PASSING null COLUMNS v1 timestamp) AS f (v1, v2);
11411141
ERROR: XMLTABLE function has 1 columns available but 2 columns specified
1142+
SELECT * FROM XMLTABLE (ROW () PASSING null COLUMNS v1 timestamp __pg__is_not_null 1) AS f (v1);
1143+
ERROR: option name "__pg__is_not_null" cannot be used in XMLTABLE
1144+
LINE 1: ...MLTABLE (ROW () PASSING null COLUMNS v1 timestamp __pg__is_n...
1145+
^
11421146
-- XMLNAMESPACES tests
11431147
SELECT * FROM XMLTABLE(XMLNAMESPACES('http://x.y' AS zz),
11441148
'/zz:rows/zz:row'

src/test/regress/expected/xml_1.out

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -876,6 +876,10 @@ EXPLAIN (COSTS OFF, VERBOSE) SELECT * FROM xmltableview1;
876876
-- errors
877877
SELECT * FROM XMLTABLE (ROW () PASSING null COLUMNS v1 timestamp) AS f (v1, v2);
878878
ERROR: XMLTABLE function has 1 columns available but 2 columns specified
879+
SELECT * FROM XMLTABLE (ROW () PASSING null COLUMNS v1 timestamp __pg__is_not_null 1) AS f (v1);
880+
ERROR: option name "__pg__is_not_null" cannot be used in XMLTABLE
881+
LINE 1: ...MLTABLE (ROW () PASSING null COLUMNS v1 timestamp __pg__is_n...
882+
^
879883
-- XMLNAMESPACES tests
880884
SELECT * FROM XMLTABLE(XMLNAMESPACES('http://x.y' AS zz),
881885
'/zz:rows/zz:row'

src/test/regress/expected/xml_2.out

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,6 +1125,10 @@ EXPLAIN (COSTS OFF, VERBOSE) SELECT * FROM xmltableview1;
11251125
-- errors
11261126
SELECT * FROM XMLTABLE (ROW () PASSING null COLUMNS v1 timestamp) AS f (v1, v2);
11271127
ERROR: XMLTABLE function has 1 columns available but 2 columns specified
1128+
SELECT * FROM XMLTABLE (ROW () PASSING null COLUMNS v1 timestamp __pg__is_not_null 1) AS f (v1);
1129+
ERROR: option name "__pg__is_not_null" cannot be used in XMLTABLE
1130+
LINE 1: ...MLTABLE (ROW () PASSING null COLUMNS v1 timestamp __pg__is_n...
1131+
^
11281132
-- XMLNAMESPACES tests
11291133
SELECT * FROM XMLTABLE(XMLNAMESPACES('http://x.y' AS zz),
11301134
'/zz:rows/zz:row'

src/test/regress/sql/xml.sql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,8 @@ EXPLAIN (COSTS OFF, VERBOSE) SELECT * FROM xmltableview1;
387387
-- errors
388388
SELECT * FROM XMLTABLE (ROW () PASSING null COLUMNS v1 timestamp) AS f (v1, v2);
389389

390+
SELECT * FROM XMLTABLE (ROW () PASSING null COLUMNS v1 timestamp __pg__is_not_null 1) AS f (v1);
391+
390392
-- XMLNAMESPACES tests
391393
SELECT * FROM XMLTABLE(XMLNAMESPACES('http://x.y' AS zz),
392394
'/zz:rows/zz:row'

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy