diff --git a/src/backend/executor/nodeTableFuncscan.c b/src/backend/executor/nodeTableFuncscan.c index 7b749f6e927..5bbbc20b1cc 100644 --- a/src/backend/executor/nodeTableFuncscan.c +++ b/src/backend/executor/nodeTableFuncscan.c @@ -370,8 +370,9 @@ tfuncInitialize(TableFuncScanState *tstate, ExprContext *econtext, Datum doc) forboth(lc1, tstate->ns_uris, lc2, tstate->ns_names) { ExprState *expr = (ExprState *) lfirst(lc1); - char *ns_name = strVal(lfirst(lc2)); + Value *ns_node = (Value *) lfirst(lc2); char *ns_uri; + char *ns_name; value = ExecEvalExpr((ExprState *) expr, econtext, &isnull); if (isnull) @@ -380,6 +381,9 @@ tfuncInitialize(TableFuncScanState *tstate, ExprContext *econtext, Datum doc) errmsg("namespace URI must not be null"))); ns_uri = TextDatumGetCString(value); + /* DEFAULT is passed down to SetNamespace as NULL */ + ns_name = ns_node ? strVal(ns_node) : NULL; + routine->SetNamespace(tstate, ns_name, ns_uri); } diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c index ed26517c266..14ba4270dab 100644 --- a/src/backend/parser/parse_clause.c +++ b/src/backend/parser/parse_clause.c @@ -772,7 +772,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; @@ -893,15 +893,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))); } } @@ -915,8 +915,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; diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 4c9a49cd6d8..da07fbd7251 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -9618,17 +9618,17 @@ get_tablefunc(TableFunc *tf, deparse_context *context, bool showimplicit) forboth(lc1, tf->ns_uris, lc2, tf->ns_names) { Node *expr = (Node *) lfirst(lc1); - char *name = strVal(lfirst(lc2)); + Value *ns_node = (Value *) lfirst(lc2); if (!first) appendStringInfoString(buf, ", "); else first = false; - if (name != NULL) + if (ns_node != NULL) { get_rule_expr(expr, context, showimplicit); - appendStringInfo(buf, " AS %s", name); + appendStringInfo(buf, " AS %s", strVal(ns_node)); } else { diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index 78d276bf884..b2490779c21 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -1476,8 +1476,8 @@ typedef struct TableFuncScanState ExprState *rowexpr; /* state for row-generating expression */ List *colexprs; /* state for column-generating expression */ List *coldefexprs; /* state for column default expressions */ - List *ns_names; /* list of str nodes with namespace names */ - List *ns_uris; /* list of states of namespace uri exprs */ + List *ns_names; /* same as TableFunc.ns_names */ + List *ns_uris; /* list of states of namespace URI exprs */ Bitmapset *notnulls; /* nullability flag for each output column */ void *opaque; /* table builder private space */ const struct TableFuncRoutine *routine; /* table builder methods */ diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h index 8c536a8d38d..02288c84124 100644 --- a/src/include/nodes/primnodes.h +++ b/src/include/nodes/primnodes.h @@ -75,12 +75,15 @@ typedef struct RangeVar /* * TableFunc - node for a table function, such as XMLTABLE. + * + * Entries in the ns_names list are either string Value nodes containing + * literal namespace names, or NULL pointers to represent DEFAULT. */ typedef struct TableFunc { NodeTag type; - List *ns_uris; /* list of namespace uri */ - List *ns_names; /* list of namespace names */ + List *ns_uris; /* list of namespace URI expressions */ + List *ns_names; /* list of namespace names or NULL */ Node *docexpr; /* input document expression */ Node *rowexpr; /* row filter expression */ List *colnames; /* column names (list of String) */