Matheus Farias
Matheus Farias

Reputation: 715

Changing from RTE to PNSI struct in Apache AGE

Postgres source code has changed some struct members between versions. In Apache AGE source code, the RTE members are used a lot and we are trying to verify if it's possible to change RTE to PNSI in some cases. For instance, some of these changes in RTE and PNSI from PG13 to PG16 are:

----------------------------------
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

----------------------------------

One significant change is the perinfoindex member. In one section of AGE's code, it occurs an error with the perinfoindex attribute. We were debugging the code an found out that this error happens inside markVarForSelectPriv, which invokes markRTEForSelectPriv, and then calls getRTEPermissionInfo where the error message "invalid perminfoindex 1 in RTE with relid..." occurs.

Here is AGE's function where all of this happens:

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;
}

This error does not occur in previous versions of AGE, and since the struct members where modified, how to properly modify the RTE's perminfo so that this error does not occur?

Upvotes: 1

Views: 70

Answers (1)

Wendel
Wendel

Reputation: 650

This error occurred because the query parser did not receive the RTE permission information in its property 'rteperminfos' from the ParseState, which has the property 'p_rteperminfos' containing this information.

You can see all changes from Postgres 16 regarding query relation permission checking here.

Upvotes: 1

Related Questions