clauses.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:23k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. /*-------------------------------------------------------------------------
  2.  *
  3.  * clauses.c
  4.  *   routines to manipulate qualification clauses
  5.  *
  6.  * Copyright (c) 1994, Regents of the University of California
  7.  *
  8.  *
  9.  * IDENTIFICATION
  10.  *   $Header: /usr/local/cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.37.2.1 1999/08/02 06:27:07 scrappy Exp $
  11.  *
  12.  * HISTORY
  13.  *   AUTHOR DATE MAJOR EVENT
  14.  *   Andrew Yu Nov 3, 1994 clause.c and clauses.c combined
  15.  *
  16.  *-------------------------------------------------------------------------
  17.  */
  18. #include "postgres.h"
  19. #include "catalog/pg_operator.h"
  20. #include "nodes/makefuncs.h"
  21. #include "nodes/nodeFuncs.h"
  22. #include "nodes/plannodes.h"
  23. #include "optimizer/clauses.h"
  24. #include "optimizer/internal.h"
  25. #include "optimizer/var.h"
  26. #include "utils/lsyscache.h"
  27. static bool fix_opid_walker(Node *node, void *context);
  28. Expr *
  29. make_clause(int type, Node *oper, List *args)
  30. {
  31. if (type == AND_EXPR || type == OR_EXPR || type == NOT_EXPR ||
  32. type == OP_EXPR || type == FUNC_EXPR)
  33. {
  34. Expr    *expr = makeNode(Expr);
  35. /*
  36.  * assume type checking already done and we don't need the type of
  37.  * the expr any more.
  38.  */
  39. expr->typeOid = InvalidOid;
  40. expr->opType = type;
  41. expr->oper = oper; /* ignored for AND, OR, NOT */
  42. expr->args = args;
  43. return expr;
  44. }
  45. else
  46. {
  47. elog(ERROR, "make_clause: unsupported type %d", type);
  48. /* will this ever happen? translated from lispy C code - ay 10/94 */
  49. return (Expr *) args;
  50. }
  51. }
  52. /*****************************************************************************
  53.  * OPERATOR clause functions
  54.  *****************************************************************************/
  55. /*
  56.  * is_opclause
  57.  *
  58.  * Returns t iff the clause is an operator clause:
  59.  * (op expr expr) or (op expr).
  60.  *
  61.  * [historical note: is_clause has the exact functionality and is used
  62.  * throughout the code. They're renamed to is_opclause for clarity.
  63.  * - ay 10/94.]
  64.  */
  65. bool
  66. is_opclause(Node *clause)
  67. {
  68. return (clause != NULL &&
  69.   nodeTag(clause) == T_Expr && ((Expr *) clause)->opType == OP_EXPR);
  70. }
  71. /*
  72.  * make_opclause
  73.  *   Creates a clause given its operator left operand and right
  74.  *   operand (if it is non-null).
  75.  *
  76.  */
  77. Expr *
  78. make_opclause(Oper *op, Var *leftop, Var *rightop)
  79. {
  80. Expr    *expr = makeNode(Expr);
  81. expr->typeOid = InvalidOid; /* assume type checking done */
  82. expr->opType = OP_EXPR;
  83. expr->oper = (Node *) op;
  84. if (rightop)
  85. expr->args = lcons(leftop, lcons(rightop, NIL));
  86. else
  87. expr->args = lcons(leftop, NIL);
  88. return expr;
  89. }
  90. /*
  91.  * get_leftop
  92.  *
  93.  * Returns the left operand of a clause of the form (op expr expr)
  94.  * or (op expr)
  95.  * NB: it is assumed (for now) that all expr must be Var nodes
  96.  */
  97. Var *
  98. get_leftop(Expr *clause)
  99. {
  100. if (clause->args != NULL)
  101. return lfirst(clause->args);
  102. else
  103. return NULL;
  104. }
  105. /*
  106.  * get_rightop
  107.  *
  108.  * Returns the right operand in a clause of the form (op expr expr).
  109.  * NB: result will be NULL if applied to a unary op clause.
  110.  */
  111. Var *
  112. get_rightop(Expr *clause)
  113. {
  114. if (clause->args != NULL && lnext(clause->args) != NULL)
  115. return lfirst(lnext(clause->args));
  116. else
  117. return NULL;
  118. }
  119. /*****************************************************************************
  120.  * FUNC clause functions
  121.  *****************************************************************************/
  122. /*
  123.  * is_funcclause
  124.  *
  125.  * Returns t iff the clause is a function clause: (func { expr }).
  126.  *
  127.  */
  128. bool
  129. is_funcclause(Node *clause)
  130. {
  131. return (clause != NULL &&
  132. nodeTag(clause) == T_Expr &&
  133. ((Expr *) clause)->opType == FUNC_EXPR);
  134. }
  135. /*
  136.  * make_funcclause
  137.  *
  138.  * Creates a function clause given the FUNC node and the functional
  139.  * arguments.
  140.  *
  141.  */
  142. Expr *
  143. make_funcclause(Func *func, List *funcargs)
  144. {
  145. Expr    *expr = makeNode(Expr);
  146. expr->typeOid = InvalidOid; /* assume type checking done */
  147. expr->opType = FUNC_EXPR;
  148. expr->oper = (Node *) func;
  149. expr->args = funcargs;
  150. return expr;
  151. }
  152. /*****************************************************************************
  153.  * OR clause functions
  154.  *****************************************************************************/
  155. /*
  156.  * or_clause
  157.  *
  158.  * Returns t iff the clause is an 'or' clause: (OR { expr }).
  159.  *
  160.  */
  161. bool
  162. or_clause(Node *clause)
  163. {
  164. return clause != NULL &&
  165. nodeTag(clause) == T_Expr &&
  166. ((Expr *) clause)->opType == OR_EXPR;
  167. }
  168. /*
  169.  * make_orclause
  170.  *
  171.  * Creates an 'or' clause given a list of its subclauses.
  172.  *
  173.  */
  174. Expr *
  175. make_orclause(List *orclauses)
  176. {
  177. Expr    *expr = makeNode(Expr);
  178. expr->typeOid = InvalidOid; /* assume type checking done */
  179. expr->opType = OR_EXPR;
  180. expr->oper = NULL;
  181. expr->args = orclauses;
  182. return expr;
  183. }
  184. /*****************************************************************************
  185.  * NOT clause functions
  186.  *****************************************************************************/
  187. /*
  188.  * not_clause
  189.  *
  190.  * Returns t iff this is a 'not' clause: (NOT expr).
  191.  *
  192.  */
  193. bool
  194. not_clause(Node *clause)
  195. {
  196. return (clause != NULL &&
  197. nodeTag(clause) == T_Expr &&
  198. ((Expr *) clause)->opType == NOT_EXPR);
  199. }
  200. /*
  201.  * make_notclause
  202.  *
  203.  * Create a 'not' clause given the expression to be negated.
  204.  *
  205.  */
  206. Expr *
  207. make_notclause(Expr *notclause)
  208. {
  209. Expr    *expr = makeNode(Expr);
  210. expr->typeOid = InvalidOid; /* assume type checking done */
  211. expr->opType = NOT_EXPR;
  212. expr->oper = NULL;
  213. expr->args = lcons(notclause, NIL);
  214. return expr;
  215. }
  216. /*
  217.  * get_notclausearg
  218.  *
  219.  * Retrieve the clause within a 'not' clause
  220.  *
  221.  */
  222. Expr *
  223. get_notclausearg(Expr *notclause)
  224. {
  225. return lfirst(notclause->args);
  226. }
  227. /*****************************************************************************
  228.  * AND clause functions
  229.  *****************************************************************************/
  230. /*
  231.  * and_clause
  232.  *
  233.  * Returns t iff its argument is an 'and' clause: (AND { expr }).
  234.  *
  235.  */
  236. bool
  237. and_clause(Node *clause)
  238. {
  239. return (clause != NULL &&
  240. nodeTag(clause) == T_Expr &&
  241. ((Expr *) clause)->opType == AND_EXPR);
  242. }
  243. /*
  244.  * make_andclause
  245.  *
  246.  * Create an 'and' clause given its arguments in a list.
  247.  *
  248.  */
  249. Expr *
  250. make_andclause(List *andclauses)
  251. {
  252. Expr    *expr = makeNode(Expr);
  253. expr->typeOid = InvalidOid; /* assume type checking done */
  254. expr->opType = AND_EXPR;
  255. expr->oper = NULL;
  256. expr->args = andclauses;
  257. return expr;
  258. }
  259. /*****************************************************************************
  260.  * CASE clause functions
  261.  *****************************************************************************/
  262. /*
  263.  * case_clause
  264.  *
  265.  * Returns t iff its argument is a 'case' clause: (CASE { expr }).
  266.  *
  267.  */
  268. bool
  269. case_clause(Node *clause)
  270. {
  271. return (clause != NULL &&
  272. nodeTag(clause) == T_CaseExpr);
  273. }
  274. /*****************************************************************************
  275.  *  *
  276.  *  *
  277.  *  *
  278.  *****************************************************************************/
  279. /*
  280.  * pull_constant_clauses
  281.  *   Scans through a list of qualifications and find those that
  282.  *   contain no variables.
  283.  *
  284.  * Returns a list of the constant clauses in constantQual and the remaining
  285.  * quals as the return value.
  286.  *
  287.  */
  288. List *
  289. pull_constant_clauses(List *quals, List **constantQual)
  290. {
  291. List    *q;
  292. List    *constqual = NIL;
  293. List    *restqual = NIL;
  294. foreach(q, quals)
  295. {
  296. if (!contain_var_clause(lfirst(q)))
  297. constqual = lcons(lfirst(q), constqual);
  298. else
  299. restqual = lcons(lfirst(q), restqual);
  300. }
  301. freeList(quals);
  302. *constantQual = constqual;
  303. return restqual;
  304. }
  305. /*
  306.  * clause_relids_vars
  307.  *   Retrieves relids and vars appearing within a clause.
  308.  *   Returns ((relid1 relid2 ... relidn) (var1 var2 ... varm)) where
  309.  *   vars appear in the clause  this is done by recursively searching
  310.  *   through the left and right operands of a clause.
  311.  *
  312.  * Returns the list of relids and vars.
  313.  *
  314.  */
  315. void
  316. clause_get_relids_vars(Node *clause, Relids *relids, List **vars)
  317. {
  318. List    *clvars = pull_var_clause(clause);
  319. List    *var_list = NIL;
  320. List    *varno_list = NIL;
  321. List    *i;
  322. foreach(i, clvars)
  323. {
  324. Var    *var = (Var *) lfirst(i);
  325. List    *vi;
  326. Assert(var->varlevelsup == 0);
  327. if (!intMember(var->varno, varno_list))
  328. varno_list = lappendi(varno_list, var->varno);
  329. foreach(vi, var_list)
  330. {
  331. Var    *in_list = (Var *) lfirst(vi);
  332. if (in_list->varno == var->varno &&
  333. in_list->varattno == var->varattno)
  334. break;
  335. }
  336. if (vi == NIL)
  337. var_list = lappend(var_list, var);
  338. }
  339. *relids = varno_list;
  340. *vars = var_list;
  341. }
  342. /*
  343.  * NumRelids
  344.  * (formerly clause_relids)
  345.  *
  346.  * Returns the number of different relations referenced in 'clause'.
  347.  */
  348. int
  349. NumRelids(Node *clause)
  350. {
  351. List    *vars = pull_var_clause(clause);
  352. List    *var_list = NIL;
  353. List    *i;
  354. foreach(i, vars)
  355. {
  356. Var    *var = (Var *) lfirst(i);
  357. if (!intMember(var->varno, var_list))
  358. var_list = lconsi(var->varno, var_list);
  359. }
  360. return length(var_list);
  361. }
  362. /*
  363.  * contains_not
  364.  *
  365.  * Returns t iff the clause is a 'not' clause or if any of the
  366.  * subclauses within an 'or' clause contain 'not's.
  367.  *
  368.  * NOTE that only the top-level AND/OR structure is searched for NOTs;
  369.  * we are not interested in buried substructure.
  370.  */
  371. bool
  372. contains_not(Node *clause)
  373. {
  374. if (single_node(clause))
  375. return false;
  376. if (not_clause(clause))
  377. return true;
  378. if (or_clause(clause) || and_clause(clause))
  379. {
  380. List    *a;
  381. foreach(a, ((Expr *) clause)->args)
  382. {
  383. if (contains_not(lfirst(a)))
  384. return true;
  385. }
  386. }
  387. return false;
  388. }
  389. /*
  390.  * is_joinable
  391.  *
  392.  * Returns t iff 'clause' is a valid join clause.
  393.  *
  394.  */
  395. bool
  396. is_joinable(Node *clause)
  397. {
  398. Node    *leftop,
  399.    *rightop;
  400. if (!is_opclause(clause))
  401. return false;
  402. leftop = (Node *) get_leftop((Expr *) clause);
  403. rightop = (Node *) get_rightop((Expr *) clause);
  404. if (!rightop)
  405. return false; /* unary opclauses need not apply */
  406. /*
  407.  * One side of the clause (i.e. left or right operands) must either be
  408.  * a var node ...
  409.  */
  410. if (IsA(leftop, Var) ||IsA(rightop, Var))
  411. return true;
  412. /*
  413.  * ... or a func node.
  414.  */
  415. if (is_funcclause(leftop) || is_funcclause(rightop))
  416. return true;
  417. return false;
  418. }
  419. /*
  420.  * qual_clause_p
  421.  *
  422.  * Returns t iff 'clause' is a valid qualification clause.
  423.  *
  424.  * For now we accept only "var op const" or "const op var".
  425.  */
  426. bool
  427. qual_clause_p(Node *clause)
  428. {
  429. Node    *leftop,
  430.    *rightop;
  431. if (!is_opclause(clause))
  432. return false;
  433. leftop = (Node *) get_leftop((Expr *) clause);
  434. rightop = (Node *) get_rightop((Expr *) clause);
  435. if (!rightop)
  436. return false; /* unary opclauses need not apply */
  437. /* How about Param-s ? - vadim 02/03/98 */
  438. if (IsA(leftop, Var) &&IsA(rightop, Const))
  439. return true;
  440. if (IsA(rightop, Var) &&IsA(leftop, Const))
  441. return true;
  442. return false;
  443. }
  444. /*
  445.  * fix_opid
  446.  *   Calculate opid field from opno for each Oper node in given tree.
  447.  *
  448.  * Returns nothing.
  449.  */
  450. void
  451. fix_opid(Node *clause)
  452. {
  453. /* This tree walk requires no special setup, so away we go... */
  454. fix_opid_walker(clause, NULL);
  455. }
  456. static bool
  457. fix_opid_walker (Node *node, void *context)
  458. {
  459. if (node == NULL)
  460. return false;
  461. if (is_opclause(node))
  462. replace_opid((Oper *) ((Expr *) node)->oper);
  463. return expression_tree_walker(node, fix_opid_walker, context);
  464. }
  465. /*
  466.  * fix_opids
  467.  *   Calculate the opid from the opno for all the clauses...
  468.  *
  469.  * Returns its argument.
  470.  *
  471.  * XXX This could and should be merged with fix_opid.
  472.  *
  473.  */
  474. List *
  475. fix_opids(List *clauses)
  476. {
  477. fix_opid((Node *) clauses);
  478. return clauses;
  479. }
  480. /*
  481.  * get_relattval
  482.  * For a non-join clause, returns a list consisting of the
  483.  * relid,
  484.  * attno,
  485.  * value of the CONST node (if any), and a
  486.  * flag indicating whether the value appears on the left or right
  487.  * of the operator and whether the value varied.
  488.  *
  489.  * OLD OBSOLETE COMMENT FOLLOWS:
  490.  * If 'clause' is not of the format (op var node) or (op node var),
  491.  * or if the var refers to a nested attribute, then -1's are returned for
  492.  * everything but the value  a blank string "" (pointer to ) is
  493.  * returned for the value if it is unknown or null.
  494.  * END OF OLD OBSOLETE COMMENT.
  495.  * NEW COMMENT:
  496.  * when defining rules one of the attributes of the operator can
  497.  * be a Param node (which is supposed to be treated as a constant).
  498.  * However as there is no value specified for a parameter until run time
  499.  * this routine used to return "" as value, which caused 'compute_selec'
  500.  * to bomb (because it was expecting a lisp integer and got back a lisp
  501.  * string). Now the code returns a plain old good "lispInteger(0)".
  502.  */
  503. void
  504. get_relattval(Node *clause,
  505.   int *relid,
  506.   AttrNumber *attno,
  507.   Datum *constval,
  508.   int *flag)
  509. {
  510. Var    *left,
  511.    *right;
  512. /* Careful; the passed clause might not be a binary operator at all */
  513. if (!is_opclause(clause))
  514. goto default_results;
  515. left = get_leftop((Expr *) clause);
  516. right = get_rightop((Expr *) clause);
  517. if (!right)
  518. goto default_results;
  519. if (IsA(left, Var) &&IsA(right, Const))
  520. {
  521. *relid = left->varno;
  522. *attno = left->varattno;
  523. *constval = ((Const *) right)->constvalue;
  524. *flag = (_SELEC_CONSTANT_RIGHT_ | _SELEC_IS_CONSTANT_);
  525. }
  526. else if (IsA(left, Var) &&IsA(right, Param))
  527. {
  528. *relid = left->varno;
  529. *attno = left->varattno;
  530. *constval = 0;
  531. *flag = (_SELEC_NOT_CONSTANT_);
  532. }
  533. else if (is_funcclause((Node *) left) && IsA(right, Const))
  534. {
  535. List    *vars = pull_var_clause((Node *) left);
  536. *relid = ((Var *) lfirst(vars))->varno;
  537. *attno = InvalidAttrNumber;
  538. *constval = ((Const *) right)->constvalue;
  539. *flag = (_SELEC_CONSTANT_RIGHT_ | _SELEC_IS_CONSTANT_);
  540. }
  541. else if (IsA(right, Var) &&IsA(left, Const))
  542. {
  543. *relid = right->varno;
  544. *attno = right->varattno;
  545. *constval = ((Const *) left)->constvalue;
  546. *flag = (_SELEC_IS_CONSTANT_);
  547. }
  548. else if (IsA(right, Var) &&IsA(left, Param))
  549. {
  550. *relid = right->varno;
  551. *attno = right->varattno;
  552. *constval = 0;
  553. *flag = (_SELEC_NOT_CONSTANT_);
  554. }
  555. else if (is_funcclause((Node *) right) && IsA(left, Const))
  556. {
  557. List    *vars = pull_var_clause((Node *) right);
  558. *relid = ((Var *) lfirst(vars))->varno;
  559. *attno = InvalidAttrNumber;
  560. *constval = ((Const *) left)->constvalue;
  561. *flag = (_SELEC_IS_CONSTANT_);
  562. }
  563. else
  564. {
  565. /* Duh, it's too complicated for me... */
  566. default_results:
  567. *relid = _SELEC_VALUE_UNKNOWN_;
  568. *attno = _SELEC_VALUE_UNKNOWN_;
  569. *constval = 0;
  570. *flag = (_SELEC_NOT_CONSTANT_);
  571. }
  572. }
  573. /*
  574.  * get_relsatts
  575.  *
  576.  * Returns a list
  577.  * ( relid1 attno1 relid2 attno2 )
  578.  * for a joinclause.
  579.  *
  580.  * If the clause is not of the form (op var var) or if any of the vars
  581.  * refer to nested attributes, then -1's are returned.
  582.  *
  583.  */
  584. void
  585. get_rels_atts(Node *clause,
  586.   int *relid1,
  587.   AttrNumber *attno1,
  588.   int *relid2,
  589.   AttrNumber *attno2)
  590. {
  591. if (is_opclause(clause))
  592. {
  593. Var    *left = get_leftop((Expr *) clause);
  594. Var    *right = get_rightop((Expr *) clause);
  595. if (left && right)
  596. {
  597. bool var_left = IsA(left, Var);
  598. bool var_right = IsA(right, Var);
  599. bool varexpr_left = (bool) ((IsA(left, Func) ||IsA(left, Oper)) &&
  600.   contain_var_clause((Node *) left));
  601. bool varexpr_right = (bool) ((IsA(right, Func) ||IsA(right, Oper)) &&
  602.  contain_var_clause((Node *) right));
  603. if (var_left && var_right)
  604. {
  605. *relid1 = left->varno;
  606. *attno1 = left->varoattno;
  607. *relid2 = right->varno;
  608. *attno2 = right->varoattno;
  609. return;
  610. }
  611. if (var_left && varexpr_right)
  612. {
  613. *relid1 = left->varno;
  614. *attno1 = left->varoattno;
  615. *relid2 = _SELEC_VALUE_UNKNOWN_;
  616. *attno2 = _SELEC_VALUE_UNKNOWN_;
  617. return;
  618. }
  619. if (varexpr_left && var_right)
  620. {
  621. *relid1 = _SELEC_VALUE_UNKNOWN_;
  622. *attno1 = _SELEC_VALUE_UNKNOWN_;
  623. *relid2 = right->varno;
  624. *attno2 = right->varoattno;
  625. return;
  626. }
  627. }
  628. }
  629. *relid1 = _SELEC_VALUE_UNKNOWN_;
  630. *attno1 = _SELEC_VALUE_UNKNOWN_;
  631. *relid2 = _SELEC_VALUE_UNKNOWN_;
  632. *attno2 = _SELEC_VALUE_UNKNOWN_;
  633. }
  634. /*--------------------
  635.  * CommuteClause: commute a binary operator clause
  636.  *--------------------
  637.  */
  638. void
  639. CommuteClause(Node *clause)
  640. {
  641. Node    *temp;
  642. Oper    *commu;
  643. Form_pg_operator commuTup;
  644. HeapTuple heapTup;
  645. if (!is_opclause(clause))
  646. elog(ERROR, "CommuteClause: applied to non-operator clause");
  647. heapTup = (HeapTuple)
  648. get_operator_tuple(get_commutator(((Oper *) ((Expr *) clause)->oper)->opno));
  649. if (heapTup == (HeapTuple) NULL)
  650. elog(ERROR, "CommuteClause: no commutator for operator %u",
  651.  ((Oper *) ((Expr *) clause)->oper)->opno);
  652. commuTup = (Form_pg_operator) GETSTRUCT(heapTup);
  653. commu = makeOper(heapTup->t_data->t_oid,
  654.  commuTup->oprcode,
  655.  commuTup->oprresult,
  656.  ((Oper *) ((Expr *) clause)->oper)->opsize,
  657.  NULL);
  658. /*
  659.  * re-form the clause in-place!
  660.  */
  661. ((Expr *) clause)->oper = (Node *) commu;
  662. temp = lfirst(((Expr *) clause)->args);
  663. lfirst(((Expr *) clause)->args) = lsecond(((Expr *) clause)->args);
  664. lsecond(((Expr *) clause)->args) = temp;
  665. }
  666. /*--------------------
  667.  * Standard expression-tree walking support
  668.  *
  669.  * We used to have near-duplicate code in many different routines that
  670.  * understood how to recurse through an expression node tree.  That was
  671.  * a pain to maintain, and we frequently had bugs due to some particular
  672.  * routine neglecting to support a particular node type.  In most cases,
  673.  * these routines only actually care about certain node types, and don't
  674.  * care about other types except insofar as they have to recurse through
  675.  * non-primitive node types.  Therefore, we now provide generic tree-walking
  676.  * logic to consolidate the redundant "boilerplate" code.
  677.  *
  678.  * expression_tree_walker() is designed to support routines that traverse
  679.  * a tree in a read-only fashion (although it will also work for routines
  680.  * that modify nodes in-place but never add or delete nodes).  A walker
  681.  * routine should look like this:
  682.  *
  683.  * bool my_walker (Node *node, my_struct *context)
  684.  * {
  685.  * if (node == NULL)
  686.  * return false;
  687.  * // check for nodes that special work is required for, eg:
  688.  * if (IsA(node, Var))
  689.  * {
  690.  * ... do special actions for Var nodes
  691.  * }
  692.  * else if (IsA(node, ...))
  693.  * {
  694.  * ... do special actions for other node types
  695.  * }
  696.  * // for any node type not specially processed, do:
  697.  * return expression_tree_walker(node, my_walker, (void *) context);
  698.  * }
  699.  *
  700.  * The "context" argument points to a struct that holds whatever context
  701.  * information the walker routine needs (it can be used to return data
  702.  * gathered by the walker, too).  This argument is not touched by
  703.  * expression_tree_walker, but it is passed down to recursive sub-invocations
  704.  * of my_walker.  The tree walk is started from a setup routine that
  705.  * fills in the appropriate context struct, calls my_walker with the top-level
  706.  * node of the tree, and then examines the results.
  707.  *
  708.  * The walker routine should return "false" to continue the tree walk, or
  709.  * "true" to abort the walk and immediately return "true" to the top-level
  710.  * caller.  This can be used to short-circuit the traversal if the walker
  711.  * has found what it came for.  "false" is returned to the top-level caller
  712.  * iff no invocation of the walker returned "true".
  713.  *
  714.  * The node types handled by expression_tree_walker include all those
  715.  * normally found in target lists and qualifier clauses during the planning
  716.  * stage.  In particular, it handles List nodes since a cnf-ified qual clause
  717.  * will have List structure at the top level, and it handles TargetEntry nodes
  718.  * so that a scan of a target list can be handled without additional code.
  719.  * (But only the "expr" part of a TargetEntry is examined, unless the walker
  720.  * chooses to process TargetEntry nodes specially.)
  721.  *
  722.  * expression_tree_walker will handle a SUBPLAN_EXPR node by recursing into
  723.  * the args and slink->oper lists (which belong to the outer plan), but it
  724.  * will *not* visit the inner plan, since that's typically what expression
  725.  * tree walkers want.  A walker that wants to visit the subplan can force
  726.  * appropriate behavior by recognizing subplan nodes and doing the right
  727.  * thing.
  728.  *
  729.  * Bare SubLink nodes (without a SUBPLAN_EXPR) are handled by recursing into
  730.  * the "lefthand" argument list only.  (A bare SubLink should be seen only if
  731.  * the tree has not yet been processed by subselect.c.)  Again, this can be
  732.  * overridden by the walker, but it seems to be the most useful default
  733.  * behavior.
  734.  *--------------------
  735.  */
  736. bool
  737. expression_tree_walker(Node *node, bool (*walker) (), void *context)
  738. {
  739. List    *temp;
  740. /*
  741.  * The walker has already visited the current node,
  742.  * and so we need only recurse into any sub-nodes it has.
  743.  *
  744.  * We assume that the walker is not interested in List nodes per se,
  745.  * so when we expect a List we just recurse directly to self without
  746.  * bothering to call the walker.
  747.  */
  748. if (node == NULL)
  749. return false;
  750. switch (nodeTag(node))
  751. {
  752. case T_Ident:
  753. case T_Const:
  754. case T_Var:
  755. case T_Param:
  756. /* primitive node types with no subnodes */
  757. break;
  758. case T_Expr:
  759. {
  760. Expr   *expr = (Expr *) node;
  761. if (expr->opType == SUBPLAN_EXPR)
  762. {
  763. /* examine args list (params to be passed to subplan) */
  764. if (expression_tree_walker((Node *) expr->args,
  765.    walker, context))
  766. return true;
  767. /* examine oper list as well */
  768. if (expression_tree_walker(
  769. (Node *) ((SubPlan *) expr->oper)->sublink->oper,
  770. walker, context))
  771. return true;
  772. /* but not the subplan itself */
  773. }
  774. else
  775. {
  776. /* for other Expr node types, just examine args list */
  777. if (expression_tree_walker((Node *) expr->args,
  778.    walker, context))
  779. return true;
  780. }
  781. }
  782. break;
  783. case T_Aggref:
  784. return walker(((Aggref *) node)->target, context);
  785. case T_Iter:
  786. return walker(((Iter *) node)->iterexpr, context);
  787. case T_ArrayRef:
  788. {
  789. ArrayRef   *aref = (ArrayRef *) node;
  790. /* recurse directly for upper/lower array index lists */
  791. if (expression_tree_walker((Node *) aref->refupperindexpr,
  792.    walker, context))
  793. return true;
  794. if (expression_tree_walker((Node *) aref->reflowerindexpr,
  795.    walker, context))
  796. return true;
  797. /* walker must see the refexpr and refassgnexpr, however */
  798. if (walker(aref->refexpr, context))
  799. return true;
  800. if (walker(aref->refassgnexpr, context))
  801. return true;
  802. }
  803. break;
  804. case T_CaseExpr:
  805. {
  806. CaseExpr   *caseexpr = (CaseExpr *) node;
  807. /* we assume walker doesn't care about CaseWhens, either */
  808. foreach(temp, caseexpr->args)
  809. {
  810. CaseWhen   *when = (CaseWhen *) lfirst(temp);
  811. Assert(IsA(when, CaseWhen));
  812. if (walker(when->expr, context))
  813. return true;
  814. if (walker(when->result, context))
  815. return true;
  816. }
  817. /* caseexpr->arg should be null, but we'll check it anyway */
  818. if (walker(caseexpr->arg, context))
  819. return true;
  820. if (walker(caseexpr->defresult, context))
  821. return true;
  822. }
  823. break;
  824. case T_SubLink:
  825. /* A "bare" SubLink (note we will not come here if we found
  826.  * a SUBPLAN_EXPR node above).  Examine the lefthand side,
  827.  * but not the oper list nor the subquery.
  828.  */
  829. return walker(((SubLink *) node)->lefthand, context);
  830. case T_List:
  831. foreach(temp, (List *) node)
  832. {
  833. if (walker((Node *) lfirst(temp), context))
  834. return true;
  835. }
  836. break;
  837. case T_TargetEntry:
  838. return walker(((TargetEntry *) node)->expr, context);
  839. default:
  840. elog(ERROR, "expression_tree_walker: Unexpected node type %d",
  841.  nodeTag(node));
  842. break;
  843. }
  844. return false;
  845. }