aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_coerce.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2004-12-11 23:26:51 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2004-12-11 23:26:51 +0000
commit12b1b5d837b5ce1c07ee3535e74e4cc3039063d6 (patch)
tree1ef0ecc2ccfba9a8a33f0b20ef31533b499cbdba /src/backend/parser/parse_coerce.c
parentfd536dd257b12a8b1abf8d744d8a3688e1db126b (diff)
downloadpostgresql-12b1b5d837b5ce1c07ee3535e74e4cc3039063d6.tar.gz
postgresql-12b1b5d837b5ce1c07ee3535e74e4cc3039063d6.zip
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/parser/parse_coerce.c')
-rw-r--r--src/backend/parser/parse_coerce.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/src/backend/parser/parse_coerce.c b/src/backend/parser/parse_coerce.c
index 4ac4ec84ece..d4407ec3732 100644
--- a/src/backend/parser/parse_coerce.c
+++ b/src/backend/parser/parse_coerce.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.124 2004/11/06 17:46:33 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.125 2004/12/11 23:26:42 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -321,13 +321,16 @@ coerce_type(ParseState *pstate, Node *node,
if (typeInheritsFrom(inputTypeId, targetTypeId))
{
/*
- * Input class type is a subclass of target, so nothing to do ---
- * except relabel the type. This is binary compatibility for
- * complex types.
+ * Input class type is a subclass of target, so generate an
+ * appropriate runtime conversion (removing unneeded columns
+ * and possibly rearranging the ones that are wanted).
*/
- return (Node *) makeRelabelType((Expr *) node,
- targetTypeId, -1,
- cformat);
+ ConvertRowtypeExpr *r = makeNode(ConvertRowtypeExpr);
+
+ r->arg = (Expr *) node;
+ r->resulttype = targetTypeId;
+ r->convertformat = cformat;
+ return (Node *) r;
}
/* If we get here, caller blew it */
elog(ERROR, "failed to find conversion function from %s to %s",
@@ -567,6 +570,8 @@ hide_coercion_node(Node *node)
((FuncExpr *) node)->funcformat = COERCE_IMPLICIT_CAST;
else if (IsA(node, RelabelType))
((RelabelType *) node)->relabelformat = COERCE_IMPLICIT_CAST;
+ else if (IsA(node, ConvertRowtypeExpr))
+ ((ConvertRowtypeExpr *) node)->convertformat = COERCE_IMPLICIT_CAST;
else if (IsA(node, RowExpr))
((RowExpr *) node)->row_format = COERCE_IMPLICIT_CAST;
else if (IsA(node, CoerceToDomain))