summaryrefslogtreecommitdiff
path: root/src/backend/optimizer
diff options
context:
space:
mode:
authorPeter Eisentraut2019-03-30 07:13:09 +0000
committerPeter Eisentraut2019-03-30 07:15:57 +0000
commitfc22b6623b6b3bab3cb057ccd282c2bfad1a0b30 (patch)
treecda5092955ece5d547d5517ed56a3d480f199d25 /src/backend/optimizer
parent6b8b5364ddd0e4d882562615c6b6c28638ade9f2 (diff)
Generated columns
This is an SQL-standard feature that allows creating columns that are computed from expressions rather than assigned, similar to a view or materialized view but on a column basis. This implements one kind of generated column: stored (computed on write). Another kind, virtual (computed on read), is planned for the future, and some room is left for it. Reviewed-by: Michael Paquier <michael@paquier.xyz> Reviewed-by: Pavel Stehule <pavel.stehule@gmail.com> Discussion: https://www.postgresql.org/message-id/flat/b151f851-4019-bdb1-699e-ebab07d2f40a@2ndquadrant.com
Diffstat (limited to 'src/backend/optimizer')
-rw-r--r--src/backend/optimizer/plan/createplan.c8
-rw-r--r--src/backend/optimizer/util/inherit.c6
-rw-r--r--src/backend/optimizer/util/plancat.c19
3 files changed, 30 insertions, 3 deletions
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index 979c3c212fd..cc222cb06cf 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -6570,8 +6570,9 @@ make_modifytable(PlannerInfo *root,
/*
* Try to modify the foreign table directly if (1) the FDW provides
- * callback functions needed for that, (2) there are no row-level
- * triggers on the foreign table, and (3) there are no WITH CHECK
+ * callback functions needed for that and (2) there are no local
+ * structures that need to be run for each modified row: row-level
+ * triggers on the foreign table, stored generated columns, WITH CHECK
* OPTIONs from parent views.
*/
direct_modify = false;
@@ -6581,7 +6582,8 @@ make_modifytable(PlannerInfo *root,
fdwroutine->IterateDirectModify != NULL &&
fdwroutine->EndDirectModify != NULL &&
withCheckOptionLists == NIL &&
- !has_row_triggers(subroot, rti, operation))
+ !has_row_triggers(subroot, rti, operation) &&
+ !has_stored_generated_columns(subroot, rti))
direct_modify = fdwroutine->PlanDirectModify(subroot, node, rti, i);
if (direct_modify)
direct_modify_plans = bms_add_member(direct_modify_plans, i);
diff --git a/src/backend/optimizer/util/inherit.c b/src/backend/optimizer/util/inherit.c
index 1d1e5060e26..d467a4826b0 100644
--- a/src/backend/optimizer/util/inherit.c
+++ b/src/backend/optimizer/util/inherit.c
@@ -280,6 +280,10 @@ expand_partitioned_rtentry(PlannerInfo *root, RangeTblEntry *parentrte,
if (!root->partColsUpdated)
root->partColsUpdated =
has_partition_attrs(parentrel, parentrte->updatedCols, NULL);
+ /*
+ * There shouldn't be any generated columns in the partition key.
+ */
+ Assert(!has_partition_attrs(parentrel, parentrte->extraUpdatedCols, NULL));
/*
* If the partitioned table has no partitions, treat this as the
@@ -415,6 +419,8 @@ expand_single_inheritance_child(PlannerInfo *root, RangeTblEntry *parentrte,
appinfo->translated_vars);
childrte->updatedCols = translate_col_privs(parentrte->updatedCols,
appinfo->translated_vars);
+ childrte->extraUpdatedCols = translate_col_privs(parentrte->extraUpdatedCols,
+ appinfo->translated_vars);
}
/*
diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c
index a0a7c5442de..2ebded8a954 100644
--- a/src/backend/optimizer/util/plancat.c
+++ b/src/backend/optimizer/util/plancat.c
@@ -2083,6 +2083,25 @@ has_row_triggers(PlannerInfo *root, Index rti, CmdType event)
return result;
}
+bool
+has_stored_generated_columns(PlannerInfo *root, Index rti)
+{
+ RangeTblEntry *rte = planner_rt_fetch(rti, root);
+ Relation relation;
+ TupleDesc tupdesc;
+ bool result = false;
+
+ /* Assume we already have adequate lock */
+ relation = heap_open(rte->relid, NoLock);
+
+ tupdesc = RelationGetDescr(relation);
+ result = tupdesc->constr && tupdesc->constr->has_generated_stored;
+
+ heap_close(relation, NoLock);
+
+ return result;
+}
+
/*
* set_relation_partition_info
*