Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 91a3a74

Browse files
committed
Fix core dump in transformValuesClause when there are no columns.
The parser code that transformed VALUES from row-oriented to column-oriented lists failed if there were zero columns. You can't write that straightforwardly (though probably you should be able to), but the case can be reached by expanding a "tab.*" reference to a zero-column table. Per bug #17477 from Wang Ke. Back-patch to all supported branches. Discussion: https://postgr.es/m/17477-0af3c6ac6b0a6ae0@postgresql.org
1 parent 7f0754b commit 91a3a74

File tree

3 files changed

+19
-14
lines changed

3 files changed

+19
-14
lines changed

src/backend/parser/analyze.c

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1331,7 +1331,7 @@ static Query *
13311331
transformValuesClause(ParseState *pstate, SelectStmt *stmt)
13321332
{
13331333
Query *qry = makeNode(Query);
1334-
List *exprsLists;
1334+
List *exprsLists = NIL;
13351335
List *coltypes = NIL;
13361336
List *coltypmods = NIL;
13371337
List *colcollations = NIL;
@@ -1415,6 +1415,9 @@ transformValuesClause(ParseState *pstate, SelectStmt *stmt)
14151415

14161416
/* Release sub-list's cells to save memory */
14171417
list_free(sublist);
1418+
1419+
/* Prepare an exprsLists element for this row */
1420+
exprsLists = lappend(exprsLists, NIL);
14181421
}
14191422

14201423
/*
@@ -1469,25 +1472,15 @@ transformValuesClause(ParseState *pstate, SelectStmt *stmt)
14691472
/*
14701473
* Finally, rearrange the coerced expressions into row-organized lists.
14711474
*/
1472-
exprsLists = NIL;
1473-
foreach(lc, colexprs[0])
1474-
{
1475-
Node *col = (Node *) lfirst(lc);
1476-
List *sublist;
1477-
1478-
sublist = list_make1(col);
1479-
exprsLists = lappend(exprsLists, sublist);
1480-
}
1481-
list_free(colexprs[0]);
1482-
for (i = 1; i < sublist_length; i++)
1475+
for (i = 0; i < sublist_length; i++)
14831476
{
14841477
forboth(lc, colexprs[i], lc2, exprsLists)
14851478
{
14861479
Node *col = (Node *) lfirst(lc);
14871480
List *sublist = lfirst(lc2);
14881481

1489-
/* sublist pointer in exprsLists won't need adjustment */
1490-
(void) lappend(sublist, col);
1482+
sublist = lappend(sublist, col);
1483+
lfirst(lc2) = sublist;
14911484
}
14921485
list_free(colexprs[i]);
14931486
}

src/test/regress/expected/select.out

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,13 @@ TABLE int8_tbl;
517517
4567890123456789 | -4567890123456789
518518
(9 rows)
519519

520+
-- corner case: VALUES with no columns
521+
CREATE TEMP TABLE nocols();
522+
INSERT INTO nocols DEFAULT VALUES;
523+
SELECT * FROM nocols n, LATERAL (VALUES(n.*)) v;
524+
--
525+
(1 row)
526+
520527
--
521528
-- Test ORDER BY options
522529
--

src/test/regress/sql/select.sql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,11 @@ SELECT 2+2, 57
148148
UNION ALL
149149
TABLE int8_tbl;
150150

151+
-- corner case: VALUES with no columns
152+
CREATE TEMP TABLE nocols();
153+
INSERT INTO nocols DEFAULT VALUES;
154+
SELECT * FROM nocols n, LATERAL (VALUES(n.*)) v;
155+
151156
--
152157
-- Test ORDER BY options
153158
--

0 commit comments

Comments
 (0)