diff options
| author | Tom Lane | 2004-12-11 23:26:51 +0000 |
|---|---|---|
| committer | Tom Lane | 2004-12-11 23:26:51 +0000 |
| commit | 12b1b5d837b5ce1c07ee3535e74e4cc3039063d6 (patch) | |
| tree | 1ef0ecc2ccfba9a8a33f0b20ef31533b499cbdba /src/backend/nodes | |
| parent | fd536dd257b12a8b1abf8d744d8a3688e1db126b (diff) | |
Instead of supposing (wrongly, in the general case) that the rowtype
of an inheritance child table is binary-compatible with the rowtype of
its parent, invent an expression node type that does the conversion
correctly. Fixes the new bug exhibited by Kris Shannon as well as a
lot of old bugs that would only show up when using multiple inheritance
or after altering the parent table.
Diffstat (limited to 'src/backend/nodes')
| -rw-r--r-- | src/backend/nodes/copyfuncs.c | 20 | ||||
| -rw-r--r-- | src/backend/nodes/equalfuncs.c | 23 | ||||
| -rw-r--r-- | src/backend/nodes/outfuncs.c | 15 | ||||
| -rw-r--r-- | src/backend/nodes/readfuncs.c | 19 |
4 files changed, 73 insertions, 4 deletions
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 093965a5174..abe0ebe065d 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -15,7 +15,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.293 2004/11/05 19:15:59 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.294 2004/12/11 23:26:33 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -877,6 +877,21 @@ _copyRelabelType(RelabelType *from) } /* + * _copyConvertRowtypeExpr + */ +static ConvertRowtypeExpr * +_copyConvertRowtypeExpr(ConvertRowtypeExpr *from) +{ + ConvertRowtypeExpr *newnode = makeNode(ConvertRowtypeExpr); + + COPY_NODE_FIELD(arg); + COPY_SCALAR_FIELD(resulttype); + COPY_SCALAR_FIELD(convertformat); + + return newnode; +} + +/* * _copyCaseExpr */ static CaseExpr * @@ -2696,6 +2711,9 @@ copyObject(void *from) case T_RelabelType: retval = _copyRelabelType(from); break; + case T_ConvertRowtypeExpr: + retval = _copyConvertRowtypeExpr(from); + break; case T_CaseExpr: retval = _copyCaseExpr(from); break; diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 6099f42cca7..f47fbdd5a41 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -18,7 +18,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.232 2004/11/05 19:15:59 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.233 2004/12/11 23:26:33 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -381,6 +381,24 @@ _equalRelabelType(RelabelType *a, RelabelType *b) } static bool +_equalConvertRowtypeExpr(ConvertRowtypeExpr *a, ConvertRowtypeExpr *b) +{ + COMPARE_NODE_FIELD(arg); + COMPARE_SCALAR_FIELD(resulttype); + + /* + * Special-case COERCE_DONTCARE, so that planner can build coercion + * nodes that are equal() to both explicit and implicit coercions. + */ + if (a->convertformat != b->convertformat && + a->convertformat != COERCE_DONTCARE && + b->convertformat != COERCE_DONTCARE) + return false; + + return true; +} + +static bool _equalCaseExpr(CaseExpr *a, CaseExpr *b) { COMPARE_SCALAR_FIELD(casetype); @@ -1844,6 +1862,9 @@ equal(void *a, void *b) case T_RelabelType: retval = _equalRelabelType(a, b); break; + case T_ConvertRowtypeExpr: + retval = _equalConvertRowtypeExpr(a, b); + break; case T_CaseExpr: retval = _equalCaseExpr(a, b); break; diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index b80cee4944c..292b608c22f 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.243 2004/08/29 05:06:43 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.244 2004/12/11 23:26:33 tgl Exp $ * * NOTES * Every node type that can appear in stored rules' parsetrees *must* @@ -768,6 +768,16 @@ _outRelabelType(StringInfo str, RelabelType *node) } static void +_outConvertRowtypeExpr(StringInfo str, ConvertRowtypeExpr *node) +{ + WRITE_NODE_TYPE("CONVERTROWTYPEEXPR"); + + WRITE_NODE_FIELD(arg); + WRITE_OID_FIELD(resulttype); + WRITE_ENUM_FIELD(convertformat, CoercionForm); +} + +static void _outCaseExpr(StringInfo str, CaseExpr *node) { WRITE_NODE_TYPE("CASE"); @@ -1728,6 +1738,9 @@ _outNode(StringInfo str, void *obj) case T_RelabelType: _outRelabelType(str, obj); break; + case T_ConvertRowtypeExpr: + _outConvertRowtypeExpr(str, obj); + break; case T_CaseExpr: _outCaseExpr(str, obj); break; diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c index cf2502c7151..7928c04de35 100644 --- a/src/backend/nodes/readfuncs.c +++ b/src/backend/nodes/readfuncs.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.173 2004/08/29 04:12:33 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.174 2004/12/11 23:26:34 tgl Exp $ * * NOTES * Path and Plan nodes do not have any readfuncs support, because we @@ -576,6 +576,21 @@ _readRelabelType(void) } /* + * _readConvertRowtypeExpr + */ +static ConvertRowtypeExpr * +_readConvertRowtypeExpr(void) +{ + READ_LOCALS(ConvertRowtypeExpr); + + READ_NODE_FIELD(arg); + READ_OID_FIELD(resulttype); + READ_ENUM_FIELD(convertformat, CoercionForm); + + READ_DONE(); +} + +/* * _readCaseExpr */ static CaseExpr * @@ -971,6 +986,8 @@ parseNodeString(void) return_value = _readFieldStore(); else if (MATCH("RELABELTYPE", 11)) return_value = _readRelabelType(); + else if (MATCH("CONVERTROWTYPEEXPR", 18)) + return_value = _readConvertRowtypeExpr(); else if (MATCH("CASE", 4)) return_value = _readCaseExpr(); else if (MATCH("WHEN", 4)) |
