From 096943966c2b716adbf35066b56372923b340a7c Mon Sep 17 00:00:00 2001 From: Alvaro Herrera Date: Tue, 23 Jan 2024 12:11:46 +0900 Subject: [PATCH v39 2/3] Show function name in TableFuncScan Previously we were only showing the user-specified alias, but this is clearly not the code's intent. Discussion: https://postgr.es/m/202401181711.qxjxpnl3ohnw%40alvherre.pgsql --- src/backend/commands/explain.c | 2 +- src/backend/nodes/outfuncs.c | 1 + src/backend/nodes/readfuncs.c | 1 + src/backend/parser/parse_relation.c | 4 ++-- src/include/nodes/parsenodes.h | 1 + src/test/regress/expected/xml.out | 16 ++++++++-------- src/test/regress/expected/xml_1.out | 16 ++++++++-------- src/test/regress/expected/xml_2.out | 16 ++++++++-------- 8 files changed, 30 insertions(+), 27 deletions(-) diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c index 843472e6dd..b3230f297b 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -3892,7 +3892,7 @@ ExplainTargetRel(Plan *plan, Index rti, ExplainState *es) break; case T_TableFuncScan: Assert(rte->rtekind == RTE_TABLEFUNC); - objectname = "xmltable"; + objectname = rte->tablefunc_name; objecttag = "Table Function Name"; break; case T_ValuesScan: diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index 03f67b6850..ffa3402c92 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -531,6 +531,7 @@ _outRangeTblEntry(StringInfo str, const RangeTblEntry *node) break; case RTE_TABLEFUNC: WRITE_NODE_FIELD(tablefunc); + WRITE_STRING_FIELD(tablefunc_name); break; case RTE_VALUES: WRITE_NODE_FIELD(values_lists); diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c index cfb552fde7..2d009251f3 100644 --- a/src/backend/nodes/readfuncs.c +++ b/src/backend/nodes/readfuncs.c @@ -530,6 +530,7 @@ _readRangeTblEntry(void) break; case RTE_TABLEFUNC: READ_NODE_FIELD(tablefunc); + READ_STRING_FIELD(tablefunc_name); /* The RTE must have a copy of the column type info, if any */ if (local_node->tablefunc) { diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c index 34a0ec5901..65e54abdd1 100644 --- a/src/backend/parser/parse_relation.c +++ b/src/backend/parser/parse_relation.c @@ -2073,17 +2073,17 @@ addRangeTableEntryForTableFunc(ParseState *pstate, Assert(list_length(tf->coltypmods) == list_length(tf->colnames)); Assert(list_length(tf->colcollations) == list_length(tf->colnames)); - refname = alias ? alias->aliasname : pstrdup("xmltable"); - rte->rtekind = RTE_TABLEFUNC; rte->relid = InvalidOid; rte->subquery = NULL; rte->tablefunc = tf; + rte->tablefunc_name = pstrdup("XMLTABLE"); rte->coltypes = tf->coltypes; rte->coltypmods = tf->coltypmods; rte->colcollations = tf->colcollations; rte->alias = alias; + refname = alias ? alias->aliasname : pstrdup("xmltable"); eref = alias ? copyObject(alias) : makeAlias(refname, NIL); numaliases = list_length(eref->colnames); diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 600cd8408e..aa36aaf769 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -1144,6 +1144,7 @@ typedef struct RangeTblEntry * Fields valid for a TableFunc RTE (else NULL): */ TableFunc *tablefunc; + char *tablefunc_name; /* * Fields valid for a values RTE (else NIL): diff --git a/src/test/regress/expected/xml.out b/src/test/regress/expected/xml.out index 6500cff885..70335c74df 100644 --- a/src/test/regress/expected/xml.out +++ b/src/test/regress/expected/xml.out @@ -1343,11 +1343,11 @@ CREATE OR REPLACE VIEW public.xmltableview1 AS FROM xmldata) x, LATERAL XMLTABLE(('/ROWS/ROW'::text) PASSING (x.data) COLUMNS id integer PATH ('@id'::text), _id FOR ORDINALITY, country_name text PATH ('COUNTRY_NAME/text()'::text) NOT NULL, country_id text PATH ('COUNTRY_ID'::text), region_id integer PATH ('REGION_ID'::text), size double precision PATH ('SIZE'::text), unit text PATH ('SIZE/@unit'::text), premier_name text DEFAULT ('not specified'::text) PATH ('PREMIER_NAME'::text)) EXPLAIN (COSTS OFF) SELECT * FROM xmltableview1; - QUERY PLAN ------------------------------------------ + QUERY PLAN +---------------------------------------------------- Nested Loop -> Seq Scan on xmldata - -> Table Function Scan on "xmltable" + -> Table Function Scan on "XMLTABLE" "xmltable" (3 rows) EXPLAIN (COSTS OFF, VERBOSE) SELECT * FROM xmltableview1; @@ -1357,7 +1357,7 @@ EXPLAIN (COSTS OFF, VERBOSE) SELECT * FROM xmltableview1; Output: "xmltable".id, "xmltable"._id, "xmltable".country_name, "xmltable".country_id, "xmltable".region_id, "xmltable".size, "xmltable".unit, "xmltable".premier_name -> Seq Scan on public.xmldata Output: xmldata.data - -> Table Function Scan on "xmltable" + -> Table Function Scan on "XMLTABLE" "xmltable" Output: "xmltable".id, "xmltable"._id, "xmltable".country_name, "xmltable".country_id, "xmltable".region_id, "xmltable".size, "xmltable".unit, "xmltable".premier_name Table Function Call: XMLTABLE(('/ROWS/ROW'::text) PASSING (xmldata.data) COLUMNS id integer PATH ('@id'::text), _id FOR ORDINALITY, country_name text PATH ('COUNTRY_NAME/text()'::text) NOT NULL, country_id text PATH ('COUNTRY_ID'::text), region_id integer PATH ('REGION_ID'::text), size double precision PATH ('SIZE'::text), unit text PATH ('SIZE/@unit'::text), premier_name text DEFAULT ('not specified'::text) PATH ('PREMIER_NAME'::text)) (7 rows) @@ -1536,7 +1536,7 @@ SELECT xmltable.* Output: "xmltable".id, "xmltable"._id, "xmltable".country_name, "xmltable".country_id, "xmltable".region_id, "xmltable".size, "xmltable".unit, "xmltable".premier_name -> Seq Scan on public.xmldata Output: xmldata.data - -> Table Function Scan on "xmltable" + -> Table Function Scan on "XMLTABLE" "xmltable" Output: "xmltable".id, "xmltable"._id, "xmltable".country_name, "xmltable".country_id, "xmltable".region_id, "xmltable".size, "xmltable".unit, "xmltable".premier_name Table Function Call: XMLTABLE(('/ROWS/ROW'::text) PASSING (xmldata.data) COLUMNS id integer PATH ('@id'::text), _id FOR ORDINALITY, country_name text PATH ('COUNTRY_NAME'::text) NOT NULL, country_id text PATH ('COUNTRY_ID'::text), region_id integer PATH ('REGION_ID'::text), size double precision PATH ('SIZE'::text), unit text PATH ('SIZE/@unit'::text), premier_name text DEFAULT ('not specified'::text) PATH ('PREMIER_NAME'::text)) (7 rows) @@ -1556,7 +1556,7 @@ SELECT f.* FROM xmldata, LATERAL xmltable('/ROWS/ROW[COUNTRY_NAME="Japan" or COU Output: f."COUNTRY_NAME", f."REGION_ID" -> Seq Scan on public.xmldata Output: xmldata.data - -> Table Function Scan on "xmltable" f + -> Table Function Scan on "XMLTABLE" f Output: f."COUNTRY_NAME", f."REGION_ID" Table Function Call: XMLTABLE(('/ROWS/ROW[COUNTRY_NAME="Japan" or COUNTRY_NAME="India"]'::text) PASSING (xmldata.data) COLUMNS "COUNTRY_NAME" text, "REGION_ID" integer) Filter: (f."COUNTRY_NAME" = 'Japan'::text) @@ -1591,7 +1591,7 @@ SELECT f.* FROM xmldata, LATERAL xmltable('/ROWS/ROW[COUNTRY_NAME="Japan" or COU "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + - "Table Function Name": "xmltable", + + "Table Function Name": "XMLTABLE", + "Alias": "f", + "Output": ["f.\"COUNTRY_NAME\"", "f.\"REGION_ID\""], + "Table Function Call": "XMLTABLE(('/ROWS/ROW[COUNTRY_NAME=\"Japan\" or COUNTRY_NAME=\"India\"]'::text) PASSING (xmldata.data) COLUMNS \"COUNTRY_NAME\" text, \"REGION_ID\" integer)",+ @@ -1700,7 +1700,7 @@ SELECT xmltable.* Output: "xmltable".id, "xmltable"._id, "xmltable".country_name, "xmltable".country_id, "xmltable".region_id, "xmltable".size, "xmltable".unit, "xmltable".premier_name -> Seq Scan on public.xmldata Output: xmldata.data - -> Table Function Scan on "xmltable" + -> Table Function Scan on "XMLTABLE" "xmltable" Output: "xmltable".id, "xmltable"._id, "xmltable".country_name, "xmltable".country_id, "xmltable".region_id, "xmltable".size, "xmltable".unit, "xmltable".premier_name Table Function Call: XMLTABLE(('/ROWS/ROW'::text) PASSING (xmldata.data) COLUMNS id integer PATH ('@id'::text), _id FOR ORDINALITY, country_name text PATH ('COUNTRY_NAME'::text) NOT NULL, country_id text PATH ('COUNTRY_ID'::text), region_id integer PATH ('REGION_ID'::text), size double precision PATH ('SIZE'::text), unit text PATH ('SIZE/@unit'::text), premier_name text DEFAULT ('not specified'::text) PATH ('PREMIER_NAME'::text)) Filter: ("xmltable".region_id = 2) diff --git a/src/test/regress/expected/xml_1.out b/src/test/regress/expected/xml_1.out index 9323b84ae2..08127db720 100644 --- a/src/test/regress/expected/xml_1.out +++ b/src/test/regress/expected/xml_1.out @@ -1004,11 +1004,11 @@ CREATE OR REPLACE VIEW public.xmltableview1 AS FROM xmldata) x, LATERAL XMLTABLE(('/ROWS/ROW'::text) PASSING (x.data) COLUMNS id integer PATH ('@id'::text), _id FOR ORDINALITY, country_name text PATH ('COUNTRY_NAME/text()'::text) NOT NULL, country_id text PATH ('COUNTRY_ID'::text), region_id integer PATH ('REGION_ID'::text), size double precision PATH ('SIZE'::text), unit text PATH ('SIZE/@unit'::text), premier_name text DEFAULT ('not specified'::text) PATH ('PREMIER_NAME'::text)) EXPLAIN (COSTS OFF) SELECT * FROM xmltableview1; - QUERY PLAN ------------------------------------------ + QUERY PLAN +---------------------------------------------------- Nested Loop -> Seq Scan on xmldata - -> Table Function Scan on "xmltable" + -> Table Function Scan on "XMLTABLE" "xmltable" (3 rows) EXPLAIN (COSTS OFF, VERBOSE) SELECT * FROM xmltableview1; @@ -1018,7 +1018,7 @@ EXPLAIN (COSTS OFF, VERBOSE) SELECT * FROM xmltableview1; Output: "xmltable".id, "xmltable"._id, "xmltable".country_name, "xmltable".country_id, "xmltable".region_id, "xmltable".size, "xmltable".unit, "xmltable".premier_name -> Seq Scan on public.xmldata Output: xmldata.data - -> Table Function Scan on "xmltable" + -> Table Function Scan on "XMLTABLE" "xmltable" Output: "xmltable".id, "xmltable"._id, "xmltable".country_name, "xmltable".country_id, "xmltable".region_id, "xmltable".size, "xmltable".unit, "xmltable".premier_name Table Function Call: XMLTABLE(('/ROWS/ROW'::text) PASSING (xmldata.data) COLUMNS id integer PATH ('@id'::text), _id FOR ORDINALITY, country_name text PATH ('COUNTRY_NAME/text()'::text) NOT NULL, country_id text PATH ('COUNTRY_ID'::text), region_id integer PATH ('REGION_ID'::text), size double precision PATH ('SIZE'::text), unit text PATH ('SIZE/@unit'::text), premier_name text DEFAULT ('not specified'::text) PATH ('PREMIER_NAME'::text)) (7 rows) @@ -1162,7 +1162,7 @@ SELECT xmltable.* Output: "xmltable".id, "xmltable"._id, "xmltable".country_name, "xmltable".country_id, "xmltable".region_id, "xmltable".size, "xmltable".unit, "xmltable".premier_name -> Seq Scan on public.xmldata Output: xmldata.data - -> Table Function Scan on "xmltable" + -> Table Function Scan on "XMLTABLE" "xmltable" Output: "xmltable".id, "xmltable"._id, "xmltable".country_name, "xmltable".country_id, "xmltable".region_id, "xmltable".size, "xmltable".unit, "xmltable".premier_name Table Function Call: XMLTABLE(('/ROWS/ROW'::text) PASSING (xmldata.data) COLUMNS id integer PATH ('@id'::text), _id FOR ORDINALITY, country_name text PATH ('COUNTRY_NAME'::text) NOT NULL, country_id text PATH ('COUNTRY_ID'::text), region_id integer PATH ('REGION_ID'::text), size double precision PATH ('SIZE'::text), unit text PATH ('SIZE/@unit'::text), premier_name text DEFAULT ('not specified'::text) PATH ('PREMIER_NAME'::text)) (7 rows) @@ -1181,7 +1181,7 @@ SELECT f.* FROM xmldata, LATERAL xmltable('/ROWS/ROW[COUNTRY_NAME="Japan" or COU Output: f."COUNTRY_NAME", f."REGION_ID" -> Seq Scan on public.xmldata Output: xmldata.data - -> Table Function Scan on "xmltable" f + -> Table Function Scan on "XMLTABLE" f Output: f."COUNTRY_NAME", f."REGION_ID" Table Function Call: XMLTABLE(('/ROWS/ROW[COUNTRY_NAME="Japan" or COUNTRY_NAME="India"]'::text) PASSING (xmldata.data) COLUMNS "COUNTRY_NAME" text, "REGION_ID" integer) Filter: (f."COUNTRY_NAME" = 'Japan'::text) @@ -1216,7 +1216,7 @@ SELECT f.* FROM xmldata, LATERAL xmltable('/ROWS/ROW[COUNTRY_NAME="Japan" or COU "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + - "Table Function Name": "xmltable", + + "Table Function Name": "XMLTABLE", + "Alias": "f", + "Output": ["f.\"COUNTRY_NAME\"", "f.\"REGION_ID\""], + "Table Function Call": "XMLTABLE(('/ROWS/ROW[COUNTRY_NAME=\"Japan\" or COUNTRY_NAME=\"India\"]'::text) PASSING (xmldata.data) COLUMNS \"COUNTRY_NAME\" text, \"REGION_ID\" integer)",+ @@ -1319,7 +1319,7 @@ SELECT xmltable.* Output: "xmltable".id, "xmltable"._id, "xmltable".country_name, "xmltable".country_id, "xmltable".region_id, "xmltable".size, "xmltable".unit, "xmltable".premier_name -> Seq Scan on public.xmldata Output: xmldata.data - -> Table Function Scan on "xmltable" + -> Table Function Scan on "XMLTABLE" "xmltable" Output: "xmltable".id, "xmltable"._id, "xmltable".country_name, "xmltable".country_id, "xmltable".region_id, "xmltable".size, "xmltable".unit, "xmltable".premier_name Table Function Call: XMLTABLE(('/ROWS/ROW'::text) PASSING (xmldata.data) COLUMNS id integer PATH ('@id'::text), _id FOR ORDINALITY, country_name text PATH ('COUNTRY_NAME'::text) NOT NULL, country_id text PATH ('COUNTRY_ID'::text), region_id integer PATH ('REGION_ID'::text), size double precision PATH ('SIZE'::text), unit text PATH ('SIZE/@unit'::text), premier_name text DEFAULT ('not specified'::text) PATH ('PREMIER_NAME'::text)) Filter: ("xmltable".region_id = 2) diff --git a/src/test/regress/expected/xml_2.out b/src/test/regress/expected/xml_2.out index e1d165c6c9..c720a05f5a 100644 --- a/src/test/regress/expected/xml_2.out +++ b/src/test/regress/expected/xml_2.out @@ -1323,11 +1323,11 @@ CREATE OR REPLACE VIEW public.xmltableview1 AS FROM xmldata) x, LATERAL XMLTABLE(('/ROWS/ROW'::text) PASSING (x.data) COLUMNS id integer PATH ('@id'::text), _id FOR ORDINALITY, country_name text PATH ('COUNTRY_NAME/text()'::text) NOT NULL, country_id text PATH ('COUNTRY_ID'::text), region_id integer PATH ('REGION_ID'::text), size double precision PATH ('SIZE'::text), unit text PATH ('SIZE/@unit'::text), premier_name text DEFAULT ('not specified'::text) PATH ('PREMIER_NAME'::text)) EXPLAIN (COSTS OFF) SELECT * FROM xmltableview1; - QUERY PLAN ------------------------------------------ + QUERY PLAN +---------------------------------------------------- Nested Loop -> Seq Scan on xmldata - -> Table Function Scan on "xmltable" + -> Table Function Scan on "XMLTABLE" "xmltable" (3 rows) EXPLAIN (COSTS OFF, VERBOSE) SELECT * FROM xmltableview1; @@ -1337,7 +1337,7 @@ EXPLAIN (COSTS OFF, VERBOSE) SELECT * FROM xmltableview1; Output: "xmltable".id, "xmltable"._id, "xmltable".country_name, "xmltable".country_id, "xmltable".region_id, "xmltable".size, "xmltable".unit, "xmltable".premier_name -> Seq Scan on public.xmldata Output: xmldata.data - -> Table Function Scan on "xmltable" + -> Table Function Scan on "XMLTABLE" "xmltable" Output: "xmltable".id, "xmltable"._id, "xmltable".country_name, "xmltable".country_id, "xmltable".region_id, "xmltable".size, "xmltable".unit, "xmltable".premier_name Table Function Call: XMLTABLE(('/ROWS/ROW'::text) PASSING (xmldata.data) COLUMNS id integer PATH ('@id'::text), _id FOR ORDINALITY, country_name text PATH ('COUNTRY_NAME/text()'::text) NOT NULL, country_id text PATH ('COUNTRY_ID'::text), region_id integer PATH ('REGION_ID'::text), size double precision PATH ('SIZE'::text), unit text PATH ('SIZE/@unit'::text), premier_name text DEFAULT ('not specified'::text) PATH ('PREMIER_NAME'::text)) (7 rows) @@ -1516,7 +1516,7 @@ SELECT xmltable.* Output: "xmltable".id, "xmltable"._id, "xmltable".country_name, "xmltable".country_id, "xmltable".region_id, "xmltable".size, "xmltable".unit, "xmltable".premier_name -> Seq Scan on public.xmldata Output: xmldata.data - -> Table Function Scan on "xmltable" + -> Table Function Scan on "XMLTABLE" "xmltable" Output: "xmltable".id, "xmltable"._id, "xmltable".country_name, "xmltable".country_id, "xmltable".region_id, "xmltable".size, "xmltable".unit, "xmltable".premier_name Table Function Call: XMLTABLE(('/ROWS/ROW'::text) PASSING (xmldata.data) COLUMNS id integer PATH ('@id'::text), _id FOR ORDINALITY, country_name text PATH ('COUNTRY_NAME'::text) NOT NULL, country_id text PATH ('COUNTRY_ID'::text), region_id integer PATH ('REGION_ID'::text), size double precision PATH ('SIZE'::text), unit text PATH ('SIZE/@unit'::text), premier_name text DEFAULT ('not specified'::text) PATH ('PREMIER_NAME'::text)) (7 rows) @@ -1536,7 +1536,7 @@ SELECT f.* FROM xmldata, LATERAL xmltable('/ROWS/ROW[COUNTRY_NAME="Japan" or COU Output: f."COUNTRY_NAME", f."REGION_ID" -> Seq Scan on public.xmldata Output: xmldata.data - -> Table Function Scan on "xmltable" f + -> Table Function Scan on "XMLTABLE" f Output: f."COUNTRY_NAME", f."REGION_ID" Table Function Call: XMLTABLE(('/ROWS/ROW[COUNTRY_NAME="Japan" or COUNTRY_NAME="India"]'::text) PASSING (xmldata.data) COLUMNS "COUNTRY_NAME" text, "REGION_ID" integer) Filter: (f."COUNTRY_NAME" = 'Japan'::text) @@ -1571,7 +1571,7 @@ SELECT f.* FROM xmldata, LATERAL xmltable('/ROWS/ROW[COUNTRY_NAME="Japan" or COU "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + - "Table Function Name": "xmltable", + + "Table Function Name": "XMLTABLE", + "Alias": "f", + "Output": ["f.\"COUNTRY_NAME\"", "f.\"REGION_ID\""], + "Table Function Call": "XMLTABLE(('/ROWS/ROW[COUNTRY_NAME=\"Japan\" or COUNTRY_NAME=\"India\"]'::text) PASSING (xmldata.data) COLUMNS \"COUNTRY_NAME\" text, \"REGION_ID\" integer)",+ @@ -1680,7 +1680,7 @@ SELECT xmltable.* Output: "xmltable".id, "xmltable"._id, "xmltable".country_name, "xmltable".country_id, "xmltable".region_id, "xmltable".size, "xmltable".unit, "xmltable".premier_name -> Seq Scan on public.xmldata Output: xmldata.data - -> Table Function Scan on "xmltable" + -> Table Function Scan on "XMLTABLE" "xmltable" Output: "xmltable".id, "xmltable"._id, "xmltable".country_name, "xmltable".country_id, "xmltable".region_id, "xmltable".size, "xmltable".unit, "xmltable".premier_name Table Function Call: XMLTABLE(('/ROWS/ROW'::text) PASSING (xmldata.data) COLUMNS id integer PATH ('@id'::text), _id FOR ORDINALITY, country_name text PATH ('COUNTRY_NAME'::text) NOT NULL, country_id text PATH ('COUNTRY_ID'::text), region_id integer PATH ('REGION_ID'::text), size double precision PATH ('SIZE'::text), unit text PATH ('SIZE/@unit'::text), premier_name text DEFAULT ('not specified'::text) PATH ('PREMIER_NAME'::text)) Filter: ("xmltable".region_id = 2) -- 2.35.3