summaryrefslogtreecommitdiff
path: root/src/backend/optimizer/util/inherit.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/util/inherit.c')
-rw-r--r--src/backend/optimizer/util/inherit.c107
1 files changed, 51 insertions, 56 deletions
diff --git a/src/backend/optimizer/util/inherit.c b/src/backend/optimizer/util/inherit.c
index 6c93c224774..bf3ea26cf4b 100644
--- a/src/backend/optimizer/util/inherit.c
+++ b/src/backend/optimizer/util/inherit.c
@@ -25,6 +25,7 @@
#include "optimizer/inherit.h"
#include "optimizer/optimizer.h"
#include "optimizer/pathnode.h"
+#include "optimizer/plancat.h"
#include "optimizer/planmain.h"
#include "optimizer/planner.h"
#include "optimizer/prep.h"
@@ -51,7 +52,7 @@ static Bitmapset *translate_col_privs(const Bitmapset *parent_privs,
List *translated_vars);
static Bitmapset *translate_col_privs_multilevel(PlannerInfo *root,
RelOptInfo *rel,
- RelOptInfo *top_parent_rel,
+ RelOptInfo *parent_rel,
Bitmapset *parent_cols);
static void expand_appendrel_subquery(PlannerInfo *root, RelOptInfo *rel,
RangeTblEntry *rte, Index rti);
@@ -345,11 +346,6 @@ expand_partitioned_rtentry(PlannerInfo *root, RelOptInfo *relinfo,
root->partColsUpdated =
has_partition_attrs(parentrel, parent_updatedCols, NULL);
- /*
- * There shouldn't be any generated columns in the partition key.
- */
- Assert(!has_partition_attrs(parentrel, parentrte->extraUpdatedCols, NULL));
-
/* Nothing further to do here if there are no partitions. */
if (partdesc->nparts == 0)
return;
@@ -566,13 +562,6 @@ expand_single_inheritance_child(PlannerInfo *root, RangeTblEntry *parentrte,
childrte->alias = childrte->eref = makeAlias(parentrte->eref->aliasname,
child_colnames);
- /* Translate the bitmapset of generated columns being updated. */
- if (childOID != parentOID)
- childrte->extraUpdatedCols = translate_col_privs(parentrte->extraUpdatedCols,
- appinfo->translated_vars);
- else
- childrte->extraUpdatedCols = bms_copy(parentrte->extraUpdatedCols);
-
/*
* Store the RTE and appinfo in the respective PlannerInfo arrays, which
* the caller must already have allocated space for.
@@ -672,21 +661,16 @@ get_rel_all_updated_cols(PlannerInfo *root, RelOptInfo *rel)
Assert(IS_SIMPLE_REL(rel));
/*
- * We obtain updatedCols and extraUpdatedCols for the query's result
- * relation. Then, if necessary, we map it to the column numbers of the
- * relation for which they were requested.
+ * We obtain updatedCols for the query's result relation. Then, if
+ * necessary, we map it to the column numbers of the relation for which
+ * they were requested.
*/
relid = root->parse->resultRelation;
rte = planner_rt_fetch(relid, root);
perminfo = getRTEPermissionInfo(root->parse->rteperminfos, rte);
updatedCols = perminfo->updatedCols;
- extraUpdatedCols = rte->extraUpdatedCols;
- /*
- * For "other" rels, we must look up the root parent relation mentioned in
- * the query, and translate the column numbers.
- */
if (rel->relid != relid)
{
RelOptInfo *top_parent_rel = find_base_rel(root, relid);
@@ -695,10 +679,15 @@ get_rel_all_updated_cols(PlannerInfo *root, RelOptInfo *rel)
updatedCols = translate_col_privs_multilevel(root, rel, top_parent_rel,
updatedCols);
- extraUpdatedCols = translate_col_privs_multilevel(root, rel, top_parent_rel,
- extraUpdatedCols);
}
+ /*
+ * Now we must check to see if there are any generated columns that depend
+ * on the updatedCols, and add them to the result.
+ */
+ extraUpdatedCols = get_dependent_generated_columns(root, rel->relid,
+ updatedCols);
+
return bms_union(updatedCols, extraUpdatedCols);
}
@@ -755,6 +744,45 @@ translate_col_privs(const Bitmapset *parent_privs,
}
/*
+ * translate_col_privs_multilevel
+ * Recursively translates the column numbers contained in 'parent_cols'
+ * to the column numbers of a descendant relation given by 'rel'
+ *
+ * Note that because this is based on translate_col_privs, it will expand
+ * a whole-row reference into all inherited columns. This is not an issue
+ * for current usages, but beware.
+ */
+static Bitmapset *
+translate_col_privs_multilevel(PlannerInfo *root, RelOptInfo *rel,
+ RelOptInfo *parent_rel,
+ Bitmapset *parent_cols)
+{
+ AppendRelInfo *appinfo;
+
+ /* Fast path for easy case. */
+ if (parent_cols == NULL)
+ return NULL;
+
+ /* Recurse if immediate parent is not the top parent. */
+ if (rel->parent != parent_rel)
+ {
+ if (rel->parent)
+ parent_cols = translate_col_privs_multilevel(root, rel->parent,
+ parent_rel,
+ parent_cols);
+ else
+ elog(ERROR, "rel with relid %u is not a child rel", rel->relid);
+ }
+
+ /* Now translate for this child. */
+ Assert(root->append_rel_array != NULL);
+ appinfo = root->append_rel_array[rel->relid];
+ Assert(appinfo != NULL);
+
+ return translate_col_privs(parent_cols, appinfo->translated_vars);
+}
+
+/*
* expand_appendrel_subquery
* Add "other rel" RelOptInfos for the children of an appendrel baserel
*
@@ -920,36 +948,3 @@ apply_child_basequals(PlannerInfo *root, RelOptInfo *parentrel,
return true;
}
-
-/*
- * translate_col_privs_multilevel
- * Recursively translates the column numbers contained in 'parent_cols'
- * to the columns numbers of a descendent relation given by 'rel'
- */
-static Bitmapset *
-translate_col_privs_multilevel(PlannerInfo *root, RelOptInfo *rel,
- RelOptInfo *top_parent_rel,
- Bitmapset *parent_cols)
-{
- AppendRelInfo *appinfo;
-
- if (parent_cols == NULL)
- return NULL;
-
- /* Recurse if immediate parent is not the top parent. */
- if (rel->parent != top_parent_rel)
- {
- if (rel->parent)
- parent_cols = translate_col_privs_multilevel(root, rel->parent,
- top_parent_rel,
- parent_cols);
- else
- elog(ERROR, "rel with relid %u is not a child rel", rel->relid);
- }
-
- Assert(root->append_rel_array != NULL);
- appinfo = root->append_rel_array[rel->relid];
- Assert(appinfo != NULL);
-
- return translate_col_privs(parent_cols, appinfo->translated_vars);
-}