Skip to content

Commit 7cd67c8

Browse files
committed
Oops, DEFAULT processing wasn't doing type compatibility checking
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...
1 parent eabc714 commit 7cd67c8

File tree

1 file changed

+41
-17
lines changed

1 file changed

+41
-17
lines changed

src/backend/catalog/heap.c

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* 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 $
1111
*
1212
*
1313
* INTERFACE ROUTINES
@@ -43,15 +43,16 @@
4343
#include "catalog/pg_ipl.h"
4444
#include "catalog/pg_proc.h"
4545
#include "catalog/pg_relcheck.h"
46+
#include "catalog/pg_type.h"
4647
#include "commands/trigger.h"
4748
#include "optimizer/clauses.h"
4849
#include "optimizer/planmain.h"
4950
#include "optimizer/tlist.h"
5051
#include "optimizer/var.h"
5152
#include "parser/parse_clause.h"
52-
#include "parser/parse_coerce.h"
5353
#include "parser/parse_expr.h"
5454
#include "parser/parse_relation.h"
55+
#include "parser/parse_target.h"
5556
#include "rewrite/rewriteRemove.h"
5657
#include "storage/smgr.h"
5758
#include "tcop/tcopprot.h"
@@ -1668,9 +1669,7 @@ static void
16681669
StoreAttrDefault(Relation rel, AttrNumber attnum, char *adbin,
16691670
bool updatePgAttribute)
16701671
{
1671-
Form_pg_attribute atp = rel->rd_att->attrs[attnum - 1];
16721672
Node *expr;
1673-
Oid type;
16741673
RangeTblEntry *rte;
16751674
char *adsrc;
16761675
Relation adrel;
@@ -1683,20 +1682,10 @@ StoreAttrDefault(Relation rel, AttrNumber attnum, char *adbin,
16831682
HeapTuple atttup;
16841683
Form_pg_attribute attStruct;
16851684

1685+
/*
1686+
* Need to construct source equivalent of given node-string.
1687+
*/
16861688
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-
17001689
/*
17011690
* deparse_expression needs a RangeTblEntry list, so make one
17021691
*/
@@ -1904,6 +1893,7 @@ AddRelationRawConstraints(Relation rel,
19041893
{
19051894
RawColumnDefault *colDef = (RawColumnDefault *) lfirst(listptr);
19061895
Node *expr;
1896+
Oid type_id;
19071897

19081898
Assert(colDef->raw_default != NULL);
19091899
/*
@@ -1915,6 +1905,34 @@ AddRelationRawConstraints(Relation rel,
19151905
*/
19161906
if (contain_var_clause(expr))
19171907
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+
}
19181936
/*
19191937
* Might as well try to reduce any constant expressions.
19201938
*/
@@ -1981,6 +1999,12 @@ AddRelationRawConstraints(Relation rel,
19811999
* Transform raw parsetree to executable expression.
19822000
*/
19832001
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);
19842008
/*
19852009
* Make sure no outside relations are referred to.
19862010
*/

0 commit comments

Comments
 (0)