summaryrefslogtreecommitdiff
path: root/src/backend/nodes
diff options
context:
space:
mode:
authorTom Lane2004-12-11 23:26:51 +0000
committerTom Lane2004-12-11 23:26:51 +0000
commit12b1b5d837b5ce1c07ee3535e74e4cc3039063d6 (patch)
tree1ef0ecc2ccfba9a8a33f0b20ef31533b499cbdba /src/backend/nodes
parentfd536dd257b12a8b1abf8d744d8a3688e1db126b (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.c20
-rw-r--r--src/backend/nodes/equalfuncs.c23
-rw-r--r--src/backend/nodes/outfuncs.c15
-rw-r--r--src/backend/nodes/readfuncs.c19
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))