0001-Resolve-unknown-type-literals-in-GRAPH_TABLE-COLUMNS.patch

application/octet-stream

Filename: 0001-Resolve-unknown-type-literals-in-GRAPH_TABLE-COLUMNS.patch
Type: application/octet-stream
Part: 0
Message: [PATCH] Resolve unknown-type literals in GRAPH_TABLE COLUMNS

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: format-patch
Series: patch 0001
Subject: Resolve unknown-type literals in GRAPH_TABLE COLUMNS expressions
File+
src/backend/parser/parse_clause.c 3 0
src/test/regress/expected/graph_table.out 54 0
src/test/regress/sql/graph_table.sql 21 0
From efa000905343f6c2512f363c0013c19fbad5b8a5 Mon Sep 17 00:00:00 2001
From: Satya Narlapuram <satyanarlapuram@gmail.com>
Date: Sat, 25 Apr 2026 17:30:43 +0000
Subject: [PATCH] Resolve unknown-type literals in GRAPH_TABLE COLUMNS
 expressions

transformRangeGraphTable() calls transformExpr() and
assign_list_collations() for COLUMNS expressions but missed calling
resolveTargetListUnknowns(). As a result, literals such as 'col1' 
in a COLUMNS clause retained type "unknown", causing failures with 
ORDER BY, UNION, and output conversions.

Fix by calling resolveTargetListUnknowns() on the columns target
list right after assign_list_collations(), similar to SELECT target 
lists in transformSelectStmt().
---
 src/backend/parser/parse_clause.c         |  3 ++
 src/test/regress/expected/graph_table.out | 54 +++++++++++++++++++++++
 src/test/regress/sql/graph_table.sql      | 21 +++++++++
 3 files changed, 78 insertions(+)

diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c
index f3736979..77981850 100644
--- a/src/backend/parser/parse_clause.c
+++ b/src/backend/parser/parse_clause.c
@@ -1010,6 +1010,9 @@ transformRangeGraphTable(ParseState *pstate, RangeGraphTable *rgt)
 	 */
 	assign_list_collations(pstate, columns);
 
+	/* Resolve unknown-type literals to text */
+	resolveTargetListUnknowns(pstate, columns);
+
 	table_close(rel, NoLock);
 
 	pstate->p_graph_table_pstate = NULL;
diff --git a/src/test/regress/expected/graph_table.out b/src/test/regress/expected/graph_table.out
index d3c20610..212fa29f 100644
--- a/src/test/regress/expected/graph_table.out
+++ b/src/test/regress/expected/graph_table.out
@@ -1110,4 +1110,58 @@ SELECT * FROM GRAPH_TABLE (g1 MATCH (a IS vl1) COLUMNS (upper(a.vname) AS n)) OR
  V13
 (3 rows)
 
+-- String and NULL literals in COLUMNS must resolve to proper types
+-- (not remain as "unknown")
+SELECT pg_typeof(c1), c1
+  FROM GRAPH_TABLE (g1 MATCH (a IS vl1)
+    COLUMNS (a.vname AS n, 'val1' AS c1)) ORDER BY n;
+ pg_typeof |  c1  
+-----------+------
+ text      | val1
+ text      | val1
+ text      | val1
+(3 rows)
+
+-- ORDER BY on a literal column
+SELECT * FROM GRAPH_TABLE (g1 MATCH (a IS vl1)
+    COLUMNS (a.vname AS n, 'val1' AS c1)) ORDER BY c1, n;
+  n  |  c1  
+-----+------
+ v11 | val1
+ v12 | val1
+ v13 | val1
+(3 rows)
+
+-- UNION between GRAPH_TABLE literal column and plain text
+SELECT * FROM GRAPH_TABLE (g1 MATCH (a IS vl1)
+    COLUMNS (a.vname AS n, 'val1' AS c1))
+  UNION ALL SELECT 'val2', 'val3';
+  n   |  c1  
+------+------
+ v11  | val1
+ v12  | val1
+ v13  | val1
+ val2 | val3
+(4 rows)
+
+-- NULL literal must not cause failures
+SELECT n, pg_typeof(c1)
+  FROM GRAPH_TABLE (g1 MATCH (a IS vl1)
+    COLUMNS (a.vname AS n, NULL AS c1)) ORDER BY n;
+  n  | pg_typeof 
+-----+-----------
+ v11 | text
+ v12 | text
+ v13 | text
+(3 rows)
+
+-- integer literal type is preserved
+SELECT pg_typeof(c1)
+  FROM GRAPH_TABLE (g1 MATCH (a IS vl1)
+    COLUMNS (42 AS c1)) LIMIT 1;
+ pg_typeof 
+-----------
+ integer
+(1 row)
+
 -- leave the objects behind for pg_upgrade/pg_dump tests
diff --git a/src/test/regress/sql/graph_table.sql b/src/test/regress/sql/graph_table.sql
index 2521c4ca..3d74ab4c 100644
--- a/src/test/regress/sql/graph_table.sql
+++ b/src/test/regress/sql/graph_table.sql
@@ -634,4 +634,25 @@ SELECT src.vname, count(*)
 SELECT * FROM GRAPH_TABLE (g1 MATCH (a IS vl1) COLUMNS (a.vname || '!' AS n)) ORDER BY n;
 SELECT * FROM GRAPH_TABLE (g1 MATCH (a IS vl1) COLUMNS (upper(a.vname) AS n)) ORDER BY n;
 
+-- String and NULL literals in COLUMNS must resolve to proper types
+-- (not remain as "unknown")
+SELECT pg_typeof(c1), c1
+  FROM GRAPH_TABLE (g1 MATCH (a IS vl1)
+    COLUMNS (a.vname AS n, 'val1' AS c1)) ORDER BY n;
+-- ORDER BY on a literal column
+SELECT * FROM GRAPH_TABLE (g1 MATCH (a IS vl1)
+    COLUMNS (a.vname AS n, 'val1' AS c1)) ORDER BY c1, n;
+-- UNION between GRAPH_TABLE literal column and plain text
+SELECT * FROM GRAPH_TABLE (g1 MATCH (a IS vl1)
+    COLUMNS (a.vname AS n, 'val1' AS c1))
+  UNION ALL SELECT 'val2', 'val3';
+-- NULL literal must not cause failures
+SELECT n, pg_typeof(c1)
+  FROM GRAPH_TABLE (g1 MATCH (a IS vl1)
+    COLUMNS (a.vname AS n, NULL AS c1)) ORDER BY n;
+-- integer literal type is preserved
+SELECT pg_typeof(c1)
+  FROM GRAPH_TABLE (g1 MATCH (a IS vl1)
+    COLUMNS (42 AS c1)) LIMIT 1;
+
 -- leave the objects behind for pg_upgrade/pg_dump tests
-- 
2.43.0