162 foreach(l, parsetree->
rtable)
173 switch (
rte->rtekind)
193 lockmode =
rte->rellockmode;
196 lockmode =
rte->rellockmode;
223 foreach(ll,
rte->joinaliasvars)
254 elog(
ERROR,
"unexpected varno %d in JOIN RTE %d",
301 if (parsetree->hasSubLinks)
466 if (parsetree->hasSubLinks && !
sub_action->hasSubLinks)
472 switch (
rte->rtekind)
508 sub_action->hasRowSecurity |= parsetree->hasRowSecurity;
546 errmsg(
"conditional UNION/INTERSECT/EXCEPT statements are not implemented")));
555 if (parsetree->hasSubLinks && !
sub_action->hasSubLinks)
590 errmsg(
"WITH query name \"%s\" appears in both a rule action and the query being rewritten",
602 sub_action->hasRecursive |= parsetree->hasRecursive;
603 sub_action->hasModifyingCTE |= parsetree->hasModifyingCTE;
620 errmsg(
"INSERT ... SELECT rule actions are not supported for queries having data-modifying statements in WITH")));
674 errmsg(
"cannot have RETURNING lists in multiple rules")));
678 parsetree->resultRelation,
689 rule_action->returningOldAlias = parsetree->returningOldAlias;
690 rule_action->returningNewAlias = parsetree->returningNewAlias;
696 if (parsetree->hasSubLinks && !
rule_action->hasSubLinks)
725 rtr->rtindex == rt_index)
806 foreach(
temp, targetList)
911 errmsg(
"cannot insert a non-DEFAULT value into column \"%s\"",
913 errdetail(
"Column \"%s\" is an identity column defined as GENERATED ALWAYS.",
915 errhint(
"Use OVERRIDING SYSTEM VALUE to override.")));
951 errmsg(
"cannot insert a non-DEFAULT value into column \"%s\"",
953 errdetail(
"Column \"%s\" is a generated column.",
978 errmsg(
"column \"%s\" can only be updated to DEFAULT",
980 errdetail(
"Column \"%s\" is an identity column defined as GENERATED ALWAYS.",
986 errmsg(
"column \"%s\" can only be updated to DEFAULT",
988 errdetail(
"Column \"%s\" is a generated column.",
1122 errmsg(
"multiple assignments to same column \"%s\"",
1140 errmsg(
"multiple assignments to same column \"%s\"",
1257 elog(
ERROR,
"default expression not found for attribute %d of relation \"%s\"",
1289 errmsg(
"column \"%s\" is of type %s"
1290 " but default expression is of type %s",
1294 errhint(
"You will need to rewrite or cast the expression.")));
1306 foreach(
lc,
rte->values_lists)
1333 foreach(
lc,
rte->values_lists)
1457 if (var->
varno == rti)
1483 parsetree->resultRelation, parsetree, &
hasUpdate);
1509 foreach(
lc,
rte->values_lists)
1546 elog(
ERROR,
"cannot set value in column %d to DEFAULT",
i);
1607 foreach(
lc,
rte->values_lists)
1655 if (parsetree->resultRelation != varno)
1661 for (
i = 0;
i < nlocks;
i++)
1693 errmsg(
"cannot execute MERGE on relation \"%s\"",
1695 errdetail(
"MERGE is not supported for relations with rules."));
1726 elog(
ERROR,
"expected just one rule action");
1728 elog(
ERROR,
"cannot handle qualified ON SELECT rule");
1735 errmsg(
"access to non-system view \"%s\" is restricted",
1738 if (rt_index == parsetree->resultRelation)
1784 parsetree->resultRelation, 0);
1803 elog(
ERROR,
"unrecognized commandType: %d",
1843 parsetree->hasRowSecurity |=
rule_action->hasRowSecurity;
1919 strength, waitPolicy,
true);
1939 elog(
ERROR,
"unrecognized node type: %d",
2010 if (cte->search_clause || cte->cycle_clause)
2048 parsetree->hasRowSecurity |=
rte->subquery->hasRowSecurity;
2090 if (rt_index != parsetree->resultRelation &&
2098 if (rt_index == parsetree->resultRelation &&
2115 for (
i = 0;
i <
rules->numLocks;
i++)
2134 errmsg(
"infinite recursion detected in rules for relation \"%s\"",
2168 parsetree->hasRowSecurity |= ((
Query *) cte->
ctequery)->hasRowSecurity;
2175 if (parsetree->hasSubLinks)
2205 bool hasRowSecurity;
2239 errmsg(
"infinite recursion detected in policy for relation \"%s\"",
2287 rte->securityQuals);
2290 parsetree->withCheckOptions);
2298 parsetree->hasRowSecurity =
true;
2300 parsetree->hasSubLinks =
true;
2352 parsetree->resultRelation,
2357 &parsetree->hasSubLinks);
2499 elog(
ERROR,
"invalid _RETURN rule action specification");
2505 elog(
ERROR,
"failed to find _RETURN rule for view");
2545 switch (action->commandType)
2563 elog(
ERROR,
"unrecognized commandType: %d", action->commandType);
2569 elog(
ERROR,
"unrecognized CmdType: %d", (
int) event);
2602 return gettext_noop(
"Junk view columns are not updatable.");
2607 return gettext_noop(
"View columns that are not columns of their base relation are not updatable.");
2610 return gettext_noop(
"View columns that refer to system columns are not updatable.");
2613 return gettext_noop(
"View columns that return whole-row references are not updatable.");
2674 return gettext_noop(
"Views containing DISTINCT are not automatically updatable.");
2677 return gettext_noop(
"Views containing GROUP BY are not automatically updatable.");
2680 return gettext_noop(
"Views containing HAVING are not automatically updatable.");
2683 return gettext_noop(
"Views containing UNION, INTERSECT, or EXCEPT are not automatically updatable.");
2686 return gettext_noop(
"Views containing WITH are not automatically updatable.");
2689 return gettext_noop(
"Views containing LIMIT or OFFSET are not automatically updatable.");
2701 return gettext_noop(
"Views that return aggregate functions are not automatically updatable.");
2704 return gettext_noop(
"Views that return window functions are not automatically updatable.");
2707 return gettext_noop(
"Views that return set-returning functions are not automatically updatable.");
2714 return gettext_noop(
"Views that do not select from a single table or view are not automatically updatable.");
2718 return gettext_noop(
"Views that do not select from a single table or view are not automatically updatable.");
2726 return gettext_noop(
"Views that do not select from a single table or view are not automatically updatable.");
2729 return gettext_noop(
"Views containing TABLESAMPLE are not automatically updatable.");
2753 return gettext_noop(
"Views that have no updatable columns are not automatically updatable.");
2876#define ALL_EVENTS ((1 << CMD_INSERT) | (1 << CMD_UPDATE) | (1 << CMD_DELETE))
2937 if (
trigDesc->trig_insert_instead_row)
2939 if (
trigDesc->trig_update_instead_row)
2941 if (
trigDesc->trig_delete_instead_row)
3070 foreach(
lc, targetlist)
3099 elog(
ERROR,
"attribute number %d not found in view targetlist",
3124 List *mergeActionList,
3134 errmsg(
"cannot insert into view \"%s\"",
3137 errhint(
"To enable inserting into the view, provide an INSTEAD OF INSERT trigger or an unconditional ON INSERT DO INSTEAD rule."));
3142 errmsg(
"cannot update view \"%s\"",
3145 errhint(
"To enable updating the view, provide an INSTEAD OF UPDATE trigger or an unconditional ON UPDATE DO INSTEAD rule."));
3150 errmsg(
"cannot delete from view \"%s\"",
3153 errhint(
"To enable deleting from the view, provide an INSTEAD OF DELETE trigger or an unconditional ON DELETE DO INSTEAD rule."));
3163 switch (action->commandType)
3169 errmsg(
"cannot insert into view \"%s\"",
3172 errhint(
"To enable inserting into the view using MERGE, provide an INSTEAD OF INSERT trigger."));
3178 errmsg(
"cannot update view \"%s\"",
3181 errhint(
"To enable updating the view using MERGE, provide an INSTEAD OF UPDATE trigger."));
3187 errmsg(
"cannot delete from view \"%s\"",
3190 errhint(
"To enable deleting from the view using MERGE, provide an INSTEAD OF DELETE trigger."));
3195 elog(
ERROR,
"unrecognized commandType: %d", action->commandType);
3201 elog(
ERROR,
"unrecognized CmdType: %d", (
int) command);
3275 errmsg(
"access to non-system view \"%s\" is restricted",
3365 errmsg(
"cannot insert into column \"%s\" of view \"%s\"",
3373 errmsg(
"cannot update column \"%s\" of view \"%s\"",
3381 errmsg(
"cannot merge into column \"%s\" of view \"%s\"",
3409 errmsg(
"cannot merge into view \"%s\"",
3411 errdetail(
"MERGE is not supported for views with INSTEAD OF triggers for some actions but not all."),
3412 errhint(
"To enable merging into the view, either provide a full set of INSTEAD OF triggers or drop the existing INSTEAD OF triggers."));
3571 parsetree = (
Query *)
3573 parsetree->resultRelation,
3589 parsetree->resultRelation,
3618 elog(
ERROR,
"attribute number %d not found in view targetlist",
3638 elog(
ERROR,
"attribute number %d not found in view targetlist",
3675 elog(
ERROR,
"attribute number %d not found in view targetlist",
3732 &parsetree->hasSubLinks);
3783 if (!parsetree->hasSubLinks)
3809 if (parsetree->withCheckOptions !=
NIL)
3839 wco->cascaded = cascaded;
3841 parsetree->withCheckOptions =
lcons(
wco,
3842 parsetree->withCheckOptions);
3855 if (!parsetree->hasSubLinks &&
3887 bool instead =
false;
3888 bool returning =
false;
3943 errmsg(
"DO INSTEAD NOTIFY rules are not supported for data-modifying statements in WITH")));
3946 Assert(!ctequery->canSetTag);
3954 errmsg(
"DO INSTEAD NOTHING rules are not supported for data-modifying statements in WITH")));
3968 errmsg(
"conditional DO INSTEAD rules are not supported for data-modifying statements in WITH")));
3972 errmsg(
"DO ALSO rules are not supported for data-modifying statements in WITH")));
3977 errmsg(
"multi-statement DO INSTEAD rules are not supported for data-modifying statements in WITH")));
3992 int result_relation;
4002 result_relation = parsetree->resultRelation;
4003 Assert(result_relation != 0);
4040 elog(
ERROR,
"more than one VALUES RTE found");
4055 parsetree->override,
4072 parsetree->override,
4083 parsetree->override,
4094 parsetree->override,
4109 switch (action->commandType)
4121 action->targetList =
4123 action->commandType,
4129 elog(
ERROR,
"unrecognized commandType: %d", action->commandType);
4139 elog(
ERROR,
"unrecognized commandType: %d", (
int) event);
4145 result_relation, parsetree, &
hasUpdate);
4203 elog(
ERROR,
"failed to find VALUES RTE in product query");
4238 gettext_noop(
"Views with conditional DO INSTEAD rules are not automatically updatable."));
4283 rev->event == event)
4286 errmsg(
"infinite recursion detected in rules for relation \"%s\"",
4336 errmsg(
"cannot perform INSERT RETURNING on relation \"%s\"",
4338 errhint(
"You need an unconditional ON INSERT DO INSTEAD rule with a RETURNING clause.")));
4343 errmsg(
"cannot perform UPDATE RETURNING on relation \"%s\"",
4345 errhint(
"You need an unconditional ON UPDATE DO INSTEAD rule with a RETURNING clause.")));
4350 errmsg(
"cannot perform DELETE RETURNING on relation \"%s\"",
4352 errhint(
"You need an unconditional ON DELETE DO INSTEAD rule with a RETURNING clause.")));
4355 elog(
ERROR,
"unrecognized commandType: %d",
4370 errmsg(
"INSERT with ON CONFLICT clause cannot be used with table that has INSERT or UPDATE rules")));
4427 errmsg(
"WITH cannot be used in a query that is rewritten by rules into multiple queries")));
4460 for (
int i = 0;
i < tupdesc->
natts;
i++)
4532 if (defexpr ==
NULL)
4533 elog(
ERROR,
"no generation expression found for column number %d of table \"%s\"",
4546 ce->arg = (
Expr *) defexpr;
4581 Assert(parsetree->canSetTag);
4606 results =
lappend(results, query);
4635 Assert(query->canSetTag);
4638#ifndef USE_ASSERT_CHECKING
4644 Assert(!query->canSetTag);
#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)
#define Assert(condition)
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)
#define palloc_object(type)
FdwRoutine * GetFdwRoutineForRelation(Relation relation, bool makecopy)
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_current_index(var_or_cell)
#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 List * RewriteQuery(Query *parsetree, List *rewrite_events, int orig_rt_length, int num_ctes_processed)
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)
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 Bitmapset * adjust_view_column_set(Bitmapset *cols, List *targetlist)
const char * view_query_is_auto_updatable(Query *viewquery, bool check_cols)
static const char * view_col_is_auto_updatable(RangeTblRef *rtr, TargetEntry *tle)
static bool searchForDefault(RangeTblEntry *rte)
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
LockClauseStrength strength
LockWaitPolicy waitPolicy
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