mirror of
https://github.com/postgres/postgres.git
synced 2025-11-07 19:06:32 +03:00
Merge Resdom nodes into TargetEntry nodes to simplify code and save a
few palloc's. I also chose to eliminate the restype and restypmod fields entirely, since they are redundant with information stored in the node's contained expression; re-examining the expression at need seems simpler and more reliable than trying to keep restype/restypmod up to date. initdb forced due to change in contents of stored rules.
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.124 2005/03/10 23:21:21 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.125 2005/04/06 16:34:05 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "optimizer/var.h"
|
||||
#include "parser/parsetree.h"
|
||||
#include "parser/parse_clause.h"
|
||||
#include "parser/parse_expr.h"
|
||||
#include "rewrite/rewriteManip.h"
|
||||
|
||||
|
||||
@@ -656,12 +657,12 @@ compare_tlist_datatypes(List *tlist, List *colTypes,
|
||||
{
|
||||
TargetEntry *tle = (TargetEntry *) lfirst(l);
|
||||
|
||||
if (tle->resdom->resjunk)
|
||||
if (tle->resjunk)
|
||||
continue; /* ignore resjunk columns */
|
||||
if (colType == NULL)
|
||||
elog(ERROR, "wrong number of tlist entries");
|
||||
if (tle->resdom->restype != lfirst_oid(colType))
|
||||
differentTypes[tle->resdom->resno] = true;
|
||||
if (exprType((Node *) tle->expr) != lfirst_oid(colType))
|
||||
differentTypes[tle->resno] = true;
|
||||
colType = lnext(colType);
|
||||
}
|
||||
if (colType != NULL)
|
||||
@@ -740,7 +741,7 @@ qual_is_pushdown_safe(Query *subquery, Index rti, Node *qual,
|
||||
/* Must find the tlist element referenced by the Var */
|
||||
tle = get_tle_by_resno(subquery->targetList, var->varattno);
|
||||
Assert(tle != NULL);
|
||||
Assert(!tle->resdom->resjunk);
|
||||
Assert(!tle->resjunk);
|
||||
|
||||
/* If subquery uses DISTINCT or DISTINCT ON, check point 3 */
|
||||
if (subquery->distinctClause != NIL &&
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/pathkeys.c,v 1.65 2005/03/27 06:29:36 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/pathkeys.c,v 1.66 2005/04/06 16:34:05 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -791,7 +791,7 @@ build_subquery_pathkeys(Query *root, RelOptInfo *rel, Query *subquery)
|
||||
{
|
||||
TargetEntry *tle = (TargetEntry *) lfirst(k);
|
||||
|
||||
if (!tle->resdom->resjunk &&
|
||||
if (!tle->resjunk &&
|
||||
equal(tle->expr, sub_key))
|
||||
{
|
||||
/* Found a representation for this sub_key */
|
||||
@@ -800,9 +800,9 @@ build_subquery_pathkeys(Query *root, RelOptInfo *rel, Query *subquery)
|
||||
int score;
|
||||
|
||||
outer_var = makeVar(rel->relid,
|
||||
tle->resdom->resno,
|
||||
tle->resdom->restype,
|
||||
tle->resdom->restypmod,
|
||||
tle->resno,
|
||||
exprType((Node *) tle->expr),
|
||||
exprTypmod((Node *) tle->expr),
|
||||
0);
|
||||
outer_item = makePathKeyItem((Node *) outer_var,
|
||||
sub_item->sortop,
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.177 2005/03/27 06:29:38 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.178 2005/04/06 16:34:05 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -259,7 +259,7 @@ static List *
|
||||
build_relation_tlist(RelOptInfo *rel)
|
||||
{
|
||||
List *tlist = NIL;
|
||||
int resdomno = 1;
|
||||
int resno = 1;
|
||||
ListCell *v;
|
||||
|
||||
foreach(v, rel->reltargetlist)
|
||||
@@ -267,8 +267,11 @@ build_relation_tlist(RelOptInfo *rel)
|
||||
/* Do we really need to copy here? Not sure */
|
||||
Var *var = (Var *) copyObject(lfirst(v));
|
||||
|
||||
tlist = lappend(tlist, create_tl_element(var, resdomno));
|
||||
resdomno++;
|
||||
tlist = lappend(tlist, makeTargetEntry((Expr *) var,
|
||||
resno,
|
||||
NULL,
|
||||
false));
|
||||
resno++;
|
||||
}
|
||||
return tlist;
|
||||
}
|
||||
@@ -557,20 +560,18 @@ create_unique_plan(Query *root, UniquePath *best_path)
|
||||
Node *uniqexpr = lfirst(l);
|
||||
TargetEntry *tle;
|
||||
|
||||
tle = tlistentry_member(uniqexpr, newtlist);
|
||||
tle = tlist_member(uniqexpr, newtlist);
|
||||
if (!tle)
|
||||
{
|
||||
tle = makeTargetEntry(makeResdom(nextresno,
|
||||
exprType(uniqexpr),
|
||||
exprTypmod(uniqexpr),
|
||||
NULL,
|
||||
false),
|
||||
(Expr *) uniqexpr);
|
||||
tle = makeTargetEntry((Expr *) uniqexpr,
|
||||
nextresno,
|
||||
NULL,
|
||||
false);
|
||||
newtlist = lappend(newtlist, tle);
|
||||
nextresno++;
|
||||
newitems = true;
|
||||
}
|
||||
groupColIdx[groupColPos++] = tle->resdom->resno;
|
||||
groupColIdx[groupColPos++] = tle->resno;
|
||||
}
|
||||
|
||||
if (newitems)
|
||||
@@ -1844,7 +1845,7 @@ make_sort_from_pathkeys(Query *root, Plan *lefttree, List *pathkeys)
|
||||
{
|
||||
List *keysublist = (List *) lfirst(i);
|
||||
PathKeyItem *pathkey = NULL;
|
||||
Resdom *resdom = NULL;
|
||||
TargetEntry *tle = NULL;
|
||||
ListCell *j;
|
||||
|
||||
/*
|
||||
@@ -1863,11 +1864,11 @@ make_sort_from_pathkeys(Query *root, Plan *lefttree, List *pathkeys)
|
||||
{
|
||||
pathkey = (PathKeyItem *) lfirst(j);
|
||||
Assert(IsA(pathkey, PathKeyItem));
|
||||
resdom = tlist_member(pathkey->key, tlist);
|
||||
if (resdom)
|
||||
tle = tlist_member(pathkey->key, tlist);
|
||||
if (tle)
|
||||
break;
|
||||
}
|
||||
if (!resdom)
|
||||
if (!tle)
|
||||
{
|
||||
/* No matching Var; look for a computable expression */
|
||||
foreach(j, keysublist)
|
||||
@@ -1901,14 +1902,11 @@ make_sort_from_pathkeys(Query *root, Plan *lefttree, List *pathkeys)
|
||||
/*
|
||||
* Add resjunk entry to input's tlist
|
||||
*/
|
||||
resdom = makeResdom(list_length(tlist) + 1,
|
||||
exprType(pathkey->key),
|
||||
exprTypmod(pathkey->key),
|
||||
NULL,
|
||||
true);
|
||||
tlist = lappend(tlist,
|
||||
makeTargetEntry(resdom,
|
||||
(Expr *) pathkey->key));
|
||||
tle = makeTargetEntry((Expr *) pathkey->key,
|
||||
list_length(tlist) + 1,
|
||||
NULL,
|
||||
true);
|
||||
tlist = lappend(tlist, tle);
|
||||
lefttree->targetlist = tlist; /* just in case NIL before */
|
||||
}
|
||||
|
||||
@@ -1918,7 +1916,7 @@ make_sort_from_pathkeys(Query *root, Plan *lefttree, List *pathkeys)
|
||||
* scenarios where multiple mergejoinable clauses mention the same
|
||||
* var, for example.) So enter it only once in the sort arrays.
|
||||
*/
|
||||
numsortkeys = add_sort_column(resdom->resno, pathkey->sortop,
|
||||
numsortkeys = add_sort_column(tle->resno, pathkey->sortop,
|
||||
numsortkeys, sortColIdx, sortOperators);
|
||||
}
|
||||
|
||||
@@ -1964,7 +1962,7 @@ make_sort_from_sortclauses(Query *root, List *sortcls, Plan *lefttree)
|
||||
* parser should have removed 'em, but no point in sorting
|
||||
* redundantly.
|
||||
*/
|
||||
numsortkeys = add_sort_column(tle->resdom->resno, sortcl->sortop,
|
||||
numsortkeys = add_sort_column(tle->resno, sortcl->sortop,
|
||||
numsortkeys, sortColIdx, sortOperators);
|
||||
}
|
||||
|
||||
@@ -2020,7 +2018,7 @@ make_sort_from_groupcols(Query *root,
|
||||
* parser should have removed 'em, but no point in sorting
|
||||
* redundantly.
|
||||
*/
|
||||
numsortkeys = add_sort_column(tle->resdom->resno, grpcl->sortop,
|
||||
numsortkeys = add_sort_column(tle->resno, grpcl->sortop,
|
||||
numsortkeys, sortColIdx, sortOperators);
|
||||
grpno++;
|
||||
}
|
||||
@@ -2253,7 +2251,7 @@ make_unique(Plan *lefttree, List *distinctList)
|
||||
SortClause *sortcl = (SortClause *) lfirst(slitem);
|
||||
TargetEntry *tle = get_sortgroupclause_tle(sortcl, plan->targetlist);
|
||||
|
||||
uniqColIdx[keyno++] = tle->resdom->resno;
|
||||
uniqColIdx[keyno++] = tle->resno;
|
||||
}
|
||||
|
||||
node->numCols = numCols;
|
||||
@@ -2311,7 +2309,7 @@ make_setop(SetOpCmd cmd, Plan *lefttree,
|
||||
SortClause *sortcl = (SortClause *) lfirst(slitem);
|
||||
TargetEntry *tle = get_sortgroupclause_tle(sortcl, plan->targetlist);
|
||||
|
||||
dupColIdx[keyno++] = tle->resdom->resno;
|
||||
dupColIdx[keyno++] = tle->resno;
|
||||
}
|
||||
|
||||
node->cmd = cmd;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.181 2005/03/28 00:58:23 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.182 2005/04/06 16:34:05 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -1349,7 +1349,7 @@ hash_safe_grouping(Query *parse)
|
||||
Operator optup;
|
||||
bool oprcanhash;
|
||||
|
||||
optup = equality_oper(tle->resdom->restype, true);
|
||||
optup = equality_oper(exprType((Node *) tle->expr), true);
|
||||
if (!optup)
|
||||
return false;
|
||||
oprcanhash = ((Form_pg_operator) GETSTRUCT(optup))->oprcanhash;
|
||||
@@ -1467,18 +1467,16 @@ make_subplanTargetList(Query *parse,
|
||||
}
|
||||
if (!sl)
|
||||
{
|
||||
te = makeTargetEntry(makeResdom(list_length(sub_tlist) + 1,
|
||||
exprType(groupexpr),
|
||||
exprTypmod(groupexpr),
|
||||
NULL,
|
||||
false),
|
||||
(Expr *) groupexpr);
|
||||
te = makeTargetEntry((Expr *) groupexpr,
|
||||
list_length(sub_tlist) + 1,
|
||||
NULL,
|
||||
false);
|
||||
sub_tlist = lappend(sub_tlist, te);
|
||||
*need_tlist_eval = true; /* it's not flat anymore */
|
||||
}
|
||||
|
||||
/* and save its resno */
|
||||
grpColIdx[keyno++] = te->resdom->resno;
|
||||
grpColIdx[keyno++] = te->resno;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1528,7 +1526,7 @@ locate_grouping_columns(Query *parse,
|
||||
if (!sl)
|
||||
elog(ERROR, "failed to locate grouping columns");
|
||||
|
||||
groupColIdx[keyno++] = te->resdom->resno;
|
||||
groupColIdx[keyno++] = te->resno;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1554,17 +1552,16 @@ postprocess_setop_tlist(List *new_tlist, List *orig_tlist)
|
||||
TargetEntry *orig_tle;
|
||||
|
||||
/* ignore resjunk columns in setop result */
|
||||
if (new_tle->resdom->resjunk)
|
||||
if (new_tle->resjunk)
|
||||
continue;
|
||||
|
||||
Assert(orig_tlist_item != NULL);
|
||||
orig_tle = (TargetEntry *) lfirst(orig_tlist_item);
|
||||
orig_tlist_item = lnext(orig_tlist_item);
|
||||
if (orig_tle->resdom->resjunk) /* should not happen */
|
||||
if (orig_tle->resjunk) /* should not happen */
|
||||
elog(ERROR, "resjunk output columns are not implemented");
|
||||
Assert(new_tle->resdom->resno == orig_tle->resdom->resno);
|
||||
Assert(new_tle->resdom->restype == orig_tle->resdom->restype);
|
||||
new_tle->resdom->ressortgroupref = orig_tle->resdom->ressortgroupref;
|
||||
Assert(new_tle->resno == orig_tle->resno);
|
||||
new_tle->ressortgroupref = orig_tle->ressortgroupref;
|
||||
}
|
||||
if (orig_tlist_item != NULL)
|
||||
elog(ERROR, "resjunk output columns are not implemented");
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/plan/setrefs.c,v 1.105 2004/12/31 22:00:09 pgsql Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/plan/setrefs.c,v 1.106 2005/04/06 16:34:05 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "optimizer/planmain.h"
|
||||
#include "optimizer/tlist.h"
|
||||
#include "optimizer/var.h"
|
||||
#include "parser/parse_expr.h"
|
||||
#include "parser/parsetree.h"
|
||||
#include "utils/lsyscache.h"
|
||||
|
||||
@@ -462,9 +463,9 @@ set_uppernode_references(Plan *plan, Index subvarno)
|
||||
subvarno,
|
||||
subplan_targetlist,
|
||||
tlist_has_non_vars);
|
||||
output_targetlist = lappend(output_targetlist,
|
||||
makeTargetEntry(tle->resdom,
|
||||
(Expr *) newexpr));
|
||||
tle = flatCopyTargetEntry(tle);
|
||||
tle->expr = (Expr *) newexpr;
|
||||
output_targetlist = lappend(output_targetlist, tle);
|
||||
}
|
||||
plan->targetlist = output_targetlist;
|
||||
|
||||
@@ -550,25 +551,25 @@ join_references_mutator(Node *node,
|
||||
if (IsA(node, Var))
|
||||
{
|
||||
Var *var = (Var *) node;
|
||||
Resdom *resdom;
|
||||
TargetEntry *tle;
|
||||
|
||||
/* First look for the var in the input tlists */
|
||||
resdom = tlist_member((Node *) var, context->outer_tlist);
|
||||
if (resdom)
|
||||
tle = tlist_member((Node *) var, context->outer_tlist);
|
||||
if (tle)
|
||||
{
|
||||
Var *newvar = (Var *) copyObject(var);
|
||||
|
||||
newvar->varno = OUTER;
|
||||
newvar->varattno = resdom->resno;
|
||||
newvar->varattno = tle->resno;
|
||||
return (Node *) newvar;
|
||||
}
|
||||
resdom = tlist_member((Node *) var, context->inner_tlist);
|
||||
if (resdom)
|
||||
tle = tlist_member((Node *) var, context->inner_tlist);
|
||||
if (tle)
|
||||
{
|
||||
Var *newvar = (Var *) copyObject(var);
|
||||
|
||||
newvar->varno = INNER;
|
||||
newvar->varattno = resdom->resno;
|
||||
newvar->varattno = tle->resno;
|
||||
return (Node *) newvar;
|
||||
}
|
||||
|
||||
@@ -582,33 +583,33 @@ join_references_mutator(Node *node,
|
||||
/* Try matching more complex expressions too, if tlists have any */
|
||||
if (context->tlists_have_non_vars)
|
||||
{
|
||||
Resdom *resdom;
|
||||
TargetEntry *tle;
|
||||
|
||||
resdom = tlist_member(node, context->outer_tlist);
|
||||
if (resdom)
|
||||
tle = tlist_member(node, context->outer_tlist);
|
||||
if (tle)
|
||||
{
|
||||
/* Found a matching subplan output expression */
|
||||
Var *newvar;
|
||||
|
||||
newvar = makeVar(OUTER,
|
||||
resdom->resno,
|
||||
resdom->restype,
|
||||
resdom->restypmod,
|
||||
tle->resno,
|
||||
exprType((Node *) tle->expr),
|
||||
exprTypmod((Node *) tle->expr),
|
||||
0);
|
||||
newvar->varnoold = 0; /* wasn't ever a plain Var */
|
||||
newvar->varoattno = 0;
|
||||
return (Node *) newvar;
|
||||
}
|
||||
resdom = tlist_member(node, context->inner_tlist);
|
||||
if (resdom)
|
||||
tle = tlist_member(node, context->inner_tlist);
|
||||
if (tle)
|
||||
{
|
||||
/* Found a matching subplan output expression */
|
||||
Var *newvar;
|
||||
|
||||
newvar = makeVar(INNER,
|
||||
resdom->resno,
|
||||
resdom->restype,
|
||||
resdom->restypmod,
|
||||
tle->resno,
|
||||
exprType((Node *) tle->expr),
|
||||
exprTypmod((Node *) tle->expr),
|
||||
0);
|
||||
newvar->varnoold = 0; /* wasn't ever a plain Var */
|
||||
newvar->varoattno = 0;
|
||||
@@ -668,32 +669,32 @@ replace_vars_with_subplan_refs_mutator(Node *node,
|
||||
if (IsA(node, Var))
|
||||
{
|
||||
Var *var = (Var *) node;
|
||||
Resdom *resdom;
|
||||
TargetEntry *tle;
|
||||
Var *newvar;
|
||||
|
||||
resdom = tlist_member((Node *) var, context->subplan_targetlist);
|
||||
if (!resdom)
|
||||
tle = tlist_member((Node *) var, context->subplan_targetlist);
|
||||
if (!tle)
|
||||
elog(ERROR, "variable not found in subplan target list");
|
||||
newvar = (Var *) copyObject(var);
|
||||
newvar->varno = context->subvarno;
|
||||
newvar->varattno = resdom->resno;
|
||||
newvar->varattno = tle->resno;
|
||||
return (Node *) newvar;
|
||||
}
|
||||
/* Try matching more complex expressions too, if tlist has any */
|
||||
if (context->tlist_has_non_vars)
|
||||
{
|
||||
Resdom *resdom;
|
||||
TargetEntry *tle;
|
||||
|
||||
resdom = tlist_member(node, context->subplan_targetlist);
|
||||
if (resdom)
|
||||
tle = tlist_member(node, context->subplan_targetlist);
|
||||
if (tle)
|
||||
{
|
||||
/* Found a matching subplan output expression */
|
||||
Var *newvar;
|
||||
|
||||
newvar = makeVar(context->subvarno,
|
||||
resdom->resno,
|
||||
resdom->restype,
|
||||
resdom->restypmod,
|
||||
tle->resno,
|
||||
exprType((Node *) tle->expr),
|
||||
exprTypmod((Node *) tle->expr),
|
||||
0);
|
||||
newvar->varnoold = 0; /* wasn't ever a plain Var */
|
||||
newvar->varoattno = 0;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/plan/subselect.c,v 1.94 2004/12/31 22:00:09 pgsql Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/plan/subselect.c,v 1.95 2005/04/06 16:34:05 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -350,8 +350,9 @@ make_subplan(SubLink *slink, List *lefthand, bool isTopQual)
|
||||
TargetEntry *te = linitial(plan->targetlist);
|
||||
Param *prm;
|
||||
|
||||
Assert(!te->resdom->resjunk);
|
||||
prm = generate_new_param(te->resdom->restype, te->resdom->restypmod);
|
||||
Assert(!te->resjunk);
|
||||
prm = generate_new_param(exprType((Node *) te->expr),
|
||||
exprTypmod((Node *) te->expr));
|
||||
node->setParam = list_make1_int(prm->paramid);
|
||||
PlannerInitPlan = lappend(PlannerInitPlan, node);
|
||||
result = (Node *) prm;
|
||||
@@ -362,11 +363,11 @@ make_subplan(SubLink *slink, List *lefthand, bool isTopQual)
|
||||
Oid arraytype;
|
||||
Param *prm;
|
||||
|
||||
Assert(!te->resdom->resjunk);
|
||||
arraytype = get_array_type(te->resdom->restype);
|
||||
Assert(!te->resjunk);
|
||||
arraytype = get_array_type(exprType((Node *) te->expr));
|
||||
if (!OidIsValid(arraytype))
|
||||
elog(ERROR, "could not find array type for datatype %s",
|
||||
format_type_be(te->resdom->restype));
|
||||
format_type_be(exprType((Node *) te->expr)));
|
||||
prm = generate_new_param(arraytype, -1);
|
||||
node->setParam = list_make1_int(prm->paramid);
|
||||
PlannerInitPlan = lappend(PlannerInitPlan, node);
|
||||
@@ -525,15 +526,15 @@ convert_sublink_opers(List *lefthand, List *operOids,
|
||||
Node *rightop;
|
||||
Operator tup;
|
||||
|
||||
Assert(!te->resdom->resjunk);
|
||||
Assert(!te->resjunk);
|
||||
|
||||
if (rtindex)
|
||||
{
|
||||
/* Make the Var node representing the subplan's result */
|
||||
rightop = (Node *) makeVar(rtindex,
|
||||
te->resdom->resno,
|
||||
te->resdom->restype,
|
||||
te->resdom->restypmod,
|
||||
te->resno,
|
||||
exprType((Node *) te->expr),
|
||||
exprTypmod((Node *) te->expr),
|
||||
0);
|
||||
|
||||
/*
|
||||
@@ -547,8 +548,8 @@ convert_sublink_opers(List *lefthand, List *operOids,
|
||||
/* Make the Param node representing the subplan's result */
|
||||
Param *prm;
|
||||
|
||||
prm = generate_new_param(te->resdom->restype,
|
||||
te->resdom->restypmod);
|
||||
prm = generate_new_param(exprType((Node *) te->expr),
|
||||
exprTypmod((Node *) te->expr));
|
||||
/* Record its ID */
|
||||
*righthandIds = lappend_int(*righthandIds, prm->paramid);
|
||||
rightop = (Node *) prm;
|
||||
@@ -575,7 +576,7 @@ convert_sublink_opers(List *lefthand, List *operOids,
|
||||
leftop,
|
||||
rightop,
|
||||
exprType(leftop),
|
||||
te->resdom->restype));
|
||||
exprType((Node *) te->expr)));
|
||||
|
||||
ReleaseSysCache(tup);
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepjointree.c,v 1.25 2004/12/31 22:00:20 pgsql Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepjointree.c,v 1.26 2005/04/06 16:34:06 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -458,7 +458,7 @@ has_nullable_targetlist(Query *subquery)
|
||||
TargetEntry *tle = (TargetEntry *) lfirst(l);
|
||||
|
||||
/* ignore resjunk columns */
|
||||
if (tle->resdom->resjunk)
|
||||
if (tle->resjunk)
|
||||
continue;
|
||||
|
||||
/* Must contain a Var of current level */
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/prep/preptlist.c,v 1.73 2005/03/17 23:44:52 neilc Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/prep/preptlist.c,v 1.74 2005/04/06 16:34:06 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -79,18 +79,17 @@ preprocess_targetlist(Query *parse, List *tlist)
|
||||
*/
|
||||
if (command_type == CMD_UPDATE || command_type == CMD_DELETE)
|
||||
{
|
||||
Resdom *resdom;
|
||||
TargetEntry *tle;
|
||||
Var *var;
|
||||
|
||||
resdom = makeResdom(list_length(tlist) + 1,
|
||||
TIDOID,
|
||||
-1,
|
||||
pstrdup("ctid"),
|
||||
true);
|
||||
|
||||
var = makeVar(result_relation, SelfItemPointerAttributeNumber,
|
||||
TIDOID, -1, 0);
|
||||
|
||||
tle = makeTargetEntry((Expr *) var,
|
||||
list_length(tlist) + 1,
|
||||
pstrdup("ctid"),
|
||||
true);
|
||||
|
||||
/*
|
||||
* For an UPDATE, expand_targetlist already created a fresh tlist.
|
||||
* For DELETE, better do a listCopy so that we don't destructively
|
||||
@@ -99,7 +98,7 @@ preprocess_targetlist(Query *parse, List *tlist)
|
||||
if (command_type == CMD_DELETE)
|
||||
tlist = list_copy(tlist);
|
||||
|
||||
tlist = lappend(tlist, makeTargetEntry(resdom, (Expr *) var));
|
||||
tlist = lappend(tlist, tle);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -132,18 +131,9 @@ preprocess_targetlist(Query *parse, List *tlist)
|
||||
foreach(l, parse->rowMarks)
|
||||
{
|
||||
Index rti = lfirst_int(l);
|
||||
char *resname;
|
||||
Resdom *resdom;
|
||||
Var *var;
|
||||
TargetEntry *ctid;
|
||||
|
||||
resname = (char *) palloc(32);
|
||||
snprintf(resname, 32, "ctid%u", rti);
|
||||
resdom = makeResdom(list_length(tlist) + 1,
|
||||
TIDOID,
|
||||
-1,
|
||||
resname,
|
||||
true);
|
||||
char *resname;
|
||||
TargetEntry *tle;
|
||||
|
||||
var = makeVar(rti,
|
||||
SelfItemPointerAttributeNumber,
|
||||
@@ -151,8 +141,15 @@ preprocess_targetlist(Query *parse, List *tlist)
|
||||
-1,
|
||||
0);
|
||||
|
||||
ctid = makeTargetEntry(resdom, (Expr *) var);
|
||||
tlist = lappend(tlist, ctid);
|
||||
resname = (char *) palloc(32);
|
||||
snprintf(resname, 32, "ctid%u", rti);
|
||||
|
||||
tle = makeTargetEntry((Expr *) var,
|
||||
list_length(tlist) + 1,
|
||||
resname,
|
||||
true);
|
||||
|
||||
tlist = lappend(tlist, tle);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,9 +203,8 @@ expand_targetlist(List *tlist, int command_type,
|
||||
if (tlist_item != NULL)
|
||||
{
|
||||
TargetEntry *old_tle = (TargetEntry *) lfirst(tlist_item);
|
||||
Resdom *resdom = old_tle->resdom;
|
||||
|
||||
if (!resdom->resjunk && resdom->resno == attrno)
|
||||
if (!old_tle->resjunk && old_tle->resno == attrno)
|
||||
{
|
||||
new_tle = old_tle;
|
||||
tlist_item = lnext(tlist_item);
|
||||
@@ -268,9 +264,6 @@ expand_targetlist(List *tlist, int command_type,
|
||||
(Datum) 0,
|
||||
true, /* isnull */
|
||||
true /* byval */ );
|
||||
/* label resdom with INT4, too */
|
||||
atttype = INT4OID;
|
||||
atttypmod = -1;
|
||||
}
|
||||
break;
|
||||
case CMD_UPDATE:
|
||||
@@ -290,9 +283,6 @@ expand_targetlist(List *tlist, int command_type,
|
||||
(Datum) 0,
|
||||
true, /* isnull */
|
||||
true /* byval */ );
|
||||
/* label resdom with INT4, too */
|
||||
atttype = INT4OID;
|
||||
atttypmod = -1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -302,12 +292,10 @@ expand_targetlist(List *tlist, int command_type,
|
||||
break;
|
||||
}
|
||||
|
||||
new_tle = makeTargetEntry(makeResdom(attrno,
|
||||
atttype,
|
||||
atttypmod,
|
||||
new_tle = makeTargetEntry((Expr *) new_expr,
|
||||
attrno,
|
||||
pstrdup(NameStr(att_tup->attname)),
|
||||
false),
|
||||
(Expr *) new_expr);
|
||||
false);
|
||||
}
|
||||
|
||||
new_tlist = lappend(new_tlist, new_tle);
|
||||
@@ -324,16 +312,14 @@ expand_targetlist(List *tlist, int command_type,
|
||||
while (tlist_item)
|
||||
{
|
||||
TargetEntry *old_tle = (TargetEntry *) lfirst(tlist_item);
|
||||
Resdom *resdom = old_tle->resdom;
|
||||
|
||||
if (!resdom->resjunk)
|
||||
if (!old_tle->resjunk)
|
||||
elog(ERROR, "targetlist is not sorted correctly");
|
||||
/* Get the resno right, but don't copy unnecessarily */
|
||||
if (resdom->resno != attrno)
|
||||
if (old_tle->resno != attrno)
|
||||
{
|
||||
resdom = (Resdom *) copyObject((Node *) resdom);
|
||||
resdom->resno = attrno;
|
||||
old_tle = makeTargetEntry(resdom, old_tle->expr);
|
||||
old_tle = flatCopyTargetEntry(old_tle);
|
||||
old_tle->resno = attrno;
|
||||
}
|
||||
new_tlist = lappend(new_tlist, old_tle);
|
||||
attrno++;
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepunion.c,v 1.119 2004/12/31 22:00:20 pgsql Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepunion.c,v 1.120 2005/04/06 16:34:06 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "optimizer/tlist.h"
|
||||
#include "parser/parse_clause.h"
|
||||
#include "parser/parse_coerce.h"
|
||||
#include "parser/parse_expr.h"
|
||||
#include "parser/parsetree.h"
|
||||
#include "utils/lsyscache.h"
|
||||
|
||||
@@ -429,7 +430,7 @@ generate_setop_tlist(List *colTypes, int flag,
|
||||
ListCell *i,
|
||||
*j,
|
||||
*k;
|
||||
Resdom *resdom;
|
||||
TargetEntry *tle;
|
||||
Node *expr;
|
||||
|
||||
j = list_head(input_tlist);
|
||||
@@ -439,12 +440,11 @@ generate_setop_tlist(List *colTypes, int flag,
|
||||
Oid colType = lfirst_oid(i);
|
||||
TargetEntry *inputtle = (TargetEntry *) lfirst(j);
|
||||
TargetEntry *reftle = (TargetEntry *) lfirst(k);
|
||||
int32 colTypmod;
|
||||
|
||||
Assert(inputtle->resdom->resno == resno);
|
||||
Assert(reftle->resdom->resno == resno);
|
||||
Assert(!inputtle->resdom->resjunk);
|
||||
Assert(!reftle->resdom->resjunk);
|
||||
Assert(inputtle->resno == resno);
|
||||
Assert(reftle->resno == resno);
|
||||
Assert(!inputtle->resjunk);
|
||||
Assert(!reftle->resjunk);
|
||||
|
||||
/*
|
||||
* Generate columns referencing input columns and having
|
||||
@@ -463,29 +463,23 @@ generate_setop_tlist(List *colTypes, int flag,
|
||||
expr = (Node *) inputtle->expr;
|
||||
else
|
||||
expr = (Node *) makeVar(0,
|
||||
inputtle->resdom->resno,
|
||||
inputtle->resdom->restype,
|
||||
inputtle->resdom->restypmod,
|
||||
inputtle->resno,
|
||||
exprType((Node *) inputtle->expr),
|
||||
exprTypmod((Node *) inputtle->expr),
|
||||
0);
|
||||
if (inputtle->resdom->restype == colType)
|
||||
{
|
||||
/* no coercion needed, and believe the input typmod */
|
||||
colTypmod = inputtle->resdom->restypmod;
|
||||
}
|
||||
else
|
||||
if (exprType(expr) != colType)
|
||||
{
|
||||
expr = coerce_to_common_type(NULL, /* no UNKNOWNs here */
|
||||
expr,
|
||||
colType,
|
||||
"UNION/INTERSECT/EXCEPT");
|
||||
colTypmod = -1;
|
||||
}
|
||||
resdom = makeResdom((AttrNumber) resno++,
|
||||
colType,
|
||||
colTypmod,
|
||||
pstrdup(reftle->resdom->resname),
|
||||
false);
|
||||
tlist = lappend(tlist, makeTargetEntry(resdom, (Expr *) expr));
|
||||
tle = makeTargetEntry((Expr *) expr,
|
||||
(AttrNumber) resno++,
|
||||
pstrdup(reftle->resname),
|
||||
false);
|
||||
tlist = lappend(tlist, tle);
|
||||
|
||||
j = lnext(j);
|
||||
k = lnext(k);
|
||||
}
|
||||
@@ -493,18 +487,17 @@ generate_setop_tlist(List *colTypes, int flag,
|
||||
if (flag >= 0)
|
||||
{
|
||||
/* Add a resjunk flag column */
|
||||
resdom = makeResdom((AttrNumber) resno++,
|
||||
INT4OID,
|
||||
-1,
|
||||
pstrdup("flag"),
|
||||
true);
|
||||
/* flag value is the given constant */
|
||||
expr = (Node *) makeConst(INT4OID,
|
||||
sizeof(int4),
|
||||
Int32GetDatum(flag),
|
||||
false,
|
||||
true);
|
||||
tlist = lappend(tlist, makeTargetEntry(resdom, (Expr *) expr));
|
||||
tle = makeTargetEntry((Expr *) expr,
|
||||
(AttrNumber) resno++,
|
||||
pstrdup("flag"),
|
||||
true);
|
||||
tlist = lappend(tlist, tle);
|
||||
}
|
||||
|
||||
return tlist;
|
||||
@@ -531,7 +524,7 @@ generate_append_tlist(List *colTypes, bool flag,
|
||||
ListCell *curColType;
|
||||
ListCell *ref_tl_item;
|
||||
int colindex;
|
||||
Resdom *resdom;
|
||||
TargetEntry *tle;
|
||||
Node *expr;
|
||||
ListCell *planl;
|
||||
int32 *colTypmods;
|
||||
@@ -555,15 +548,17 @@ generate_append_tlist(List *colTypes, bool flag,
|
||||
{
|
||||
TargetEntry *subtle = (TargetEntry *) lfirst(subtlist);
|
||||
|
||||
if (subtle->resdom->resjunk)
|
||||
if (subtle->resjunk)
|
||||
continue;
|
||||
Assert(curColType != NULL);
|
||||
if (subtle->resdom->restype == lfirst_oid(curColType))
|
||||
if (exprType((Node *) subtle->expr) == lfirst_oid(curColType))
|
||||
{
|
||||
/* If first subplan, copy the typmod; else compare */
|
||||
int32 subtypmod = exprTypmod((Node *) subtle->expr);
|
||||
|
||||
if (planl == list_head(input_plans))
|
||||
colTypmods[colindex] = subtle->resdom->restypmod;
|
||||
else if (subtle->resdom->restypmod != colTypmods[colindex])
|
||||
colTypmods[colindex] = subtypmod;
|
||||
else if (subtypmod != colTypmods[colindex])
|
||||
colTypmods[colindex] = -1;
|
||||
}
|
||||
else
|
||||
@@ -587,36 +582,34 @@ generate_append_tlist(List *colTypes, bool flag,
|
||||
int32 colTypmod = colTypmods[colindex++];
|
||||
TargetEntry *reftle = (TargetEntry *) lfirst(ref_tl_item);
|
||||
|
||||
Assert(reftle->resdom->resno == resno);
|
||||
Assert(!reftle->resdom->resjunk);
|
||||
Assert(reftle->resno == resno);
|
||||
Assert(!reftle->resjunk);
|
||||
expr = (Node *) makeVar(0,
|
||||
resno,
|
||||
colType,
|
||||
colTypmod,
|
||||
0);
|
||||
resdom = makeResdom((AttrNumber) resno++,
|
||||
colType,
|
||||
colTypmod,
|
||||
pstrdup(reftle->resdom->resname),
|
||||
false);
|
||||
tlist = lappend(tlist, makeTargetEntry(resdom, (Expr *) expr));
|
||||
tle = makeTargetEntry((Expr *) expr,
|
||||
(AttrNumber) resno++,
|
||||
pstrdup(reftle->resname),
|
||||
false);
|
||||
tlist = lappend(tlist, tle);
|
||||
}
|
||||
|
||||
if (flag)
|
||||
{
|
||||
/* Add a resjunk flag column */
|
||||
resdom = makeResdom((AttrNumber) resno++,
|
||||
INT4OID,
|
||||
-1,
|
||||
pstrdup("flag"),
|
||||
true);
|
||||
/* flag value is shown as copied up from subplan */
|
||||
expr = (Node *) makeVar(0,
|
||||
resdom->resno,
|
||||
resno,
|
||||
INT4OID,
|
||||
-1,
|
||||
0);
|
||||
tlist = lappend(tlist, makeTargetEntry(resdom, (Expr *) expr));
|
||||
tle = makeTargetEntry((Expr *) expr,
|
||||
(AttrNumber) resno++,
|
||||
pstrdup("flag"),
|
||||
true);
|
||||
tlist = lappend(tlist, tle);
|
||||
}
|
||||
|
||||
pfree(colTypmods);
|
||||
@@ -640,7 +633,7 @@ tlist_same_datatypes(List *tlist, List *colTypes, bool junkOK)
|
||||
{
|
||||
TargetEntry *tle = (TargetEntry *) lfirst(l);
|
||||
|
||||
if (tle->resdom->resjunk)
|
||||
if (tle->resjunk)
|
||||
{
|
||||
if (!junkOK)
|
||||
return false;
|
||||
@@ -649,7 +642,7 @@ tlist_same_datatypes(List *tlist, List *colTypes, bool junkOK)
|
||||
{
|
||||
if (curColType == NULL)
|
||||
return false;
|
||||
if (tle->resdom->restype != lfirst_oid(curColType))
|
||||
if (exprType((Node *) tle->expr) != lfirst_oid(curColType))
|
||||
return false;
|
||||
curColType = lnext(curColType);
|
||||
}
|
||||
@@ -1105,8 +1098,7 @@ adjust_relid_set(Relids relids, Index oldrelid, Index newrelid)
|
||||
*
|
||||
* The given tlist has already been through expression_tree_mutator;
|
||||
* therefore the TargetEntry nodes are fresh copies that it's okay to
|
||||
* scribble on. But the Resdom nodes have not been copied; make new ones
|
||||
* if we need to change them!
|
||||
* scribble on.
|
||||
*
|
||||
* Note that this is not needed for INSERT because INSERT isn't inheritable.
|
||||
*/
|
||||
@@ -1124,18 +1116,15 @@ adjust_inherited_tlist(List *tlist,
|
||||
foreach(tl, tlist)
|
||||
{
|
||||
TargetEntry *tle = (TargetEntry *) lfirst(tl);
|
||||
Resdom *resdom = tle->resdom;
|
||||
|
||||
if (resdom->resjunk)
|
||||
if (tle->resjunk)
|
||||
continue; /* ignore junk items */
|
||||
|
||||
attrno = translate_inherited_attnum(resdom->resno, context);
|
||||
attrno = translate_inherited_attnum(tle->resno, context);
|
||||
|
||||
if (resdom->resno != attrno)
|
||||
if (tle->resno != attrno)
|
||||
{
|
||||
resdom = (Resdom *) copyObject((Node *) resdom);
|
||||
resdom->resno = attrno;
|
||||
tle->resdom = resdom;
|
||||
tle->resno = attrno;
|
||||
changed_it = true;
|
||||
}
|
||||
}
|
||||
@@ -1157,14 +1146,13 @@ adjust_inherited_tlist(List *tlist,
|
||||
foreach(tl, tlist)
|
||||
{
|
||||
TargetEntry *tle = (TargetEntry *) lfirst(tl);
|
||||
Resdom *resdom = tle->resdom;
|
||||
|
||||
if (resdom->resjunk)
|
||||
if (tle->resjunk)
|
||||
continue; /* ignore junk items */
|
||||
|
||||
if (resdom->resno == attrno)
|
||||
if (tle->resno == attrno)
|
||||
new_tlist = lappend(new_tlist, tle);
|
||||
else if (resdom->resno > attrno)
|
||||
else if (tle->resno > attrno)
|
||||
more = true;
|
||||
}
|
||||
}
|
||||
@@ -1172,17 +1160,11 @@ adjust_inherited_tlist(List *tlist,
|
||||
foreach(tl, tlist)
|
||||
{
|
||||
TargetEntry *tle = (TargetEntry *) lfirst(tl);
|
||||
Resdom *resdom = tle->resdom;
|
||||
|
||||
if (!resdom->resjunk)
|
||||
if (!tle->resjunk)
|
||||
continue; /* here, ignore non-junk items */
|
||||
|
||||
if (resdom->resno != attrno)
|
||||
{
|
||||
resdom = (Resdom *) copyObject((Node *) resdom);
|
||||
resdom->resno = attrno;
|
||||
tle->resdom = resdom;
|
||||
}
|
||||
tle->resno = attrno;
|
||||
new_tlist = lappend(new_tlist, tle);
|
||||
attrno++;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.192 2005/03/31 22:46:09 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.193 2005/04/06 16:34:06 tgl Exp $
|
||||
*
|
||||
* HISTORY
|
||||
* AUTHOR DATE MAJOR EVENT
|
||||
@@ -966,22 +966,22 @@ has_distinct_on_clause(Query *query)
|
||||
{
|
||||
TargetEntry *tle = (TargetEntry *) lfirst(l);
|
||||
|
||||
if (tle->resdom->ressortgroupref == 0)
|
||||
if (tle->ressortgroupref == 0)
|
||||
{
|
||||
if (tle->resdom->resjunk)
|
||||
if (tle->resjunk)
|
||||
continue; /* we can ignore unsorted junk cols */
|
||||
return true; /* definitely not in DISTINCT list */
|
||||
}
|
||||
if (targetIsInSortList(tle, query->distinctClause))
|
||||
{
|
||||
if (tle->resdom->resjunk)
|
||||
if (tle->resjunk)
|
||||
return true; /* junk TLE in DISTINCT means DISTINCT ON */
|
||||
/* else this TLE is okay, keep looking */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This TLE is not in DISTINCT list */
|
||||
if (!tle->resdom->resjunk)
|
||||
if (!tle->resjunk)
|
||||
return true; /* non-junk, non-DISTINCT, so DISTINCT ON */
|
||||
if (targetIsInSortList(tle, query->sortClause))
|
||||
return true; /* sorted, non-distinct junk */
|
||||
@@ -3314,10 +3314,6 @@ expression_tree_mutator(Node *node,
|
||||
break;
|
||||
case T_TargetEntry:
|
||||
{
|
||||
/*
|
||||
* We mutate the expression, but not the resdom, by
|
||||
* default.
|
||||
*/
|
||||
TargetEntry *targetentry = (TargetEntry *) node;
|
||||
TargetEntry *newnode;
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/util/pathnode.c,v 1.114 2005/03/27 06:29:42 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/util/pathnode.c,v 1.115 2005/04/06 16:34:06 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -789,7 +789,7 @@ is_distinct_query(Query *query)
|
||||
TargetEntry *tle = get_sortgroupclause_tle(grpcl,
|
||||
query->targetList);
|
||||
|
||||
if (tle->resdom->resjunk)
|
||||
if (tle->resjunk)
|
||||
break;
|
||||
}
|
||||
if (!gl) /* got to the end? */
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.103 2005/03/29 00:17:02 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.104 2005/04/06 16:34:06 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -378,6 +378,7 @@ build_physical_tlist(Query *root, RelOptInfo *rel)
|
||||
for (attrno = 1; attrno <= numattrs; attrno++)
|
||||
{
|
||||
Form_pg_attribute att_tup = relation->rd_att->attrs[attrno - 1];
|
||||
Var *var;
|
||||
|
||||
if (att_tup->attisdropped)
|
||||
{
|
||||
@@ -386,13 +387,17 @@ build_physical_tlist(Query *root, RelOptInfo *rel)
|
||||
break;
|
||||
}
|
||||
|
||||
var = makeVar(varno,
|
||||
attrno,
|
||||
att_tup->atttypid,
|
||||
att_tup->atttypmod,
|
||||
0);
|
||||
|
||||
tlist = lappend(tlist,
|
||||
create_tl_element(makeVar(varno,
|
||||
attrno,
|
||||
att_tup->atttypid,
|
||||
att_tup->atttypmod,
|
||||
0),
|
||||
attrno));
|
||||
makeTargetEntry((Expr *) var,
|
||||
attrno,
|
||||
NULL,
|
||||
false));
|
||||
}
|
||||
|
||||
heap_close(relation, AccessShareLock);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/util/tlist.c,v 1.68 2004/12/31 22:00:23 pgsql Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/util/tlist.c,v 1.69 2005/04/06 16:34:06 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -25,12 +25,12 @@
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* tlistentry_member
|
||||
* tlist_member
|
||||
* Finds the (first) member of the given tlist whose expression is
|
||||
* equal() to the given expression. Result is NULL if no such member.
|
||||
*/
|
||||
TargetEntry *
|
||||
tlistentry_member(Node *node, List *targetlist)
|
||||
tlist_member(Node *node, List *targetlist)
|
||||
{
|
||||
ListCell *temp;
|
||||
|
||||
@@ -44,77 +44,6 @@ tlistentry_member(Node *node, List *targetlist)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef NOT_USED
|
||||
/*
|
||||
* matching_tlist_expr
|
||||
* Same as tlistentry_member(), except returns the tlist expression
|
||||
* rather than its parent TargetEntry node.
|
||||
*/
|
||||
Node *
|
||||
matching_tlist_expr(Node *node, List *targetlist)
|
||||
{
|
||||
TargetEntry *tlentry;
|
||||
|
||||
tlentry = tlistentry_member(node, targetlist);
|
||||
if (tlentry)
|
||||
return tlentry->expr;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* tlist_member
|
||||
* Same as tlistentry_member(), except returns the Resdom node
|
||||
* rather than its parent TargetEntry node.
|
||||
*/
|
||||
Resdom *
|
||||
tlist_member(Node *node, List *targetlist)
|
||||
{
|
||||
TargetEntry *tlentry;
|
||||
|
||||
tlentry = tlistentry_member(node, targetlist);
|
||||
if (tlentry)
|
||||
return tlentry->resdom;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* create_tl_element
|
||||
* Creates a target list entry node and its associated (resdom var) pair
|
||||
* with its resdom number equal to 'resdomno'.
|
||||
*
|
||||
* Note: the argument is almost always a Var, but occasionally not.
|
||||
*/
|
||||
TargetEntry *
|
||||
create_tl_element(Var *var, int resdomno)
|
||||
{
|
||||
Oid vartype;
|
||||
int32 vartypmod;
|
||||
|
||||
if (IsA(var, Var))
|
||||
{
|
||||
vartype = var->vartype;
|
||||
vartypmod = var->vartypmod;
|
||||
}
|
||||
else
|
||||
{
|
||||
vartype = exprType((Node *) var);
|
||||
vartypmod = exprTypmod((Node *) var);
|
||||
}
|
||||
return makeTargetEntry(makeResdom(resdomno,
|
||||
vartype,
|
||||
vartypmod,
|
||||
NULL,
|
||||
false),
|
||||
(Expr *) var);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* ---------- GENERAL target list routines ----------
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* flatten_tlist
|
||||
* Create a target list that only contains unique variables.
|
||||
@@ -153,24 +82,22 @@ flatten_tlist(List *tlist)
|
||||
List *
|
||||
add_to_flat_tlist(List *tlist, List *vars)
|
||||
{
|
||||
int next_resdomno = list_length(tlist) + 1;
|
||||
int next_resno = list_length(tlist) + 1;
|
||||
ListCell *v;
|
||||
|
||||
foreach(v, vars)
|
||||
{
|
||||
Var *var = (Var *) lfirst(v);
|
||||
|
||||
if (!tlistentry_member((Node *) var, tlist))
|
||||
if (!tlist_member((Node *) var, tlist))
|
||||
{
|
||||
Resdom *r;
|
||||
TargetEntry *tle;
|
||||
|
||||
r = makeResdom(next_resdomno++,
|
||||
var->vartype,
|
||||
var->vartypmod,
|
||||
NULL,
|
||||
false);
|
||||
tlist = lappend(tlist,
|
||||
makeTargetEntry(r, copyObject(var)));
|
||||
tle = makeTargetEntry(copyObject(var), /* copy needed?? */
|
||||
next_resno++,
|
||||
NULL,
|
||||
false);
|
||||
tlist = lappend(tlist, tle);
|
||||
}
|
||||
}
|
||||
return tlist;
|
||||
@@ -195,7 +122,7 @@ get_sortgroupclause_tle(SortClause *sortClause,
|
||||
{
|
||||
TargetEntry *tle = (TargetEntry *) lfirst(l);
|
||||
|
||||
if (tle->resdom->ressortgroupref == refnumber)
|
||||
if (tle->ressortgroupref == refnumber)
|
||||
return tle;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user