*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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));
}
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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);
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);
}
/* 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...
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))
{
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'",
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 */ );
if (string_palloced)
pfree(const_string);
- return (Node *) adt;
+ return (Node *) con;
}
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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;
}
* 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)
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;
}
* 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.
*
char *valptr;
bool isnull = FALSE;
- if (constval->constisnull)
- {
- appendStringInfo(buf, "NULL");
- return;
- }
-
typetup = SearchSysCacheTuple(TYPEOID,
ObjectIdGetDatum(constval->consttype),
0, 0, 0);
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);