summaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
authorTom Lane2020-10-28 17:47:02 +0000
committerTom Lane2020-10-28 17:47:02 +0000
commitad77039fad0f4128b0e4a05ddbf5dbc3ab5f3fa4 (patch)
tree8c9b20bb980bf3c1fe8d26c7766d8fbaf616ba20 /src/include
parent36b93121436cbbf357974144068c23bac75154fa (diff)
Calculate extraUpdatedCols in query rewriter, not parser.
It's unsafe to do this at parse time because addition of generated columns to a table would not invalidate stored rules containing UPDATEs on the table ... but there might now be dependent generated columns that were not there when the rule was made. This also fixes an oversight that rewriteTargetView failed to update extraUpdatedCols when transforming an UPDATE on an updatable view. (Since the new calculation is downstream of that, rewriteTargetView doesn't actually need to do anything; but before, there was a demonstrable bug there.) In v13 and HEAD, this leads to easily-visible bugs because (since commit c6679e4fc) we won't recalculate generated columns that aren't listed in extraUpdatedCols. In v12 this bitmap is mostly just used for trigger-firing decisions, so you'd only notice a problem if a trigger cared whether a generated column had been updated. I'd complained about this back in May, but then forgot about it until bug #16671 from Michael Paul Killian revived the issue. Back-patch to v12 where this field was introduced. If existing stored rules contain any extraUpdatedCols values, they'll be ignored because the rewriter will overwrite them, so the bug will be fixed even for existing rules. (But note that if someone were to update to 13.1 or 12.5, store some rules with UPDATEs on tables having generated columns, and then downgrade to a prior minor version, they might observe issues similar to what this patch fixes. That seems unlikely enough to not be worth going to a lot of effort to fix.) Discussion: https://postgr.es/m/10206.1588964727@sss.pgh.pa.us Discussion: https://postgr.es/m/16671-2fa55851859fb166@postgresql.org
Diffstat (limited to 'src/include')
-rw-r--r--src/include/nodes/parsenodes.h16
-rw-r--r--src/include/parser/analyze.h2
-rw-r--r--src/include/rewrite/rewriteHandler.h3
3 files changed, 13 insertions, 8 deletions
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 60c2f454660..ff584f2955b 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -940,12 +940,16 @@ typedef struct PartitionCmd
*
* updatedCols is also used in some other places, for example, to determine
* which triggers to fire and in FDWs to know which changed columns they
- * need to ship off. Generated columns that are caused to be updated by an
- * update to a base column are collected in extraUpdatedCols. This is not
- * considered for permission checking, but it is useful in those places
- * that want to know the full set of columns being updated as opposed to
- * only the ones the user explicitly mentioned in the query. (There is
- * currently no need for an extraInsertedCols, but it could exist.)
+ * need to ship off.
+ *
+ * Generated columns that are caused to be updated by an update to a base
+ * column are listed in extraUpdatedCols. This is not considered for
+ * permission checking, but it is useful in those places that want to know
+ * the full set of columns being updated as opposed to only the ones the
+ * user explicitly mentioned in the query. (There is currently no need for
+ * an extraInsertedCols, but it could exist.) Note that extraUpdatedCols
+ * is populated during query rewrite, NOT in the parser, since generated
+ * columns could be added after a rule has been parsed and stored.
*
* securityQuals is a list of security barrier quals (boolean expressions),
* to be tested in the listed order before returning a row from the
diff --git a/src/include/parser/analyze.h b/src/include/parser/analyze.h
index 9d09a021419..d6a467a5728 100644
--- a/src/include/parser/analyze.h
+++ b/src/include/parser/analyze.h
@@ -46,6 +46,4 @@ extern void applyLockingClause(Query *qry, Index rtindex,
extern List *BuildOnConflictExcludedTargetlist(Relation targetrel,
Index exclRelIndex);
-extern void fill_extraUpdatedCols(RangeTblEntry *target_rte, TupleDesc tupdesc);
-
#endif /* ANALYZE_H */
diff --git a/src/include/rewrite/rewriteHandler.h b/src/include/rewrite/rewriteHandler.h
index eb2e7b1768a..a18211f4a23 100644
--- a/src/include/rewrite/rewriteHandler.h
+++ b/src/include/rewrite/rewriteHandler.h
@@ -26,6 +26,9 @@ extern Node *build_column_default(Relation rel, int attrno);
extern void rewriteTargetListUD(Query *parsetree, RangeTblEntry *target_rte,
Relation target_relation);
+extern void fill_extraUpdatedCols(RangeTblEntry *target_rte,
+ Relation target_relation);
+
extern Query *get_view_query(Relation view);
extern const char *view_query_is_auto_updatable(Query *viewquery,
bool check_cols);