summaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_expr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/parser/parse_expr.c')
-rw-r--r--src/backend/parser/parse_expr.c50
1 files changed, 27 insertions, 23 deletions
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index 0b738a87307..dab7161c042 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.62 1999/12/17 01:25:25 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.63 1999/12/24 06:43:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -353,7 +353,7 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
n->val.type = T_Null;
c->defresult = (Node *) n;
}
- c->defresult = transformExpr(pstate, (Node *) c->defresult, precedence);
+ c->defresult = transformExpr(pstate, c->defresult, precedence);
/* now check types across result clauses... */
c->casetype = exprType(c->defresult);
@@ -369,32 +369,30 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
if (wtype && (wtype != UNKNOWNOID)
&& (wtype != ptype))
{
- /* so far, only nulls so take anything... */
- if (!ptype)
+ if (!ptype || ptype == UNKNOWNOID)
{
+ /* so far, only nulls so take anything... */
ptype = wtype;
pcategory = TypeCategory(ptype);
}
-
- /*
- * both types in different categories? then not
- * much hope...
- */
else if ((TypeCategory(wtype) != pcategory)
|| ((TypeCategory(wtype) == USER_TYPE)
&& (TypeCategory(c->casetype) == USER_TYPE)))
{
+ /*
+ * both types in different categories?
+ * then not much hope...
+ */
elog(ERROR, "CASE/WHEN types '%s' and '%s' not matched",
typeidTypeName(c->casetype), typeidTypeName(wtype));
}
-
- /*
- * new one is preferred and can convert? then take
- * it...
- */
else if (IsPreferredType(pcategory, wtype)
&& can_coerce_type(1, &ptype, &wtype))
{
+ /*
+ * new one is preferred and can convert?
+ * then take it...
+ */
ptype = wtype;
pcategory = TypeCategory(ptype);
}
@@ -404,9 +402,8 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
/* Convert default result clause, if necessary */
if (c->casetype != ptype)
{
- if (!c->casetype)
+ if (!c->casetype || c->casetype == UNKNOWNOID)
{
-
/*
* default clause is NULL, so assign preferred
* type from WHEN clauses...
@@ -694,11 +691,12 @@ exprTypmod(Node *expr)
static Node *
parser_typecast(Value *expr, TypeName *typename, int32 atttypmod)
{
- Const *adt;
- Datum lcp;
+ Const *con;
Type tp;
+ Datum datum;
char *const_string = NULL;
bool string_palloced = false;
+ bool isNull = false;
switch (nodeTag(expr))
{
@@ -713,6 +711,9 @@ parser_typecast(Value *expr, TypeName *typename, int32 atttypmod)
string_palloced = true;
const_string = float8out(&expr->val.dval);
break;
+ case T_Null:
+ isNull = true;
+ break;
default:
elog(ERROR,
"parser_typecast: cannot cast this expression to type '%s'",
@@ -729,12 +730,15 @@ parser_typecast(Value *expr, TypeName *typename, int32 atttypmod)
else
tp = (Type) typenameType(typename->name);
- lcp = stringTypeDatum(tp, const_string, atttypmod);
+ if (isNull)
+ datum = (Datum) NULL;
+ else
+ datum = stringTypeDatum(tp, const_string, atttypmod);
- adt = makeConst(typeTypeId(tp),
+ con = makeConst(typeTypeId(tp),
typeLen(tp),
- (Datum) lcp,
- false,
+ datum,
+ isNull,
typeByVal(tp),
false, /* not a set */
true /* is cast */ );
@@ -742,5 +746,5 @@ parser_typecast(Value *expr, TypeName *typename, int32 atttypmod)
if (string_palloced)
pfree(const_string);
- return (Node *) adt;
+ return (Node *) con;
}