@@ -587,6 +587,7 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
587587 List * exprsLists = NIL ;
588588 List * collations = NIL ;
589589 int sublist_length = -1 ;
590+ bool lateral = false;
590591 int i ;
591592
592593 Assert (selectStmt -> intoClause == NULL );
@@ -647,25 +648,20 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
647648 collations = lappend_oid (collations , InvalidOid );
648649
649650 /*
650- * Another thing we can't currently support is NEW/OLD references in
651- * rules --- seems we'd need something like SQL99's LATERAL construct
652- * to ensure that the values would be available while evaluating the
653- * VALUES RTE. This is a shame. FIXME
651+ * Ordinarily there can't be any current-level Vars in the expression
652+ * lists, because the namespace was empty ... but if we're inside
653+ * CREATE RULE, then NEW/OLD references might appear. In that case we
654+ * have to mark the VALUES RTE as LATERAL.
654655 */
655656 if (list_length (pstate -> p_rtable ) != 1 &&
656657 contain_vars_of_level ((Node * ) exprsLists , 0 ))
657- ereport (ERROR ,
658- (errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
659- errmsg ("VALUES must not contain OLD or NEW references" ),
660- errhint ("Use SELECT ... UNION ALL ... instead." ),
661- parser_errposition (pstate ,
662- locate_var_of_level ((Node * ) exprsLists , 0 ))));
658+ lateral = true;
663659
664660 /*
665661 * Generate the VALUES RTE
666662 */
667663 rte = addRangeTableEntryForValues (pstate , exprsLists , collations ,
668- NULL , true);
664+ NULL , lateral , true);
669665 rtr = makeNode (RangeTblRef );
670666 /* assume new rte is at end */
671667 rtr -> rtindex = list_length (pstate -> p_rtable );
@@ -1032,6 +1028,7 @@ transformValuesClause(ParseState *pstate, SelectStmt *stmt)
10321028 List * collations ;
10331029 List * * colexprs = NULL ;
10341030 int sublist_length = -1 ;
1031+ bool lateral = false;
10351032 RangeTblEntry * rte ;
10361033 int rtindex ;
10371034 ListCell * lc ;
@@ -1176,11 +1173,21 @@ transformValuesClause(ParseState *pstate, SelectStmt *stmt)
11761173 list_free (colexprs [i ]);
11771174 }
11781175
1176+ /*
1177+ * Ordinarily there can't be any current-level Vars in the expression
1178+ * lists, because the namespace was empty ... but if we're inside CREATE
1179+ * RULE, then NEW/OLD references might appear. In that case we have to
1180+ * mark the VALUES RTE as LATERAL.
1181+ */
1182+ if (pstate -> p_rtable != NIL &&
1183+ contain_vars_of_level ((Node * ) exprsLists , 0 ))
1184+ lateral = true;
1185+
11791186 /*
11801187 * Generate the VALUES RTE
11811188 */
11821189 rte = addRangeTableEntryForValues (pstate , exprsLists , collations ,
1183- NULL , true);
1190+ NULL , lateral , true);
11841191 addRTEtoQuery (pstate , rte , true, true, true);
11851192
11861193 /* assume new rte is at end */
@@ -1214,21 +1221,6 @@ transformValuesClause(ParseState *pstate, SelectStmt *stmt)
12141221 (errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
12151222 errmsg ("SELECT FOR UPDATE/SHARE cannot be applied to VALUES" )));
12161223
1217- /*
1218- * Another thing we can't currently support is NEW/OLD references in rules
1219- * --- seems we'd need something like SQL99's LATERAL construct to ensure
1220- * that the values would be available while evaluating the VALUES RTE.
1221- * This is a shame. FIXME
1222- */
1223- if (list_length (pstate -> p_rtable ) != 1 &&
1224- contain_vars_of_level ((Node * ) exprsLists , 0 ))
1225- ereport (ERROR ,
1226- (errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
1227- errmsg ("VALUES must not contain OLD or NEW references" ),
1228- errhint ("Use SELECT ... UNION ALL ... instead." ),
1229- parser_errposition (pstate ,
1230- locate_var_of_level ((Node * ) exprsLists , 0 ))));
1231-
12321224 qry -> rtable = pstate -> p_rtable ;
12331225 qry -> jointree = makeFromExpr (pstate -> p_joinlist , NULL );
12341226
0 commit comments