diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2002-12-12 15:49:42 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2002-12-12 15:49:42 +0000 |
commit | a0bf885f9eaccadd23b766ecbc064f17f06ae883 (patch) | |
tree | 62b65e5cf1a8ec02ece3a98c15457ddff018bb94 /src/backend/parser/parse_expr.c | |
parent | debb072886efcb15e7f0825e35b168afe316d37d (diff) | |
download | postgresql-a0bf885f9eaccadd23b766ecbc064f17f06ae883.tar.gz postgresql-a0bf885f9eaccadd23b766ecbc064f17f06ae883.zip |
Phase 2 of read-only-plans project: restructure expression-tree nodes
so that all executable expression nodes inherit from a common supertype
Expr. This is somewhat of an exercise in code purity rather than any
real functional advance, but getting rid of the extra Oper or Func node
formerly used in each operator or function call should provide at least
a little space and speed improvement.
initdb forced by changes in stored-rules representation.
Diffstat (limited to 'src/backend/parser/parse_expr.c')
-rw-r--r-- | src/backend/parser/parse_expr.c | 159 |
1 files changed, 85 insertions, 74 deletions
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c index 41e66942859..7dcbf59a4e3 100644 --- a/src/backend/parser/parse_expr.c +++ b/src/backend/parser/parse_expr.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.135 2002/12/06 05:00:26 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.136 2002/12/12 15:49:39 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -199,9 +199,9 @@ transformExpr(ParseState *pstate, Node *expr, ConstraintTestValue *domVal) n->nulltesttype = IS_NULL; if (exprIsNullConstant(a->lexpr)) - n->arg = a->rexpr; + n->arg = (Expr *) a->rexpr; else - n->arg = a->lexpr; + n->arg = (Expr *) a->lexpr; result = transformExpr(pstate, (Node *) n, domVal); @@ -225,15 +225,13 @@ transformExpr(ParseState *pstate, Node *expr, ConstraintTestValue *domVal) a->lexpr, domVal); Node *rexpr = transformExpr(pstate, a->rexpr, domVal); - Expr *expr = makeNode(Expr); lexpr = coerce_to_boolean(lexpr, "AND"); rexpr = coerce_to_boolean(rexpr, "AND"); - expr->typeOid = BOOLOID; - expr->opType = AND_EXPR; - expr->args = makeList2(lexpr, rexpr); - result = (Node *) expr; + result = (Node *) makeBoolExpr(AND_EXPR, + makeList2(lexpr, + rexpr)); } break; case OR: @@ -242,29 +240,24 @@ transformExpr(ParseState *pstate, Node *expr, ConstraintTestValue *domVal) a->lexpr, domVal); Node *rexpr = transformExpr(pstate, a->rexpr, domVal); - Expr *expr = makeNode(Expr); lexpr = coerce_to_boolean(lexpr, "OR"); rexpr = coerce_to_boolean(rexpr, "OR"); - expr->typeOid = BOOLOID; - expr->opType = OR_EXPR; - expr->args = makeList2(lexpr, rexpr); - result = (Node *) expr; + result = (Node *) makeBoolExpr(OR_EXPR, + makeList2(lexpr, + rexpr)); } break; case NOT: { Node *rexpr = transformExpr(pstate, a->rexpr, domVal); - Expr *expr = makeNode(Expr); rexpr = coerce_to_boolean(rexpr, "NOT"); - expr->typeOid = BOOLOID; - expr->opType = NOT_EXPR; - expr->args = makeList1(rexpr); - result = (Node *) expr; + result = (Node *) makeBoolExpr(NOT_EXPR, + makeList1(rexpr)); } break; case DISTINCT: @@ -277,9 +270,12 @@ transformExpr(ParseState *pstate, Node *expr, ConstraintTestValue *domVal) result = (Node *) make_op(a->name, lexpr, rexpr); - if (((Expr *) result)->typeOid != BOOLOID) + if (((OpExpr *) result)->opresulttype != BOOLOID) elog(ERROR, "IS DISTINCT FROM requires = operator to yield boolean"); - ((Expr *) result)->opType = DISTINCT_EXPR; + /* + * We rely on DistinctExpr and OpExpr being same struct + */ + NodeSetTag(result, T_DistinctExpr); } break; case OF: @@ -433,7 +429,7 @@ transformExpr(ParseState *pstate, Node *expr, ConstraintTestValue *domVal) Node *lexpr; Operator optup; Form_pg_operator opform; - Oper *newop; + OpExpr *newop; right_list = lnext(right_list); if (tent->resdom->resjunk) @@ -451,7 +447,7 @@ transformExpr(ParseState *pstate, Node *expr, ConstraintTestValue *domVal) */ optup = oper(op, exprType(lexpr), - exprType(tent->expr), + exprType((Node *) tent->expr), false); opform = (Form_pg_operator) GETSTRUCT(optup); @@ -466,11 +462,15 @@ transformExpr(ParseState *pstate, Node *expr, ConstraintTestValue *domVal) " to be used with quantified predicate subquery", opname); - newop = makeOper(oprid(optup), /* opno */ - InvalidOid, /* opid */ - opform->oprresult, - false); + 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); + ReleaseSysCache(optup); } if (left_list != NIL) @@ -499,22 +499,24 @@ transformExpr(ParseState *pstate, Node *expr, ConstraintTestValue *domVal) Assert(IsA(w, CaseWhen)); - warg = w->expr; + warg = (Node *) w->expr; if (c->arg != NULL) { /* shorthand form was specified, so expand... */ warg = (Node *) makeSimpleA_Expr(OP, "=", - c->arg, warg); + (Node *) c->arg, + warg); } - neww->expr = transformExpr(pstate, warg, domVal); + neww->expr = (Expr *) transformExpr(pstate, warg, domVal); - neww->expr = coerce_to_boolean(neww->expr, "CASE/WHEN"); + neww->expr = (Expr *) coerce_to_boolean((Node *) neww->expr, + "CASE/WHEN"); /* * result is NULL for NULLIF() construct - thomas * 1998-11-11 */ - warg = w->result; + warg = (Node *) w->result; if (warg == NULL) { A_Const *n = makeNode(A_Const); @@ -522,10 +524,10 @@ transformExpr(ParseState *pstate, Node *expr, ConstraintTestValue *domVal) n->val.type = T_Null; warg = (Node *) n; } - neww->result = transformExpr(pstate, warg, domVal); + neww->result = (Expr *) transformExpr(pstate, warg, domVal); newargs = lappend(newargs, neww); - typeids = lappendi(typeids, exprType(neww->result)); + typeids = lappendi(typeids, exprType((Node *) neww->result)); } newc->args = newargs; @@ -538,7 +540,7 @@ transformExpr(ParseState *pstate, Node *expr, ConstraintTestValue *domVal) newc->arg = NULL; /* transform the default clause */ - defresult = c->defresult; + defresult = (Node *) c->defresult; if (defresult == NULL) { A_Const *n = makeNode(A_Const); @@ -546,7 +548,7 @@ transformExpr(ParseState *pstate, Node *expr, ConstraintTestValue *domVal) n->val.type = T_Null; defresult = (Node *) n; } - newc->defresult = transformExpr(pstate, defresult, domVal); + newc->defresult = (Expr *) transformExpr(pstate, defresult, domVal); /* * Note: default result is considered the most significant @@ -554,24 +556,26 @@ transformExpr(ParseState *pstate, Node *expr, ConstraintTestValue *domVal) * code worked before, but it seems a little bogus to me * --- tgl */ - typeids = lconsi(exprType(newc->defresult), typeids); + typeids = lconsi(exprType((Node *) newc->defresult), typeids); ptype = select_common_type(typeids, "CASE"); newc->casetype = ptype; /* Convert default result clause, if necessary */ - newc->defresult = coerce_to_common_type(newc->defresult, - ptype, - "CASE/ELSE"); + newc->defresult = (Expr *) + coerce_to_common_type((Node *) newc->defresult, + ptype, + "CASE/ELSE"); /* Convert when-clause results, if necessary */ foreach(args, newc->args) { CaseWhen *w = (CaseWhen *) lfirst(args); - w->result = coerce_to_common_type(w->result, - ptype, - "CASE/WHEN"); + w->result = (Expr *) + coerce_to_common_type((Node *) w->result, + ptype, + "CASE/WHEN"); } result = (Node *) newc; @@ -582,7 +586,7 @@ transformExpr(ParseState *pstate, Node *expr, ConstraintTestValue *domVal) { NullTest *n = (NullTest *) expr; - n->arg = transformExpr(pstate, n->arg, domVal); + n->arg = (Expr *) transformExpr(pstate, (Node *) n->arg, domVal); /* the argument can be any type, so don't coerce it */ result = expr; break; @@ -619,9 +623,9 @@ transformExpr(ParseState *pstate, Node *expr, ConstraintTestValue *domVal) clausename = NULL; /* keep compiler quiet */ } - b->arg = transformExpr(pstate, b->arg, domVal); + b->arg = (Expr *) transformExpr(pstate, (Node *) b->arg, domVal); - b->arg = coerce_to_boolean(b->arg, clausename); + b->arg = (Expr *) coerce_to_boolean((Node *) b->arg, clausename); result = expr; break; @@ -885,36 +889,39 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref) Oid exprType(Node *expr) { - Oid type = (Oid) InvalidOid; + Oid type; if (!expr) - return type; + return InvalidOid; switch (nodeTag(expr)) { case T_Var: type = ((Var *) expr)->vartype; break; - case T_Expr: - type = ((Expr *) expr)->typeOid; - break; case T_Const: type = ((Const *) expr)->consttype; break; - case T_ArrayRef: - type = ((ArrayRef *) expr)->refrestype; + case T_Param: + type = ((Param *) expr)->paramtype; break; case T_Aggref: type = ((Aggref *) expr)->aggtype; break; - case T_Param: - type = ((Param *) expr)->paramtype; + case T_ArrayRef: + type = ((ArrayRef *) expr)->refrestype; break; - case T_FieldSelect: - type = ((FieldSelect *) expr)->resulttype; + case T_FuncExpr: + type = ((FuncExpr *) expr)->funcresulttype; break; - case T_RelabelType: - type = ((RelabelType *) expr)->resulttype; + case T_OpExpr: + type = ((OpExpr *) expr)->opresulttype; + break; + case T_DistinctExpr: + type = ((DistinctExpr *) expr)->opresulttype; + break; + case T_BoolExpr: + type = BOOLOID; break; case T_SubLink: { @@ -938,11 +945,17 @@ exprType(Node *expr) } } break; + case T_FieldSelect: + type = ((FieldSelect *) expr)->resulttype; + break; + case T_RelabelType: + type = ((RelabelType *) expr)->resulttype; + break; case T_CaseExpr: type = ((CaseExpr *) expr)->casetype; break; case T_CaseWhen: - type = exprType(((CaseWhen *) expr)->result); + type = exprType((Node *) ((CaseWhen *) expr)->result); break; case T_NullTest: type = BOOLOID; @@ -951,7 +964,7 @@ exprType(Node *expr) type = BOOLOID; break; case T_ConstraintTest: - type = exprType(((ConstraintTest *) expr)->arg); + type = exprType((Node *) ((ConstraintTest *) expr)->arg); break; case T_ConstraintTestValue: type = ((ConstraintTestValue *) expr)->typeId; @@ -959,6 +972,7 @@ exprType(Node *expr) default: elog(ERROR, "exprType: Do not know how to get type for %d node", nodeTag(expr)); + type = InvalidOid; /* keep compiler quiet */ break; } return type; @@ -995,7 +1009,7 @@ exprTypmod(Node *expr) } } break; - case T_Expr: + case T_FuncExpr: { int32 coercedTypmod; @@ -1021,9 +1035,9 @@ exprTypmod(Node *expr) if (!cexpr->defresult) return -1; - if (exprType(cexpr->defresult) != casetype) + if (exprType((Node *) cexpr->defresult) != casetype) return -1; - typmod = exprTypmod(cexpr->defresult); + typmod = exprTypmod((Node *) cexpr->defresult); if (typmod < 0) return -1; /* no point in trying harder */ foreach(arg, cexpr->args) @@ -1031,16 +1045,16 @@ exprTypmod(Node *expr) CaseWhen *w = (CaseWhen *) lfirst(arg); Assert(IsA(w, CaseWhen)); - if (exprType(w->result) != casetype) + if (exprType((Node *) w->result) != casetype) return -1; - if (exprTypmod(w->result) != typmod) + if (exprTypmod((Node *) w->result) != typmod) return -1; } return typmod; } break; case T_ConstraintTest: - return exprTypmod(((ConstraintTest *) expr)->arg); + return exprTypmod((Node *) ((ConstraintTest *) expr)->arg); default: break; @@ -1059,7 +1073,7 @@ exprTypmod(Node *expr) bool exprIsLengthCoercion(Node *expr, int32 *coercedTypmod) { - Func *func; + FuncExpr *func; int nargs; Const *second_arg; @@ -1067,12 +1081,9 @@ exprIsLengthCoercion(Node *expr, int32 *coercedTypmod) *coercedTypmod = -1; /* default result on failure */ /* Is it a function-call at all? */ - if (expr == NULL || - !IsA(expr, Expr) || - ((Expr *) expr)->opType != FUNC_EXPR) + if (expr == NULL || !IsA(expr, FuncExpr)) return false; - func = (Func *) (((Expr *) expr)->oper); - Assert(IsA(func, Func)); + func = (FuncExpr *) expr; /* * If it didn't come from a coercion context, reject. @@ -1086,11 +1097,11 @@ exprIsLengthCoercion(Node *expr, int32 *coercedTypmod) * argument being an int4 constant, it can't have been created from a * length coercion (it must be a type coercion, instead). */ - nargs = length(((Expr *) expr)->args); + nargs = length(func->args); if (nargs < 2 || nargs > 3) return false; - second_arg = (Const *) lsecond(((Expr *) expr)->args); + second_arg = (Const *) lsecond(func->args); if (!IsA(second_arg, Const) || second_arg->consttype != INT4OID || second_arg->constisnull) |