mirror of
https://github.com/postgres/postgres.git
synced 2025-07-15 19:21:59 +03:00
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.
This commit is contained in:
@ -6,7 +6,7 @@
|
||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.254 2002/11/15 02:50:07 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.255 2002/12/12 15:49:33 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -479,14 +479,14 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt,
|
||||
{
|
||||
TargetEntry *tle = (TargetEntry *) lfirst(tl);
|
||||
Resdom *resnode = tle->resdom;
|
||||
Node *expr;
|
||||
Expr *expr;
|
||||
|
||||
if (resnode->resjunk)
|
||||
continue;
|
||||
if (tle->expr && IsA(tle->expr, Const))
|
||||
expr = tle->expr;
|
||||
else
|
||||
expr = (Node *) makeVar(rtr->rtindex,
|
||||
expr = (Expr *) makeVar(rtr->rtindex,
|
||||
resnode->resno,
|
||||
resnode->restype,
|
||||
resnode->restypmod,
|
||||
@ -1807,14 +1807,14 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
|
||||
Resdom *leftResdom = ((TargetEntry *) lfirst(lefttl))->resdom;
|
||||
char *colName = pstrdup(leftResdom->resname);
|
||||
Resdom *resdom;
|
||||
Node *expr;
|
||||
Expr *expr;
|
||||
|
||||
resdom = makeResdom((AttrNumber) pstate->p_last_resno++,
|
||||
colType,
|
||||
-1,
|
||||
colName,
|
||||
false);
|
||||
expr = (Node *) makeVar(1,
|
||||
expr = (Expr *) makeVar(1,
|
||||
leftResdom->resno,
|
||||
colType,
|
||||
-1,
|
||||
@ -2424,7 +2424,7 @@ transformExecuteStmt(ParseState *pstate, ExecuteStmt *stmt)
|
||||
format_type_be(given_type_id),
|
||||
format_type_be(expected_type_id));
|
||||
|
||||
fix_opids(expr);
|
||||
fix_opfuncids(expr);
|
||||
|
||||
lfirst(l) = expr;
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.386 2002/12/06 05:00:22 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.387 2002/12/12 15:49:36 tgl Exp $
|
||||
*
|
||||
* HISTORY
|
||||
* AUTHOR DATE MAJOR EVENT
|
||||
@ -5755,70 +5755,70 @@ a_expr: c_expr { $$ = $1; }
|
||||
| a_expr ISNULL
|
||||
{
|
||||
NullTest *n = makeNode(NullTest);
|
||||
n->arg = $1;
|
||||
n->arg = (Expr *) $1;
|
||||
n->nulltesttype = IS_NULL;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| a_expr IS NULL_P
|
||||
{
|
||||
NullTest *n = makeNode(NullTest);
|
||||
n->arg = $1;
|
||||
n->arg = (Expr *) $1;
|
||||
n->nulltesttype = IS_NULL;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| a_expr NOTNULL
|
||||
{
|
||||
NullTest *n = makeNode(NullTest);
|
||||
n->arg = $1;
|
||||
n->arg = (Expr *) $1;
|
||||
n->nulltesttype = IS_NOT_NULL;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| a_expr IS NOT NULL_P
|
||||
{
|
||||
NullTest *n = makeNode(NullTest);
|
||||
n->arg = $1;
|
||||
n->arg = (Expr *) $1;
|
||||
n->nulltesttype = IS_NOT_NULL;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| a_expr IS TRUE_P
|
||||
{
|
||||
BooleanTest *b = makeNode(BooleanTest);
|
||||
b->arg = $1;
|
||||
b->arg = (Expr *) $1;
|
||||
b->booltesttype = IS_TRUE;
|
||||
$$ = (Node *)b;
|
||||
}
|
||||
| a_expr IS NOT TRUE_P
|
||||
{
|
||||
BooleanTest *b = makeNode(BooleanTest);
|
||||
b->arg = $1;
|
||||
b->arg = (Expr *) $1;
|
||||
b->booltesttype = IS_NOT_TRUE;
|
||||
$$ = (Node *)b;
|
||||
}
|
||||
| a_expr IS FALSE_P
|
||||
{
|
||||
BooleanTest *b = makeNode(BooleanTest);
|
||||
b->arg = $1;
|
||||
b->arg = (Expr *) $1;
|
||||
b->booltesttype = IS_FALSE;
|
||||
$$ = (Node *)b;
|
||||
}
|
||||
| a_expr IS NOT FALSE_P
|
||||
{
|
||||
BooleanTest *b = makeNode(BooleanTest);
|
||||
b->arg = $1;
|
||||
b->arg = (Expr *) $1;
|
||||
b->booltesttype = IS_NOT_FALSE;
|
||||
$$ = (Node *)b;
|
||||
}
|
||||
| a_expr IS UNKNOWN
|
||||
{
|
||||
BooleanTest *b = makeNode(BooleanTest);
|
||||
b->arg = $1;
|
||||
b->arg = (Expr *) $1;
|
||||
b->booltesttype = IS_UNKNOWN;
|
||||
$$ = (Node *)b;
|
||||
}
|
||||
| a_expr IS NOT UNKNOWN
|
||||
{
|
||||
BooleanTest *b = makeNode(BooleanTest);
|
||||
b->arg = $1;
|
||||
b->arg = (Expr *) $1;
|
||||
b->booltesttype = IS_NOT_UNKNOWN;
|
||||
$$ = (Node *)b;
|
||||
}
|
||||
@ -6640,9 +6640,9 @@ in_expr: select_with_parens
|
||||
case_expr: CASE case_arg when_clause_list case_default END_TRANS
|
||||
{
|
||||
CaseExpr *c = makeNode(CaseExpr);
|
||||
c->arg = $2;
|
||||
c->arg = (Expr *) $2;
|
||||
c->args = $3;
|
||||
c->defresult = $4;
|
||||
c->defresult = (Expr *) $4;
|
||||
$$ = (Node *)c;
|
||||
}
|
||||
| NULLIF '(' a_expr ',' a_expr ')'
|
||||
@ -6650,10 +6650,10 @@ case_expr: CASE case_arg when_clause_list case_default END_TRANS
|
||||
CaseExpr *c = makeNode(CaseExpr);
|
||||
CaseWhen *w = makeNode(CaseWhen);
|
||||
|
||||
w->expr = (Node *) makeSimpleA_Expr(OP, "=", $3, $5);
|
||||
w->expr = (Expr *) makeSimpleA_Expr(OP, "=", $3, $5);
|
||||
/* w->result is left NULL */
|
||||
c->args = makeList1(w);
|
||||
c->defresult = $3;
|
||||
c->defresult = (Expr *) $3;
|
||||
$$ = (Node *)c;
|
||||
}
|
||||
| COALESCE '(' expr_list ')'
|
||||
@ -6666,7 +6666,7 @@ case_expr: CASE case_arg when_clause_list case_default END_TRANS
|
||||
NullTest *n = makeNode(NullTest);
|
||||
n->arg = lfirst(l);
|
||||
n->nulltesttype = IS_NOT_NULL;
|
||||
w->expr = (Node *) n;
|
||||
w->expr = (Expr *) n;
|
||||
w->result = lfirst(l);
|
||||
c->args = lappend(c->args, w);
|
||||
}
|
||||
@ -6684,8 +6684,8 @@ when_clause:
|
||||
WHEN a_expr THEN a_expr
|
||||
{
|
||||
CaseWhen *w = makeNode(CaseWhen);
|
||||
w->expr = $2;
|
||||
w->result = $4;
|
||||
w->expr = (Expr *) $2;
|
||||
w->result = (Expr *) $4;
|
||||
$$ = (Node *)w;
|
||||
}
|
||||
;
|
||||
@ -7594,20 +7594,17 @@ static Node *
|
||||
makeRowNullTest(NullTestType test, List *args)
|
||||
{
|
||||
Node *expr = NULL;
|
||||
Node *arg;
|
||||
NullTest *n;
|
||||
|
||||
if (lnext(args) != NIL)
|
||||
expr = makeRowNullTest(test, lnext(args));
|
||||
|
||||
arg = lfirst(args);
|
||||
|
||||
n = makeNode(NullTest);
|
||||
n->arg = arg;
|
||||
n->arg = (Expr *) lfirst(args);
|
||||
n->nulltesttype = test;
|
||||
|
||||
if (expr == NULL)
|
||||
expr = (Node *)n;
|
||||
expr = (Node *) n;
|
||||
else if (test == IS_NOT_NULL)
|
||||
expr = (Node *) makeA_Expr(OR, NIL, expr, (Node *)n);
|
||||
else
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.100 2002/11/29 21:39:11 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.101 2002/12/12 15:49:38 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -502,17 +502,6 @@ transformRangeFunction(ParseState *pstate, RangeFunction *r)
|
||||
elog(ERROR, "cannot use aggregate function in FROM function expression");
|
||||
}
|
||||
|
||||
/*
|
||||
* Insist we have a bare function call (explain.c is the only place
|
||||
* that depends on this, I think). If this fails, it's probably
|
||||
* because transformExpr interpreted the function notation as a type
|
||||
* coercion.
|
||||
*/
|
||||
if (!funcexpr ||
|
||||
!IsA(funcexpr, Expr) ||
|
||||
((Expr *) funcexpr)->opType != FUNC_EXPR)
|
||||
elog(ERROR, "Coercion function not allowed in FROM clause");
|
||||
|
||||
/*
|
||||
* OK, build an RTE for the function.
|
||||
*/
|
||||
@ -876,7 +865,7 @@ buildMergedJoinVar(JoinType jointype, Var *l_colvar, Var *r_colvar)
|
||||
outcoltype,
|
||||
COERCION_IMPLICIT, COERCE_IMPLICIT_CAST);
|
||||
else if (l_colvar->vartypmod != outcoltypmod)
|
||||
l_node = (Node *) makeRelabelType((Node *) l_colvar,
|
||||
l_node = (Node *) makeRelabelType((Expr *) l_colvar,
|
||||
outcoltype, outcoltypmod,
|
||||
COERCE_IMPLICIT_CAST);
|
||||
else
|
||||
@ -887,7 +876,7 @@ buildMergedJoinVar(JoinType jointype, Var *l_colvar, Var *r_colvar)
|
||||
outcoltype,
|
||||
COERCION_IMPLICIT, COERCE_IMPLICIT_CAST);
|
||||
else if (r_colvar->vartypmod != outcoltypmod)
|
||||
r_node = (Node *) makeRelabelType((Node *) r_colvar,
|
||||
r_node = (Node *) makeRelabelType((Expr *) r_colvar,
|
||||
outcoltype, outcoltypmod,
|
||||
COERCE_IMPLICIT_CAST);
|
||||
else
|
||||
@ -928,13 +917,13 @@ buildMergedJoinVar(JoinType jointype, Var *l_colvar, Var *r_colvar)
|
||||
CaseWhen *w = makeNode(CaseWhen);
|
||||
NullTest *n = makeNode(NullTest);
|
||||
|
||||
n->arg = l_node;
|
||||
n->arg = (Expr *) l_node;
|
||||
n->nulltesttype = IS_NOT_NULL;
|
||||
w->expr = (Node *) n;
|
||||
w->result = l_node;
|
||||
w->expr = (Expr *) n;
|
||||
w->result = (Expr *) l_node;
|
||||
c->casetype = outcoltype;
|
||||
c->args = makeList1(w);
|
||||
c->defresult = r_node;
|
||||
c->defresult = (Expr *) r_node;
|
||||
res_node = (Node *) c;
|
||||
break;
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.89 2002/11/30 18:28:49 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.90 2002/12/12 15:49:38 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -88,7 +88,8 @@ coerce_to_target_type(Node *expr, Oid exprtype,
|
||||
ccontext, cformat);
|
||||
/* Need a RelabelType if no typmod coercion is performed */
|
||||
if (targettypmod < 0)
|
||||
expr = (Node *) makeRelabelType(expr, targettype, -1,
|
||||
expr = (Node *) makeRelabelType((Expr *) expr,
|
||||
targettype, -1,
|
||||
cformat);
|
||||
}
|
||||
else
|
||||
@ -190,7 +191,8 @@ coerce_type(Node *node, Oid inputTypeId, Oid targetTypeId,
|
||||
cformat);
|
||||
/* We might now need a RelabelType. */
|
||||
if (exprType(result) != targetTypeId)
|
||||
result = (Node *) makeRelabelType(result, targetTypeId, -1,
|
||||
result = (Node *) makeRelabelType((Expr *) result,
|
||||
targetTypeId, -1,
|
||||
cformat);
|
||||
}
|
||||
|
||||
@ -227,7 +229,8 @@ coerce_type(Node *node, Oid inputTypeId, Oid targetTypeId,
|
||||
{
|
||||
result = coerce_type_constraints(result, targetTypeId,
|
||||
cformat);
|
||||
result = (Node *) makeRelabelType(result, targetTypeId, -1,
|
||||
result = (Node *) makeRelabelType((Expr *) result,
|
||||
targetTypeId, -1,
|
||||
cformat);
|
||||
}
|
||||
|
||||
@ -266,7 +269,8 @@ coerce_type(Node *node, Oid inputTypeId, Oid targetTypeId,
|
||||
* typmod, which is likely but not certain (wrong if target is
|
||||
* a domain, in any case).
|
||||
*/
|
||||
result = (Node *) makeRelabelType(result, targetTypeId, -1,
|
||||
result = (Node *) makeRelabelType((Expr *) result,
|
||||
targetTypeId, -1,
|
||||
cformat);
|
||||
}
|
||||
}
|
||||
@ -277,7 +281,8 @@ coerce_type(Node *node, Oid inputTypeId, Oid targetTypeId,
|
||||
* except relabel the type. This is binary compatibility for
|
||||
* complex types.
|
||||
*/
|
||||
result = (Node *) makeRelabelType(node, targetTypeId, -1,
|
||||
result = (Node *) makeRelabelType((Expr *) node,
|
||||
targetTypeId, -1,
|
||||
cformat);
|
||||
}
|
||||
else
|
||||
@ -449,7 +454,7 @@ coerce_type_constraints(Node *arg, Oid typeId, CoercionForm cformat)
|
||||
elog(ERROR, "coerce_type_constraints: domain %s constraint %s has NULL conbin",
|
||||
NameStr(typTup->typname), NameStr(c->conname));
|
||||
|
||||
r->arg = arg;
|
||||
r->arg = (Expr *) arg;
|
||||
r->testtype = CONSTR_TEST_CHECK;
|
||||
r->name = NameStr(c->conname);
|
||||
r->domname = NameStr(typTup->typname);
|
||||
@ -492,7 +497,7 @@ coerce_type_constraints(Node *arg, Oid typeId, CoercionForm cformat)
|
||||
{
|
||||
ConstraintTest *r = makeNode(ConstraintTest);
|
||||
|
||||
r->arg = arg;
|
||||
r->arg = (Expr *) arg;
|
||||
r->testtype = CONSTR_TEST_NOTNULL;
|
||||
r->name = "NOT NULL";
|
||||
r->domname = notNull;
|
||||
@ -1140,21 +1145,14 @@ find_typmod_coercion_function(Oid typeId, int *nargs)
|
||||
static Node *
|
||||
build_func_call(Oid funcid, Oid rettype, List *args, CoercionForm fformat)
|
||||
{
|
||||
Func *funcnode;
|
||||
Expr *expr;
|
||||
FuncExpr *funcexpr;
|
||||
|
||||
funcnode = makeNode(Func);
|
||||
funcnode->funcid = funcid;
|
||||
funcnode->funcresulttype = rettype;
|
||||
funcnode->funcretset = false; /* only possible case here */
|
||||
funcnode->funcformat = fformat;
|
||||
funcnode->func_fcache = NULL;
|
||||
funcexpr = makeNode(FuncExpr);
|
||||
funcexpr->funcid = funcid;
|
||||
funcexpr->funcresulttype = rettype;
|
||||
funcexpr->funcretset = false; /* only possible case here */
|
||||
funcexpr->funcformat = fformat;
|
||||
funcexpr->args = args;
|
||||
|
||||
expr = makeNode(Expr);
|
||||
expr->typeOid = rettype;
|
||||
expr->opType = FUNC_EXPR;
|
||||
expr->oper = (Node *) funcnode;
|
||||
expr->args = args;
|
||||
|
||||
return (Node *) expr;
|
||||
return (Node *) funcexpr;
|
||||
}
|
||||
|
@ -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;
|
||||
break;
|
||||
case T_Aggref:
|
||||
type = ((Aggref *) expr)->aggtype;
|
||||
break;
|
||||
case T_Param:
|
||||
type = ((Param *) expr)->paramtype;
|
||||
break;
|
||||
case T_FieldSelect:
|
||||
type = ((FieldSelect *) expr)->resulttype;
|
||||
case T_Aggref:
|
||||
type = ((Aggref *) expr)->aggtype;
|
||||
break;
|
||||
case T_RelabelType:
|
||||
type = ((RelabelType *) expr)->resulttype;
|
||||
case T_ArrayRef:
|
||||
type = ((ArrayRef *) expr)->refrestype;
|
||||
break;
|
||||
case T_FuncExpr:
|
||||
type = ((FuncExpr *) expr)->funcresulttype;
|
||||
break;
|
||||
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)
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.142 2002/11/13 00:39:47 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.143 2002/12/12 15:49:39 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -315,21 +315,15 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
|
||||
/* build the appropriate output structure */
|
||||
if (fdresult == FUNCDETAIL_NORMAL)
|
||||
{
|
||||
Expr *expr = makeNode(Expr);
|
||||
Func *funcnode = makeNode(Func);
|
||||
FuncExpr *funcexpr = makeNode(FuncExpr);
|
||||
|
||||
funcnode->funcid = funcid;
|
||||
funcnode->funcresulttype = rettype;
|
||||
funcnode->funcretset = retset;
|
||||
funcnode->funcformat = COERCE_EXPLICIT_CALL;
|
||||
funcnode->func_fcache = NULL;
|
||||
funcexpr->funcid = funcid;
|
||||
funcexpr->funcresulttype = rettype;
|
||||
funcexpr->funcretset = retset;
|
||||
funcexpr->funcformat = COERCE_EXPLICIT_CALL;
|
||||
funcexpr->args = fargs;
|
||||
|
||||
expr->typeOid = rettype;
|
||||
expr->opType = FUNC_EXPR;
|
||||
expr->oper = (Node *) funcnode;
|
||||
expr->args = fargs;
|
||||
|
||||
retval = (Node *) expr;
|
||||
retval = (Node *) funcexpr;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1182,7 +1176,7 @@ setup_field_select(Node *input, char *attname, Oid relid)
|
||||
elog(ERROR, "Relation \"%s\" has no column \"%s\"",
|
||||
get_rel_name(relid), attname);
|
||||
|
||||
fselect->arg = input;
|
||||
fselect->arg = (Expr *) input;
|
||||
fselect->fieldnum = attno;
|
||||
fselect->resulttype = get_atttype(relid, attno);
|
||||
fselect->resulttypmod = get_atttypmod(relid, attno);
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.74 2002/11/25 21:29:41 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.75 2002/12/12 15:49:39 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -89,10 +89,9 @@ make_op(List *opname, Node *ltree, Node *rtree)
|
||||
rtypeId;
|
||||
Operator tup;
|
||||
Form_pg_operator opform;
|
||||
Oper *newop;
|
||||
Node *left,
|
||||
*right;
|
||||
Expr *result;
|
||||
OpExpr *result;
|
||||
|
||||
ltypeId = (ltree == NULL) ? UNKNOWNOID : exprType(ltree);
|
||||
rtypeId = (rtree == NULL) ? UNKNOWNOID : exprType(rtree);
|
||||
@ -124,15 +123,11 @@ make_op(List *opname, Node *ltree, Node *rtree)
|
||||
right = make_operand(rtree, rtypeId, opform->oprright);
|
||||
}
|
||||
|
||||
newop = makeOper(oprid(tup), /* opno */
|
||||
InvalidOid, /* opid */
|
||||
opform->oprresult, /* opresulttype */
|
||||
get_func_retset(opform->oprcode)); /* opretset */
|
||||
|
||||
result = makeNode(Expr);
|
||||
result->typeOid = opform->oprresult;
|
||||
result->opType = OP_EXPR;
|
||||
result->oper = (Node *) newop;
|
||||
result = makeNode(OpExpr);
|
||||
result->opno = oprid(tup);
|
||||
result->opfuncid = InvalidOid;
|
||||
result->opresulttype = opform->oprresult;
|
||||
result->opretset = get_func_retset(opform->oprcode);
|
||||
|
||||
if (!left)
|
||||
result->args = makeList1(right);
|
||||
@ -143,7 +138,7 @@ make_op(List *opname, Node *ltree, Node *rtree)
|
||||
|
||||
ReleaseSysCache(tup);
|
||||
|
||||
return result;
|
||||
return (Expr *) result;
|
||||
} /* make_op() */
|
||||
|
||||
|
||||
@ -343,8 +338,8 @@ transformArraySubscripts(ParseState *pstate,
|
||||
aref->refelemalign = type_struct_element->typalign;
|
||||
aref->refupperindexpr = upperIndexpr;
|
||||
aref->reflowerindexpr = lowerIndexpr;
|
||||
aref->refexpr = arrayBase;
|
||||
aref->refassgnexpr = assignFrom;
|
||||
aref->refexpr = (Expr *) arrayBase;
|
||||
aref->refassgnexpr = (Expr *) assignFrom;
|
||||
|
||||
ReleaseSysCache(type_tuple_array);
|
||||
ReleaseSysCache(type_tuple_element);
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.79 2002/09/04 20:31:24 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.80 2002/12/12 15:49:39 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -1452,7 +1452,7 @@ expandRelAttrs(ParseState *pstate, RangeTblEntry *rte)
|
||||
exprTypmod(varnode),
|
||||
label,
|
||||
false);
|
||||
te->expr = varnode;
|
||||
te->expr = (Expr *) varnode;
|
||||
te_list = lappend(te_list, te);
|
||||
|
||||
names = lnext(names);
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.92 2002/11/15 02:50:09 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.93 2002/12/12 15:49:39 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -79,7 +79,7 @@ transformTargetEntry(ParseState *pstate,
|
||||
colname,
|
||||
resjunk);
|
||||
|
||||
return makeTargetEntry(resnode, expr);
|
||||
return makeTargetEntry(resnode, (Expr *) expr);
|
||||
}
|
||||
|
||||
|
||||
@ -225,7 +225,7 @@ updateTargetListEntry(ParseState *pstate,
|
||||
int attrno,
|
||||
List *indirection)
|
||||
{
|
||||
Oid type_id = exprType(tle->expr); /* type of value provided */
|
||||
Oid type_id = exprType((Node *) tle->expr); /* type of value provided */
|
||||
Oid attrtype; /* type of target column */
|
||||
int32 attrtypmod;
|
||||
Resdom *resnode = tle->resdom;
|
||||
@ -277,8 +277,8 @@ updateTargetListEntry(ParseState *pstate,
|
||||
attrtypmod,
|
||||
indirection,
|
||||
pstate->p_is_insert,
|
||||
tle->expr);
|
||||
tle->expr = (Node *) aref;
|
||||
(Node *) tle->expr);
|
||||
tle->expr = (Expr *) aref;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -289,10 +289,11 @@ updateTargetListEntry(ParseState *pstate,
|
||||
*/
|
||||
if (type_id != InvalidOid)
|
||||
{
|
||||
tle->expr = coerce_to_target_type(tle->expr, type_id,
|
||||
attrtype, attrtypmod,
|
||||
COERCION_ASSIGNMENT,
|
||||
COERCE_IMPLICIT_CAST);
|
||||
tle->expr = (Expr *)
|
||||
coerce_to_target_type((Node *) tle->expr, type_id,
|
||||
attrtype, attrtypmod,
|
||||
COERCION_ASSIGNMENT,
|
||||
COERCE_IMPLICIT_CAST);
|
||||
if (tle->expr == NULL)
|
||||
elog(ERROR, "column \"%s\" is of type %s"
|
||||
" but expression is of type %s"
|
||||
@ -501,7 +502,7 @@ FigureColnameInternal(Node *node, char **name)
|
||||
}
|
||||
break;
|
||||
case T_CaseExpr:
|
||||
strength = FigureColnameInternal(((CaseExpr *) node)->defresult,
|
||||
strength = FigureColnameInternal((Node *) ((CaseExpr *) node)->defresult,
|
||||
name);
|
||||
if (strength <= 1)
|
||||
{
|
||||
|
Reference in New Issue
Block a user