diff options
Diffstat (limited to 'src/backend/parser/parse_expr.c')
-rw-r--r-- | src/backend/parser/parse_expr.c | 120 |
1 files changed, 81 insertions, 39 deletions
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c index a196779f44c..5fda57f5f92 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.97 2001/06/04 23:27:23 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.98 2001/06/19 22:39:11 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -167,32 +167,6 @@ transformExpr(ParseState *pstate, Node *expr, int precedence) result = (Node *) make_op(a->opname, lexpr, rexpr); } break; - case ISNULL: - { - Node *lexpr = transformExpr(pstate, - a->lexpr, - precedence); - - result = ParseFuncOrColumn(pstate, - "nullvalue", - makeList1(lexpr), - false, false, - precedence); - } - break; - case NOTNULL: - { - Node *lexpr = transformExpr(pstate, - a->lexpr, - precedence); - - result = ParseFuncOrColumn(pstate, - "nonnullvalue", - makeList1(lexpr), - false, false, - precedence); - } - break; case AND: { Node *lexpr = transformExpr(pstate, @@ -203,13 +177,15 @@ transformExpr(ParseState *pstate, Node *expr, int precedence) precedence); Expr *expr = makeNode(Expr); - if (exprType(lexpr) != BOOLOID) + if (! coerce_to_boolean(pstate, &lexpr)) elog(ERROR, "left-hand side of AND is type '%s', not '%s'", - typeidTypeName(exprType(lexpr)), typeidTypeName(BOOLOID)); + typeidTypeName(exprType(lexpr)), + typeidTypeName(BOOLOID)); - if (exprType(rexpr) != BOOLOID) + if (! coerce_to_boolean(pstate, &rexpr)) elog(ERROR, "right-hand side of AND is type '%s', not '%s'", - typeidTypeName(exprType(rexpr)), typeidTypeName(BOOLOID)); + typeidTypeName(exprType(rexpr)), + typeidTypeName(BOOLOID)); expr->typeOid = BOOLOID; expr->opType = AND_EXPR; @@ -227,12 +203,16 @@ transformExpr(ParseState *pstate, Node *expr, int precedence) precedence); Expr *expr = makeNode(Expr); - if (exprType(lexpr) != BOOLOID) + if (! coerce_to_boolean(pstate, &lexpr)) elog(ERROR, "left-hand side of OR is type '%s', not '%s'", - typeidTypeName(exprType(lexpr)), typeidTypeName(BOOLOID)); - if (exprType(rexpr) != BOOLOID) + typeidTypeName(exprType(lexpr)), + typeidTypeName(BOOLOID)); + + if (! coerce_to_boolean(pstate, &rexpr)) elog(ERROR, "right-hand side of OR is type '%s', not '%s'", - typeidTypeName(exprType(rexpr)), typeidTypeName(BOOLOID)); + typeidTypeName(exprType(rexpr)), + typeidTypeName(BOOLOID)); + expr->typeOid = BOOLOID; expr->opType = OR_EXPR; expr->args = makeList2(lexpr, rexpr); @@ -246,9 +226,11 @@ transformExpr(ParseState *pstate, Node *expr, int precedence) precedence); Expr *expr = makeNode(Expr); - if (exprType(rexpr) != BOOLOID) + if (! coerce_to_boolean(pstate, &rexpr)) elog(ERROR, "argument to NOT is type '%s', not '%s'", - typeidTypeName(exprType(rexpr)), typeidTypeName(BOOLOID)); + typeidTypeName(exprType(rexpr)), + typeidTypeName(BOOLOID)); + expr->typeOid = BOOLOID; expr->opType = NOT_EXPR; expr->args = makeList1(rexpr); @@ -491,7 +473,8 @@ transformExpr(ParseState *pstate, Node *expr, int precedence) CaseWhen *w = (CaseWhen *) expr; w->expr = transformExpr(pstate, w->expr, precedence); - if (exprType(w->expr) != BOOLOID) + + if (! coerce_to_boolean(pstate, &w->expr)) elog(ERROR, "WHEN clause must have a boolean result"); /* @@ -510,6 +493,59 @@ transformExpr(ParseState *pstate, Node *expr, int precedence) break; } + case T_NullTest: + { + NullTest *n = (NullTest *) expr; + + n->arg = transformExpr(pstate, n->arg, precedence); + /* the argument can be any type, so don't coerce it */ + result = expr; + break; + } + + case T_BooleanTest: + { + BooleanTest *b = (BooleanTest *) expr; + + b->arg = transformExpr(pstate, b->arg, precedence); + + if (! coerce_to_boolean(pstate, &b->arg)) + { + const char *clausename; + + switch (b->booltesttype) + { + case IS_TRUE: + clausename = "IS TRUE"; + break; + case IS_NOT_TRUE: + clausename = "IS NOT TRUE"; + break; + case IS_FALSE: + clausename = "IS FALSE"; + break; + case IS_NOT_FALSE: + clausename = "IS NOT FALSE"; + break; + case IS_UNKNOWN: + clausename = "IS UNKNOWN"; + break; + case IS_NOT_UNKNOWN: + clausename = "IS NOT UNKNOWN"; + break; + default: + elog(ERROR, "transformExpr: unexpected booltesttype %d", + (int) b->booltesttype); + clausename = NULL; /* keep compiler quiet */ + } + + elog(ERROR, "Argument of %s must be boolean", + clausename); + } + result = expr; + break; + } + /* * Quietly accept node types that may be presented when we are * called on an already-transformed tree. @@ -669,8 +705,14 @@ exprType(Node *expr) case T_CaseWhen: type = exprType(((CaseWhen *) expr)->result); break; + case T_NullTest: + type = BOOLOID; + break; + case T_BooleanTest: + type = BOOLOID; + break; case T_Ident: - /* is this right? */ + /* XXX is this right? */ type = UNKNOWNOID; break; default: |