subselect.c 29.1 KB
Newer Older
1 2
/*-------------------------------------------------------------------------
 *
3
 * subselect.c
4 5
 *	  Planning routines for subselects and parameters.
 *
B
Bruce Momjian 已提交
6
 * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
B
Add:  
Bruce Momjian 已提交
7
 * Portions Copyright (c) 1994, Regents of the University of California
8 9
 *
 * IDENTIFICATION
10
 *	  $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.73 2003/03/10 03:53:50 tgl Exp $
11 12 13 14 15
 *
 *-------------------------------------------------------------------------
 */
#include "postgres.h"

16
#include "catalog/pg_operator.h"
17
#include "catalog/pg_type.h"
18
#include "miscadmin.h"
19
#include "nodes/makefuncs.h"
20
#include "nodes/params.h"
21
#include "optimizer/clauses.h"
22 23
#include "optimizer/cost.h"
#include "optimizer/planmain.h"
B
Bruce Momjian 已提交
24 25
#include "optimizer/planner.h"
#include "optimizer/subselect.h"
26
#include "optimizer/var.h"
27
#include "parser/parsetree.h"
28 29
#include "parser/parse_expr.h"
#include "parser/parse_oper.h"
30
#include "parser/parse_relation.h"
31
#include "utils/lsyscache.h"
32
#include "utils/syscache.h"
33

34

35
Index		PlannerQueryLevel;	/* level of current query */
36
List	   *PlannerInitPlan;	/* init subplans for current query */
37
List	   *PlannerParamVar;	/* to get Var from Param->paramid */
38 39

int			PlannerPlanId = 0;	/* to assign unique ID to subquery plans */
40 41 42 43 44 45 46 47 48 49 50 51

/*--------------------
 * PlannerParamVar is a list of Var nodes, wherein the n'th entry
 * (n counts from 0) corresponds to Param->paramid = n.  The Var nodes
 * are ordinary except for one thing: their varlevelsup field does NOT
 * have the usual interpretation of "subplan levels out from current".
 * Instead, it contains the absolute plan level, with the outermost
 * plan being level 1 and nested plans having higher level numbers.
 * This nonstandardness is useful because we don't have to run around
 * and update the list elements when we enter or exit a subplan
 * recursion level.  But we must pay attention not to confuse this
 * meaning with the normal meaning of varlevelsup.
52 53 54 55
 *
 * We also need to create Param slots that don't correspond to any outer Var.
 * For these, we set varno = 0 and varlevelsup = 0, so that they can't
 * accidentally match an outer Var.
56 57
 *--------------------
 */
58 59


60
typedef struct finalize_primnode_context
61
{
62 63 64
	Bitmapset   *paramids;		/* Set of PARAM_EXEC paramids found */
	Bitmapset   *outer_params;	/* Set of accessible outer paramids */
} finalize_primnode_context;
65 66


67
static List *convert_sublink_opers(List *lefthand, List *operOids,
68 69
								   List *targetlist, int rtindex,
								   List **righthandIds);
70
static bool subplan_is_hashable(SubLink *slink, SubPlan *node);
71
static Node *replace_correlation_vars_mutator(Node *node, void *context);
72
static Node *process_sublinks_mutator(Node *node, bool *isTopQual);
73 74 75 76
static Bitmapset *finalize_plan(Plan *plan, List *rtable,
								Bitmapset *outer_params,
								Bitmapset *valid_params);
static bool finalize_primnode(Node *node, finalize_primnode_context *context);
77 78


79 80 81
/*
 * Create a new entry in the PlannerParamVar list, and return its index.
 *
82 83 84 85
 * var contains the data to use, except for varlevelsup which
 * is set from the absolute level value given by varlevel.  NOTE that
 * the passed var is scribbled on and placed directly into the list!
 * Generally, caller should have just created or copied it.
86
 */
87
static int
88
new_param(Var *var, Index varlevel)
89
{
90
	var->varlevelsup = varlevel;
91

92
	PlannerParamVar = lappend(PlannerParamVar, var);
93

94
	return length(PlannerParamVar) - 1;
95 96
}

97 98 99 100
/*
 * Generate a Param node to replace the given Var,
 * which is expected to have varlevelsup > 0 (ie, it is not local).
 */
101
static Param *
102
replace_var(Var *var)
103
{
104
	List	   *ppv;
105
	Param	   *retval;
106
	Index		varlevel;
107 108
	int			i;

109 110
	Assert(var->varlevelsup > 0 && var->varlevelsup < PlannerQueryLevel);
	varlevel = PlannerQueryLevel - var->varlevelsup;
111

112
	/*
113
	 * If there's already a PlannerParamVar entry for this same Var, just
B
Bruce Momjian 已提交
114 115 116 117 118 119
	 * use it.	NOTE: in sufficiently complex querytrees, it is possible
	 * for the same varno/varlevel to refer to different RTEs in different
	 * parts of the parsetree, so that different fields might end up
	 * sharing the same Param number.  As long as we check the vartype as
	 * well, I believe that this sort of aliasing will cause no trouble.
	 * The correct field should get stored into the Param slot at
120
	 * execution in each part of the tree.
121 122 123
	 */
	i = 0;
	foreach(ppv, PlannerParamVar)
124
	{
125
		Var		   *pvar = lfirst(ppv);
126 127 128 129 130

		if (pvar->varno == var->varno &&
			pvar->varattno == var->varattno &&
			pvar->varlevelsup == varlevel &&
			pvar->vartype == var->vartype)
131
			break;
132
		i++;
133
	}
134

135
	if (!ppv)
136 137
	{
		/* Nope, so make a new one */
138
		i = new_param((Var *) copyObject(var), varlevel);
139
	}
140

141 142 143 144
	retval = makeNode(Param);
	retval->paramkind = PARAM_EXEC;
	retval->paramid = (AttrNumber) i;
	retval->paramtype = var->vartype;
145

146
	return retval;
147 148
}

149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
/*
 * Generate a new Param node that will not conflict with any other.
 */
static Param *
generate_new_param(Oid paramtype, int32 paramtypmod)
{
	Var		   *var = makeVar(0, 0, paramtype, paramtypmod, 0);
	Param	   *retval = makeNode(Param);

	retval->paramkind = PARAM_EXEC;
	retval->paramid = (AttrNumber) new_param(var, 0);
	retval->paramtype = paramtype;

	return retval;
}

165
/*
166 167 168
 * Convert a bare SubLink (as created by the parser) into a SubPlan.
 *
 * We are given the raw SubLink and the already-processed lefthand argument
169 170
 * list (use this instead of the SubLink's own field).  We are also told if
 * this expression appears at top level of a WHERE/HAVING qual.
171 172 173 174 175 176
 *
 * The result is whatever we need to substitute in place of the SubLink
 * node in the executable expression.  This will be either the SubPlan
 * node (if we have to do the subplan as a subplan), or a Param node
 * representing the result of an InitPlan, or possibly an AND or OR tree
 * containing InitPlan Param nodes.
177
 */
178
static Node *
179
make_subplan(SubLink *slink, List *lefthand, bool isTopQual)
180
{
181
	SubPlan	   *node = makeNode(SubPlan);
182
	Query	   *subquery = (Query *) (slink->subselect);
183
	double		tuple_fraction;
184
	Plan	   *plan;
185 186
	Bitmapset  *tmpset;
	int			paramid;
187 188
	List	   *lst;
	Node	   *result;
189

190
	/*
B
Bruce Momjian 已提交
191 192 193 194
	 * Copy the source Query node.	This is a quick and dirty kluge to
	 * resolve the fact that the parser can generate trees with multiple
	 * links to the same sub-Query node, but the planner wants to scribble
	 * on the Query. Try to clean this up when we do querytree redesign...
195 196 197
	 */
	subquery = (Query *) copyObject(subquery);

198
	/*
199 200 201 202 203 204 205
	 * For an EXISTS subplan, tell lower-level planner to expect that only
	 * the first tuple will be retrieved.  For ALL and ANY subplans, we
	 * will be able to stop evaluating if the test condition fails, so
	 * very often not all the tuples will be retrieved; for lack of a
	 * better idea, specify 50% retrieval.	For EXPR and MULTIEXPR
	 * subplans, use default behavior (we're only expecting one row out,
	 * anyway).
206
	 *
207 208 209
	 * NOTE: if you change these numbers, also change cost_qual_eval_walker()
	 * in path/costsize.c.
	 *
210 211 212
	 * XXX If an ALL/ANY subplan is uncorrelated, we may decide to hash or
	 * materialize its result below.  In that case it would've been better to
	 * specify full retrieval.  At present, however, we can only detect
213 214 215 216 217
	 * correlation or lack of it after we've made the subplan :-(. Perhaps
	 * detection of correlation should be done as a separate step.
	 * Meanwhile, we don't want to be too optimistic about the percentage
	 * of tuples retrieved, for fear of selecting a plan that's bad for
	 * the materialization case.
218 219 220
	 */
	if (slink->subLinkType == EXISTS_SUBLINK)
		tuple_fraction = 1.0;	/* just like a LIMIT 1 */
221 222
	else if (slink->subLinkType == ALL_SUBLINK ||
			 slink->subLinkType == ANY_SUBLINK)
223
		tuple_fraction = 0.5;	/* 50% */
224
	else
225
		tuple_fraction = 0.0;	/* default behavior */
226

227
	/*
228
	 * Generate the plan for the subquery.
229
	 */
230
	node->plan = plan = subquery_planner(subquery, tuple_fraction);
231

B
Bruce Momjian 已提交
232
	node->plan_id = PlannerPlanId++;	/* Assign unique ID to this
233
										 * SubPlan */
234

235
	node->rtable = subquery->rtable;
236

237
	/*
238
	 * Initialize other fields of the SubPlan node.
239 240
	 */
	node->subLinkType = slink->subLinkType;
241
	node->useOr = slink->useOr;
242 243 244
	node->exprs = NIL;
	node->paramIds = NIL;
	node->useHashTable = false;
245 246
	/* At top level of a qual, can treat UNKNOWN the same as FALSE */
	node->unknownEqFalse = isTopQual;
247 248 249
	node->setParam = NIL;
	node->parParam = NIL;
	node->args = NIL;
250

251
	/*
B
Bruce Momjian 已提交
252 253
	 * Make parParam list of params that current query level will pass to
	 * this child plan.
254
	 */
255 256
	tmpset = bms_copy(plan->extParam);
	while ((paramid = bms_first_member(tmpset)) >= 0)
257
	{
258
		Var		   *var = nth(paramid, PlannerParamVar);
259

260
		/* note varlevelsup is absolute level number */
261
		if (var->varlevelsup == PlannerQueryLevel)
262
			node->parParam = lappendi(node->parParam, paramid);
263
	}
264
	bms_free(tmpset);
265 266

	/*
267
	 * Un-correlated or undirect correlated plans of EXISTS, EXPR, or
268 269
	 * MULTIEXPR types can be used as initPlans.  For EXISTS or EXPR, we
	 * just produce a Param referring to the result of evaluating the
270 271 272
	 * initPlan.  For MULTIEXPR, we must build an AND or OR-clause of the
	 * individual comparison operators, using the appropriate lefthand
	 * side expressions and Params for the initPlan's target items.
273
	 */
274 275
	if (node->parParam == NIL && slink->subLinkType == EXISTS_SUBLINK)
	{
276
		Param	   *prm;
277

278
		prm = generate_new_param(BOOLOID, -1);
279
		node->setParam = makeListi1(prm->paramid);
280 281 282 283 284 285
		PlannerInitPlan = lappend(PlannerInitPlan, node);
		result = (Node *) prm;
	}
	else if (node->parParam == NIL && slink->subLinkType == EXPR_SUBLINK)
	{
		TargetEntry *te = lfirst(plan->targetlist);
286
		Param	   *prm;
287

288
		Assert(!te->resdom->resjunk);
289
		prm = generate_new_param(te->resdom->restype, te->resdom->restypmod);
290
		node->setParam = makeListi1(prm->paramid);
291 292 293 294
		PlannerInitPlan = lappend(PlannerInitPlan, node);
		result = (Node *) prm;
	}
	else if (node->parParam == NIL && slink->subLinkType == MULTIEXPR_SUBLINK)
295
	{
296 297 298 299 300 301
		List   *exprs;

		/* Convert the lefthand exprs and oper OIDs into executable exprs */
		exprs = convert_sublink_opers(lefthand,
									  slink->operOids,
									  plan->targetlist,
302
									  0,
303
									  &node->paramIds);
304
		node->setParam = listCopy(node->paramIds);
305
		PlannerInitPlan = lappend(PlannerInitPlan, node);
306 307 308 309 310 311 312 313
		/*
		 * The executable expressions are returned to become part of the
		 * outer plan's expression tree; they are not kept in the initplan
		 * node.
		 */
		if (length(exprs) > 1)
			result = (Node *) (node->useOr ? make_orclause(exprs) :
							   make_andclause(exprs));
314
		else
315
			result = (Node *) lfirst(exprs);
316
	}
317
	else
318
	{
319
		List	   *args;
320

321
		/*
322 323 324
		 * We can't convert subplans of ALL_SUBLINK or ANY_SUBLINK types
		 * to initPlans, even when they are uncorrelated or undirect
		 * correlated, because we need to scan the output of the subplan
325 326 327 328 329 330 331 332 333 334 335 336 337 338
		 * for each outer tuple.  But if it's an IN (= ANY) test, we might
		 * be able to use a hashtable to avoid comparing all the tuples.
		 */
		if (subplan_is_hashable(slink, node))
			node->useHashTable = true;
		/*
		 * Otherwise, we have the option to tack a MATERIAL node onto the top
		 * of the subplan, to reduce the cost of reading it repeatedly.  This
		 * is pointless for a direct-correlated subplan, since we'd have to
		 * recompute its results each time anyway.  For uncorrelated/undirect
		 * correlated subplans, we add MATERIAL if the subplan's top plan node
		 * is anything more complicated than a plain sequential scan, and we
		 * do it even for seqscan if the qual appears selective enough to
		 * eliminate many tuples.
339
		 */
340
		else if (node->parParam == NIL)
341 342 343 344 345 346
		{
			bool		use_material;

			switch (nodeTag(plan))
			{
				case T_SeqScan:
347
					if (plan->initPlan)
348 349 350 351 352 353 354
						use_material = true;
					else
					{
						Selectivity qualsel;

						qualsel = clauselist_selectivity(subquery,
														 plan->qual,
355
														 0, JOIN_INNER);
356 357 358
						/* Is 10% selectivity a good threshold?? */
						use_material = qualsel < 0.10;
					}
359 360
					break;
				case T_Material:
361
				case T_FunctionScan:
362
				case T_Sort:
363 364 365

					/*
					 * Don't add another Material node if there's one
366 367
					 * already, nor if the top node is any other type that
					 * materializes its output anyway.
368 369 370 371 372 373 374 375 376
					 */
					use_material = false;
					break;
				default:
					use_material = true;
					break;
			}
			if (use_material)
			{
377
				node->plan = plan = materialize_finished_plan(plan);
378 379 380
			}
		}

381 382 383 384
		/* Convert the lefthand exprs and oper OIDs into executable exprs */
		node->exprs = convert_sublink_opers(lefthand,
											slink->operOids,
											plan->targetlist,
385
											0,
386
											&node->paramIds);
387

388
		/*
389
		 * Make node->args from parParam.
390
		 */
391
		args = NIL;
392
		foreach(lst, node->parParam)
393
		{
394 395 396
			Var		   *var = nth(lfirsti(lst), PlannerParamVar);

			var = (Var *) copyObject(var);
397 398 399 400 401

			/*
			 * Must fix absolute-level varlevelsup from the
			 * PlannerParamVar entry.  But since var is at current subplan
			 * level, this is easy:
402
			 */
403
			var->varlevelsup = 0;
404
			args = lappend(args, var);
405
		}
406
		node->args = args;
407

408
		result = (Node *) node;
409 410 411 412 413 414
	}

	return result;
}

/*
415 416
 * convert_sublink_opers: given a lefthand-expressions list and a list of
 * operator OIDs, build a list of actually executable expressions.  The
417 418
 * righthand sides of the expressions are Params or Vars representing the
 * results of the sub-select.
419
 *
420 421 422 423 424 425
 * If rtindex is 0, we build Params to represent the sub-select outputs.
 * The paramids of the Params created are returned in the *righthandIds list.
 *
 * If rtindex is not 0, we build Vars using that rtindex as varno.  The
 * Vars themselves are returned in *righthandIds (this is a bit of a type
 * cheat, but we can get away with it).
426
 */
427
static List *
428
convert_sublink_opers(List *lefthand, List *operOids,
429 430
					  List *targetlist, int rtindex,
					  List **righthandIds)
431
{
432
	List	   *result = NIL;
433 434
	List	   *lst;

435
	*righthandIds = NIL;
436 437

	foreach(lst, operOids)
438
	{
439
		Oid			opid = lfirsto(lst);
440
		Node	   *leftop = lfirst(lefthand);
441
		TargetEntry *te = lfirst(targetlist);
442
		Node	   *rightop;
443 444 445 446 447
		Operator	tup;
		Form_pg_operator opform;
		Node	   *left,
				   *right;

448 449
		Assert(!te->resdom->resjunk);

450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471
		if (rtindex)
		{
			/* Make the Var node representing the subplan's result */
			rightop = (Node *) makeVar(rtindex,
									   te->resdom->resno,
									   te->resdom->restype,
									   te->resdom->restypmod,
									   0);
			/* Record it for caller */
			*righthandIds = lappend(*righthandIds, rightop);
		}
		else
		{
			/* Make the Param node representing the subplan's result */
			Param	   *prm;

			prm = generate_new_param(te->resdom->restype,
									 te->resdom->restypmod);
			/* Record its ID */
			*righthandIds = lappendi(*righthandIds, prm->paramid);
			rightop = (Node *) prm;
		}
472

473
		/* Look up the operator to get its declared input types */
474
		tup = SearchSysCache(OPEROID,
475
							 ObjectIdGetDatum(opid),
476 477
							 0, 0, 0);
		if (!HeapTupleIsValid(tup))
478
			elog(ERROR, "cache lookup failed for operator %u", opid);
479 480
		opform = (Form_pg_operator) GETSTRUCT(tup);

481
		/*
482 483 484 485
		 * Make the expression node.
		 *
		 * Note: we use make_operand in case runtime type conversion
		 * function calls must be inserted for this operator!
486
		 */
487
		left = make_operand(leftop, exprType(leftop), opform->oprleft);
488
		right = make_operand(rightop, te->resdom->restype, opform->oprright);
489 490 491 492 493 494
		result = lappend(result,
						 make_opclause(opid,
									   opform->oprresult,
									   false, /* set-result not allowed */
									   (Expr *) left,
									   (Expr *) right));
495

496 497
		ReleaseSysCache(tup);

498
		lefthand = lnext(lefthand);
499
		targetlist = lnext(targetlist);
500
	}
501

502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543
	return result;
}

/*
 * subplan_is_hashable: decide whether we can implement a subplan by hashing
 *
 * Caution: the SubPlan node is not completely filled in yet.  We can rely
 * on its plan and parParam fields, however.
 */
static bool
subplan_is_hashable(SubLink *slink, SubPlan *node)
{
	double		subquery_size;
	List	   *opids;

	/*
	 * The sublink type must be "= ANY" --- that is, an IN operator.
	 * (We require the operator name to be unqualified, which may be
	 * overly paranoid, or may not be.)  XXX since we also check that the
	 * operators are hashable, the test on operator name may be redundant?
	 */
	if (slink->subLinkType != ANY_SUBLINK)
		return false;
	if (length(slink->operName) != 1 ||
		strcmp(strVal(lfirst(slink->operName)), "=") != 0)
		return false;
	/*
	 * The subplan must not have any direct correlation vars --- else we'd
	 * have to recompute its output each time, so that the hashtable wouldn't
	 * gain anything.
	 */
	if (node->parParam != NIL)
		return false;
	/*
	 * The estimated size of the subquery result must fit in SortMem.
	 * (XXX what about hashtable overhead?)
	 */
	subquery_size = node->plan->plan_rows *
		(MAXALIGN(node->plan->plan_width) + MAXALIGN(sizeof(HeapTupleData)));
	if (subquery_size > SortMem * 1024L)
		return false;
	/*
544 545 546 547 548 549 550 551 552 553 554
	 * The combining operators must be hashable, strict, and self-commutative.
	 * The need for hashability is obvious, since we want to use hashing.
	 * Without strictness, behavior in the presence of nulls is too
	 * unpredictable.  (We actually must assume even more than plain
	 * strictness, see nodeSubplan.c for details.)  And commutativity ensures
	 * that the left and right datatypes are the same; this allows us to
	 * assume that the combining operators are equality for the righthand
	 * datatype, so that they can be used to compare righthand tuples as
	 * well as comparing lefthand to righthand tuples.  (This last restriction
	 * could be relaxed by using two different sets of operators with the
	 * hash table, but there is no obvious usefulness to that at present.)
555 556 557
	 */
	foreach(opids, slink->operOids)
	{
558
		Oid			opid = lfirsto(opids);
559 560 561 562 563 564 565 566 567
		HeapTuple	tup;
		Form_pg_operator optup;

		tup = SearchSysCache(OPEROID,
							 ObjectIdGetDatum(opid),
							 0, 0, 0);
		if (!HeapTupleIsValid(tup))
			elog(ERROR, "cache lookup failed for operator %u", opid);
		optup = (Form_pg_operator) GETSTRUCT(tup);
568 569
		if (!optup->oprcanhash || optup->oprcom != opid ||
			!func_strict(optup->oprcode))
570 571 572 573 574 575 576
		{
			ReleaseSysCache(tup);
			return false;
		}
		ReleaseSysCache(tup);
	}
	return true;
577 578
}

579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594
/*
 * convert_IN_to_join: can we convert an IN SubLink to join style?
 *
 * The caller has found a SubLink at the top level of WHERE, but has not
 * checked the properties of the SubLink at all.  Decide whether it is
 * appropriate to process this SubLink in join style.  If not, return NULL.
 * If so, build the qual clause(s) to replace the SubLink, and return them.
 *
 * Side effects of a successful conversion include adding the SubLink's
 * subselect to the query's rangetable and adding an InClauseInfo node to
 * its in_info_list.
 */
Node *
convert_IN_to_join(Query *parse, SubLink *sublink)
{
	Query	   *subselect = (Query *) sublink->subselect;
595
	Relids		left_varnos;
596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622
	int			rtindex;
	RangeTblEntry *rte;
	RangeTblRef *rtr;
	InClauseInfo  *ininfo;
	List	   *exprs;

	/*
	 * The sublink type must be "= ANY" --- that is, an IN operator.
	 * (We require the operator name to be unqualified, which may be
	 * overly paranoid, or may not be.)
	 */
	if (sublink->subLinkType != ANY_SUBLINK)
		return NULL;
	if (length(sublink->operName) != 1 ||
		strcmp(strVal(lfirst(sublink->operName)), "=") != 0)
		return NULL;
	/*
	 * The sub-select must not refer to any Vars of the parent query.
	 * (Vars of higher levels should be okay, though.)
	 */
	if (contain_vars_of_level((Node *) subselect, 1))
		return NULL;
	/*
	 * The left-hand expressions must contain some Vars of the current
	 * query, else it's not gonna be a join.
	 */
	left_varnos = pull_varnos((Node *) sublink->lefthand);
623
	if (bms_is_empty(left_varnos))
624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653
		return NULL;
	/*
	 * The left-hand expressions mustn't be volatile.  (Perhaps we should
	 * test the combining operators, too?  We'd only need to point the
	 * function directly at the sublink ...)
	 */
	if (contain_volatile_functions((Node *) sublink->lefthand))
		return NULL;
	/*
	 * Okay, pull up the sub-select into top range table and jointree.
	 *
	 * We rely here on the assumption that the outer query has no references
	 * to the inner (necessarily true, other than the Vars that we build
	 * below).  Therefore this is a lot easier than what pull_up_subqueries
	 * has to go through.
	 */
	rte = addRangeTableEntryForSubquery(NULL,
										subselect,
										makeAlias("IN_subquery", NIL),
										false);
	parse->rtable = lappend(parse->rtable, rte);
	rtindex = length(parse->rtable);
	rtr = makeNode(RangeTblRef);
	rtr->rtindex = rtindex;
	parse->jointree->fromlist = lappend(parse->jointree->fromlist, rtr);
	/*
	 * Now build the InClauseInfo node.
	 */
	ininfo = makeNode(InClauseInfo);
	ininfo->lefthand = left_varnos;
654
	ininfo->righthand = bms_make_singleton(rtindex);
655 656 657 658 659 660 661 662 663 664 665 666 667 668
	parse->in_info_list = lcons(ininfo, parse->in_info_list);
	/*
	 * Build the result qual expressions.  As a side effect,
	 * ininfo->sub_targetlist is filled with a list of the Vars
	 * representing the subselect outputs.
	 */
	exprs = convert_sublink_opers(sublink->lefthand,
								  sublink->operOids,
								  subselect->targetList,
								  rtindex,
								  &ininfo->sub_targetlist);
	return (Node *) make_ands_explicit(exprs);
}

669 670
/*
 * Replace correlation vars (uplevel vars) with Params.
671
 */
672
Node *
673
SS_replace_correlation_vars(Node *expr)
674
{
675 676 677
	/* No setup needed for tree walk, so away we go */
	return replace_correlation_vars_mutator(expr, NULL);
}
678

679 680 681 682 683 684
static Node *
replace_correlation_vars_mutator(Node *node, void *context)
{
	if (node == NULL)
		return NULL;
	if (IsA(node, Var))
685
	{
686 687
		if (((Var *) node)->varlevelsup > 0)
			return (Node *) replace_var((Var *) node);
688
	}
689 690 691
	return expression_tree_mutator(node,
								   replace_correlation_vars_mutator,
								   context);
692 693
}

694 695
/*
 * Expand SubLinks to SubPlans in the given expression.
696 697 698 699
 *
 * The isQual argument tells whether or not this expression is a WHERE/HAVING
 * qualifier expression.  If it is, any sublinks appearing at top level need
 * not distinguish FALSE from UNKNOWN return values.
700
 */
701
Node *
702
SS_process_sublinks(Node *expr, bool isQual)
703
{
704 705
	/* The only context needed is the initial are-we-in-a-qual flag */
	return process_sublinks_mutator(expr, &isQual);
706 707 708
}

static Node *
709
process_sublinks_mutator(Node *node, bool *isTopQual)
710
{
711 712
	bool	locTopQual;

713
	if (node == NULL)
714
		return NULL;
715
	if (IsA(node, SubLink))
716
	{
717
		SubLink    *sublink = (SubLink *) node;
718
		List	   *lefthand;
719

720
		/*
721
		 * First, recursively process the lefthand-side expressions, if any.
722
		 */
723
		locTopQual = false;
724
		lefthand = (List *)
725
			process_sublinks_mutator((Node *) sublink->lefthand, &locTopQual);
726 727 728
		/*
		 * Now build the SubPlan node and make the expr to return.
		 */
729
		return make_subplan(sublink, lefthand, *isTopQual);
730
	}
731

732
	/*
733 734 735
	 * We should never see a SubPlan expression in the input (since this is
	 * the very routine that creates 'em to begin with).  We shouldn't find
	 * ourselves invoked directly on a Query, either.
736
	 */
737
	Assert(!is_subplan(node));
738
	Assert(!IsA(node, Query));
739

740 741 742 743 744 745 746 747 748
	/*
	 * If we recurse down through anything other than a List node, we are
	 * definitely not at top qual level anymore.
	 */
	if (IsA(node, List))
		locTopQual = *isTopQual;
	else
		locTopQual = false;

749 750
	return expression_tree_mutator(node,
								   process_sublinks_mutator,
751
								   (void *) &locTopQual);
752 753
}

754 755 756
/*
 * SS_finalize_plan - do final sublink processing for a completed Plan.
 *
757 758
 * This recursively computes the extParam and allParam sets
 * for every Plan node in the given plan tree.
759
 */
760
void
761
SS_finalize_plan(Plan *plan, List *rtable)
762
{
763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 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
	Bitmapset  *outer_params = NULL;
	Bitmapset  *valid_params = NULL;
	int			paramid;
	List	   *lst;

	/*
	 * First, scan the param list to discover the sets of params that
	 * are available from outer query levels and my own query level.
	 * We do this once to save time in the per-plan recursion steps.
	 */
	paramid = 0;
	foreach(lst, PlannerParamVar)
	{
		Var		   *var = (Var *) lfirst(lst);

		/* note varlevelsup is absolute level number */
		if (var->varlevelsup < PlannerQueryLevel)
		{
			/* valid outer-level parameter */
			outer_params = bms_add_member(outer_params, paramid);
			valid_params = bms_add_member(valid_params, paramid);
		}
		else if (var->varlevelsup == PlannerQueryLevel &&
				 var->varno == 0 && var->varattno == 0)
		{
			/* valid local parameter (i.e., a setParam of my child) */
			valid_params = bms_add_member(valid_params, paramid);
		}

		paramid++;
	}

	/*
	 * Now recurse through plan tree.
	 */
	(void) finalize_plan(plan, rtable, outer_params, valid_params);

	bms_free(outer_params);
	bms_free(valid_params);
}

/*
 * Recursive processing of all nodes in the plan tree
 *
 * The return value is the computed allParam set for the given Plan node.
 * This is just an internal notational convenience.
 */
static Bitmapset *
finalize_plan(Plan *plan, List *rtable,
			  Bitmapset *outer_params, Bitmapset *valid_params)
{
	finalize_primnode_context context;
815 816 817
	List	   *lst;

	if (plan == NULL)
818
		return NULL;
819

820 821
	context.paramids = NULL;	/* initialize set to empty */
	context.outer_params = outer_params;
822

823
	/*
824
	 * When we call finalize_primnode, context.paramids sets are
825
	 * automatically merged together.  But when recursing to self, we have
826
	 * to do it the hard way.  We want the paramids set to include params
827
	 * in subplans as well as at this level.
828 829
	 */

830
	/* Find params in targetlist and qual */
831 832
	finalize_primnode((Node *) plan->targetlist, &context);
	finalize_primnode((Node *) plan->qual, &context);
833

834
	/* Check additional node-type-specific fields */
835 836 837
	switch (nodeTag(plan))
	{
		case T_Result:
838
			finalize_primnode(((Result *) plan)->resconstantqual,
839
							  &context);
840 841
			break;

842 843
		case T_IndexScan:
			finalize_primnode((Node *) ((IndexScan *) plan)->indxqual,
844
							  &context);
845 846 847

			/*
			 * we need not look at indxqualorig, since it will have the
848
			 * same param references as indxqual.
849 850 851 852 853
			 */
			break;

		case T_TidScan:
			finalize_primnode((Node *) ((TidScan *) plan)->tideval,
854
							  &context);
855
			break;
856

857
		case T_SubqueryScan:
B
Bruce Momjian 已提交
858

859
			/*
B
Bruce Momjian 已提交
860 861 862 863 864
			 * In a SubqueryScan, SS_finalize_plan has already been run on
			 * the subplan by the inner invocation of subquery_planner, so
			 * there's no need to do it again.  Instead, just pull out the
			 * subplan's extParams list, which represents the params it
			 * needs from my level and higher levels.
865
			 */
866
			context.paramids = bms_add_members(context.paramids,
B
Bruce Momjian 已提交
867
							 ((SubqueryScan *) plan)->subplan->extParam);
868 869
			break;

870 871 872
		case T_FunctionScan:
			{
				RangeTblEntry *rte;
873

874 875 876
				rte = rt_fetch(((FunctionScan *) plan)->scan.scanrelid,
							   rtable);
				Assert(rte->rtekind == RTE_FUNCTION);
877
				finalize_primnode(rte->funcexpr, &context);
878 879 880 881 882
			}
			break;

		case T_Append:
			foreach(lst, ((Append *) plan)->appendplans)
883 884 885 886 887 888 889 890
			{
				context.paramids =
					bms_add_members(context.paramids,
									finalize_plan((Plan *) lfirst(lst),
												  rtable,
												  outer_params,
												  valid_params));
			}
891 892
			break;

893 894
		case T_NestLoop:
			finalize_primnode((Node *) ((Join *) plan)->joinqual,
895
							  &context);
896 897
			break;

898
		case T_MergeJoin:
899
			finalize_primnode((Node *) ((Join *) plan)->joinqual,
900
							  &context);
901
			finalize_primnode((Node *) ((MergeJoin *) plan)->mergeclauses,
902
							  &context);
903 904 905
			break;

		case T_HashJoin:
906
			finalize_primnode((Node *) ((Join *) plan)->joinqual,
907
							  &context);
908
			finalize_primnode((Node *) ((HashJoin *) plan)->hashclauses,
909
							  &context);
910
			break;
911

912
		case T_Hash:
913
			finalize_primnode((Node *) ((Hash *) plan)->hashkeys,
914
							  &context);
915 916 917 918 919 920 921
			break;

		case T_Agg:
		case T_SeqScan:
		case T_Material:
		case T_Sort:
		case T_Unique:
922
		case T_SetOp:
923
		case T_Limit:
924 925
		case T_Group:
			break;
926

927
		default:
928
			elog(ERROR, "finalize_plan: node %d unsupported",
929
				 nodeTag(plan));
930
	}
931

932
	/* Process left and right child plans, if any */
933 934 935 936 937 938 939 940 941 942 943
	context.paramids = bms_add_members(context.paramids,
									   finalize_plan(plan->lefttree,
													 rtable,
													 outer_params,
													 valid_params));

	context.paramids = bms_add_members(context.paramids,
									   finalize_plan(plan->righttree,
													 rtable,
													 outer_params,
													 valid_params));
944

945
	/* Now we have all the paramids */
946

947 948
	if (!bms_is_subset(context.paramids, valid_params))
		elog(ERROR, "finalize_plan: plan shouldn't reference subplan's variable");
949

950 951
	plan->extParam = bms_intersect(context.paramids, outer_params);
	plan->allParam = context.paramids;
952

953 954 955 956 957 958 959 960 961 962 963 964 965 966
	/*
	 * For speed at execution time, make sure extParam/allParam are actually
	 * NULL if they are empty sets.
	 */
	if (bms_is_empty(plan->extParam))
	{
		bms_free(plan->extParam);
		plan->extParam = NULL;
	}
	if (bms_is_empty(plan->allParam))
	{
		bms_free(plan->allParam);
		plan->allParam = NULL;
	}
967

968
	return plan->allParam;
969
}
970 971

/*
972 973
 * finalize_primnode: add IDs of all PARAM_EXEC params appearing in the given
 * expression tree to the result set.
974 975
 */
static bool
976
finalize_primnode(Node *node, finalize_primnode_context *context)
977 978 979 980 981 982 983 984 985
{
	if (node == NULL)
		return false;
	if (IsA(node, Param))
	{
		if (((Param *) node)->paramkind == PARAM_EXEC)
		{
			int			paramid = (int) ((Param *) node)->paramid;

986
			context->paramids = bms_add_member(context->paramids, paramid);
987 988 989 990 991 992 993
		}
		return false;			/* no more to do here */
	}
	if (is_subplan(node))
	{
		SubPlan	   *subplan = (SubPlan *) node;

994 995 996 997
		/* Add outer-level params needed by the subplan to paramids */
		context->paramids = bms_join(context->paramids,
									 bms_intersect(subplan->plan->extParam,
												   context->outer_params));
998 999 1000
		/* fall through to recurse into subplan args */
	}
	return expression_tree_walker(node, finalize_primnode,
1001
								  (void *) context);
1002
}