From 1aac2c852a2ccd817daf2dac99cf450e7822eb20 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut <peter_e@gmx.net> Date: Fri, 1 Mar 2002 22:45:19 +0000 Subject: [PATCH] User and database-specific session defaults for run-time configuration variables. New commands ALTER DATABASE ... SET and ALTER USER ... SET. --- doc/src/sgml/catalogs.sgml | 16 ++- doc/src/sgml/ref/allfiles.sgml | 3 +- doc/src/sgml/ref/alter_database.sgml | 169 +++++++++++++++++++++++++++ doc/src/sgml/ref/alter_user.sgml | 53 ++++++++- doc/src/sgml/reference.sgml | 3 +- doc/src/sgml/release.sgml | 4 +- doc/src/sgml/runtime.sgml | 11 +- src/backend/commands/dbcommands.c | 79 ++++++++++++- src/backend/commands/user.c | 89 +++++++++++++- src/backend/nodes/copyfuncs.c | 36 +++++- src/backend/nodes/equalfuncs.c | 34 +++++- src/backend/parser/gram.y | 59 +++++++++- src/backend/tcop/postgres.c | 12 +- src/backend/tcop/utility.c | 10 +- src/backend/utils/init/miscinit.c | 20 +++- src/backend/utils/init/postinit.c | 26 ++++- src/backend/utils/misc/guc.c | 156 ++++++++++++++++++++++++- src/bin/initdb/initdb.sh | 5 +- src/include/catalog/catversion.h | 4 +- src/include/catalog/pg_attribute.h | 4 +- src/include/catalog/pg_class.h | 6 +- src/include/catalog/pg_database.h | 8 +- src/include/catalog/pg_shadow.h | 8 +- src/include/commands/dbcommands.h | 5 +- src/include/commands/user.h | 3 +- src/include/nodes/nodes.h | 4 +- src/include/nodes/parsenodes.h | 24 +++- src/include/utils/guc.h | 7 +- src/test/regress/expected/rules.out | 2 +- 29 files changed, 812 insertions(+), 48 deletions(-) create mode 100644 doc/src/sgml/ref/alter_database.sgml diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml index 20adc19bab8..aab0a906d9b 100644 --- a/doc/src/sgml/catalogs.sgml +++ b/doc/src/sgml/catalogs.sgml @@ -1,6 +1,6 @@ <!-- Documentation of the system catalogs, directed toward PostgreSQL developers - $Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.30 2002/02/18 23:10:59 petere Exp $ + $Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.31 2002/03/01 22:45:03 petere Exp $ --> <chapter id="catalogs"> @@ -889,6 +889,13 @@ or an absolute path, depending how it was entered. </entry> </row> + + <row> + <entry>datconfig</entry> + <entry><type>text[]</type></entry> + <entry></entry> + <entry>Session defaults for run-time configuration variables</entry> + </row> </tbody> </tgroup> </table> @@ -1980,6 +1987,13 @@ <entry></entry> <entry>Account expiry time (only used for password authentication)</entry> </row> + + <row> + <entry>useconfig</entry> + <entry><type>text[]</type></entry> + <entry></entry> + <entry>Session defaults for run-time configuration variables</entry> + </row> </tbody> </tgroup> </table> diff --git a/doc/src/sgml/ref/allfiles.sgml b/doc/src/sgml/ref/allfiles.sgml index ef29c0e8b98..94f1226c24f 100644 --- a/doc/src/sgml/ref/allfiles.sgml +++ b/doc/src/sgml/ref/allfiles.sgml @@ -1,5 +1,5 @@ <!-- -$Header: /cvsroot/pgsql/doc/src/sgml/ref/allfiles.sgml,v 1.32 2002/01/15 05:05:49 tgl Exp $ +$Header: /cvsroot/pgsql/doc/src/sgml/ref/allfiles.sgml,v 1.33 2002/03/01 22:45:07 petere Exp $ PostgreSQL documentation Complete list of usable sgml source files in this directory. --> @@ -37,6 +37,7 @@ Complete list of usable sgml source files in this directory. <!-- SQL commands --> <!entity abort system "abort.sgml"> +<!entity alterDatabase system "alter_database.sgml"> <!entity alterGroup system "alter_group.sgml"> <!entity alterTable system "alter_table.sgml"> <!entity alterUser system "alter_user.sgml"> diff --git a/doc/src/sgml/ref/alter_database.sgml b/doc/src/sgml/ref/alter_database.sgml new file mode 100644 index 00000000000..b1aa34262a1 --- /dev/null +++ b/doc/src/sgml/ref/alter_database.sgml @@ -0,0 +1,169 @@ +<!-- +$Header: /cvsroot/pgsql/doc/src/sgml/ref/alter_database.sgml,v 1.1 2002/03/01 22:45:07 petere Exp $ +PostgreSQL documentation +--> + +<refentry id="SQL-ALTERDATABASE"> + <refmeta> + <refentrytitle id="sql-alterdatabase-title">ALTER DATABASE</refentrytitle> + <refmiscinfo>SQL - Language Statements</refmiscinfo> + </refmeta> + + <refnamediv> + <refname>ALTER DATABASE</refname> + <refpurpose>change a database</refpurpose> + </refnamediv> + + <refsynopsisdiv> +<synopsis> +ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> SET <replaceable>variable</replaceable> { TO | = } { <replaceable>value</replaceable> | DEFAULT } +ALTER DATABASE <replaceable class="PARAMETER">name</replaceable> RESET <replaceable>variable</replaceable> +</synopsis> + </refsynopsisdiv> + + <refsect1> + <title>Description</title> + + <para> + <command>ALTER DATABASE</command> is used to change the session + default of a run-time configuration variable for a + <productname>PostgreSQL</productname> database. Whenever a new + session is subsequently started, <literal>SET + <replaceable>variable</replaceable> TO + <replaceable>value</replaceable></literal> is effectively executed + before the start of the session. + </para> + + <para> + Only a database owner can change the session defaults for a + database. Superusers can change the session defaults of any + database. + </para> + + <refsect2> + <title>Parameters</title> + + <para> + <variablelist> + <varlistentry> + <term><replaceable class="PARAMETER">name</replaceable></term> + <listitem> + <para> + The name of the database whose session defaults are to be altered. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><replaceable>variable</replaceable></term> + <term><replaceable>value</replaceable></term> + <listitem> + <para> + Set the session default for this database of the specified + configuration variable to the given value. If + <replaceable>value</replaceable> is <literal>DEFAULT</literal> + or, equivalently, <literal>RESET</literal> is used, the + database-specific variable setting is removed and the default + setting will be inherited in new sessions. Use <literal>RESET + ALL</literal> to clear all settings. + </para> + + <para> + See <xref linkend="sql-set" endterm="sql-set-title"> and the + <citetitle>Administrator's Guide</citetitle> for more + information about allowed variable names and values. + </para> + </listitem> + </varlistentry> + </variablelist> + </para> + </refsect2> + </refsect1> + + <refsect1> + <title>Diagnostics</title> + + <para> + <variablelist> + <varlistentry> + <term><computeroutput>ALTER DATABASE</computeroutput></term> + <listitem> + <para> + Message returned if the alteration was successful. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><computeroutput>ERROR: database "dbname" does not exist</computeroutput></term> + <listitem> + <para> + Error message returned if the specified database is not known + to the system. + </para> + </listitem> + </varlistentry> + </variablelist> + </para> + </refsect1> + + <refsect1> + <title>Notes</title> + + <para> + Using <xref linkend="sql-alteruser" endterm="sql-alteruser-title">, + it is also possible to tie a session default to a specific user + rather than a database. + </para> + </refsect1> + + <refsect1> + <title>Examples</title> + + <para> + To disable index scans by default in the database + <literal>test</literal>: + +<programlisting> +ALTER DATABASE test SET enable_indexscan TO off; +</programlisting> + </para> + </refsect1> + + <refsect1> + <title>Compatibility</title> + + <para> + The <command>ALTER DATABASE</command> statement is a + <productname>PostgreSQL</productname> extension. + </para> + </refsect1> + + <refsect1> + <title>See Also</title> + + <simplelist type="inline"> + <member><xref linkend="sql-alteruser" endterm="sql-alteruser-title"></member> + <member><xref linkend="sql-createdatabase" endterm="sql-createdatabase-title"></member> + <member><xref linkend="sql-dropdatabase" endterm="sql-dropdatabase-title"></member> + <member><xref linkend="sql-set" endterm="sql-set-title"></member> + </simplelist> + </refsect1> +</refentry> + +<!-- Keep this comment at the end of the file +Local variables: +mode: sgml +sgml-omittag:nil +sgml-shorttag:t +sgml-minimize-attributes:nil +sgml-always-quote-attributes:t +sgml-indent-step:1 +sgml-indent-data:t +sgml-parent-document:nil +sgml-default-dtd-file:"../reference.ced" +sgml-exposed-tags:nil +sgml-local-catalogs:"/usr/lib/sgml/catalog" +sgml-local-ecat-files:nil +End: +--> diff --git a/doc/src/sgml/ref/alter_user.sgml b/doc/src/sgml/ref/alter_user.sgml index 0156565eb50..3819bf8d964 100644 --- a/doc/src/sgml/ref/alter_user.sgml +++ b/doc/src/sgml/ref/alter_user.sgml @@ -1,5 +1,5 @@ <!-- -$Header: /cvsroot/pgsql/doc/src/sgml/ref/alter_user.sgml,v 1.19 2002/02/27 21:14:53 petere Exp $ +$Header: /cvsroot/pgsql/doc/src/sgml/ref/alter_user.sgml,v 1.20 2002/03/01 22:45:07 petere Exp $ PostgreSQL documentation --> @@ -24,6 +24,9 @@ where <replaceable class="PARAMETER">option</replaceable> can be: | CREATEDB | NOCREATEDB | CREATEUSER | NOCREATEUSER | VALID UNTIL '<replaceable class="PARAMETER">abstime</replaceable>' + +ALTER USER <replaceable class="PARAMETER">username</replaceable> SET <replaceable>variable</replaceable> { TO | = } { <replaceable>value</replaceable> | DEFAULT } +ALTER USER <replaceable class="PARAMETER">username</replaceable> RESET <replaceable>variable</replaceable> </synopsis> </refsynopsisdiv> @@ -37,9 +40,22 @@ where <replaceable class="PARAMETER">option</replaceable> can be: </para> <para> - Only a database superuser can change privileges and password - expiration with this command. Ordinary users can only change their - own password. + The first variant of this command in the synopsis changes certain + global user privileges and authentication settings. (See below for + details.) Only a database superuser can change privileges and + password expiration with this command. Ordinary users can only + change their own password. + </para> + + <para> + The second and the third variant change a user's session default of + a specified configuration variable. Whenever the user subsequently + starts a new session, <literal>SET + <replaceable>variable</replaceable> TO + <replaceable>value</replaceable></literal> is effectively executed + before the start of the session. Ordinary users can change their + own session defaults. Superusers can change anyone's session + defaults. </para> <refsect2> @@ -113,6 +129,28 @@ where <replaceable class="PARAMETER">option</replaceable> can be: </para> </listitem> </varlistentry> + + <varlistentry> + <term><replaceable>variable</replaceable></term> + <term><replaceable>value</replaceable></term> + <listitem> + <para> + Set this user's session default of the specified configuration + variable to the given value. If + <replaceable>value</replaceable> is <literal>DEFAULT</literal> + or, equivalently, <literal>RESET</literal> is used, the + user-specific variable setting is removed and the user will + inherit the default setting in new sessions. Use + <literal>RESET ALL</literal> to clear all settings. + </para> + + <para> + See <xref linkend="sql-set" endterm="sql-set-title"> and the + <citetitle>Administrator's Guide</citetitle> for more + information about allowed variable names and values. + </para> + </listitem> + </varlistentry> </variablelist> </para> </refsect2> @@ -159,6 +197,12 @@ where <replaceable class="PARAMETER">option</replaceable> can be: Use <xref linkend="SQL-ALTERGROUP" endterm="SQL-ALTERGROUP-title"> to do that. </para> + + <para> + Using <xref linkend="sql-alterdatabase" + endterm="sql-alterdatabase-title">, it is also possible to tie a + session default to a specific database rather than a user. + </para> </refsect1> <refsect1> @@ -214,6 +258,7 @@ ALTER USER miriam CREATEUSER CREATEDB; <simplelist type="inline"> <member><xref linkend="sql-createuser" endterm="sql-createuser-title"></member> <member><xref linkend="sql-dropuser" endterm="sql-dropuser-title"></member> + <member><xref linkend="sql-set" endterm="sql-set-title"></member> </simplelist> </refsect1> </refentry> diff --git a/doc/src/sgml/reference.sgml b/doc/src/sgml/reference.sgml index a5b8cfbf163..27f218d33fb 100644 --- a/doc/src/sgml/reference.sgml +++ b/doc/src/sgml/reference.sgml @@ -1,5 +1,5 @@ <!-- reference.sgml -$Header: /cvsroot/pgsql/doc/src/sgml/reference.sgml,v 1.20 2002/01/15 05:05:49 tgl Exp $ +$Header: /cvsroot/pgsql/doc/src/sgml/reference.sgml,v 1.21 2002/03/01 22:45:04 petere Exp $ PostgreSQL Reference Manual --> @@ -46,6 +46,7 @@ PostgreSQL Reference Manual </partintro> &abort; + &alterDatabase; &alterGroup; &alterTable; &alterUser; diff --git a/doc/src/sgml/release.sgml b/doc/src/sgml/release.sgml index edcdc9405aa..3801b8d1eab 100644 --- a/doc/src/sgml/release.sgml +++ b/doc/src/sgml/release.sgml @@ -1,5 +1,5 @@ <!-- -$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.118 2002/02/24 20:20:19 tgl Exp $ +$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.119 2002/03/01 22:45:04 petere Exp $ --> <appendix id="release"> @@ -28,6 +28,8 @@ Access privileges on functions Access privileges on procedural languages CREATE DATABASE has OWNER option so superuser can create DB for someone else Kerberos 5 support now works with Heimdal +Database and user-specific session defaults of run-time configurations variables + (ALTER DATABASE ... SET and ALTER USER ... SET) ]]></literallayout> </sect1> diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index 2c0441fdcc9..3f46a3e9e4f 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1,5 +1,5 @@ <!-- -$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.103 2002/01/20 22:19:56 petere Exp $ +$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.104 2002/03/01 22:45:05 petere Exp $ --> <Chapter Id="runtime"> @@ -537,12 +537,17 @@ env PGOPTIONS='-c geqo=off' psql </para> <para> - Finally, some options can be changed in individual SQL sessions - with the <command>SET</command> command, for example + Some options can be changed in individual SQL sessions with the + <command>SET</command> command, for example <screen> => <userinput>SET ENABLE_SEQSCAN TO OFF;</userinput> </screen> See the SQL command language reference for details on the syntax. + Furthermore, it is possible to assign a set of option settings to + a user or a database. Whenever a session is started, the default + settings for the user and database involved are loaded. The + commands <literal>ALTER DATABASE</literal> and <literal>ALTER + USER</literal>, respectively, are used to set this up. </para> <sect2 id="runtime-config-optimizer"> diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c index 712df38ec51..3de94de9c6e 100644 --- a/src/backend/commands/dbcommands.c +++ b/src/backend/commands/dbcommands.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.83 2002/02/24 20:20:19 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.84 2002/03/01 22:45:08 petere Exp $ * *------------------------------------------------------------------------- */ @@ -32,8 +32,10 @@ #include "miscadmin.h" #include "storage/freespace.h" #include "storage/sinval.h" +#include "utils/array.h" #include "utils/builtins.h" #include "utils/fmgroids.h" +#include "utils/guc.h" #include "utils/lsyscache.h" #include "utils/syscache.h" @@ -287,6 +289,7 @@ createdb(const char *dbname, const char *dbowner, DirectFunctionCall1(textin, CStringGetDatum(dbpath ? dbpath : "")); memset(new_record_nulls, ' ', sizeof(new_record_nulls)); + new_record_nulls[Anum_pg_database_datconfig - 1] = 'n'; tuple = heap_formtuple(pg_database_dsc, new_record, new_record_nulls); @@ -446,6 +449,80 @@ dropdb(const char *dbname) +/* + * ALTER DATABASE name SET ... + */ +void +AlterDatabaseSet(AlterDatabaseSetStmt *stmt) +{ + char *valuestr; + HeapTuple tuple, + newtuple; + Relation rel; + ScanKeyData scankey; + HeapScanDesc scan; + Datum repl_val[Natts_pg_database]; + char repl_null[Natts_pg_database]; + char repl_repl[Natts_pg_database]; + int i; + + valuestr = (stmt->value + ? ((A_Const *) lfirst(stmt->value))->val.val.str + : NULL); + + rel = heap_openr(DatabaseRelationName, RowExclusiveLock); + ScanKeyEntryInitialize(&scankey, 0, Anum_pg_database_datname, + F_NAMEEQ, NameGetDatum(stmt->dbname)); + scan = heap_beginscan(rel, 0, SnapshotNow, 1, &scankey); + tuple = heap_getnext(scan, 0); + if (!HeapTupleIsValid(tuple)) + elog(ERROR, "database \"%s\" does not exist", stmt->dbname); + + if (!(superuser() + || ((Form_pg_database) GETSTRUCT(tuple))->datdba == GetUserId())) + elog(ERROR, "permission denied"); + + for (i = 0; i < Natts_pg_database; i++) + repl_repl[i] = ' '; + + repl_repl[Anum_pg_database_datconfig-1] = 'r'; + if (strcmp(stmt->variable, "all")==0 && stmt->value == NULL) + /* RESET ALL */ + repl_null[Anum_pg_database_datconfig-1] = 'n'; + else + { + Datum datum; + bool isnull; + ArrayType *a; + + repl_null[Anum_pg_database_datconfig-1] = ' '; + + datum = heap_getattr(tuple, Anum_pg_database_datconfig, + RelationGetDescr(rel), &isnull); + + if (valuestr) + a = GUCArrayAdd(isnull + ? NULL + : (ArrayType *) pg_detoast_datum((struct varlena *)datum), + stmt->variable, valuestr); + else + a = GUCArrayDelete(isnull + ? NULL + : (ArrayType *) pg_detoast_datum((struct varlena *)datum), + stmt->variable); + + repl_val[Anum_pg_database_datconfig-1] = PointerGetDatum(a); + } + + newtuple = heap_modifytuple(tuple, rel, repl_val, repl_null, repl_repl); + simple_heap_update(rel, &tuple->t_self, newtuple); + + heap_endscan(scan); + heap_close(rel, RowExclusiveLock); +} + + + /* * Helper functions */ diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c index a7ccd3768ff..a059207b0aa 100644 --- a/src/backend/commands/user.c +++ b/src/backend/commands/user.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.90 2001/11/05 17:46:25 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.91 2002/03/01 22:45:08 petere Exp $ * *------------------------------------------------------------------------- */ @@ -30,6 +30,7 @@ #include "utils/array.h" #include "utils/builtins.h" #include "utils/fmgroids.h" +#include "utils/guc.h" #include "utils/lsyscache.h" #include "utils/syscache.h" @@ -406,6 +407,8 @@ CreateUser(CreateUserStmt *stmt) new_record_nulls[Anum_pg_shadow_passwd - 1] = password ? ' ' : 'n'; new_record_nulls[Anum_pg_shadow_valuntil - 1] = validUntil ? ' ' : 'n'; + new_record_nulls[Anum_pg_shadow_useconfig - 1] = 'n'; + tuple = heap_formtuple(pg_shadow_dsc, new_record, new_record_nulls); /* @@ -653,6 +656,11 @@ AlterUser(AlterUserStmt *stmt) new_record_nulls[Anum_pg_shadow_valuntil - 1] = null ? 'n' : ' '; } + /* leave useconfig as is */ + new_record[Anum_pg_shadow_useconfig - 1] = + heap_getattr(tuple, Anum_pg_shadow_useconfig, pg_shadow_dsc, &null); + new_record_nulls[Anum_pg_shadow_useconfig - 1] = null ? 'n' : ' '; + new_tuple = heap_formtuple(pg_shadow_dsc, new_record, new_record_nulls); simple_heap_update(pg_shadow_rel, &tuple->t_self, new_tuple); @@ -684,6 +692,85 @@ AlterUser(AlterUserStmt *stmt) +/* + * ALTER USER ... SET + */ +void +AlterUserSet(AlterUserSetStmt *stmt) +{ + char *valuestr; + HeapTuple oldtuple, + newtuple; + Relation rel; + Datum repl_val[Natts_pg_shadow]; + char repl_null[Natts_pg_shadow]; + char repl_repl[Natts_pg_shadow]; + int i; + + valuestr = (stmt->value + ? ((A_Const *) lfirst(stmt->value))->val.val.str + : NULL); + + rel = heap_openr(ShadowRelationName, RowExclusiveLock); + oldtuple = SearchSysCache(SHADOWNAME, + PointerGetDatum(stmt->user), + 0, 0, 0); + if (!HeapTupleIsValid(oldtuple)) + elog(ERROR, "user \"%s\" does not exist", stmt->user); + + if (!(superuser() + || ((Form_pg_shadow) GETSTRUCT(oldtuple))->usesysid == GetUserId())) + elog(ERROR, "permission denied"); + + for (i = 0; i < Natts_pg_shadow; i++) + repl_repl[i] = ' '; + + repl_repl[Anum_pg_shadow_useconfig-1] = 'r'; + if (strcmp(stmt->variable, "all")==0 && stmt->value == NULL) + /* RESET ALL */ + repl_null[Anum_pg_shadow_useconfig-1] = 'n'; + else + { + Datum datum; + bool isnull; + ArrayType *a; + + repl_null[Anum_pg_shadow_useconfig-1] = ' '; + + datum = SysCacheGetAttr(SHADOWNAME, oldtuple, + Anum_pg_shadow_useconfig, &isnull); + + if (valuestr) + a = GUCArrayAdd(isnull + ? NULL + : (ArrayType *) pg_detoast_datum((struct varlena *)datum), + stmt->variable, valuestr); + else + a = GUCArrayDelete(isnull + ? NULL + : (ArrayType *) pg_detoast_datum((struct varlena *)datum), + stmt->variable); + + repl_val[Anum_pg_shadow_useconfig-1] = PointerGetDatum(a); + } + + newtuple = heap_modifytuple(oldtuple, rel, repl_val, repl_null, repl_repl); + simple_heap_update(rel, &oldtuple->t_self, newtuple); + + { + Relation idescs[Num_pg_shadow_indices]; + + CatalogOpenIndices(Num_pg_shadow_indices, Name_pg_shadow_indices, idescs); + CatalogIndexInsert(idescs, Num_pg_shadow_indices, rel, newtuple); + CatalogCloseIndices(Num_pg_shadow_indices, idescs); + } + + ReleaseSysCache(oldtuple); + heap_close(rel, RowExclusiveLock); +} + + + /* * DROP USER */ diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 570fa285234..d3fe436ac77 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -15,7 +15,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.164 2002/03/01 06:01:18 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.165 2002/03/01 22:45:11 petere Exp $ * *------------------------------------------------------------------------- */ @@ -2245,6 +2245,20 @@ _copyCreatedbStmt(CreatedbStmt *from) return newnode; } +static AlterDatabaseSetStmt * +_copyAlterDatabaseSetStmt(AlterDatabaseSetStmt *from) +{ + AlterDatabaseSetStmt *newnode = makeNode(AlterDatabaseSetStmt); + + if (from->dbname) + newnode->dbname = pstrdup(from->dbname); + if (from->variable) + newnode->variable = pstrdup(from->variable); + Node_Copy(from, newnode, value); + + return newnode; +} + static DropdbStmt * _copyDropdbStmt(DropdbStmt *from) { @@ -2427,6 +2441,20 @@ _copyAlterUserStmt(AlterUserStmt *from) return newnode; } +static AlterUserSetStmt * +_copyAlterUserSetStmt(AlterUserSetStmt *from) +{ + AlterUserSetStmt *newnode = makeNode(AlterUserSetStmt); + + if (from->user) + newnode->user = pstrdup(from->user); + if (from->variable) + newnode->user = pstrdup(from->variable); + Node_Copy(from, newnode, value); + + return newnode; +} + static DropUserStmt * _copyDropUserStmt(DropUserStmt *from) { @@ -2845,6 +2873,9 @@ copyObject(void *from) case T_CreatedbStmt: retval = _copyCreatedbStmt(from); break; + case T_AlterDatabaseSetStmt: + retval = _copyAlterDatabaseSetStmt(from); + break; case T_DropdbStmt: retval = _copyDropdbStmt(from); break; @@ -2884,6 +2915,9 @@ copyObject(void *from) case T_AlterUserStmt: retval = _copyAlterUserStmt(from); break; + case T_AlterUserSetStmt: + retval = _copyAlterUserSetStmt(from); + break; case T_DropUserStmt: retval = _copyDropUserStmt(from); break; diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 408c14bb7e4..46cf4497923 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -20,7 +20,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.111 2002/02/26 22:47:05 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.112 2002/03/01 22:45:12 petere Exp $ * *------------------------------------------------------------------------- */ @@ -1112,6 +1112,19 @@ _equalCreatedbStmt(CreatedbStmt *a, CreatedbStmt *b) return true; } +static bool +_equalAlterDatabaseSetStmt(AlterDatabaseSetStmt *a, AlterDatabaseSetStmt *b) +{ + if (!equalstr(a->dbname, b->dbname)) + return false; + if (!equalstr(a->variable, b->variable)) + return false; + if (!equal(a->value, b->value)) + return false; + + return true; +} + static bool _equalDropdbStmt(DropdbStmt *a, DropdbStmt *b) { @@ -1289,6 +1302,19 @@ _equalAlterUserStmt(AlterUserStmt *a, AlterUserStmt *b) return true; } +static bool +_equalAlterUserSetStmt(AlterUserSetStmt *a, AlterUserSetStmt *b) +{ + if (!equalstr(a->user, b->user)) + return false; + if (!equalstr(a->variable, b->variable)) + return false; + if (!equal(a->value, b->value)) + return false; + + return true; +} + static bool _equalDropUserStmt(DropUserStmt *a, DropUserStmt *b) { @@ -1988,6 +2014,9 @@ equal(void *a, void *b) case T_CreatedbStmt: retval = _equalCreatedbStmt(a, b); break; + case T_AlterDatabaseSetStmt: + retval = _equalAlterDatabaseSetStmt(a, b); + break; case T_DropdbStmt: retval = _equalDropdbStmt(a, b); break; @@ -2027,6 +2056,9 @@ equal(void *a, void *b) case T_AlterUserStmt: retval = _equalAlterUserStmt(a, b); break; + case T_AlterUserSetStmt: + retval = _equalAlterUserSetStmt(a, b); + break; case T_DropUserStmt: retval = _equalDropUserStmt(a, b); break; diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index f522769704c..841d136f47b 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.281 2002/02/25 03:37:14 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.282 2002/03/01 22:45:12 petere Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -130,8 +130,8 @@ static void doNegateFloat(Value *v); } %type <node> stmt, - AlterGroupStmt, AlterSchemaStmt, AlterTableStmt, AlterUserStmt, - AnalyzeStmt, + AlterDatabaseSetStmt, AlterGroupStmt, AlterSchemaStmt, AlterTableStmt, + AlterUserStmt, AlterUserSetStmt, AnalyzeStmt, ClosePortalStmt, ClusterStmt, CommentStmt, ConstraintsSetStmt, CopyStmt, CreateAsStmt, CreateGroupStmt, CreatePLangStmt, CreateSchemaStmt, CreateSeqStmt, CreateStmt, CreateTrigStmt, @@ -436,10 +436,12 @@ stmtmulti: stmtmulti ';' stmt } ; -stmt : AlterSchemaStmt - | AlterTableStmt +stmt : AlterDatabaseSetStmt | AlterGroupStmt + | AlterSchemaStmt + | AlterTableStmt | AlterUserStmt + | AlterUserSetStmt | ClosePortalStmt | CopyStmt | CreateStmt @@ -539,6 +541,26 @@ AlterUserStmt: ALTER USER UserId OptUserList } ; + +AlterUserSetStmt: ALTER USER UserId VariableSetStmt + { + AlterUserSetStmt *n = makeNode(AlterUserSetStmt); + n->user = $3; + n->variable = ((VariableSetStmt *)$4)->name; + n->value = ((VariableSetStmt *)$4)->args; + $$ = (Node *)n; + } + | ALTER USER UserId VariableResetStmt + { + AlterUserSetStmt *n = makeNode(AlterUserSetStmt); + n->user = $3; + n->variable = ((VariableResetStmt *)$4)->name; + n->value = NULL; + $$ = (Node *)n; + } + ; + + /***************************************************************************** * * Drop a postgresql DBMS user @@ -3163,6 +3185,33 @@ opt_equal: '=' { $$ = TRUE; } | /*EMPTY*/ { $$ = FALSE; } ; + +/***************************************************************************** + * + * ALTER DATABASE + * + * + *****************************************************************************/ + +AlterDatabaseSetStmt: ALTER DATABASE database_name VariableSetStmt + { + AlterDatabaseSetStmt *n = makeNode(AlterDatabaseSetStmt); + n->dbname = $3; + n->variable = ((VariableSetStmt *)$4)->name; + n->value = ((VariableSetStmt *)$4)->args; + $$ = (Node *)n; + } + | ALTER DATABASE database_name VariableResetStmt + { + AlterDatabaseSetStmt *n = makeNode(AlterDatabaseSetStmt); + n->dbname = $3; + n->variable = ((VariableResetStmt *)$4)->name; + n->value = NULL; + $$ = (Node *)n; + } + ; + + /***************************************************************************** * * DROP DATABASE diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index e688c414830..fad79146cc8 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.250 2002/02/27 23:16:07 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.251 2002/03/01 22:45:13 petere Exp $ * * NOTES * this is the "main" module of the postgres backend and @@ -1707,7 +1707,7 @@ PostgresMain(int argc, char *argv[], const char *username) if (!IsUnderPostmaster) { puts("\nPOSTGRES backend interactive interface "); - puts("$Revision: 1.250 $ $Date: 2002/02/27 23:16:07 $\n"); + puts("$Revision: 1.251 $ $Date: 2002/03/01 22:45:13 $\n"); } /* @@ -2265,6 +2265,10 @@ CreateCommandTag(Node *parsetree) tag = "CREATE DATABASE"; break; + case T_AlterDatabaseSetStmt: + tag = "ALTER DATABASE"; + break; + case T_DropdbStmt: tag = "DROP DATABASE"; break; @@ -2342,6 +2346,10 @@ CreateCommandTag(Node *parsetree) tag = "ALTER USER"; break; + case T_AlterUserSetStmt: + tag = "ALTER USER"; + break; + case T_DropUserStmt: tag = "DROP USER"; break; diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index a6a8b561e02..4e2b89508e7 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.127 2002/02/26 22:47:09 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.128 2002/03/01 22:45:14 petere Exp $ * *------------------------------------------------------------------------- */ @@ -600,6 +600,10 @@ ProcessUtility(Node *parsetree, } break; + case T_AlterDatabaseSetStmt: + AlterDatabaseSet((AlterDatabaseSetStmt *)parsetree); + break; + case T_DropdbStmt: { DropdbStmt *stmt = (DropdbStmt *) parsetree; @@ -748,6 +752,10 @@ ProcessUtility(Node *parsetree, AlterUser((AlterUserStmt *) parsetree); break; + case T_AlterUserSetStmt: + AlterUserSet((AlterUserSetStmt *) parsetree); + break; + case T_DropUserStmt: DropUser((DropUserStmt *) parsetree); break; diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c index 9705dda664c..0ccbe753d06 100644 --- a/src/backend/utils/init/miscinit.c +++ b/src/backend/utils/init/miscinit.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.82 2002/01/09 19:13:41 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.83 2002/03/01 22:45:15 petere Exp $ * *------------------------------------------------------------------------- */ @@ -31,6 +31,7 @@ #include "libpq/libpq-be.h" #include "miscadmin.h" #include "utils/builtins.h" +#include "utils/guc.h" #include "utils/lsyscache.h" #include "utils/syscache.h" @@ -437,6 +438,8 @@ void InitializeSessionUserId(const char *username) { HeapTuple userTup; + Datum datum; + bool isnull; /* * Don't do scans if we're bootstrapping, none of the system catalogs @@ -457,6 +460,21 @@ InitializeSessionUserId(const char *username) AuthenticatedUserIsSuperuser = ((Form_pg_shadow) GETSTRUCT(userTup))->usesuper; + /* + * Set up user-specific configuration variables. This is a good + * place to do it so we don't have to read pg_shadow twice during + * session startup. + */ + datum = SysCacheGetAttr(SHADOWNAME, userTup, + Anum_pg_shadow_useconfig, &isnull); + if (!isnull) + { + ArrayType *a; + + a = (ArrayType *) pg_detoast_datum((struct varlena *)datum); + ProcessGUCArray(a, PGC_S_USER); + } + ReleaseSysCache(userTup); } diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c index 222ab6d54ab..858b6e649c7 100644 --- a/src/backend/utils/init/postinit.c +++ b/src/backend/utils/init/postinit.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.98 2002/02/19 20:11:18 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.99 2002/03/01 22:45:15 petere Exp $ * * *------------------------------------------------------------------------- @@ -35,6 +35,7 @@ #include "storage/sinval.h" #include "storage/smgr.h" #include "utils/fmgroids.h" +#include "utils/guc.h" #include "utils/portal.h" #include "utils/relcache.h" #include "utils/syscache.h" @@ -70,6 +71,10 @@ static bool ThereIsAtLeastOneUser(void); * * This is also a handy place to fetch the database encoding info out * of pg_database, if we are in MULTIBYTE mode. + * + * To avoid having to read pg_database more times than necessary + * during session startup, this place is also fitting to set up any + * database-specific configuration variables. * -------------------------------- */ static void @@ -132,6 +137,25 @@ ReverifyMyDatabase(const char *name) dbform->encoding); #endif + /* + * Set up datbase-specific configuration variables. + */ + if (IsUnderPostmaster) + { + Datum datum; + bool isnull; + + datum = heap_getattr(tup, Anum_pg_database_datconfig, + RelationGetDescr(pgdbrel), &isnull); + if (!isnull) + { + ArrayType *a; + + a = (ArrayType *) pg_detoast_datum((struct varlena *)datum); + ProcessGUCArray(a, PGC_S_DATABASE); + } + } + heap_endscan(pgdbscan); heap_close(pgdbrel, AccessShareLock); } diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 6e112caa43c..f140d871f0c 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -4,7 +4,7 @@ * Support for grand unified configuration scheme, including SET * command, configuration file, and command line options. * - * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.59 2002/02/23 01:31:36 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.60 2002/03/01 22:45:16 petere Exp $ * * Copyright 2000 by PostgreSQL Global Development Group * Written by Peter Eisentraut <peter_e@gmx.net>. @@ -36,6 +36,8 @@ #include "storage/lock.h" #include "storage/proc.h" #include "tcop/tcopprot.h" +#include "utils/array.h" +#include "utils/builtins.h" #include "utils/datetime.h" #include "pgstat.h" @@ -89,6 +91,7 @@ bool Password_encryption = false; #define PG_KRB_SRVTAB "" #endif +static bool guc_session_init = false; /* XXX mildly bogus */ /* * Declarations for GUC tables @@ -882,7 +885,12 @@ set_config_option(const char *name, const char *value, int elevel; bool makeDefault; - elevel = (context == PGC_SIGHUP) ? DEBUG : ERROR; + if (context == PGC_SIGHUP) + elevel = DEBUG; + else if (guc_session_init) + elevel = NOTICE; + else + elevel = ERROR; type = find_option(name, &record); if (type == PGC_NONE) @@ -1362,3 +1370,147 @@ assign_defaultxactisolevel(const char *value) else elog(ERROR, "bogus transaction isolation level"); } + + + +void +ProcessGUCArray(ArrayType *array, GucSource source) +{ + int i; + + Assert(array); + + for (i = 1; i <= ARR_DIMS(array)[0]; i++) + { + Datum d; + bool isnull; + char *s; + char *name; + char *value; + + d = array_ref(array, 1, &i, + false /*notbyvalue*/, + -1 /*varlenelem*/, + -1 /*varlenarray*/, + &isnull); + + if (isnull) + continue; + + s = DatumGetCString(DirectFunctionCall1(textout, d)); + ParseLongOption(s, &name, &value); + if (!value) + { + elog(NOTICE, "cannot to parse setting \"%s\"", name); + continue; + } + + /* prevent errors from incorrect options */ + guc_session_init = true; + + SetConfigOption(name, value, PGC_SUSET, source); + + guc_session_init = false; + } +} + + + +ArrayType * +GUCArrayAdd(ArrayType *array, const char *name, const char *value) +{ + Datum datum; + char *newval; + ArrayType *a; + + Assert(name); + Assert(value); + + /* test if the option is valid */ + set_config_option(name, value, + superuser() ? PGC_SUSET : PGC_USERSET, + false, PGC_S_INFINITY); + + newval = palloc(strlen(name) + 1 + strlen(value) + 1); + sprintf(newval, "%s=%s", name, value); + datum = DirectFunctionCall1(textin, CStringGetDatum(newval)); + + if (array) + { + int index; + bool isnull; + int i; + + index = ARR_DIMS(array)[0] + 1; /* add after end */ + + for (i = 1; i <= ARR_DIMS(array)[0]; i++) + { + Datum d; + char *current; + + d = array_ref(array, 1, &i, + false /*notbyvalue*/, + -1 /*varlenelem*/, + -1 /*varlenarray*/, + &isnull); + current = DatumGetCString(DirectFunctionCall1(textout, d)); + if (strncmp(current, newval, strlen(name) + 1)==0) + { + index = i; + break; + } + } + + isnull = false; + a = array_set(array, 1, &index, datum, false/*notbyval*/, -1, -1, &isnull); + } + else + a = construct_array(&datum, 1, false, -1, 'i'); + + return a; +} + + + +ArrayType * +GUCArrayDelete(ArrayType *array, const char *name) +{ + ArrayType *newarray; + int i; + int index; + + Assert(name); + Assert(array); + + /* test if the option is valid */ + set_config_option(name, NULL, + superuser() ? PGC_SUSET : PGC_USERSET, + false, PGC_S_INFINITY); + + newarray = construct_array(NULL, 0, false, -1, 'i'); + index = 1; + + for (i = 1; i <= ARR_DIMS(array)[0]; i++) + { + Datum d; + char *val; + bool isnull; + + d = array_ref(array, 1, &i, + false /*notbyvalue*/, + -1 /*varlenelem*/, + -1 /*varlenarray*/, + &isnull); + val = DatumGetCString(DirectFunctionCall1(textout, d)); + + if (strncmp(val, name, strlen(name))==0 + && val[strlen(name)] == '=') + continue; + + isnull = false; + newarray = array_set(newarray, 1, &index, d, false/*notbyval*/, -1, -1, &isnull); + index++; + } + + return newarray; +} diff --git a/src/bin/initdb/initdb.sh b/src/bin/initdb/initdb.sh index c75d44c6a30..a3b283ab906 100644 --- a/src/bin/initdb/initdb.sh +++ b/src/bin/initdb/initdb.sh @@ -27,7 +27,7 @@ # Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # -# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.143 2002/02/18 23:11:28 petere Exp $ +# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.144 2002/03/01 22:45:16 petere Exp $ # #------------------------------------------------------------------------- @@ -579,7 +579,8 @@ CREATE VIEW pg_user AS \ usesuper, \ usecatupd, \ '********'::text as passwd, \ - valuntil \ + valuntil, \ + useconfig \ FROM pg_shadow; CREATE VIEW pg_rules AS \ diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 447469072b3..f579d0267c3 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -37,7 +37,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: catversion.h,v 1.104 2002/02/18 23:11:32 petere Exp $ + * $Id: catversion.h,v 1.105 2002/03/01 22:45:16 petere Exp $ * *------------------------------------------------------------------------- */ @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 200202181 +#define CATALOG_VERSION_NO 200203011 #endif diff --git a/src/include/catalog/pg_attribute.h b/src/include/catalog/pg_attribute.h index f8c68f3ce69..43f806188e6 100644 --- a/src/include/catalog/pg_attribute.h +++ b/src/include/catalog/pg_attribute.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: pg_attribute.h,v 1.80 2002/02/18 23:11:33 petere Exp $ + * $Id: pg_attribute.h,v 1.81 2002/03/01 22:45:16 petere Exp $ * * NOTES * the genbki.sh script reads this file and generates .bki @@ -281,6 +281,7 @@ DATA(insert ( 1262 datvacuumxid 28 0 4 7 0 -1 -1 t p f i f f)); DATA(insert ( 1262 datfrozenxid 28 0 4 8 0 -1 -1 t p f i f f)); /* do not mark datpath as toastable; GetRawDatabaseInfo won't cope */ DATA(insert ( 1262 datpath 25 0 -1 9 0 -1 -1 f p f i f f)); +DATA(insert ( 1262 datconfig 1009 0 -1 10 0 -1 -1 f x f i f f)); DATA(insert ( 1262 ctid 27 0 6 -1 0 -1 -1 f p f i f f)); DATA(insert ( 1262 oid 26 0 4 -2 0 -1 -1 t p f i f f)); DATA(insert ( 1262 xmin 28 0 4 -3 0 -1 -1 t p f i f f)); @@ -351,6 +352,7 @@ DATA(insert ( 1260 usesuper 16 0 1 5 0 -1 -1 t p f c f f)); DATA(insert ( 1260 usecatupd 16 0 1 6 0 -1 -1 t p f c f f)); DATA(insert ( 1260 passwd 25 0 -1 7 0 -1 -1 f x f i f f)); DATA(insert ( 1260 valuntil 702 0 4 8 0 -1 -1 t p f i f f)); +DATA(insert ( 1260 useconfig 1009 0 -1 9 0 -1 -1 f x f i f f)); DATA(insert ( 1260 ctid 27 0 6 -1 0 -1 -1 f p f i f f)); /* no OIDs in pg_shadow */ DATA(insert ( 1260 xmin 28 0 4 -3 0 -1 -1 t p f i f f)); diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h index c37c5ec8f4f..2a4bc84a363 100644 --- a/src/include/catalog/pg_class.h +++ b/src/include/catalog/pg_class.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: pg_class.h,v 1.58 2002/02/18 23:11:34 petere Exp $ + * $Id: pg_class.h,v 1.59 2002/03/01 22:45:17 petere Exp $ * * NOTES * the genbki.sh script reads this file and generates .bki @@ -140,11 +140,11 @@ DATA(insert OID = 1255 ( pg_proc 81 PGUID 0 1255 0 0 0 0 f f r 18 0 0 0 0 0 t DESCR(""); DATA(insert OID = 1259 ( pg_class 83 PGUID 0 1259 0 0 0 0 f f r 23 0 0 0 0 0 t f f f _null_ )); DESCR(""); -DATA(insert OID = 1260 ( pg_shadow 86 PGUID 0 1260 0 0 0 0 f t r 8 0 0 0 0 0 f f f f _null_ )); +DATA(insert OID = 1260 ( pg_shadow 86 PGUID 0 1260 0 0 0 0 f t r 9 0 0 0 0 0 f f f f _null_ )); DESCR(""); DATA(insert OID = 1261 ( pg_group 87 PGUID 0 1261 0 0 0 0 f t r 3 0 0 0 0 0 f f f f _null_ )); DESCR(""); -DATA(insert OID = 1262 ( pg_database 88 PGUID 0 1262 0 0 0 0 f t r 9 0 0 0 0 0 t f f f _null_ )); +DATA(insert OID = 1262 ( pg_database 88 PGUID 0 1262 0 0 0 0 f t r 10 0 0 0 0 0 t f f f _null_ )); DESCR(""); DATA(insert OID = 376 ( pg_xactlock 0 PGUID 0 0 0 0 0 0 f t s 1 0 0 0 0 0 f f f f _null_ )); DESCR(""); diff --git a/src/include/catalog/pg_database.h b/src/include/catalog/pg_database.h index 34df08595ef..5a04e2917ab 100644 --- a/src/include/catalog/pg_database.h +++ b/src/include/catalog/pg_database.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: pg_database.h,v 1.21 2001/11/05 17:46:32 momjian Exp $ + * $Id: pg_database.h,v 1.22 2002/03/01 22:45:17 petere Exp $ * * NOTES * the genbki.sh script reads this file and generates .bki @@ -42,6 +42,7 @@ CATALOG(pg_database) BOOTSTRAP TransactionId datvacuumxid; /* all XIDs before this are vacuumed */ TransactionId datfrozenxid; /* all XIDs before this are frozen */ text datpath; /* VARIABLE LENGTH FIELD */ + text datconfig[1]; /* database-specific GUC */ } FormData_pg_database; /* ---------------- @@ -55,7 +56,7 @@ typedef FormData_pg_database *Form_pg_database; * compiler constants for pg_database * ---------------- */ -#define Natts_pg_database 9 +#define Natts_pg_database 10 #define Anum_pg_database_datname 1 #define Anum_pg_database_datdba 2 #define Anum_pg_database_encoding 3 @@ -65,8 +66,9 @@ typedef FormData_pg_database *Form_pg_database; #define Anum_pg_database_datvacuumxid 7 #define Anum_pg_database_datfrozenxid 8 #define Anum_pg_database_datpath 9 +#define Anum_pg_database_datconfig 10 -DATA(insert OID = 1 ( template1 PGUID ENCODING t t 0 0 0 "" )); +DATA(insert OID = 1 ( template1 PGUID ENCODING t t 0 0 0 "" _null_ )); DESCR("Default template database"); #define TemplateDbOid 1 diff --git a/src/include/catalog/pg_shadow.h b/src/include/catalog/pg_shadow.h index 00ccaeb85f3..2e8d5b771c5 100644 --- a/src/include/catalog/pg_shadow.h +++ b/src/include/catalog/pg_shadow.h @@ -9,7 +9,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: pg_shadow.h,v 1.17 2001/11/05 17:46:32 momjian Exp $ + * $Id: pg_shadow.h,v 1.18 2002/03/01 22:45:17 petere Exp $ * * NOTES * the genbki.sh script reads this file and generates .bki @@ -39,6 +39,7 @@ CATALOG(pg_shadow) BOOTSTRAP BKI_WITHOUT_OIDS bool usecatupd; text passwd; int4 valuntil; + text useconfig[1]; } FormData_pg_shadow; /* ---------------- @@ -52,7 +53,7 @@ typedef FormData_pg_shadow *Form_pg_shadow; * compiler constants for pg_shadow * ---------------- */ -#define Natts_pg_shadow 8 +#define Natts_pg_shadow 9 #define Anum_pg_shadow_usename 1 #define Anum_pg_shadow_usesysid 2 #define Anum_pg_shadow_usecreatedb 3 @@ -61,6 +62,7 @@ typedef FormData_pg_shadow *Form_pg_shadow; #define Anum_pg_shadow_usecatupd 6 #define Anum_pg_shadow_passwd 7 #define Anum_pg_shadow_valuntil 8 +#define Anum_pg_shadow_useconfig 9 /* ---------------- * initial contents of pg_shadow @@ -69,7 +71,7 @@ typedef FormData_pg_shadow *Form_pg_shadow; * user choices. * ---------------- */ -DATA(insert ( "POSTGRES" PGUID t t t t _null_ _null_ )); +DATA(insert ( "POSTGRES" PGUID t t t t _null_ _null_ _null_ )); #define BOOTSTRAP_USESYSID 1 diff --git a/src/include/commands/dbcommands.h b/src/include/commands/dbcommands.h index 0636130c2e1..32c823e152c 100644 --- a/src/include/commands/dbcommands.h +++ b/src/include/commands/dbcommands.h @@ -7,16 +7,19 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: dbcommands.h,v 1.20 2002/02/24 20:20:21 tgl Exp $ + * $Id: dbcommands.h,v 1.21 2002/03/01 22:45:17 petere Exp $ * *------------------------------------------------------------------------- */ #ifndef DBCOMMANDS_H #define DBCOMMANDS_H +#include <nodes/parsenodes.h> + extern void createdb(const char *dbname, const char *dbowner, const char *dbpath, const char *dbtemplate, int encoding); extern void dropdb(const char *dbname); +extern void AlterDatabaseSet(AlterDatabaseSetStmt *stmt); #endif /* DBCOMMANDS_H */ diff --git a/src/include/commands/user.h b/src/include/commands/user.h index 3a56547a3fa..351c2d6ef6d 100644 --- a/src/include/commands/user.h +++ b/src/include/commands/user.h @@ -3,7 +3,7 @@ * user.h * * - * $Id: user.h,v 1.16 2001/11/05 17:46:33 momjian Exp $ + * $Id: user.h,v 1.17 2002/03/01 22:45:17 petere Exp $ * *------------------------------------------------------------------------- */ @@ -14,6 +14,7 @@ extern void CreateUser(CreateUserStmt *stmt); extern void AlterUser(AlterUserStmt *stmt); +extern void AlterUserSet(AlterUserSetStmt *stmt); extern void DropUser(DropUserStmt *stmt); extern void CreateGroup(CreateGroupStmt *stmt); diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index 1d5cf2dceab..96a89d9df56 100644 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: nodes.h,v 1.97 2002/02/18 23:11:41 petere Exp $ + * $Id: nodes.h,v 1.98 2002/03/01 22:45:17 petere Exp $ * *------------------------------------------------------------------------- */ @@ -194,6 +194,8 @@ typedef enum NodeTag T_DropGroupStmt, T_ReindexStmt, T_CheckPointStmt, + T_AlterDatabaseSetStmt, + T_AlterUserSetStmt, T_A_Expr = 700, T_Attr, diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index bfcbc91cd43..564985ae0e3 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: parsenodes.h,v 1.154 2002/02/26 22:47:10 tgl Exp $ + * $Id: parsenodes.h,v 1.155 2002/03/01 22:45:18 petere Exp $ * *------------------------------------------------------------------------- */ @@ -359,7 +359,7 @@ typedef struct DropPLangStmt /* ---------------------- - * Create/Alter/Drop User Statements + * Create/Alter/Drop User Statements * ---------------------- */ typedef struct CreateUserStmt @@ -376,6 +376,14 @@ typedef struct AlterUserStmt List *options; /* List of DefElem nodes */ } AlterUserStmt; +typedef struct AlterUserSetStmt +{ + NodeTag type; + char *user; + char *variable; + List *value; +} AlterUserSetStmt; + typedef struct DropUserStmt { NodeTag type; @@ -687,6 +695,18 @@ typedef struct CreatedbStmt int encoding; /* MULTIBYTE encoding (-1 = use default) */ } CreatedbStmt; +/* ---------------------- + * Alter Database + * ---------------------- + */ +typedef struct AlterDatabaseSetStmt +{ + NodeTag type; + char *dbname; + char *variable; + List *value; +} AlterDatabaseSetStmt; + /* ---------------------- * Dropdb Statement * ---------------------- diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h index f7361dff47e..d58b9ef66ff 100644 --- a/src/include/utils/guc.h +++ b/src/include/utils/guc.h @@ -4,11 +4,13 @@ * External declarations pertaining to backend/utils/misc/guc.c and * backend/utils/misc/guc-file.l * - * $Id: guc.h,v 1.14 2002/02/23 01:31:37 petere Exp $ + * $Id: guc.h,v 1.15 2002/03/01 22:45:18 petere Exp $ */ #ifndef GUC_H #define GUC_H +#include "utils/array.h" + /* * Certain options can only be set at certain times. The rules are * like this: @@ -74,6 +76,9 @@ extern bool set_config_option(const char *name, const char *value, GucContext context, bool DoIt, GucSource source); extern void ShowAllGUCConfig(void); +extern void ProcessGUCArray(ArrayType *array, GucSource source); +extern ArrayType *GUCArrayAdd(ArrayType *array, const char *name, const char *value); +extern ArrayType *GUCArrayDelete(ArrayType *array, const char *name); extern bool Debug_print_query; extern bool Debug_print_plan; diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out index af00a05a339..4f54ed3a7cc 100644 --- a/src/test/regress/expected/rules.out +++ b/src/test/regress/expected/rules.out @@ -1288,7 +1288,7 @@ SELECT viewname, definition FROM pg_views ORDER BY viewname; pg_statio_user_tables | SELECT pg_statio_all_tables.relid, pg_statio_all_tables.relname, pg_statio_all_tables.heap_blks_read, pg_statio_all_tables.heap_blks_hit, pg_statio_all_tables.idx_blks_read, pg_statio_all_tables.idx_blks_hit, pg_statio_all_tables.toast_blks_read, pg_statio_all_tables.toast_blks_hit, pg_statio_all_tables.tidx_blks_read, pg_statio_all_tables.tidx_blks_hit FROM pg_statio_all_tables WHERE (pg_statio_all_tables.relname !~ '^pg_'::text); pg_stats | SELECT c.relname AS tablename, a.attname, s.stanullfrac AS null_frac, s.stawidth AS avg_width, s.stadistinct AS n_distinct, CASE WHEN (1 = s.stakind1) THEN s.stavalues1 WHEN (1 = s.stakind2) THEN s.stavalues2 WHEN (1 = s.stakind3) THEN s.stavalues3 WHEN (1 = s.stakind4) THEN s.stavalues4 ELSE NULL::"_text" END AS most_common_vals, CASE WHEN (1 = s.stakind1) THEN s.stanumbers1 WHEN (1 = s.stakind2) THEN s.stanumbers2 WHEN (1 = s.stakind3) THEN s.stanumbers3 WHEN (1 = s.stakind4) THEN s.stanumbers4 ELSE NULL::"_float4" END AS most_common_freqs, CASE WHEN (2 = s.stakind1) THEN s.stavalues1 WHEN (2 = s.stakind2) THEN s.stavalues2 WHEN (2 = s.stakind3) THEN s.stavalues3 WHEN (2 = s.stakind4) THEN s.stavalues4 ELSE NULL::"_text" END AS histogram_bounds, CASE WHEN (3 = s.stakind1) THEN s.stanumbers1[1] WHEN (3 = s.stakind2) THEN s.stanumbers2[1] WHEN (3 = s.stakind3) THEN s.stanumbers3[1] WHEN (3 = s.stakind4) THEN s.stanumbers4[1] ELSE NULL::float4 END AS correlation FROM pg_class c, pg_attribute a, pg_statistic s WHERE ((((c.oid = s.starelid) AND (c.oid = a.attrelid)) AND (a.attnum = s.staattnum)) AND has_table_privilege(c.oid, 'select'::text)); pg_tables | SELECT c.relname AS tablename, pg_get_userbyid(c.relowner) AS tableowner, c.relhasindex AS hasindexes, c.relhasrules AS hasrules, (c.reltriggers > 0) AS hastriggers FROM pg_class c WHERE ((c.relkind = 'r'::"char") OR (c.relkind = 's'::"char")); - pg_user | SELECT pg_shadow.usename, pg_shadow.usesysid, pg_shadow.usecreatedb, pg_shadow.usetrace, pg_shadow.usesuper, pg_shadow.usecatupd, '********'::text AS passwd, pg_shadow.valuntil FROM pg_shadow; + pg_user | SELECT pg_shadow.usename, pg_shadow.usesysid, pg_shadow.usecreatedb, pg_shadow.usetrace, pg_shadow.usesuper, pg_shadow.usecatupd, '********'::text AS passwd, pg_shadow.valuntil, pg_shadow.useconfig FROM pg_shadow; pg_views | SELECT c.relname AS viewname, pg_get_userbyid(c.relowner) AS viewowner, pg_get_viewdef(c.relname) AS definition FROM pg_class c WHERE (c.relkind = 'v'::"char"); rtest_v1 | SELECT rtest_t1.a, rtest_t1.b FROM rtest_t1; rtest_vcomp | SELECT x.part, (x.size * y.factor) AS size_in_cm FROM rtest_comp x, rtest_unitfact y WHERE (x.unit = y.unit); -- GitLab