Apache AGE中RTE到PNSI结构的转换

fquxozlt  于 2023-06-21  发布在  Apache
关注(0)|答案(1)|浏览(79)

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以使这个错误不会发生呢?

pjngdqdw

pjngdqdw1#

发生此错误的原因是,查询分析器未从ParseState接收到其属性“rteperminfos”中的RTE权限信息,而ParseState的属性“p_rteperminfos”包含此信息。
您可以查看Postgres 16中关于查询关系权限检查here的所有更改。

相关问题