aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/nodes/equalfuncs.c9
-rw-r--r--src/backend/parser/parse_expr.c50
-rw-r--r--src/backend/parser/parse_node.c30
-rw-r--r--src/backend/utils/adt/ruleutils.c21
4 files changed, 67 insertions, 43 deletions
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index f70fe508ae5..cc23555c46f 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.53 1999/12/13 01:26:53 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.54 1999/12/24 06:43:32 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -144,6 +144,13 @@ _equalConst(Const *a, Const *b)
if (a->constbyval != b->constbyval)
return false;
/* XXX What about constisset and constiscast? */
+ /*
+ * We treat all NULL constants of the same type as equal.
+ * Someday this might need to change? But datumIsEqual
+ * doesn't work on nulls, so...
+ */
+ if (a->constisnull)
+ return true;
return (datumIsEqual(a->constvalue, b->constvalue,
a->consttype, a->constbyval, a->constlen));
}
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;
}
diff --git a/src/backend/parser/parse_node.c b/src/backend/parser/parse_node.c
index 2cab730412d..c660df38261 100644
--- a/src/backend/parser/parse_node.c
+++ b/src/backend/parser/parse_node.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.33 1999/11/22 17:56:21 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.34 1999/12/24 06:43:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -61,28 +61,27 @@ make_operand(char *opname,
Oid target_typeId)
{
Node *result;
- Type target_type;
+ Type target_type = typeidType(target_typeId);
if (tree != NULL)
{
- result = tree;
- target_type = typeidType(target_typeId);
- disallow_setop(opname, target_type, result);
-
+ disallow_setop(opname, target_type, tree);
/* must coerce? */
if (target_typeId != orig_typeId)
result = coerce_type(NULL, tree, orig_typeId, target_typeId, -1);
+ else
+ result = tree;
}
- /* otherwise, this is a NULL value */
else
{
+ /* otherwise, this is a NULL value */
Const *con = makeNode(Const);
con->consttype = target_typeId;
- con->constlen = 0;
- con->constvalue = (Datum) (struct varlena *) NULL;
+ con->constlen = typeLen(target_type);
+ con->constvalue = (Datum) NULL;
con->constisnull = true;
- con->constbyval = true;
+ con->constbyval = typeByVal(target_type);
con->constisset = false;
result = (Node *) con;
}
@@ -394,7 +393,8 @@ transformArraySubscripts(ParseState *pstate,
* of the "natural" type for the constant. For strings we produce
* a constant of type UNKNOWN ---- representation is the same as text,
* but this indicates to later type resolution that we're not sure that
- * it should be considered text.
+ * it should be considered text. Explicit "NULL" constants are also
+ * typed as UNKNOWN.
*/
Const *
make_const(Value *value)
@@ -444,7 +444,13 @@ make_const(Value *value)
elog(NOTICE, "make_const: unknown type %d\n", nodeTag(value));
/* return a null const */
- con = makeConst(0, 0, (Datum) NULL, true, false, false, false);
+ con = makeConst(UNKNOWNOID,
+ -1,
+ (Datum) NULL,
+ true,
+ false,
+ false,
+ false);
return con;
}
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 47fd957c994..00099791c09 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -3,7 +3,7 @@
* out of it's tuple
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.35 1999/12/13 01:27:01 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.36 1999/12/24 06:43:34 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
@@ -1606,12 +1606,6 @@ get_const_expr(Const *constval, deparse_context *context)
char *valptr;
bool isnull = FALSE;
- if (constval->constisnull)
- {
- appendStringInfo(buf, "NULL");
- return;
- }
-
typetup = SearchSysCacheTuple(TYPEOID,
ObjectIdGetDatum(constval->consttype),
0, 0, 0);
@@ -1620,6 +1614,19 @@ get_const_expr(Const *constval, deparse_context *context)
typeStruct = (Form_pg_type) GETSTRUCT(typetup);
+ if (constval->constisnull)
+ {
+ /*
+ * Always label the type of a NULL constant. This not only
+ * prevents misdecisions about the type, but it ensures that
+ * our output is a valid b_expr.
+ */
+ extval = pstrdup(NameStr(typeStruct->typname));
+ appendStringInfo(buf, "NULL::%s", quote_identifier(extval));
+ pfree(extval);
+ return;
+ }
+
fmgr_info(typeStruct->typoutput, &finfo_output);
extval = (char *) (*fmgr_faddr(&finfo_output)) (constval->constvalue,
&isnull, -1);