]> granicus.if.org Git - postgresql/commitdiff
Oops, DEFAULT processing wasn't doing type compatibility checking
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 4 Oct 1999 02:12:26 +0000 (02:12 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 4 Oct 1999 02:12:26 +0000 (02:12 +0000)
quite the same way that transformInsertStatement does, so that an expression
could be accepted by CREATE TABLE and then fail when used.  Also, put back
check that CONSTRAINT expressions must yield boolean...

src/backend/catalog/heap.c

index 5cb9da1cae1b633f840a665c36ff3810bd901f70..e5eec36219f80d3fada86a8dd9e5fa4c8bb00955 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.100 1999/10/03 23:55:26 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.101 1999/10/04 02:12:26 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
 #include "catalog/pg_ipl.h"
 #include "catalog/pg_proc.h"
 #include "catalog/pg_relcheck.h"
+#include "catalog/pg_type.h"
 #include "commands/trigger.h"
 #include "optimizer/clauses.h"
 #include "optimizer/planmain.h"
 #include "optimizer/tlist.h"
 #include "optimizer/var.h"
 #include "parser/parse_clause.h"
-#include "parser/parse_coerce.h"
 #include "parser/parse_expr.h"
 #include "parser/parse_relation.h"
+#include "parser/parse_target.h"
 #include "rewrite/rewriteRemove.h"
 #include "storage/smgr.h"
 #include "tcop/tcopprot.h"
@@ -1668,9 +1669,7 @@ static void
 StoreAttrDefault(Relation rel, AttrNumber attnum, char *adbin,
                                 bool updatePgAttribute)
 {
-       Form_pg_attribute atp = rel->rd_att->attrs[attnum - 1];
        Node       *expr;
-       Oid                     type;
        RangeTblEntry *rte;
        char       *adsrc;
        Relation        adrel;
@@ -1683,20 +1682,10 @@ StoreAttrDefault(Relation rel, AttrNumber attnum, char *adbin,
        HeapTuple       atttup;
        Form_pg_attribute attStruct;
 
+       /*
+        * Need to construct source equivalent of given node-string.
+        */
        expr = stringToNode(adbin);
-       type = exprType(expr);
-
-       if (type != atp->atttypid)
-       {
-               /*
-                * Check that it will be possible to coerce the expression
-                * to the column's type.  We store the expression without
-                * coercion, however, to avoid premature coercion in cases like
-                * CREATE TABLE tbl (fld datetime DEFAULT 'now');
-                */
-               coerce_type(NULL, expr, type, atp->atttypid, atp->atttypmod);
-       }
-
        /*
         * deparse_expression needs a RangeTblEntry list, so make one
         */
@@ -1904,6 +1893,7 @@ AddRelationRawConstraints(Relation rel,
        {
                RawColumnDefault *colDef = (RawColumnDefault *) lfirst(listptr);
                Node       *expr;
+               Oid                     type_id;
 
                Assert(colDef->raw_default != NULL);
                /*
@@ -1915,6 +1905,34 @@ AddRelationRawConstraints(Relation rel,
                 */
                if (contain_var_clause(expr))
                        elog(ERROR, "Cannot use attribute(s) in DEFAULT clause");
+               /*
+                * Check that it will be possible to coerce the expression
+                * to the column's type.  We store the expression without
+                * coercion, however, to avoid premature coercion in cases like
+                *
+                * CREATE TABLE tbl (fld datetime DEFAULT 'now');
+                *
+                * NB: this should match the code in updateTargetListEntry()
+                * that will actually do the coercion, to ensure we don't accept
+                * an unusable default expression.
+                */
+               type_id = exprType(expr);
+               if (type_id != InvalidOid)
+               {
+                       Form_pg_attribute atp = rel->rd_att->attrs[colDef->attnum - 1];
+
+                       if (type_id != atp->atttypid)
+                       {
+                               if (CoerceTargetExpr(NULL, expr,
+                                                                        type_id, atp->atttypid) == NULL)
+                                       elog(ERROR, "Attribute '%s' is of type '%s'"
+                                                " but default expression is of type '%s'"
+                                                "\n\tYou will need to rewrite or cast the expression",
+                                                atp->attname.data,
+                                                typeidTypeName(atp->atttypid),
+                                                typeidTypeName(type_id));
+                       }
+               }
                /*
                 * Might as well try to reduce any constant expressions.
                 */
@@ -1981,6 +1999,12 @@ AddRelationRawConstraints(Relation rel,
                 * Transform raw parsetree to executable expression.
                 */
                expr = transformExpr(pstate, cdef->raw_expr, EXPR_COLUMN_FIRST);
+               /*
+                * Make sure it yields a boolean result.
+                */
+               if (exprType(expr) != BOOLOID)
+                       elog(ERROR, "CHECK '%s' does not yield boolean result",
+                                ccname);
                /*
                 * Make sure no outside relations are referred to.
                 */