1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-29 10:41:53 +03:00

Fix parsetree representation of XMLTABLE(XMLNAMESPACES(DEFAULT ...)).

The original coding for XMLTABLE thought it could represent a default
namespace by a T_String Value node with a null string pointer.  That's
not okay, though; in particular outfuncs.c/readfuncs.c are not on board
with such a representation, meaning you'll get a null pointer crash
if you try to store a view or rule containing this construct.

To fix, change the parsetree representation so that we have a NULL
list element, instead of a bogus Value node.

This isn't really a functional limitation since default XML namespaces
aren't yet implemented in the executor; you'd just get "DEFAULT
namespace is not supported" anyway.  But crashes are not nice, so
back-patch to v10 where this syntax was added.  Ordinarily we'd consider
a parsetree representation change to be un-backpatchable; but since
existing releases would crash on the way to storing such constructs,
there can't be any existing views/rules to be incompatible with.

Per report from Andrey Lepikhov.

Discussion: https://postgr.es/m/3690074f-abd2-56a9-144a-aa5545d7a291@postgrespro.ru
This commit is contained in:
Tom Lane
2018-09-17 13:16:32 -04:00
parent 789ba5029a
commit 07a3af0ff8
5 changed files with 23 additions and 15 deletions

View File

@ -779,7 +779,7 @@ transformRangeTableFunc(ParseState *pstate, RangeTableFunc *rtf)
/* undef ordinality column number */
tf->ordinalitycol = -1;
/* Process column specs */
names = palloc(sizeof(char *) * list_length(rtf->columns));
colno = 0;
@ -900,15 +900,15 @@ transformRangeTableFunc(ParseState *pstate, RangeTableFunc *rtf)
{
foreach(lc2, ns_names)
{
char *name = strVal(lfirst(lc2));
Value *ns_node = (Value *) lfirst(lc2);
if (name == NULL)
if (ns_node == NULL)
continue;
if (strcmp(name, r->name) == 0)
if (strcmp(strVal(ns_node), r->name) == 0)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("namespace name \"%s\" is not unique",
name),
r->name),
parser_errposition(pstate, r->location)));
}
}
@ -922,8 +922,9 @@ transformRangeTableFunc(ParseState *pstate, RangeTableFunc *rtf)
default_ns_seen = true;
}
/* Note the string may be NULL */
ns_names = lappend(ns_names, makeString(r->name));
/* We represent DEFAULT by a null pointer */
ns_names = lappend(ns_names,
r->name ? makeString(r->name) : NULL);
}
tf->ns_uris = ns_uris;