diff options
| author | vvvv <[email protected]> | 2025-10-24 14:59:50 +0300 |
|---|---|---|
| committer | vvvv <[email protected]> | 2025-10-24 15:29:24 +0300 |
| commit | 5b0d18921f2a509d8363c40a5ca208dfed026287 (patch) | |
| tree | d1369c696d3a9e9a65b68d9208e198269a48cfbc /yql/essentials/parser/pg_wrapper/postgresql/src/backend/rewrite/rewriteHandler.c | |
| parent | e7fbdb6e81ae4a296e710b133de7a2a04b31bbc4 (diff) | |
YQL-20567 upgrade PG up to 16.10 & fix instructions
init
commit_hash:81aba13295273281d19d2d332a48ff1c44977447
Diffstat (limited to 'yql/essentials/parser/pg_wrapper/postgresql/src/backend/rewrite/rewriteHandler.c')
| -rw-r--r-- | yql/essentials/parser/pg_wrapper/postgresql/src/backend/rewrite/rewriteHandler.c | 161 |
1 files changed, 109 insertions, 52 deletions
diff --git a/yql/essentials/parser/pg_wrapper/postgresql/src/backend/rewrite/rewriteHandler.c b/yql/essentials/parser/pg_wrapper/postgresql/src/backend/rewrite/rewriteHandler.c index 2510ce79c6e..57f075de394 100644 --- a/yql/essentials/parser/pg_wrapper/postgresql/src/backend/rewrite/rewriteHandler.c +++ b/yql/essentials/parser/pg_wrapper/postgresql/src/backend/rewrite/rewriteHandler.c @@ -41,6 +41,7 @@ #include "rewrite/rewriteManip.h" #include "rewrite/rewriteSearchCycle.h" #include "rewrite/rowsecurity.h" +#include "tcop/tcopprot.h" #include "utils/builtins.h" #include "utils/lsyscache.h" #include "utils/rel.h" @@ -58,6 +59,12 @@ typedef struct acquireLocksOnSubLinks_context bool for_execute; /* AcquireRewriteLocks' forExecute param */ } acquireLocksOnSubLinks_context; +typedef struct fireRIRonSubLink_context +{ + List *activeRIRs; + bool hasRowSecurity; +} fireRIRonSubLink_context; + static bool acquireLocksOnSubLinks(Node *node, acquireLocksOnSubLinks_context *context); static Query *rewriteRuleAction(Query *parsetree, @@ -997,23 +1004,11 @@ rewriteTargetListIU(List *targetList, if (commandType == CMD_INSERT) new_tle = NULL; else - { - new_expr = (Node *) makeConst(att_tup->atttypid, - -1, - att_tup->attcollation, - att_tup->attlen, - (Datum) 0, - true, /* isnull */ - att_tup->attbyval); - /* this is to catch a NOT NULL domain constraint */ - new_expr = coerce_to_domain(new_expr, - InvalidOid, -1, - att_tup->atttypid, - COERCION_IMPLICIT, - COERCE_IMPLICIT_CAST, - -1, - false); - } + new_expr = coerce_null_to_domain(att_tup->atttypid, + att_tup->atttypmod, + att_tup->attcollation, + att_tup->attlen, + att_tup->attbyval); } if (new_expr) @@ -1575,21 +1570,11 @@ rewriteValuesRTE(Query *parsetree, RangeTblEntry *rte, int rti, continue; } - new_expr = (Node *) makeConst(att_tup->atttypid, - -1, - att_tup->attcollation, - att_tup->attlen, - (Datum) 0, - true, /* isnull */ - att_tup->attbyval); - /* this is to catch a NOT NULL domain constraint */ - new_expr = coerce_to_domain(new_expr, - InvalidOid, -1, - att_tup->atttypid, - COERCION_IMPLICIT, - COERCE_IMPLICIT_CAST, - -1, - false); + new_expr = coerce_null_to_domain(att_tup->atttypid, + att_tup->atttypmod, + att_tup->attcollation, + att_tup->attlen, + att_tup->attbyval); } newList = lappend(newList, new_expr); } @@ -1740,6 +1725,14 @@ ApplyRetrieveRule(Query *parsetree, if (rule->qual != NULL) elog(ERROR, "cannot handle qualified ON SELECT rule"); + /* Check if the expansion of non-system views are restricted */ + if (unlikely((restrict_nonsystem_relation_kind & RESTRICT_RELKIND_VIEW) != 0 && + RelationGetRelid(relation) >= FirstNormalObjectId)) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("access to non-system view \"%s\" is restricted", + RelationGetRelationName(relation)))); + if (rt_index == parsetree->resultRelation) { /* @@ -1840,6 +1833,12 @@ ApplyRetrieveRule(Query *parsetree, rule_action = fireRIRrules(rule_action, activeRIRs); /* + * Make sure the query is marked as having row security if the view query + * does. + */ + parsetree->hasRowSecurity |= rule_action->hasRowSecurity; + + /* * Now, plug the view query in as a subselect, converting the relation's * original RTE to a subquery RTE. */ @@ -1952,7 +1951,7 @@ markQueryForLocking(Query *qry, Node *jtnode, * the SubLink's subselect link with the possibly-rewritten subquery. */ static bool -fireRIRonSubLink(Node *node, List *activeRIRs) +fireRIRonSubLink(Node *node, fireRIRonSubLink_context *context) { if (node == NULL) return false; @@ -1962,7 +1961,13 @@ fireRIRonSubLink(Node *node, List *activeRIRs) /* Do what we came for */ sub->subselect = (Node *) fireRIRrules((Query *) sub->subselect, - activeRIRs); + context->activeRIRs); + + /* + * Remember if any of the sublinks have row security. + */ + context->hasRowSecurity |= ((Query *) sub->subselect)->hasRowSecurity; + /* Fall through to process lefthand args of SubLink */ } @@ -1971,7 +1976,7 @@ fireRIRonSubLink(Node *node, List *activeRIRs) * subselects of subselects for us. */ return expression_tree_walker(node, fireRIRonSubLink, - (void *) activeRIRs); + (void *) context); } @@ -2032,6 +2037,13 @@ fireRIRrules(Query *parsetree, List *activeRIRs) if (rte->rtekind == RTE_SUBQUERY) { rte->subquery = fireRIRrules(rte->subquery, activeRIRs); + + /* + * While we are here, make sure the query is marked as having row + * security if any of its subqueries do. + */ + parsetree->hasRowSecurity |= rte->subquery->hasRowSecurity; + continue; } @@ -2145,6 +2157,12 @@ fireRIRrules(Query *parsetree, List *activeRIRs) cte->ctequery = (Node *) fireRIRrules((Query *) cte->ctequery, activeRIRs); + + /* + * While we are here, make sure the query is marked as having row + * security if any of its CTEs do. + */ + parsetree->hasRowSecurity |= ((Query *) cte->ctequery)->hasRowSecurity; } /* @@ -2152,9 +2170,22 @@ fireRIRrules(Query *parsetree, List *activeRIRs) * the rtable and cteList. */ if (parsetree->hasSubLinks) - query_tree_walker(parsetree, fireRIRonSubLink, (void *) activeRIRs, + { + fireRIRonSubLink_context context; + + context.activeRIRs = activeRIRs; + context.hasRowSecurity = false; + + query_tree_walker(parsetree, fireRIRonSubLink, (void *) &context, QTW_IGNORE_RC_SUBQUERIES); + /* + * Make sure the query is marked as having row security if any of its + * sublinks do. + */ + parsetree->hasRowSecurity |= context.hasRowSecurity; + } + /* * Apply any row-level security policies. We do this last because it * requires special recursion detection if the new quals have sublink @@ -2193,6 +2224,7 @@ fireRIRrules(Query *parsetree, List *activeRIRs) if (hasSubLinks) { acquireLocksOnSubLinks_context context; + fireRIRonSubLink_context fire_context; /* * Recursively process the new quals, checking for infinite @@ -2223,11 +2255,21 @@ fireRIRrules(Query *parsetree, List *activeRIRs) * Now that we have the locks on anything added by * get_row_security_policies, fire any RIR rules for them. */ + fire_context.activeRIRs = activeRIRs; + fire_context.hasRowSecurity = false; + expression_tree_walker((Node *) securityQuals, - fireRIRonSubLink, (void *) activeRIRs); + fireRIRonSubLink, (void *) &fire_context); expression_tree_walker((Node *) withCheckOptions, - fireRIRonSubLink, (void *) activeRIRs); + fireRIRonSubLink, (void *) &fire_context); + + /* + * We can ignore the value of fire_context.hasRowSecurity + * since we only reach this code in cases where hasRowSecurity + * is already true. + */ + Assert(hasRowSecurity); activeRIRs = list_delete_last(activeRIRs); } @@ -2963,7 +3005,7 @@ relation_is_updatable(Oid reloid, * * This is used with simply-updatable views to map column-permissions sets for * the view columns onto the matching columns in the underlying base relation. - * The targetlist is expected to be a list of plain Vars of the underlying + * Relevant entries in the targetlist must be plain Vars of the underlying * relation (as per the checks above in view_query_is_auto_updatable). */ static Bitmapset * @@ -3063,6 +3105,10 @@ rewriteTargetView(Query *parsetree, Relation view) */ viewquery = copyObject(get_view_query(view)); + /* Locate RTE and perminfo describing the view in the outer query */ + view_rte = rt_fetch(parsetree->resultRelation, parsetree->rtable); + view_perminfo = getRTEPermissionInfo(parsetree->rteperminfos, view_rte); + /* The view must be updatable, else fail */ auto_update_detail = view_query_is_auto_updatable(viewquery, @@ -3104,18 +3150,35 @@ rewriteTargetView(Query *parsetree, Relation view) } } + /* Check if the expansion of non-system views are restricted */ + if (unlikely((restrict_nonsystem_relation_kind & RESTRICT_RELKIND_VIEW) != 0 && + RelationGetRelid(view) >= FirstNormalObjectId)) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("access to non-system view \"%s\" is restricted", + RelationGetRelationName(view)))); + /* - * For INSERT/UPDATE the modified columns must all be updatable. Note that - * we get the modified columns from the query's targetlist, not from the - * result RTE's insertedCols and/or updatedCols set, since - * rewriteTargetListIU may have added additional targetlist entries for - * view defaults, and these must also be updatable. + * For INSERT/UPDATE the modified columns must all be updatable. */ if (parsetree->commandType != CMD_DELETE) { - Bitmapset *modified_cols = NULL; + Bitmapset *modified_cols; char *non_updatable_col; + /* + * Compute the set of modified columns as those listed in the result + * RTE's insertedCols and/or updatedCols sets plus those that are + * targets of the query's targetlist(s). We must consider the query's + * targetlist because rewriteTargetListIU may have added additional + * targetlist entries for view defaults, and these must also be + * updatable. But rewriteTargetListIU can also remove entries if they + * are DEFAULT markers and the column's default is NULL, so + * considering only the targetlist would also be wrong. + */ + modified_cols = bms_union(view_perminfo->insertedCols, + view_perminfo->updatedCols); + foreach(lc, parsetree->targetList) { TargetEntry *tle = (TargetEntry *) lfirst(lc); @@ -3173,9 +3236,6 @@ rewriteTargetView(Query *parsetree, Relation view) } } - /* Locate RTE describing the view in the outer query */ - view_rte = rt_fetch(parsetree->resultRelation, parsetree->rtable); - /* * If we get here, view_query_is_auto_updatable() has verified that the * view contains a single base relation. @@ -3270,10 +3330,7 @@ rewriteTargetView(Query *parsetree, Relation view) * Note: the original view's RTEPermissionInfo remains in the query's * rteperminfos so that the executor still performs appropriate * permissions checks for the query caller's use of the view. - */ - view_perminfo = getRTEPermissionInfo(parsetree->rteperminfos, view_rte); - - /* + * * Disregard the perminfo in viewquery->rteperminfos that the base_rte * would currently be pointing at, because we'd like it to point now to a * new one that will be filled below. Must set perminfoindex to 0 to not |
