Skip to content

Commit fe20afa

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 29904f5 commit fe20afa

File tree

3 files changed

+18
-12
lines changed

3 files changed

+18
-12
lines changed

src/backend/parser/analyze.c

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1424,7 +1424,7 @@ static Query *
14241424
transformValuesClause(ParseState *pstate, SelectStmt *stmt)
14251425
{
14261426
Query *qry = makeNode(Query);
1427-
List *exprsLists;
1427+
List *exprsLists = NIL;
14281428
List *coltypes = NIL;
14291429
List *coltypmods = NIL;
14301430
List *colcollations = NIL;
@@ -1508,6 +1508,9 @@ transformValuesClause(ParseState *pstate, SelectStmt *stmt)
15081508

15091509
/* Release sub-list's cells to save memory */
15101510
list_free(sublist);
1511+
1512+
/* Prepare an exprsLists element for this row */
1513+
exprsLists = lappend(exprsLists, NIL);
15111514
}
15121515

15131516
/*
@@ -1551,24 +1554,15 @@ transformValuesClause(ParseState *pstate, SelectStmt *stmt)
15511554
/*
15521555
* Finally, rearrange the coerced expressions into row-organized lists.
15531556
*/
1554-
exprsLists = NIL;
1555-
foreach(lc, colexprs[0])
1556-
{
1557-
Node *col = (Node *) lfirst(lc);
1558-
List *sublist;
1559-
1560-
sublist = list_make1(col);
1561-
exprsLists = lappend(exprsLists, sublist);
1562-
}
1563-
list_free(colexprs[0]);
1564-
for (i = 1; i < sublist_length; i++)
1557+
for (i = 0; i < sublist_length; i++)
15651558
{
15661559
forboth(lc, colexprs[i], lc2, exprsLists)
15671560
{
15681561
Node *col = (Node *) lfirst(lc);
15691562
List *sublist = lfirst(lc2);
15701563

15711564
sublist = lappend(sublist, col);
1565+
lfirst(lc2) = sublist;
15721566
}
15731567
list_free(colexprs[i]);
15741568
}

src/test/regress/expected/select.out

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,13 @@ TABLE int8_tbl;
514514
4567890123456789 | -4567890123456789
515515
(9 rows)
516516

517+
-- corner case: VALUES with no columns
518+
CREATE TEMP TABLE nocols();
519+
INSERT INTO nocols DEFAULT VALUES;
520+
SELECT * FROM nocols n, LATERAL (VALUES(n.*)) v;
521+
--
522+
(1 row)
523+
517524
--
518525
-- Test ORDER BY options
519526
--

src/test/regress/sql/select.sql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,11 @@ SELECT 2+2, 57
143143
UNION ALL
144144
TABLE int8_tbl;
145145

146+
-- corner case: VALUES with no columns
147+
CREATE TEMP TABLE nocols();
148+
INSERT INTO nocols DEFAULT VALUES;
149+
SELECT * FROM nocols n, LATERAL (VALUES(n.*)) v;
150+
146151
--
147152
-- Test ORDER BY options
148153
--

0 commit comments

Comments
 (0)