rewriteHandler.c 46.3 KB
Newer Older
1 2
/*-------------------------------------------------------------------------
 *
3
 * rewriteHandler.c
4
 *		Primary module of query rewriter.
5
 *
6
 * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
B
Add:  
Bruce Momjian 已提交
7
 * Portions Copyright (c) 1994, Regents of the University of California
8 9
 *
 * IDENTIFICATION
10
 *	  $PostgreSQL: pgsql/src/backend/rewrite/rewriteHandler.c,v 1.162 2006/04/05 22:11:55 tgl Exp $
11 12 13 14 15
 *
 *-------------------------------------------------------------------------
 */
#include "postgres.h"

B
Bruce Momjian 已提交
16
#include "access/heapam.h"
17
#include "catalog/pg_operator.h"
18
#include "catalog/pg_type.h"
B
Bruce Momjian 已提交
19
#include "miscadmin.h"
20
#include "nodes/makefuncs.h"
B
Bruce Momjian 已提交
21 22
#include "optimizer/clauses.h"
#include "optimizer/prep.h"
23
#include "optimizer/var.h"
B
Bruce Momjian 已提交
24
#include "parser/analyze.h"
25
#include "parser/parse_coerce.h"
26 27
#include "parser/parse_expr.h"
#include "parser/parse_oper.h"
B
Bruce Momjian 已提交
28
#include "parser/parse_type.h"
29
#include "parser/parsetree.h"
30
#include "rewrite/rewriteHandler.h"
B
Bruce Momjian 已提交
31
#include "rewrite/rewriteManip.h"
32
#include "utils/builtins.h"
B
Bruce Momjian 已提交
33
#include "utils/lsyscache.h"
34 35


36
/* We use a list of these to detect recursion in RewriteQuery */
B
Bruce Momjian 已提交
37 38
typedef struct rewrite_event
{
39 40
	Oid			relation;		/* OID of relation having rules */
	CmdType		event;			/* type of rule being fired */
41
} rewrite_event;
42

43
static bool acquireLocksOnSubLinks(Node *node, void *context);
44
static Query *rewriteRuleAction(Query *parsetree,
45 46 47 48
				  Query *rule_action,
				  Node *rule_qual,
				  int rt_index,
				  CmdType event);
49
static List *adjustJoinTreeList(Query *parsetree, bool removert, int rt_index);
50 51
static void rewriteTargetList(Query *parsetree, Relation target_relation);
static TargetEntry *process_matched_tle(TargetEntry *src_tle,
B
Bruce Momjian 已提交
52 53
					TargetEntry *prior_tle,
					const char *attrName);
54
static Node *get_assignment_input(Node *node);
55
static void markQueryForLocking(Query *qry, bool forUpdate, bool noWait,
B
Bruce Momjian 已提交
56
					bool skipOldNew);
57
static List *matchLocks(CmdType event, RuleLock *rulelocks,
B
Bruce Momjian 已提交
58
		   int varno, Query *parsetree);
59
static Query *fireRIRrules(Query *parsetree, List *activeRIRs);
60

61

62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
/*
 * 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
 *	  while we are rewriting and planning the query.
 *
 * A secondary purpose of this routine is to fix up JOIN RTE references to
 * dropped columns (see details below).  Because the RTEs are modified in
 * place, it is generally appropriate for the caller of this routine to have
 * first done a copyObject() to make a writable copy of the querytree in the
 * current memory context.
 *
 * 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
 * prevent the column drop.)  To support get_rte_attribute_is_dropped(),
 * we replace join alias vars that reference dropped columns with NULL Const
 * nodes.
 *
 * (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
AcquireRewriteLocks(Query *parsetree)
{
	ListCell   *l;
	int			rt_index;

	/*
	 * 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;
110 111
		Index		curinputvarno;
		RangeTblEntry *curinputrte;
112 113 114 115 116 117
		ListCell   *ll;

		++rt_index;
		switch (rte->rtekind)
		{
			case RTE_RELATION:
B
Bruce Momjian 已提交
118

119
				/*
B
Bruce Momjian 已提交
120 121 122
				 * Grab the appropriate lock type for the relation, and do not
				 * release it until end of transaction. This protects the
				 * rewriter and planner against schema changes mid-query.
123
				 *
124 125 126 127 128 129
				 * If the relation is the query's result relation, then we
				 * need RowExclusiveLock.  Otherwise, check to see if the
				 * relation is accessed FOR UPDATE/SHARE or not.  We can't
				 * just grab AccessShareLock because then the executor would
				 * be trying to upgrade the lock, leading to possible
				 * deadlocks.
130 131 132 133 134 135 136 137 138 139 140 141 142
				 */
				if (rt_index == parsetree->resultRelation)
					lockmode = RowExclusiveLock;
				else if (list_member_int(parsetree->rowMarks, rt_index))
					lockmode = RowShareLock;
				else
					lockmode = AccessShareLock;

				rel = heap_open(rte->relid, lockmode);
				heap_close(rel, NoLock);
				break;

			case RTE_JOIN:
B
Bruce Momjian 已提交
143

144
				/*
B
Bruce Momjian 已提交
145 146 147
				 * Scan the join's alias var list to see if any columns have
				 * been dropped, and if so replace those Vars with NULL
				 * Consts.
148
				 *
B
Bruce Momjian 已提交
149 150 151
				 * Since a join has only two inputs, we can expect to see
				 * multiple references to the same input RTE; optimize away
				 * multiple fetches.
152 153
				 */
				newaliasvars = NIL;
154 155
				curinputvarno = 0;
				curinputrte = NULL;
156 157 158 159 160 161 162 163
				foreach(ll, rte->joinaliasvars)
				{
					Var		   *aliasvar = (Var *) lfirst(ll);

					/*
					 * 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
B
Bruce Momjian 已提交
164 165
					 * the join clause.  (Conceivably it could also be a NULL
					 * constant already?  But that's OK too.)
166 167 168 169 170
					 */
					if (IsA(aliasvar, Var))
					{
						/*
						 * The elements of an alias list have to refer to
B
Bruce Momjian 已提交
171 172 173 174 175 176
						 * earlier RTEs of the same rtable, because that's the
						 * order the planner builds things in.	So we already
						 * 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.)
177 178
						 */
						Assert(aliasvar->varlevelsup == 0);
179 180 181 182 183 184 185 186 187 188 189
						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))
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
						{
							/*
							 * can't use vartype here, since that might be a
							 * now-dropped type OID, but it doesn't really
							 * matter what type the Const claims to be.
							 */
							aliasvar = (Var *) makeNullConst(INT4OID);
						}
					}
					newaliasvars = lappend(newaliasvars, aliasvar);
				}
				rte->joinaliasvars = newaliasvars;
				break;

			case RTE_SUBQUERY:
B
Bruce Momjian 已提交
205

206 207 208 209 210 211 212 213 214 215 216 217 218 219
				/*
				 * The subquery RTE itself is all right, but we have to
				 * recurse to process the represented subquery.
				 */
				AcquireRewriteLocks(rte->subquery);
				break;

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

	/*
B
Bruce Momjian 已提交
220 221
	 * Recurse into sublink subqueries, too.  But we already did the ones in
	 * the rtable.
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252
	 */
	if (parsetree->hasSubLinks)
		query_tree_walker(parsetree, acquireLocksOnSubLinks, NULL,
						  QTW_IGNORE_RT_SUBQUERIES);
}

/*
 * Walker to find sublink subqueries for AcquireRewriteLocks
 */
static bool
acquireLocksOnSubLinks(Node *node, void *context)
{
	if (node == NULL)
		return false;
	if (IsA(node, SubLink))
	{
		SubLink    *sub = (SubLink *) node;

		/* Do what we came for */
		AcquireRewriteLocks((Query *) sub->subselect);
		/* 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);
}


253
/*
254 255 256
 * rewriteRuleAction -
 *	  Rewrite the rule action with appropriate qualifiers (taken from
 *	  the triggering query).
257
 */
258 259
static Query *
rewriteRuleAction(Query *parsetree,
260 261
				  Query *rule_action,
				  Node *rule_qual,
262
				  int rt_index,
263
				  CmdType event)
264
{
265 266 267
	int			current_varno,
				new_varno;
	int			rt_length;
268 269
	Query	   *sub_action;
	Query	  **sub_action_ptr;
270

271
	/*
B
Bruce Momjian 已提交
272 273
	 * Make modifiable copies of rule action and qual (what we're passed are
	 * the stored versions in the relcache; don't touch 'em!).
274 275 276 277
	 */
	rule_action = (Query *) copyObject(rule_action);
	rule_qual = (Node *) copyObject(rule_qual);

278 279 280 281 282 283
	/*
	 * Acquire necessary locks and fix any deleted JOIN RTE entries.
	 */
	AcquireRewriteLocks(rule_action);
	(void) acquireLocksOnSubLinks(rule_qual, NULL);

284
	current_varno = rt_index;
285
	rt_length = list_length(parsetree->rtable);
286
	new_varno = PRS2_NEW_VARNO + rt_length;
287

288
	/*
B
Bruce Momjian 已提交
289 290
	 * Adjust rule action and qual to offset its varnos, so that we can merge
	 * its rtable with the main parsetree's rtable.
291
	 *
292 293
	 * 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
B
Bruce Momjian 已提交
294
	 * top-level INSERT (kluge!).
295
	 */
296
	sub_action = getInsertSelectQuery(rule_action, &sub_action_ptr);
297

298
	OffsetVarNodes((Node *) sub_action, rt_length, 0);
299
	OffsetVarNodes(rule_qual, rt_length, 0);
300 301 302
	/* but references to *OLD* should point at original rt_index */
	ChangeVarNodes((Node *) sub_action,
				   PRS2_OLD_VARNO + rt_length, rt_index, 0);
303
	ChangeVarNodes(rule_qual,
304 305 306
				   PRS2_OLD_VARNO + rt_length, rt_index, 0);

	/*
307 308
	 * Generate expanded rtable consisting of main parsetree's rtable plus
	 * rule action's rtable; this becomes the complete rtable for the rule
B
Bruce Momjian 已提交
309 310
	 * action.	Some of the entries may be unused after we finish rewriting,
	 * but we leave them all in place for two reasons:
311
	 *
312 313
	 * We'd have a much harder job to adjust the query's varnos if we
	 * selectively removed RT entries.
314
	 *
315 316 317
	 * 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.
318 319
	 *
	 * RT entries that are not referenced in the completed jointree will be
B
Bruce Momjian 已提交
320 321 322 323 324
	 * 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.
325
	 *
326 327
	 * 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
B
Bruce Momjian 已提交
328
	 * original query, but we don't bother to treat that case differently.
329
	 *
330 331 332
	 * 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.
333
	 */
334
	sub_action->rtable = list_concat((List *) copyObject(parsetree->rtable),
B
Bruce Momjian 已提交
335
									 sub_action->rtable);
336

337 338
	/*
	 * Each rule action's jointree should be the main parsetree's jointree
B
Bruce Momjian 已提交
339 340 341 342 343 344 345 346
	 * 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
	 * the original rtindex in the jointree to provide data for the quals.	We
	 * don't want the original rtindex to be joined twice, however, so avoid
	 * keeping it if the rule action mentions it.
347
	 *
348 349
	 * As above, the action's jointree must not share substructure with the
	 * main parsetree's.
350
	 */
351
	if (sub_action->commandType != CMD_UTILITY)
352
	{
B
Bruce Momjian 已提交
353 354
		bool		keeporig;
		List	   *newjointree;
355

356
		Assert(sub_action->jointree != NULL);
B
Bruce Momjian 已提交
357 358
		keeporig = (!rangeTableEntry_used((Node *) sub_action->jointree,
										  rt_index, 0)) &&
359
			(rangeTableEntry_used(rule_qual, rt_index, 0) ||
B
Bruce Momjian 已提交
360
			 rangeTableEntry_used(parsetree->jointree->quals, rt_index, 0));
361
		newjointree = adjustJoinTreeList(parsetree, !keeporig, rt_index);
362 363 364
		if (newjointree != NIL)
		{
			/*
B
Bruce Momjian 已提交
365 366 367 368
			 * If sub_action is a setop, manipulating its jointree will do no
			 * good at all, because the jointree is dummy.	(Perhaps someday
			 * we could push the joining and quals down to the member
			 * statements of the setop?)
369 370
			 */
			if (sub_action->setOperations != NULL)
371 372 373
				ereport(ERROR,
						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
						 errmsg("conditional UNION/INTERSECT/EXCEPT statements are not implemented")));
374 375

			sub_action->jointree->fromlist =
376
				list_concat(newjointree, sub_action->jointree->fromlist);
377 378 379 380 381 382 383 384

			/*
			 * 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);
385
		}
386 387 388
	}

	/*
B
Bruce Momjian 已提交
389 390 391
	 * 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
392
	 */
393
	AddQual(sub_action, rule_qual);
394 395 396 397

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

	/*
B
Bruce Momjian 已提交
398 399
	 * Rewrite new.attribute w/ right hand side of target-list entry for
	 * appropriate field name in insert/update.
400
	 *
401 402 403
	 * KLUGE ALERT: since ResolveNew 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.
404
	 */
405 406
	if ((event == CMD_INSERT || event == CMD_UPDATE) &&
		sub_action->commandType != CMD_UTILITY)
407 408
	{
		sub_action = (Query *) ResolveNew((Node *) sub_action,
409
										  new_varno,
410
										  0,
411 412
										  rt_fetch(new_varno,
												   sub_action->rtable),
413
										  parsetree->targetList,
414 415
										  event,
										  current_varno);
416 417 418
		if (sub_action_ptr)
			*sub_action_ptr = sub_action;
		else
419
			rule_action = sub_action;
420
	}
421

422
	return rule_action;
423 424
}

425
/*
426 427 428 429
 * 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
430 431
 * of the join).  Returns modified jointree list --- this is a separate copy
 * sharing no nodes with the original.
432
 */
433
static List *
434
adjustJoinTreeList(Query *parsetree, bool removert, int rt_index)
435
{
436
	List	   *newjointree = copyObject(parsetree->jointree->fromlist);
437
	ListCell   *l;
438

439
	if (removert)
B
Bruce Momjian 已提交
440
	{
441
		foreach(l, newjointree)
442
		{
443
			RangeTblRef *rtr = lfirst(l);
444

445 446
			if (IsA(rtr, RangeTblRef) &&
				rtr->rtindex == rt_index)
447
			{
448
				newjointree = list_delete_ptr(newjointree, rtr);
B
Bruce Momjian 已提交
449 450

				/*
B
Bruce Momjian 已提交
451
				 * foreach is safe because we exit loop after list_delete...
B
Bruce Momjian 已提交
452
				 */
453 454
				break;
			}
455
		}
456
	}
457
	return newjointree;
458
}
459

460

461 462 463 464 465 466 467 468 469
/*
 * rewriteTargetList - rewrite INSERT/UPDATE targetlist into standard form
 *
 * 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
470 471 472
 * down rewriter processing with extra tlist nodes.)  Also, for both INSERT
 * and UPDATE, replace explicit DEFAULT specifications with column default
 * expressions.
473 474
 *
 * 2. Merge multiple entries for the same target attribute, or declare error
475 476 477
 * 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;
478 479 480 481 482 483 484 485
 * We can merge such operations into a single assignment op.  Essentially,
 * the expression we want to produce in this case is like
 *		foo = array_set(array_set(foo, 2, 42), 4, 43)
 *
 * 3. Sort the tlist into standard order: non-junk fields in order by resno,
 * then junk fields (these in no particular order).
 *
 * We must do items 1 and 2 before firing rewrite rules, else rewritten
B
Bruce Momjian 已提交
486
 * references to NEW.foo will produce wrong or incomplete results.	Item 3
487 488 489 490 491 492 493
 * is not needed for rewriting, but will be needed by the planner, and we
 * can do it essentially for free while handling items 1 and 2.
 */
static void
rewriteTargetList(Query *parsetree, Relation target_relation)
{
	CmdType		commandType = parsetree->commandType;
494
	TargetEntry **new_tles;
495
	List	   *new_tlist = NIL;
496 497
	List	   *junk_tlist = NIL;
	Form_pg_attribute att_tup;
498
	int			attrno,
499
				next_junk_attrno,
500
				numattrs;
501
	ListCell   *temp;
502 503

	/*
B
Bruce Momjian 已提交
504 505 506 507
	 * 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.
508
	 *
B
Bruce Momjian 已提交
509 510
	 * Junk attributes are tossed into a separate list during the same tlist
	 * scan, then appended to the reconstructed tlist.
511 512
	 */
	numattrs = RelationGetNumberOfAttributes(target_relation);
513 514
	new_tles = (TargetEntry **) palloc0(numattrs * sizeof(TargetEntry *));
	next_junk_attrno = numattrs + 1;
515

516
	foreach(temp, parsetree->targetList)
517
	{
518
		TargetEntry *old_tle = (TargetEntry *) lfirst(temp);
519

520
		if (!old_tle->resjunk)
521 522
		{
			/* Normal attr: stash it into new_tles[] */
523
			attrno = old_tle->resno;
524 525 526 527 528 529 530 531 532 533 534 535 536 537 538
			if (attrno < 1 || attrno > numattrs)
				elog(ERROR, "bogus resno %d in targetlist", attrno);
			att_tup = target_relation->rd_att->attrs[attrno - 1];

			/* 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
539
		{
540
			/*
B
Bruce Momjian 已提交
541 542
			 * Copy all resjunk tlist entries to junk_tlist, and assign them
			 * resnos above the last real resno.
543
			 *
544 545
			 * Typical junk entries include ORDER BY or GROUP BY expressions
			 * (are these actually possible in an INSERT or UPDATE?), system
546 547
			 * attribute references, etc.
			 */
548

549
			/* Get the resno right, but don't copy unnecessarily */
550
			if (old_tle->resno != next_junk_attrno)
551
			{
552 553
				old_tle = flatCopyTargetEntry(old_tle);
				old_tle->resno = next_junk_attrno;
554
			}
555 556
			junk_tlist = lappend(junk_tlist, old_tle);
			next_junk_attrno++;
557
		}
558 559 560 561 562 563 564 565 566 567 568
	}

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

		att_tup = target_relation->rd_att->attrs[attrno - 1];

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

570
		/*
B
Bruce Momjian 已提交
571 572 573
		 * 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.
574 575
		 */
		if ((new_tle == NULL && commandType == CMD_INSERT) ||
576
			(new_tle && new_tle->expr && IsA(new_tle->expr, SetToDefault)))
577 578 579 580 581
		{
			Node	   *new_expr;

			new_expr = build_column_default(target_relation, attrno);

582
			/*
B
Bruce Momjian 已提交
583 584 585 586 587
			 * 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.
588 589 590 591 592 593 594 595 596 597 598 599 600 601
			 */
			if (!new_expr)
			{
				if (commandType == CMD_INSERT)
					new_tle = NULL;
				else
				{
					new_expr = (Node *) makeConst(att_tup->atttypid,
												  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,
602
												InvalidOid, -1,
603
												att_tup->atttypid,
604
												COERCE_IMPLICIT_CAST,
605
												false,
606
												false);
607 608 609
				}
			}

610
			if (new_expr)
611 612 613 614
				new_tle = makeTargetEntry((Expr *) new_expr,
										  attrno,
										  pstrdup(NameStr(att_tup->attname)),
										  false);
615 616 617 618 619 620
		}

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

621
	pfree(new_tles);
622

623
	parsetree->targetList = list_concat(new_tlist, junk_tlist);
624 625 626 627 628 629 630
}


/*
 * Convert a matched TLE from the original tlist into a correct new TLE.
 *
 * This routine detects and handles multiple assignments to the same target
631
 * attribute.  (The attribute name is needed only for error messages.)
632 633 634
 */
static TargetEntry *
process_matched_tle(TargetEntry *src_tle,
635 636
					TargetEntry *prior_tle,
					const char *attrName)
637
{
638
	TargetEntry *result;
639 640 641 642
	Node	   *src_expr;
	Node	   *prior_expr;
	Node	   *src_input;
	Node	   *prior_input;
643
	Node	   *priorbottom;
644
	Node	   *newexpr;
645 646 647 648

	if (prior_tle == NULL)
	{
		/*
B
Bruce Momjian 已提交
649
		 * Normal case where this is the first assignment to the attribute.
650 651 652 653
		 */
		return src_tle;
	}

654
	/*----------
655
	 * Multiple assignments to same attribute.	Allow only if all are
656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672
	 * FieldStore or ArrayRef assignment operations.  This is a bit
	 * 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))
	 *		FieldStore(col, fld2, FieldStore(placeholder, subfld2, x))
	 * However, we can ignore the substructure and just consider the top
	 * FieldStore or ArrayRef from each assignment, because it works to
	 * combine these as
	 *		FieldStore(FieldStore(col, fld1,
	 *							  FieldStore(placeholder, subfld1, x)),
	 *				   fld2, FieldStore(placeholder, subfld2, x))
	 * 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
B
Bruce Momjian 已提交
673
	 * FieldStore with multiple target fields.	We must nest when
674 675
	 * ArrayRefs are involved though.
	 *----------
676
	 */
677 678 679 680 681 682 683
	src_expr = (Node *) src_tle->expr;
	prior_expr = (Node *) prior_tle->expr;
	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))
684 685
		ereport(ERROR,
				(errcode(ERRCODE_SYNTAX_ERROR),
686
				 errmsg("multiple assignments to same column \"%s\"",
687
						attrName)));
688 689

	/*
B
Bruce Momjian 已提交
690
	 * Prior TLE could be a nest of assignments if we do this more than once.
691
	 */
692 693 694
	priorbottom = prior_input;
	for (;;)
	{
B
Bruce Momjian 已提交
695
		Node	   *newbottom = get_assignment_input(priorbottom);
696 697 698 699 700 701

		if (newbottom == NULL)
			break;				/* found the original Var reference */
		priorbottom = newbottom;
	}
	if (!equal(priorbottom, src_input))
702 703
		ereport(ERROR,
				(errcode(ERRCODE_SYNTAX_ERROR),
704
				 errmsg("multiple assignments to same column \"%s\"",
705
						attrName)));
706 707 708 709

	/*
	 * Looks OK to nest 'em.
	 */
710 711
	if (IsA(src_expr, FieldStore))
	{
B
Bruce Momjian 已提交
712
		FieldStore *fstore = makeNode(FieldStore);
713 714 715 716 717 718 719

		if (IsA(prior_expr, FieldStore))
		{
			/* combine the two */
			memcpy(fstore, prior_expr, sizeof(FieldStore));
			fstore->newvals =
				list_concat(list_copy(((FieldStore *) prior_expr)->newvals),
B
Bruce Momjian 已提交
720
							list_copy(((FieldStore *) src_expr)->newvals));
721 722
			fstore->fieldnums =
				list_concat(list_copy(((FieldStore *) prior_expr)->fieldnums),
B
Bruce Momjian 已提交
723
							list_copy(((FieldStore *) src_expr)->fieldnums));
724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745
		}
		else
		{
			/* general case, just nest 'em */
			memcpy(fstore, src_expr, sizeof(FieldStore));
			fstore->arg = (Expr *) prior_expr;
		}
		newexpr = (Node *) fstore;
	}
	else if (IsA(src_expr, ArrayRef))
	{
		ArrayRef   *aref = makeNode(ArrayRef);

		memcpy(aref, src_expr, sizeof(ArrayRef));
		aref->refexpr = (Expr *) prior_expr;
		newexpr = (Node *) aref;
	}
	else
	{
		elog(ERROR, "can't happen");
		newexpr = NULL;
	}
746

747 748 749
	result = flatCopyTargetEntry(src_tle);
	result->expr = (Expr *) newexpr;
	return result;
750 751
}

752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775
/*
 * 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;
	}
	else if (IsA(node, ArrayRef))
	{
		ArrayRef   *aref = (ArrayRef *) node;

		if (aref->refassgnexpr == NULL)
			return NULL;
		return (Node *) aref->refexpr;
	}
	return NULL;
}
776 777 778 779 780 781

/*
 * Make an expression tree for the default value for a column.
 *
 * If there is no default, return a NULL instead.
 */
782
Node *
783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815
build_column_default(Relation rel, int attrno)
{
	TupleDesc	rd_att = rel->rd_att;
	Form_pg_attribute att_tup = rd_att->attrs[attrno - 1];
	Oid			atttype = att_tup->atttypid;
	int32		atttypmod = att_tup->atttypmod;
	Node	   *expr = NULL;
	Oid			exprtype;

	/*
	 * Scan to see if relation has a default for this column.
	 */
	if (rd_att->constr && rd_att->constr->num_defval > 0)
	{
		AttrDefault *defval = rd_att->constr->defval;
		int			ndef = rd_att->constr->num_defval;

		while (--ndef >= 0)
		{
			if (attrno == defval[ndef].adnum)
			{
				/*
				 * Found it, convert string representation to node tree.
				 */
				expr = stringToNode(defval[ndef].adbin);
				break;
			}
		}
	}

	if (expr == NULL)
	{
		/*
B
Bruce Momjian 已提交
816
		 * No per-column default, so look for a default for the type itself.
817
		 */
818
		expr = get_typdefault(atttype);
819 820 821 822 823 824
	}

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

	/*
825 826
	 * 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
B
Bruce Momjian 已提交
827 828
	 * involving domain defaults where it might not be true. This should match
	 * the parser's processing of non-defaulted expressions --- see
B
Bruce Momjian 已提交
829
	 * updateTargetListEntry().
830 831 832
	 */
	exprtype = exprType(expr);

B
Bruce Momjian 已提交
833
	expr = coerce_to_target_type(NULL,	/* no UNKNOWN params here */
834
								 expr, exprtype,
835 836 837 838
								 atttype, atttypmod,
								 COERCION_ASSIGNMENT,
								 COERCE_IMPLICIT_CAST);
	if (expr == NULL)
839 840 841 842 843 844 845
		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)),
B
Bruce Momjian 已提交
846
			   errhint("You will need to rewrite or cast the expression.")));
847 848 849 850 851

	return expr;
}


852
/*
853 854
 * matchLocks -
 *	  match the list of locks and returns the matching rules
855
 */
856 857 858 859 860
static List *
matchLocks(CmdType event,
		   RuleLock *rulelocks,
		   int varno,
		   Query *parsetree)
861
{
862
	List	   *matching_locks = NIL;
863 864
	int			nlocks;
	int			i;
865

866 867
	if (rulelocks == NULL)
		return NIL;
868

869
	if (parsetree->commandType != CMD_SELECT)
870
	{
871 872
		if (parsetree->resultRelation != varno)
			return NIL;
873
	}
874

875
	nlocks = rulelocks->numLocks;
876

877
	for (i = 0; i < nlocks; i++)
B
Bruce Momjian 已提交
878
	{
879
		RewriteRule *oneLock = rulelocks->rules[i];
880

881
		if (oneLock->event == event)
882
		{
883 884 885 886 887
			if (parsetree->commandType != CMD_SELECT ||
				(oneLock->attrno == -1 ?
				 rangeTableEntry_used((Node *) parsetree, varno, 0) :
				 attribute_used((Node *) parsetree,
								varno, oneLock->attrno, 0)))
888
				matching_locks = lappend(matching_locks, oneLock);
889
		}
890
	}
891

892
	return matching_locks;
893 894
}

895

896 897 898
/*
 * ApplyRetrieveRule - expand an ON SELECT rule
 */
899 900 901 902 903 904
static Query *
ApplyRetrieveRule(Query *parsetree,
				  RewriteRule *rule,
				  int rt_index,
				  bool relation_level,
				  Relation relation,
905
				  List *activeRIRs)
906 907 908 909
{
	Query	   *rule_action;
	RangeTblEntry *rte,
			   *subrte;
910

911
	if (list_length(rule->actions) != 1)
912
		elog(ERROR, "expected just one rule action");
913
	if (rule->qual != NULL)
914
		elog(ERROR, "cannot handle qualified ON SELECT rule");
B
Bruce Momjian 已提交
915
	if (!relation_level)
916
		elog(ERROR, "cannot handle per-attribute ON SELECT rule");
917

918
	/*
B
Bruce Momjian 已提交
919 920
	 * Make a modifiable copy of the view query, and acquire needed locks on
	 * the relations it mentions.
921
	 */
922
	rule_action = copyObject(linitial(rule->actions));
923

924 925 926 927 928
	AcquireRewriteLocks(rule_action);

	/*
	 * Recursively expand any view references inside the view.
	 */
929
	rule_action = fireRIRrules(rule_action, activeRIRs);
930

931
	/*
B
Bruce Momjian 已提交
932 933
	 * VIEWs are really easy --- just plug the view query in as a subselect,
	 * replacing the relation's original RTE.
934
	 */
935
	rte = rt_fetch(rt_index, parsetree->rtable);
936

937
	rte->rtekind = RTE_SUBQUERY;
938 939 940
	rte->relid = InvalidOid;
	rte->subquery = rule_action;
	rte->inh = false;			/* must not be set for a subquery */
941

942
	/*
B
Bruce Momjian 已提交
943 944
	 * We move the view's permission check data down to its rangetable. The
	 * checks will actually be done against the *OLD* entry therein.
945
	 */
946 947
	subrte = rt_fetch(PRS2_OLD_VARNO, rule_action->rtable);
	Assert(subrte->relid == relation->rd_id);
948
	subrte->requiredPerms = rte->requiredPerms;
949
	subrte->checkAsUser = rte->checkAsUser;
950

951
	rte->requiredPerms = 0;		/* no permission check on subquery itself */
952
	rte->checkAsUser = InvalidOid;
953

954
	/*
955
	 * FOR UPDATE/SHARE of view?
956
	 */
957
	if (list_member_int(parsetree->rowMarks, rt_index))
958
	{
959
		/*
B
Bruce Momjian 已提交
960 961 962
		 * Remove the view from the list of rels that will actually be marked
		 * FOR UPDATE/SHARE by the executor.  It will still be access- checked
		 * for write access, though.
963
		 */
964
		parsetree->rowMarks = list_delete_int(parsetree->rowMarks, rt_index);
B
Bruce Momjian 已提交
965 966

		/*
967
		 * Set up the view's referenced tables as if FOR UPDATE/SHARE.
968
		 */
969 970
		markQueryForLocking(rule_action, parsetree->forUpdate,
							parsetree->rowNoWait, true);
971 972
	}

973
	return parsetree;
974 975
}

976
/*
977
 * Recursively mark all relations used by a view as FOR UPDATE/SHARE.
978 979 980 981
 *
 * This may generate an invalid query, eg if some sub-query uses an
 * aggregate.  We leave it to the planner to detect that.
 *
982
 * NB: this must agree with the parser's transformLocking() routine.
983 984
 */
static void
985
markQueryForLocking(Query *qry, bool forUpdate, bool noWait, bool skipOldNew)
986 987
{
	Index		rti = 0;
988
	ListCell   *l;
989

990 991 992 993 994
	if (qry->rowMarks)
	{
		if (forUpdate != qry->forUpdate)
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
B
Bruce Momjian 已提交
995
			errmsg("cannot use both FOR UPDATE and FOR SHARE in one query")));
996 997 998 999 1000
		if (noWait != qry->rowNoWait)
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
					 errmsg("cannot use both wait and NOWAIT in one query")));
	}
1001
	qry->forUpdate = forUpdate;
1002
	qry->rowNoWait = noWait;
1003

1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014
	foreach(l, qry->rtable)
	{
		RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);

		rti++;

		/* Ignore OLD and NEW entries if we are at top level of view */
		if (skipOldNew &&
			(rti == PRS2_OLD_VARNO || rti == PRS2_NEW_VARNO))
			continue;

1015
		if (rte->rtekind == RTE_RELATION)
1016
		{
1017
			qry->rowMarks = list_append_unique_int(qry->rowMarks, rti);
1018
			rte->requiredPerms |= ACL_SELECT_FOR_UPDATE;
1019
		}
1020 1021
		else if (rte->rtekind == RTE_SUBQUERY)
		{
1022
			/* FOR UPDATE/SHARE of subquery is propagated to subquery's rels */
1023
			markQueryForLocking(rte->subquery, forUpdate, noWait, false);
1024
		}
1025 1026 1027
	}
}

1028

1029
/*
1030 1031 1032
 * fireRIRonSubLink -
 *	Apply fireRIRrules() to each SubLink (subselect in expression) found
 *	in the given tree.
1033 1034
 *
 * NOTE: although this has the form of a walker, we cheat and modify the
1035
 * SubLink nodes in-place.	It is caller's responsibility to ensure that
1036
 * no unwanted side-effects occur!
1037 1038 1039 1040
 *
 * 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.
1041 1042
 */
static bool
1043
fireRIRonSubLink(Node *node, List *activeRIRs)
1044 1045
{
	if (node == NULL)
1046 1047
		return false;
	if (IsA(node, SubLink))
B
Bruce Momjian 已提交
1048
	{
1049 1050 1051
		SubLink    *sub = (SubLink *) node;

		/* Do what we came for */
1052 1053
		sub->subselect = (Node *) fireRIRrules((Query *) sub->subselect,
											   activeRIRs);
1054
		/* Fall through to process lefthand args of SubLink */
1055
	}
B
Bruce Momjian 已提交
1056

1057
	/*
B
Bruce Momjian 已提交
1058 1059
	 * Do NOT recurse into Query nodes, because fireRIRrules already processed
	 * subselects of subselects for us.
1060
	 */
1061
	return expression_tree_walker(node, fireRIRonSubLink,
1062
								  (void *) activeRIRs);
1063 1064 1065 1066 1067 1068 1069 1070
}


/*
 * fireRIRrules -
 *	Apply all RIR rules on each rangetable entry in a query
 */
static Query *
1071
fireRIRrules(Query *parsetree, List *activeRIRs)
1072
{
B
Bruce Momjian 已提交
1073
	int			rt_index;
1074

1075
	/*
B
Bruce Momjian 已提交
1076 1077
	 * don't try to convert this into a foreach loop, because rtable list can
	 * get changed each time through...
1078
	 */
1079
	rt_index = 0;
1080
	while (rt_index < list_length(parsetree->rtable))
B
Bruce Momjian 已提交
1081
	{
1082 1083 1084 1085 1086 1087 1088
		RangeTblEntry *rte;
		Relation	rel;
		List	   *locks;
		RuleLock   *rules;
		RewriteRule *rule;
		int			i;

1089 1090
		++rt_index;

1091
		rte = rt_fetch(rt_index, parsetree->rtable);
1092

1093
		/*
B
Bruce Momjian 已提交
1094 1095
		 * 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
1096 1097
		 * subquery to expand any rule references in it.
		 */
1098
		if (rte->rtekind == RTE_SUBQUERY)
1099
		{
1100
			rte->subquery = fireRIRrules(rte->subquery, activeRIRs);
1101 1102 1103
			continue;
		}

1104 1105 1106 1107 1108 1109
		/*
		 * Joins and other non-relation RTEs can be ignored completely.
		 */
		if (rte->rtekind != RTE_RELATION)
			continue;

1110
		/*
1111 1112 1113
		 * 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
B
Bruce Momjian 已提交
1114 1115
		 * part of the join set (a source table), or is referenced by any Var
		 * nodes, or is the result table.
1116
		 */
1117 1118
		if (rt_index != parsetree->resultRelation &&
			!rangeTableEntry_used((Node *) parsetree, rt_index, 0))
1119
			continue;
B
Bruce Momjian 已提交
1120

1121
		/*
1122 1123
		 * We can use NoLock here since either the parser or
		 * AcquireRewriteLocks should have locked the rel already.
1124
		 */
1125
		rel = heap_open(rte->relid, NoLock);
1126 1127 1128 1129

		/*
		 * Collect the RIR rules that we must apply
		 */
1130 1131
		rules = rel->rd_rules;
		if (rules == NULL)
B
Bruce Momjian 已提交
1132
		{
1133
			heap_close(rel, NoLock);
1134 1135
			continue;
		}
1136
		locks = NIL;
B
Bruce Momjian 已提交
1137 1138
		for (i = 0; i < rules->numLocks; i++)
		{
1139 1140 1141
			rule = rules->rules[i];
			if (rule->event != CMD_SELECT)
				continue;
B
Bruce Momjian 已提交
1142

1143 1144 1145
			if (rule->attrno > 0)
			{
				/* per-attr rule; do we need it? */
1146
				if (!attribute_used((Node *) parsetree, rt_index,
1147
									rule->attrno, 0))
1148 1149
					continue;
			}
1150 1151 1152 1153 1154

			locks = lappend(locks, rule);
		}

		/*
1155
		 * If we found any, apply them --- but first check for recursion!
1156
		 */
1157
		if (locks != NIL)
B
Bruce Momjian 已提交
1158
		{
1159
			ListCell   *l;
1160

1161
			if (list_member_oid(activeRIRs, RelationGetRelid(rel)))
1162 1163 1164 1165
				ereport(ERROR,
						(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
						 errmsg("infinite recursion detected in rules for relation \"%s\"",
								RelationGetRelationName(rel))));
1166
			activeRIRs = lcons_oid(RelationGetRelid(rel), activeRIRs);
1167 1168 1169 1170 1171 1172 1173 1174 1175 1176

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

				parsetree = ApplyRetrieveRule(parsetree,
											  rule,
											  rt_index,
											  rule->attrno == -1,
											  rel,
1177
											  activeRIRs);
1178
			}
1179 1180

			activeRIRs = list_delete_first(activeRIRs);
1181 1182
		}

1183
		heap_close(rel, NoLock);
1184 1185
	}

1186
	/*
B
Bruce Momjian 已提交
1187 1188
	 * Recurse into sublink subqueries, too.  But we already did the ones in
	 * the rtable.
1189 1190
	 */
	if (parsetree->hasSubLinks)
1191
		query_tree_walker(parsetree, fireRIRonSubLink, (void *) activeRIRs,
1192
						  QTW_IGNORE_RT_SUBQUERIES);
1193 1194 1195 1196 1197

	return parsetree;
}


1198
/*
1199 1200 1201 1202 1203
 * 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.)
1204
 *
B
Bruce Momjian 已提交
1205
 * The rule_qual may contain references to OLD or NEW.	OLD references are
1206 1207 1208 1209 1210
 * 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.
 */
1211
static Query *
1212 1213 1214 1215
CopyAndAddInvertedQual(Query *parsetree,
					   Node *rule_qual,
					   int rt_index,
					   CmdType event)
1216
{
1217
	/* Don't scribble on the passed qual (it's in the relcache!) */
1218 1219
	Node	   *new_qual = (Node *) copyObject(rule_qual);

1220 1221 1222
	/*
	 * In case there are subqueries in the qual, acquire necessary locks and
	 * fix any deleted JOIN RTE entries.  (This is somewhat redundant with
B
Bruce Momjian 已提交
1223 1224
	 * rewriteRuleAction, but not entirely ... consider restructuring so that
	 * we only need to process the qual this way once.)
1225 1226 1227
	 */
	(void) acquireLocksOnSubLinks(new_qual, NULL);

1228 1229 1230 1231 1232 1233 1234
	/* Fix references to OLD */
	ChangeVarNodes(new_qual, PRS2_OLD_VARNO, rt_index, 0);
	/* Fix references to NEW */
	if (event == CMD_INSERT || event == CMD_UPDATE)
		new_qual = ResolveNew(new_qual,
							  PRS2_NEW_VARNO,
							  0,
1235
							  rt_fetch(rt_index, parsetree->rtable),
1236 1237 1238 1239
							  parsetree->targetList,
							  event,
							  rt_index);
	/* And attach the fixed qual */
1240
	AddInvertedQual(parsetree, new_qual);
1241

1242
	return parsetree;
1243 1244 1245 1246
}


/*
1247
 *	fireRules -
M
 
Marc G. Fournier 已提交
1248
 *	   Iterate through rule locks applying rules.
1249
 *
1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261
 * 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:
 *	*instead_flag - set TRUE if any unqualified INSTEAD rule is found
 *					(must be initialized to FALSE)
 *	*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
1262
 *
1263 1264 1265 1266 1267 1268
 * 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
B
Bruce Momjian 已提交
1269
 * query if we find either qualified or unqualified INSTEAD rules.	If
1270
 * we find both, the modified original query is discarded too.
1271
 */
1272
static List *
1273
fireRules(Query *parsetree,
1274 1275
		  int rt_index,
		  CmdType event,
1276
		  List *locks,
1277 1278
		  bool *instead_flag,
		  Query **qual_product)
1279
{
1280
	List	   *results = NIL;
1281
	ListCell   *l;
1282

1283
	foreach(l, locks)
1284
	{
1285
		RewriteRule *rule_lock = (RewriteRule *) lfirst(l);
1286 1287
		Node	   *event_qual = rule_lock->qual;
		List	   *actions = rule_lock->actions;
B
Bruce Momjian 已提交
1288
		QuerySource qsrc;
1289
		ListCell   *r;
1290

1291 1292 1293 1294 1295 1296
		/* Determine correct QuerySource value for actions */
		if (rule_lock->isInstead)
		{
			if (event_qual != NULL)
				qsrc = QSRC_QUAL_INSTEAD_RULE;
			else
1297
			{
1298
				qsrc = QSRC_INSTEAD_RULE;
B
Bruce Momjian 已提交
1299
				*instead_flag = true;	/* report unqualified INSTEAD */
1300
			}
1301 1302 1303 1304 1305
		}
		else
			qsrc = QSRC_NON_INSTEAD_RULE;

		if (qsrc == QSRC_QUAL_INSTEAD_RULE)
1306
		{
1307
			/*
B
Bruce Momjian 已提交
1308 1309 1310 1311 1312 1313 1314
			 * 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.
1315
			 *
B
Bruce Momjian 已提交
1316 1317
			 * If we have already found an unqualified INSTEAD rule, then
			 * *qual_product won't be used, so don't bother building it.
M
 
Marc G. Fournier 已提交
1318
			 */
B
Bruce Momjian 已提交
1319
			if (!*instead_flag)
1320 1321
			{
				if (*qual_product == NULL)
1322
					*qual_product = copyObject(parsetree);
1323 1324 1325 1326
				*qual_product = CopyAndAddInvertedQual(*qual_product,
													   event_qual,
													   rt_index,
													   event);
1327
			}
M
 
Marc G. Fournier 已提交
1328 1329
		}

1330
		/* Now process the rule's actions and add them to the result list */
1331 1332
		foreach(r, actions)
		{
1333
			Query	   *rule_action = lfirst(r);
1334

M
 
Marc G. Fournier 已提交
1335 1336 1337
			if (rule_action->commandType == CMD_NOTHING)
				continue;

1338 1339
			rule_action = rewriteRuleAction(parsetree, rule_action,
											event_qual, rt_index, event);
1340

1341
			rule_action->querySource = qsrc;
1342
			rule_action->canSetTag = false;		/* might change later */
1343

1344
			results = lappend(results, rule_action);
1345 1346
		}
	}
1347

1348
	return results;
1349 1350
}

M
 
Marc G. Fournier 已提交
1351

1352
/*
1353 1354
 * RewriteQuery -
 *	  rewrites the query and apply the rules again on the queries rewritten
1355
 *
1356 1357
 * rewrite_events is a list of open query-rewrite actions, so we can detect
 * infinite recursion.
1358
 */
1359
static List *
1360
RewriteQuery(Query *parsetree, List *rewrite_events)
1361
{
1362 1363 1364 1365
	CmdType		event = parsetree->commandType;
	bool		instead = false;
	Query	   *qual_product = NULL;
	List	   *rewritten = NIL;
1366

1367
	/*
1368 1369
	 * If the statement is an update, insert or delete - fire rules on it.
	 *
B
Bruce Momjian 已提交
1370 1371 1372
	 * 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?)
1373
	 */
1374 1375 1376 1377 1378 1379
	if (event != CMD_SELECT && event != CMD_UTILITY)
	{
		int			result_relation;
		RangeTblEntry *rt_entry;
		Relation	rt_entry_relation;
		List	   *locks;
1380

1381 1382 1383 1384
		result_relation = parsetree->resultRelation;
		Assert(result_relation != 0);
		rt_entry = rt_fetch(result_relation, parsetree->rtable);
		Assert(rt_entry->rtekind == RTE_RELATION);
M
 
Marc G. Fournier 已提交
1385

1386
		/*
1387 1388
		 * We can use NoLock here since either the parser or
		 * AcquireRewriteLocks should have locked the rel already.
1389
		 */
1390
		rt_entry_relation = heap_open(rt_entry->relid, NoLock);
1391

1392
		/*
B
Bruce Momjian 已提交
1393 1394 1395
		 * If it's an INSERT or UPDATE, rewrite the targetlist into standard
		 * form.  This will be needed by the planner anyway, and doing it now
		 * ensures that any references to NEW.field will behave sanely.
1396 1397 1398
		 */
		if (event == CMD_INSERT || event == CMD_UPDATE)
			rewriteTargetList(parsetree, rt_entry_relation);
1399

1400 1401 1402 1403 1404
		/*
		 * Collect and apply the appropriate rules.
		 */
		locks = matchLocks(event, rt_entry_relation->rd_rules,
						   result_relation, parsetree);
1405

1406 1407 1408
		if (locks != NIL)
		{
			List	   *product_queries;
1409

1410 1411 1412 1413 1414 1415
			product_queries = fireRules(parsetree,
										result_relation,
										event,
										locks,
										&instead,
										&qual_product);
1416

1417
			/*
B
Bruce Momjian 已提交
1418 1419
			 * If we got any product queries, recursively rewrite them --- but
			 * first check for recursion!
1420 1421 1422
			 */
			if (product_queries != NIL)
			{
B
Bruce Momjian 已提交
1423 1424
				ListCell   *n;
				rewrite_event *rev;
1425

1426 1427 1428 1429 1430
				foreach(n, rewrite_events)
				{
					rev = (rewrite_event *) lfirst(n);
					if (rev->relation == RelationGetRelid(rt_entry_relation) &&
						rev->event == event)
1431
						ereport(ERROR,
B
Bruce Momjian 已提交
1432 1433 1434
								(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
								 errmsg("infinite recursion detected in rules for relation \"%s\"",
							   RelationGetRelationName(rt_entry_relation))));
1435
				}
1436

1437 1438 1439 1440
				rev = (rewrite_event *) palloc(sizeof(rewrite_event));
				rev->relation = RelationGetRelid(rt_entry_relation);
				rev->event = event;
				rewrite_events = lcons(rev, rewrite_events);
1441

1442 1443 1444 1445
				foreach(n, product_queries)
				{
					Query	   *pt = (Query *) lfirst(n);
					List	   *newstuff;
1446

1447
					newstuff = RewriteQuery(pt, rewrite_events);
1448
					rewritten = list_concat(rewritten, newstuff);
1449
				}
1450 1451

				rewrite_events = list_delete_first(rewrite_events);
1452 1453
			}
		}
1454

1455
		heap_close(rt_entry_relation, NoLock);
1456
	}
M
 
Marc G. Fournier 已提交
1457

1458
	/*
B
Bruce Momjian 已提交
1459 1460 1461 1462 1463 1464
	 * 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.
1465
	 *
B
Bruce Momjian 已提交
1466 1467 1468
	 * 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.
M
 
Marc G. Fournier 已提交
1469
	 */
1470
	if (!instead)
1471
	{
1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485
		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);
		}
1486
	}
M
 
Marc G. Fournier 已提交
1487

1488 1489
	return rewritten;
}
1490 1491 1492


/*
1493 1494 1495 1496 1497
 * QueryRewrite -
 *	  Primary entry point to the query rewriter.
 *	  Rewrite one query via query rewrite system, possibly returning 0
 *	  or many queries.
 *
1498 1499
 * NOTE: the parsetree must either have come straight from the parser,
 * or have been scanned by AcquireRewriteLocks to acquire suitable locks.
1500
 */
1501 1502
List *
QueryRewrite(Query *parsetree)
1503
{
B
Bruce Momjian 已提交
1504 1505
	List	   *querylist;
	List	   *results = NIL;
1506
	ListCell   *l;
1507 1508 1509
	CmdType		origCmdType;
	bool		foundOriginalQuery;
	Query	   *lastInstead;
1510 1511 1512 1513 1514 1515

	/*
	 * Step 1
	 *
	 * Apply all non-SELECT rules possibly getting 0 or many queries
	 */
1516
	querylist = RewriteQuery(parsetree, NIL);
1517 1518

	/*
1519
	 * Step 2
1520 1521 1522
	 *
	 * Apply all the RIR rules on each query
	 */
B
Bruce Momjian 已提交
1523 1524
	foreach(l, querylist)
	{
B
Bruce Momjian 已提交
1525
		Query	   *query = (Query *) lfirst(l);
B
Bruce Momjian 已提交
1526

1527
		query = fireRIRrules(query, NIL);
1528

B
Bruce Momjian 已提交
1529
		/*
1530
		 * If the query target was rewritten as a view, complain.
B
Bruce Momjian 已提交
1531
		 */
1532
		if (query->resultRelation)
B
Bruce Momjian 已提交
1533
		{
1534 1535
			RangeTblEntry *rte = rt_fetch(query->resultRelation,
										  query->rtable);
B
Bruce Momjian 已提交
1536

1537
			if (rte->rtekind == RTE_SUBQUERY)
B
Bruce Momjian 已提交
1538
			{
1539 1540 1541
				switch (query->commandType)
				{
					case CMD_INSERT:
1542 1543 1544 1545
						ereport(ERROR,
								(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
								 errmsg("cannot insert into a view"),
								 errhint("You need an unconditional ON INSERT DO INSTEAD rule.")));
1546 1547
						break;
					case CMD_UPDATE:
1548 1549 1550 1551
						ereport(ERROR,
								(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
								 errmsg("cannot update a view"),
								 errhint("You need an unconditional ON UPDATE DO INSTEAD rule.")));
1552 1553
						break;
					case CMD_DELETE:
1554 1555 1556 1557
						ereport(ERROR,
								(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
								 errmsg("cannot delete from a view"),
								 errhint("You need an unconditional ON DELETE DO INSTEAD rule.")));
1558 1559
						break;
					default:
1560
						elog(ERROR, "unrecognized commandType: %d",
1561 1562 1563
							 (int) query->commandType);
						break;
				}
B
Bruce Momjian 已提交
1564 1565 1566
			}
		}

1567
		results = lappend(results, query);
B
Bruce Momjian 已提交
1568
	}
1569

1570 1571 1572
	/*
	 * Step 3
	 *
1573 1574
	 * Determine which, if any, of the resulting queries is supposed to set
	 * the command-result tag; and update the canSetTag fields accordingly.
1575 1576
	 *
	 * If the original query is still in the list, it sets the command tag.
B
Bruce Momjian 已提交
1577 1578 1579 1580
	 * Otherwise, the last INSTEAD query of the same kind as the original is
	 * allowed to set the tag.	(Note these rules can leave us with no query
	 * setting the tag.  The tcop code has to cope with this by setting up a
	 * default tag based on the original un-rewritten query.)
1581 1582
	 *
	 * The Asserts verify that at most one query in the result list is marked
B
Bruce Momjian 已提交
1583 1584
	 * canSetTag.  If we aren't checking asserts, we can fall out of the loop
	 * as soon as we find the original query.
1585 1586 1587 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
	 */
	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;

1616
	return results;
B
Hi!  
Bruce Momjian 已提交
1617
}