summaryrefslogtreecommitdiff
path: root/src/backend/optimizer
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer')
-rw-r--r--src/backend/optimizer/prep/preptlist.c53
1 files changed, 38 insertions, 15 deletions
diff --git a/src/backend/optimizer/prep/preptlist.c b/src/backend/optimizer/prep/preptlist.c
index c2a77503d4b..ffc9d6c3f30 100644
--- a/src/backend/optimizer/prep/preptlist.c
+++ b/src/backend/optimizer/prep/preptlist.c
@@ -44,6 +44,7 @@
#include "optimizer/tlist.h"
#include "parser/parse_coerce.h"
#include "parser/parsetree.h"
+#include "utils/lsyscache.h"
#include "utils/rel.h"
static List *expand_insert_targetlist(PlannerInfo *root, List *tlist,
@@ -419,9 +420,8 @@ expand_insert_targetlist(PlannerInfo *root, List *tlist, Relation rel)
*
* INSERTs should insert NULL in this case. (We assume the
* rewriter would have inserted any available non-NULL default
- * value.) Also, if the column isn't dropped, apply any domain
- * constraints that might exist --- this is to catch domain NOT
- * NULL.
+ * value.) Also, normally we must apply any domain constraints
+ * that might exist --- this is to catch domain NOT NULL.
*
* When generating a NULL constant for a dropped column, we label
* it INT4 (any other guaranteed-to-exist datatype would do as
@@ -431,21 +431,17 @@ expand_insert_targetlist(PlannerInfo *root, List *tlist, Relation rel)
* representation is datatype-independent. This could perhaps
* confuse code comparing the finished plan to the target
* relation, however.
+ *
+ * Another exception is that if the column is generated, the value
+ * we produce here will be ignored, and we don't want to risk
+ * throwing an error. So in that case we *don't* want to apply
+ * domain constraints, so we must produce a NULL of the base type.
+ * Again, code comparing the finished plan to the target relation
+ * must account for this.
*/
Node *new_expr;
- if (!att_tup->attisdropped)
- {
- new_expr = coerce_null_to_domain(att_tup->atttypid,
- att_tup->atttypmod,
- att_tup->attcollation,
- att_tup->attlen,
- att_tup->attbyval);
- /* Must run expression preprocessing on any non-const nodes */
- if (!IsA(new_expr, Const))
- new_expr = eval_const_expressions(root, new_expr);
- }
- else
+ if (att_tup->attisdropped)
{
/* Insert NULL for dropped column */
new_expr = (Node *) makeConst(INT4OID,
@@ -456,6 +452,33 @@ expand_insert_targetlist(PlannerInfo *root, List *tlist, Relation rel)
true, /* isnull */
true /* byval */ );
}
+ else if (att_tup->attgenerated)
+ {
+ /* Generated column, insert a NULL of the base type */
+ Oid baseTypeId = att_tup->atttypid;
+ int32 baseTypeMod = att_tup->atttypmod;
+
+ baseTypeId = getBaseTypeAndTypmod(baseTypeId, &baseTypeMod);
+ new_expr = (Node *) makeConst(baseTypeId,
+ baseTypeMod,
+ att_tup->attcollation,
+ att_tup->attlen,
+ (Datum) 0,
+ true, /* isnull */
+ att_tup->attbyval);
+ }
+ else
+ {
+ /* Normal column, insert a NULL of the column datatype */
+ new_expr = coerce_null_to_domain(att_tup->atttypid,
+ att_tup->atttypmod,
+ att_tup->attcollation,
+ att_tup->attlen,
+ att_tup->attbyval);
+ /* Must run expression preprocessing on any non-const nodes */
+ if (!IsA(new_expr, Const))
+ new_expr = eval_const_expressions(root, new_expr);
+ }
new_tle = makeTargetEntry((Expr *) new_expr,
attrno,