]> granicus.if.org Git - postgresql/commitdiff
User and database-specific session defaults for run-time configuration
authorPeter Eisentraut <peter_e@gmx.net>
Fri, 1 Mar 2002 22:45:19 +0000 (22:45 +0000)
committerPeter Eisentraut <peter_e@gmx.net>
Fri, 1 Mar 2002 22:45:19 +0000 (22:45 +0000)
variables.  New commands ALTER DATABASE ... SET and ALTER USER ... SET.

29 files changed:
doc/src/sgml/catalogs.sgml
doc/src/sgml/ref/allfiles.sgml
doc/src/sgml/ref/alter_database.sgml [new file with mode: 0644]
doc/src/sgml/ref/alter_user.sgml
doc/src/sgml/reference.sgml
doc/src/sgml/release.sgml
doc/src/sgml/runtime.sgml
src/backend/commands/dbcommands.c
src/backend/commands/user.c
src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/parser/gram.y
src/backend/tcop/postgres.c
src/backend/tcop/utility.c
src/backend/utils/init/miscinit.c
src/backend/utils/init/postinit.c
src/backend/utils/misc/guc.c
src/bin/initdb/initdb.sh
src/include/catalog/catversion.h
src/include/catalog/pg_attribute.h
src/include/catalog/pg_class.h
src/include/catalog/pg_database.h
src/include/catalog/pg_shadow.h
src/include/commands/dbcommands.h
src/include/commands/user.h
src/include/nodes/nodes.h
src/include/nodes/parsenodes.h
src/include/utils/guc.h
src/test/regress/expected/rules.out

index 20adc19bab893ba0f86ab40cd105bda184dbe180..aab0a906d9b7a589c648e70e55dd4ab6b5e8adcb 100644 (file)
@@ -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">
        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>
       <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>
index ef29c0e8b98746f37b2a05483089cb07d2c07197..94f1226c24f73997675812a41a2e4ab59afb9fe5 100644 (file)
@@ -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 (file)
index 0000000..b1aa342
--- /dev/null
@@ -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:
+-->
index 0156565eb508dffd80d6814c799268c9fd39c108..3819bf8d964346f90c8b7f1216984149727cf391 100644 (file)
@@ -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>
index a5b8cfbf163d81f7babdc27e62d3eec9ea301c4d..27f218d33fb6d7e69e34b7e4f7b9618797a77baf 100644 (file)
@@ -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;
index edcdc9405aa42fa5733b3044bb5538b36b7fa9a0..3801b8d1eab6298fcef907b8272c67ac04e4d221 100644 (file)
@@ -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>
index 2c0441fdcc9850f7214e7f96029d4f4a437ceb87..3f46a3e9e4fd404fa290450f1bc17b384a783f15 100644 (file)
@@ -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>
 =&gt; <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">
index 712df38ec51470e281feddbc60938f835452dad8..3de94de9c6e7aa7515ccc9df58cc5bc30e85eb1a 100644 (file)
@@ -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 $
  *
  *-------------------------------------------------------------------------
  */
 #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
  */
index a7ccd3768ff119e3a8b4fca215f1e8fd5b967552..a059207b0aae48794a664215cbc8c76018ee6460 100644 (file)
@@ -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
  */
index 570fa28523475d14b970cd0198d25b0a2124ce42..d3fe436ac77755e9578619e3c4dffd1c16fc7872 100644 (file)
@@ -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;
index 408c14bb7e4be2bbb4744671bc6d921eb28deb44..46cf44979233bad1f3c1130ba47c9ca3f76c024c 100644 (file)
@@ -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;
index f522769704c023c97abdb4153fe916cd4d54b77f..841d136f47b1d28add0ded11f2b46d3c1270a2f6 100644 (file)
@@ -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
index e688c414830e9075d0b096a8f91007d4ea6cb03f..fad79146cc85d9330d5d2830ab74836c7420394b 100644 (file)
@@ -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;
index a6a8b561e02fd2ec0be36d790102c1473f13dab6..4e2b89508e73a00feb8e5f8f44bd5dddfc710292 100644 (file)
@@ -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;
index 9705dda664c93423949173d860ed6a6f488bbc97..0ccbe753d0670497a519ede7f5ecab0f4ab0f00b 100644 (file)
@@ -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);
 }
 
index 222ab6d54ab2aed462512795c63717403842055f..858b6e649c732846d7262849e570be90eb48b9c4 100644 (file)
@@ -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);
 }
index 6e112caa43c65990ebcb2a3a6c2d3ce27a8a6f2c..f140d871f0c3826937c4fca7e92ed1366d7df121 100644 (file)
@@ -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;
+}
index c75d44c6a30f6744e16880890aa7d3523cd75748..a3b283ab90697c8483ea1a113d7c5a2047975931 100644 (file)
@@ -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 \
index 447469072b3bd7c5d65812982fb5cd75443e04cf..f579d0267c3bef555a69f367c60e1620cce39cb4 100644 (file)
@@ -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
index f8c68f3ce69bb362a3f2809160129f8cbb9a16ed..43f806188e68593b77ff52d0b2481c170b49c2b3 100644 (file)
@@ -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));
index c37c5ec8f4fb061824097f693f1fde1cbf8b3fdf..2a4bc84a363834e7bb7dc63011f7e9b0281335ca 100644 (file)
@@ -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("");
index 34df08595ef94668da33c707b3dff5cbea4f9edd..5a04e2917ab933fcc454fd1e75513208bd9048e5 100644 (file)
@@ -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
index 00ccaeb85f3b47f22701a82c1de4bce5aa95061b..2e8d5b771c5d96a48d3be1d75d64e0ab468fb39c 100644 (file)
@@ -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
 
index 0636130c2e1c7fed6a4acf712910120a9c1ef4ba..32c823e152c4fa4c763c2241281fa1afe625e63f 100644 (file)
@@ -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 */
index 3a56547a3fa3d2363eb264121aac868eaf6d262a..351c2d6ef6dd7d677404f730d349cc05229d6f9d 100644 (file)
@@ -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);
index 1d5cf2dceab3bc5522eb06802c609766c323e169..96a89d9df56662f8999654ef6582154b72bad4b4 100644 (file)
@@ -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,
index bfcbc91cd43a0b8daf044cfb99d08ef929f32e2f..564985ae0e3819a86b98c39f9114d418c60087c3 100644 (file)
@@ -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
  * ----------------------
index f7361dff47ebd19cf78478ef4d65b18e7b85ca64..d58b9ef66ff5bf2caa00ad0bd46bb885c2417b07 100644 (file)
@@ -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;
index af00a05a3393c2d21965570862038bb9d940e4e1..4f54ed3a7cc2fd616408b624c83d1c1330fc17c7 100644 (file)
@@ -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);