subselect.c 30.0 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.72 2003/02/09 06:56:27 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 225
	else
		tuple_fraction = -1.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 341 342 343 344
		 *
		 * XXX It's pretty ugly to be inserting a MATERIAL node at this
		 * point.  Since subquery_planner has already run SS_finalize_plan
		 * on the subplan tree, we have to kluge up parameter lists for
		 * the MATERIAL node.  Possibly this could be fixed by postponing
		 * SS_finalize_plan processing until setrefs.c is run.
345
		 */
346
		else if (node->parParam == NIL)
347 348 349 350 351 352
		{
			bool		use_material;

			switch (nodeTag(plan))
			{
				case T_SeqScan:
353
					if (plan->initPlan)
354 355 356 357 358 359 360
						use_material = true;
					else
					{
						Selectivity qualsel;

						qualsel = clauselist_selectivity(subquery,
														 plan->qual,
361
														 0, JOIN_INNER);
362 363 364
						/* Is 10% selectivity a good threshold?? */
						use_material = qualsel < 0.10;
					}
365 366
					break;
				case T_Material:
367
				case T_FunctionScan:
368
				case T_Sort:
369 370 371

					/*
					 * Don't add another Material node if there's one
372 373
					 * already, nor if the top node is any other type that
					 * materializes its output anyway.
374 375 376 377 378 379 380 381 382
					 */
					use_material = false;
					break;
				default:
					use_material = true;
					break;
			}
			if (use_material)
			{
B
Bruce Momjian 已提交
383
				Plan	   *matplan;
384
				Path		matpath; /* dummy for result of cost_material */
385 386

				matplan = (Plan *) make_material(plan->targetlist, plan);
387 388 389 390 391 392 393
				/* need to calculate costs */
				cost_material(&matpath,
							  plan->total_cost,
							  plan->plan_rows,
							  plan->plan_width);
				matplan->startup_cost = matpath.startup_cost;
				matplan->total_cost = matpath.total_cost;
394 395
				matplan->plan_rows = plan->plan_rows;
				matplan->plan_width = plan->plan_width;
396
				/* parameter kluge --- see comments above */
397 398
				matplan->extParam = bms_copy(plan->extParam);
				matplan->allParam = bms_copy(plan->allParam);
399
				node->plan = plan = matplan;
400 401 402
			}
		}

403 404 405 406
		/* Convert the lefthand exprs and oper OIDs into executable exprs */
		node->exprs = convert_sublink_opers(lefthand,
											slink->operOids,
											plan->targetlist,
407
											0,
408
											&node->paramIds);
409

410
		/*
411
		 * Make node->args from parParam.
412
		 */
413
		args = NIL;
414
		foreach(lst, node->parParam)
415
		{
416 417 418
			Var		   *var = nth(lfirsti(lst), PlannerParamVar);

			var = (Var *) copyObject(var);
419 420 421 422 423

			/*
			 * Must fix absolute-level varlevelsup from the
			 * PlannerParamVar entry.  But since var is at current subplan
			 * level, this is easy:
424
			 */
425
			var->varlevelsup = 0;
426
			args = lappend(args, var);
427
		}
428
		node->args = args;
429

430
		result = (Node *) node;
431 432 433 434 435 436
	}

	return result;
}

/*
437 438
 * convert_sublink_opers: given a lefthand-expressions list and a list of
 * operator OIDs, build a list of actually executable expressions.  The
439 440
 * righthand sides of the expressions are Params or Vars representing the
 * results of the sub-select.
441
 *
442 443 444 445 446 447
 * 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).
448
 */
449
static List *
450
convert_sublink_opers(List *lefthand, List *operOids,
451 452
					  List *targetlist, int rtindex,
					  List **righthandIds)
453
{
454
	List	   *result = NIL;
455 456
	List	   *lst;

457
	*righthandIds = NIL;
458 459

	foreach(lst, operOids)
460
	{
461
		Oid			opid = lfirsto(lst);
462
		Node	   *leftop = lfirst(lefthand);
463
		TargetEntry *te = lfirst(targetlist);
464
		Node	   *rightop;
465 466 467 468 469
		Operator	tup;
		Form_pg_operator opform;
		Node	   *left,
				   *right;

470 471
		Assert(!te->resdom->resjunk);

472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493
		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;
		}
494

495
		/* Look up the operator to get its declared input types */
496
		tup = SearchSysCache(OPEROID,
497
							 ObjectIdGetDatum(opid),
498 499
							 0, 0, 0);
		if (!HeapTupleIsValid(tup))
500
			elog(ERROR, "cache lookup failed for operator %u", opid);
501 502
		opform = (Form_pg_operator) GETSTRUCT(tup);

503
		/*
504 505 506 507
		 * Make the expression node.
		 *
		 * Note: we use make_operand in case runtime type conversion
		 * function calls must be inserted for this operator!
508
		 */
509
		left = make_operand(leftop, exprType(leftop), opform->oprleft);
510
		right = make_operand(rightop, te->resdom->restype, opform->oprright);
511 512 513 514 515 516
		result = lappend(result,
						 make_opclause(opid,
									   opform->oprresult,
									   false, /* set-result not allowed */
									   (Expr *) left,
									   (Expr *) right));
517

518 519
		ReleaseSysCache(tup);

520
		lefthand = lnext(lefthand);
521
		targetlist = lnext(targetlist);
522
	}
523

524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565
	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;
	/*
566 567 568 569 570 571 572 573 574 575 576
	 * 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.)
577 578 579
	 */
	foreach(opids, slink->operOids)
	{
580
		Oid			opid = lfirsto(opids);
581 582 583 584 585 586 587 588 589
		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);
590 591
		if (!optup->oprcanhash || optup->oprcom != opid ||
			!func_strict(optup->oprcode))
592 593 594 595 596 597 598
		{
			ReleaseSysCache(tup);
			return false;
		}
		ReleaseSysCache(tup);
	}
	return true;
599 600
}

601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616
/*
 * 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;
617
	Relids		left_varnos;
618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644
	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);
645
	if (bms_is_empty(left_varnos))
646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675
		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;
676
	ininfo->righthand = bms_make_singleton(rtindex);
677 678 679 680 681 682 683 684 685 686 687 688 689 690
	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);
}

691 692
/*
 * Replace correlation vars (uplevel vars) with Params.
693
 */
694
Node *
695
SS_replace_correlation_vars(Node *expr)
696
{
697 698 699
	/* No setup needed for tree walk, so away we go */
	return replace_correlation_vars_mutator(expr, NULL);
}
700

701 702 703 704 705 706
static Node *
replace_correlation_vars_mutator(Node *node, void *context)
{
	if (node == NULL)
		return NULL;
	if (IsA(node, Var))
707
	{
708 709
		if (((Var *) node)->varlevelsup > 0)
			return (Node *) replace_var((Var *) node);
710
	}
711 712 713
	return expression_tree_mutator(node,
								   replace_correlation_vars_mutator,
								   context);
714 715
}

716 717
/*
 * Expand SubLinks to SubPlans in the given expression.
718 719 720 721
 *
 * 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.
722
 */
723
Node *
724
SS_process_sublinks(Node *expr, bool isQual)
725
{
726 727
	/* The only context needed is the initial are-we-in-a-qual flag */
	return process_sublinks_mutator(expr, &isQual);
728 729 730
}

static Node *
731
process_sublinks_mutator(Node *node, bool *isTopQual)
732
{
733 734
	bool	locTopQual;

735
	if (node == NULL)
736
		return NULL;
737
	if (IsA(node, SubLink))
738
	{
739
		SubLink    *sublink = (SubLink *) node;
740
		List	   *lefthand;
741

742
		/*
743
		 * First, recursively process the lefthand-side expressions, if any.
744
		 */
745
		locTopQual = false;
746
		lefthand = (List *)
747
			process_sublinks_mutator((Node *) sublink->lefthand, &locTopQual);
748 749 750
		/*
		 * Now build the SubPlan node and make the expr to return.
		 */
751
		return make_subplan(sublink, lefthand, *isTopQual);
752
	}
753

754
	/*
755 756 757
	 * 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.
758
	 */
759
	Assert(!is_subplan(node));
760
	Assert(!IsA(node, Query));
761

762 763 764 765 766 767 768 769 770
	/*
	 * 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;

771 772
	return expression_tree_mutator(node,
								   process_sublinks_mutator,
773
								   (void *) &locTopQual);
774 775
}

776 777 778
/*
 * SS_finalize_plan - do final sublink processing for a completed Plan.
 *
779 780
 * This recursively computes the extParam and allParam sets
 * for every Plan node in the given plan tree.
781
 */
782
void
783
SS_finalize_plan(Plan *plan, List *rtable)
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 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836
	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;
837 838 839
	List	   *lst;

	if (plan == NULL)
840
		return NULL;
841

842 843
	context.paramids = NULL;	/* initialize set to empty */
	context.outer_params = outer_params;
844

845
	/*
846
	 * When we call finalize_primnode, context.paramids sets are
847
	 * automatically merged together.  But when recursing to self, we have
848
	 * to do it the hard way.  We want the paramids set to include params
849
	 * in subplans as well as at this level.
850 851
	 */

852
	/* Find params in targetlist and qual */
853 854
	finalize_primnode((Node *) plan->targetlist, &context);
	finalize_primnode((Node *) plan->qual, &context);
855

856
	/* Check additional node-type-specific fields */
857 858 859
	switch (nodeTag(plan))
	{
		case T_Result:
860
			finalize_primnode(((Result *) plan)->resconstantqual,
861
							  &context);
862 863
			break;

864 865
		case T_IndexScan:
			finalize_primnode((Node *) ((IndexScan *) plan)->indxqual,
866
							  &context);
867 868 869

			/*
			 * we need not look at indxqualorig, since it will have the
870
			 * same param references as indxqual.
871 872 873 874 875
			 */
			break;

		case T_TidScan:
			finalize_primnode((Node *) ((TidScan *) plan)->tideval,
876
							  &context);
877
			break;
878

879
		case T_SubqueryScan:
B
Bruce Momjian 已提交
880

881
			/*
B
Bruce Momjian 已提交
882 883 884 885 886
			 * 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.
887
			 */
888
			context.paramids = bms_add_members(context.paramids,
B
Bruce Momjian 已提交
889
							 ((SubqueryScan *) plan)->subplan->extParam);
890 891
			break;

892 893 894
		case T_FunctionScan:
			{
				RangeTblEntry *rte;
895

896 897 898
				rte = rt_fetch(((FunctionScan *) plan)->scan.scanrelid,
							   rtable);
				Assert(rte->rtekind == RTE_FUNCTION);
899
				finalize_primnode(rte->funcexpr, &context);
900 901 902 903 904
			}
			break;

		case T_Append:
			foreach(lst, ((Append *) plan)->appendplans)
905 906 907 908 909 910 911 912
			{
				context.paramids =
					bms_add_members(context.paramids,
									finalize_plan((Plan *) lfirst(lst),
												  rtable,
												  outer_params,
												  valid_params));
			}
913 914
			break;

915 916
		case T_NestLoop:
			finalize_primnode((Node *) ((Join *) plan)->joinqual,
917
							  &context);
918 919
			break;

920
		case T_MergeJoin:
921
			finalize_primnode((Node *) ((Join *) plan)->joinqual,
922
							  &context);
923
			finalize_primnode((Node *) ((MergeJoin *) plan)->mergeclauses,
924
							  &context);
925 926 927
			break;

		case T_HashJoin:
928
			finalize_primnode((Node *) ((Join *) plan)->joinqual,
929
							  &context);
930
			finalize_primnode((Node *) ((HashJoin *) plan)->hashclauses,
931
							  &context);
932
			break;
933

934
		case T_Hash:
935
			finalize_primnode((Node *) ((Hash *) plan)->hashkeys,
936
							  &context);
937 938 939 940 941 942 943
			break;

		case T_Agg:
		case T_SeqScan:
		case T_Material:
		case T_Sort:
		case T_Unique:
944
		case T_SetOp:
945
		case T_Limit:
946 947
		case T_Group:
			break;
948

949
		default:
950
			elog(ERROR, "finalize_plan: node %d unsupported",
951
				 nodeTag(plan));
952
	}
953

954
	/* Process left and right child plans, if any */
955 956 957 958 959 960 961 962 963 964 965
	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));
966

967
	/* Now we have all the paramids */
968

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

972 973
	plan->extParam = bms_intersect(context.paramids, outer_params);
	plan->allParam = context.paramids;
974

975 976 977 978 979 980 981 982 983 984 985 986 987 988
	/*
	 * 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;
	}
989

990
	return plan->allParam;
991
}
992 993

/*
994 995
 * finalize_primnode: add IDs of all PARAM_EXEC params appearing in the given
 * expression tree to the result set.
996 997
 */
static bool
998
finalize_primnode(Node *node, finalize_primnode_context *context)
999 1000 1001 1002 1003 1004 1005 1006 1007
{
	if (node == NULL)
		return false;
	if (IsA(node, Param))
	{
		if (((Param *) node)->paramkind == PARAM_EXEC)
		{
			int			paramid = (int) ((Param *) node)->paramid;

1008
			context->paramids = bms_add_member(context->paramids, paramid);
1009 1010 1011 1012 1013 1014 1015
		}
		return false;			/* no more to do here */
	}
	if (is_subplan(node))
	{
		SubPlan	   *subplan = (SubPlan *) node;

1016 1017 1018 1019
		/* Add outer-level params needed by the subplan to paramids */
		context->paramids = bms_join(context->paramids,
									 bms_intersect(subplan->plan->extParam,
												   context->outer_params));
1020 1021 1022
		/* fall through to recurse into subplan args */
	}
	return expression_tree_walker(node, finalize_primnode,
1023
								  (void *) context);
1024
}