7
7
*
8
8
*
9
9
* IDENTIFICATION
10
- * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.100 1999/10/03 23:55 :26 tgl Exp $
10
+ * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.101 1999/10/04 02:12 :26 tgl Exp $
11
11
*
12
12
*
13
13
* INTERFACE ROUTINES
43
43
#include "catalog/pg_ipl.h"
44
44
#include "catalog/pg_proc.h"
45
45
#include "catalog/pg_relcheck.h"
46
+ #include "catalog/pg_type.h"
46
47
#include "commands/trigger.h"
47
48
#include "optimizer/clauses.h"
48
49
#include "optimizer/planmain.h"
49
50
#include "optimizer/tlist.h"
50
51
#include "optimizer/var.h"
51
52
#include "parser/parse_clause.h"
52
- #include "parser/parse_coerce.h"
53
53
#include "parser/parse_expr.h"
54
54
#include "parser/parse_relation.h"
55
+ #include "parser/parse_target.h"
55
56
#include "rewrite/rewriteRemove.h"
56
57
#include "storage/smgr.h"
57
58
#include "tcop/tcopprot.h"
@@ -1668,9 +1669,7 @@ static void
1668
1669
StoreAttrDefault (Relation rel ,AttrNumber attnum ,char * adbin ,
1669
1670
bool updatePgAttribute )
1670
1671
{
1671
- Form_pg_attribute atp = rel -> rd_att -> attrs [attnum - 1 ];
1672
1672
Node * expr ;
1673
- Oid type ;
1674
1673
RangeTblEntry * rte ;
1675
1674
char * adsrc ;
1676
1675
Relation adrel ;
@@ -1683,20 +1682,10 @@ StoreAttrDefault(Relation rel, AttrNumber attnum, char *adbin,
1683
1682
HeapTuple atttup ;
1684
1683
Form_pg_attribute attStruct ;
1685
1684
1685
+ /*
1686
+ * Need to construct source equivalent of given node-string.
1687
+ */
1686
1688
expr = stringToNode (adbin );
1687
- type = exprType (expr );
1688
-
1689
- if (type != atp -> atttypid )
1690
- {
1691
- /*
1692
- * Check that it will be possible to coerce the expression
1693
- * to the column's type. We store the expression without
1694
- * coercion, however, to avoid premature coercion in cases like
1695
- * CREATE TABLE tbl (fld datetime DEFAULT 'now');
1696
- */
1697
- coerce_type (NULL ,expr ,type ,atp -> atttypid ,atp -> atttypmod );
1698
- }
1699
-
1700
1689
/*
1701
1690
* deparse_expression needs a RangeTblEntry list, so make one
1702
1691
*/
@@ -1904,6 +1893,7 @@ AddRelationRawConstraints(Relation rel,
1904
1893
{
1905
1894
RawColumnDefault * colDef = (RawColumnDefault * )lfirst (listptr );
1906
1895
Node * expr ;
1896
+ Oid type_id ;
1907
1897
1908
1898
Assert (colDef -> raw_default != NULL );
1909
1899
/*
@@ -1915,6 +1905,34 @@ AddRelationRawConstraints(Relation rel,
1915
1905
*/
1916
1906
if (contain_var_clause (expr ))
1917
1907
elog (ERROR ,"Cannot use attribute(s) in DEFAULT clause" );
1908
+ /*
1909
+ * Check that it will be possible to coerce the expression
1910
+ * to the column's type. We store the expression without
1911
+ * coercion, however, to avoid premature coercion in cases like
1912
+ *
1913
+ * CREATE TABLE tbl (fld datetime DEFAULT 'now');
1914
+ *
1915
+ * NB: this should match the code in updateTargetListEntry()
1916
+ * that will actually do the coercion, to ensure we don't accept
1917
+ * an unusable default expression.
1918
+ */
1919
+ type_id = exprType (expr );
1920
+ if (type_id != InvalidOid )
1921
+ {
1922
+ Form_pg_attribute atp = rel -> rd_att -> attrs [colDef -> attnum - 1 ];
1923
+
1924
+ if (type_id != atp -> atttypid )
1925
+ {
1926
+ if (CoerceTargetExpr (NULL ,expr ,
1927
+ type_id ,atp -> atttypid )== NULL )
1928
+ elog (ERROR ,"Attribute '%s' is of type '%s'"
1929
+ " but default expression is of type '%s'"
1930
+ "\n\tYou will need to rewrite or cast the expression" ,
1931
+ atp -> attname .data ,
1932
+ typeidTypeName (atp -> atttypid ),
1933
+ typeidTypeName (type_id ));
1934
+ }
1935
+ }
1918
1936
/*
1919
1937
* Might as well try to reduce any constant expressions.
1920
1938
*/
@@ -1981,6 +1999,12 @@ AddRelationRawConstraints(Relation rel,
1981
1999
* Transform raw parsetree to executable expression.
1982
2000
*/
1983
2001
expr = transformExpr (pstate ,cdef -> raw_expr ,EXPR_COLUMN_FIRST );
2002
+ /*
2003
+ * Make sure it yields a boolean result.
2004
+ */
2005
+ if (exprType (expr )!= BOOLOID )
2006
+ elog (ERROR ,"CHECK '%s' does not yield boolean result" ,
2007
+ ccname );
1984
2008
/*
1985
2009
* Make sure no outside relations are referred to.
1986
2010
*/