74 bool *returning_flag);
85 const char *attrName);
96 int varno,
Query *parsetree,
bool *hasUpdate);
150 bool forUpdatePushedDown)
162 foreach(l, parsetree->
rtable)
188 else if (forUpdatePushedDown)
193 lockmode = rte->rellockmode;
196 lockmode = rte->rellockmode;
204 rte->relkind = rel->
rd_rel->relkind;
223 foreach(ll, rte->joinaliasvars)
226 Var *aliasvar = aliasitem;
238 if (aliasvar &&
IsA(aliasvar,
Var))
250 if (aliasvar->
varno != curinputvarno)
252 curinputvarno = aliasvar->
varno;
253 if (curinputvarno >= rt_index)
254 elog(
ERROR,
"unexpected varno %d in JOIN RTE %d",
255 curinputvarno, rt_index);
256 curinputrte =
rt_fetch(curinputvarno,
266 newaliasvars =
lappend(newaliasvars, aliasitem);
268 rte->joinaliasvars = newaliasvars;
279 (forUpdatePushedDown ||
301 if (parsetree->hasSubLinks)
356 bool *returning_flag)
362 Query **sub_action_ptr;
381 current_varno = rt_index;
411 foreach(lc, sub_action->
rtable)
449 List *perminfos_tail = sub_action->rteperminfos;
457 sub_action->rteperminfos =
copyObject(parsetree->rteperminfos);
459 rtable_tail, perminfos_tail);
466 if (parsetree->hasSubLinks && !sub_action->hasSubLinks)
468 foreach(lc, parsetree->
rtable)
475 sub_action->hasSubLinks =
479 sub_action->hasSubLinks =
483 sub_action->hasSubLinks =
487 sub_action->hasSubLinks =
494 sub_action->hasSubLinks |=
496 if (sub_action->hasSubLinks)
508 sub_action->hasRowSecurity |= parsetree->hasRowSecurity;
535 if (newjointree !=
NIL)
545 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
546 errmsg(
"conditional UNION/INTERSECT/EXCEPT statements are not implemented")));
555 if (parsetree->hasSubLinks && !sub_action->hasSubLinks)
556 sub_action->hasSubLinks =
578 foreach(lc, parsetree->
cteList)
583 foreach(lc2, sub_action->
cteList)
589 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
590 errmsg(
"WITH query name \"%s\" appears in both a rule action and the query being rewritten",
599 sub_action->hasRecursive |= parsetree->hasRecursive;
600 sub_action->hasModifyingCTE |= parsetree->hasModifyingCTE;
614 if (sub_action->hasModifyingCTE && rule_action != sub_action)
616 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
617 errmsg(
"INSERT ... SELECT rule actions are not supported for queries having data-modifying statements in WITH")));
625 AddQual(sub_action, rule_qual);
640 sub_action = (
Query *)
646 sub_action->resultRelation,
653 *sub_action_ptr = sub_action;
655 rule_action = sub_action;
670 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
671 errmsg(
"cannot have RETURNING lists in multiple rules")));
672 *returning_flag =
true;
675 parsetree->resultRelation,
680 rule_action->resultRelation,
683 &rule_action->hasSubLinks);
686 rule_action->returningOldAlias = parsetree->returningOldAlias;
687 rule_action->returningNewAlias = parsetree->returningNewAlias;
693 if (parsetree->hasSubLinks && !rule_action->hasSubLinks)
694 rule_action->hasSubLinks =
717 foreach(l, newjointree)
777 int values_rte_index,
801 next_junk_attrno = numattrs + 1;
803 foreach(temp, targetList)
807 if (!old_tle->resjunk)
810 attrno = old_tle->
resno;
811 if (attrno < 1 || attrno > numattrs)
812 elog(
ERROR,
"bogus resno %d in targetlist", attrno);
816 if (att_tup->attisdropped)
820 new_tles[attrno - 1] =
822 new_tles[attrno - 1],
837 if (old_tle->
resno != next_junk_attrno)
840 old_tle->
resno = next_junk_attrno;
842 junk_tlist =
lappend(junk_tlist, old_tle);
847 for (attrno = 1; attrno <= numattrs; attrno++)
855 if (att_tup->attisdropped)
863 apply_default = ((new_tle == NULL && commandType ==
CMD_INSERT) ||
868 int values_attrno = 0;
871 if (values_rte && new_tle &&
IsA(new_tle->
expr,
Var))
875 if (var->
varno == values_rte_index)
884 if (att_tup->attidentity == ATTRIBUTE_IDENTITY_ALWAYS && !apply_default)
887 apply_default =
true;
896 if (values_attrno != 0)
898 if (default_only_cols == NULL)
902 apply_default =
true;
907 (
errcode(ERRCODE_GENERATED_ALWAYS),
908 errmsg(
"cannot insert a non-DEFAULT value into column \"%s\"",
910 errdetail(
"Column \"%s\" is an identity column defined as GENERATED ALWAYS.",
912 errhint(
"Use OVERRIDING SYSTEM VALUE to override.")));
921 if (att_tup->attidentity == ATTRIBUTE_IDENTITY_BY_DEFAULT &&
923 apply_default =
true;
929 if (att_tup->attgenerated && !apply_default)
935 if (values_attrno != 0)
937 if (default_only_cols == NULL)
941 apply_default =
true;
946 (
errcode(ERRCODE_GENERATED_ALWAYS),
947 errmsg(
"cannot insert a non-DEFAULT value into column \"%s\"",
949 errdetail(
"Column \"%s\" is a generated column.",
958 if (values_attrno != 0 && apply_default && unused_values_attrnos)
970 if (att_tup->attidentity == ATTRIBUTE_IDENTITY_ALWAYS &&
971 new_tle && !apply_default)
973 (
errcode(ERRCODE_GENERATED_ALWAYS),
974 errmsg(
"column \"%s\" can only be updated to DEFAULT",
976 errdetail(
"Column \"%s\" is an identity column defined as GENERATED ALWAYS.",
979 if (att_tup->attgenerated && new_tle && !apply_default)
981 (
errcode(ERRCODE_GENERATED_ALWAYS),
982 errmsg(
"column \"%s\" can only be updated to DEFAULT",
984 errdetail(
"Column \"%s\" is a generated column.",
988 if (att_tup->attgenerated)
996 else if (apply_default)
1016 att_tup->attcollation,
1029 new_tlist =
lappend(new_tlist, new_tle);
1047 const char *attrName)
1058 if (prior_tle == NULL)
1098 prior_expr = (
Node *) prior_tle->
expr;
1113 if (src_input == NULL ||
1114 prior_input == NULL ||
1117 (
errcode(ERRCODE_SYNTAX_ERROR),
1118 errmsg(
"multiple assignments to same column \"%s\"",
1124 priorbottom = prior_input;
1129 if (newbottom == NULL)
1131 priorbottom = newbottom;
1133 if (!
equal(priorbottom, src_input))
1135 (
errcode(ERRCODE_SYNTAX_ERROR),
1136 errmsg(
"multiple assignments to same column \"%s\"",
1149 memcpy(fstore, prior_expr,
sizeof(
FieldStore));
1160 memcpy(fstore, src_expr,
sizeof(
FieldStore));
1161 fstore->
arg = (
Expr *) prior_expr;
1163 newexpr = (
Node *) fstore;
1171 newexpr = (
Node *) sbsref;
1185 newcoerce->
arg = (
Expr *) newexpr;
1186 newexpr = (
Node *) newcoerce;
1231 Oid atttype = att_tup->atttypid;
1232 int32 atttypmod = att_tup->atttypmod;
1236 if (att_tup->attidentity)
1241 nve->
typeId = att_tup->atttypid;
1243 return (
Node *) nve;
1249 if (att_tup->atthasdef)
1253 elog(
ERROR,
"default expression not found for attribute %d of relation \"%s\"",
1261 if (expr == NULL && !att_tup->attgenerated)
1284 (
errcode(ERRCODE_DATATYPE_MISMATCH),
1285 errmsg(
"column \"%s\" is of type %s"
1286 " but default expression is of type %s",
1290 errhint(
"You will need to rewrite or cast the expression.")));
1307 foreach(lc2, sublist)
1335 if (default_only_cols == NULL)
1339 foreach(lc2, sublist)
1352 foreach(lc2, sublist)
1370 return default_only_cols;
1418 bool isAutoUpdatableView;
1443 attrnos = (
int *)
palloc0(numattrs *
sizeof(
int));
1457 Assert(attrno >= 1 && attrno <= numattrs);
1458 attrnos[attrno - 1] = tle->
resno;
1468 isAutoUpdatableView =
false;
1469 if (target_relation->
rd_rel->relkind == RELKIND_VIEW &&
1479 parsetree->resultRelation, parsetree, &hasUpdate);
1487 rule_lock->
qual == NULL)
1500 isAutoUpdatableView =
true;
1515 foreach(lc2, sublist)
1518 int attrno = attrnos[
i++];
1542 elog(
ERROR,
"cannot set value in column %d to DEFAULT",
i);
1543 Assert(attrno > 0 && attrno <= target_relation->rd_att->natts);
1546 if (!att_tup->attisdropped)
1558 if (isAutoUpdatableView)
1561 newList =
lappend(newList, col);
1562 allReplaced =
false;
1568 att_tup->attcollation,
1572 newList =
lappend(newList, new_expr);
1575 newList =
lappend(newList, col);
1577 newValues =
lappend(newValues, newList);
1609 foreach(lc2, sublist)
1622 newList =
lappend(newList, col);
1624 newValues =
lappend(newValues, newList);
1646 if (rulelocks == NULL)
1651 if (parsetree->resultRelation != varno)
1657 for (
i = 0;
i < nlocks;
i++)
1688 errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1689 errmsg(
"cannot execute MERGE on relation \"%s\"",
1691 errdetail(
"MERGE is not supported for relations with rules."));
1694 if (oneLock->
event == event)
1698 matching_locks =
lappend(matching_locks, oneLock);
1702 return matching_locks;
1722 elog(
ERROR,
"expected just one rule action");
1723 if (
rule->qual != NULL)
1724 elog(
ERROR,
"cannot handle qualified ON SELECT rule");
1730 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1731 errmsg(
"access to non-system view \"%s\" is restricted",
1734 if (rt_index == parsetree->resultRelation)
1780 parsetree->resultRelation, 0);
1799 elog(
ERROR,
"unrecognized commandType: %d",
1839 parsetree->hasRowSecurity |= rule_action->hasRowSecurity;
1868 while (
list_length(rte->eref->colnames) < numCols)
1870 rte->eref->colnames =
lappend(rte->eref->colnames,
1915 strength, waitPolicy,
true);
1935 elog(
ERROR,
"unrecognized node type: %d",
1992 int origResultRelation = parsetree->resultRelation;
2002 foreach(lc, parsetree->
cteList)
2006 if (cte->search_clause || cte->cycle_clause)
2044 parsetree->hasRowSecurity |= rte->
subquery->hasRowSecurity;
2065 if (rte->relkind == RELKIND_MATVIEW)
2086 if (rt_index != parsetree->resultRelation &&
2094 if (rt_index == parsetree->resultRelation &&
2095 rt_index != origResultRelation)
2111 for (
i = 0;
i <
rules->numLocks;
i++)
2129 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
2130 errmsg(
"infinite recursion detected in rules for relation \"%s\"",
2153 foreach(lc, parsetree->
cteList)
2164 parsetree->hasRowSecurity |= ((
Query *) cte->
ctequery)->hasRowSecurity;
2171 if (parsetree->hasSubLinks)
2195 foreach(lc, parsetree->
rtable)
2199 List *securityQuals;
2200 List *withCheckOptions;
2201 bool hasRowSecurity;
2208 (rte->relkind != RELKIND_RELATION &&
2209 rte->relkind != RELKIND_PARTITIONED_TABLE))
2218 &securityQuals, &withCheckOptions,
2219 &hasRowSecurity, &hasSubLinks);
2221 if (securityQuals !=
NIL || withCheckOptions !=
NIL)
2234 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
2235 errmsg(
"infinite recursion detected in policy for relation \"%s\"",
2283 rte->securityQuals);
2285 parsetree->withCheckOptions =
list_concat(withCheckOptions,
2286 parsetree->withCheckOptions);
2294 parsetree->hasRowSecurity =
true;
2296 parsetree->hasSubLinks =
true;
2348 parsetree->resultRelation,
2353 &parsetree->hasSubLinks);
2395 bool *returning_flag,
2396 Query **qual_product)
2404 Node *event_qual = rule_lock->
qual;
2412 if (event_qual != NULL)
2417 *instead_flag =
true;
2439 if (*qual_product == NULL)
2457 event_qual, rt_index, event,
2460 rule_action->querySource = qsrc;
2461 rule_action->canSetTag =
false;
2463 results =
lappend(results, rule_action);
2495 elog(
ERROR,
"invalid _RETURN rule action specification");
2501 elog(
ERROR,
"failed to find _RETURN rule for view");
2541 switch (
action->commandType)
2565 elog(
ERROR,
"unrecognized CmdType: %d", (
int) event);
2598 return gettext_noop(
"Junk view columns are not updatable.");
2603 return gettext_noop(
"View columns that are not columns of their base relation are not updatable.");
2606 return gettext_noop(
"View columns that refer to system columns are not updatable.");
2609 return gettext_noop(
"View columns that return whole-row references are not updatable.");
2670 return gettext_noop(
"Views containing DISTINCT are not automatically updatable.");
2673 return gettext_noop(
"Views containing GROUP BY are not automatically updatable.");
2676 return gettext_noop(
"Views containing HAVING are not automatically updatable.");
2679 return gettext_noop(
"Views containing UNION, INTERSECT, or EXCEPT are not automatically updatable.");
2682 return gettext_noop(
"Views containing WITH are not automatically updatable.");
2685 return gettext_noop(
"Views containing LIMIT or OFFSET are not automatically updatable.");
2696 if (viewquery->hasAggs)
2697 return gettext_noop(
"Views that return aggregate functions are not automatically updatable.");
2699 if (viewquery->hasWindowFuncs)
2700 return gettext_noop(
"Views that return window functions are not automatically updatable.");
2702 if (viewquery->hasTargetSRFs)
2703 return gettext_noop(
"Views that return set-returning functions are not automatically updatable.");
2710 return gettext_noop(
"Views that do not select from a single table or view are not automatically updatable.");
2714 return gettext_noop(
"Views that do not select from a single table or view are not automatically updatable.");
2718 (base_rte->relkind != RELKIND_RELATION &&
2719 base_rte->relkind != RELKIND_FOREIGN_TABLE &&
2720 base_rte->relkind != RELKIND_VIEW &&
2721 base_rte->relkind != RELKIND_PARTITIONED_TABLE))
2722 return gettext_noop(
"Views that do not select from a single table or view are not automatically updatable.");
2725 return gettext_noop(
"Views containing TABLESAMPLE are not automatically updatable.");
2749 return gettext_noop(
"Views that have no updatable columns are not automatically updatable.");
2783 char **non_updatable_col)
2797 if (updatable_cols != NULL)
2798 *updatable_cols = NULL;
2799 if (non_updatable_col != NULL)
2800 *non_updatable_col = NULL;
2807 const char *col_update_detail;
2812 if (col_update_detail == NULL)
2815 if (updatable_cols != NULL)
2821 if (non_updatable_col != NULL)
2822 *non_updatable_col = tle->resname;
2823 return col_update_detail;
2864 List *outer_reloids,
2865 bool include_triggers,
2872#define ALL_EVENTS ((1 << CMD_INSERT) | (1 << CMD_UPDATE) | (1 << CMD_DELETE))
2896 if (rel->
rd_rel->relkind == RELKIND_RELATION ||
2897 rel->
rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
2905 if (rulelocks != NULL)
2927 if (include_triggers)
2950 if (rel->
rd_rel->relkind == RELKIND_FOREIGN_TABLE)
2972 if (rel->
rd_rel->relkind == RELKIND_VIEW)
2991 &updatable_cols, NULL);
2993 if (include_cols != NULL)
3011 if (base_rte->relkind != RELKIND_RELATION &&
3012 base_rte->relkind != RELKIND_PARTITIONED_TABLE)
3014 baseoid = base_rte->
relid;
3025 events |= auto_events;
3066 foreach(lc, targetlist)
3087 if (tle != NULL && !tle->resjunk &&
IsA(tle->
expr,
Var))
3095 elog(
ERROR,
"attribute number %d not found in view targetlist",
3120 List *mergeActionList,
3129 errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
3130 errmsg(
"cannot insert into view \"%s\"",
3133 errhint(
"To enable inserting into the view, provide an INSTEAD OF INSERT trigger or an unconditional ON INSERT DO INSTEAD rule."));
3137 errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
3138 errmsg(
"cannot update view \"%s\"",
3141 errhint(
"To enable updating the view, provide an INSTEAD OF UPDATE trigger or an unconditional ON UPDATE DO INSTEAD rule."));
3145 errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
3146 errmsg(
"cannot delete from view \"%s\"",
3149 errhint(
"To enable deleting from the view, provide an INSTEAD OF DELETE trigger or an unconditional ON DELETE DO INSTEAD rule."));
3159 switch (
action->commandType)
3164 errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
3165 errmsg(
"cannot insert into view \"%s\"",
3168 errhint(
"To enable inserting into the view using MERGE, provide an INSTEAD OF INSERT trigger."));
3173 errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
3174 errmsg(
"cannot update view \"%s\"",
3177 errhint(
"To enable updating the view using MERGE, provide an INSTEAD OF UPDATE trigger."));
3182 errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
3183 errmsg(
"cannot delete from view \"%s\"",
3186 errhint(
"To enable deleting from the view using MERGE, provide an INSTEAD OF DELETE trigger."));
3197 elog(
ERROR,
"unrecognized CmdType: %d", (
int) command);
3216 bool insert_or_update;
3217 const char *auto_update_detail;
3228 List *view_targetlist;
3241 view_rte =
rt_fetch(parsetree->resultRelation, parsetree->
rtable);
3260 insert_or_update =
true;
3270 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
3271 errmsg(
"access to non-system view \"%s\" is restricted",
3280 auto_update_detail =
3283 if (auto_update_detail)
3287 auto_update_detail);
3293 if (insert_or_update)
3296 char *non_updatable_col;
3349 &non_updatable_col);
3350 if (auto_update_detail)
3360 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3361 errmsg(
"cannot insert into column \"%s\" of view \"%s\"",
3368 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3369 errmsg(
"cannot update column \"%s\" of view \"%s\"",
3376 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3377 errmsg(
"cannot merge into column \"%s\" of view \"%s\"",
3404 errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3405 errmsg(
"cannot merge into view \"%s\"",
3407 errdetail(
"MERGE is not supported for views with INSTEAD OF triggers for some actions but not all."),
3408 errhint(
"To enable merging into the view, either provide a full set of INSTEAD OF triggers or drop the existing INSTEAD OF triggers."));
3437 base_rte->relkind = base_rel->
rd_rel->relkind;
3445 if (viewquery->hasSubLinks)
3476 new_rte->
inh =
false;
3512 new_rte->perminfoindex = 0;
3560 new_rte->securityQuals = view_rte->securityQuals;
3561 view_rte->securityQuals =
NIL;
3567 parsetree = (
Query *)
3569 parsetree->resultRelation,
3585 parsetree->resultRelation,
3588 Assert(parsetree->resultRelation == new_rt_index);
3611 if (view_tle != NULL && !view_tle->resjunk &&
IsA(view_tle->
expr,
Var))
3614 elog(
ERROR,
"attribute number %d not found in view targetlist",
3631 if (view_tle != NULL && !view_tle->resjunk &&
IsA(view_tle->
expr,
Var))
3632 tle->resno = ((
Var *) view_tle->
expr)->varattno;
3634 elog(
ERROR,
"attribute number %d not found in view targetlist",
3648 Index old_exclRelIndex,
3668 if (view_tle != NULL && !view_tle->resjunk &&
IsA(view_tle->
expr,
Var))
3671 elog(
ERROR,
"attribute number %d not found in view targetlist",
3690 new_exclRte = new_exclNSItem->
p_rte;
3691 new_exclRte->relkind = RELKIND_COMPOSITE_TYPE;
3693 new_exclRte->perminfoindex = 0;
3717 new_exclRelIndex, 0);
3728 &parsetree->hasSubLinks);
3768 new_rte->securityQuals =
lcons(viewqual, new_rte->securityQuals);
3779 if (!parsetree->hasSubLinks)
3792 if (insert_or_update)
3805 if (parsetree->withCheckOptions !=
NIL)
3826 if (has_wco && (cascaded || viewquery->
jointree->
quals != NULL))
3837 parsetree->withCheckOptions =
lcons(wco,
3838 parsetree->withCheckOptions);
3851 if (!parsetree->hasSubLinks &&
3879 bool instead =
false;
3880 bool returning =
false;
3881 bool updatableview =
false;
3882 Query *qual_product = NULL;
3891 foreach(lc1, parsetree->
cteList)
3922 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3923 errmsg(
"DO INSTEAD NOTIFY rules are not supported for data-modifying statements in WITH")));
3926 Assert(!ctequery->canSetTag);
3930 else if (newstuff ==
NIL)
3933 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3934 errmsg(
"DO INSTEAD NOTHING rules are not supported for data-modifying statements in WITH")));
3941 foreach(lc2, newstuff)
3947 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3948 errmsg(
"conditional DO INSTEAD rules are not supported for data-modifying statements in WITH")));
3951 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3952 errmsg(
"DO ALSO rules are not supported for data-modifying statements in WITH")));
3956 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3957 errmsg(
"multi-statement DO INSTEAD rules are not supported for data-modifying statements in WITH")));
3971 int result_relation;
3975 int product_orig_rt_length;
3976 List *product_queries;
3977 bool hasUpdate =
false;
3978 int values_rte_index = 0;
3979 bool defaults_remaining =
false;
3981 result_relation = parsetree->resultRelation;
3982 Assert(result_relation != 0);
4018 if (values_rte != NULL)
4019 elog(
ERROR,
"more than one VALUES RTE found");
4022 values_rte_index = rtr->
rtindex;
4029 Bitmapset *unused_values_attrnos = NULL;
4034 parsetree->override,
4038 &unused_values_attrnos);
4042 unused_values_attrnos))
4043 defaults_remaining =
true;
4051 parsetree->override,
4062 parsetree->override,
4073 parsetree->override,
4088 switch (
action->commandType)
4118 elog(
ERROR,
"unrecognized commandType: %d", (
int) event);
4124 result_relation, parsetree, &hasUpdate);
4143 if (defaults_remaining && product_queries !=
NIL)
4156 foreach(n, product_queries)
4182 elog(
ERROR,
"failed to find VALUES RTE in product query");
4204 rt_entry_relation->
rd_rel->relkind == RELKIND_VIEW &&
4213 if (qual_product != NULL)
4217 gettext_noop(
"Views with conditional DO INSTEAD rules are not automatically updatable."));
4233 product_queries =
lcons(parsetree, product_queries);
4235 product_queries =
lappend(product_queries, parsetree);
4246 updatableview =
true;
4253 if (product_queries !=
NIL)
4258 foreach(n, rewrite_events)
4262 rev->
event == event)
4264 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
4265 errmsg(
"infinite recursion detected in rules for relation \"%s\"",
4272 rewrite_events =
lappend(rewrite_events, rev);
4274 foreach(n, product_queries)
4291 product_orig_rt_length);
4305 if ((instead || qual_product != NULL) &&
4313 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4314 errmsg(
"cannot perform INSERT RETURNING on relation \"%s\"",
4316 errhint(
"You need an unconditional ON INSERT DO INSTEAD rule with a RETURNING clause.")));
4320 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4321 errmsg(
"cannot perform UPDATE RETURNING on relation \"%s\"",
4323 errhint(
"You need an unconditional ON UPDATE DO INSTEAD rule with a RETURNING clause.")));
4327 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4328 errmsg(
"cannot perform DELETE RETURNING on relation \"%s\"",
4330 errhint(
"You need an unconditional ON DELETE DO INSTEAD rule with a RETURNING clause.")));
4333 elog(
ERROR,
"unrecognized commandType: %d",
4344 (product_queries !=
NIL || hasUpdate) &&
4347 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4348 errmsg(
"INSERT with ON CONFLICT clause cannot be used with table that has INSERT or UPDATE rules")));
4369 if (qual_product != NULL)
4370 rewritten =
lcons(qual_product, rewritten);
4372 rewritten =
lcons(parsetree, rewritten);
4376 if (qual_product != NULL)
4377 rewritten =
lappend(rewritten, qual_product);
4379 rewritten =
lappend(rewritten, parsetree);
4395 foreach(lc1, rewritten)
4404 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4405 errmsg(
"WITH cannot be used in a query that is rewritten by rules into multiple queries")));
4438 for (
int i = 0;
i < tupdesc->
natts;
i++)
4442 if (attr->attgenerated == ATTRIBUTE_GENERATED_VIRTUAL)
4507 Assert(att_tup->attgenerated == ATTRIBUTE_GENERATED_VIRTUAL);
4510 if (defexpr == NULL)
4511 elog(
ERROR,
"no generation expression found for column number %d of table \"%s\"",
4519 attcollid = att_tup->attcollation;
4528 defexpr = (
Node *) ce;
4547 uint64 input_query_id = parsetree->queryId;
4552 bool foundOriginalQuery;
4559 Assert(parsetree->canSetTag);
4576 foreach(l, querylist)
4582 query->queryId = input_query_id;
4584 results =
lappend(results, query);
4604 foundOriginalQuery =
false;
4613 Assert(query->canSetTag);
4614 Assert(!foundOriginalQuery);
4615 foundOriginalQuery =
true;
4616#ifndef USE_ASSERT_CHECKING
4622 Assert(!query->canSetTag);
4626 lastInstead = query;
4630 if (!foundOriginalQuery && lastInstead != NULL)
4631 lastInstead->canSetTag =
true;
#define InvalidAttrNumber
Bitmapset * bms_int_members(Bitmapset *a, const Bitmapset *b)
int bms_next_member(const Bitmapset *a, int prevbit)
Bitmapset * bms_del_member(Bitmapset *a, int x)
bool bms_is_member(int x, const Bitmapset *a)
Bitmapset * bms_add_member(Bitmapset *a, int x)
Bitmapset * bms_union(const Bitmapset *a, const Bitmapset *b)
int errdetail_internal(const char *fmt,...)
int errdetail(const char *fmt,...)
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
bool equal(const void *a, const void *b)
int ExecCleanTargetListLength(List *targetlist)
FdwRoutine * GetFdwRoutineForRelation(Relation relation, bool makecopy)
Assert(PointerIsAligned(start, uint64))
if(TABLE==NULL||TABLE_index==NULL)
List * lappend(List *list, void *datum)
List * list_concat(List *list1, const List *list2)
List * list_concat_copy(const List *list1, const List *list2)
List * lappend_oid(List *list, Oid datum)
List * lcons(void *datum, List *list)
List * list_delete_last(List *list)
bool list_member_oid(const List *list, Oid datum)
Node * get_typdefault(Oid typid)
Alias * makeAlias(const char *aliasname, List *colnames)
Const * makeNullConst(Oid consttype, int32 consttypmod, Oid constcollid)
Var * makeWholeRowVar(RangeTblEntry *rte, int varno, Index varlevelsup, bool allowScalar)
TargetEntry * makeTargetEntry(Expr *expr, AttrNumber resno, char *resname, bool resjunk)
TargetEntry * flatCopyTargetEntry(TargetEntry *src_tle)
char * pstrdup(const char *in)
void pfree(void *pointer)
void * palloc0(Size size)
Oid exprType(const Node *expr)
Oid exprCollation(const Node *expr)
Node * strip_implicit_coercions(Node *node)
#define query_tree_walker(q, w, c, f)
#define expression_tree_walker(n, w, c)
#define QTW_IGNORE_RC_SUBQUERIES
#define IsA(nodeptr, _type_)
#define castNode(_type_, nodeptr)
Node * coerce_null_to_domain(Oid typid, int32 typmod, Oid collation, int typlen, bool typbyval)
Node * coerce_to_target_type(ParseState *pstate, Node *expr, Oid exprtype, Oid targettype, int32 targettypmod, CoercionContext ccontext, CoercionForm cformat, int location)
ParseState * make_parsestate(ParseState *parentParseState)
ParseNamespaceItem * addRangeTableEntryForRelation(ParseState *pstate, Relation rel, int lockmode, Alias *alias, bool inh, bool inFromCl)
RTEPermissionInfo * getRTEPermissionInfo(List *rteperminfos, RangeTblEntry *rte)
RowMarkClause * get_parse_rowmark(Query *qry, Index rtindex)
TargetEntry * get_tle_by_resno(List *tlist, AttrNumber resno)
bool get_rte_attribute_is_dropped(RangeTblEntry *rte, AttrNumber attnum)
RTEPermissionInfo * addRTEPermissionInfo(List **rteperminfos, RangeTblEntry *rte)
#define ACL_SELECT_FOR_UPDATE
void applyLockingClause(Query *qry, Index rtindex, LockClauseStrength strength, LockWaitPolicy waitPolicy, bool pushedDown)
List * BuildOnConflictExcludedTargetlist(Relation targetrel, Index exclRelIndex)
#define rt_fetch(rangetable_index, rangetable)
FormData_pg_attribute * Form_pg_attribute
Oid getIdentitySequence(Relation rel, AttrNumber attnum, bool missing_ok)
#define lfirst_node(type, lc)
static int list_length(const List *l)
#define linitial_node(type, l)
#define foreach_delete_current(lst, var_or_cell)
#define foreach_node(type, var, lst)
int restrict_nonsystem_relation_kind
@ OVERRIDING_SYSTEM_VALUE
#define RelationGetRelid(relation)
#define RelationHasCheckOption(relation)
#define RelationHasSecurityInvoker(relation)
#define RelationGetDescr(relation)
#define RelationGetNumberOfAttributes(relation)
#define RelationGetRelationName(relation)
#define RelationHasCascadedCheckOption(relation)
#define RelationIsSecurityView(relation)
#define RULE_FIRES_ON_ORIGIN
#define RULE_FIRES_ON_REPLICA
static void markQueryForLocking(Query *qry, Node *jtnode, LockClauseStrength strength, LockWaitPolicy waitPolicy, bool pushedDown)
static Query * ApplyRetrieveRule(Query *parsetree, RewriteRule *rule, int rt_index, Relation relation, List *activeRIRs)
static Query * rewriteRuleAction(Query *parsetree, Query *rule_action, Node *rule_qual, int rt_index, CmdType event, bool *returning_flag)
static TargetEntry * process_matched_tle(TargetEntry *src_tle, TargetEntry *prior_tle, const char *attrName)
static bool fireRIRonSubLink(Node *node, fireRIRonSubLink_context *context)
static List * adjustJoinTreeList(Query *parsetree, bool removert, int rt_index)
void AcquireRewriteLocks(Query *parsetree, bool forExecute, bool forUpdatePushedDown)
bool view_has_instead_trigger(Relation view, CmdType event, List *mergeActionList)
static const char * view_cols_are_auto_updatable(Query *viewquery, Bitmapset *required_cols, Bitmapset **updatable_cols, char **non_updatable_col)
struct fireRIRonSubLink_context fireRIRonSubLink_context
static List * fireRules(Query *parsetree, int rt_index, CmdType event, List *locks, bool *instead_flag, bool *returning_flag, Query **qual_product)
static Query * CopyAndAddInvertedQual(Query *parsetree, Node *rule_qual, int rt_index, CmdType event)
int relation_is_updatable(Oid reloid, List *outer_reloids, bool include_triggers, Bitmapset *include_cols)
Query * get_view_query(Relation view)
static bool acquireLocksOnSubLinks(Node *node, acquireLocksOnSubLinks_context *context)
static bool rewriteValuesRTE(Query *parsetree, RangeTblEntry *rte, int rti, Relation target_relation, Bitmapset *unused_cols)
static Node * get_assignment_input(Node *node)
static List * RewriteQuery(Query *parsetree, List *rewrite_events, int orig_rt_length)
static Bitmapset * adjust_view_column_set(Bitmapset *cols, List *targetlist)
const char * view_query_is_auto_updatable(Query *viewquery, bool check_cols)
struct acquireLocksOnSubLinks_context acquireLocksOnSubLinks_context
static const char * view_col_is_auto_updatable(RangeTblRef *rtr, TargetEntry *tle)
static bool searchForDefault(RangeTblEntry *rte)
struct rewrite_event rewrite_event
static Query * fireRIRrules(Query *parsetree, List *activeRIRs)
static Query * rewriteTargetView(Query *parsetree, Relation view)
List * QueryRewrite(Query *parsetree)
static Node * expand_generated_columns_internal(Node *node, Relation rel, int rt_index, RangeTblEntry *rte, int result_relation)
static Bitmapset * findDefaultOnlyColumns(RangeTblEntry *rte)
static void rewriteValuesRTEToNulls(Query *parsetree, RangeTblEntry *rte)
Node * build_generation_expression(Relation rel, int attrno)
static List * matchLocks(CmdType event, Relation relation, int varno, Query *parsetree, bool *hasUpdate)
void error_view_not_updatable(Relation view, CmdType command, List *mergeActionList, const char *detail)
Node * build_column_default(Relation rel, int attrno)
static List * rewriteTargetListIU(List *targetList, CmdType commandType, OverridingKind override, Relation target_relation, RangeTblEntry *values_rte, int values_rte_index, Bitmapset **unused_values_attrnos)
Node * expand_generated_columns_in_expr(Node *node, Relation rel, int rt_index)
void ChangeVarNodes(Node *node, int rt_index, int new_index, int sublevels_up)
void OffsetVarNodes(Node *node, int offset, int sublevels_up)
bool checkExprHasSubLink(Node *node)
void CombineRangeTables(List **dst_rtable, List **dst_perminfos, List *src_rtable, List *src_perminfos)
void AddQual(Query *parsetree, Node *qual)
bool rangeTableEntry_used(Node *node, int rt_index, int sublevels_up)
Query * getInsertSelectQuery(Query *parsetree, Query ***subquery_ptr)
void AddInvertedQual(Query *parsetree, Node *qual)
Node * ReplaceVarsFromTargetList(Node *node, int target_varno, int sublevels_up, RangeTblEntry *target_rte, List *targetlist, int result_relation, ReplaceVarsNoMatchOption nomatch_option, int nomatch_varno, bool *outer_hasSubLinks)
@ REPLACEVARS_SUBSTITUTE_NULL
@ REPLACEVARS_CHANGE_VARNO
@ REPLACEVARS_REPORT_ERROR
CommonTableExpr * rewriteSearchAndCycle(CommonTableExpr *cte)
void get_row_security_policies(Query *root, RangeTblEntry *rte, int rt_index, List **securityQuals, List **withCheckOptions, bool *hasRowSecurity, bool *hasSubLinks)
void relation_close(Relation relation, LOCKMODE lockmode)
Relation try_relation_open(Oid relationId, LOCKMODE lockmode)
void check_stack_depth(void)
ExecForeignInsert_function ExecForeignInsert
ExecForeignUpdate_function ExecForeignUpdate
ExecForeignDelete_function ExecForeignDelete
IsForeignRelUpdatable_function IsForeignRelUpdatable
OnConflictExpr * onConflict
struct TableSampleClause * tablesample
LockClauseStrength strength
LockWaitPolicy waitPolicy
bool trig_update_instead_row
bool trig_delete_instead_row
bool trig_insert_instead_row
bool has_generated_virtual
#define FirstLowInvalidHeapAttributeNumber
void table_close(Relation relation, LOCKMODE lockmode)
Relation table_open(Oid relationId, LOCKMODE lockmode)
#define RESTRICT_RELKIND_VIEW
#define FirstNormalObjectId
int SessionReplicationRole
#define SESSION_REPLICATION_ROLE_REPLICA
Node * TupleDescGetDefault(TupleDesc tupdesc, AttrNumber attnum)
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
String * makeString(char *str)
bool contain_vars_of_level(Node *node, int levelsup)
static struct rule * rules