rewriteHandler.c 131 KB
Newer Older
1 2
/*-------------------------------------------------------------------------
 *
3
 * rewriteHandler.c
4
 *		Primary module of query rewriter.
5
 *
Bruce Momjian's avatar
Bruce Momjian committed
6
 * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
Bruce Momjian's avatar
Add:  
Bruce Momjian committed
7
 * Portions Copyright (c) 1994, Regents of the University of California
8 9
 *
 * IDENTIFICATION
10
 *	  src/backend/rewrite/rewriteHandler.c
11
 *
12 13 14 15 16 17 18
 * NOTES
 *	  Some of the terms used in this file are of historic nature: "retrieve"
 *	  was the PostQUEL keyword for what today is SELECT. "RIR" stands for
 *	  "Retrieve-Instead-Retrieve", that is an ON SELECT DO INSTEAD SELECT rule
 *	  (which has to be unconditional and where only one rule can exist on each
 *	  relation).
 *
19 20 21 22
 *-------------------------------------------------------------------------
 */
#include "postgres.h"

23
#include "access/relation.h"
Tom Lane's avatar
Tom Lane committed
24
#include "access/sysattr.h"
25
#include "access/table.h"
Peter Eisentraut's avatar
Peter Eisentraut committed
26
#include "catalog/dependency.h"
27
#include "catalog/pg_type.h"
28
#include "commands/trigger.h"
Tom Lane's avatar
Tom Lane committed
29
#include "foreign/fdwapi.h"
30
#include "miscadmin.h"
31
#include "nodes/makefuncs.h"
32
#include "nodes/nodeFuncs.h"
33
#include "optimizer/optimizer.h"
Bruce Momjian's avatar
Bruce Momjian committed
34
#include "parser/analyze.h"
35
#include "parser/parse_coerce.h"
36
#include "parser/parse_relation.h"
37
#include "parser/parsetree.h"
38
#include "rewrite/rewriteDefine.h"
39
#include "rewrite/rewriteHandler.h"
Bruce Momjian's avatar
Bruce Momjian committed
40
#include "rewrite/rewriteManip.h"
41
#include "rewrite/rewriteSearchCycle.h"
42
#include "rewrite/rowsecurity.h"
43
#include "utils/builtins.h"
Bruce Momjian's avatar
Bruce Momjian committed
44
#include "utils/lsyscache.h"
45
#include "utils/rel.h"
46 47


48
/* We use a list of these to detect recursion in RewriteQuery */
Bruce Momjian's avatar
Bruce Momjian committed
49 50
typedef struct rewrite_event
{
51 52
	Oid			relation;		/* OID of relation having rules */
	CmdType		event;			/* type of rule being fired */
53
} rewrite_event;
54

55 56 57 58 59 60
typedef struct acquireLocksOnSubLinks_context
{
	bool		for_execute;	/* AcquireRewriteLocks' forExecute param */
} acquireLocksOnSubLinks_context;

static bool acquireLocksOnSubLinks(Node *node,
Tom Lane's avatar
Tom Lane committed
61
								   acquireLocksOnSubLinks_context *context);
62
static Query *rewriteRuleAction(Query *parsetree,
Tom Lane's avatar
Tom Lane committed
63 64 65 66 67
								Query *rule_action,
								Node *rule_qual,
								int rt_index,
								CmdType event,
								bool *returning_flag);
68
static List *adjustJoinTreeList(Query *parsetree, bool removert, int rt_index);
69
static List *rewriteTargetListIU(List *targetList,
Tom Lane's avatar
Tom Lane committed
70 71 72
								 CmdType commandType,
								 OverridingKind override,
								 Relation target_relation,
73 74 75
								 RangeTblEntry *values_rte,
								 int values_rte_index,
								 Bitmapset **unused_values_attrnos);
76
static TargetEntry *process_matched_tle(TargetEntry *src_tle,
Tom Lane's avatar
Tom Lane committed
77 78
										TargetEntry *prior_tle,
										const char *attrName);
79
static Node *get_assignment_input(Node *node);
80
static Bitmapset *findDefaultOnlyColumns(RangeTblEntry *rte);
81
static bool rewriteValuesRTE(Query *parsetree, RangeTblEntry *rte, int rti,
82 83
							 Relation target_relation, bool force_nulls,
							 Bitmapset *unused_cols);
84
static void markQueryForLocking(Query *qry, Node *jtnode,
Tom Lane's avatar
Tom Lane committed
85 86
								LockClauseStrength strength, LockWaitPolicy waitPolicy,
								bool pushedDown);
87
static List *matchLocks(CmdType event, RuleLock *rulelocks,
Tom Lane's avatar
Tom Lane committed
88
						int varno, Query *parsetree, bool *hasUpdate);
89
static Query *fireRIRrules(Query *parsetree, List *activeRIRs);
90 91
static bool view_has_instead_trigger(Relation view, CmdType event);
static Bitmapset *adjust_view_column_set(Bitmapset *cols, List *targetlist);
92

93

94 95 96 97
/*
 * AcquireRewriteLocks -
 *	  Acquire suitable locks on all the relations mentioned in the Query.
 *	  These locks will ensure that the relation schemas don't change under us
98
 *	  while we are rewriting, planning, and executing the query.
99
 *
100 101 102 103
 * Caution: this may modify the querytree, therefore caller should usually
 * have done a copyObject() to make a writable copy of the querytree in the
 * current memory context.
 *
104 105
 * forExecute indicates that the query is about to be executed.  If so,
 * we'll acquire the lock modes specified in the RTE rellockmode fields.
106 107 108 109 110 111 112
 * If forExecute is false, AccessShareLock is acquired on all relations.
 * This case is suitable for ruleutils.c, for example, where we only need
 * schema stability and we don't intend to actually modify any relations.
 *
 * forUpdatePushedDown indicates that a pushed-down FOR [KEY] UPDATE/SHARE
 * applies to the current subquery, requiring all rels to be opened with at
 * least RowShareLock.  This should always be false at the top of the
113 114
 * recursion.  When it is true, we adjust RTE rellockmode fields to reflect
 * the higher lock level.  This flag is ignored if forExecute is false.
115
 *
116
 * A secondary purpose of this routine is to fix up JOIN RTE references to
117
 * dropped columns (see details below).  Such RTEs are modified in-place.
118 119 120 121 122 123 124 125 126 127 128 129
 *
 * This processing can, and for efficiency's sake should, be skipped when the
 * querytree has just been built by the parser: parse analysis already got
 * all the same locks we'd get here, and the parser will have omitted dropped
 * columns from JOINs to begin with.  But we must do this whenever we are
 * dealing with a querytree produced earlier than the current command.
 *
 * About JOINs and dropped columns: although the parser never includes an
 * already-dropped column in a JOIN RTE's alias var list, it is possible for
 * such a list in a stored rule to include references to dropped columns.
 * (If the column is not explicitly referenced anywhere else in the query,
 * the dependency mechanism won't consider it used by the rule and so won't
130 131
 * prevent the column drop.)  To support get_rte_attribute_is_dropped(), we
 * replace join alias vars that reference dropped columns with null pointers.
132 133 134 135 136 137 138
 *
 * (In PostgreSQL 8.0, we did not do this processing but instead had
 * get_rte_attribute_is_dropped() recurse to detect dropped columns in joins.
 * That approach had horrible performance unfortunately; in particular
 * construction of a nested join was O(N^2) in the nesting depth.)
 */
void
139 140 141
AcquireRewriteLocks(Query *parsetree,
					bool forExecute,
					bool forUpdatePushedDown)
142 143 144
{
	ListCell   *l;
	int			rt_index;
145 146 147
	acquireLocksOnSubLinks_context context;

	context.for_execute = forExecute;
148 149 150 151 152 153 154 155 156 157 158

	/*
	 * First, process RTEs of the current query level.
	 */
	rt_index = 0;
	foreach(l, parsetree->rtable)
	{
		RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
		Relation	rel;
		LOCKMODE	lockmode;
		List	   *newaliasvars;
159 160
		Index		curinputvarno;
		RangeTblEntry *curinputrte;
161 162 163 164 165 166
		ListCell   *ll;

		++rt_index;
		switch (rte->rtekind)
		{
			case RTE_RELATION:
167

168
				/*
169
				 * Grab the appropriate lock type for the relation, and do not
170 171 172
				 * release it until end of transaction.  This protects the
				 * rewriter, planner, and executor against schema changes
				 * mid-query.
173
				 *
174 175
				 * If forExecute is false, ignore rellockmode and just use
				 * AccessShareLock.
176
				 */
177 178
				if (!forExecute)
					lockmode = AccessShareLock;
179 180 181 182 183
				else if (forUpdatePushedDown)
				{
					/* Upgrade RTE's lock mode to reflect pushed-down lock */
					if (rte->rellockmode == AccessShareLock)
						rte->rellockmode = RowShareLock;
184
					lockmode = rte->rellockmode;
185
				}
186
				else
187
					lockmode = rte->rellockmode;
188

189
				rel = table_open(rte->relid, lockmode);
190 191 192 193 194 195 196

				/*
				 * While we have the relation open, update the RTE's relkind,
				 * just in case it changed since this rule was made.
				 */
				rte->relkind = rel->rd_rel->relkind;

197
				table_close(rel, NoLock);
198 199 200
				break;

			case RTE_JOIN:
201

202
				/*
203
				 * Scan the join's alias var list to see if any columns have
204 205
				 * been dropped, and if so replace those Vars with null
				 * pointers.
206
				 *
207 208 209
				 * Since a join has only two inputs, we can expect to see
				 * multiple references to the same input RTE; optimize away
				 * multiple fetches.
210 211
				 */
				newaliasvars = NIL;
212 213
				curinputvarno = 0;
				curinputrte = NULL;
214 215
				foreach(ll, rte->joinaliasvars)
				{
216 217 218 219 220
					Var		   *aliasitem = (Var *) lfirst(ll);
					Var		   *aliasvar = aliasitem;

					/* Look through any implicit coercion */
					aliasvar = (Var *) strip_implicit_coercions((Node *) aliasvar);
221 222 223 224 225

					/*
					 * If the list item isn't a simple Var, then it must
					 * represent a merged column, ie a USING column, and so it
					 * couldn't possibly be dropped, since it's referenced in
226 227
					 * the join clause.  (Conceivably it could also be a null
					 * pointer already?  But that's OK too.)
228
					 */
229
					if (aliasvar && IsA(aliasvar, Var))
230 231 232
					{
						/*
						 * The elements of an alias list have to refer to
233
						 * earlier RTEs of the same rtable, because that's the
Bruce Momjian's avatar
Bruce Momjian committed
234
						 * order the planner builds things in.  So we already
235 236 237 238
						 * processed the referenced RTE, and so it's safe to
						 * use get_rte_attribute_is_dropped on it. (This might
						 * not hold after rewriting or planning, but it's OK
						 * to assume here.)
239 240
						 */
						Assert(aliasvar->varlevelsup == 0);
241 242 243 244 245 246 247 248 249 250 251
						if (aliasvar->varno != curinputvarno)
						{
							curinputvarno = aliasvar->varno;
							if (curinputvarno >= rt_index)
								elog(ERROR, "unexpected varno %d in JOIN RTE %d",
									 curinputvarno, rt_index);
							curinputrte = rt_fetch(curinputvarno,
												   parsetree->rtable);
						}
						if (get_rte_attribute_is_dropped(curinputrte,
														 aliasvar->varattno))
252
						{
253 254
							/* Replace the join alias item with a NULL */
							aliasitem = NULL;
255 256
						}
					}
257
					newaliasvars = lappend(newaliasvars, aliasitem);
258 259 260 261 262
				}
				rte->joinaliasvars = newaliasvars;
				break;

			case RTE_SUBQUERY:
263

264 265 266 267
				/*
				 * The subquery RTE itself is all right, but we have to
				 * recurse to process the represented subquery.
				 */
268
				AcquireRewriteLocks(rte->subquery,
269
									forExecute,
270
									(forUpdatePushedDown ||
Tom Lane's avatar
Tom Lane committed
271
									 get_parse_rowmark(parsetree, rt_index) != NULL));
272 273 274 275 276 277 278 279
				break;

			default:
				/* ignore other types of RTEs */
				break;
		}
	}

280 281 282 283 284
	/* Recurse into subqueries in WITH */
	foreach(l, parsetree->cteList)
	{
		CommonTableExpr *cte = (CommonTableExpr *) lfirst(l);

285
		AcquireRewriteLocks((Query *) cte->ctequery, forExecute, false);
286 287
	}

288
	/*
289
	 * Recurse into sublink subqueries, too.  But we already did the ones in
290
	 * the rtable and cteList.
291 292
	 */
	if (parsetree->hasSubLinks)
293
		query_tree_walker(parsetree, acquireLocksOnSubLinks, &context,
294
						  QTW_IGNORE_RC_SUBQUERIES);
295 296 297 298 299 300
}

/*
 * Walker to find sublink subqueries for AcquireRewriteLocks
 */
static bool
301
acquireLocksOnSubLinks(Node *node, acquireLocksOnSubLinks_context *context)
302 303 304 305 306 307 308 309
{
	if (node == NULL)
		return false;
	if (IsA(node, SubLink))
	{
		SubLink    *sub = (SubLink *) node;

		/* Do what we came for */
310 311 312
		AcquireRewriteLocks((Query *) sub->subselect,
							context->for_execute,
							false);
313 314 315 316 317 318 319 320 321 322 323
		/* Fall through to process lefthand args of SubLink */
	}

	/*
	 * Do NOT recurse into Query nodes, because AcquireRewriteLocks already
	 * processed subselects of subselects for us.
	 */
	return expression_tree_walker(node, acquireLocksOnSubLinks, context);
}


324
/*
325 326 327
 * rewriteRuleAction -
 *	  Rewrite the rule action with appropriate qualifiers (taken from
 *	  the triggering query).
328 329 330 331 332 333 334 335
 *
 * Input arguments:
 *	parsetree - original query
 *	rule_action - one action (query) of a rule
 *	rule_qual - WHERE condition of rule, or NULL if unconditional
 *	rt_index - RT index of result relation in original query
 *	event - type of rule event
 * Output arguments:
336 337
 *	*returning_flag - set true if we rewrite RETURNING clause in rule_action
 *					(must be initialized to false)
338 339
 * Return value:
 *	rewritten form of rule_action
340
 */
341 342
static Query *
rewriteRuleAction(Query *parsetree,
343 344
				  Query *rule_action,
				  Node *rule_qual,
345
				  int rt_index,
346 347
				  CmdType event,
				  bool *returning_flag)
348
{
349 350 351
	int			current_varno,
				new_varno;
	int			rt_length;
352 353
	Query	   *sub_action;
	Query	  **sub_action_ptr;
354 355 356
	acquireLocksOnSubLinks_context context;

	context.for_execute = true;
357

358
	/*
359 360
	 * Make modifiable copies of rule action and qual (what we're passed are
	 * the stored versions in the relcache; don't touch 'em!).
361
	 */
362 363
	rule_action = copyObject(rule_action);
	rule_qual = copyObject(rule_qual);
364

365 366 367
	/*
	 * Acquire necessary locks and fix any deleted JOIN RTE entries.
	 */
368 369
	AcquireRewriteLocks(rule_action, true, false);
	(void) acquireLocksOnSubLinks(rule_qual, &context);
370

371
	current_varno = rt_index;
372
	rt_length = list_length(parsetree->rtable);
373
	new_varno = PRS2_NEW_VARNO + rt_length;
374

375
	/*
376 377
	 * Adjust rule action and qual to offset its varnos, so that we can merge
	 * its rtable with the main parsetree's rtable.
378
	 *
379 380
	 * If the rule action is an INSERT...SELECT, the OLD/NEW rtable entries
	 * will be in the SELECT part, and we have to modify that rather than the
381
	 * top-level INSERT (kluge!).
382
	 */
383
	sub_action = getInsertSelectQuery(rule_action, &sub_action_ptr);
384

385
	OffsetVarNodes((Node *) sub_action, rt_length, 0);
386
	OffsetVarNodes(rule_qual, rt_length, 0);
387
	/* but references to OLD should point at original rt_index */
388 389
	ChangeVarNodes((Node *) sub_action,
				   PRS2_OLD_VARNO + rt_length, rt_index, 0);
390
	ChangeVarNodes(rule_qual,
391 392 393
				   PRS2_OLD_VARNO + rt_length, rt_index, 0);

	/*
394 395
	 * Generate expanded rtable consisting of main parsetree's rtable plus
	 * rule action's rtable; this becomes the complete rtable for the rule
Bruce Momjian's avatar
Bruce Momjian committed
396
	 * action.  Some of the entries may be unused after we finish rewriting,
397
	 * but we leave them all in place for two reasons:
398
	 *
399 400
	 * We'd have a much harder job to adjust the query's varnos if we
	 * selectively removed RT entries.
401
	 *
402 403 404
	 * If the rule is INSTEAD, then the original query won't be executed at
	 * all, and so its rtable must be preserved so that the executor will do
	 * the correct permissions checks on it.
405 406
	 *
	 * RT entries that are not referenced in the completed jointree will be
407 408 409 410 411
	 * ignored by the planner, so they do not affect query semantics.  But any
	 * permissions checks specified in them will be applied during executor
	 * startup (see ExecCheckRTEPerms()).  This allows us to check that the
	 * caller has, say, insert-permission on a view, when the view is not
	 * semantically referenced at all in the resulting query.
412
	 *
413 414
	 * When a rule is not INSTEAD, the permissions checks done on its copied
	 * RT entries will be redundant with those done during execution of the
415
	 * original query, but we don't bother to treat that case differently.
416
	 *
417 418 419
	 * NOTE: because planner will destructively alter rtable, we must ensure
	 * that rule action's rtable is separate and shares no substructure with
	 * the main rtable.  Hence do a deep copy here.
420
	 */
421
	sub_action->rtable = list_concat(copyObject(parsetree->rtable),
Bruce Momjian's avatar
Bruce Momjian committed
422
									 sub_action->rtable);
423

424 425 426 427 428 429 430 431 432 433 434 435 436 437
	/*
	 * There could have been some SubLinks in parsetree's rtable, in which
	 * case we'd better mark the sub_action correctly.
	 */
	if (parsetree->hasSubLinks && !sub_action->hasSubLinks)
	{
		ListCell   *lc;

		foreach(lc, parsetree->rtable)
		{
			RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc);

			switch (rte->rtekind)
			{
438 439 440 441
				case RTE_RELATION:
					sub_action->hasSubLinks =
						checkExprHasSubLink((Node *) rte->tablesample);
					break;
442 443
				case RTE_FUNCTION:
					sub_action->hasSubLinks =
444
						checkExprHasSubLink((Node *) rte->functions);
445
					break;
446 447 448 449
				case RTE_TABLEFUNC:
					sub_action->hasSubLinks =
						checkExprHasSubLink((Node *) rte->tablefunc);
					break;
450 451 452 453 454 455 456 457 458
				case RTE_VALUES:
					sub_action->hasSubLinks =
						checkExprHasSubLink((Node *) rte->values_lists);
					break;
				default:
					/* other RTE types don't contain bare expressions */
					break;
			}
			if (sub_action->hasSubLinks)
459
				break;			/* no need to keep scanning rtable */
460 461 462
		}
	}

463 464 465 466 467 468 469 470 471
	/*
	 * Also, we might have absorbed some RTEs with RLS conditions into the
	 * sub_action.  If so, mark it as hasRowSecurity, whether or not those
	 * RTEs will be referenced after we finish rewriting.  (Note: currently
	 * this is a no-op because RLS conditions aren't added till later, but it
	 * seems like good future-proofing to do this anyway.)
	 */
	sub_action->hasRowSecurity |= parsetree->hasRowSecurity;

472 473
	/*
	 * Each rule action's jointree should be the main parsetree's jointree
474 475 476 477 478
	 * plus that rule's jointree, but usually *without* the original rtindex
	 * that we're replacing (if present, which it won't be for INSERT). Note
	 * that if the rule action refers to OLD, its jointree will add a
	 * reference to rt_index.  If the rule action doesn't refer to OLD, but
	 * either the rule_qual or the user query quals do, then we need to keep
Bruce Momjian's avatar
Bruce Momjian committed
479
	 * the original rtindex in the jointree to provide data for the quals.  We
480 481
	 * don't want the original rtindex to be joined twice, however, so avoid
	 * keeping it if the rule action mentions it.
482
	 *
483 484
	 * As above, the action's jointree must not share substructure with the
	 * main parsetree's.
485
	 */
486
	if (sub_action->commandType != CMD_UTILITY)
487
	{
488 489
		bool		keeporig;
		List	   *newjointree;
490

491
		Assert(sub_action->jointree != NULL);
492 493
		keeporig = (!rangeTableEntry_used((Node *) sub_action->jointree,
										  rt_index, 0)) &&
494
			(rangeTableEntry_used(rule_qual, rt_index, 0) ||
495
			 rangeTableEntry_used(parsetree->jointree->quals, rt_index, 0));
496
		newjointree = adjustJoinTreeList(parsetree, !keeporig, rt_index);
497 498 499
		if (newjointree != NIL)
		{
			/*
500
			 * If sub_action is a setop, manipulating its jointree will do no
Bruce Momjian's avatar
Bruce Momjian committed
501
			 * good at all, because the jointree is dummy.  (Perhaps someday
502 503
			 * we could push the joining and quals down to the member
			 * statements of the setop?)
504 505
			 */
			if (sub_action->setOperations != NULL)
506 507 508
				ereport(ERROR,
						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
						 errmsg("conditional UNION/INTERSECT/EXCEPT statements are not implemented")));
509 510

			sub_action->jointree->fromlist =
511
				list_concat(newjointree, sub_action->jointree->fromlist);
512 513 514 515 516 517 518 519

			/*
			 * There could have been some SubLinks in newjointree, in which
			 * case we'd better mark the sub_action correctly.
			 */
			if (parsetree->hasSubLinks && !sub_action->hasSubLinks)
				sub_action->hasSubLinks =
					checkExprHasSubLink((Node *) newjointree);
520
		}
521 522
	}

523
	/*
524 525
	 * If the original query has any CTEs, copy them into the rule action. But
	 * we don't need them for a utility action.
526 527 528 529 530 531
	 */
	if (parsetree->cteList != NIL && sub_action->commandType != CMD_UTILITY)
	{
		ListCell   *lc;

		/*
532 533 534
		 * Annoying implementation restriction: because CTEs are identified by
		 * name within a cteList, we can't merge a CTE from the original query
		 * if it has the same name as any CTE in the rule action.
535 536 537
		 *
		 * This could possibly be fixed by using some sort of internally
		 * generated ID, instead of names, to link CTE RTEs to their CTEs.
538 539 540
		 * However, decompiling the results would be quite confusing; note the
		 * merge of hasRecursive flags below, which could change the apparent
		 * semantics of such redundantly-named CTEs.
541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561
		 */
		foreach(lc, parsetree->cteList)
		{
			CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc);
			ListCell   *lc2;

			foreach(lc2, sub_action->cteList)
			{
				CommonTableExpr *cte2 = (CommonTableExpr *) lfirst(lc2);

				if (strcmp(cte->ctename, cte2->ctename) == 0)
					ereport(ERROR,
							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
							 errmsg("WITH query name \"%s\" appears in both a rule action and the query being rewritten",
									cte->ctename)));
			}
		}

		/* OK, it's safe to combine the CTE lists */
		sub_action->cteList = list_concat(sub_action->cteList,
										  copyObject(parsetree->cteList));
562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581
		/* ... and don't forget about the associated flags */
		sub_action->hasRecursive |= parsetree->hasRecursive;
		sub_action->hasModifyingCTE |= parsetree->hasModifyingCTE;

		/*
		 * If rule_action is different from sub_action (i.e., the rule action
		 * is an INSERT...SELECT), then we might have just added some
		 * data-modifying CTEs that are not at the top query level.  This is
		 * disallowed by the parser and we mustn't generate such trees here
		 * either, so throw an error.
		 *
		 * Conceivably such cases could be supported by attaching the original
		 * query's CTEs to rule_action not sub_action.  But to do that, we'd
		 * have to increment ctelevelsup in RTEs and SubLinks copied from the
		 * original query.  For now, it doesn't seem worth the trouble.
		 */
		if (sub_action->hasModifyingCTE && rule_action != sub_action)
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
					 errmsg("INSERT...SELECT rule actions are not supported for queries having data-modifying statements in WITH")));
582 583
	}

584
	/*
585 586 587
	 * Event Qualification forces copying of parsetree and splitting into two
	 * queries one w/rule_qual, one w/NOT rule_qual. Also add user query qual
	 * onto rule action
588
	 */
589
	AddQual(sub_action, rule_qual);
590 591 592 593

	AddQual(sub_action, parsetree->jointree->quals);

	/*
594
	 * Rewrite new.attribute with right hand side of target-list entry for
595
	 * appropriate field name in insert/update.
596
	 *
597 598 599
	 * KLUGE ALERT: since ReplaceVarsFromTargetList returns a mutated copy, we
	 * can't just apply it to sub_action; we have to remember to update the
	 * sublink inside rule_action, too.
600
	 */
601 602
	if ((event == CMD_INSERT || event == CMD_UPDATE) &&
		sub_action->commandType != CMD_UTILITY)
603
	{
604 605 606 607 608 609 610 611 612 613 614
		sub_action = (Query *)
			ReplaceVarsFromTargetList((Node *) sub_action,
									  new_varno,
									  0,
									  rt_fetch(new_varno, sub_action->rtable),
									  parsetree->targetList,
									  (event == CMD_UPDATE) ?
									  REPLACEVARS_CHANGE_VARNO :
									  REPLACEVARS_SUBSTITUTE_NULL,
									  current_varno,
									  NULL);
615 616 617
		if (sub_action_ptr)
			*sub_action_ptr = sub_action;
		else
618
			rule_action = sub_action;
619
	}
620

621
	/*
Bruce Momjian's avatar
Bruce Momjian committed
622 623 624 625
	 * If rule_action has a RETURNING clause, then either throw it away if the
	 * triggering query has no RETURNING clause, or rewrite it to emit what
	 * the triggering query's RETURNING clause asks for.  Throw an error if
	 * more than one rule has a RETURNING clause.
626 627 628 629 630 631 632 633
	 */
	if (!parsetree->returningList)
		rule_action->returningList = NIL;
	else if (rule_action->returningList)
	{
		if (*returning_flag)
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
Tom Lane's avatar
Tom Lane committed
634
					 errmsg("cannot have RETURNING lists in multiple rules")));
635 636
		*returning_flag = true;
		rule_action->returningList = (List *)
637 638 639 640 641 642 643 644 645
			ReplaceVarsFromTargetList((Node *) parsetree->returningList,
									  parsetree->resultRelation,
									  0,
									  rt_fetch(parsetree->resultRelation,
											   parsetree->rtable),
									  rule_action->returningList,
									  REPLACEVARS_REPORT_ERROR,
									  0,
									  &rule_action->hasSubLinks);
646 647 648 649 650 651 652

		/*
		 * There could have been some SubLinks in parsetree's returningList,
		 * in which case we'd better mark the rule_action correctly.
		 */
		if (parsetree->hasSubLinks && !rule_action->hasSubLinks)
			rule_action->hasSubLinks =
653
				checkExprHasSubLink((Node *) rule_action->returningList);
654 655
	}

656
	return rule_action;
657 658
}

659
/*
660 661 662 663
 * Copy the query's jointree list, and optionally attempt to remove any
 * occurrence of the given rt_index as a top-level join item (we do not look
 * for it within join items; this is OK because we are only expecting to find
 * it as an UPDATE or DELETE target relation, which will be at the top level
664 665
 * of the join).  Returns modified jointree list --- this is a separate copy
 * sharing no nodes with the original.
666
 */
667
static List *
668
adjustJoinTreeList(Query *parsetree, bool removert, int rt_index)
669
{
670
	List	   *newjointree = copyObject(parsetree->jointree->fromlist);
671
	ListCell   *l;
672

673
	if (removert)
Bruce Momjian's avatar
Bruce Momjian committed
674
	{
675
		foreach(l, newjointree)
676
		{
677
			RangeTblRef *rtr = lfirst(l);
678

679 680
			if (IsA(rtr, RangeTblRef) &&
				rtr->rtindex == rt_index)
681
			{
682
				newjointree = foreach_delete_current(newjointree, l);
683 684
				break;
			}
685
		}
686
	}
687
	return newjointree;
688
}
689

690

691
/*
Tom Lane's avatar
Tom Lane committed
692
 * rewriteTargetListIU - rewrite INSERT/UPDATE targetlist into standard form
693 694 695 696 697 698 699
 *
 * This has the following responsibilities:
 *
 * 1. For an INSERT, add tlist entries to compute default values for any
 * attributes that have defaults and are not assigned to in the given tlist.
 * (We do not insert anything for default-less attributes, however.  The
 * planner will later insert NULLs for them, but there's no reason to slow
700 701 702
 * down rewriter processing with extra tlist nodes.)  Also, for both INSERT
 * and UPDATE, replace explicit DEFAULT specifications with column default
 * expressions.
703
 *
704
 * 2. Merge multiple entries for the same target attribute, or declare error
705 706 707
 * if we can't.  Multiple entries are only allowed for INSERT/UPDATE of
 * portions of an array or record field, for example
 *			UPDATE table SET foo[2] = 42, foo[4] = 43;
708 709
 * We can merge such operations into a single assignment op.  Essentially,
 * the expression we want to produce in this case is like
710
 *		foo = array_set_element(array_set_element(foo, 2, 42), 4, 43)
711
 *
712
 * 3. Sort the tlist into standard order: non-junk fields in order by resno,
713 714
 * then junk fields (these in no particular order).
 *
715 716
 * We must do items 1 and 2 before firing rewrite rules, else rewritten
 * references to NEW.foo will produce wrong or incomplete results.  Item 3
717
 * is not needed for rewriting, but it is helpful for the planner, and we
Tom Lane's avatar
Tom Lane committed
718
 * can do it essentially for free while handling the other items.
719
 *
720 721 722 723 724 725 726 727
 * If values_rte is non-NULL (i.e., we are doing a multi-row INSERT using
 * values from a VALUES RTE), we populate *unused_values_attrnos with the
 * attribute numbers of any unused columns from the VALUES RTE.  This can
 * happen for identity and generated columns whose targetlist entries are
 * replaced with generated expressions (if INSERT ... OVERRIDING USER VALUE is
 * used, or all the values to be inserted are DEFAULT).  This information is
 * required by rewriteValuesRTE() to handle any DEFAULT items in the unused
 * columns.  The caller must have initialized *unused_values_attrnos to NULL.
728
 */
Bruce Momjian's avatar
Bruce Momjian committed
729
static List *
730 731
rewriteTargetListIU(List *targetList,
					CmdType commandType,
Peter Eisentraut's avatar
Peter Eisentraut committed
732
					OverridingKind override,
733
					Relation target_relation,
734 735 736
					RangeTblEntry *values_rte,
					int values_rte_index,
					Bitmapset **unused_values_attrnos)
737
{
738
	TargetEntry **new_tles;
739
	List	   *new_tlist = NIL;
740 741
	List	   *junk_tlist = NIL;
	Form_pg_attribute att_tup;
742
	int			attrno,
743
				next_junk_attrno,
744
				numattrs;
745
	ListCell   *temp;
746
	Bitmapset  *default_only_cols = NULL;
747 748

	/*
749 750 751 752
	 * We process the normal (non-junk) attributes by scanning the input tlist
	 * once and transferring TLEs into an array, then scanning the array to
	 * build an output tlist.  This avoids O(N^2) behavior for large numbers
	 * of attributes.
753
	 *
754 755
	 * Junk attributes are tossed into a separate list during the same tlist
	 * scan, then appended to the reconstructed tlist.
756 757
	 */
	numattrs = RelationGetNumberOfAttributes(target_relation);
758 759
	new_tles = (TargetEntry **) palloc0(numattrs * sizeof(TargetEntry *));
	next_junk_attrno = numattrs + 1;
760

761
	foreach(temp, targetList)
762
	{
763
		TargetEntry *old_tle = (TargetEntry *) lfirst(temp);
764

765
		if (!old_tle->resjunk)
766 767
		{
			/* Normal attr: stash it into new_tles[] */
768
			attrno = old_tle->resno;
769 770
			if (attrno < 1 || attrno > numattrs)
				elog(ERROR, "bogus resno %d in targetlist", attrno);
771
			att_tup = TupleDescAttr(target_relation->rd_att, attrno - 1);
772 773 774 775 776 777 778 779 780 781 782 783

			/* We can (and must) ignore deleted attributes */
			if (att_tup->attisdropped)
				continue;

			/* Merge with any prior assignment to same attribute */
			new_tles[attrno - 1] =
				process_matched_tle(old_tle,
									new_tles[attrno - 1],
									NameStr(att_tup->attname));
		}
		else
784
		{
785
			/*
786 787
			 * Copy all resjunk tlist entries to junk_tlist, and assign them
			 * resnos above the last real resno.
788
			 *
789 790
			 * Typical junk entries include ORDER BY or GROUP BY expressions
			 * (are these actually possible in an INSERT or UPDATE?), system
791 792
			 * attribute references, etc.
			 */
793

794
			/* Get the resno right, but don't copy unnecessarily */
795
			if (old_tle->resno != next_junk_attrno)
796
			{
797 798
				old_tle = flatCopyTargetEntry(old_tle);
				old_tle->resno = next_junk_attrno;
799
			}
800 801
			junk_tlist = lappend(junk_tlist, old_tle);
			next_junk_attrno++;
802
		}
803 804 805 806 807
	}

	for (attrno = 1; attrno <= numattrs; attrno++)
	{
		TargetEntry *new_tle = new_tles[attrno - 1];
808
		bool		apply_default;
809

810
		att_tup = TupleDescAttr(target_relation->rd_att, attrno - 1);
811 812 813 814

		/* We can (and must) ignore deleted attributes */
		if (att_tup->attisdropped)
			continue;
815

816
		/*
817 818 819
		 * Handle the two cases where we need to insert a default expression:
		 * it's an INSERT and there's no tlist entry for the column, or the
		 * tlist entry is a DEFAULT placeholder node.
820
		 */
Peter Eisentraut's avatar
Peter Eisentraut committed
821
		apply_default = ((new_tle == NULL && commandType == CMD_INSERT) ||
Tom Lane's avatar
Tom Lane committed
822
						 (new_tle && new_tle->expr && IsA(new_tle->expr, SetToDefault)));
Peter Eisentraut's avatar
Peter Eisentraut committed
823 824 825

		if (commandType == CMD_INSERT)
		{
826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841
			int			values_attrno = 0;

			/* Source attribute number for values that come from a VALUES RTE */
			if (values_rte && new_tle && IsA(new_tle->expr, Var))
			{
				Var		   *var = (Var *) new_tle->expr;

				if (var->varno == values_rte_index)
					values_attrno = var->varattno;
			}

			/*
			 * Can only insert DEFAULT into GENERATED ALWAYS identity columns,
			 * unless either OVERRIDING USER VALUE or OVERRIDING SYSTEM VALUE
			 * is specified.
			 */
Peter Eisentraut's avatar
Peter Eisentraut committed
842 843
			if (att_tup->attidentity == ATTRIBUTE_IDENTITY_ALWAYS && !apply_default)
			{
844 845 846
				if (override == OVERRIDING_USER_VALUE)
					apply_default = true;
				else if (override != OVERRIDING_SYSTEM_VALUE)
847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865
				{
					/*
					 * If this column's values come from a VALUES RTE, test
					 * whether it contains only SetToDefault items.  Since the
					 * VALUES list might be quite large, we arrange to only
					 * scan it once.
					 */
					if (values_attrno != 0)
					{
						if (default_only_cols == NULL)
							default_only_cols = findDefaultOnlyColumns(values_rte);

						if (bms_is_member(values_attrno, default_only_cols))
							apply_default = true;
					}

					if (!apply_default)
						ereport(ERROR,
								(errcode(ERRCODE_GENERATED_ALWAYS),
866
								 errmsg("cannot insert a non-DEFAULT value into column \"%s\"",
867 868 869 870 871
										NameStr(att_tup->attname)),
								 errdetail("Column \"%s\" is an identity column defined as GENERATED ALWAYS.",
										   NameStr(att_tup->attname)),
								 errhint("Use OVERRIDING SYSTEM VALUE to override.")));
				}
Peter Eisentraut's avatar
Peter Eisentraut committed
872 873
			}

874 875 876 877 878 879 880
			/*
			 * Although inserting into a GENERATED BY DEFAULT identity column
			 * is allowed, apply the default if OVERRIDING USER VALUE is
			 * specified.
			 */
			if (att_tup->attidentity == ATTRIBUTE_IDENTITY_BY_DEFAULT &&
				override == OVERRIDING_USER_VALUE)
Peter Eisentraut's avatar
Peter Eisentraut committed
881
				apply_default = true;
Peter Eisentraut's avatar
Peter Eisentraut committed
882

883 884 885 886
			/*
			 * Can only insert DEFAULT into generated columns, regardless of
			 * any OVERRIDING clauses.
			 */
Peter Eisentraut's avatar
Peter Eisentraut committed
887
			if (att_tup->attgenerated && !apply_default)
888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903
			{
				/*
				 * If this column's values come from a VALUES RTE, test
				 * whether it contains only SetToDefault items, as above.
				 */
				if (values_attrno != 0)
				{
					if (default_only_cols == NULL)
						default_only_cols = findDefaultOnlyColumns(values_rte);

					if (bms_is_member(values_attrno, default_only_cols))
						apply_default = true;
				}

				if (!apply_default)
					ereport(ERROR,
904 905
							(errcode(ERRCODE_GENERATED_ALWAYS),
							 errmsg("cannot insert a non-DEFAULT value into column \"%s\"",
906 907 908 909 910 911 912 913 914 915 916 917 918
									NameStr(att_tup->attname)),
							 errdetail("Column \"%s\" is a generated column.",
									   NameStr(att_tup->attname))));
			}

			/*
			 * For an INSERT from a VALUES RTE, return the attribute numbers
			 * of any VALUES columns that will no longer be used (due to the
			 * targetlist entry being replaced by a default expression).
			 */
			if (values_attrno != 0 && apply_default && unused_values_attrnos)
				*unused_values_attrnos = bms_add_member(*unused_values_attrnos,
														values_attrno);
Peter Eisentraut's avatar
Peter Eisentraut committed
919 920
		}

921 922 923 924 925
		/*
		 * Updates to identity and generated columns follow the same rules as
		 * above, except that UPDATE doesn't admit OVERRIDING clauses.  Also,
		 * the source can't be a VALUES RTE, so we needn't consider that.
		 */
Peter Eisentraut's avatar
Peter Eisentraut committed
926 927
		if (commandType == CMD_UPDATE)
		{
928 929
			if (att_tup->attidentity == ATTRIBUTE_IDENTITY_ALWAYS &&
				new_tle && !apply_default)
Peter Eisentraut's avatar
Peter Eisentraut committed
930 931
				ereport(ERROR,
						(errcode(ERRCODE_GENERATED_ALWAYS),
932 933
						 errmsg("column \"%s\" can only be updated to DEFAULT",
								NameStr(att_tup->attname)),
Peter Eisentraut's avatar
Peter Eisentraut committed
934 935
						 errdetail("Column \"%s\" is an identity column defined as GENERATED ALWAYS.",
								   NameStr(att_tup->attname))));
Peter Eisentraut's avatar
Peter Eisentraut committed
936 937 938

			if (att_tup->attgenerated && new_tle && !apply_default)
				ereport(ERROR,
939 940 941
						(errcode(ERRCODE_GENERATED_ALWAYS),
						 errmsg("column \"%s\" can only be updated to DEFAULT",
								NameStr(att_tup->attname)),
Peter Eisentraut's avatar
Peter Eisentraut committed
942 943
						 errdetail("Column \"%s\" is a generated column.",
								   NameStr(att_tup->attname))));
Peter Eisentraut's avatar
Peter Eisentraut committed
944 945
		}

Peter Eisentraut's avatar
Peter Eisentraut committed
946 947 948 949 950 951 952 953
		if (att_tup->attgenerated)
		{
			/*
			 * stored generated column will be fixed in executor
			 */
			new_tle = NULL;
		}
		else if (apply_default)
954 955 956
		{
			Node	   *new_expr;

957
			new_expr = build_column_default(target_relation, attrno);
958

959
			/*
960 961 962 963 964
			 * If there is no default (ie, default is effectively NULL), we
			 * can omit the tlist entry in the INSERT case, since the planner
			 * can insert a NULL for itself, and there's no point in spending
			 * any more rewriter cycles on the entry.  But in the UPDATE case
			 * we've got to explicitly set the column to NULL.
965 966 967 968 969 970 971 972
			 */
			if (!new_expr)
			{
				if (commandType == CMD_INSERT)
					new_tle = NULL;
				else
				{
					new_expr = (Node *) makeConst(att_tup->atttypid,
973
												  -1,
974
												  att_tup->attcollation,
975 976 977 978 979 980
												  att_tup->attlen,
												  (Datum) 0,
												  true, /* isnull */
												  att_tup->attbyval);
					/* this is to catch a NOT NULL domain constraint */
					new_expr = coerce_to_domain(new_expr,
981
												InvalidOid, -1,
982
												att_tup->atttypid,
Tom Lane's avatar
Tom Lane committed
983
												COERCION_IMPLICIT,
984
												COERCE_IMPLICIT_CAST,
985
												-1,
986
												false);
987 988 989
				}
			}

990
			if (new_expr)
991 992 993 994
				new_tle = makeTargetEntry((Expr *) new_expr,
										  attrno,
										  pstrdup(NameStr(att_tup->attname)),
										  false);
995 996 997 998 999 1000
		}

		if (new_tle)
			new_tlist = lappend(new_tlist, new_tle);
	}

1001
	pfree(new_tles);
1002

1003
	return list_concat(new_tlist, junk_tlist);
1004 1005 1006 1007 1008 1009 1010
}


/*
 * Convert a matched TLE from the original tlist into a correct new TLE.
 *
 * This routine detects and handles multiple assignments to the same target
1011
 * attribute.  (The attribute name is needed only for error messages.)
1012 1013 1014
 */
static TargetEntry *
process_matched_tle(TargetEntry *src_tle,
1015 1016
					TargetEntry *prior_tle,
					const char *attrName)
1017
{
1018
	TargetEntry *result;
1019
	CoerceToDomain *coerce_expr = NULL;
1020 1021 1022 1023
	Node	   *src_expr;
	Node	   *prior_expr;
	Node	   *src_input;
	Node	   *prior_input;
1024
	Node	   *priorbottom;
1025
	Node	   *newexpr;
1026 1027 1028 1029

	if (prior_tle == NULL)
	{
		/*
1030
		 * Normal case where this is the first assignment to the attribute.
1031 1032 1033 1034
		 */
		return src_tle;
	}

1035
	/*----------
Bruce Momjian's avatar
Bruce Momjian committed
1036
	 * Multiple assignments to same attribute.  Allow only if all are
1037
	 * FieldStore or SubscriptingRef assignment operations.  This is a bit
1038 1039 1040 1041 1042
	 * tricky because what we may actually be looking at is a nest of
	 * such nodes; consider
	 *		UPDATE tab SET col.fld1.subfld1 = x, col.fld2.subfld2 = y
	 * The two expressions produced by the parser will look like
	 *		FieldStore(col, fld1, FieldStore(placeholder, subfld1, x))
Robert Haas's avatar
Robert Haas committed
1043
	 *		FieldStore(col, fld2, FieldStore(placeholder, subfld2, y))
1044
	 * However, we can ignore the substructure and just consider the top
1045
	 * FieldStore or SubscriptingRef from each assignment, because it works to
1046 1047 1048
	 * combine these as
	 *		FieldStore(FieldStore(col, fld1,
	 *							  FieldStore(placeholder, subfld1, x)),
Robert Haas's avatar
Robert Haas committed
1049
	 *				   fld2, FieldStore(placeholder, subfld2, y))
1050 1051 1052 1053
	 * Note the leftmost expression goes on the inside so that the
	 * assignments appear to occur left-to-right.
	 *
	 * For FieldStore, instead of nesting we can generate a single
Bruce Momjian's avatar
Bruce Momjian committed
1054
	 * FieldStore with multiple target fields.  We must nest when
1055
	 * SubscriptingRefs are involved though.
1056 1057 1058
	 *
	 * As a further complication, the destination column might be a domain,
	 * resulting in each assignment containing a CoerceToDomain node over a
1059 1060 1061 1062 1063
	 * FieldStore or SubscriptingRef.  These should have matching target
	 * domains, so we strip them and reconstitute a single CoerceToDomain over
	 * the combined FieldStore/SubscriptingRef nodes.  (Notice that this has the
	 * result that the domain's checks are applied only after we do all the
	 * field or element updates, not after each one.  This is arguably desirable.)
1064
	 *----------
1065
	 */
1066 1067
	src_expr = (Node *) src_tle->expr;
	prior_expr = (Node *) prior_tle->expr;
1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079

	if (src_expr && IsA(src_expr, CoerceToDomain) &&
		prior_expr && IsA(prior_expr, CoerceToDomain) &&
		((CoerceToDomain *) src_expr)->resulttype ==
		((CoerceToDomain *) prior_expr)->resulttype)
	{
		/* we assume without checking that resulttypmod/resultcollid match */
		coerce_expr = (CoerceToDomain *) src_expr;
		src_expr = (Node *) ((CoerceToDomain *) src_expr)->arg;
		prior_expr = (Node *) ((CoerceToDomain *) prior_expr)->arg;
	}

1080 1081 1082 1083 1084
	src_input = get_assignment_input(src_expr);
	prior_input = get_assignment_input(prior_expr);
	if (src_input == NULL ||
		prior_input == NULL ||
		exprType(src_expr) != exprType(prior_expr))
1085 1086
		ereport(ERROR,
				(errcode(ERRCODE_SYNTAX_ERROR),
1087
				 errmsg("multiple assignments to same column \"%s\"",
1088
						attrName)));
1089 1090

	/*
1091
	 * Prior TLE could be a nest of assignments if we do this more than once.
1092
	 */
1093 1094 1095
	priorbottom = prior_input;
	for (;;)
	{
Bruce Momjian's avatar
Bruce Momjian committed
1096
		Node	   *newbottom = get_assignment_input(priorbottom);
1097 1098 1099 1100 1101 1102

		if (newbottom == NULL)
			break;				/* found the original Var reference */
		priorbottom = newbottom;
	}
	if (!equal(priorbottom, src_input))
1103 1104
		ereport(ERROR,
				(errcode(ERRCODE_SYNTAX_ERROR),
1105
				 errmsg("multiple assignments to same column \"%s\"",
1106
						attrName)));
1107 1108 1109 1110

	/*
	 * Looks OK to nest 'em.
	 */
1111 1112
	if (IsA(src_expr, FieldStore))
	{
Bruce Momjian's avatar
Bruce Momjian committed
1113
		FieldStore *fstore = makeNode(FieldStore);
1114 1115 1116 1117 1118 1119

		if (IsA(prior_expr, FieldStore))
		{
			/* combine the two */
			memcpy(fstore, prior_expr, sizeof(FieldStore));
			fstore->newvals =
1120 1121
				list_concat_copy(((FieldStore *) prior_expr)->newvals,
								 ((FieldStore *) src_expr)->newvals);
1122
			fstore->fieldnums =
1123 1124
				list_concat_copy(((FieldStore *) prior_expr)->fieldnums,
								 ((FieldStore *) src_expr)->fieldnums);
1125 1126 1127 1128 1129 1130 1131 1132 1133
		}
		else
		{
			/* general case, just nest 'em */
			memcpy(fstore, src_expr, sizeof(FieldStore));
			fstore->arg = (Expr *) prior_expr;
		}
		newexpr = (Node *) fstore;
	}
1134
	else if (IsA(src_expr, SubscriptingRef))
1135
	{
1136
		SubscriptingRef *sbsref = makeNode(SubscriptingRef);
1137

1138 1139 1140
		memcpy(sbsref, src_expr, sizeof(SubscriptingRef));
		sbsref->refexpr = (Expr *) prior_expr;
		newexpr = (Node *) sbsref;
1141 1142 1143
	}
	else
	{
1144
		elog(ERROR, "cannot happen");
1145 1146
		newexpr = NULL;
	}
1147

1148 1149 1150 1151 1152 1153 1154 1155 1156 1157
	if (coerce_expr)
	{
		/* put back the CoerceToDomain */
		CoerceToDomain *newcoerce = makeNode(CoerceToDomain);

		memcpy(newcoerce, coerce_expr, sizeof(CoerceToDomain));
		newcoerce->arg = (Expr *) newexpr;
		newexpr = (Node *) newcoerce;
	}

1158 1159 1160
	result = flatCopyTargetEntry(src_tle);
	result->expr = (Expr *) newexpr;
	return result;
1161 1162
}

1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176
/*
 * If node is an assignment node, return its input; else return NULL
 */
static Node *
get_assignment_input(Node *node)
{
	if (node == NULL)
		return NULL;
	if (IsA(node, FieldStore))
	{
		FieldStore *fstore = (FieldStore *) node;

		return (Node *) fstore->arg;
	}
1177
	else if (IsA(node, SubscriptingRef))
1178
	{
1179
		SubscriptingRef *sbsref = (SubscriptingRef *) node;
1180

1181
		if (sbsref->refassgnexpr == NULL)
1182
			return NULL;
1183 1184

		return (Node *) sbsref->refexpr;
1185
	}
1186

1187 1188
	return NULL;
}
1189 1190 1191 1192 1193 1194

/*
 * Make an expression tree for the default value for a column.
 *
 * If there is no default, return a NULL instead.
 */
1195
Node *
1196 1197 1198
build_column_default(Relation rel, int attrno)
{
	TupleDesc	rd_att = rel->rd_att;
1199
	Form_pg_attribute att_tup = TupleDescAttr(rd_att, attrno - 1);
1200 1201 1202 1203 1204
	Oid			atttype = att_tup->atttypid;
	int32		atttypmod = att_tup->atttypmod;
	Node	   *expr = NULL;
	Oid			exprtype;

1205 1206 1207 1208
	if (att_tup->attidentity)
	{
		NextValueExpr *nve = makeNode(NextValueExpr);

1209
		nve->seqid = getIdentitySequence(RelationGetRelid(rel), attrno, false);
1210 1211 1212 1213 1214
		nve->typeId = att_tup->atttypid;

		return (Node *) nve;
	}

1215
	/*
1216
	 * If relation has a default for this column, fetch that expression.
1217
	 */
1218
	if (att_tup->atthasdef)
1219
	{
1220
		if (rd_att->constr && rd_att->constr->num_defval > 0)
1221
		{
1222 1223 1224 1225
			AttrDefault *defval = rd_att->constr->defval;
			int			ndef = rd_att->constr->num_defval;

			while (--ndef >= 0)
1226
			{
1227 1228 1229 1230 1231 1232
				if (attrno == defval[ndef].adnum)
				{
					/* Found it, convert string representation to node tree. */
					expr = stringToNode(defval[ndef].adbin);
					break;
				}
1233 1234
			}
		}
1235 1236 1237
		if (expr == NULL)
			elog(ERROR, "default expression not found for attribute %d of relation \"%s\"",
				 attrno, RelationGetRelationName(rel));
1238 1239
	}

Peter Eisentraut's avatar
Peter Eisentraut committed
1240 1241 1242 1243 1244
	/*
	 * No per-column default, so look for a default for the type itself.  But
	 * not for generated columns.
	 */
	if (expr == NULL && !att_tup->attgenerated)
1245
		expr = get_typdefault(atttype);
1246 1247 1248 1249 1250

	if (expr == NULL)
		return NULL;			/* No default anywhere */

	/*
1251 1252
	 * Make sure the value is coerced to the target column type; this will
	 * generally be true already, but there seem to be some corner cases
1253 1254
	 * involving domain defaults where it might not be true. This should match
	 * the parser's processing of non-defaulted expressions --- see
1255
	 * transformAssignedExpr().
1256 1257 1258
	 */
	exprtype = exprType(expr);

Bruce Momjian's avatar
Bruce Momjian committed
1259
	expr = coerce_to_target_type(NULL,	/* no UNKNOWN params here */
1260
								 expr, exprtype,
1261 1262
								 atttype, atttypmod,
								 COERCION_ASSIGNMENT,
1263 1264
								 COERCE_IMPLICIT_CAST,
								 -1);
1265
	if (expr == NULL)
1266 1267 1268 1269 1270 1271 1272
		ereport(ERROR,
				(errcode(ERRCODE_DATATYPE_MISMATCH),
				 errmsg("column \"%s\" is of type %s"
						" but default expression is of type %s",
						NameStr(att_tup->attname),
						format_type_be(atttype),
						format_type_be(exprtype)),
Tom Lane's avatar
Tom Lane committed
1273
				 errhint("You will need to rewrite or cast the expression.")));
1274 1275 1276 1277 1278

	return expr;
}


1279 1280 1281 1282 1283 1284 1285 1286
/* Does VALUES RTE contain any SetToDefault items? */
static bool
searchForDefault(RangeTblEntry *rte)
{
	ListCell   *lc;

	foreach(lc, rte->values_lists)
	{
Bruce Momjian's avatar
Bruce Momjian committed
1287 1288
		List	   *sublist = (List *) lfirst(lc);
		ListCell   *lc2;
1289 1290 1291

		foreach(lc2, sublist)
		{
Bruce Momjian's avatar
Bruce Momjian committed
1292
			Node	   *col = (Node *) lfirst(lc2);
1293 1294 1295 1296 1297 1298 1299 1300

			if (IsA(col, SetToDefault))
				return true;
		}
	}
	return false;
}

1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356

/*
 * Search a VALUES RTE for columns that contain only SetToDefault items,
 * returning a Bitmapset containing the attribute numbers of any such columns.
 */
static Bitmapset *
findDefaultOnlyColumns(RangeTblEntry *rte)
{
	Bitmapset  *default_only_cols = NULL;
	ListCell   *lc;

	foreach(lc, rte->values_lists)
	{
		List	   *sublist = (List *) lfirst(lc);
		ListCell   *lc2;
		int			i;

		if (default_only_cols == NULL)
		{
			/* Populate the initial result bitmap from the first row */
			i = 0;
			foreach(lc2, sublist)
			{
				Node	   *col = (Node *) lfirst(lc2);

				i++;
				if (IsA(col, SetToDefault))
					default_only_cols = bms_add_member(default_only_cols, i);
			}
		}
		else
		{
			/* Update the result bitmap from this next row */
			i = 0;
			foreach(lc2, sublist)
			{
				Node	   *col = (Node *) lfirst(lc2);

				i++;
				if (!IsA(col, SetToDefault))
					default_only_cols = bms_del_member(default_only_cols, i);
			}
		}

		/*
		 * If no column in the rows read so far contains only DEFAULT items,
		 * we are done.
		 */
		if (bms_is_empty(default_only_cols))
			break;
	}

	return default_only_cols;
}


1357 1358 1359
/*
 * When processing INSERT ... VALUES with a VALUES RTE (ie, multiple VALUES
 * lists), we have to replace any DEFAULT items in the VALUES lists with
Tom Lane's avatar
Tom Lane committed
1360 1361
 * the appropriate default expressions.  The other aspects of targetlist
 * rewriting need be applied only to the query's targetlist proper.
1362
 *
1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383
 * For an auto-updatable view, each DEFAULT item in the VALUES list is
 * replaced with the default from the view, if it has one.  Otherwise it is
 * left untouched so that the underlying base relation's default can be
 * applied instead (when we later recurse to here after rewriting the query
 * to refer to the base relation instead of the view).
 *
 * For other types of relation, including rule- and trigger-updatable views,
 * all DEFAULT items are replaced, and if the target relation doesn't have a
 * default, the value is explicitly set to NULL.
 *
 * Additionally, if force_nulls is true, the target relation's defaults are
 * ignored and all DEFAULT items in the VALUES list are explicitly set to
 * NULL, regardless of the target relation's type.  This is used for the
 * product queries generated by DO ALSO rules attached to an auto-updatable
 * view, for which we will have already called this function with force_nulls
 * false.  For these product queries, we must then force any remaining DEFAULT
 * items to NULL to provide concrete values for the rule actions.
 * Essentially, this is a mix of the 2 cases above --- the original query is
 * an insert into an auto-updatable view, and the product queries are inserts
 * into a rule-updatable view.
 *
1384 1385 1386 1387 1388 1389 1390 1391 1392 1393
 * Finally, if a DEFAULT item is found in a column mentioned in unused_cols,
 * it is explicitly set to NULL.  This happens for columns in the VALUES RTE
 * whose corresponding targetlist entries have already been replaced with the
 * relation's default expressions, so that any values in those columns of the
 * VALUES RTE are no longer used.  This can happen for identity and generated
 * columns (if INSERT ... OVERRIDING USER VALUE is used, or all the values to
 * be inserted are DEFAULT).  In principle we could replace all entries in
 * such a column with NULL, whether DEFAULT or not; but it doesn't seem worth
 * the trouble.
 *
1394 1395 1396
 * Note that we may have subscripted or field assignment targetlist entries,
 * as well as more complex expressions from already-replaced DEFAULT items if
 * we have recursed to here for an auto-updatable view. However, it ought to
1397 1398 1399 1400
 * be impossible for such entries to have DEFAULTs assigned to them, except
 * for unused columns, as described above --- we should only have to replace
 * DEFAULT items for targetlist entries that contain simple Vars referencing
 * the VALUES RTE, or which are no longer referred to by the targetlist.
1401 1402 1403
 *
 * Returns true if all DEFAULT items were replaced, and false if some were
 * left untouched.
1404
 */
1405
static bool
1406
rewriteValuesRTE(Query *parsetree, RangeTblEntry *rte, int rti,
1407 1408
				 Relation target_relation, bool force_nulls,
				 Bitmapset *unused_cols)
1409 1410 1411
{
	List	   *newValues;
	ListCell   *lc;
1412 1413
	bool		isAutoUpdatableView;
	bool		allReplaced;
1414 1415
	int			numattrs;
	int		   *attrnos;
1416 1417 1418 1419 1420

	/*
	 * Rebuilding all the lists is a pretty expensive proposition in a big
	 * VALUES list, and it's a waste of time if there aren't any DEFAULT
	 * placeholders.  So first scan to see if there are any.
1421 1422 1423
	 *
	 * We skip this check if force_nulls is true, because we know that there
	 * are DEFAULT items present in that case.
1424
	 */
1425 1426
	if (!force_nulls && !searchForDefault(rte))
		return true;			/* nothing to do */
1427

1428 1429 1430 1431
	/*
	 * Scan the targetlist for entries referring to the VALUES RTE, and note
	 * the target attributes. As noted above, we should only need to do this
	 * for targetlist entries containing simple Vars --- nothing else in the
1432 1433
	 * VALUES RTE should contain DEFAULT items (except possibly for unused
	 * columns), and we complain if such a thing does occur.
1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454
	 */
	numattrs = list_length(linitial(rte->values_lists));
	attrnos = (int *) palloc0(numattrs * sizeof(int));

	foreach(lc, parsetree->targetList)
	{
		TargetEntry *tle = (TargetEntry *) lfirst(lc);

		if (IsA(tle->expr, Var))
		{
			Var		   *var = (Var *) tle->expr;

			if (var->varno == rti)
			{
				int			attrno = var->varattno;

				Assert(attrno >= 1 && attrno <= numattrs);
				attrnos[attrno - 1] = tle->resno;
			}
		}
	}
1455

1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497
	/*
	 * Check if the target relation is an auto-updatable view, in which case
	 * unresolved defaults will be left untouched rather than being set to
	 * NULL.  If force_nulls is true, we always set DEFAULT items to NULL, so
	 * skip this check in that case --- it isn't an auto-updatable view.
	 */
	isAutoUpdatableView = false;
	if (!force_nulls &&
		target_relation->rd_rel->relkind == RELKIND_VIEW &&
		!view_has_instead_trigger(target_relation, CMD_INSERT))
	{
		List	   *locks;
		bool		hasUpdate;
		bool		found;
		ListCell   *l;

		/* Look for an unconditional DO INSTEAD rule */
		locks = matchLocks(CMD_INSERT, target_relation->rd_rules,
						   parsetree->resultRelation, parsetree, &hasUpdate);

		found = false;
		foreach(l, locks)
		{
			RewriteRule *rule_lock = (RewriteRule *) lfirst(l);

			if (rule_lock->isInstead &&
				rule_lock->qual == NULL)
			{
				found = true;
				break;
			}
		}

		/*
		 * If we didn't find an unconditional DO INSTEAD rule, assume that the
		 * view is auto-updatable.  If it isn't, rewriteTargetView() will
		 * throw an error.
		 */
		if (!found)
			isAutoUpdatableView = true;
	}

1498
	newValues = NIL;
1499
	allReplaced = true;
1500 1501
	foreach(lc, rte->values_lists)
	{
Bruce Momjian's avatar
Bruce Momjian committed
1502 1503 1504
		List	   *sublist = (List *) lfirst(lc);
		List	   *newList = NIL;
		ListCell   *lc2;
1505 1506 1507
		int			i;

		Assert(list_length(sublist) == numattrs);
1508

1509 1510
		i = 0;
		foreach(lc2, sublist)
1511
		{
Bruce Momjian's avatar
Bruce Momjian committed
1512
			Node	   *col = (Node *) lfirst(lc2);
1513
			int			attrno = attrnos[i++];
1514 1515 1516 1517 1518 1519

			if (IsA(col, SetToDefault))
			{
				Form_pg_attribute att_tup;
				Node	   *new_expr;

1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535
				/*
				 * If this column isn't used, just replace the DEFAULT with
				 * NULL (attrno will be 0 in this case because the targetlist
				 * entry will have been replaced by the default expression).
				 */
				if (bms_is_member(i, unused_cols))
				{
					SetToDefault *def = (SetToDefault *) col;

					newList = lappend(newList,
									  makeNullConst(def->typeId,
													def->typeMod,
													def->collation));
					continue;
				}

1536 1537
				if (attrno == 0)
					elog(ERROR, "cannot set value in column %d to DEFAULT", i);
1538
				att_tup = TupleDescAttr(target_relation->rd_att, attrno - 1);
1539

1540
				if (!force_nulls && !att_tup->attisdropped)
1541 1542
					new_expr = build_column_default(target_relation, attrno);
				else
Bruce Momjian's avatar
Bruce Momjian committed
1543
					new_expr = NULL;	/* force a NULL if dropped */
1544 1545 1546

				/*
				 * If there is no default (ie, default is effectively NULL),
1547 1548
				 * we've got to explicitly set the column to NULL, unless the
				 * target relation is an auto-updatable view.
1549 1550 1551
				 */
				if (!new_expr)
				{
1552 1553 1554 1555 1556 1557 1558 1559
					if (isAutoUpdatableView)
					{
						/* Leave the value untouched */
						newList = lappend(newList, col);
						allReplaced = false;
						continue;
					}

1560
					new_expr = (Node *) makeConst(att_tup->atttypid,
1561
												  -1,
1562
												  att_tup->attcollation,
1563 1564 1565 1566 1567 1568 1569 1570
												  att_tup->attlen,
												  (Datum) 0,
												  true, /* isnull */
												  att_tup->attbyval);
					/* this is to catch a NOT NULL domain constraint */
					new_expr = coerce_to_domain(new_expr,
												InvalidOid, -1,
												att_tup->atttypid,
Tom Lane's avatar
Tom Lane committed
1571
												COERCION_IMPLICIT,
1572
												COERCE_IMPLICIT_CAST,
1573
												-1,
1574 1575 1576 1577 1578 1579 1580 1581 1582 1583
												false);
				}
				newList = lappend(newList, new_expr);
			}
			else
				newList = lappend(newList, col);
		}
		newValues = lappend(newValues, newList);
	}
	rte->values_lists = newValues;
1584

1585 1586
	pfree(attrnos);

1587
	return allReplaced;
1588 1589 1590
}


1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626
/*
 * Record in target_rte->extraUpdatedCols the indexes of any generated columns
 * that depend on any columns mentioned in target_rte->updatedCols.
 */
void
fill_extraUpdatedCols(RangeTblEntry *target_rte, Relation target_relation)
{
	TupleDesc	tupdesc = RelationGetDescr(target_relation);
	TupleConstr *constr = tupdesc->constr;

	target_rte->extraUpdatedCols = NULL;

	if (constr && constr->has_generated_stored)
	{
		for (int i = 0; i < constr->num_defval; i++)
		{
			AttrDefault *defval = &constr->defval[i];
			Node	   *expr;
			Bitmapset  *attrs_used = NULL;

			/* skip if not generated column */
			if (!TupleDescAttr(tupdesc, defval->adnum - 1)->attgenerated)
				continue;

			/* identify columns this generated column depends on */
			expr = stringToNode(defval->adbin);
			pull_varattnos(expr, 1, &attrs_used);

			if (bms_overlap(target_rte->updatedCols, attrs_used))
				target_rte->extraUpdatedCols =
					bms_add_member(target_rte->extraUpdatedCols,
								   defval->adnum - FirstLowInvalidHeapAttributeNumber);
		}
	}
}

Tom Lane's avatar
Tom Lane committed
1627

1628
/*
1629 1630
 * matchLocks -
 *	  match the list of locks and returns the matching rules
1631
 */
1632 1633 1634 1635
static List *
matchLocks(CmdType event,
		   RuleLock *rulelocks,
		   int varno,
1636 1637
		   Query *parsetree,
		   bool *hasUpdate)
1638
{
1639
	List	   *matching_locks = NIL;
1640 1641
	int			nlocks;
	int			i;
1642

1643 1644
	if (rulelocks == NULL)
		return NIL;
1645

1646
	if (parsetree->commandType != CMD_SELECT)
1647
	{
1648 1649
		if (parsetree->resultRelation != varno)
			return NIL;
1650
	}
1651

1652
	nlocks = rulelocks->numLocks;
1653

1654
	for (i = 0; i < nlocks; i++)
Bruce Momjian's avatar
Bruce Momjian committed
1655
	{
1656
		RewriteRule *oneLock = rulelocks->rules[i];
1657

1658 1659 1660
		if (oneLock->event == CMD_UPDATE)
			*hasUpdate = true;

1661
		/*
1662 1663 1664 1665
		 * Suppress ON INSERT/UPDATE/DELETE rules that are disabled or
		 * configured to not fire during the current sessions replication
		 * role. ON SELECT rules will always be applied in order to keep views
		 * working even in LOCAL or REPLICA role.
1666 1667 1668 1669 1670 1671 1672 1673 1674
		 */
		if (oneLock->event != CMD_SELECT)
		{
			if (SessionReplicationRole == SESSION_REPLICATION_ROLE_REPLICA)
			{
				if (oneLock->enabled == RULE_FIRES_ON_ORIGIN ||
					oneLock->enabled == RULE_DISABLED)
					continue;
			}
1675
			else				/* ORIGIN or LOCAL ROLE */
1676 1677 1678 1679 1680 1681 1682
			{
				if (oneLock->enabled == RULE_FIRES_ON_REPLICA ||
					oneLock->enabled == RULE_DISABLED)
					continue;
			}
		}

1683
		if (oneLock->event == event)
1684
		{
1685
			if (parsetree->commandType != CMD_SELECT ||
1686
				rangeTableEntry_used((Node *) parsetree, varno, 0))
1687
				matching_locks = lappend(matching_locks, oneLock);
1688
		}
1689
	}
1690

1691
	return matching_locks;
1692 1693
}

1694

1695 1696 1697
/*
 * ApplyRetrieveRule - expand an ON SELECT rule
 */
1698 1699 1700 1701 1702
static Query *
ApplyRetrieveRule(Query *parsetree,
				  RewriteRule *rule,
				  int rt_index,
				  Relation relation,
1703
				  List *activeRIRs)
1704 1705 1706 1707
{
	Query	   *rule_action;
	RangeTblEntry *rte,
			   *subrte;
1708
	RowMarkClause *rc;
1709

1710
	if (list_length(rule->actions) != 1)
1711
		elog(ERROR, "expected just one rule action");
1712
	if (rule->qual != NULL)
1713
		elog(ERROR, "cannot handle qualified ON SELECT rule");
1714

Tom Lane's avatar
Tom Lane committed
1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727
	if (rt_index == parsetree->resultRelation)
	{
		/*
		 * We have a view as the result relation of the query, and it wasn't
		 * rewritten by any rule.  This case is supported if there is an
		 * INSTEAD OF trigger that will trap attempts to insert/update/delete
		 * view rows.  The executor will check that; for the moment just plow
		 * ahead.  We have two cases:
		 *
		 * For INSERT, we needn't do anything.  The unmodified RTE will serve
		 * fine as the result relation.
		 *
		 * For UPDATE/DELETE, we need to expand the view so as to have source
Bruce Momjian's avatar
Bruce Momjian committed
1728
		 * data for the operation.  But we also need an unmodified RTE to
Tom Lane's avatar
Tom Lane committed
1729
		 * serve as the target.  So, copy the RTE and add the copy to the
Bruce Momjian's avatar
Bruce Momjian committed
1730
		 * rangetable.  Note that the copy does not get added to the jointree.
1731 1732
		 * Also note that there's a hack in fireRIRrules to avoid calling this
		 * function again when it arrives at the copied RTE.
Tom Lane's avatar
Tom Lane committed
1733 1734 1735 1736 1737 1738 1739
		 */
		if (parsetree->commandType == CMD_INSERT)
			return parsetree;
		else if (parsetree->commandType == CMD_UPDATE ||
				 parsetree->commandType == CMD_DELETE)
		{
			RangeTblEntry *newrte;
1740 1741
			Var		   *var;
			TargetEntry *tle;
Tom Lane's avatar
Tom Lane committed
1742 1743 1744 1745 1746 1747 1748

			rte = rt_fetch(rt_index, parsetree->rtable);
			newrte = copyObject(rte);
			parsetree->rtable = lappend(parsetree->rtable, newrte);
			parsetree->resultRelation = list_length(parsetree->rtable);

			/*
1749 1750 1751
			 * There's no need to do permissions checks twice, so wipe out the
			 * permissions info for the original RTE (we prefer to keep the
			 * bits set on the result RTE).
Tom Lane's avatar
Tom Lane committed
1752 1753 1754 1755
			 */
			rte->requiredPerms = 0;
			rte->checkAsUser = InvalidOid;
			rte->selectedCols = NULL;
1756 1757
			rte->insertedCols = NULL;
			rte->updatedCols = NULL;
1758
			rte->extraUpdatedCols = NULL;
Tom Lane's avatar
Tom Lane committed
1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772

			/*
			 * For the most part, Vars referencing the view should remain as
			 * they are, meaning that they implicitly represent OLD values.
			 * But in the RETURNING list if any, we want such Vars to
			 * represent NEW values, so change them to reference the new RTE.
			 *
			 * Since ChangeVarNodes scribbles on the tree in-place, copy the
			 * RETURNING list first for safety.
			 */
			parsetree->returningList = copyObject(parsetree->returningList);
			ChangeVarNodes((Node *) parsetree->returningList, rt_index,
						   parsetree->resultRelation, 0);

1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786
			/*
			 * To allow the executor to compute the original view row to pass
			 * to the INSTEAD OF trigger, we add a resjunk whole-row Var
			 * referencing the original RTE.  This will later get expanded
			 * into a RowExpr computing all the OLD values of the view row.
			 */
			var = makeWholeRowVar(rte, rt_index, 0, false);
			tle = makeTargetEntry((Expr *) var,
								  list_length(parsetree->targetList) + 1,
								  pstrdup("wholerow"),
								  true);

			parsetree->targetList = lappend(parsetree->targetList, tle);

Tom Lane's avatar
Tom Lane committed
1787 1788 1789 1790 1791 1792 1793
			/* Now, continue with expanding the original view RTE */
		}
		else
			elog(ERROR, "unrecognized commandType: %d",
				 (int) parsetree->commandType);
	}

1794
	/*
1795 1796 1797 1798 1799
	 * Check if there's a FOR [KEY] UPDATE/SHARE clause applying to this view.
	 *
	 * Note: we needn't explicitly consider any such clauses appearing in
	 * ancestor query levels; their effects have already been pushed down to
	 * here by markQueryForLocking, and will be reflected in "rc".
1800 1801 1802
	 */
	rc = get_parse_rowmark(parsetree, rt_index);

1803
	/*
1804
	 * Make a modifiable copy of the view query, and acquire needed locks on
1805 1806
	 * the relations it mentions.  Force at least RowShareLock for all such
	 * rels if there's a FOR [KEY] UPDATE/SHARE clause affecting this view.
1807
	 */
1808
	rule_action = copyObject(linitial(rule->actions));
1809

1810
	AcquireRewriteLocks(rule_action, true, (rc != NULL));
1811

1812 1813 1814 1815 1816 1817 1818 1819 1820
	/*
	 * If FOR [KEY] UPDATE/SHARE of view, mark all the contained tables as
	 * implicit FOR [KEY] UPDATE/SHARE, the same as the parser would have done
	 * if the view's subquery had been written out explicitly.
	 */
	if (rc != NULL)
		markQueryForLocking(rule_action, (Node *) rule_action->jointree,
							rc->strength, rc->waitPolicy, true);

1821 1822
	/*
	 * Recursively expand any view references inside the view.
1823 1824 1825 1826 1827 1828
	 *
	 * Note: this must happen after markQueryForLocking.  That way, any UPDATE
	 * permission bits needed for sub-views are initially applied to their
	 * RTE_RELATION RTEs by markQueryForLocking, and then transferred to their
	 * OLD rangetable entries by the action below (in a recursive call of this
	 * routine).
1829
	 */
1830
	rule_action = fireRIRrules(rule_action, activeRIRs);
1831

1832
	/*
1833 1834
	 * Now, plug the view query in as a subselect, converting the relation's
	 * original RTE to a subquery RTE.
1835
	 */
1836
	rte = rt_fetch(rt_index, parsetree->rtable);
1837

1838
	rte->rtekind = RTE_SUBQUERY;
1839
	rte->subquery = rule_action;
1840 1841 1842 1843
	rte->security_barrier = RelationIsSecurityView(relation);
	/* Clear fields that should not be set in a subquery RTE */
	rte->relid = InvalidOid;
	rte->relkind = 0;
1844
	rte->rellockmode = 0;
1845
	rte->tablesample = NULL;
1846
	rte->inh = false;			/* must not be set for a subquery */
1847

1848
	/*
1849
	 * We move the view's permission check data down to its rangetable. The
1850
	 * checks will actually be done against the OLD entry therein.
1851
	 */
1852 1853
	subrte = rt_fetch(PRS2_OLD_VARNO, rule_action->rtable);
	Assert(subrte->relid == relation->rd_id);
1854
	subrte->requiredPerms = rte->requiredPerms;
1855
	subrte->checkAsUser = rte->checkAsUser;
1856
	subrte->selectedCols = rte->selectedCols;
1857 1858
	subrte->insertedCols = rte->insertedCols;
	subrte->updatedCols = rte->updatedCols;
Peter Eisentraut's avatar
Peter Eisentraut committed
1859
	subrte->extraUpdatedCols = rte->extraUpdatedCols;
1860

1861
	rte->requiredPerms = 0;		/* no permission check on subquery itself */
1862
	rte->checkAsUser = InvalidOid;
1863
	rte->selectedCols = NULL;
1864 1865
	rte->insertedCols = NULL;
	rte->updatedCols = NULL;
Peter Eisentraut's avatar
Peter Eisentraut committed
1866
	rte->extraUpdatedCols = NULL;
1867

1868
	return parsetree;
1869 1870
}

1871
/*
1872
 * Recursively mark all relations used by a view as FOR [KEY] UPDATE/SHARE.
1873 1874 1875 1876
 *
 * This may generate an invalid query, eg if some sub-query uses an
 * aggregate.  We leave it to the planner to detect that.
 *
1877 1878 1879 1880
 * NB: this must agree with the parser's transformLockingClause() routine.
 * However, unlike the parser we have to be careful not to mark a view's
 * OLD and NEW rels for updating.  The best way to handle that seems to be
 * to scan the jointree to determine which rels are used.
1881 1882
 */
static void
1883
markQueryForLocking(Query *qry, Node *jtnode,
1884 1885
					LockClauseStrength strength, LockWaitPolicy waitPolicy,
					bool pushedDown)
1886
{
1887 1888 1889
	if (jtnode == NULL)
		return;
	if (IsA(jtnode, RangeTblRef))
1890
	{
1891 1892
		int			rti = ((RangeTblRef *) jtnode)->rtindex;
		RangeTblEntry *rte = rt_fetch(rti, qry->rtable);
1893

1894
		if (rte->rtekind == RTE_RELATION)
1895
		{
1896
			applyLockingClause(qry, rti, strength, waitPolicy, pushedDown);
Tom Lane's avatar
Tom Lane committed
1897
			rte->requiredPerms |= ACL_SELECT_FOR_UPDATE;
1898
		}
1899 1900
		else if (rte->rtekind == RTE_SUBQUERY)
		{
1901
			applyLockingClause(qry, rti, strength, waitPolicy, pushedDown);
Tom Lane's avatar
Tom Lane committed
1902
			/* FOR UPDATE/SHARE of subquery is propagated to subquery's rels */
1903
			markQueryForLocking(rte->subquery, (Node *) rte->subquery->jointree,
1904
								strength, waitPolicy, true);
1905
		}
1906
		/* other RTE types are unaffected by FOR UPDATE */
1907
	}
1908 1909 1910 1911 1912 1913
	else if (IsA(jtnode, FromExpr))
	{
		FromExpr   *f = (FromExpr *) jtnode;
		ListCell   *l;

		foreach(l, f->fromlist)
1914
			markQueryForLocking(qry, lfirst(l), strength, waitPolicy, pushedDown);
1915 1916 1917 1918 1919
	}
	else if (IsA(jtnode, JoinExpr))
	{
		JoinExpr   *j = (JoinExpr *) jtnode;

1920 1921
		markQueryForLocking(qry, j->larg, strength, waitPolicy, pushedDown);
		markQueryForLocking(qry, j->rarg, strength, waitPolicy, pushedDown);
1922 1923 1924 1925
	}
	else
		elog(ERROR, "unrecognized node type: %d",
			 (int) nodeTag(jtnode));
1926 1927
}

1928

1929
/*
1930 1931 1932
 * fireRIRonSubLink -
 *	Apply fireRIRrules() to each SubLink (subselect in expression) found
 *	in the given tree.
1933 1934
 *
 * NOTE: although this has the form of a walker, we cheat and modify the
Bruce Momjian's avatar
Bruce Momjian committed
1935
 * SubLink nodes in-place.  It is caller's responsibility to ensure that
1936
 * no unwanted side-effects occur!
1937 1938 1939 1940
 *
 * This is unlike most of the other routines that recurse into subselects,
 * because we must take control at the SubLink node in order to replace
 * the SubLink's subselect link with the possibly-rewritten subquery.
1941 1942
 */
static bool
1943
fireRIRonSubLink(Node *node, List *activeRIRs)
1944 1945
{
	if (node == NULL)
1946 1947
		return false;
	if (IsA(node, SubLink))
Bruce Momjian's avatar
Bruce Momjian committed
1948
	{
1949 1950 1951
		SubLink    *sub = (SubLink *) node;

		/* Do what we came for */
1952
		sub->subselect = (Node *) fireRIRrules((Query *) sub->subselect,
1953
											   activeRIRs);
1954
		/* Fall through to process lefthand args of SubLink */
1955
	}
1956

1957
	/*
1958 1959
	 * Do NOT recurse into Query nodes, because fireRIRrules already processed
	 * subselects of subselects for us.
1960
	 */
1961
	return expression_tree_walker(node, fireRIRonSubLink,
1962
								  (void *) activeRIRs);
1963 1964 1965 1966 1967
}


/*
 * fireRIRrules -
1968 1969 1970 1971
 *	Apply all RIR rules on each rangetable entry in the given query
 *
 * activeRIRs is a list of the OIDs of views we're already processing RIR
 * rules for, used to detect/reject recursion.
1972 1973
 */
static Query *
1974
fireRIRrules(Query *parsetree, List *activeRIRs)
1975
{
Tom Lane's avatar
Tom Lane committed
1976
	int			origResultRelation = parsetree->resultRelation;
Bruce Momjian's avatar
Bruce Momjian committed
1977
	int			rt_index;
1978
	ListCell   *lc;
1979

1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996
	/*
	 * Expand SEARCH and CYCLE clauses in CTEs.
	 *
	 * This is just a convenient place to do this, since we are already
	 * looking at each Query.
	 */
	foreach(lc, parsetree->cteList)
	{
		CommonTableExpr *cte = lfirst_node(CommonTableExpr, lc);

		if (cte->search_clause || cte->cycle_clause)
		{
			cte = rewriteSearchAndCycle(cte);
			lfirst(lc) = cte;
		}
	}

1997
	/*
1998 1999
	 * don't try to convert this into a foreach loop, because rtable list can
	 * get changed each time through...
2000
	 */
2001
	rt_index = 0;
2002
	while (rt_index < list_length(parsetree->rtable))
Bruce Momjian's avatar
Bruce Momjian committed
2003
	{
2004 2005 2006 2007 2008 2009 2010
		RangeTblEntry *rte;
		Relation	rel;
		List	   *locks;
		RuleLock   *rules;
		RewriteRule *rule;
		int			i;

2011 2012
		++rt_index;

2013
		rte = rt_fetch(rt_index, parsetree->rtable);
2014

2015
		/*
2016 2017
		 * A subquery RTE can't have associated rules, so there's nothing to
		 * do to this level of the query, but we must recurse into the
2018 2019
		 * subquery to expand any rule references in it.
		 */
2020
		if (rte->rtekind == RTE_SUBQUERY)
2021
		{
2022
			rte->subquery = fireRIRrules(rte->subquery, activeRIRs);
2023 2024 2025
			continue;
		}

2026 2027 2028 2029 2030 2031
		/*
		 * Joins and other non-relation RTEs can be ignored completely.
		 */
		if (rte->rtekind != RTE_RELATION)
			continue;

2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044
		/*
		 * Always ignore RIR rules for materialized views referenced in
		 * queries.  (This does not prevent refreshing MVs, since they aren't
		 * referenced in their own query definitions.)
		 *
		 * Note: in the future we might want to allow MVs to be conditionally
		 * expanded as if they were regular views, if they are not scannable.
		 * In that case this test would need to be postponed till after we've
		 * opened the rel, so that we could check its state.
		 */
		if (rte->relkind == RELKIND_MATVIEW)
			continue;

2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055
		/*
		 * In INSERT ... ON CONFLICT, ignore the EXCLUDED pseudo-relation;
		 * even if it points to a view, we needn't expand it, and should not
		 * because we want the RTE to remain of RTE_RELATION type.  Otherwise,
		 * it would get changed to RTE_SUBQUERY type, which is an
		 * untested/unsupported situation.
		 */
		if (parsetree->onConflict &&
			rt_index == parsetree->onConflict->exclRelIndex)
			continue;

2056
		/*
2057 2058 2059
		 * If the table is not referenced in the query, then we ignore it.
		 * This prevents infinite expansion loop due to new rtable entries
		 * inserted by expansion of a rule. A table is referenced if it is
2060 2061
		 * part of the join set (a source table), or is referenced by any Var
		 * nodes, or is the result table.
2062
		 */
2063 2064
		if (rt_index != parsetree->resultRelation &&
			!rangeTableEntry_used((Node *) parsetree, rt_index, 0))
2065
			continue;
Bruce Momjian's avatar
Bruce Momjian committed
2066

Tom Lane's avatar
Tom Lane committed
2067 2068 2069 2070 2071 2072 2073 2074
		/*
		 * Also, if this is a new result relation introduced by
		 * ApplyRetrieveRule, we don't want to do anything more with it.
		 */
		if (rt_index == parsetree->resultRelation &&
			rt_index != origResultRelation)
			continue;

2075
		/*
2076 2077
		 * We can use NoLock here since either the parser or
		 * AcquireRewriteLocks should have locked the rel already.
2078
		 */
2079
		rel = table_open(rte->relid, NoLock);
2080 2081 2082 2083

		/*
		 * Collect the RIR rules that we must apply
		 */
2084
		rules = rel->rd_rules;
2085
		if (rules != NULL)
Bruce Momjian's avatar
Bruce Momjian committed
2086
		{
2087 2088 2089 2090 2091 2092
			locks = NIL;
			for (i = 0; i < rules->numLocks; i++)
			{
				rule = rules->rules[i];
				if (rule->event != CMD_SELECT)
					continue;
Bruce Momjian's avatar
Bruce Momjian committed
2093

2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108
				locks = lappend(locks, rule);
			}

			/*
			 * If we found any, apply them --- but first check for recursion!
			 */
			if (locks != NIL)
			{
				ListCell   *l;

				if (list_member_oid(activeRIRs, RelationGetRelid(rel)))
					ereport(ERROR,
							(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
							 errmsg("infinite recursion detected in rules for relation \"%s\"",
									RelationGetRelationName(rel))));
2109
				activeRIRs = lappend_oid(activeRIRs, RelationGetRelid(rel));
2110 2111 2112 2113 2114 2115 2116 2117 2118

				foreach(l, locks)
				{
					rule = lfirst(l);

					parsetree = ApplyRetrieveRule(parsetree,
												  rule,
												  rt_index,
												  rel,
2119
												  activeRIRs);
2120
				}
2121

2122
				activeRIRs = list_delete_last(activeRIRs);
2123 2124
			}
		}
2125

2126
		table_close(rel, NoLock);
2127 2128
	}

2129 2130 2131 2132 2133 2134
	/* Recurse into subqueries in WITH */
	foreach(lc, parsetree->cteList)
	{
		CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc);

		cte->ctequery = (Node *)
2135
			fireRIRrules((Query *) cte->ctequery, activeRIRs);
2136 2137
	}

2138
	/*
2139
	 * Recurse into sublink subqueries, too.  But we already did the ones in
2140
	 * the rtable and cteList.
2141 2142
	 */
	if (parsetree->hasSubLinks)
2143
		query_tree_walker(parsetree, fireRIRonSubLink, (void *) activeRIRs,
2144
						  QTW_IGNORE_RC_SUBQUERIES);
2145

2146
	/*
2147
	 * Apply any row-level security policies.  We do this last because it
2148
	 * requires special recursion detection if the new quals have sublink
Bruce Momjian's avatar
Bruce Momjian committed
2149 2150
	 * subqueries, and if we did it in the loop above query_tree_walker would
	 * then recurse into those quals a second time.
2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165
	 */
	rt_index = 0;
	foreach(lc, parsetree->rtable)
	{
		RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc);
		Relation	rel;
		List	   *securityQuals;
		List	   *withCheckOptions;
		bool		hasRowSecurity;
		bool		hasSubLinks;

		++rt_index;

		/* Only normal relations can have RLS policies */
		if (rte->rtekind != RTE_RELATION ||
2166
			(rte->relkind != RELKIND_RELATION &&
Tom Lane's avatar
Tom Lane committed
2167
			 rte->relkind != RELKIND_PARTITIONED_TABLE))
2168 2169
			continue;

2170
		rel = table_open(rte->relid, NoLock);
2171 2172 2173 2174

		/*
		 * Fetch any new security quals that must be applied to this RTE.
		 */
Stephen Frost's avatar
Stephen Frost committed
2175 2176
		get_row_security_policies(parsetree, rte, rt_index,
								  &securityQuals, &withCheckOptions,
2177 2178 2179 2180 2181 2182
								  &hasRowSecurity, &hasSubLinks);

		if (securityQuals != NIL || withCheckOptions != NIL)
		{
			if (hasSubLinks)
			{
2183 2184
				acquireLocksOnSubLinks_context context;

2185 2186 2187 2188 2189 2190 2191 2192 2193 2194
				/*
				 * Recursively process the new quals, checking for infinite
				 * recursion.
				 */
				if (list_member_oid(activeRIRs, RelationGetRelid(rel)))
					ereport(ERROR,
							(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
							 errmsg("infinite recursion detected in policy for relation \"%s\"",
									RelationGetRelationName(rel))));

2195
				activeRIRs = lappend_oid(activeRIRs, RelationGetRelid(rel));
2196

2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213
				/*
				 * get_row_security_policies just passed back securityQuals
				 * and/or withCheckOptions, and there were SubLinks, make sure
				 * we lock any relations which are referenced.
				 *
				 * These locks would normally be acquired by the parser, but
				 * securityQuals and withCheckOptions are added post-parsing.
				 */
				context.for_execute = true;
				(void) acquireLocksOnSubLinks((Node *) securityQuals, &context);
				(void) acquireLocksOnSubLinks((Node *) withCheckOptions,
											  &context);

				/*
				 * Now that we have the locks on anything added by
				 * get_row_security_policies, fire any RIR rules for them.
				 */
Bruce Momjian's avatar
Bruce Momjian committed
2214 2215
				expression_tree_walker((Node *) securityQuals,
									   fireRIRonSubLink, (void *) activeRIRs);
2216

Bruce Momjian's avatar
Bruce Momjian committed
2217 2218
				expression_tree_walker((Node *) withCheckOptions,
									   fireRIRonSubLink, (void *) activeRIRs);
2219

2220
				activeRIRs = list_delete_last(activeRIRs);
2221 2222 2223
			}

			/*
2224 2225 2226 2227
			 * Add the new security barrier quals to the start of the RTE's
			 * list so that they get applied before any existing barrier quals
			 * (which would have come from a security-barrier view, and should
			 * get lower priority than RLS conditions on the table itself).
2228 2229 2230 2231 2232
			 */
			rte->securityQuals = list_concat(securityQuals,
											 rte->securityQuals);

			parsetree->withCheckOptions = list_concat(withCheckOptions,
Tom Lane's avatar
Tom Lane committed
2233
													  parsetree->withCheckOptions);
2234 2235 2236
		}

		/*
2237
		 * Make sure the query is marked correctly if row-level security
2238 2239 2240 2241 2242 2243 2244
		 * applies, or if the new quals had sublinks.
		 */
		if (hasRowSecurity)
			parsetree->hasRowSecurity = true;
		if (hasSubLinks)
			parsetree->hasSubLinks = true;

2245
		table_close(rel, NoLock);
2246 2247
	}

2248 2249 2250 2251
	return parsetree;
}


2252
/*
2253 2254 2255 2256 2257
 * Modify the given query by adding 'AND rule_qual IS NOT TRUE' to its
 * qualification.  This is used to generate suitable "else clauses" for
 * conditional INSTEAD rules.  (Unfortunately we must use "x IS NOT TRUE",
 * not just "NOT x" which the planner is much smarter about, else we will
 * do the wrong thing when the qual evaluates to NULL.)
2258
 *
Bruce Momjian's avatar
Bruce Momjian committed
2259
 * The rule_qual may contain references to OLD or NEW.  OLD references are
2260 2261 2262 2263 2264
 * replaced by references to the specified rt_index (the relation that the
 * rule applies to).  NEW references are only possible for INSERT and UPDATE
 * queries on the relation itself, and so they should be replaced by copies
 * of the related entries in the query's own targetlist.
 */
2265
static Query *
2266 2267 2268 2269
CopyAndAddInvertedQual(Query *parsetree,
					   Node *rule_qual,
					   int rt_index,
					   CmdType event)
2270
{
2271
	/* Don't scribble on the passed qual (it's in the relcache!) */
2272
	Node	   *new_qual = copyObject(rule_qual);
2273 2274 2275
	acquireLocksOnSubLinks_context context;

	context.for_execute = true;
2276

2277 2278 2279
	/*
	 * In case there are subqueries in the qual, acquire necessary locks and
	 * fix any deleted JOIN RTE entries.  (This is somewhat redundant with
2280 2281
	 * rewriteRuleAction, but not entirely ... consider restructuring so that
	 * we only need to process the qual this way once.)
2282
	 */
2283
	(void) acquireLocksOnSubLinks(new_qual, &context);
2284

2285 2286 2287 2288
	/* Fix references to OLD */
	ChangeVarNodes(new_qual, PRS2_OLD_VARNO, rt_index, 0);
	/* Fix references to NEW */
	if (event == CMD_INSERT || event == CMD_UPDATE)
2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299
		new_qual = ReplaceVarsFromTargetList(new_qual,
											 PRS2_NEW_VARNO,
											 0,
											 rt_fetch(rt_index,
													  parsetree->rtable),
											 parsetree->targetList,
											 (event == CMD_UPDATE) ?
											 REPLACEVARS_CHANGE_VARNO :
											 REPLACEVARS_SUBSTITUTE_NULL,
											 rt_index,
											 &parsetree->hasSubLinks);
2300
	/* And attach the fixed qual */
2301
	AddInvertedQual(parsetree, new_qual);
2302

2303
	return parsetree;
2304 2305 2306 2307
}


/*
2308
 *	fireRules -
2309
 *	   Iterate through rule locks applying rules.
2310
 *
2311 2312 2313 2314 2315 2316
 * Input arguments:
 *	parsetree - original query
 *	rt_index - RT index of result relation in original query
 *	event - type of rule event
 *	locks - list of rules to fire
 * Output arguments:
2317 2318 2319 2320
 *	*instead_flag - set true if any unqualified INSTEAD rule is found
 *					(must be initialized to false)
 *	*returning_flag - set true if we rewrite RETURNING clause in any rule
 *					(must be initialized to false)
2321 2322 2323 2324
 *	*qual_product - filled with modified original query if any qualified
 *					INSTEAD rule is found (must be initialized to NULL)
 * Return value:
 *	list of rule actions adjusted for use with this query
2325
 *
2326 2327 2328 2329 2330 2331
 * Qualified INSTEAD rules generate their action with the qualification
 * condition added.  They also generate a modified version of the original
 * query with the negated qualification added, so that it will run only for
 * rows that the qualified action doesn't act on.  (If there are multiple
 * qualified INSTEAD rules, we AND all the negated quals onto a single
 * modified original query.)  We won't execute the original, unmodified
Bruce Momjian's avatar
Bruce Momjian committed
2332
 * query if we find either qualified or unqualified INSTEAD rules.  If
2333
 * we find both, the modified original query is discarded too.
2334
 */
2335
static List *
2336
fireRules(Query *parsetree,
2337 2338
		  int rt_index,
		  CmdType event,
2339
		  List *locks,
2340
		  bool *instead_flag,
2341
		  bool *returning_flag,
2342
		  Query **qual_product)
2343
{
2344
	List	   *results = NIL;
2345
	ListCell   *l;
2346

2347
	foreach(l, locks)
2348
	{
2349
		RewriteRule *rule_lock = (RewriteRule *) lfirst(l);
2350 2351
		Node	   *event_qual = rule_lock->qual;
		List	   *actions = rule_lock->actions;
Bruce Momjian's avatar
Bruce Momjian committed
2352
		QuerySource qsrc;
2353
		ListCell   *r;
2354

2355 2356 2357 2358 2359 2360
		/* Determine correct QuerySource value for actions */
		if (rule_lock->isInstead)
		{
			if (event_qual != NULL)
				qsrc = QSRC_QUAL_INSTEAD_RULE;
			else
2361
			{
2362
				qsrc = QSRC_INSTEAD_RULE;
Bruce Momjian's avatar
Bruce Momjian committed
2363
				*instead_flag = true;	/* report unqualified INSTEAD */
2364
			}
2365 2366 2367 2368 2369
		}
		else
			qsrc = QSRC_NON_INSTEAD_RULE;

		if (qsrc == QSRC_QUAL_INSTEAD_RULE)
2370
		{
2371
			/*
2372 2373 2374 2375 2376 2377 2378
			 * If there are INSTEAD rules with qualifications, the original
			 * query is still performed. But all the negated rule
			 * qualifications of the INSTEAD rules are added so it does its
			 * actions only in cases where the rule quals of all INSTEAD rules
			 * are false. Think of it as the default action in a case. We save
			 * this in *qual_product so RewriteQuery() can add it to the query
			 * list after we mangled it up enough.
2379
			 *
Bruce Momjian's avatar
Bruce Momjian committed
2380 2381
			 * If we have already found an unqualified INSTEAD rule, then
			 * *qual_product won't be used, so don't bother building it.
2382
			 */
Bruce Momjian's avatar
Bruce Momjian committed
2383
			if (!*instead_flag)
2384 2385
			{
				if (*qual_product == NULL)
2386
					*qual_product = copyObject(parsetree);
2387 2388 2389 2390
				*qual_product = CopyAndAddInvertedQual(*qual_product,
													   event_qual,
													   rt_index,
													   event);
2391
			}
2392 2393
		}

2394
		/* Now process the rule's actions and add them to the result list */
2395 2396
		foreach(r, actions)
		{
2397
			Query	   *rule_action = lfirst(r);
2398

2399 2400 2401
			if (rule_action->commandType == CMD_NOTHING)
				continue;

2402
			rule_action = rewriteRuleAction(parsetree, rule_action,
2403 2404
											event_qual, rt_index, event,
											returning_flag);
2405

2406
			rule_action->querySource = qsrc;
Tom Lane's avatar
Tom Lane committed
2407
			rule_action->canSetTag = false; /* might change later */
2408

2409
			results = lappend(results, rule_action);
2410 2411
		}
	}
2412

2413
	return results;
2414 2415
}

2416

2417 2418 2419 2420 2421
/*
 * get_view_query - get the Query from a view's _RETURN rule.
 *
 * Caller should have verified that the relation is a view, and therefore
 * we should find an ON SELECT action.
2422 2423 2424
 *
 * Note that the pointer returned is into the relcache and therefore must
 * be treated as read-only to the caller and not modified or scribbled on.
2425
 */
2426
Query *
2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455
get_view_query(Relation view)
{
	int			i;

	Assert(view->rd_rel->relkind == RELKIND_VIEW);

	for (i = 0; i < view->rd_rules->numLocks; i++)
	{
		RewriteRule *rule = view->rd_rules->rules[i];

		if (rule->event == CMD_SELECT)
		{
			/* A _RETURN rule should have only one action */
			if (list_length(rule->actions) != 1)
				elog(ERROR, "invalid _RETURN rule action specification");

			return (Query *) linitial(rule->actions);
		}
	}

	elog(ERROR, "failed to find _RETURN rule for view");
	return NULL;				/* keep compiler quiet */
}


/*
 * view_has_instead_trigger - does view have an INSTEAD OF trigger for event?
 *
 * If it does, we don't want to treat it as auto-updatable.  This test can't
2456 2457
 * be folded into view_query_is_auto_updatable because it's not an error
 * condition.
2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486
 */
static bool
view_has_instead_trigger(Relation view, CmdType event)
{
	TriggerDesc *trigDesc = view->trigdesc;

	switch (event)
	{
		case CMD_INSERT:
			if (trigDesc && trigDesc->trig_insert_instead_row)
				return true;
			break;
		case CMD_UPDATE:
			if (trigDesc && trigDesc->trig_update_instead_row)
				return true;
			break;
		case CMD_DELETE:
			if (trigDesc && trigDesc->trig_delete_instead_row)
				return true;
			break;
		default:
			elog(ERROR, "unrecognized CmdType: %d", (int) event);
			break;
	}
	return false;
}


/*
2487 2488 2489
 * view_col_is_auto_updatable - test whether the specified column of a view
 * is auto-updatable. Returns NULL (if the column can be updated) or a message
 * string giving the reason that it cannot be.
2490
 *
2491 2492 2493
 * The returned string has not been translated; if it is shown as an error
 * message, the caller should apply _() to translate it.
 *
2494 2495
 * Note that the checks performed here are local to this view. We do not check
 * whether the referenced column of the underlying base relation is updatable.
2496
 */
2497 2498
static const char *
view_col_is_auto_updatable(RangeTblRef *rtr, TargetEntry *tle)
2499
{
2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523
	Var		   *var = (Var *) tle->expr;

	/*
	 * For now, the only updatable columns we support are those that are Vars
	 * referring to user columns of the underlying base relation.
	 *
	 * The view targetlist may contain resjunk columns (e.g., a view defined
	 * like "SELECT * FROM t ORDER BY a+b" is auto-updatable) but such columns
	 * are not auto-updatable, and in fact should never appear in the outer
	 * query's targetlist.
	 */
	if (tle->resjunk)
		return gettext_noop("Junk view columns are not updatable.");

	if (!IsA(var, Var) ||
		var->varno != rtr->rtindex ||
		var->varlevelsup != 0)
		return gettext_noop("View columns that are not columns of their base relation are not updatable.");

	if (var->varattno < 0)
		return gettext_noop("View columns that refer to system columns are not updatable.");

	if (var->varattno == 0)
		return gettext_noop("View columns that return whole-row references are not updatable.");
2524

2525
	return NULL;				/* the view column is updatable */
2526 2527 2528 2529
}


/*
2530 2531 2532
 * view_query_is_auto_updatable - test whether the specified view definition
 * represents an auto-updatable view. Returns NULL (if the view can be updated)
 * or a message string giving the reason that it cannot be.
2533 2534 2535

 * The returned string has not been translated; if it is shown as an error
 * message, the caller should apply _() to translate it.
2536
 *
2537 2538 2539
 * If check_cols is true, the view is required to have at least one updatable
 * column (necessary for INSERT/UPDATE). Otherwise the view's columns are not
 * checked for updatability. See also view_cols_are_auto_updatable.
2540
 *
2541 2542 2543
 * Note that the checks performed here are only based on the view definition.
 * We do not check whether any base relations referred to by the view are
 * updatable.
2544 2545
 */
const char *
2546
view_query_is_auto_updatable(Query *viewquery, bool check_cols)
2547
{
2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565
	RangeTblRef *rtr;
	RangeTblEntry *base_rte;

	/*----------
	 * Check if the view is simply updatable.  According to SQL-92 this means:
	 *	- No DISTINCT clause.
	 *	- Each TLE is a column reference, and each column appears at most once.
	 *	- FROM contains exactly one base relation.
	 *	- No GROUP BY or HAVING clauses.
	 *	- No set operations (UNION, INTERSECT or EXCEPT).
	 *	- No sub-queries in the WHERE clause that reference the target table.
	 *
	 * We ignore that last restriction since it would be complex to enforce
	 * and there isn't any actual benefit to disallowing sub-queries.  (The
	 * semantic issues that the standard is presumably concerned about don't
	 * arise in Postgres, since any such sub-query will not see any updates
	 * executed by the outer query anyway, thanks to MVCC snapshotting.)
	 *
2566 2567 2568 2569 2570
	 * We also relax the second restriction by supporting part of SQL:1999
	 * feature T111, which allows for a mix of updatable and non-updatable
	 * columns, provided that an INSERT or UPDATE doesn't attempt to assign to
	 * a non-updatable column.
	 *
2571 2572 2573 2574 2575
	 * In addition we impose these constraints, involving features that are
	 * not part of SQL-92:
	 *	- No CTEs (WITH clauses).
	 *	- No OFFSET or LIMIT clauses (this matches a SQL:2008 restriction).
	 *	- No system columns (including whole-row references) in the tlist.
2576 2577
	 *	- No window functions in the tlist.
	 *	- No set-returning functions in the tlist.
2578 2579 2580 2581 2582 2583 2584 2585
	 *
	 * Note that we do these checks without recursively expanding the view.
	 * If the base relation is a view, we'll recursively deal with it later.
	 *----------
	 */
	if (viewquery->distinctClause != NIL)
		return gettext_noop("Views containing DISTINCT are not automatically updatable.");

2586
	if (viewquery->groupClause != NIL || viewquery->groupingSets)
2587 2588 2589 2590 2591 2592
		return gettext_noop("Views containing GROUP BY are not automatically updatable.");

	if (viewquery->havingQual != NULL)
		return gettext_noop("Views containing HAVING are not automatically updatable.");

	if (viewquery->setOperations != NULL)
Peter Eisentraut's avatar
Peter Eisentraut committed
2593
		return gettext_noop("Views containing UNION, INTERSECT, or EXCEPT are not automatically updatable.");
2594 2595 2596 2597 2598 2599 2600

	if (viewquery->cteList != NIL)
		return gettext_noop("Views containing WITH are not automatically updatable.");

	if (viewquery->limitOffset != NULL || viewquery->limitCount != NULL)
		return gettext_noop("Views containing LIMIT or OFFSET are not automatically updatable.");

2601 2602 2603 2604 2605 2606 2607 2608 2609 2610
	/*
	 * We must not allow window functions or set returning functions in the
	 * targetlist. Otherwise we might end up inserting them into the quals of
	 * the main query. We must also check for aggregates in the targetlist in
	 * case they appear without a GROUP BY.
	 *
	 * These restrictions ensure that each row of the view corresponds to a
	 * unique row in the underlying base relation.
	 */
	if (viewquery->hasAggs)
2611
		return gettext_noop("Views that return aggregate functions are not automatically updatable.");
2612 2613

	if (viewquery->hasWindowFuncs)
2614
		return gettext_noop("Views that return window functions are not automatically updatable.");
2615

2616
	if (viewquery->hasTargetSRFs)
2617 2618
		return gettext_noop("Views that return set-returning functions are not automatically updatable.");

2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632
	/*
	 * The view query should select from a single base relation, which must be
	 * a table or another view.
	 */
	if (list_length(viewquery->jointree->fromlist) != 1)
		return gettext_noop("Views that do not select from a single table or view are not automatically updatable.");

	rtr = (RangeTblRef *) linitial(viewquery->jointree->fromlist);
	if (!IsA(rtr, RangeTblRef))
		return gettext_noop("Views that do not select from a single table or view are not automatically updatable.");

	base_rte = rt_fetch(rtr->rtindex, viewquery->rtable);
	if (base_rte->rtekind != RTE_RELATION ||
		(base_rte->relkind != RELKIND_RELATION &&
2633
		 base_rte->relkind != RELKIND_FOREIGN_TABLE &&
2634 2635
		 base_rte->relkind != RELKIND_VIEW &&
		 base_rte->relkind != RELKIND_PARTITIONED_TABLE))
2636 2637
		return gettext_noop("Views that do not select from a single table or view are not automatically updatable.");

2638 2639 2640
	if (base_rte->tablesample)
		return gettext_noop("Views containing TABLESAMPLE are not automatically updatable.");

2641
	/*
2642 2643
	 * Check that the view has at least one updatable column. This is required
	 * for INSERT/UPDATE but not for DELETE.
2644
	 */
2645
	if (check_cols)
2646
	{
2647 2648
		ListCell   *cell;
		bool		found;
2649

2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660
		found = false;
		foreach(cell, viewquery->targetList)
		{
			TargetEntry *tle = (TargetEntry *) lfirst(cell);

			if (view_col_is_auto_updatable(rtr, tle) == NULL)
			{
				found = true;
				break;
			}
		}
2661

2662 2663 2664
		if (!found)
			return gettext_noop("Views that have no updatable columns are not automatically updatable.");
	}
2665

2666 2667
	return NULL;				/* the view is updatable */
}
2668 2669


2670 2671 2672 2673 2674 2675
/*
 * view_cols_are_auto_updatable - test whether all of the required columns of
 * an auto-updatable view are actually updatable. Returns NULL (if all the
 * required columns can be updated) or a message string giving the reason that
 * they cannot be.
 *
2676 2677 2678
 * The returned string has not been translated; if it is shown as an error
 * message, the caller should apply _() to translate it.
 *
2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701
 * This should be used for INSERT/UPDATE to ensure that we don't attempt to
 * assign to any non-updatable columns.
 *
 * Additionally it may be used to retrieve the set of updatable columns in the
 * view, or if one or more of the required columns is not updatable, the name
 * of the first offending non-updatable column.
 *
 * The caller must have already verified that this is an auto-updatable view
 * using view_query_is_auto_updatable.
 *
 * Note that the checks performed here are only based on the view definition.
 * We do not check whether the referenced columns of the base relation are
 * updatable.
 */
static const char *
view_cols_are_auto_updatable(Query *viewquery,
							 Bitmapset *required_cols,
							 Bitmapset **updatable_cols,
							 char **non_updatable_col)
{
	RangeTblRef *rtr;
	AttrNumber	col;
	ListCell   *cell;
2702

2703
	/*
Bruce Momjian's avatar
Bruce Momjian committed
2704 2705
	 * The caller should have verified that this view is auto-updatable and so
	 * there should be a single base relation.
2706 2707
	 */
	Assert(list_length(viewquery->jointree->fromlist) == 1);
2708
	rtr = linitial_node(RangeTblRef, viewquery->jointree->fromlist);
2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738

	/* Initialize the optional return values */
	if (updatable_cols != NULL)
		*updatable_cols = NULL;
	if (non_updatable_col != NULL)
		*non_updatable_col = NULL;

	/* Test each view column for updatability */
	col = -FirstLowInvalidHeapAttributeNumber;
	foreach(cell, viewquery->targetList)
	{
		TargetEntry *tle = (TargetEntry *) lfirst(cell);
		const char *col_update_detail;

		col++;
		col_update_detail = view_col_is_auto_updatable(rtr, tle);

		if (col_update_detail == NULL)
		{
			/* The column is updatable */
			if (updatable_cols != NULL)
				*updatable_cols = bms_add_member(*updatable_cols, col);
		}
		else if (bms_is_member(col, required_cols))
		{
			/* The required column is not updatable */
			if (non_updatable_col != NULL)
				*non_updatable_col = tle->resname;
			return col_update_detail;
		}
2739 2740
	}

Bruce Momjian's avatar
Bruce Momjian committed
2741
	return NULL;				/* all the required view columns are updatable */
2742 2743 2744 2745
}


/*
2746 2747
 * relation_is_updatable - determine which update events the specified
 * relation supports.
2748
 *
2749 2750 2751 2752 2753 2754
 * Note that views may contain a mix of updatable and non-updatable columns.
 * For a view to support INSERT/UPDATE it must have at least one updatable
 * column, but there is no such restriction for DELETE. If include_cols is
 * non-NULL, then only the specified columns are considered when testing for
 * updatability.
 *
2755 2756 2757 2758 2759
 * Unlike the preceding functions, this does recurse to look at a view's
 * base relations, so it needs to detect recursion.  To do that, we pass
 * a list of currently-considered outer relations.  External callers need
 * only pass NIL.
 *
2760
 * This is used for the information_schema views, which have separate concepts
Bruce Momjian's avatar
Bruce Momjian committed
2761
 * of "updatable" and "trigger updatable".  A relation is "updatable" if it
2762 2763 2764 2765 2766
 * can be updated without the need for triggers (either because it has a
 * suitable RULE, or because it is simple enough to be automatically updated).
 * A relation is "trigger updatable" if it has a suitable INSTEAD OF trigger.
 * The SQL standard regards this as not necessarily updatable, presumably
 * because there is no way of knowing what the trigger will actually do.
2767 2768 2769 2770
 * The information_schema views therefore call this function with
 * include_triggers = false.  However, other callers might only care whether
 * data-modifying SQL will work, so they can pass include_triggers = true
 * to have trigger updatability included in the result.
2771
 *
2772
 * The return value is a bitmask of rule event numbers indicating which of
Bruce Momjian's avatar
Bruce Momjian committed
2773
 * the INSERT, UPDATE and DELETE operations are supported.  (We do it this way
2774
 * so that we can test for UPDATE plus DELETE support in a single call.)
2775
 */
2776
int
2777
relation_is_updatable(Oid reloid,
2778
					  List *outer_reloids,
2779 2780
					  bool include_triggers,
					  Bitmapset *include_cols)
2781
{
2782
	int			events = 0;
2783 2784 2785
	Relation	rel;
	RuleLock   *rulelocks;

2786 2787
#define ALL_EVENTS ((1 << CMD_INSERT) | (1 << CMD_UPDATE) | (1 << CMD_DELETE))

2788 2789 2790
	/* Since this function recurses, it could be driven to stack overflow */
	check_stack_depth();

2791 2792 2793
	rel = try_relation_open(reloid, AccessShareLock);

	/*
2794
	 * If the relation doesn't exist, return zero rather than throwing an
Bruce Momjian's avatar
Bruce Momjian committed
2795
	 * error.  This is helpful since scanning an information_schema view under
2796 2797
	 * MVCC rules can result in referencing rels that have actually been
	 * deleted already.
2798 2799
	 */
	if (rel == NULL)
2800 2801
		return 0;

2802 2803 2804 2805 2806 2807 2808
	/* If we detect a recursive view, report that it is not updatable */
	if (list_member_oid(outer_reloids, RelationGetRelid(rel)))
	{
		relation_close(rel, AccessShareLock);
		return 0;
	}

2809
	/* If the relation is a table, it is always updatable */
2810 2811
	if (rel->rd_rel->relkind == RELKIND_RELATION ||
		rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
2812 2813 2814 2815
	{
		relation_close(rel, AccessShareLock);
		return ALL_EVENTS;
	}
2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827

	/* Look for unconditional DO INSTEAD rules, and note supported events */
	rulelocks = rel->rd_rules;
	if (rulelocks != NULL)
	{
		int			i;

		for (i = 0; i < rulelocks->numLocks; i++)
		{
			if (rulelocks->rules[i]->isInstead &&
				rulelocks->rules[i]->qual == NULL)
			{
2828
				events |= ((1 << rulelocks->rules[i]->event) & ALL_EVENTS);
2829 2830 2831
			}
		}

2832 2833
		/* If we have rules for all events, we're done */
		if (events == ALL_EVENTS)
2834 2835
		{
			relation_close(rel, AccessShareLock);
2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878
			return events;
		}
	}

	/* Similarly look for INSTEAD OF triggers, if they are to be included */
	if (include_triggers)
	{
		TriggerDesc *trigDesc = rel->trigdesc;

		if (trigDesc)
		{
			if (trigDesc->trig_insert_instead_row)
				events |= (1 << CMD_INSERT);
			if (trigDesc->trig_update_instead_row)
				events |= (1 << CMD_UPDATE);
			if (trigDesc->trig_delete_instead_row)
				events |= (1 << CMD_DELETE);

			/* If we have triggers for all events, we're done */
			if (events == ALL_EVENTS)
			{
				relation_close(rel, AccessShareLock);
				return events;
			}
		}
	}

	/* If this is a foreign table, check which update events it supports */
	if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
	{
		FdwRoutine *fdwroutine = GetFdwRoutineForRelation(rel, false);

		if (fdwroutine->IsForeignRelUpdatable != NULL)
			events |= fdwroutine->IsForeignRelUpdatable(rel);
		else
		{
			/* Assume presence of executor functions is sufficient */
			if (fdwroutine->ExecForeignInsert != NULL)
				events |= (1 << CMD_INSERT);
			if (fdwroutine->ExecForeignUpdate != NULL)
				events |= (1 << CMD_UPDATE);
			if (fdwroutine->ExecForeignDelete != NULL)
				events |= (1 << CMD_DELETE);
2879
		}
2880 2881 2882

		relation_close(rel, AccessShareLock);
		return events;
2883 2884 2885
	}

	/* Check if this is an automatically updatable view */
2886
	if (rel->rd_rel->relkind == RELKIND_VIEW)
2887
	{
2888 2889
		Query	   *viewquery = get_view_query(rel);

2890
		if (view_query_is_auto_updatable(viewquery, false) == NULL)
2891
		{
2892 2893 2894 2895 2896 2897 2898 2899
			Bitmapset  *updatable_cols;
			int			auto_events;
			RangeTblRef *rtr;
			RangeTblEntry *base_rte;
			Oid			baseoid;

			/*
			 * Determine which of the view's columns are updatable. If there
Bruce Momjian's avatar
Bruce Momjian committed
2900 2901 2902
			 * are none within the set of columns we are looking at, then the
			 * view doesn't support INSERT/UPDATE, but it may still support
			 * DELETE.
2903 2904 2905 2906 2907 2908 2909 2910
			 */
			view_cols_are_auto_updatable(viewquery, NULL,
										 &updatable_cols, NULL);

			if (include_cols != NULL)
				updatable_cols = bms_int_members(updatable_cols, include_cols);

			if (bms_is_empty(updatable_cols))
Tom Lane's avatar
Tom Lane committed
2911
				auto_events = (1 << CMD_DELETE);	/* May support DELETE */
2912
			else
Tom Lane's avatar
Tom Lane committed
2913
				auto_events = ALL_EVENTS;	/* May support all events */
2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924

			/*
			 * The base relation must also support these update commands.
			 * Tables are always updatable, but for any other kind of base
			 * relation we must do a recursive check limited to the columns
			 * referenced by the locally updatable columns in this view.
			 */
			rtr = (RangeTblRef *) linitial(viewquery->jointree->fromlist);
			base_rte = rt_fetch(rtr->rtindex, viewquery->rtable);
			Assert(base_rte->rtekind == RTE_RELATION);

2925 2926
			if (base_rte->relkind != RELKIND_RELATION &&
				base_rte->relkind != RELKIND_PARTITIONED_TABLE)
2927 2928
			{
				baseoid = base_rte->relid;
2929 2930
				outer_reloids = lappend_oid(outer_reloids,
											RelationGetRelid(rel));
2931 2932 2933
				include_cols = adjust_view_column_set(updatable_cols,
													  viewquery->targetList);
				auto_events &= relation_is_updatable(baseoid,
2934
													 outer_reloids,
2935 2936
													 include_triggers,
													 include_cols);
2937
				outer_reloids = list_delete_last(outer_reloids);
2938 2939
			}
			events |= auto_events;
2940 2941 2942
		}
	}

2943
	/* If we reach here, the relation may support some update commands */
2944
	relation_close(rel, AccessShareLock);
2945
	return events;
2946 2947 2948 2949 2950 2951 2952 2953 2954
}


/*
 * adjust_view_column_set - map a set of column numbers according to targetlist
 *
 * This is used with simply-updatable views to map column-permissions sets for
 * the view columns onto the matching columns in the underlying base relation.
 * The targetlist is expected to be a list of plain Vars of the underlying
2955
 * relation (as per the checks above in view_query_is_auto_updatable).
2956 2957 2958 2959 2960
 */
static Bitmapset *
adjust_view_column_set(Bitmapset *cols, List *targetlist)
{
	Bitmapset  *result = NULL;
2961
	int			col;
2962

2963 2964
	col = -1;
	while ((col = bms_next_member(cols, col)) >= 0)
2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981
	{
		/* bit numbers are offset by FirstLowInvalidHeapAttributeNumber */
		AttrNumber	attno = col + FirstLowInvalidHeapAttributeNumber;

		if (attno == InvalidAttrNumber)
		{
			/*
			 * There's a whole-row reference to the view.  For permissions
			 * purposes, treat it as a reference to each column available from
			 * the view.  (We should *not* convert this to a whole-row
			 * reference to the base relation, since the view may not touch
			 * all columns of the base relation.)
			 */
			ListCell   *lc;

			foreach(lc, targetlist)
			{
2982
				TargetEntry *tle = lfirst_node(TargetEntry, lc);
2983 2984 2985 2986
				Var		   *var;

				if (tle->resjunk)
					continue;
2987
				var = castNode(Var, tle->expr);
2988
				result = bms_add_member(result,
Tom Lane's avatar
Tom Lane committed
2989
										var->varattno - FirstLowInvalidHeapAttributeNumber);
2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005
			}
		}
		else
		{
			/*
			 * Views do not have system columns, so we do not expect to see
			 * any other system attnos here.  If we do find one, the error
			 * case will apply.
			 */
			TargetEntry *tle = get_tle_by_resno(targetlist, attno);

			if (tle != NULL && !tle->resjunk && IsA(tle->expr, Var))
			{
				Var		   *var = (Var *) tle->expr;

				result = bms_add_member(result,
Tom Lane's avatar
Tom Lane committed
3006
										var->varattno - FirstLowInvalidHeapAttributeNumber);
3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023
			}
			else
				elog(ERROR, "attribute number %d not found in view targetlist",
					 attno);
		}
	}

	return result;
}


/*
 * rewriteTargetView -
 *	  Attempt to rewrite a query where the target relation is a view, so that
 *	  the view's base relation becomes the target relation.
 *
 * Note that the base relation here may itself be a view, which may or may not
Bruce Momjian's avatar
Bruce Momjian committed
3024
 * have INSTEAD OF triggers or rules to handle the update.  That is handled by
3025 3026 3027 3028 3029 3030
 * the recursion in RewriteQuery.
 */
static Query *
rewriteTargetView(Query *parsetree, Relation view)
{
	Query	   *viewquery;
3031
	const char *auto_update_detail;
3032 3033 3034 3035 3036 3037 3038 3039 3040 3041
	RangeTblRef *rtr;
	int			base_rt_index;
	int			new_rt_index;
	RangeTblEntry *base_rte;
	RangeTblEntry *view_rte;
	RangeTblEntry *new_rte;
	Relation	base_rel;
	List	   *view_targetlist;
	ListCell   *lc;

3042 3043 3044 3045 3046 3047 3048 3049
	/*
	 * Get the Query from the view's ON SELECT rule.  We're going to munge the
	 * Query to change the view's base relation into the target relation,
	 * along with various other changes along the way, so we need to make a
	 * copy of it (get_view_query() returns a pointer into the relcache, so we
	 * have to treat it as read-only).
	 */
	viewquery = copyObject(get_view_query(view));
3050

3051
	/* The view must be updatable, else fail */
3052 3053 3054 3055
	auto_update_detail =
		view_query_is_auto_updatable(viewquery,
									 parsetree->commandType != CMD_DELETE);

3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066
	if (auto_update_detail)
	{
		/* messages here should match execMain.c's CheckValidResultRel */
		switch (parsetree->commandType)
		{
			case CMD_INSERT:
				ereport(ERROR,
						(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
						 errmsg("cannot insert into view \"%s\"",
								RelationGetRelationName(view)),
						 errdetail_internal("%s", _(auto_update_detail)),
3067
						 errhint("To enable inserting into the view, provide an INSTEAD OF INSERT trigger or an unconditional ON INSERT DO INSTEAD rule.")));
3068 3069 3070 3071 3072 3073 3074
				break;
			case CMD_UPDATE:
				ereport(ERROR,
						(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
						 errmsg("cannot update view \"%s\"",
								RelationGetRelationName(view)),
						 errdetail_internal("%s", _(auto_update_detail)),
3075
						 errhint("To enable updating the view, provide an INSTEAD OF UPDATE trigger or an unconditional ON UPDATE DO INSTEAD rule.")));
3076 3077 3078 3079 3080 3081 3082
				break;
			case CMD_DELETE:
				ereport(ERROR,
						(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
						 errmsg("cannot delete from view \"%s\"",
								RelationGetRelationName(view)),
						 errdetail_internal("%s", _(auto_update_detail)),
3083
						 errhint("To enable deleting from the view, provide an INSTEAD OF DELETE trigger or an unconditional ON DELETE DO INSTEAD rule.")));
3084 3085 3086 3087 3088 3089 3090 3091
				break;
			default:
				elog(ERROR, "unrecognized CmdType: %d",
					 (int) parsetree->commandType);
				break;
		}
	}

3092 3093 3094
	/*
	 * For INSERT/UPDATE the modified columns must all be updatable. Note that
	 * we get the modified columns from the query's targetlist, not from the
3095 3096 3097
	 * result RTE's insertedCols and/or updatedCols set, since
	 * rewriteTargetListIU may have added additional targetlist entries for
	 * view defaults, and these must also be updatable.
3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109
	 */
	if (parsetree->commandType != CMD_DELETE)
	{
		Bitmapset  *modified_cols = NULL;
		char	   *non_updatable_col;

		foreach(lc, parsetree->targetList)
		{
			TargetEntry *tle = (TargetEntry *) lfirst(lc);

			if (!tle->resjunk)
				modified_cols = bms_add_member(modified_cols,
Tom Lane's avatar
Tom Lane committed
3110
											   tle->resno - FirstLowInvalidHeapAttributeNumber);
3111 3112
		}

3113 3114 3115 3116 3117 3118 3119 3120
		if (parsetree->onConflict)
		{
			foreach(lc, parsetree->onConflict->onConflictSet)
			{
				TargetEntry *tle = (TargetEntry *) lfirst(lc);

				if (!tle->resjunk)
					modified_cols = bms_add_member(modified_cols,
Tom Lane's avatar
Tom Lane committed
3121
												   tle->resno - FirstLowInvalidHeapAttributeNumber);
3122 3123 3124
			}
		}

3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139
		auto_update_detail = view_cols_are_auto_updatable(viewquery,
														  modified_cols,
														  NULL,
														  &non_updatable_col);
		if (auto_update_detail)
		{
			/*
			 * This is a different error, caused by an attempt to update a
			 * non-updatable column in an otherwise updatable view.
			 */
			switch (parsetree->commandType)
			{
				case CMD_INSERT:
					ereport(ERROR,
							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
Tom Lane's avatar
Tom Lane committed
3140 3141 3142 3143
							 errmsg("cannot insert into column \"%s\" of view \"%s\"",
									non_updatable_col,
									RelationGetRelationName(view)),
							 errdetail_internal("%s", _(auto_update_detail))));
3144 3145 3146 3147
					break;
				case CMD_UPDATE:
					ereport(ERROR,
							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
Tom Lane's avatar
Tom Lane committed
3148 3149 3150 3151
							 errmsg("cannot update column \"%s\" of view \"%s\"",
									non_updatable_col,
									RelationGetRelationName(view)),
							 errdetail_internal("%s", _(auto_update_detail))));
3152 3153 3154 3155 3156 3157 3158 3159 3160
					break;
				default:
					elog(ERROR, "unrecognized CmdType: %d",
						 (int) parsetree->commandType);
					break;
			}
		}
	}

3161 3162 3163 3164
	/* Locate RTE describing the view in the outer query */
	view_rte = rt_fetch(parsetree->resultRelation, parsetree->rtable);

	/*
3165 3166
	 * If we get here, view_query_is_auto_updatable() has verified that the
	 * view contains a single base relation.
3167 3168
	 */
	Assert(list_length(viewquery->jointree->fromlist) == 1);
3169
	rtr = linitial_node(RangeTblRef, viewquery->jointree->fromlist);
3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181

	base_rt_index = rtr->rtindex;
	base_rte = rt_fetch(base_rt_index, viewquery->rtable);
	Assert(base_rte->rtekind == RTE_RELATION);

	/*
	 * Up to now, the base relation hasn't been touched at all in our query.
	 * We need to acquire lock on it before we try to do anything with it.
	 * (The subsequent recursive call of RewriteQuery will suppose that we
	 * already have the right lock!)  Since it will become the query target
	 * relation, RowExclusiveLock is always the right thing.
	 */
3182
	base_rel = table_open(base_rte->relid, RowExclusiveLock);
3183 3184 3185 3186 3187 3188 3189

	/*
	 * While we have the relation open, update the RTE's relkind, just in case
	 * it changed since this view was made (cf. AcquireRewriteLocks).
	 */
	base_rte->relkind = base_rel->rd_rel->relkind;

3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204
	/*
	 * If the view query contains any sublink subqueries then we need to also
	 * acquire locks on any relations they refer to.  We know that there won't
	 * be any subqueries in the range table or CTEs, so we can skip those, as
	 * in AcquireRewriteLocks.
	 */
	if (viewquery->hasSubLinks)
	{
		acquireLocksOnSubLinks_context context;

		context.for_execute = true;
		query_tree_walker(viewquery, acquireLocksOnSubLinks, &context,
						  QTW_IGNORE_RC_SUBQUERIES);
	}

3205 3206 3207 3208 3209 3210
	/*
	 * Create a new target RTE describing the base relation, and add it to the
	 * outer query's rangetable.  (What's happening in the next few steps is
	 * very much like what the planner would do to "pull up" the view into the
	 * outer query.  Perhaps someday we should refactor things enough so that
	 * we can share code with the planner.)
3211 3212 3213 3214
	 *
	 * Be sure to set rellockmode to the correct thing for the target table.
	 * Since we copied the whole viewquery above, we can just scribble on
	 * base_rte instead of copying it.
3215
	 */
3216 3217 3218
	new_rte = base_rte;
	new_rte->rellockmode = RowExclusiveLock;

3219 3220 3221
	parsetree->rtable = lappend(parsetree->rtable, new_rte);
	new_rt_index = list_length(parsetree->rtable);

3222 3223 3224 3225 3226 3227 3228
	/*
	 * INSERTs never inherit.  For UPDATE/DELETE, we use the view query's
	 * inheritance flag for the base relation.
	 */
	if (parsetree->commandType == CMD_INSERT)
		new_rte->inh = false;

3229
	/*
3230 3231 3232 3233 3234 3235
	 * Adjust the view's targetlist Vars to reference the new target RTE, ie
	 * make their varnos be new_rt_index instead of base_rt_index.  There can
	 * be no Vars for other rels in the tlist, so this is sufficient to pull
	 * up the tlist expressions for use in the outer query.  The tlist will
	 * provide the replacement expressions used by ReplaceVarsFromTargetList
	 * below.
3236
	 */
3237
	view_targetlist = viewquery->targetList;
3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263

	ChangeVarNodes((Node *) view_targetlist,
				   base_rt_index,
				   new_rt_index,
				   0);

	/*
	 * Mark the new target RTE for the permissions checks that we want to
	 * enforce against the view owner, as distinct from the query caller.  At
	 * the relation level, require the same INSERT/UPDATE/DELETE permissions
	 * that the query caller needs against the view.  We drop the ACL_SELECT
	 * bit that is presumably in new_rte->requiredPerms initially.
	 *
	 * Note: the original view RTE remains in the query's rangetable list.
	 * Although it will be unused in the query plan, we need it there so that
	 * the executor still performs appropriate permissions checks for the
	 * query caller's use of the view.
	 */
	new_rte->checkAsUser = view->rd_rel->relowner;
	new_rte->requiredPerms = view_rte->requiredPerms;

	/*
	 * Now for the per-column permissions bits.
	 *
	 * Initially, new_rte contains selectedCols permission check bits for all
	 * base-rel columns referenced by the view, but since the view is a SELECT
3264 3265 3266 3267 3268 3269 3270 3271 3272 3273
	 * query its insertedCols/updatedCols is empty.  We set insertedCols and
	 * updatedCols to include all the columns the outer query is trying to
	 * modify, adjusting the column numbers as needed.  But we leave
	 * selectedCols as-is, so the view owner must have read permission for all
	 * columns used in the view definition, even if some of them are not read
	 * by the outer query.  We could try to limit selectedCols to only columns
	 * used in the transformed query, but that does not correspond to what
	 * happens in ordinary SELECT usage of a view: all referenced columns must
	 * have read permission, even if optimization finds that some of them can
	 * be discarded during query transformation.  The flattening we're doing
Bruce Momjian's avatar
Bruce Momjian committed
3274 3275
	 * here is an optional optimization, too.  (If you are unpersuaded and
	 * want to change this, note that applying adjust_view_column_set to
3276 3277
	 * view_rte->selectedCols is clearly *not* the right answer, since that
	 * neglects base-rel columns used in the view's WHERE quals.)
3278 3279 3280 3281
	 *
	 * This step needs the modified view targetlist, so we have to do things
	 * in this order.
	 */
3282 3283 3284 3285
	Assert(bms_is_empty(new_rte->insertedCols) &&
		   bms_is_empty(new_rte->updatedCols));

	new_rte->insertedCols = adjust_view_column_set(view_rte->insertedCols,
3286 3287
												   view_targetlist);

3288 3289 3290
	new_rte->updatedCols = adjust_view_column_set(view_rte->updatedCols,
												  view_targetlist);

3291 3292
	/*
	 * Move any security barrier quals from the view RTE onto the new target
Bruce Momjian's avatar
Bruce Momjian committed
3293 3294
	 * RTE.  Any such quals should now apply to the new target RTE and will
	 * not reference the original view RTE in the rewritten query.
3295 3296 3297 3298
	 */
	new_rte->securityQuals = view_rte->securityQuals;
	view_rte->securityQuals = NIL;

3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352
	/*
	 * Now update all Vars in the outer query that reference the view to
	 * reference the appropriate column of the base relation instead.
	 */
	parsetree = (Query *)
		ReplaceVarsFromTargetList((Node *) parsetree,
								  parsetree->resultRelation,
								  0,
								  view_rte,
								  view_targetlist,
								  REPLACEVARS_REPORT_ERROR,
								  0,
								  &parsetree->hasSubLinks);

	/*
	 * Update all other RTI references in the query that point to the view
	 * (for example, parsetree->resultRelation itself) to point to the new
	 * base relation instead.  Vars will not be affected since none of them
	 * reference parsetree->resultRelation any longer.
	 */
	ChangeVarNodes((Node *) parsetree,
				   parsetree->resultRelation,
				   new_rt_index,
				   0);
	Assert(parsetree->resultRelation == new_rt_index);

	/*
	 * For INSERT/UPDATE we must also update resnos in the targetlist to refer
	 * to columns of the base relation, since those indicate the target
	 * columns to be affected.
	 *
	 * Note that this destroys the resno ordering of the targetlist, but that
	 * will be fixed when we recurse through rewriteQuery, which will invoke
	 * rewriteTargetListIU again on the updated targetlist.
	 */
	if (parsetree->commandType != CMD_DELETE)
	{
		foreach(lc, parsetree->targetList)
		{
			TargetEntry *tle = (TargetEntry *) lfirst(lc);
			TargetEntry *view_tle;

			if (tle->resjunk)
				continue;

			view_tle = get_tle_by_resno(view_targetlist, tle->resno);
			if (view_tle != NULL && !view_tle->resjunk && IsA(view_tle->expr, Var))
				tle->resno = ((Var *) view_tle->expr)->varattno;
			else
				elog(ERROR, "attribute number %d not found in view targetlist",
					 tle->resno);
		}
	}

3353 3354 3355 3356 3357 3358 3359 3360 3361
	/*
	 * For INSERT .. ON CONFLICT .. DO UPDATE, we must also update assorted
	 * stuff in the onConflict data structure.
	 */
	if (parsetree->onConflict &&
		parsetree->onConflict->action == ONCONFLICT_UPDATE)
	{
		Index		old_exclRelIndex,
					new_exclRelIndex;
3362
		ParseNamespaceItem *new_exclNSItem;
3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396
		RangeTblEntry *new_exclRte;
		List	   *tmp_tlist;

		/*
		 * Like the INSERT/UPDATE code above, update the resnos in the
		 * auxiliary UPDATE targetlist to refer to columns of the base
		 * relation.
		 */
		foreach(lc, parsetree->onConflict->onConflictSet)
		{
			TargetEntry *tle = (TargetEntry *) lfirst(lc);
			TargetEntry *view_tle;

			if (tle->resjunk)
				continue;

			view_tle = get_tle_by_resno(view_targetlist, tle->resno);
			if (view_tle != NULL && !view_tle->resjunk && IsA(view_tle->expr, Var))
				tle->resno = ((Var *) view_tle->expr)->varattno;
			else
				elog(ERROR, "attribute number %d not found in view targetlist",
					 tle->resno);
		}

		/*
		 * Also, create a new RTE for the EXCLUDED pseudo-relation, using the
		 * query's new base rel (which may well have a different column list
		 * from the view, hence we need a new column alias list).  This should
		 * match transformOnConflictClause.  In particular, note that the
		 * relkind is set to composite to signal that we're not dealing with
		 * an actual relation, and no permissions checks are wanted.
		 */
		old_exclRelIndex = parsetree->onConflict->exclRelIndex;

3397 3398 3399 3400 3401 3402
		new_exclNSItem = addRangeTableEntryForRelation(make_parsestate(NULL),
													   base_rel,
													   RowExclusiveLock,
													   makeAlias("excluded", NIL),
													   false, false);
		new_exclRte = new_exclNSItem->p_rte;
3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441
		new_exclRte->relkind = RELKIND_COMPOSITE_TYPE;
		new_exclRte->requiredPerms = 0;
		/* other permissions fields in new_exclRte are already empty */

		parsetree->rtable = lappend(parsetree->rtable, new_exclRte);
		new_exclRelIndex = parsetree->onConflict->exclRelIndex =
			list_length(parsetree->rtable);

		/*
		 * Replace the targetlist for the EXCLUDED pseudo-relation with a new
		 * one, representing the columns from the new base relation.
		 */
		parsetree->onConflict->exclRelTlist =
			BuildOnConflictExcludedTargetlist(base_rel, new_exclRelIndex);

		/*
		 * Update all Vars in the ON CONFLICT clause that refer to the old
		 * EXCLUDED pseudo-relation.  We want to use the column mappings
		 * defined in the view targetlist, but we need the outputs to refer to
		 * the new EXCLUDED pseudo-relation rather than the new target RTE.
		 * Also notice that "EXCLUDED.*" will be expanded using the view's
		 * rowtype, which seems correct.
		 */
		tmp_tlist = copyObject(view_targetlist);

		ChangeVarNodes((Node *) tmp_tlist, new_rt_index,
					   new_exclRelIndex, 0);

		parsetree->onConflict = (OnConflictExpr *)
			ReplaceVarsFromTargetList((Node *) parsetree->onConflict,
									  old_exclRelIndex,
									  0,
									  view_rte,
									  tmp_tlist,
									  REPLACEVARS_REPORT_ERROR,
									  0,
									  &parsetree->hasSubLinks);
	}

3442 3443 3444 3445 3446 3447
	/*
	 * For UPDATE/DELETE, pull up any WHERE quals from the view.  We know that
	 * any Vars in the quals must reference the one base relation, so we need
	 * only adjust their varnos to reference the new target (just the same as
	 * we did with the view targetlist).
	 *
3448 3449 3450
	 * If it's a security-barrier view, its WHERE quals must be applied before
	 * quals from the outer query, so we attach them to the RTE as security
	 * barrier quals rather than adding them to the main WHERE clause.
3451
	 *
3452
	 * For INSERT, the view's quals can be ignored in the main query.
3453 3454 3455 3456
	 */
	if (parsetree->commandType != CMD_INSERT &&
		viewquery->jointree->quals != NULL)
	{
3457
		Node	   *viewqual = (Node *) viewquery->jointree->quals;
3458

3459 3460 3461 3462 3463 3464 3465
		/*
		 * Even though we copied viewquery already at the top of this
		 * function, we must duplicate the viewqual again here, because we may
		 * need to use the quals again below for a WithCheckOption clause.
		 */
		viewqual = copyObject(viewqual);

3466
		ChangeVarNodes(viewqual, base_rt_index, new_rt_index, 0);
3467 3468 3469 3470

		if (RelationIsSecurityView(view))
		{
			/*
3471 3472 3473 3474
			 * The view's quals go in front of existing barrier quals: those
			 * would have come from an outer level of security-barrier view,
			 * and so must get evaluated later.
			 *
3475 3476 3477 3478 3479 3480
			 * Note: the parsetree has been mutated, so the new_rte pointer is
			 * stale and needs to be re-computed.
			 */
			new_rte = rt_fetch(new_rt_index, parsetree->rtable);
			new_rte->securityQuals = lcons(viewqual, new_rte->securityQuals);

3481 3482 3483 3484 3485
			/*
			 * Do not set parsetree->hasRowSecurity, because these aren't RLS
			 * conditions (they aren't affected by enabling/disabling RLS).
			 */

3486 3487 3488 3489 3490 3491 3492 3493 3494
			/*
			 * Make sure that the query is marked correctly if the added qual
			 * has sublinks.
			 */
			if (!parsetree->hasSubLinks)
				parsetree->hasSubLinks = checkExprHasSubLink(viewqual);
		}
		else
			AddQual(parsetree, (Node *) viewqual);
3495 3496
	}

3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510
	/*
	 * For INSERT/UPDATE, if the view has the WITH CHECK OPTION, or any parent
	 * view specified WITH CASCADED CHECK OPTION, add the quals from the view
	 * to the query's withCheckOptions list.
	 */
	if (parsetree->commandType != CMD_DELETE)
	{
		bool		has_wco = RelationHasCheckOption(view);
		bool		cascaded = RelationHasCascadedCheckOption(view);

		/*
		 * If the parent view has a cascaded check option, treat this view as
		 * if it also had a cascaded check option.
		 *
Bruce Momjian's avatar
Bruce Momjian committed
3511 3512 3513
		 * New WithCheckOptions are added to the start of the list, so if
		 * there is a cascaded check option, it will be the first item in the
		 * list.
3514 3515 3516 3517
		 */
		if (parsetree->withCheckOptions != NIL)
		{
			WithCheckOption *parent_wco =
Bruce Momjian's avatar
Bruce Momjian committed
3518
			(WithCheckOption *) linitial(parsetree->withCheckOptions);
3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540

			if (parent_wco->cascaded)
			{
				has_wco = true;
				cascaded = true;
			}
		}

		/*
		 * Add the new WithCheckOption to the start of the list, so that
		 * checks on inner views are run before checks on outer views, as
		 * required by the SQL standard.
		 *
		 * If the new check is CASCADED, we need to add it even if this view
		 * has no quals, since there may be quals on child views.  A LOCAL
		 * check can be omitted if this view has no quals.
		 */
		if (has_wco && (cascaded || viewquery->jointree->quals != NULL))
		{
			WithCheckOption *wco;

			wco = makeNode(WithCheckOption);
3541 3542
			wco->kind = WCO_VIEW_CHECK;
			wco->relname = pstrdup(RelationGetRelationName(view));
Stephen Frost's avatar
Stephen Frost committed
3543
			wco->polname = NULL;
3544 3545 3546 3547 3548 3549 3550 3551
			wco->qual = NULL;
			wco->cascaded = cascaded;

			parsetree->withCheckOptions = lcons(wco,
												parsetree->withCheckOptions);

			if (viewquery->jointree->quals != NULL)
			{
3552
				wco->qual = (Node *) viewquery->jointree->quals;
3553 3554 3555 3556 3557 3558
				ChangeVarNodes(wco->qual, base_rt_index, new_rt_index, 0);

				/*
				 * Make sure that the query is marked correctly if the added
				 * qual has sublinks.  We can skip this check if the query is
				 * already marked, or if the command is an UPDATE, in which
3559 3560
				 * case the same qual will have already been added, and this
				 * check will already have been done.
3561 3562 3563 3564 3565 3566 3567 3568
				 */
				if (!parsetree->hasSubLinks &&
					parsetree->commandType != CMD_UPDATE)
					parsetree->hasSubLinks = checkExprHasSubLink(wco->qual);
			}
		}
	}

3569
	table_close(base_rel, NoLock);
3570

3571 3572 3573 3574
	return parsetree;
}


3575
/*
3576 3577
 * RewriteQuery -
 *	  rewrites the query and apply the rules again on the queries rewritten
3578
 *
3579 3580
 * rewrite_events is a list of open query-rewrite actions, so we can detect
 * infinite recursion.
3581
 */
3582
static List *
3583
RewriteQuery(Query *parsetree, List *rewrite_events)
3584
{
3585 3586
	CmdType		event = parsetree->commandType;
	bool		instead = false;
3587
	bool		returning = false;
3588
	bool		updatableview = false;
3589 3590
	Query	   *qual_product = NULL;
	List	   *rewritten = NIL;
3591
	ListCell   *lc1;
3592

3593 3594 3595 3596 3597 3598 3599
	/*
	 * First, recursively process any insert/update/delete statements in WITH
	 * clauses.  (We have to do this first because the WITH clauses may get
	 * copied into rule actions below.)
	 */
	foreach(lc1, parsetree->cteList)
	{
3600
		CommonTableExpr *cte = lfirst_node(CommonTableExpr, lc1);
3601
		Query	   *ctequery = castNode(Query, cte->ctequery);
3602 3603 3604 3605 3606 3607 3608 3609 3610
		List	   *newstuff;

		if (ctequery->commandType == CMD_SELECT)
			continue;

		newstuff = RewriteQuery(ctequery, rewrite_events);

		/*
		 * Currently we can only handle unconditional, single-statement DO
3611 3612
		 * INSTEAD rules correctly; we have to get exactly one non-utility
		 * Query out of the rewrite operation to stuff back into the CTE node.
3613 3614 3615
		 */
		if (list_length(newstuff) == 1)
		{
3616
			/* Must check it's not a utility command */
3617
			ctequery = linitial_node(Query, newstuff);
3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630
			if (!(ctequery->commandType == CMD_SELECT ||
				  ctequery->commandType == CMD_UPDATE ||
				  ctequery->commandType == CMD_INSERT ||
				  ctequery->commandType == CMD_DELETE))
			{
				/*
				 * Currently it could only be NOTIFY; this error message will
				 * need work if we ever allow other utility commands in rules.
				 */
				ereport(ERROR,
						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
						 errmsg("DO INSTEAD NOTIFY rules are not supported for data-modifying statements in WITH")));
			}
3631 3632
			/* WITH queries should never be canSetTag */
			Assert(!ctequery->canSetTag);
3633
			/* Push the single Query back into the CTE node */
3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666
			cte->ctequery = (Node *) ctequery;
		}
		else if (newstuff == NIL)
		{
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
					 errmsg("DO INSTEAD NOTHING rules are not supported for data-modifying statements in WITH")));
		}
		else
		{
			ListCell   *lc2;

			/* examine queries to determine which error message to issue */
			foreach(lc2, newstuff)
			{
				Query	   *q = (Query *) lfirst(lc2);

				if (q->querySource == QSRC_QUAL_INSTEAD_RULE)
					ereport(ERROR,
							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
							 errmsg("conditional DO INSTEAD rules are not supported for data-modifying statements in WITH")));
				if (q->querySource == QSRC_NON_INSTEAD_RULE)
					ereport(ERROR,
							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
							 errmsg("DO ALSO rules are not supported for data-modifying statements in WITH")));
			}

			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
					 errmsg("multi-statement DO INSTEAD rules are not supported for data-modifying statements in WITH")));
		}
	}

3667
	/*
Tom Lane's avatar
Tom Lane committed
3668 3669
	 * If the statement is an insert, update, or delete, adjust its targetlist
	 * as needed, and then fire INSERT/UPDATE/DELETE rules on it.
3670
	 *
3671 3672 3673
	 * SELECT rules are handled later when we have all the queries that should
	 * get executed.  Also, utilities aren't rewritten at all (do we still
	 * need that check?)
3674
	 */
3675 3676 3677 3678 3679 3680
	if (event != CMD_SELECT && event != CMD_UTILITY)
	{
		int			result_relation;
		RangeTblEntry *rt_entry;
		Relation	rt_entry_relation;
		List	   *locks;
3681
		List	   *product_queries;
3682
		bool		hasUpdate = false;
3683 3684
		int			values_rte_index = 0;
		bool		defaults_remaining = false;
3685

3686 3687 3688 3689
		result_relation = parsetree->resultRelation;
		Assert(result_relation != 0);
		rt_entry = rt_fetch(result_relation, parsetree->rtable);
		Assert(rt_entry->rtekind == RTE_RELATION);
3690

3691
		/*
3692 3693
		 * We can use NoLock here since either the parser or
		 * AcquireRewriteLocks should have locked the rel already.
3694
		 */
3695
		rt_entry_relation = table_open(rt_entry->relid, NoLock);
3696

3697
		/*
Tom Lane's avatar
Tom Lane committed
3698
		 * Rewrite the targetlist as needed for the command type.
3699
		 */
Tom Lane's avatar
Tom Lane committed
3700
		if (event == CMD_INSERT)
3701 3702 3703 3704
		{
			RangeTblEntry *values_rte = NULL;

			/*
Bruce Momjian's avatar
Bruce Momjian committed
3705 3706
			 * If it's an INSERT ... VALUES (...), (...), ... there will be a
			 * single RTE for the VALUES targetlists.
3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717
			 */
			if (list_length(parsetree->jointree->fromlist) == 1)
			{
				RangeTblRef *rtr = (RangeTblRef *) linitial(parsetree->jointree->fromlist);

				if (IsA(rtr, RangeTblRef))
				{
					RangeTblEntry *rte = rt_fetch(rtr->rtindex,
												  parsetree->rtable);

					if (rte->rtekind == RTE_VALUES)
3718
					{
3719
						values_rte = rte;
3720 3721
						values_rte_index = rtr->rtindex;
					}
3722 3723 3724 3725 3726
				}
			}

			if (values_rte)
			{
3727 3728
				Bitmapset  *unused_values_attrnos = NULL;

3729
				/* Process the main targetlist ... */
3730
				parsetree->targetList = rewriteTargetListIU(parsetree->targetList,
Tom Lane's avatar
Tom Lane committed
3731 3732
															parsetree->commandType,
															parsetree->override,
3733
															rt_entry_relation,
3734 3735 3736
															values_rte,
															values_rte_index,
															&unused_values_attrnos);
3737
				/* ... and the VALUES expression lists */
3738
				if (!rewriteValuesRTE(parsetree, values_rte, values_rte_index,
3739 3740
									  rt_entry_relation, false,
									  unused_values_attrnos))
3741
					defaults_remaining = true;
3742 3743 3744 3745
			}
			else
			{
				/* Process just the main targetlist */
3746 3747 3748
				parsetree->targetList =
					rewriteTargetListIU(parsetree->targetList,
										parsetree->commandType,
Peter Eisentraut's avatar
Peter Eisentraut committed
3749
										parsetree->override,
3750
										rt_entry_relation,
3751
										NULL, 0, NULL);
3752 3753 3754 3755 3756 3757 3758 3759
			}

			if (parsetree->onConflict &&
				parsetree->onConflict->action == ONCONFLICT_UPDATE)
			{
				parsetree->onConflict->onConflictSet =
					rewriteTargetListIU(parsetree->onConflict->onConflictSet,
										CMD_UPDATE,
Peter Eisentraut's avatar
Peter Eisentraut committed
3760
										parsetree->override,
3761
										rt_entry_relation,
3762
										NULL, 0, NULL);
3763 3764
			}
		}
Tom Lane's avatar
Tom Lane committed
3765 3766
		else if (event == CMD_UPDATE)
		{
3767 3768
			parsetree->targetList =
				rewriteTargetListIU(parsetree->targetList,
Peter Eisentraut's avatar
Peter Eisentraut committed
3769 3770 3771
									parsetree->commandType,
									parsetree->override,
									rt_entry_relation,
3772
									NULL, 0, NULL);
3773 3774 3775

			/* Also populate extraUpdatedCols (for generated columns) */
			fill_extraUpdatedCols(rt_entry, rt_entry_relation);
Tom Lane's avatar
Tom Lane committed
3776 3777 3778
		}
		else if (event == CMD_DELETE)
		{
3779
			/* Nothing to do here */
Tom Lane's avatar
Tom Lane committed
3780 3781 3782
		}
		else
			elog(ERROR, "unrecognized commandType: %d", (int) event);
3783

3784 3785 3786 3787
		/*
		 * Collect and apply the appropriate rules.
		 */
		locks = matchLocks(event, rt_entry_relation->rd_rules,
3788
						   result_relation, parsetree, &hasUpdate);
3789

Simon Riggs's avatar
Simon Riggs committed
3790 3791 3792 3793 3794 3795 3796
		product_queries = fireRules(parsetree,
									result_relation,
									event,
									locks,
									&instead,
									&returning,
									&qual_product);
3797

3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819
		/*
		 * If we have a VALUES RTE with any remaining untouched DEFAULT items,
		 * and we got any product queries, finalize the VALUES RTE for each
		 * product query (replacing the remaining DEFAULT items with NULLs).
		 * We don't do this for the original query, because we know that it
		 * must be an auto-insert on a view, and so should use the base
		 * relation's defaults for any remaining DEFAULT items.
		 */
		if (defaults_remaining && product_queries != NIL)
		{
			ListCell   *n;

			/*
			 * Each product query has its own copy of the VALUES RTE at the
			 * same index in the rangetable, so we must finalize each one.
			 */
			foreach(n, product_queries)
			{
				Query	   *pt = (Query *) lfirst(n);
				RangeTblEntry *values_rte = rt_fetch(values_rte_index,
													 pt->rtable);

3820 3821
				rewriteValuesRTE(pt, values_rte, values_rte_index,
								 rt_entry_relation,
3822 3823
								 true,	/* Force remaining defaults to NULL */
								 NULL);
3824 3825 3826
			}
		}

3827
		/*
3828 3829
		 * If there was no unqualified INSTEAD rule, and the target relation
		 * is a view without any INSTEAD OF triggers, see if the view can be
3830 3831 3832 3833
		 * automatically updated.  If so, we perform the necessary query
		 * transformation here and add the resulting query to the
		 * product_queries list, so that it gets recursively rewritten if
		 * necessary.
3834 3835 3836 3837 3838 3839
		 *
		 * If the view cannot be automatically updated, we throw an error here
		 * which is OK since the query would fail at runtime anyway.  Throwing
		 * the error here is preferable to the executor check since we have
		 * more detailed information available about why the view isn't
		 * updatable.
3840
		 */
3841
		if (!instead &&
3842 3843
			rt_entry_relation->rd_rel->relkind == RELKIND_VIEW &&
			!view_has_instead_trigger(rt_entry_relation, event))
3844
		{
3845
			/*
3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890
			 * If there were any qualified INSTEAD rules, don't allow the view
			 * to be automatically updated (an unqualified INSTEAD rule or
			 * INSTEAD OF trigger is required).
			 *
			 * The messages here should match execMain.c's CheckValidResultRel
			 * and in principle make those checks in executor unnecessary, but
			 * we keep them just in case.
			 */
			if (qual_product != NULL)
			{
				switch (parsetree->commandType)
				{
					case CMD_INSERT:
						ereport(ERROR,
								(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
								 errmsg("cannot insert into view \"%s\"",
										RelationGetRelationName(rt_entry_relation)),
								 errdetail("Views with conditional DO INSTEAD rules are not automatically updatable."),
								 errhint("To enable inserting into the view, provide an INSTEAD OF INSERT trigger or an unconditional ON INSERT DO INSTEAD rule.")));
						break;
					case CMD_UPDATE:
						ereport(ERROR,
								(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
								 errmsg("cannot update view \"%s\"",
										RelationGetRelationName(rt_entry_relation)),
								 errdetail("Views with conditional DO INSTEAD rules are not automatically updatable."),
								 errhint("To enable updating the view, provide an INSTEAD OF UPDATE trigger or an unconditional ON UPDATE DO INSTEAD rule.")));
						break;
					case CMD_DELETE:
						ereport(ERROR,
								(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
								 errmsg("cannot delete from view \"%s\"",
										RelationGetRelationName(rt_entry_relation)),
								 errdetail("Views with conditional DO INSTEAD rules are not automatically updatable."),
								 errhint("To enable deleting from the view, provide an INSTEAD OF DELETE trigger or an unconditional ON DELETE DO INSTEAD rule.")));
						break;
					default:
						elog(ERROR, "unrecognized CmdType: %d",
							 (int) parsetree->commandType);
						break;
				}
			}

			/*
			 * Attempt to rewrite the query to automatically update the view.
3891
			 * This throws an error if the view can't be automatically
3892
			 * updated.
3893 3894
			 */
			parsetree = rewriteTargetView(parsetree, rt_entry_relation);
3895

3896
			/*
Bruce Momjian's avatar
Bruce Momjian committed
3897
			 * At this point product_queries contains any DO ALSO rule
Bruce Momjian's avatar
Bruce Momjian committed
3898
			 * actions. Add the rewritten query before or after those.  This
Bruce Momjian's avatar
Bruce Momjian committed
3899 3900
			 * must match the handling the original query would have gotten
			 * below, if we allowed it to be included again.
3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915
			 */
			if (parsetree->commandType == CMD_INSERT)
				product_queries = lcons(parsetree, product_queries);
			else
				product_queries = lappend(product_queries, parsetree);

			/*
			 * Set the "instead" flag, as if there had been an unqualified
			 * INSTEAD, to prevent the original query from being included a
			 * second time below.  The transformation will have rewritten any
			 * RETURNING list, so we can also set "returning" to forestall
			 * throwing an error below.
			 */
			instead = true;
			returning = true;
3916
			updatableview = true;
3917
		}
3918

Bruce Momjian's avatar
Bruce Momjian committed
3919 3920 3921 3922 3923 3924 3925 3926
		/*
		 * If we got any product queries, recursively rewrite them --- but
		 * first check for recursion!
		 */
		if (product_queries != NIL)
		{
			ListCell   *n;
			rewrite_event *rev;
3927

Bruce Momjian's avatar
Bruce Momjian committed
3928 3929 3930 3931 3932 3933 3934 3935
			foreach(n, rewrite_events)
			{
				rev = (rewrite_event *) lfirst(n);
				if (rev->relation == RelationGetRelid(rt_entry_relation) &&
					rev->event == event)
					ereport(ERROR,
							(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
							 errmsg("infinite recursion detected in rules for relation \"%s\"",
Tom Lane's avatar
Tom Lane committed
3936
									RelationGetRelationName(rt_entry_relation))));
Bruce Momjian's avatar
Bruce Momjian committed
3937
			}
3938

Bruce Momjian's avatar
Bruce Momjian committed
3939 3940 3941
			rev = (rewrite_event *) palloc(sizeof(rewrite_event));
			rev->relation = RelationGetRelid(rt_entry_relation);
			rev->event = event;
3942
			rewrite_events = lappend(rewrite_events, rev);
3943

Bruce Momjian's avatar
Bruce Momjian committed
3944 3945 3946 3947
			foreach(n, product_queries)
			{
				Query	   *pt = (Query *) lfirst(n);
				List	   *newstuff;
3948

Bruce Momjian's avatar
Bruce Momjian committed
3949 3950
				newstuff = RewriteQuery(pt, rewrite_events);
				rewritten = list_concat(rewritten, newstuff);
3951
			}
3952

3953
			rewrite_events = list_delete_last(rewrite_events);
Bruce Momjian's avatar
Bruce Momjian committed
3954 3955
		}

3956
		/*
Bruce Momjian's avatar
Bruce Momjian committed
3957 3958 3959 3960 3961
		 * If there is an INSTEAD, and the original query has a RETURNING, we
		 * have to have found a RETURNING in the rule(s), else fail. (Because
		 * DefineQueryRewrite only allows RETURNING in unconditional INSTEAD
		 * rules, there's no need to worry whether the substituted RETURNING
		 * will actually be executed --- it must be.)
3962 3963 3964 3965 3966 3967 3968 3969 3970 3971
		 */
		if ((instead || qual_product != NULL) &&
			parsetree->returningList &&
			!returning)
		{
			switch (event)
			{
				case CMD_INSERT:
					ereport(ERROR,
							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3972
							 errmsg("cannot perform INSERT RETURNING on relation \"%s\"",
Tom Lane's avatar
Tom Lane committed
3973
									RelationGetRelationName(rt_entry_relation)),
3974 3975 3976 3977 3978
							 errhint("You need an unconditional ON INSERT DO INSTEAD rule with a RETURNING clause.")));
					break;
				case CMD_UPDATE:
					ereport(ERROR,
							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3979
							 errmsg("cannot perform UPDATE RETURNING on relation \"%s\"",
Tom Lane's avatar
Tom Lane committed
3980
									RelationGetRelationName(rt_entry_relation)),
3981 3982 3983 3984 3985
							 errhint("You need an unconditional ON UPDATE DO INSTEAD rule with a RETURNING clause.")));
					break;
				case CMD_DELETE:
					ereport(ERROR,
							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3986
							 errmsg("cannot perform DELETE RETURNING on relation \"%s\"",
Tom Lane's avatar
Tom Lane committed
3987
									RelationGetRelationName(rt_entry_relation)),
3988 3989 3990 3991 3992 3993 3994 3995 3996
							 errhint("You need an unconditional ON DELETE DO INSTEAD rule with a RETURNING clause.")));
					break;
				default:
					elog(ERROR, "unrecognized commandType: %d",
						 (int) event);
					break;
			}
		}

3997 3998 3999 4000 4001 4002 4003
		/*
		 * Updatable views are supported by ON CONFLICT, so don't prevent that
		 * case from proceeding
		 */
		if (parsetree->onConflict &&
			(product_queries != NIL || hasUpdate) &&
			!updatableview)
Bruce Momjian's avatar
Bruce Momjian committed
4004 4005 4006
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
					 errmsg("INSERT with ON CONFLICT clause cannot be used with table that has INSERT or UPDATE rules")));
4007

4008
		table_close(rt_entry_relation, NoLock);
4009
	}
4010

4011
	/*
4012 4013 4014 4015 4016 4017
	 * For INSERTs, the original query is done first; for UPDATE/DELETE, it is
	 * done last.  This is needed because update and delete rule actions might
	 * not do anything if they are invoked after the update or delete is
	 * performed. The command counter increment between the query executions
	 * makes the deleted (and maybe the updated) tuples disappear so the scans
	 * for them in the rule actions cannot find them.
4018
	 *
Bruce Momjian's avatar
Bruce Momjian committed
4019 4020 4021
	 * If we found any unqualified INSTEAD, the original query is not done at
	 * all, in any form.  Otherwise, we add the modified form if qualified
	 * INSTEADs were found, else the unmodified form.
4022
	 */
4023
	if (!instead)
4024
	{
4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038
		if (parsetree->commandType == CMD_INSERT)
		{
			if (qual_product != NULL)
				rewritten = lcons(qual_product, rewritten);
			else
				rewritten = lcons(parsetree, rewritten);
		}
		else
		{
			if (qual_product != NULL)
				rewritten = lappend(rewritten, qual_product);
			else
				rewritten = lappend(rewritten, parsetree);
		}
4039
	}
4040

4041 4042
	/*
	 * If the original query has a CTE list, and we generated more than one
4043 4044 4045
	 * non-utility result query, we have to fail because we'll have copied the
	 * CTE list into each result query.  That would break the expectation of
	 * single evaluation of CTEs.  This could possibly be fixed by
4046 4047 4048 4049 4050
	 * restructuring so that a CTE list can be shared across multiple Query
	 * and PlannableStatement nodes.
	 */
	if (parsetree->cteList != NIL)
	{
4051
		int			qcount = 0;
4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065

		foreach(lc1, rewritten)
		{
			Query	   *q = (Query *) lfirst(lc1);

			if (q->commandType != CMD_UTILITY)
				qcount++;
		}
		if (qcount > 1)
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
					 errmsg("WITH cannot be used in a query that is rewritten by rules into multiple queries")));
	}

4066 4067
	return rewritten;
}
4068 4069 4070


/*
4071 4072 4073 4074 4075
 * QueryRewrite -
 *	  Primary entry point to the query rewriter.
 *	  Rewrite one query via query rewrite system, possibly returning 0
 *	  or many queries.
 *
4076 4077
 * NOTE: the parsetree must either have come straight from the parser,
 * or have been scanned by AcquireRewriteLocks to acquire suitable locks.
4078
 */
4079 4080
List *
QueryRewrite(Query *parsetree)
4081
{
4082
	uint64		input_query_id = parsetree->queryId;
Bruce Momjian's avatar
Bruce Momjian committed
4083
	List	   *querylist;
Tom Lane's avatar
Tom Lane committed
4084
	List	   *results;
4085
	ListCell   *l;
4086 4087 4088
	CmdType		origCmdType;
	bool		foundOriginalQuery;
	Query	   *lastInstead;
4089

4090 4091 4092 4093 4094 4095
	/*
	 * This function is only applied to top-level original queries
	 */
	Assert(parsetree->querySource == QSRC_ORIGINAL);
	Assert(parsetree->canSetTag);

4096 4097 4098 4099 4100
	/*
	 * Step 1
	 *
	 * Apply all non-SELECT rules possibly getting 0 or many queries
	 */
4101
	querylist = RewriteQuery(parsetree, NIL);
4102 4103

	/*
4104
	 * Step 2
4105 4106
	 *
	 * Apply all the RIR rules on each query
4107 4108
	 *
	 * This is also a handy place to mark each query with the original queryId
4109
	 */
Tom Lane's avatar
Tom Lane committed
4110
	results = NIL;
Bruce Momjian's avatar
Bruce Momjian committed
4111 4112
	foreach(l, querylist)
	{
4113
		Query	   *query = (Query *) lfirst(l);
Bruce Momjian's avatar
Bruce Momjian committed
4114

4115
		query = fireRIRrules(query, NIL);
4116 4117 4118

		query->queryId = input_query_id;

4119
		results = lappend(results, query);
Bruce Momjian's avatar
Bruce Momjian committed
4120
	}
4121

4122 4123 4124
	/*
	 * Step 3
	 *
4125 4126
	 * Determine which, if any, of the resulting queries is supposed to set
	 * the command-result tag; and update the canSetTag fields accordingly.
4127 4128
	 *
	 * If the original query is still in the list, it sets the command tag.
4129
	 * Otherwise, the last INSTEAD query of the same kind as the original is
Bruce Momjian's avatar
Bruce Momjian committed
4130
	 * allowed to set the tag.  (Note these rules can leave us with no query
4131 4132
	 * setting the tag.  The tcop code has to cope with this by setting up a
	 * default tag based on the original un-rewritten query.)
4133 4134
	 *
	 * The Asserts verify that at most one query in the result list is marked
4135 4136
	 * canSetTag.  If we aren't checking asserts, we can fall out of the loop
	 * as soon as we find the original query.
4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167
	 */
	origCmdType = parsetree->commandType;
	foundOriginalQuery = false;
	lastInstead = NULL;

	foreach(l, results)
	{
		Query	   *query = (Query *) lfirst(l);

		if (query->querySource == QSRC_ORIGINAL)
		{
			Assert(query->canSetTag);
			Assert(!foundOriginalQuery);
			foundOriginalQuery = true;
#ifndef USE_ASSERT_CHECKING
			break;
#endif
		}
		else
		{
			Assert(!query->canSetTag);
			if (query->commandType == origCmdType &&
				(query->querySource == QSRC_INSTEAD_RULE ||
				 query->querySource == QSRC_QUAL_INSTEAD_RULE))
				lastInstead = query;
		}
	}

	if (!foundOriginalQuery && lastInstead != NULL)
		lastInstead->canSetTag = true;

4168
	return results;
Bruce Momjian's avatar
Hi!  
Bruce Momjian committed
4169
}