mirror of
https://github.com/postgres/postgres.git
synced 2025-07-11 10:01:57 +03:00
Revert "Add USER SET parameter values for pg_db_role_setting"
This reverts commit096dd80f3c
and its fixupsbeecbe8e50
,afdd9f7f0e
,529da086ba
,db93e739ac
. Catversion is bumped. Discussion: https://postgr.es/m/d46f9265-ff3c-6743-2278-6772598233c2%40pgmasters.net
This commit is contained in:
@ -3212,16 +3212,6 @@ SCRAM-SHA-256$<replaceable><iteration count></replaceable>:<replaceable>&l
|
|||||||
Defaults for run-time configuration variables
|
Defaults for run-time configuration variables
|
||||||
</para></entry>
|
</para></entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
<row>
|
|
||||||
<entry role="catalog_table_entry"><para role="column_definition">
|
|
||||||
<structfield>setuser</structfield> <type>bool[]</type>
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
Values of <link linkend="sql-alterrole-user-set"><literal>USER SET</literal></link>
|
|
||||||
flag for every setting in <structfield>setconfig</structfield>
|
|
||||||
</para></entry>
|
|
||||||
</row>
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</tgroup>
|
</tgroup>
|
||||||
</table>
|
</table>
|
||||||
|
@ -37,7 +37,7 @@ ALTER DATABASE <replaceable class="parameter">name</replaceable> SET TABLESPACE
|
|||||||
|
|
||||||
ALTER DATABASE <replaceable class="parameter">name</replaceable> REFRESH COLLATION VERSION
|
ALTER DATABASE <replaceable class="parameter">name</replaceable> REFRESH COLLATION VERSION
|
||||||
|
|
||||||
ALTER DATABASE <replaceable class="parameter">name</replaceable> SET <replaceable>configuration_parameter</replaceable> { TO | = } { <replaceable>value</replaceable> | <replaceable>value</replaceable> USER SET | DEFAULT }
|
ALTER DATABASE <replaceable class="parameter">name</replaceable> SET <replaceable>configuration_parameter</replaceable> { TO | = } { <replaceable>value</replaceable> | DEFAULT }
|
||||||
ALTER DATABASE <replaceable class="parameter">name</replaceable> SET <replaceable>configuration_parameter</replaceable> FROM CURRENT
|
ALTER DATABASE <replaceable class="parameter">name</replaceable> SET <replaceable>configuration_parameter</replaceable> FROM CURRENT
|
||||||
ALTER DATABASE <replaceable class="parameter">name</replaceable> RESET <replaceable>configuration_parameter</replaceable>
|
ALTER DATABASE <replaceable class="parameter">name</replaceable> RESET <replaceable>configuration_parameter</replaceable>
|
||||||
ALTER DATABASE <replaceable class="parameter">name</replaceable> RESET ALL
|
ALTER DATABASE <replaceable class="parameter">name</replaceable> RESET ALL
|
||||||
@ -206,19 +206,6 @@ ALTER DATABASE <replaceable class="parameter">name</replaceable> RESET ALL
|
|||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term><literal>USER SET</literal></term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
Specifies that the variable should be set on behalf of an ordinary role.
|
|
||||||
That allows non-superuser and non-replication roles to set placeholder
|
|
||||||
variables, whose permission requirements are not known yet;
|
|
||||||
see <xref linkend="runtime-config-custom"/>. The variable won't
|
|
||||||
be set if it appears to require superuser privileges.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
</variablelist>
|
</variablelist>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ ALTER ROLE <replaceable class="parameter">role_specification</replaceable> [ WIT
|
|||||||
|
|
||||||
ALTER ROLE <replaceable class="parameter">name</replaceable> RENAME TO <replaceable>new_name</replaceable>
|
ALTER ROLE <replaceable class="parameter">name</replaceable> RENAME TO <replaceable>new_name</replaceable>
|
||||||
|
|
||||||
ALTER ROLE { <replaceable class="parameter">role_specification</replaceable> | ALL } [ IN DATABASE <replaceable class="parameter">database_name</replaceable> ] SET <replaceable>configuration_parameter</replaceable> { TO | = } { <replaceable>value</replaceable> | <replaceable>value</replaceable> USER SET | DEFAULT }
|
ALTER ROLE { <replaceable class="parameter">role_specification</replaceable> | ALL } [ IN DATABASE <replaceable class="parameter">database_name</replaceable> ] SET <replaceable>configuration_parameter</replaceable> { TO | = } { <replaceable>value</replaceable> | DEFAULT }
|
||||||
ALTER ROLE { <replaceable class="parameter">role_specification</replaceable> | ALL } [ IN DATABASE <replaceable class="parameter">database_name</replaceable> ] SET <replaceable>configuration_parameter</replaceable> FROM CURRENT
|
ALTER ROLE { <replaceable class="parameter">role_specification</replaceable> | ALL } [ IN DATABASE <replaceable class="parameter">database_name</replaceable> ] SET <replaceable>configuration_parameter</replaceable> FROM CURRENT
|
||||||
ALTER ROLE { <replaceable class="parameter">role_specification</replaceable> | ALL } [ IN DATABASE <replaceable class="parameter">database_name</replaceable> ] RESET <replaceable>configuration_parameter</replaceable>
|
ALTER ROLE { <replaceable class="parameter">role_specification</replaceable> | ALL } [ IN DATABASE <replaceable class="parameter">database_name</replaceable> ] RESET <replaceable>configuration_parameter</replaceable>
|
||||||
ALTER ROLE { <replaceable class="parameter">role_specification</replaceable> | ALL } [ IN DATABASE <replaceable class="parameter">database_name</replaceable> ] RESET ALL
|
ALTER ROLE { <replaceable class="parameter">role_specification</replaceable> | ALL } [ IN DATABASE <replaceable class="parameter">database_name</replaceable> ] RESET ALL
|
||||||
@ -239,19 +239,6 @@ ALTER ROLE { <replaceable class="parameter">role_specification</replaceable> | A
|
|||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry id="sql-alterrole-user-set">
|
|
||||||
<term><literal>USER SET</literal></term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
Specifies that the variable should be set on behalf of an ordinary role.
|
|
||||||
That allows non-superuser and non-replication roles to set placeholder
|
|
||||||
variables, whose permission requirements are not known yet;
|
|
||||||
see <xref linkend="runtime-config-custom"/>. The variable won't
|
|
||||||
be set if it appears to require superuser privileges.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
</variablelist>
|
</variablelist>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
@ -347,13 +334,6 @@ ALTER ROLE worker_bee SET maintenance_work_mem = 100000;
|
|||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
ALTER ROLE fred IN DATABASE devel SET client_min_messages = DEBUG;
|
ALTER ROLE fred IN DATABASE devel SET client_min_messages = DEBUG;
|
||||||
</programlisting></para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Give a role a non-default placeholder setting on behalf of ordinary user:
|
|
||||||
|
|
||||||
<programlisting>
|
|
||||||
ALTER ROLE fred SET my.param = 'value' USER SET;
|
|
||||||
</programlisting></para>
|
</programlisting></para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ ALTER USER <replaceable class="parameter">role_specification</replaceable> [ WIT
|
|||||||
|
|
||||||
ALTER USER <replaceable class="parameter">name</replaceable> RENAME TO <replaceable>new_name</replaceable>
|
ALTER USER <replaceable class="parameter">name</replaceable> RENAME TO <replaceable>new_name</replaceable>
|
||||||
|
|
||||||
ALTER USER { <replaceable class="parameter">role_specification</replaceable> | ALL } [ IN DATABASE <replaceable class="parameter">database_name</replaceable> ] SET <replaceable>configuration_parameter</replaceable> { TO | = } { <replaceable>value</replaceable> | <replaceable>value</replaceable> USER SET | DEFAULT }
|
ALTER USER { <replaceable class="parameter">role_specification</replaceable> | ALL } [ IN DATABASE <replaceable class="parameter">database_name</replaceable> ] SET <replaceable>configuration_parameter</replaceable> { TO | = } { <replaceable>value</replaceable> | DEFAULT }
|
||||||
ALTER USER { <replaceable class="parameter">role_specification</replaceable> | ALL } [ IN DATABASE <replaceable class="parameter">database_name</replaceable> ] SET <replaceable>configuration_parameter</replaceable> FROM CURRENT
|
ALTER USER { <replaceable class="parameter">role_specification</replaceable> | ALL } [ IN DATABASE <replaceable class="parameter">database_name</replaceable> ] SET <replaceable>configuration_parameter</replaceable> FROM CURRENT
|
||||||
ALTER USER { <replaceable class="parameter">role_specification</replaceable> | ALL } [ IN DATABASE <replaceable class="parameter">database_name</replaceable> ] RESET <replaceable>configuration_parameter</replaceable>
|
ALTER USER { <replaceable class="parameter">role_specification</replaceable> | ALL } [ IN DATABASE <replaceable class="parameter">database_name</replaceable> ] RESET <replaceable>configuration_parameter</replaceable>
|
||||||
ALTER USER { <replaceable class="parameter">role_specification</replaceable> | ALL } [ IN DATABASE <replaceable class="parameter">database_name</replaceable> ] RESET ALL
|
ALTER USER { <replaceable class="parameter">role_specification</replaceable> | ALL } [ IN DATABASE <replaceable class="parameter">database_name</replaceable> ] RESET ALL
|
||||||
|
@ -1902,13 +1902,6 @@ INSERT INTO tbl1 VALUES ($1, $2) \bind 'first value' 'second value' \g
|
|||||||
commands are used to define per-role and per-database configuration
|
commands are used to define per-role and per-database configuration
|
||||||
settings.
|
settings.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
|
||||||
Since <productname>PostgreSQL</productname> 16, the output includes a
|
|
||||||
column with the values of the
|
|
||||||
<link linkend="sql-alterrole-user-set"><literal>USER SET</literal></link>
|
|
||||||
flag for each setting.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
@ -63,23 +63,14 @@ AlterSetting(Oid databaseid, Oid roleid, VariableSetStmt *setstmt)
|
|||||||
if (HeapTupleIsValid(tuple))
|
if (HeapTupleIsValid(tuple))
|
||||||
{
|
{
|
||||||
ArrayType *new = NULL;
|
ArrayType *new = NULL;
|
||||||
ArrayType *usersetArray;
|
|
||||||
Datum datum;
|
Datum datum;
|
||||||
Datum usersetDatum;
|
|
||||||
bool isnull;
|
bool isnull;
|
||||||
bool usersetIsnull;
|
|
||||||
|
|
||||||
datum = heap_getattr(tuple, Anum_pg_db_role_setting_setconfig,
|
datum = heap_getattr(tuple, Anum_pg_db_role_setting_setconfig,
|
||||||
RelationGetDescr(rel), &isnull);
|
RelationGetDescr(rel), &isnull);
|
||||||
usersetDatum = heap_getattr(tuple, Anum_pg_db_role_setting_setuser,
|
|
||||||
RelationGetDescr(rel), &usersetIsnull);
|
|
||||||
|
|
||||||
if (!isnull)
|
if (!isnull)
|
||||||
{
|
new = GUCArrayReset(DatumGetArrayTypeP(datum));
|
||||||
Assert(!usersetIsnull);
|
|
||||||
usersetArray = DatumGetArrayTypeP(usersetDatum);
|
|
||||||
new = GUCArrayReset(DatumGetArrayTypeP(datum), &usersetArray);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (new)
|
if (new)
|
||||||
{
|
{
|
||||||
@ -95,11 +86,6 @@ AlterSetting(Oid databaseid, Oid roleid, VariableSetStmt *setstmt)
|
|||||||
repl_repl[Anum_pg_db_role_setting_setconfig - 1] = true;
|
repl_repl[Anum_pg_db_role_setting_setconfig - 1] = true;
|
||||||
repl_null[Anum_pg_db_role_setting_setconfig - 1] = false;
|
repl_null[Anum_pg_db_role_setting_setconfig - 1] = false;
|
||||||
|
|
||||||
repl_val[Anum_pg_db_role_setting_setuser - 1] =
|
|
||||||
PointerGetDatum(usersetArray);
|
|
||||||
repl_repl[Anum_pg_db_role_setting_setuser - 1] = true;
|
|
||||||
repl_null[Anum_pg_db_role_setting_setuser - 1] = false;
|
|
||||||
|
|
||||||
newtuple = heap_modify_tuple(tuple, RelationGetDescr(rel),
|
newtuple = heap_modify_tuple(tuple, RelationGetDescr(rel),
|
||||||
repl_val, repl_null, repl_repl);
|
repl_val, repl_null, repl_repl);
|
||||||
CatalogTupleUpdate(rel, &tuple->t_self, newtuple);
|
CatalogTupleUpdate(rel, &tuple->t_self, newtuple);
|
||||||
@ -115,39 +101,28 @@ AlterSetting(Oid databaseid, Oid roleid, VariableSetStmt *setstmt)
|
|||||||
bool repl_repl[Natts_pg_db_role_setting];
|
bool repl_repl[Natts_pg_db_role_setting];
|
||||||
HeapTuple newtuple;
|
HeapTuple newtuple;
|
||||||
Datum datum;
|
Datum datum;
|
||||||
Datum usersetDatum;
|
|
||||||
bool isnull;
|
bool isnull;
|
||||||
bool usersetIsnull;
|
|
||||||
ArrayType *a;
|
ArrayType *a;
|
||||||
ArrayType *usersetArray;
|
|
||||||
|
|
||||||
memset(repl_repl, false, sizeof(repl_repl));
|
memset(repl_repl, false, sizeof(repl_repl));
|
||||||
repl_repl[Anum_pg_db_role_setting_setconfig - 1] = true;
|
repl_repl[Anum_pg_db_role_setting_setconfig - 1] = true;
|
||||||
repl_null[Anum_pg_db_role_setting_setconfig - 1] = false;
|
repl_null[Anum_pg_db_role_setting_setconfig - 1] = false;
|
||||||
repl_repl[Anum_pg_db_role_setting_setuser - 1] = true;
|
|
||||||
repl_null[Anum_pg_db_role_setting_setuser - 1] = false;
|
|
||||||
|
|
||||||
/* Extract old values of setconfig and setuser */
|
/* Extract old value of setconfig */
|
||||||
datum = heap_getattr(tuple, Anum_pg_db_role_setting_setconfig,
|
datum = heap_getattr(tuple, Anum_pg_db_role_setting_setconfig,
|
||||||
RelationGetDescr(rel), &isnull);
|
RelationGetDescr(rel), &isnull);
|
||||||
a = isnull ? NULL : DatumGetArrayTypeP(datum);
|
a = isnull ? NULL : DatumGetArrayTypeP(datum);
|
||||||
|
|
||||||
usersetDatum = heap_getattr(tuple, Anum_pg_db_role_setting_setuser,
|
|
||||||
RelationGetDescr(rel), &usersetIsnull);
|
|
||||||
usersetArray = usersetIsnull ? NULL : DatumGetArrayTypeP(usersetDatum);
|
|
||||||
|
|
||||||
/* Update (valuestr is NULL in RESET cases) */
|
/* Update (valuestr is NULL in RESET cases) */
|
||||||
if (valuestr)
|
if (valuestr)
|
||||||
a = GUCArrayAdd(a, &usersetArray, setstmt->name, valuestr, setstmt->user_set);
|
a = GUCArrayAdd(a, setstmt->name, valuestr);
|
||||||
else
|
else
|
||||||
a = GUCArrayDelete(a, &usersetArray, setstmt->name);
|
a = GUCArrayDelete(a, setstmt->name);
|
||||||
|
|
||||||
if (a)
|
if (a)
|
||||||
{
|
{
|
||||||
repl_val[Anum_pg_db_role_setting_setconfig - 1] =
|
repl_val[Anum_pg_db_role_setting_setconfig - 1] =
|
||||||
PointerGetDatum(a);
|
PointerGetDatum(a);
|
||||||
repl_val[Anum_pg_db_role_setting_setuser - 1] =
|
|
||||||
PointerGetDatum(usersetArray);
|
|
||||||
|
|
||||||
newtuple = heap_modify_tuple(tuple, RelationGetDescr(rel),
|
newtuple = heap_modify_tuple(tuple, RelationGetDescr(rel),
|
||||||
repl_val, repl_null, repl_repl);
|
repl_val, repl_null, repl_repl);
|
||||||
@ -162,18 +137,16 @@ AlterSetting(Oid databaseid, Oid roleid, VariableSetStmt *setstmt)
|
|||||||
HeapTuple newtuple;
|
HeapTuple newtuple;
|
||||||
Datum values[Natts_pg_db_role_setting];
|
Datum values[Natts_pg_db_role_setting];
|
||||||
bool nulls[Natts_pg_db_role_setting];
|
bool nulls[Natts_pg_db_role_setting];
|
||||||
ArrayType *a,
|
ArrayType *a;
|
||||||
*usersetArray;
|
|
||||||
|
|
||||||
memset(nulls, false, sizeof(nulls));
|
memset(nulls, false, sizeof(nulls));
|
||||||
|
|
||||||
a = GUCArrayAdd(NULL, &usersetArray, setstmt->name, valuestr, setstmt->user_set);
|
a = GUCArrayAdd(NULL, setstmt->name, valuestr);
|
||||||
|
|
||||||
values[Anum_pg_db_role_setting_setdatabase - 1] =
|
values[Anum_pg_db_role_setting_setdatabase - 1] =
|
||||||
ObjectIdGetDatum(databaseid);
|
ObjectIdGetDatum(databaseid);
|
||||||
values[Anum_pg_db_role_setting_setrole - 1] = ObjectIdGetDatum(roleid);
|
values[Anum_pg_db_role_setting_setrole - 1] = ObjectIdGetDatum(roleid);
|
||||||
values[Anum_pg_db_role_setting_setconfig - 1] = PointerGetDatum(a);
|
values[Anum_pg_db_role_setting_setconfig - 1] = PointerGetDatum(a);
|
||||||
values[Anum_pg_db_role_setting_setuser - 1] = PointerGetDatum(usersetArray);
|
|
||||||
newtuple = heap_form_tuple(RelationGetDescr(rel), values, nulls);
|
newtuple = heap_form_tuple(RelationGetDescr(rel), values, nulls);
|
||||||
|
|
||||||
CatalogTupleInsert(rel, newtuple);
|
CatalogTupleInsert(rel, newtuple);
|
||||||
@ -267,25 +240,20 @@ ApplySetting(Snapshot snapshot, Oid databaseid, Oid roleid,
|
|||||||
while (HeapTupleIsValid(tup = systable_getnext(scan)))
|
while (HeapTupleIsValid(tup = systable_getnext(scan)))
|
||||||
{
|
{
|
||||||
bool isnull;
|
bool isnull;
|
||||||
bool usersetIsnull;
|
|
||||||
Datum datum;
|
Datum datum;
|
||||||
Datum usersetDatum;
|
|
||||||
|
|
||||||
datum = heap_getattr(tup, Anum_pg_db_role_setting_setconfig,
|
datum = heap_getattr(tup, Anum_pg_db_role_setting_setconfig,
|
||||||
RelationGetDescr(relsetting), &isnull);
|
RelationGetDescr(relsetting), &isnull);
|
||||||
usersetDatum = heap_getattr(tup, Anum_pg_db_role_setting_setuser,
|
|
||||||
RelationGetDescr(relsetting), &usersetIsnull);
|
|
||||||
if (!isnull)
|
if (!isnull)
|
||||||
{
|
{
|
||||||
ArrayType *a = DatumGetArrayTypeP(datum);
|
ArrayType *a = DatumGetArrayTypeP(datum);
|
||||||
ArrayType *usersetArray = DatumGetArrayTypeP(usersetDatum);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We process all the options at SUSET level. We assume that the
|
* We process all the options at SUSET level. We assume that the
|
||||||
* right to insert an option into pg_db_role_setting was checked
|
* right to insert an option into pg_db_role_setting was checked
|
||||||
* when it was inserted.
|
* when it was inserted.
|
||||||
*/
|
*/
|
||||||
ProcessGUCArray(a, usersetArray, PGC_SUSET, source, GUC_ACTION_SET);
|
ProcessGUCArray(a, PGC_SUSET, source, GUC_ACTION_SET);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -696,7 +696,6 @@ ProcedureCreate(const char *procedureName,
|
|||||||
{
|
{
|
||||||
save_nestlevel = NewGUCNestLevel();
|
save_nestlevel = NewGUCNestLevel();
|
||||||
ProcessGUCArray(set_items,
|
ProcessGUCArray(set_items,
|
||||||
NULL,
|
|
||||||
(superuser() ? PGC_SUSET : PGC_USERSET),
|
(superuser() ? PGC_SUSET : PGC_USERSET),
|
||||||
PGC_S_SESSION,
|
PGC_S_SESSION,
|
||||||
GUC_ACTION_SAVE);
|
GUC_ACTION_SAVE);
|
||||||
|
@ -662,9 +662,9 @@ update_proconfig_value(ArrayType *a, List *set_items)
|
|||||||
char *valuestr = ExtractSetVariableArgs(sstmt);
|
char *valuestr = ExtractSetVariableArgs(sstmt);
|
||||||
|
|
||||||
if (valuestr)
|
if (valuestr)
|
||||||
a = GUCArrayAdd(a, NULL, sstmt->name, valuestr, sstmt->user_set);
|
a = GUCArrayAdd(a, sstmt->name, valuestr);
|
||||||
else /* RESET */
|
else /* RESET */
|
||||||
a = GUCArrayDelete(a, NULL, sstmt->name);
|
a = GUCArrayDelete(a, sstmt->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1648,26 +1648,6 @@ generic_set:
|
|||||||
n->args = $3;
|
n->args = $3;
|
||||||
$$ = n;
|
$$ = n;
|
||||||
}
|
}
|
||||||
| var_name TO var_list USER SET
|
|
||||||
{
|
|
||||||
VariableSetStmt *n = makeNode(VariableSetStmt);
|
|
||||||
|
|
||||||
n->kind = VAR_SET_VALUE;
|
|
||||||
n->name = $1;
|
|
||||||
n->args = $3;
|
|
||||||
n->user_set = true;
|
|
||||||
$$ = n;
|
|
||||||
}
|
|
||||||
| var_name '=' var_list USER SET
|
|
||||||
{
|
|
||||||
VariableSetStmt *n = makeNode(VariableSetStmt);
|
|
||||||
|
|
||||||
n->kind = VAR_SET_VALUE;
|
|
||||||
n->name = $1;
|
|
||||||
n->args = $3;
|
|
||||||
n->user_set = true;
|
|
||||||
$$ = n;
|
|
||||||
}
|
|
||||||
| var_name TO DEFAULT
|
| var_name TO DEFAULT
|
||||||
{
|
{
|
||||||
VariableSetStmt *n = makeNode(VariableSetStmt);
|
VariableSetStmt *n = makeNode(VariableSetStmt);
|
||||||
|
@ -3367,7 +3367,6 @@ construct_array_builtin(Datum *elems, int nelems, Oid elmtype)
|
|||||||
switch (elmtype)
|
switch (elmtype)
|
||||||
{
|
{
|
||||||
case CHAROID:
|
case CHAROID:
|
||||||
case BOOLOID:
|
|
||||||
elmlen = 1;
|
elmlen = 1;
|
||||||
elmbyval = true;
|
elmbyval = true;
|
||||||
elmalign = TYPALIGN_CHAR;
|
elmalign = TYPALIGN_CHAR;
|
||||||
|
@ -692,7 +692,6 @@ fmgr_security_definer(PG_FUNCTION_ARGS)
|
|||||||
if (fcache->proconfig)
|
if (fcache->proconfig)
|
||||||
{
|
{
|
||||||
ProcessGUCArray(fcache->proconfig,
|
ProcessGUCArray(fcache->proconfig,
|
||||||
NULL,
|
|
||||||
(superuser() ? PGC_SUSET : PGC_USERSET),
|
(superuser() ? PGC_SUSET : PGC_USERSET),
|
||||||
PGC_S_SESSION,
|
PGC_S_SESSION,
|
||||||
GUC_ACTION_SAVE);
|
GUC_ACTION_SAVE);
|
||||||
|
@ -225,6 +225,7 @@ static bool reporting_enabled; /* true to enable GUC_REPORT */
|
|||||||
|
|
||||||
static int GUCNestLevel = 0; /* 1 when in main transaction */
|
static int GUCNestLevel = 0; /* 1 when in main transaction */
|
||||||
|
|
||||||
|
|
||||||
static int guc_var_compare(const void *a, const void *b);
|
static int guc_var_compare(const void *a, const void *b);
|
||||||
static uint32 guc_name_hash(const void *key, Size keysize);
|
static uint32 guc_name_hash(const void *key, Size keysize);
|
||||||
static int guc_name_match(const void *key1, const void *key2, Size keysize);
|
static int guc_name_match(const void *key1, const void *key2, Size keysize);
|
||||||
@ -244,7 +245,7 @@ static void reapply_stacked_values(struct config_generic *variable,
|
|||||||
GucContext curscontext, GucSource cursource,
|
GucContext curscontext, GucSource cursource,
|
||||||
Oid cursrole);
|
Oid cursrole);
|
||||||
static bool validate_option_array_item(const char *name, const char *value,
|
static bool validate_option_array_item(const char *name, const char *value,
|
||||||
bool user_set, bool skipIfNoPermissions);
|
bool skipIfNoPermissions);
|
||||||
static void write_auto_conf_file(int fd, const char *filename, ConfigVariable *head);
|
static void write_auto_conf_file(int fd, const char *filename, ConfigVariable *head);
|
||||||
static void replace_auto_config_value(ConfigVariable **head_p, ConfigVariable **tail_p,
|
static void replace_auto_config_value(ConfigVariable **head_p, ConfigVariable **tail_p,
|
||||||
const char *name, const char *value);
|
const char *name, const char *value);
|
||||||
@ -6197,6 +6198,7 @@ ParseLongOption(const char *string, char **name, char **value)
|
|||||||
{
|
{
|
||||||
*name = palloc(equal_pos + 1);
|
*name = palloc(equal_pos + 1);
|
||||||
strlcpy(*name, string, equal_pos + 1);
|
strlcpy(*name, string, equal_pos + 1);
|
||||||
|
|
||||||
*value = pstrdup(&string[equal_pos + 1]);
|
*value = pstrdup(&string[equal_pos + 1]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -6219,7 +6221,7 @@ ParseLongOption(const char *string, char **name, char **value)
|
|||||||
* The array parameter must be an array of TEXT (it must not be NULL).
|
* The array parameter must be an array of TEXT (it must not be NULL).
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ProcessGUCArray(ArrayType *array, ArrayType *usersetArray,
|
ProcessGUCArray(ArrayType *array,
|
||||||
GucContext context, GucSource source, GucAction action)
|
GucContext context, GucSource source, GucAction action)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -6232,7 +6234,6 @@ ProcessGUCArray(ArrayType *array, ArrayType *usersetArray,
|
|||||||
for (i = 1; i <= ARR_DIMS(array)[0]; i++)
|
for (i = 1; i <= ARR_DIMS(array)[0]; i++)
|
||||||
{
|
{
|
||||||
Datum d;
|
Datum d;
|
||||||
Datum userSetDatum = BoolGetDatum(false);
|
|
||||||
bool isnull;
|
bool isnull;
|
||||||
char *s;
|
char *s;
|
||||||
char *name;
|
char *name;
|
||||||
@ -6261,29 +6262,9 @@ ProcessGUCArray(ArrayType *array, ArrayType *usersetArray,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (usersetArray)
|
|
||||||
userSetDatum = array_ref(usersetArray, 1, &i,
|
|
||||||
-1 /* varlenarray */ ,
|
|
||||||
sizeof(bool) /* BOOL's typlen */ ,
|
|
||||||
true /* BOOL's typbyval */ ,
|
|
||||||
TYPALIGN_CHAR /* BOOL's typalign */ ,
|
|
||||||
&isnull);
|
|
||||||
if (isnull)
|
|
||||||
userSetDatum = BoolGetDatum(false);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* USER SET values are applicable only for PGC_USERSET parameters. We
|
|
||||||
* use InvalidOid as role in order to evade possible privileges of the
|
|
||||||
* current user.
|
|
||||||
*/
|
|
||||||
if (!DatumGetBool(userSetDatum))
|
|
||||||
(void) set_config_option(name, value,
|
(void) set_config_option(name, value,
|
||||||
context, source,
|
context, source,
|
||||||
action, true, 0, false);
|
action, true, 0, false);
|
||||||
else
|
|
||||||
(void) set_config_option_ext(name, value,
|
|
||||||
PGC_USERSET, source, InvalidOid,
|
|
||||||
action, true, 0, false);
|
|
||||||
|
|
||||||
pfree(name);
|
pfree(name);
|
||||||
pfree(value);
|
pfree(value);
|
||||||
@ -6297,8 +6278,7 @@ ProcessGUCArray(ArrayType *array, ArrayType *usersetArray,
|
|||||||
* to indicate the current table entry is NULL.
|
* to indicate the current table entry is NULL.
|
||||||
*/
|
*/
|
||||||
ArrayType *
|
ArrayType *
|
||||||
GUCArrayAdd(ArrayType *array, ArrayType **usersetArray,
|
GUCArrayAdd(ArrayType *array, const char *name, const char *value)
|
||||||
const char *name, const char *value, bool user_set)
|
|
||||||
{
|
{
|
||||||
struct config_generic *record;
|
struct config_generic *record;
|
||||||
Datum datum;
|
Datum datum;
|
||||||
@ -6309,7 +6289,7 @@ GUCArrayAdd(ArrayType *array, ArrayType **usersetArray,
|
|||||||
Assert(value);
|
Assert(value);
|
||||||
|
|
||||||
/* test if the option is valid and we're allowed to set it */
|
/* test if the option is valid and we're allowed to set it */
|
||||||
(void) validate_option_array_item(name, value, user_set, false);
|
(void) validate_option_array_item(name, value, false);
|
||||||
|
|
||||||
/* normalize name (converts obsolete GUC names to modern spellings) */
|
/* normalize name (converts obsolete GUC names to modern spellings) */
|
||||||
record = find_option(name, false, true, WARNING);
|
record = find_option(name, false, true, WARNING);
|
||||||
@ -6350,27 +6330,6 @@ GUCArrayAdd(ArrayType *array, ArrayType **usersetArray,
|
|||||||
/* check for match up through and including '=' */
|
/* check for match up through and including '=' */
|
||||||
if (strncmp(current, newval, strlen(name) + 1) == 0)
|
if (strncmp(current, newval, strlen(name) + 1) == 0)
|
||||||
{
|
{
|
||||||
bool currentUserSet = false;
|
|
||||||
|
|
||||||
if (usersetArray)
|
|
||||||
{
|
|
||||||
currentUserSet = DatumGetBool(array_ref(*usersetArray, 1, &i,
|
|
||||||
-1 /* varlenarray */ ,
|
|
||||||
sizeof(bool) /* BOOL's typlen */ ,
|
|
||||||
true /* BOOL's typbyval */ ,
|
|
||||||
TYPALIGN_CHAR /* BOOL's typalign */ ,
|
|
||||||
&isnull));
|
|
||||||
if (isnull)
|
|
||||||
currentUserSet = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Recheck permissions if we found an option without USER SET
|
|
||||||
* flag while we're setting an option with USER SET flag.
|
|
||||||
*/
|
|
||||||
if (!currentUserSet && user_set)
|
|
||||||
(void) validate_option_array_item(name, value,
|
|
||||||
false, false);
|
|
||||||
index = i;
|
index = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -6383,25 +6342,9 @@ GUCArrayAdd(ArrayType *array, ArrayType **usersetArray,
|
|||||||
-1 /* TEXT's typlen */ ,
|
-1 /* TEXT's typlen */ ,
|
||||||
false /* TEXT's typbyval */ ,
|
false /* TEXT's typbyval */ ,
|
||||||
TYPALIGN_INT /* TEXT's typalign */ );
|
TYPALIGN_INT /* TEXT's typalign */ );
|
||||||
|
|
||||||
if (usersetArray)
|
|
||||||
*usersetArray = array_set(*usersetArray, 1, &index,
|
|
||||||
BoolGetDatum(user_set),
|
|
||||||
false,
|
|
||||||
-1 /* varlena array */ ,
|
|
||||||
sizeof(bool) /* BOOL's typlen */ ,
|
|
||||||
true /* BOOL's typbyval */ ,
|
|
||||||
TYPALIGN_CHAR /* BOOL's typalign */ );
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
a = construct_array_builtin(&datum, 1, TEXTOID);
|
a = construct_array_builtin(&datum, 1, TEXTOID);
|
||||||
if (usersetArray)
|
|
||||||
{
|
|
||||||
datum = BoolGetDatum(user_set);
|
|
||||||
*usersetArray = construct_array_builtin(&datum, 1, BOOLOID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
@ -6413,16 +6356,18 @@ GUCArrayAdd(ArrayType *array, ArrayType **usersetArray,
|
|||||||
* is NULL then a null should be stored.
|
* is NULL then a null should be stored.
|
||||||
*/
|
*/
|
||||||
ArrayType *
|
ArrayType *
|
||||||
GUCArrayDelete(ArrayType *array, ArrayType **usersetArray, const char *name)
|
GUCArrayDelete(ArrayType *array, const char *name)
|
||||||
{
|
{
|
||||||
struct config_generic *record;
|
struct config_generic *record;
|
||||||
ArrayType *newarray;
|
ArrayType *newarray;
|
||||||
ArrayType *newUsersetArray;
|
|
||||||
int i;
|
int i;
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
Assert(name);
|
Assert(name);
|
||||||
|
|
||||||
|
/* test if the option is valid and we're allowed to set it */
|
||||||
|
(void) validate_option_array_item(name, NULL, false);
|
||||||
|
|
||||||
/* normalize name (converts obsolete GUC names to modern spellings) */
|
/* normalize name (converts obsolete GUC names to modern spellings) */
|
||||||
record = find_option(name, false, true, WARNING);
|
record = find_option(name, false, true, WARNING);
|
||||||
if (record)
|
if (record)
|
||||||
@ -6433,13 +6378,11 @@ GUCArrayDelete(ArrayType *array, ArrayType **usersetArray, const char *name)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
newarray = NULL;
|
newarray = NULL;
|
||||||
newUsersetArray = NULL;
|
|
||||||
index = 1;
|
index = 1;
|
||||||
|
|
||||||
for (i = 1; i <= ARR_DIMS(array)[0]; i++)
|
for (i = 1; i <= ARR_DIMS(array)[0]; i++)
|
||||||
{
|
{
|
||||||
Datum d;
|
Datum d;
|
||||||
Datum userSetDatum = BoolGetDatum(false);
|
|
||||||
char *val;
|
char *val;
|
||||||
bool isnull;
|
bool isnull;
|
||||||
|
|
||||||
@ -6453,29 +6396,13 @@ GUCArrayDelete(ArrayType *array, ArrayType **usersetArray, const char *name)
|
|||||||
continue;
|
continue;
|
||||||
val = TextDatumGetCString(d);
|
val = TextDatumGetCString(d);
|
||||||
|
|
||||||
if (usersetArray)
|
|
||||||
userSetDatum = array_ref(*usersetArray, 1, &i,
|
|
||||||
-1 /* varlenarray */ ,
|
|
||||||
sizeof(bool) /* BOOL's typlen */ ,
|
|
||||||
true /* BOOL's typbyval */ ,
|
|
||||||
TYPALIGN_CHAR /* BOOL's typalign */ ,
|
|
||||||
&isnull);
|
|
||||||
if (isnull)
|
|
||||||
userSetDatum = BoolGetDatum(false);
|
|
||||||
|
|
||||||
/* ignore entry if it's what we want to delete */
|
/* ignore entry if it's what we want to delete */
|
||||||
if (strncmp(val, name, strlen(name)) == 0
|
if (strncmp(val, name, strlen(name)) == 0
|
||||||
&& val[strlen(name)] == '=')
|
&& val[strlen(name)] == '=')
|
||||||
{
|
|
||||||
/* test if the option is valid and we're allowed to set it */
|
|
||||||
(void) validate_option_array_item(name, NULL,
|
|
||||||
DatumGetBool(userSetDatum), false);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
/* else add it to the output array */
|
/* else add it to the output array */
|
||||||
if (newarray)
|
if (newarray)
|
||||||
{
|
|
||||||
newarray = array_set(newarray, 1, &index,
|
newarray = array_set(newarray, 1, &index,
|
||||||
d,
|
d,
|
||||||
false,
|
false,
|
||||||
@ -6483,29 +6410,12 @@ GUCArrayDelete(ArrayType *array, ArrayType **usersetArray, const char *name)
|
|||||||
-1 /* TEXT's typlen */ ,
|
-1 /* TEXT's typlen */ ,
|
||||||
false /* TEXT's typbyval */ ,
|
false /* TEXT's typbyval */ ,
|
||||||
TYPALIGN_INT /* TEXT's typalign */ );
|
TYPALIGN_INT /* TEXT's typalign */ );
|
||||||
if (usersetArray)
|
|
||||||
newUsersetArray = array_set(newUsersetArray, 1, &index,
|
|
||||||
userSetDatum,
|
|
||||||
false,
|
|
||||||
-1 /* varlena array */ ,
|
|
||||||
sizeof(bool) /* BOOL's typlen */ ,
|
|
||||||
true /* BOOL's typbyval */ ,
|
|
||||||
TYPALIGN_CHAR /* BOOL's typalign */ );
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
newarray = construct_array_builtin(&d, 1, TEXTOID);
|
newarray = construct_array_builtin(&d, 1, TEXTOID);
|
||||||
if (usersetArray)
|
|
||||||
newUsersetArray = construct_array_builtin(&userSetDatum, 1,
|
|
||||||
BOOLOID);
|
|
||||||
}
|
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (usersetArray)
|
|
||||||
*usersetArray = newUsersetArray;
|
|
||||||
|
|
||||||
return newarray;
|
return newarray;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6516,10 +6426,9 @@ GUCArrayDelete(ArrayType *array, ArrayType **usersetArray, const char *name)
|
|||||||
* those that are PGC_USERSET or we have permission to set
|
* those that are PGC_USERSET or we have permission to set
|
||||||
*/
|
*/
|
||||||
ArrayType *
|
ArrayType *
|
||||||
GUCArrayReset(ArrayType *array, ArrayType **usersetArray)
|
GUCArrayReset(ArrayType *array)
|
||||||
{
|
{
|
||||||
ArrayType *newarray;
|
ArrayType *newarray;
|
||||||
ArrayType *newUsersetArray;
|
|
||||||
int i;
|
int i;
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
@ -6532,13 +6441,11 @@ GUCArrayReset(ArrayType *array, ArrayType **usersetArray)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
newarray = NULL;
|
newarray = NULL;
|
||||||
newUsersetArray = NULL;
|
|
||||||
index = 1;
|
index = 1;
|
||||||
|
|
||||||
for (i = 1; i <= ARR_DIMS(array)[0]; i++)
|
for (i = 1; i <= ARR_DIMS(array)[0]; i++)
|
||||||
{
|
{
|
||||||
Datum d;
|
Datum d;
|
||||||
Datum userSetDatum = BoolGetDatum(false);
|
|
||||||
char *val;
|
char *val;
|
||||||
char *eqsgn;
|
char *eqsgn;
|
||||||
bool isnull;
|
bool isnull;
|
||||||
@ -6553,27 +6460,15 @@ GUCArrayReset(ArrayType *array, ArrayType **usersetArray)
|
|||||||
continue;
|
continue;
|
||||||
val = TextDatumGetCString(d);
|
val = TextDatumGetCString(d);
|
||||||
|
|
||||||
if (usersetArray)
|
|
||||||
userSetDatum = array_ref(*usersetArray, 1, &i,
|
|
||||||
-1 /* varlenarray */ ,
|
|
||||||
sizeof(bool) /* BOOL's typlen */ ,
|
|
||||||
true /* BOOL's typbyval */ ,
|
|
||||||
TYPALIGN_CHAR /* BOOL's typalign */ ,
|
|
||||||
&isnull);
|
|
||||||
if (isnull)
|
|
||||||
userSetDatum = BoolGetDatum(false);
|
|
||||||
|
|
||||||
eqsgn = strchr(val, '=');
|
eqsgn = strchr(val, '=');
|
||||||
*eqsgn = '\0';
|
*eqsgn = '\0';
|
||||||
|
|
||||||
/* skip if we have permission to delete it */
|
/* skip if we have permission to delete it */
|
||||||
if (validate_option_array_item(val, NULL,
|
if (validate_option_array_item(val, NULL, true))
|
||||||
DatumGetBool(userSetDatum), true))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* else add it to the output array */
|
/* else add it to the output array */
|
||||||
if (newarray)
|
if (newarray)
|
||||||
{
|
|
||||||
newarray = array_set(newarray, 1, &index,
|
newarray = array_set(newarray, 1, &index,
|
||||||
d,
|
d,
|
||||||
false,
|
false,
|
||||||
@ -6581,29 +6476,13 @@ GUCArrayReset(ArrayType *array, ArrayType **usersetArray)
|
|||||||
-1 /* TEXT's typlen */ ,
|
-1 /* TEXT's typlen */ ,
|
||||||
false /* TEXT's typbyval */ ,
|
false /* TEXT's typbyval */ ,
|
||||||
TYPALIGN_INT /* TEXT's typalign */ );
|
TYPALIGN_INT /* TEXT's typalign */ );
|
||||||
if (usersetArray)
|
|
||||||
newUsersetArray = array_set(newUsersetArray, 1, &index,
|
|
||||||
userSetDatum,
|
|
||||||
false,
|
|
||||||
-1 /* varlena array */ ,
|
|
||||||
sizeof(bool) /* BOOL's typlen */ ,
|
|
||||||
true /* BOOL's typbyval */ ,
|
|
||||||
TYPALIGN_CHAR /* BOOL's typalign */ );
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
newarray = construct_array_builtin(&d, 1, TEXTOID);
|
newarray = construct_array_builtin(&d, 1, TEXTOID);
|
||||||
if (usersetArray)
|
|
||||||
newUsersetArray = construct_array_builtin(&userSetDatum, 1, BOOLOID);
|
|
||||||
}
|
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
pfree(val);
|
pfree(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (usersetArray)
|
|
||||||
*usersetArray = newUsersetArray;
|
|
||||||
|
|
||||||
return newarray;
|
return newarray;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6611,16 +6490,15 @@ GUCArrayReset(ArrayType *array, ArrayType **usersetArray)
|
|||||||
* Validate a proposed option setting for GUCArrayAdd/Delete/Reset.
|
* Validate a proposed option setting for GUCArrayAdd/Delete/Reset.
|
||||||
*
|
*
|
||||||
* name is the option name. value is the proposed value for the Add case,
|
* name is the option name. value is the proposed value for the Add case,
|
||||||
* or NULL for the Delete/Reset cases. user_set indicates this is the USER SET
|
* or NULL for the Delete/Reset cases. If skipIfNoPermissions is true, it's
|
||||||
* option. If skipIfNoPermissions is true, it's not an error to have no
|
* not an error to have no permissions to set the option.
|
||||||
* permissions to set the option.
|
|
||||||
*
|
*
|
||||||
* Returns true if OK, false if skipIfNoPermissions is true and user does not
|
* Returns true if OK, false if skipIfNoPermissions is true and user does not
|
||||||
* have permission to change this option (all other error cases result in an
|
* have permission to change this option (all other error cases result in an
|
||||||
* error being thrown).
|
* error being thrown).
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
validate_option_array_item(const char *name, const char *value, bool user_set,
|
validate_option_array_item(const char *name, const char *value,
|
||||||
bool skipIfNoPermissions)
|
bool skipIfNoPermissions)
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -6656,10 +6534,8 @@ validate_option_array_item(const char *name, const char *value, bool user_set,
|
|||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* We cannot do any meaningful check on the value, so only permissions
|
* We cannot do any meaningful check on the value, so only permissions
|
||||||
* are useful to check. USER SET options are always allowed.
|
* are useful to check.
|
||||||
*/
|
*/
|
||||||
if (user_set)
|
|
||||||
return true;
|
|
||||||
if (superuser() ||
|
if (superuser() ||
|
||||||
pg_parameter_aclcheck(name, GetUserId(), ACL_SET) == ACLCHECK_OK)
|
pg_parameter_aclcheck(name, GetUserId(), ACL_SET) == ACLCHECK_OK)
|
||||||
return true;
|
return true;
|
||||||
|
@ -166,22 +166,12 @@ ExecSetVariableStmt(VariableSetStmt *stmt, bool isTopLevel)
|
|||||||
char *
|
char *
|
||||||
ExtractSetVariableArgs(VariableSetStmt *stmt)
|
ExtractSetVariableArgs(VariableSetStmt *stmt)
|
||||||
{
|
{
|
||||||
|
|
||||||
switch (stmt->kind)
|
switch (stmt->kind)
|
||||||
{
|
{
|
||||||
case VAR_SET_VALUE:
|
case VAR_SET_VALUE:
|
||||||
return flatten_set_variable_args(stmt->name, stmt->args);
|
return flatten_set_variable_args(stmt->name, stmt->args);
|
||||||
case VAR_SET_CURRENT:
|
case VAR_SET_CURRENT:
|
||||||
{
|
return GetConfigOptionByName(stmt->name, NULL, false);
|
||||||
struct config_generic *record;
|
|
||||||
char *result;
|
|
||||||
|
|
||||||
result = GetConfigOptionByName(stmt->name, NULL, false);
|
|
||||||
record = find_option(stmt->name, false, false, ERROR);
|
|
||||||
stmt->user_set = (record->scontext == PGC_USERSET);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -821,7 +821,6 @@ SplitGUCList(char *rawstring, char separator,
|
|||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
makeAlterConfigCommand(PGconn *conn, const char *configitem,
|
makeAlterConfigCommand(PGconn *conn, const char *configitem,
|
||||||
const char *userset,
|
|
||||||
const char *type, const char *name,
|
const char *type, const char *name,
|
||||||
const char *type2, const char *name2,
|
const char *type2, const char *name2,
|
||||||
PQExpBuffer buf)
|
PQExpBuffer buf)
|
||||||
@ -880,10 +879,6 @@ makeAlterConfigCommand(PGconn *conn, const char *configitem,
|
|||||||
else
|
else
|
||||||
appendStringLiteralConn(buf, pos, conn);
|
appendStringLiteralConn(buf, pos, conn);
|
||||||
|
|
||||||
/* Add USER SET flag if specified in the string */
|
|
||||||
if (userset && !strcmp(userset, "t"))
|
|
||||||
appendPQExpBufferStr(buf, " USER SET");
|
|
||||||
|
|
||||||
appendPQExpBufferStr(buf, ";\n");
|
appendPQExpBufferStr(buf, ";\n");
|
||||||
|
|
||||||
pg_free(mine);
|
pg_free(mine);
|
||||||
|
@ -59,7 +59,6 @@ extern bool SplitGUCList(char *rawstring, char separator,
|
|||||||
char ***namelist);
|
char ***namelist);
|
||||||
|
|
||||||
extern void makeAlterConfigCommand(PGconn *conn, const char *configitem,
|
extern void makeAlterConfigCommand(PGconn *conn, const char *configitem,
|
||||||
const char *userset,
|
|
||||||
const char *type, const char *name,
|
const char *type, const char *name,
|
||||||
const char *type2, const char *name2,
|
const char *type2, const char *name2,
|
||||||
PQExpBuffer buf);
|
PQExpBuffer buf);
|
||||||
|
@ -3385,49 +3385,32 @@ dumpDatabaseConfig(Archive *AH, PQExpBuffer outbuf,
|
|||||||
PGresult *res;
|
PGresult *res;
|
||||||
|
|
||||||
/* First collect database-specific options */
|
/* First collect database-specific options */
|
||||||
printfPQExpBuffer(buf, "SELECT unnest(setconfig)");
|
printfPQExpBuffer(buf, "SELECT unnest(setconfig) FROM pg_db_role_setting "
|
||||||
if (AH->remoteVersion >= 160000)
|
|
||||||
appendPQExpBufferStr(buf, ", unnest(setuser)");
|
|
||||||
appendPQExpBuffer(buf, " FROM pg_db_role_setting "
|
|
||||||
"WHERE setrole = 0 AND setdatabase = '%u'::oid",
|
"WHERE setrole = 0 AND setdatabase = '%u'::oid",
|
||||||
dboid);
|
dboid);
|
||||||
|
|
||||||
res = ExecuteSqlQuery(AH, buf->data, PGRES_TUPLES_OK);
|
res = ExecuteSqlQuery(AH, buf->data, PGRES_TUPLES_OK);
|
||||||
|
|
||||||
for (int i = 0; i < PQntuples(res); i++)
|
for (int i = 0; i < PQntuples(res); i++)
|
||||||
{
|
makeAlterConfigCommand(conn, PQgetvalue(res, i, 0),
|
||||||
char *userset = NULL;
|
|
||||||
|
|
||||||
if (AH->remoteVersion >= 160000)
|
|
||||||
userset = PQgetvalue(res, i, 1);
|
|
||||||
makeAlterConfigCommand(conn, PQgetvalue(res, i, 0), userset,
|
|
||||||
"DATABASE", dbname, NULL, NULL,
|
"DATABASE", dbname, NULL, NULL,
|
||||||
outbuf);
|
outbuf);
|
||||||
}
|
|
||||||
|
|
||||||
PQclear(res);
|
PQclear(res);
|
||||||
|
|
||||||
/* Now look for role-and-database-specific options */
|
/* Now look for role-and-database-specific options */
|
||||||
printfPQExpBuffer(buf, "SELECT rolname, unnest(setconfig)");
|
printfPQExpBuffer(buf, "SELECT rolname, unnest(setconfig) "
|
||||||
if (AH->remoteVersion >= 160000)
|
"FROM pg_db_role_setting s, pg_roles r "
|
||||||
appendPQExpBufferStr(buf, ", unnest(setuser)");
|
|
||||||
appendPQExpBuffer(buf, " FROM pg_db_role_setting s, pg_roles r "
|
|
||||||
"WHERE setrole = r.oid AND setdatabase = '%u'::oid",
|
"WHERE setrole = r.oid AND setdatabase = '%u'::oid",
|
||||||
dboid);
|
dboid);
|
||||||
|
|
||||||
res = ExecuteSqlQuery(AH, buf->data, PGRES_TUPLES_OK);
|
res = ExecuteSqlQuery(AH, buf->data, PGRES_TUPLES_OK);
|
||||||
|
|
||||||
for (int i = 0; i < PQntuples(res); i++)
|
for (int i = 0; i < PQntuples(res); i++)
|
||||||
{
|
makeAlterConfigCommand(conn, PQgetvalue(res, i, 1),
|
||||||
char *userset = NULL;
|
|
||||||
|
|
||||||
if (AH->remoteVersion >= 160000)
|
|
||||||
userset = PQgetvalue(res, i, 2);
|
|
||||||
makeAlterConfigCommand(conn, PQgetvalue(res, i, 1), userset,
|
|
||||||
"ROLE", PQgetvalue(res, i, 0),
|
"ROLE", PQgetvalue(res, i, 0),
|
||||||
"DATABASE", dbname,
|
"DATABASE", dbname,
|
||||||
outbuf);
|
outbuf);
|
||||||
}
|
|
||||||
|
|
||||||
PQclear(res);
|
PQclear(res);
|
||||||
|
|
||||||
|
@ -1385,10 +1385,7 @@ dumpUserConfig(PGconn *conn, const char *username)
|
|||||||
PQExpBuffer buf = createPQExpBuffer();
|
PQExpBuffer buf = createPQExpBuffer();
|
||||||
PGresult *res;
|
PGresult *res;
|
||||||
|
|
||||||
printfPQExpBuffer(buf, "SELECT unnest(setconfig)");
|
printfPQExpBuffer(buf, "SELECT unnest(setconfig) FROM pg_db_role_setting "
|
||||||
if (server_version >= 160000)
|
|
||||||
appendPQExpBufferStr(buf, ", unnest(setuser)");
|
|
||||||
appendPQExpBuffer(buf, " FROM pg_db_role_setting "
|
|
||||||
"WHERE setdatabase = 0 AND setrole = "
|
"WHERE setdatabase = 0 AND setrole = "
|
||||||
"(SELECT oid FROM %s WHERE rolname = ",
|
"(SELECT oid FROM %s WHERE rolname = ",
|
||||||
role_catalog);
|
role_catalog);
|
||||||
@ -1402,13 +1399,8 @@ dumpUserConfig(PGconn *conn, const char *username)
|
|||||||
|
|
||||||
for (int i = 0; i < PQntuples(res); i++)
|
for (int i = 0; i < PQntuples(res); i++)
|
||||||
{
|
{
|
||||||
char *userset = NULL;
|
|
||||||
|
|
||||||
if (server_version >= 160000)
|
|
||||||
userset = PQgetvalue(res, i, 1);
|
|
||||||
|
|
||||||
resetPQExpBuffer(buf);
|
resetPQExpBuffer(buf);
|
||||||
makeAlterConfigCommand(conn, PQgetvalue(res, i, 0), userset,
|
makeAlterConfigCommand(conn, PQgetvalue(res, i, 0),
|
||||||
"ROLE", username, NULL, NULL,
|
"ROLE", username, NULL, NULL,
|
||||||
buf);
|
buf);
|
||||||
fprintf(OPF, "%s", buf->data);
|
fprintf(OPF, "%s", buf->data);
|
||||||
|
@ -3776,16 +3776,13 @@ listDbRoleSettings(const char *pattern, const char *pattern2)
|
|||||||
initPQExpBuffer(&buf);
|
initPQExpBuffer(&buf);
|
||||||
|
|
||||||
printfPQExpBuffer(&buf, "SELECT rolname AS \"%s\", datname AS \"%s\",\n"
|
printfPQExpBuffer(&buf, "SELECT rolname AS \"%s\", datname AS \"%s\",\n"
|
||||||
"pg_catalog.array_to_string(setconfig, E'\\n') AS \"%s\"",
|
"pg_catalog.array_to_string(setconfig, E'\\n') AS \"%s\"\n"
|
||||||
|
"FROM pg_catalog.pg_db_role_setting s\n"
|
||||||
|
"LEFT JOIN pg_catalog.pg_database d ON d.oid = setdatabase\n"
|
||||||
|
"LEFT JOIN pg_catalog.pg_roles r ON r.oid = setrole\n",
|
||||||
gettext_noop("Role"),
|
gettext_noop("Role"),
|
||||||
gettext_noop("Database"),
|
gettext_noop("Database"),
|
||||||
gettext_noop("Settings"));
|
gettext_noop("Settings"));
|
||||||
if (pset.sversion >= 160000)
|
|
||||||
appendPQExpBuffer(&buf, ",\npg_catalog.array_to_string(setuser, E'\\n') AS \"%s\"",
|
|
||||||
gettext_noop("User set"));
|
|
||||||
appendPQExpBuffer(&buf, "\nFROM pg_catalog.pg_db_role_setting s\n"
|
|
||||||
"LEFT JOIN pg_catalog.pg_database d ON d.oid = setdatabase\n"
|
|
||||||
"LEFT JOIN pg_catalog.pg_roles r ON r.oid = setrole\n");
|
|
||||||
if (!validateSQLNamePattern(&buf, pattern, false, false,
|
if (!validateSQLNamePattern(&buf, pattern, false, false,
|
||||||
NULL, "r.rolname", NULL, NULL, &havewhere, 1))
|
NULL, "r.rolname", NULL, NULL, &havewhere, 1))
|
||||||
goto error_return;
|
goto error_return;
|
||||||
|
@ -4515,10 +4515,6 @@ psql_completion(const char *text, int start, int end)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Complete ALTER DATABASE|ROLE|USER ... SET ... TO ... USER SET */
|
|
||||||
else if (HeadMatches("ALTER", "DATABASE|ROLE|USER") &&
|
|
||||||
TailMatches("SET", MatchAny, "TO|=", MatchAny))
|
|
||||||
COMPLETE_WITH("USER SET");
|
|
||||||
|
|
||||||
/* START TRANSACTION */
|
/* START TRANSACTION */
|
||||||
else if (Matches("START"))
|
else if (Matches("START"))
|
||||||
|
@ -57,6 +57,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* yyyymmddN */
|
/* yyyymmddN */
|
||||||
#define CATALOG_VERSION_NO 202305171
|
#define CATALOG_VERSION_NO 202305172
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -41,8 +41,6 @@ CATALOG(pg_db_role_setting,2964,DbRoleSettingRelationId) BKI_SHARED_RELATION
|
|||||||
|
|
||||||
#ifdef CATALOG_VARLEN /* variable-length fields start here */
|
#ifdef CATALOG_VARLEN /* variable-length fields start here */
|
||||||
text setconfig[1]; /* GUC settings to apply at login */
|
text setconfig[1]; /* GUC settings to apply at login */
|
||||||
|
|
||||||
bool setuser[1]; /* USER SET flags for GUC settings */
|
|
||||||
#endif
|
#endif
|
||||||
} FormData_pg_db_role_setting;
|
} FormData_pg_db_role_setting;
|
||||||
|
|
||||||
|
@ -2445,7 +2445,6 @@ typedef struct VariableSetStmt
|
|||||||
char *name; /* variable to be set */
|
char *name; /* variable to be set */
|
||||||
List *args; /* List of A_Const nodes */
|
List *args; /* List of A_Const nodes */
|
||||||
bool is_local; /* SET LOCAL? */
|
bool is_local; /* SET LOCAL? */
|
||||||
bool user_set;
|
|
||||||
} VariableSetStmt;
|
} VariableSetStmt;
|
||||||
|
|
||||||
/* ----------------------
|
/* ----------------------
|
||||||
|
@ -391,14 +391,11 @@ extern void AlterSystemSetConfigFile(AlterSystemStmt *altersysstmt);
|
|||||||
extern char *GetConfigOptionByName(const char *name, const char **varname,
|
extern char *GetConfigOptionByName(const char *name, const char **varname,
|
||||||
bool missing_ok);
|
bool missing_ok);
|
||||||
|
|
||||||
extern void ProcessGUCArray(ArrayType *array, ArrayType *usersetArray,
|
extern void ProcessGUCArray(ArrayType *array,
|
||||||
GucContext context, GucSource source, GucAction action);
|
GucContext context, GucSource source, GucAction action);
|
||||||
extern ArrayType *GUCArrayAdd(ArrayType *array, ArrayType **usersetArray,
|
extern ArrayType *GUCArrayAdd(ArrayType *array, const char *name, const char *value);
|
||||||
const char *name, const char *value,
|
extern ArrayType *GUCArrayDelete(ArrayType *array, const char *name);
|
||||||
bool user_set);
|
extern ArrayType *GUCArrayReset(ArrayType *array);
|
||||||
extern ArrayType *GUCArrayDelete(ArrayType *array, ArrayType **usersetArray,
|
|
||||||
const char *name);
|
|
||||||
extern ArrayType *GUCArrayReset(ArrayType *array, ArrayType **usersetArray);
|
|
||||||
|
|
||||||
extern void *guc_malloc(int elevel, size_t size);
|
extern void *guc_malloc(int elevel, size_t size);
|
||||||
extern pg_nodiscard void *guc_realloc(int elevel, void *old, size_t size);
|
extern pg_nodiscard void *guc_realloc(int elevel, void *old, size_t size);
|
||||||
|
@ -25,7 +25,6 @@ SUBDIRS = \
|
|||||||
test_misc \
|
test_misc \
|
||||||
test_oat_hooks \
|
test_oat_hooks \
|
||||||
test_parser \
|
test_parser \
|
||||||
test_pg_db_role_setting \
|
|
||||||
test_pg_dump \
|
test_pg_dump \
|
||||||
test_predtest \
|
test_predtest \
|
||||||
test_rbtree \
|
test_rbtree \
|
||||||
|
@ -22,7 +22,6 @@ subdir('test_lfind')
|
|||||||
subdir('test_misc')
|
subdir('test_misc')
|
||||||
subdir('test_oat_hooks')
|
subdir('test_oat_hooks')
|
||||||
subdir('test_parser')
|
subdir('test_parser')
|
||||||
subdir('test_pg_db_role_setting')
|
|
||||||
subdir('test_pg_dump')
|
subdir('test_pg_dump')
|
||||||
subdir('test_predtest')
|
subdir('test_predtest')
|
||||||
subdir('test_rbtree')
|
subdir('test_rbtree')
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
# Generated subdirectories
|
|
||||||
/log/
|
|
||||||
/results/
|
|
||||||
/tmp_check/
|
|
@ -1,26 +0,0 @@
|
|||||||
# src/test/modules/test_pg_db_role_setting/Makefile
|
|
||||||
|
|
||||||
MODULE_big = test_pg_db_role_setting
|
|
||||||
OBJS = \
|
|
||||||
$(WIN32RES) \
|
|
||||||
test_pg_db_role_setting.o
|
|
||||||
EXTENSION = test_pg_db_role_setting
|
|
||||||
DATA = test_pg_db_role_setting--1.0.sql
|
|
||||||
|
|
||||||
PGFILEDESC = "test_pg_db_role_setting - tests for default GUC values stored in pg_db_role_settings"
|
|
||||||
|
|
||||||
REGRESS = test_pg_db_role_setting
|
|
||||||
|
|
||||||
# disable installcheck for now
|
|
||||||
NO_INSTALLCHECK = 1
|
|
||||||
|
|
||||||
ifdef USE_PGXS
|
|
||||||
PG_CONFIG = pg_config
|
|
||||||
PGXS := $(shell $(PG_CONFIG) --pgxs)
|
|
||||||
include $(PGXS)
|
|
||||||
else
|
|
||||||
subdir = src/test/modules/test_pg_db_role_setting
|
|
||||||
top_builddir = ../../../..
|
|
||||||
include $(top_builddir)/src/Makefile.global
|
|
||||||
include $(top_srcdir)/contrib/contrib-global.mk
|
|
||||||
endif
|
|
@ -1,143 +0,0 @@
|
|||||||
CREATE EXTENSION test_pg_db_role_setting;
|
|
||||||
CREATE USER regress_super_user SUPERUSER;
|
|
||||||
CREATE USER regress_regular_user;
|
|
||||||
\c - regress_regular_user
|
|
||||||
-- successfully set a placeholder value
|
|
||||||
SET test_pg_db_role_setting.superuser_param = 'aaa';
|
|
||||||
-- module is loaded, the placeholder value is thrown away
|
|
||||||
SELECT load_test_pg_db_role_setting();
|
|
||||||
WARNING: permission denied to set parameter "test_pg_db_role_setting.superuser_param"
|
|
||||||
load_test_pg_db_role_setting
|
|
||||||
------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
SHOW test_pg_db_role_setting.superuser_param;
|
|
||||||
test_pg_db_role_setting.superuser_param
|
|
||||||
-----------------------------------------
|
|
||||||
superuser_param_value
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
SHOW test_pg_db_role_setting.user_param;
|
|
||||||
test_pg_db_role_setting.user_param
|
|
||||||
------------------------------------
|
|
||||||
user_param_value
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
\c - regress_regular_user
|
|
||||||
-- fail, not privileges
|
|
||||||
ALTER ROLE regress_regular_user SET test_pg_db_role_setting.superuser_param = 'aaa';
|
|
||||||
ERROR: permission denied to set parameter "test_pg_db_role_setting.superuser_param"
|
|
||||||
ALTER ROLE regress_regular_user SET test_pg_db_role_setting.user_param = 'bbb';
|
|
||||||
ERROR: permission denied to set parameter "test_pg_db_role_setting.user_param"
|
|
||||||
-- success for USER SET parameters
|
|
||||||
ALTER ROLE regress_regular_user SET test_pg_db_role_setting.superuser_param = 'aaa' USER SET;
|
|
||||||
ALTER ROLE regress_regular_user SET test_pg_db_role_setting.user_param = 'bbb' USER SET;
|
|
||||||
\drds regress_regular_user
|
|
||||||
List of settings
|
|
||||||
Role | Database | Settings | User set
|
|
||||||
----------------------+----------+---------------------------------------------+----------
|
|
||||||
regress_regular_user | | test_pg_db_role_setting.superuser_param=aaa+| t +
|
|
||||||
| | test_pg_db_role_setting.user_param=bbb | t
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
\c - regress_regular_user
|
|
||||||
-- successfully set placeholders
|
|
||||||
SHOW test_pg_db_role_setting.superuser_param;
|
|
||||||
test_pg_db_role_setting.superuser_param
|
|
||||||
-----------------------------------------
|
|
||||||
aaa
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
SHOW test_pg_db_role_setting.user_param;
|
|
||||||
test_pg_db_role_setting.user_param
|
|
||||||
------------------------------------
|
|
||||||
bbb
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
-- module is loaded, the placeholder value of superuser param is thrown away
|
|
||||||
SELECT load_test_pg_db_role_setting();
|
|
||||||
WARNING: permission denied to set parameter "test_pg_db_role_setting.superuser_param"
|
|
||||||
load_test_pg_db_role_setting
|
|
||||||
------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
SHOW test_pg_db_role_setting.superuser_param;
|
|
||||||
test_pg_db_role_setting.superuser_param
|
|
||||||
-----------------------------------------
|
|
||||||
superuser_param_value
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
SHOW test_pg_db_role_setting.user_param;
|
|
||||||
test_pg_db_role_setting.user_param
|
|
||||||
------------------------------------
|
|
||||||
bbb
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
\c - regress_super_user
|
|
||||||
ALTER ROLE regress_regular_user SET test_pg_db_role_setting.superuser_param = 'aaa';
|
|
||||||
\drds regress_regular_user
|
|
||||||
List of settings
|
|
||||||
Role | Database | Settings | User set
|
|
||||||
----------------------+----------+---------------------------------------------+----------
|
|
||||||
regress_regular_user | | test_pg_db_role_setting.superuser_param=aaa+| f +
|
|
||||||
| | test_pg_db_role_setting.user_param=bbb | t
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
\c - regress_regular_user
|
|
||||||
-- don't have a priviledge to change superuser value to user set one
|
|
||||||
ALTER ROLE regress_regular_user SET test_pg_db_role_setting.superuser_param = 'ccc' USER SET;
|
|
||||||
ERROR: permission denied to set parameter "test_pg_db_role_setting.superuser_param"
|
|
||||||
\c - regress_super_user
|
|
||||||
SELECT load_test_pg_db_role_setting();
|
|
||||||
load_test_pg_db_role_setting
|
|
||||||
------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
-- give the privilege to set SUSET param to the regular user
|
|
||||||
GRANT SET ON PARAMETER test_pg_db_role_setting.superuser_param TO regress_regular_user;
|
|
||||||
\c - regress_regular_user
|
|
||||||
ALTER ROLE regress_regular_user SET test_pg_db_role_setting.superuser_param = 'ccc';
|
|
||||||
\drds regress_regular_user
|
|
||||||
List of settings
|
|
||||||
Role | Database | Settings | User set
|
|
||||||
----------------------+----------+---------------------------------------------+----------
|
|
||||||
regress_regular_user | | test_pg_db_role_setting.superuser_param=ccc+| f +
|
|
||||||
| | test_pg_db_role_setting.user_param=bbb | t
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
\c - regress_regular_user
|
|
||||||
-- successfully set placeholders
|
|
||||||
SHOW test_pg_db_role_setting.superuser_param;
|
|
||||||
test_pg_db_role_setting.superuser_param
|
|
||||||
-----------------------------------------
|
|
||||||
ccc
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
SHOW test_pg_db_role_setting.user_param;
|
|
||||||
test_pg_db_role_setting.user_param
|
|
||||||
------------------------------------
|
|
||||||
bbb
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
-- module is loaded, and placeholder values are successfully set
|
|
||||||
SELECT load_test_pg_db_role_setting();
|
|
||||||
load_test_pg_db_role_setting
|
|
||||||
------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
SHOW test_pg_db_role_setting.superuser_param;
|
|
||||||
test_pg_db_role_setting.superuser_param
|
|
||||||
-----------------------------------------
|
|
||||||
ccc
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
SHOW test_pg_db_role_setting.user_param;
|
|
||||||
test_pg_db_role_setting.user_param
|
|
||||||
------------------------------------
|
|
||||||
bbb
|
|
||||||
(1 row)
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
|||||||
# Copyright (c) 2022-2023, PostgreSQL Global Development Group
|
|
||||||
|
|
||||||
test_pg_db_role_setting_sources = files(
|
|
||||||
'test_pg_db_role_setting.c',
|
|
||||||
)
|
|
||||||
|
|
||||||
if host_system == 'windows'
|
|
||||||
test_pg_db_role_setting_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
|
|
||||||
'--NAME', 'test_pg_db_role_setting',
|
|
||||||
'--FILEDESC', 'test_pg_db_role_setting - tests for default GUC values stored in pg_db_role_settings',])
|
|
||||||
endif
|
|
||||||
|
|
||||||
test_pg_db_role_setting = shared_module('test_pg_db_role_setting',
|
|
||||||
test_pg_db_role_setting_sources,
|
|
||||||
kwargs: pg_test_mod_args,
|
|
||||||
)
|
|
||||||
test_install_libs += test_pg_db_role_setting
|
|
||||||
|
|
||||||
test_install_data += files(
|
|
||||||
'test_pg_db_role_setting.control',
|
|
||||||
'test_pg_db_role_setting--1.0.sql',
|
|
||||||
)
|
|
||||||
|
|
||||||
tests += {
|
|
||||||
'name': 'test_pg_db_role_setting',
|
|
||||||
'sd': meson.current_source_dir(),
|
|
||||||
'bd': meson.current_build_dir(),
|
|
||||||
'regress': {
|
|
||||||
'sql': [
|
|
||||||
'test_pg_db_role_setting',
|
|
||||||
],
|
|
||||||
'runningcheck': false,
|
|
||||||
},
|
|
||||||
}
|
|
@ -1,63 +0,0 @@
|
|||||||
CREATE EXTENSION test_pg_db_role_setting;
|
|
||||||
CREATE USER regress_super_user SUPERUSER;
|
|
||||||
CREATE USER regress_regular_user;
|
|
||||||
|
|
||||||
\c - regress_regular_user
|
|
||||||
-- successfully set a placeholder value
|
|
||||||
SET test_pg_db_role_setting.superuser_param = 'aaa';
|
|
||||||
|
|
||||||
-- module is loaded, the placeholder value is thrown away
|
|
||||||
SELECT load_test_pg_db_role_setting();
|
|
||||||
|
|
||||||
SHOW test_pg_db_role_setting.superuser_param;
|
|
||||||
SHOW test_pg_db_role_setting.user_param;
|
|
||||||
|
|
||||||
\c - regress_regular_user
|
|
||||||
-- fail, not privileges
|
|
||||||
ALTER ROLE regress_regular_user SET test_pg_db_role_setting.superuser_param = 'aaa';
|
|
||||||
ALTER ROLE regress_regular_user SET test_pg_db_role_setting.user_param = 'bbb';
|
|
||||||
-- success for USER SET parameters
|
|
||||||
ALTER ROLE regress_regular_user SET test_pg_db_role_setting.superuser_param = 'aaa' USER SET;
|
|
||||||
ALTER ROLE regress_regular_user SET test_pg_db_role_setting.user_param = 'bbb' USER SET;
|
|
||||||
|
|
||||||
\drds regress_regular_user
|
|
||||||
|
|
||||||
\c - regress_regular_user
|
|
||||||
-- successfully set placeholders
|
|
||||||
SHOW test_pg_db_role_setting.superuser_param;
|
|
||||||
SHOW test_pg_db_role_setting.user_param;
|
|
||||||
|
|
||||||
-- module is loaded, the placeholder value of superuser param is thrown away
|
|
||||||
SELECT load_test_pg_db_role_setting();
|
|
||||||
|
|
||||||
SHOW test_pg_db_role_setting.superuser_param;
|
|
||||||
SHOW test_pg_db_role_setting.user_param;
|
|
||||||
|
|
||||||
\c - regress_super_user
|
|
||||||
ALTER ROLE regress_regular_user SET test_pg_db_role_setting.superuser_param = 'aaa';
|
|
||||||
\drds regress_regular_user
|
|
||||||
|
|
||||||
\c - regress_regular_user
|
|
||||||
-- don't have a priviledge to change superuser value to user set one
|
|
||||||
ALTER ROLE regress_regular_user SET test_pg_db_role_setting.superuser_param = 'ccc' USER SET;
|
|
||||||
|
|
||||||
\c - regress_super_user
|
|
||||||
SELECT load_test_pg_db_role_setting();
|
|
||||||
-- give the privilege to set SUSET param to the regular user
|
|
||||||
GRANT SET ON PARAMETER test_pg_db_role_setting.superuser_param TO regress_regular_user;
|
|
||||||
|
|
||||||
\c - regress_regular_user
|
|
||||||
ALTER ROLE regress_regular_user SET test_pg_db_role_setting.superuser_param = 'ccc';
|
|
||||||
|
|
||||||
\drds regress_regular_user
|
|
||||||
|
|
||||||
\c - regress_regular_user
|
|
||||||
-- successfully set placeholders
|
|
||||||
SHOW test_pg_db_role_setting.superuser_param;
|
|
||||||
SHOW test_pg_db_role_setting.user_param;
|
|
||||||
|
|
||||||
-- module is loaded, and placeholder values are successfully set
|
|
||||||
SELECT load_test_pg_db_role_setting();
|
|
||||||
|
|
||||||
SHOW test_pg_db_role_setting.superuser_param;
|
|
||||||
SHOW test_pg_db_role_setting.user_param;
|
|
@ -1,7 +0,0 @@
|
|||||||
/* src/test/modules/test_pg_db_role_setting/test_pg_db_role_setting--1.0.sql */
|
|
||||||
|
|
||||||
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
|
|
||||||
\echo Use "CREATE EXTENSION test_pg_db_role_setting" to load this file. \quit
|
|
||||||
|
|
||||||
CREATE FUNCTION load_test_pg_db_role_setting() RETURNS void
|
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE C;
|
|
@ -1,57 +0,0 @@
|
|||||||
/*--------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* test_pg_db_role_setting.c
|
|
||||||
* Code for testing mandatory access control (MAC) using object access hooks.
|
|
||||||
*
|
|
||||||
* Copyright (c) 2022-2023, PostgreSQL Global Development Group
|
|
||||||
*
|
|
||||||
* IDENTIFICATION
|
|
||||||
* src/test/modules/test_pg_db_role_setting/test_pg_db_role_setting.c
|
|
||||||
*
|
|
||||||
* -------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "postgres.h"
|
|
||||||
|
|
||||||
#include "utils/guc.h"
|
|
||||||
|
|
||||||
PG_MODULE_MAGIC;
|
|
||||||
|
|
||||||
PG_FUNCTION_INFO_V1(load_test_pg_db_role_setting);
|
|
||||||
|
|
||||||
static char *superuser_param;
|
|
||||||
static char *user_param;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Module load callback
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
_PG_init(void)
|
|
||||||
{
|
|
||||||
DefineCustomStringVariable("test_pg_db_role_setting.superuser_param",
|
|
||||||
"Sample superuser parameter.",
|
|
||||||
NULL,
|
|
||||||
&superuser_param,
|
|
||||||
"superuser_param_value",
|
|
||||||
PGC_SUSET,
|
|
||||||
0,
|
|
||||||
NULL, NULL, NULL);
|
|
||||||
|
|
||||||
DefineCustomStringVariable("test_pg_db_role_setting.user_param",
|
|
||||||
"Sample user parameter.",
|
|
||||||
NULL,
|
|
||||||
&user_param,
|
|
||||||
"user_param_value",
|
|
||||||
PGC_USERSET,
|
|
||||||
0,
|
|
||||||
NULL, NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Empty function, which is used just to trigger load of this module.
|
|
||||||
*/
|
|
||||||
Datum
|
|
||||||
load_test_pg_db_role_setting(PG_FUNCTION_ARGS)
|
|
||||||
{
|
|
||||||
PG_RETURN_VOID();
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
# test_pg_db_role_setting extension
|
|
||||||
comment = 'test_pg_db_role_setting - tests for default GUC values stored in pg_db_role_setting'
|
|
||||||
default_version = '1.0'
|
|
||||||
module_pathname = '$libdir/test_pg_db_role_setting'
|
|
||||||
relocatable = true
|
|
||||||
superuser = false
|
|
||||||
trusted = true
|
|
@ -6218,8 +6218,8 @@ List of schemas
|
|||||||
|
|
||||||
\drds "no.such.setting"
|
\drds "no.such.setting"
|
||||||
List of settings
|
List of settings
|
||||||
Role | Database | Settings | User set
|
Role | Database | Settings
|
||||||
------+----------+----------+----------
|
------+----------+----------
|
||||||
(0 rows)
|
(0 rows)
|
||||||
|
|
||||||
\dRp "no.such.publication"
|
\dRp "no.such.publication"
|
||||||
|
Reference in New Issue
Block a user