1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-15 19:21:59 +03:00

Further tweaking of parsetree & plantree representation of SubLinks.

Simplify SubLink by storing just a List of operator OIDs, instead of
a list of incomplete OpExprs --- that was a bizarre and bulky choice,
with no redeeming social value since we have to build new OpExprs
anyway when forming the plan tree.
This commit is contained in:
Tom Lane
2003-01-10 21:08:15 +00:00
parent 36ea26793a
commit e69785debf
17 changed files with 407 additions and 246 deletions

View File

@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.393 2003/01/10 11:02:51 petere Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.394 2003/01/10 21:08:13 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@ -5430,10 +5430,9 @@ opt_interval:
r_expr: row IN_P select_with_parens
{
SubLink *n = makeNode(SubLink);
n->lefthand = $1;
n->oper = (List *) makeSimpleA_Expr(OP, "=", NULL, NULL);
n->subLinkType = ANY_SUBLINK;
/* operIsEquals and useOr will be set later */
n->lefthand = $1;
n->operName = makeList1(makeString("="));
n->subselect = $3;
$$ = (Node *)n;
}
@ -5441,10 +5440,9 @@ r_expr: row IN_P select_with_parens
{
/* Make an IN node */
SubLink *n = makeNode(SubLink);
n->lefthand = $1;
n->oper = (List *) makeSimpleA_Expr(OP, "=", NULL, NULL);
n->subLinkType = ANY_SUBLINK;
/* operIsEquals and useOr will be set later */
n->lefthand = $1;
n->operName = makeList1(makeString("="));
n->subselect = $4;
/* Stick a NOT on top */
$$ = (Node *) makeA_Expr(NOT, NIL, NULL, (Node *) n);
@ -5453,10 +5451,9 @@ r_expr: row IN_P select_with_parens
%prec Op
{
SubLink *n = makeNode(SubLink);
n->lefthand = $1;
n->oper = (List *) makeA_Expr(OP, $2, NULL, NULL);
n->subLinkType = $3;
/* operIsEquals and useOr will be set later */
n->lefthand = $1;
n->operName = $2;
n->subselect = $4;
$$ = (Node *)n;
}
@ -5464,10 +5461,9 @@ r_expr: row IN_P select_with_parens
%prec Op
{
SubLink *n = makeNode(SubLink);
n->lefthand = $1;
n->oper = (List *) makeA_Expr(OP, $2, NULL, NULL);
n->subLinkType = MULTIEXPR_SUBLINK;
/* operIsEquals and useOr will be set later */
n->lefthand = $1;
n->operName = $2;
n->subselect = $3;
$$ = (Node *)n;
}
@ -5848,10 +5844,9 @@ a_expr: c_expr { $$ = $1; }
if (IsA($3, SubLink))
{
SubLink *n = (SubLink *)$3;
n->lefthand = makeList1($1);
n->oper = (List *) makeSimpleA_Expr(OP, "=", NULL, NULL);
n->subLinkType = ANY_SUBLINK;
/* operIsEquals and useOr will be set later */
n->lefthand = makeList1($1);
n->operName = makeList1(makeString("="));
$$ = (Node *)n;
}
else
@ -5877,10 +5872,9 @@ a_expr: c_expr { $$ = $1; }
{
/* Make an IN node */
SubLink *n = (SubLink *)$4;
n->lefthand = makeList1($1);
n->oper = (List *) makeSimpleA_Expr(OP, "=", NULL, NULL);
n->subLinkType = ANY_SUBLINK;
/* operIsEquals and useOr will be set later */
n->lefthand = makeList1($1);
n->operName = makeList1(makeString("="));
/* Stick a NOT on top */
$$ = (Node *) makeA_Expr(NOT, NIL, NULL, (Node *) n);
}
@ -5903,10 +5897,9 @@ a_expr: c_expr { $$ = $1; }
| a_expr qual_all_Op sub_type select_with_parens %prec Op
{
SubLink *n = makeNode(SubLink);
n->lefthand = makeList1($1);
n->oper = (List *) makeA_Expr(OP, $2, NULL, NULL);
n->subLinkType = $3;
/* operIsEquals and useOr will be set later */
n->lefthand = makeList1($1);
n->operName = $2;
n->subselect = $4;
$$ = (Node *)n;
}
@ -6447,18 +6440,18 @@ c_expr: columnref { $$ = (Node *) $1; }
| select_with_parens %prec UMINUS
{
SubLink *n = makeNode(SubLink);
n->lefthand = NIL;
n->oper = NIL;
n->subLinkType = EXPR_SUBLINK;
n->lefthand = NIL;
n->operName = NIL;
n->subselect = $1;
$$ = (Node *)n;
}
| EXISTS select_with_parens
{
SubLink *n = makeNode(SubLink);
n->lefthand = NIL;
n->oper = NIL;
n->subLinkType = EXISTS_SUBLINK;
n->lefthand = NIL;
n->operName = NIL;
n->subselect = $2;
$$ = (Node *)n;
}
@ -6610,6 +6603,7 @@ in_expr: select_with_parens
{
SubLink *n = makeNode(SubLink);
n->subselect = $1;
/* other fields will be filled later */
$$ = (Node *)n;
}
| '(' expr_list ')' { $$ = (Node *)$2; }

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.139 2003/01/09 20:50:52 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.140 2003/01/10 21:08:15 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -366,8 +366,8 @@ transformExpr(ParseState *pstate, Node *expr)
* These fields should be NIL already, but make sure.
*/
sublink->lefthand = NIL;
sublink->oper = NIL;
sublink->operIsEquals = FALSE;
sublink->operName = NIL;
sublink->operOids = NIL;
sublink->useOr = FALSE;
}
else if (sublink->subLinkType == EXPR_SUBLINK)
@ -392,8 +392,8 @@ transformExpr(ParseState *pstate, Node *expr)
* fields should be NIL already, but make sure.
*/
sublink->lefthand = NIL;
sublink->oper = NIL;
sublink->operIsEquals = FALSE;
sublink->operName = NIL;
sublink->operOids = NIL;
sublink->useOr = FALSE;
}
else
@ -403,20 +403,14 @@ transformExpr(ParseState *pstate, Node *expr)
List *right_list = qtree->targetList;
int row_length = length(left_list);
bool needNot = false;
List *op;
char *opname;
List *op = sublink->operName;
char *opname = strVal(llast(op));
List *elist;
/* transform lefthand expressions */
foreach(elist, left_list)
lfirst(elist) = transformExpr(pstate, lfirst(elist));
/* get the combining-operator name */
Assert(IsA(sublink->oper, A_Expr));
op = ((A_Expr *) sublink->oper)->name;
opname = strVal(llast(op));
sublink->oper = NIL;
/*
* If the expression is "<> ALL" (with unqualified opname)
* then convert it to "NOT IN". This is a hack to improve
@ -428,15 +422,10 @@ transformExpr(ParseState *pstate, Node *expr)
sublink->subLinkType = ANY_SUBLINK;
opname = pstrdup("=");
op = makeList1(makeString(opname));
sublink->operName = op;
needNot = true;
}
/* Set operIsEquals if op is unqualified "=" */
if (length(op) == 1 && strcmp(opname, "=") == 0)
sublink->operIsEquals = TRUE;
else
sublink->operIsEquals = FALSE;
/* Set useOr if op is "<>" (possibly qualified) */
if (strcmp(opname, "<>") == 0)
sublink->useOr = TRUE;
@ -451,19 +440,21 @@ transformExpr(ParseState *pstate, Node *expr)
opname);
/*
* Scan subquery's targetlist to find values that will
* To build the list of combining operator OIDs, we must
* scan subquery's targetlist to find values that will
* be matched against lefthand values. We need to
* ignore resjunk targets, so doing the outer
* iteration over right_list is easier than doing it
* over left_list.
*/
sublink->operOids = NIL;
while (right_list != NIL)
{
TargetEntry *tent = (TargetEntry *) lfirst(right_list);
Node *lexpr;
Operator optup;
Form_pg_operator opform;
OpExpr *newop;
right_list = lnext(right_list);
if (tent->resdom->resjunk)
@ -496,14 +487,8 @@ transformExpr(ParseState *pstate, Node *expr)
" to be used with quantified predicate subquery",
opname);
newop = makeNode(OpExpr);
newop->opno = oprid(optup);
newop->opfuncid = InvalidOid;
newop->opresulttype = opform->oprresult;
newop->opretset = false;
newop->args = NIL; /* for now */
sublink->oper = lappend(sublink->oper, newop);
sublink->operOids = lappendi(sublink->operOids,
oprid(optup));
ReleaseSysCache(optup);
}