INSERT ... VALUES with a single VALUES row is implemented quite differently
from the general VALUES case. A user-visible implication of that is that
we accept SRFs in the single-row case, but not in the multi-row case.
That's a historical artifact no doubt, but in view of the lack of field
complaints, I'm not excited about fixing it right now.
However, check_srf_call_placement() needs to know about this, first because
it should throw an error in the unsupported case, and second because it
should set p_hasTargetSRFs in the single-row case (because we treat that
like a SELECT tlist). That's an oversight in commit
a4c35ea1c.
To fix, split EXPR_KIND_VALUES into two values. So far as I can see,
this is the only place where we need to distinguish the two cases at
present; but there might be more later.
Patch by me, per report from Andres Freund.
Discussion: https://postgr.es/m/
20170116081548.zg63zltblwimpfgp@alap3.anarazel.de
*/
exprList = transformExpressionList(pstate,
(List *) linitial(valuesLists),
- EXPR_KIND_VALUES,
+ EXPR_KIND_VALUES_SINGLE,
true);
/* Prepare row for assignment to target table */
errkind = true;
break;
case EXPR_KIND_VALUES:
+ case EXPR_KIND_VALUES_SINGLE:
errkind = true;
break;
case EXPR_KIND_CHECK_CONSTRAINT:
errkind = true;
break;
case EXPR_KIND_VALUES:
+ case EXPR_KIND_VALUES_SINGLE:
errkind = true;
break;
case EXPR_KIND_CHECK_CONSTRAINT:
case EXPR_KIND_OFFSET:
case EXPR_KIND_RETURNING:
case EXPR_KIND_VALUES:
+ case EXPR_KIND_VALUES_SINGLE:
/* okay */
break;
case EXPR_KIND_CHECK_CONSTRAINT:
case EXPR_KIND_RETURNING:
return "RETURNING";
case EXPR_KIND_VALUES:
+ case EXPR_KIND_VALUES_SINGLE:
return "VALUES";
case EXPR_KIND_CHECK_CONSTRAINT:
case EXPR_KIND_DOMAIN_CHECK:
errkind = true;
break;
case EXPR_KIND_VALUES:
- /* okay */
+ /* SRFs are presently not supported by nodeValuesscan.c */
+ errkind = true;
+ break;
+ case EXPR_KIND_VALUES_SINGLE:
+ /* okay, since we process this like a SELECT tlist */
+ pstate->p_hasTargetSRFs = true;
break;
case EXPR_KIND_CHECK_CONSTRAINT:
case EXPR_KIND_DOMAIN_CHECK:
EXPR_KIND_OFFSET, /* OFFSET */
EXPR_KIND_RETURNING, /* RETURNING */
EXPR_KIND_VALUES, /* VALUES */
+ EXPR_KIND_VALUES_SINGLE, /* single-row VALUES (in INSERT only) */
EXPR_KIND_CHECK_CONSTRAINT, /* CHECK constraint for a table */
EXPR_KIND_DOMAIN_CHECK, /* CHECK constraint for a domain */
EXPR_KIND_COLUMN_DEFAULT, /* default value for a table column */
^
-- nor standalone VALUES (but surely this is a bug?)
VALUES(1, generate_series(1,2));
-ERROR: set-valued function called in context that cannot accept a set
+ERROR: set-returning functions are not allowed in VALUES
+LINE 1: VALUES(1, generate_series(1,2));
+ ^
-- We allow tSRFs that are not at top level
SELECT int4mul(generate_series(1,2), 10);
int4mul