|
30 | 30 | #include "miscadmin.h"
|
31 | 31 | #include "nodes/makefuncs.h"
|
32 | 32 | #include "nodes/nodeFuncs.h"
|
| 33 | +#include "optimizer/optimizer.h" |
33 | 34 | #include "parser/analyze.h"
|
34 | 35 | #include "parser/parse_coerce.h"
|
35 | 36 | #include "parser/parse_relation.h"
|
@@ -1508,6 +1509,42 @@ rewriteTargetListUD(Query *parsetree, RangeTblEntry *target_rte,
|
1508 | 1509 | }
|
1509 | 1510 | }
|
1510 | 1511 |
|
| 1512 | +/* |
| 1513 | + * Record in target_rte->extraUpdatedCols the indexes of any generated columns |
| 1514 | + * that depend on any columns mentioned in target_rte->updatedCols. |
| 1515 | + */ |
| 1516 | +void |
| 1517 | +fill_extraUpdatedCols(RangeTblEntry *target_rte, Relation target_relation) |
| 1518 | +{ |
| 1519 | + TupleDesc tupdesc = RelationGetDescr(target_relation); |
| 1520 | + TupleConstr *constr = tupdesc->constr; |
| 1521 | + |
| 1522 | + target_rte->extraUpdatedCols = NULL; |
| 1523 | + |
| 1524 | + if (constr && constr->has_generated_stored) |
| 1525 | + { |
| 1526 | + for (int i = 0; i < constr->num_defval; i++) |
| 1527 | + { |
| 1528 | + AttrDefault *defval = &constr->defval[i]; |
| 1529 | + Node *expr; |
| 1530 | + Bitmapset *attrs_used = NULL; |
| 1531 | + |
| 1532 | + /* skip if not generated column */ |
| 1533 | + if (!TupleDescAttr(tupdesc, defval->adnum - 1)->attgenerated) |
| 1534 | + continue; |
| 1535 | + |
| 1536 | + /* identify columns this generated column depends on */ |
| 1537 | + expr = stringToNode(defval->adbin); |
| 1538 | + pull_varattnos(expr, 1, &attrs_used); |
| 1539 | + |
| 1540 | + if (bms_overlap(target_rte->updatedCols, attrs_used)) |
| 1541 | + target_rte->extraUpdatedCols = |
| 1542 | + bms_add_member(target_rte->extraUpdatedCols, |
| 1543 | + defval->adnum - FirstLowInvalidHeapAttributeNumber); |
| 1544 | + } |
| 1545 | + } |
| 1546 | +} |
| 1547 | + |
1511 | 1548 |
|
1512 | 1549 | /*
|
1513 | 1550 | * matchLocks -
|
@@ -1639,6 +1676,7 @@ ApplyRetrieveRule(Query *parsetree,
|
1639 | 1676 | rte->selectedCols = NULL;
|
1640 | 1677 | rte->insertedCols = NULL;
|
1641 | 1678 | rte->updatedCols = NULL;
|
| 1679 | + rte->extraUpdatedCols = NULL; |
1642 | 1680 |
|
1643 | 1681 | /*
|
1644 | 1682 | * For the most part, Vars referencing the view should remain as
|
@@ -3617,6 +3655,9 @@ RewriteQuery(Query *parsetree, List *rewrite_events)
|
3617 | 3655 | parsetree->override,
|
3618 | 3656 | rt_entry_relation,
|
3619 | 3657 | parsetree->resultRelation);
|
| 3658 | + |
| 3659 | + /* Also populate extraUpdatedCols (for generated columns) */ |
| 3660 | + fill_extraUpdatedCols(rt_entry, rt_entry_relation); |
3620 | 3661 | }
|
3621 | 3662 | else if (event == CMD_DELETE)
|
3622 | 3663 | {
|
|
0 commit comments