Postgres源代码在不同版本之间更改了一些结构成员。在Apache AGE源代码中,RTE成员被大量使用,我们正在尝试验证在某些情况下是否可以将RTE更改为PNSI。例如,从PG13到PG16的RTE和PNSI的一些变化是:
----------------------------------
RTE <RangeTblEntry>
Added:
+ perinfoindex: Index
+ join_using_alias: Alias
Removed:
- requiredPerms: AclMode
- checkAsUser: Oid
- selectedCols: Bitmapset*
- insertedCols: Bitmapset*
- updatedCols: Bitmapset*
- extraUpdatedCols: Bitmapset*
----------------------------------
PNSI <ParseNamespaceItem>
Added:
+ p_names: *Alias
+ p_perminfo: *RTEPermissioninfo
----------------------------------
一个重要的变化是perinfoindex
成员。在AGE代码的一个部分中,perinfoindex
属性发生错误。我们在调试代码时发现这个错误发生在markVarForSelectPriv
内部,它调用markRTEForSelectPriv
,然后调用getRTEPermissionInfo
,在那里出现错误消息“invalid perminfoindex 1 in RTE with relid...”。
下面是AGE的函数,所有这些都发生在这里:
static List *expand_pnsi_attrs(ParseState *pstate, ParseNamespaceItem *pnsi,
int sublevels_up, bool require_col_privs, int location)
{
RangeTblEntry *rte = pnsi->p_rte;
RTEPermissionInfo *perminfo = pnsi->p_perminfo;
List *names, *vars;
ListCell *name, *var;
List *te_list = NIL;
int var_prefix_len = strlen(AGE_DEFAULT_VARNAME_PREFIX);
int alias_prefix_len = strlen(AGE_DEFAULT_ALIAS_PREFIX);
expandRTE(rte, pnsi->p_rtindex, sublevels_up, location, false, &names, &vars);
/*
* Require read access to the table. This is normally redundant with the
* markVarForSelectPriv calls below, but not if the table has zero
* columns.
*/
if (rte->rtekind == RTE_RELATION)
{
Assert(perminfo != NULL);
perminfo->requiredPerms |= ACL_SELECT;
}
/* iterate through the variables */
forboth(name, names, var, vars)
{
char *label = strVal(lfirst(name));
Var *varnode = (Var *)lfirst(var);
TargetEntry *te;
/* we want to skip our "hidden" variables */
if (strncmp(AGE_DEFAULT_VARNAME_PREFIX, label, var_prefix_len) == 0)
continue;
/* we want to skip out "hidden" aliases */
if (strncmp(AGE_DEFAULT_ALIAS_PREFIX, label, alias_prefix_len) == 0)
continue;
/* add this variable to the list */
te = makeTargetEntry((Expr *)varnode,
(AttrNumber)pstate->p_next_resno++, label, false);
te_list = lappend(te_list, te);
/* Require read access to each column */
markVarForSelectPriv(pstate, varnode);
}
Assert(name == NULL && var == NULL); /* lists not the same length? */
return te_list;
}
这个错误在以前版本的AGE中不会发生,既然结构体成员被修改了,那么如何正确地修改RTE的perminfo以使这个错误不会发生呢?
1条答案
按热度按时间pjngdqdw1#
发生此错误的原因是,查询分析器未从ParseState接收到其属性“rteperminfos”中的RTE权限信息,而ParseState的属性“p_rteperminfos”包含此信息。
您可以查看Postgres 16中关于查询关系权限检查here的所有更改。