Header And Logo

PostgreSQL
| The world's most advanced open source database.

Functions

pg_db_role_setting.c File Reference

#include "postgres.h"
#include "access/genam.h"
#include "access/heapam.h"
#include "access/htup_details.h"
#include "catalog/indexing.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_db_role_setting.h"
#include "utils/fmgroids.h"
#include "utils/rel.h"
#include "utils/tqual.h"
Include dependency graph for pg_db_role_setting.c:

Go to the source code of this file.

Functions

void AlterSetting (Oid databaseid, Oid roleid, VariableSetStmt *setstmt)
void DropSetting (Oid databaseid, Oid roleid)
void ApplySetting (Oid databaseid, Oid roleid, Relation relsetting, GucSource source)

Function Documentation

void AlterSetting ( Oid  databaseid,
Oid  roleid,
VariableSetStmt setstmt 
)

Definition at line 24 of file pg_db_role_setting.c.

References Anum_pg_db_role_setting_setconfig, Anum_pg_db_role_setting_setdatabase, Anum_pg_db_role_setting_setrole, BTEqualStrategyNumber, CatalogUpdateIndexes(), DatumGetArrayTypeP, DbRoleSettingDatidRolidIndexId, DbRoleSettingRelationId, ExtractSetVariableArgs(), GUCArrayAdd(), GUCArrayDelete(), GUCArrayReset(), heap_close, heap_form_tuple(), heap_getattr, heap_modify_tuple(), heap_open(), HeapTupleIsValid, InvokeObjectPostAlterHookArg, VariableSetStmt::kind, VariableSetStmt::name, NoLock, NULL, ObjectIdGetDatum, PointerGetDatum, RelationGetDescr, RowExclusiveLock, ScanKeyInit(), simple_heap_delete(), simple_heap_insert(), simple_heap_update(), SnapshotNow, systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, values, and VAR_RESET_ALL.

Referenced by AlterDatabaseSet(), and AlterRoleSet().

{
    char       *valuestr;
    HeapTuple   tuple;
    Relation    rel;
    ScanKeyData scankey[2];
    SysScanDesc scan;

    valuestr = ExtractSetVariableArgs(setstmt);

    /* Get the old tuple, if any. */

    rel = heap_open(DbRoleSettingRelationId, RowExclusiveLock);
    ScanKeyInit(&scankey[0],
                Anum_pg_db_role_setting_setdatabase,
                BTEqualStrategyNumber, F_OIDEQ,
                ObjectIdGetDatum(databaseid));
    ScanKeyInit(&scankey[1],
                Anum_pg_db_role_setting_setrole,
                BTEqualStrategyNumber, F_OIDEQ,
                ObjectIdGetDatum(roleid));
    scan = systable_beginscan(rel, DbRoleSettingDatidRolidIndexId, true,
                              SnapshotNow, 2, scankey);
    tuple = systable_getnext(scan);

    /*
     * There are three cases:
     *
     * - in RESET ALL, request GUC to reset the settings array and update the
     * catalog if there's anything left, delete it otherwise
     *
     * - in other commands, if there's a tuple in pg_db_role_setting, update
     * it; if it ends up empty, delete it
     *
     * - otherwise, insert a new pg_db_role_setting tuple, but only if the
     * command is not RESET
     */
    if (setstmt->kind == VAR_RESET_ALL)
    {
        if (HeapTupleIsValid(tuple))
        {
            ArrayType  *new = NULL;
            Datum       datum;
            bool        isnull;

            datum = heap_getattr(tuple, Anum_pg_db_role_setting_setconfig,
                                 RelationGetDescr(rel), &isnull);

            if (!isnull)
                new = GUCArrayReset(DatumGetArrayTypeP(datum));

            if (new)
            {
                Datum       repl_val[Natts_pg_db_role_setting];
                bool        repl_null[Natts_pg_db_role_setting];
                bool        repl_repl[Natts_pg_db_role_setting];
                HeapTuple   newtuple;

                memset(repl_repl, false, sizeof(repl_repl));

                repl_val[Anum_pg_db_role_setting_setconfig - 1] =
                    PointerGetDatum(new);
                repl_repl[Anum_pg_db_role_setting_setconfig - 1] = true;
                repl_null[Anum_pg_db_role_setting_setconfig - 1] = false;

                newtuple = heap_modify_tuple(tuple, RelationGetDescr(rel),
                                             repl_val, repl_null, repl_repl);
                simple_heap_update(rel, &tuple->t_self, newtuple);

                /* Update indexes */
                CatalogUpdateIndexes(rel, newtuple);
            }
            else
                simple_heap_delete(rel, &tuple->t_self);
        }
    }
    else if (HeapTupleIsValid(tuple))
    {
        Datum       repl_val[Natts_pg_db_role_setting];
        bool        repl_null[Natts_pg_db_role_setting];
        bool        repl_repl[Natts_pg_db_role_setting];
        HeapTuple   newtuple;
        Datum       datum;
        bool        isnull;
        ArrayType  *a;

        memset(repl_repl, false, sizeof(repl_repl));
        repl_repl[Anum_pg_db_role_setting_setconfig - 1] = true;
        repl_null[Anum_pg_db_role_setting_setconfig - 1] = false;

        /* Extract old value of setconfig */
        datum = heap_getattr(tuple, Anum_pg_db_role_setting_setconfig,
                             RelationGetDescr(rel), &isnull);
        a = isnull ? NULL : DatumGetArrayTypeP(datum);

        /* Update (valuestr is NULL in RESET cases) */
        if (valuestr)
            a = GUCArrayAdd(a, setstmt->name, valuestr);
        else
            a = GUCArrayDelete(a, setstmt->name);

        if (a)
        {
            repl_val[Anum_pg_db_role_setting_setconfig - 1] =
                PointerGetDatum(a);

            newtuple = heap_modify_tuple(tuple, RelationGetDescr(rel),
                                         repl_val, repl_null, repl_repl);
            simple_heap_update(rel, &tuple->t_self, newtuple);

            /* Update indexes */
            CatalogUpdateIndexes(rel, newtuple);
        }
        else
            simple_heap_delete(rel, &tuple->t_self);
    }
    else if (valuestr)
    {
        /* non-null valuestr means it's not RESET, so insert a new tuple */
        HeapTuple   newtuple;
        Datum       values[Natts_pg_db_role_setting];
        bool        nulls[Natts_pg_db_role_setting];
        ArrayType  *a;

        memset(nulls, false, sizeof(nulls));

        a = GUCArrayAdd(NULL, setstmt->name, valuestr);

        values[Anum_pg_db_role_setting_setdatabase - 1] =
            ObjectIdGetDatum(databaseid);
        values[Anum_pg_db_role_setting_setrole - 1] = ObjectIdGetDatum(roleid);
        values[Anum_pg_db_role_setting_setconfig - 1] = PointerGetDatum(a);
        newtuple = heap_form_tuple(RelationGetDescr(rel), values, nulls);

        simple_heap_insert(rel, newtuple);

        /* Update indexes */
        CatalogUpdateIndexes(rel, newtuple);
    }

    InvokeObjectPostAlterHookArg(DbRoleSettingRelationId,
                                 databaseid, 0, roleid, false);

    systable_endscan(scan);

    /* Close pg_db_role_setting, but keep lock till commit */
    heap_close(rel, NoLock);
}

void ApplySetting ( Oid  databaseid,
Oid  roleid,
Relation  relsetting,
GucSource  source 
)
void DropSetting ( Oid  databaseid,
Oid  roleid 
)