]> granicus.if.org Git - postgresql/commitdiff
Remove GUC USERLIMIT variable category, making the affected variables
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 14 Nov 2004 19:35:35 +0000 (19:35 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 14 Nov 2004 19:35:35 +0000 (19:35 +0000)
plain SUSET instead.  Also delay processing of options received in
client connection request until after we know if the user is a superuser,
so that SUSET values can be set that way by legitimate superusers.
Per recent discussion.

doc/src/sgml/runtime.sgml
src/backend/bootstrap/bootstrap.c
src/backend/postmaster/postmaster.c
src/backend/tcop/postgres.c
src/backend/utils/init/postinit.c
src/backend/utils/misc/guc.c
src/include/miscadmin.h
src/include/tcop/tcopprot.h
src/include/utils/guc.h

index 91cdec32284652677a51116832102f0d6bc25050..8dbd65454b225d95c29356d27f5465943c077bb9 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.291 2004/11/05 19:15:49 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.292 2004/11/14 19:35:28 tgl Exp $
 -->
 
 <Chapter Id="runtime">
@@ -2150,7 +2150,7 @@ archive_command = 'copy "%p" /mnt/server/archivedir/"%f"'  # Win32
         to the log.  The default is <literal>NOTICE</>.  Note that
         <literal>LOG</> has a different rank here than in
         <varname>client_min_messages</>.
-        Only superusers can increase this option.
+        Only superusers can change this setting.
        </para>
       </listitem>
      </varlistentry>
@@ -2186,7 +2186,7 @@ archive_command = 'copy "%p" /mnt/server/archivedir/"%f"'  # Win32
         SQL statements causing errors, fatal errors, or panics will be
         logged. Enabling this option can be helpful in tracking down
         the source of any errors that appear in the server log.
-        Only superusers can increase this option.
+        Only superusers can change this setting.
        </para>
       </listitem>
      </varlistentry>
@@ -2204,8 +2204,7 @@ archive_command = 'copy "%p" /mnt/server/archivedir/"%f"'  # Win32
          <literal>250</literal> then all SQL statements that run 250ms 
          or longer will be logged.  Enabling this option can be
          useful in tracking down unoptimized queries in your applications.
-         Only superusers can increase this or set it to minus-one if this 
-         option is set by the administrator.
+         Only superusers can change this setting.
         </para>
        </listitem>
       </varlistentry>
@@ -2332,7 +2331,7 @@ archive_command = 'copy "%p" /mnt/server/archivedir/"%f"'  # Win32
         these displays to produce a more readable but much longer
         output format.  <varname>client_min_messages</varname> or
         <varname>log_min_messages</varname> must be
-        <literal>DEBUG1</literal> or lower to send output to the
+        <literal>DEBUG1</literal> or lower to send the output to the
         client or server logs. These options are off by default.
        </para>
       </listitem>
@@ -2372,10 +2371,9 @@ archive_command = 'copy "%p" /mnt/server/archivedir/"%f"'  # Win32
         <varname>log_statement</> to be logged.  When using this option, 
         if you are not using <application>syslog</>, it is recommended 
         that you log the PID or session ID using <varname>log_line_prefix</> 
-        or log the session ID so that you can link the statement to the 
+        so that you can link the statement to the 
         duration using the process ID or session ID. The default is off.  
-        Only superusers can turn off this option if it is enabled by the 
-        administrator.
+        Only superusers can change this setting.
        </para>
       </listitem>
      </varlistentry>
@@ -2487,35 +2485,35 @@ archive_command = 'copy "%p" /mnt/server/archivedir/"%f"'  # Win32
       <listitem>
        <para>
         Controls which SQL statements are logged. Valid values are
-        <literal>all</>, <literal>ddl</>, <literal>mod</>, and
-        <literal>none</>. <literal>ddl</> logs all data definition
+        <literal>none</>, <literal>ddl</>, <literal>mod</>, and
+        <literal>all</>. <literal>ddl</> logs all data definition
         commands like <literal>CREATE</>, <literal>ALTER</>, and
         <literal>DROP</> commands. <literal>mod</> logs all
         <literal>ddl</> statements, plus <literal>INSERT</>,
         <literal>UPDATE</>, <literal>DELETE</>, <literal>TRUNCATE</>,
         and <literal>COPY FROM</>. <literal>PREPARE</> and
-        <literal>EXPLAIN ANALYZE</> statements are also considered for
-        appropriate commands. 
+        <literal>EXPLAIN ANALYZE</> statements are also logged if their
+        contained command is of an appropriate type.
        </para>
        <para>
-        The default is <literal>none</>. Only superusers can reduce 
-        the detail of this option if it has been set by an administrator.
+        The default is <literal>none</>. Only superusers can change this
+        setting.
        </para>
 
        <note>
         <para>
-         The <command>EXECUTE</command> statement not considered a
+         The <command>EXECUTE</command> statement is not considered a
          <literal>ddl</> or <literal>mod</> statement.  When it is logged, 
          only the name of the prepared statement is reported, not the
          actual prepared statement.
         </para>
 
         <para>
-         When a function is defined in a server-side language like
-         <application>PL/pgSQL</application>, any queries executed by
-         the function will only be logged the first time that the
+         When a function is defined in the
+         <application>PL/pgSQL</application>server-side language, any queries
+         executed by the function will only be logged the first time that the
          function is invoked in a particular session. This is because
-         the <application>PL/pgSQL</application> keeps a cache of the
+         <application>PL/pgSQL</application> keeps a cache of the
          query plans produced for the SQL statements in the function.
         </para>
        </note>
@@ -2556,11 +2554,10 @@ archive_command = 'copy "%p" /mnt/server/archivedir/"%f"'  # Win32
         For each query, write performance statistics of the respective
         module to the server log. This is a crude profiling
         instrument.  <varname>log_statement_stats</varname> reports total
-        statement statistics, while the others report per-state statistics.
-        <varname>log_statement_stats</varname> can not be enabled with 
-        the other options.  All of these options are disabled by default.  
-        Only superusers can turn off any of these options if they have
-        been enabled by the administrator.
+        statement statistics, while the others report per-module statistics.
+        <varname>log_statement_stats</varname> cannot be enabled together with
+        any of the per-module options.  All of these options are disabled by
+        default.   Only superusers can change these settings.
        </para>
       </listitem>
      </varlistentry>
index 04792c7261a2508296b5c45ddddd84b961cd2f91..93f01497e4271fa58c09be8ee70ef196ec2ad2b9 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.195 2004/10/10 23:37:16 neilc Exp $
+ *       $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.196 2004/11/14 19:35:29 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -424,7 +424,7 @@ BootstrapMain(int argc, char *argv[])
        /*
         * backend initialization
         */
-       InitPostgres(dbname, NULL);
+       (void) InitPostgres(dbname, NULL);
 
        /*
         * In NOP mode, all we really want to do is create shared memory and
index bb918eaedae6ca23887026b7b6a81ff04a3ebf34..724717af8c39eca87210d2e3298f65cac8769cf3 100644 (file)
@@ -37,7 +37,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.437 2004/11/09 13:01:26 petere Exp $
+ *       $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.438 2004/11/14 19:35:30 tgl Exp $
  *
  * NOTES
  *
@@ -223,8 +223,6 @@ bool                ClientAuthInProgress = false;           /* T during new-client
  */
 static unsigned int random_seed = 0;
 
-static int     debug_flag = 0;
-
 extern char *optarg;
 extern int     optind,
                        opterr;
@@ -401,17 +399,8 @@ PostmasterMain(int argc, char *argv[])
                                userDoption = optarg;
                                break;
                        case 'd':
-                               {
-                                       /* Turn on debugging for the postmaster. */
-                                       char       *debugstr = palloc(strlen("debug") + strlen(optarg) + 1);
-
-                                       sprintf(debugstr, "debug%s", optarg);
-                                       SetConfigOption("log_min_messages", debugstr,
-                                                                       PGC_POSTMASTER, PGC_S_ARGV);
-                                       pfree(debugstr);
-                                       debug_flag = atoi(optarg);
-                                       break;
-                               }
+                               set_debug_options(atoi(optarg), PGC_POSTMASTER, PGC_S_ARGV);
+                               break;
                        case 'F':
                                SetConfigOption("fsync", "false", PGC_POSTMASTER, PGC_S_ARGV);
                                break;
@@ -2511,7 +2500,6 @@ BackendRun(Port *port)
        char      **av;
        int                     maxac;
        int                     ac;
-       char            debugbuf[32];
        char            protobuf[32];
        int                     i;
 
@@ -2707,15 +2695,6 @@ BackendRun(Port *port)
 
        av[ac++] = "postgres";
 
-       /*
-        * Pass the requested debugging level along to the backend.
-        */
-       if (debug_flag > 0)
-       {
-               snprintf(debugbuf, sizeof(debugbuf), "-d%d", debug_flag);
-               av[ac++] = debugbuf;
-       }
-
        /*
         * Pass any backend switches specified with -o in the postmaster's own
         * command line.  We assume these are secure.  (It's OK to mangle
@@ -3404,7 +3383,6 @@ write_backend_variables(char *filename, Port *port)
        write_var(ProcStructLock, fp);
        write_var(pgStatSock, fp);
 
-       write_var(debug_flag, fp);
        write_var(PostmasterPid, fp);
 #ifdef WIN32
        write_var(PostmasterHandle, fp);
@@ -3478,7 +3456,6 @@ read_backend_variables(char *filename, Port *port)
        read_var(ProcStructLock, fp);
        read_var(pgStatSock, fp);
 
-       read_var(debug_flag, fp);
        read_var(PostmasterPid, fp);
 #ifdef WIN32
        read_var(PostmasterHandle, fp);
index b9abf0d6b6997ca5239c023b2f3bb5653f981282..fe6475f83ea68790e40aafd7652c4ff401d66d10 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.436 2004/10/15 16:50:31 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.437 2004/11/14 19:35:31 tgl Exp $
  *
  * NOTES
  *       this is the "main" module of the postgres backend and
@@ -2151,6 +2151,41 @@ usage(const char *progname)
 }
 
 
+/*
+ * set_debug_options --- apply "-d N" command line option
+ *
+ * -d is not quite the same as setting log_min_messages because it enables
+ * other output options.
+ */
+void
+set_debug_options(int debug_flag, GucContext context, GucSource source)
+{
+       if (debug_flag > 0)
+       {
+               char            debugstr[64];
+
+               sprintf(debugstr, "debug%d", debug_flag);
+               SetConfigOption("log_min_messages", debugstr, context, source);
+       }
+       else
+               SetConfigOption("log_min_messages", "notice", context, source);
+
+       if (debug_flag >= 1 && context == PGC_POSTMASTER)
+       {
+               SetConfigOption("log_connections", "true", context, source);
+               SetConfigOption("log_disconnections", "true", context, source);
+       }
+       if (debug_flag >= 2)
+               SetConfigOption("log_statement", "all", context, source);
+       if (debug_flag >= 3)
+               SetConfigOption("debug_print_parse", "true", context, source);
+       if (debug_flag >= 4)
+               SetConfigOption("debug_print_plan", "true", context, source);
+       if (debug_flag >= 5)
+               SetConfigOption("debug_print_rewritten", "true", context, source);
+}
+
+
 /* ----------------------------------------------------------------
  * PostgresMain
  *        postgres main loop -- all backends, interactive or otherwise start here
@@ -2169,10 +2204,12 @@ PostgresMain(int argc, char *argv[], const char *username)
        char       *userDoption = NULL;
        bool            secure;
        int                     errs = 0;
-       int                     debug_flag = 0;
-       GucContext      ctx,
-                               debug_context;
+       int                     debug_flag = -1;                /* -1 means not given */
+       List       *guc_names = NIL;            /* for possibly-SUSET options */
+       List       *guc_values = NIL;
+       GucContext      ctx;
        GucSource       gucsource;
+       bool            am_superuser;
        char       *tmp;
        int                     firstchar;
        char            stack_base;
@@ -2180,6 +2217,10 @@ PostgresMain(int argc, char *argv[], const char *username)
        sigjmp_buf      local_sigjmp_buf;
        volatile bool send_rfq = true;
 
+#define PendingConfigOption(name,val) \
+       (guc_names = lappend(guc_names, pstrdup(name)), \
+        guc_values = lappend(guc_values, pstrdup(val)))
+
        /*
         * Catch standard options before doing much else.  This even works on
         * systems without getopt_long.
@@ -2257,10 +2298,11 @@ PostgresMain(int argc, char *argv[], const char *username)
 
        /* all options are allowed until '-p' */
        secure = true;
-       ctx = debug_context = PGC_POSTMASTER;
+       ctx = PGC_POSTMASTER;
        gucsource = PGC_S_ARGV;         /* initial switches came from command line */
 
        while ((flag = getopt(argc, argv, "A:B:c:D:d:Eef:FiNOPo:p:S:st:v:W:-:")) != -1)
+       {
                switch (flag)
                {
                        case 'A':
@@ -2287,40 +2329,7 @@ PostgresMain(int argc, char *argv[], const char *username)
                                break;
 
                        case 'd':                       /* debug level */
-                               {
-                                       /*
-                                        * Client option can't decrease debug level. We have
-                                        * to do the test here because we group priv and
-                                        * client set GUC calls below, after we know the final
-                                        * debug value.
-                                        */
-                                       if (ctx != PGC_BACKEND || atoi(optarg) > debug_flag)
-                                       {
-                                               debug_flag = atoi(optarg);
-                                               debug_context = ctx;    /* save context for use
-                                                                                                * below */
-                                               /* Set server debugging level. */
-                                               if (debug_flag != 0)
-                                               {
-                                                       char       *debugstr = palloc(strlen("debug") + strlen(optarg) + 1);
-
-                                                       sprintf(debugstr, "debug%s", optarg);
-                                                       SetConfigOption("log_min_messages", debugstr, ctx, gucsource);
-                                                       pfree(debugstr);
-
-                                               }
-                                               else
-
-                                                       /*
-                                                        * -d0 allows user to prevent postmaster debug
-                                                        * from propagating to backend.  It would be
-                                                        * nice to set it to the postgresql.conf value
-                                                        * here.
-                                                        */
-                                                       SetConfigOption("log_min_messages", "notice",
-                                                                                       ctx, gucsource);
-                                       }
-                               }
+                               debug_flag = atoi(optarg);
                                break;
 
                        case 'E':
@@ -2448,7 +2457,7 @@ PostgresMain(int argc, char *argv[], const char *username)
                                /*
                                 * s - report usage statistics (timings) after each query
                                 */
-                               SetConfigOption("log_statement_stats", "true", ctx, gucsource);
+                               PendingConfigOption("log_statement_stats", "true");
                                break;
 
                        case 't':
@@ -2481,7 +2490,7 @@ PostgresMain(int argc, char *argv[], const char *username)
                                                break;
                                }
                                if (tmp)
-                                       SetConfigOption(tmp, "true", ctx, gucsource);
+                                       PendingConfigOption(tmp, "true");
                                break;
 
                        case 'v':
@@ -2518,7 +2527,7 @@ PostgresMain(int argc, char *argv[], const char *username)
                                                                                        optarg)));
                                        }
 
-                                       SetConfigOption(name, value, ctx, gucsource);
+                                       PendingConfigOption(name, value);
                                        free(name);
                                        if (value)
                                                free(value);
@@ -2529,53 +2538,6 @@ PostgresMain(int argc, char *argv[], const char *username)
                                errs++;
                                break;
                }
-
-
-       /*
-        * -d is not the same as setting log_min_messages because it enables
-        * other output options.
-        */
-       if (debug_flag >= 1)
-       {
-               SetConfigOption("log_connections", "true", debug_context, gucsource);
-               SetConfigOption("log_disconnections", "true", debug_context, gucsource);
-       }
-       if (debug_flag >= 2)
-               SetConfigOption("log_statement", "all", debug_context, gucsource);
-       if (debug_flag >= 3)
-               SetConfigOption("debug_print_parse", "true", debug_context, gucsource);
-       if (debug_flag >= 4)
-               SetConfigOption("debug_print_plan", "true", debug_context, gucsource);
-       if (debug_flag >= 5)
-               SetConfigOption("debug_print_rewritten", "true", debug_context, gucsource);
-
-       /*
-        * Process any additional GUC variable settings passed in startup
-        * packet.
-        */
-       if (MyProcPort != NULL)
-       {
-               ListCell   *gucopts = list_head(MyProcPort->guc_options);
-
-               while (gucopts)
-               {
-                       char       *name;
-                       char       *value;
-
-                       name = lfirst(gucopts);
-                       gucopts = lnext(gucopts);
-
-                       value = lfirst(gucopts);
-                       gucopts = lnext(gucopts);
-
-                       SetConfigOption(name, value, PGC_BACKEND, PGC_S_CLIENT);
-               }
-
-               /*
-                * set up handler to log session end.
-                */
-               if (IsUnderPostmaster && Log_disconnections)
-                       on_proc_exit(log_disconnections, 0);
        }
 
        /* Acquire configuration parameters, unless inherited from postmaster */
@@ -2710,10 +2672,72 @@ PostgresMain(int argc, char *argv[], const char *username)
         */
        ereport(DEBUG3,
                        (errmsg_internal("InitPostgres")));
-       InitPostgres(dbname, username);
+       am_superuser = InitPostgres(dbname, username);
 
        SetProcessingMode(NormalProcessing);
 
+       /*
+        * Now that we know if client is a superuser, we can apply GUC options
+        * that came from the client.  (For option switches that are definitely
+        * not SUSET, we just went ahead and applied them above, but anything
+        * that is or might be SUSET has to be postponed to here.)
+        */
+       ctx = am_superuser ? PGC_SUSET : PGC_USERSET;
+
+       if (debug_flag >= 0)
+               set_debug_options(debug_flag, ctx, PGC_S_CLIENT);
+
+       if (guc_names != NIL)
+       {
+               ListCell   *namcell,
+                                  *valcell;
+
+               forboth(namcell, guc_names, valcell, guc_values)
+               {
+                       char       *name = (char *) lfirst(namcell);
+                       char       *value = (char *) lfirst(valcell);
+
+                       SetConfigOption(name, value, ctx, PGC_S_CLIENT);
+                       pfree(name);
+                       pfree(value);
+               }
+       }
+
+       /*
+        * Process any additional GUC variable settings passed in startup
+        * packet.
+        */
+       if (MyProcPort != NULL)
+       {
+               ListCell   *gucopts = list_head(MyProcPort->guc_options);
+
+               while (gucopts)
+               {
+                       char       *name;
+                       char       *value;
+
+                       name = lfirst(gucopts);
+                       gucopts = lnext(gucopts);
+
+                       value = lfirst(gucopts);
+                       gucopts = lnext(gucopts);
+
+                       SetConfigOption(name, value, ctx, PGC_S_CLIENT);
+               }
+
+               /*
+                * set up handler to log session end.
+                */
+               if (IsUnderPostmaster && Log_disconnections)
+                       on_proc_exit(log_disconnections, 0);
+       }
+
+       /*
+        * Now all GUC states are fully set up.  Report them to client if
+        * appropriate.
+        */
+       BeginReportingGUCOptions();
+
        /*
         * Send this backend's cancellation info to the frontend.
         */
index a8af269591e945711f4c48aee8d6aad22da2ca2d..ddbe08d5daa9be73462d6a9800e9abf78c751f20 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.137 2004/08/29 05:06:51 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.138 2004/11/14 19:35:32 tgl Exp $
  *
  *
  *-------------------------------------------------------------------------
@@ -221,14 +221,21 @@ BaseInit(void)
  * InitPostgres
  *             Initialize POSTGRES.
  *
+ * In bootstrap mode neither of the parameters are used.
+ *
+ * The return value indicates whether the userID is a superuser.  (That
+ * can only be tested inside a transaction, so we want to do it during
+ * the startup transaction rather than doing a separate one in postgres.c.)
+ * 
  * Note:
  *             Be very careful with the order of calls in the InitPostgres function.
  * --------------------------------
  */
-void
+bool
 InitPostgres(const char *dbname, const char *username)
 {
        bool            bootstrap = IsBootstrapProcessingMode();
+       bool            am_superuser;
 
        /*
         * Set up the global variables holding database id and path.
@@ -397,16 +404,20 @@ InitPostgres(const char *dbname, const char *username)
         */
        RelationCacheInitializePhase3();
 
+       /*
+        * Check if user is a superuser.
+        */
+       if (bootstrap)
+               am_superuser = true;
+       else
+               am_superuser = superuser();
+
        /*
         * Check a normal user hasn't connected to a superuser reserved slot.
-        * We can't do this till after we've read the user information, and we
-        * must do it inside a transaction since checking superuserness may
-        * require database access.  The superuser check is probably the most
-        * expensive part; don't do it until necessary.
         */
-       if (ReservedBackends > 0 &&
-               CountEmptyBackendSlots() < ReservedBackends &&
-               !superuser())
+       if (!am_superuser &&
+               ReservedBackends > 0 &&
+               CountEmptyBackendSlots() < ReservedBackends)
                ereport(FATAL,
                                (errcode(ERRCODE_TOO_MANY_CONNECTIONS),
                                 errmsg("connection limit exceeded for non-superusers")));
@@ -422,12 +433,6 @@ InitPostgres(const char *dbname, const char *username)
        /* initialize client encoding */
        InitializeClientEncoding();
 
-       /*
-        * Now all default states are fully set up.  Report them to client if
-        * appropriate.
-        */
-       BeginReportingGUCOptions();
-
        /*
         * Set up process-exit callback to do pre-shutdown cleanup.  This
         * should be last because we want shmem_exit to call this routine
@@ -440,6 +445,8 @@ InitPostgres(const char *dbname, const char *username)
        /* close the transaction we started above */
        if (!bootstrap)
                CommitTransactionCommand();
+
+       return am_superuser;
 }
 
 /*
index b59644397cf03f300495f7324bf4c84511d0c9bd..581a96caa2623f04740bc6434947caaaf20ddd40 100644 (file)
@@ -10,7 +10,7 @@
  * Written by Peter Eisentraut <peter_e@gmx.net>.
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.248 2004/11/05 19:16:16 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.249 2004/11/14 19:35:33 tgl Exp $
  *
  *--------------------------------------------------------------------
  */
@@ -105,8 +105,6 @@ static const char *assign_log_error_verbosity(const char *newval, bool doit,
                                                   GucSource source);
 static const char *assign_log_statement(const char *newval, bool doit,
                                         GucSource source);
-static const char *assign_log_stmtlvl(int *var, const char *newval,
-                                  bool doit, GucSource source);
 static bool assign_phony_autocommit(bool newval, bool doit, GucSource source);
 static const char *assign_custom_variable_classes(const char *newval, bool doit,
                                                           GucSource source);
@@ -204,7 +202,6 @@ const char *const GucContext_Names[] =
         /* PGC_SIGHUP */ "sighup",
         /* PGC_BACKEND */ "backend",
         /* PGC_SUSET */ "superuser",
-        /* PGC_USERLIMIT */ "userlimit",
         /* PGC_USERSET */ "user"
 };
 
@@ -219,7 +216,6 @@ const char *const GucSource_Names[] =
         /* PGC_S_ENV_VAR */ "environment variable",
         /* PGC_S_FILE */ "configuration file",
         /* PGC_S_ARGV */ "command line",
-        /* PGC_S_UNPRIVILEGED */ "unprivileged",
         /* PGC_S_DATABASE */ "database",
         /* PGC_S_USER */ "user",
         /* PGC_S_CLIENT */ "client",
@@ -520,8 +516,8 @@ static struct config_bool ConfigureNamesBool[] =
                false, NULL, NULL
        },
        {
-               {"log_duration", PGC_USERLIMIT, LOGGING_WHAT,
-                       gettext_noop("Logs the duration each completed SQL statement."),
+               {"log_duration", PGC_SUSET, LOGGING_WHAT,
+                       gettext_noop("Logs the duration of each completed SQL statement."),
                        NULL
                },
                &log_duration,
@@ -560,7 +556,7 @@ static struct config_bool ConfigureNamesBool[] =
                false, NULL, NULL
        },
        {
-               {"log_parser_stats", PGC_USERLIMIT, STATS_MONITORING,
+               {"log_parser_stats", PGC_SUSET, STATS_MONITORING,
                        gettext_noop("Writes parser performance statistics to the server log."),
                        NULL
                },
@@ -568,7 +564,7 @@ static struct config_bool ConfigureNamesBool[] =
                false, assign_stage_log_stats, NULL
        },
        {
-               {"log_planner_stats", PGC_USERLIMIT, STATS_MONITORING,
+               {"log_planner_stats", PGC_SUSET, STATS_MONITORING,
                        gettext_noop("Writes planner performance statistics to the server log."),
                        NULL
                },
@@ -576,7 +572,7 @@ static struct config_bool ConfigureNamesBool[] =
                false, assign_stage_log_stats, NULL
        },
        {
-               {"log_executor_stats", PGC_USERLIMIT, STATS_MONITORING,
+               {"log_executor_stats", PGC_SUSET, STATS_MONITORING,
                        gettext_noop("Writes executor performance statistics to the server log."),
                        NULL
                },
@@ -584,7 +580,7 @@ static struct config_bool ConfigureNamesBool[] =
                false, assign_stage_log_stats, NULL
        },
        {
-               {"log_statement_stats", PGC_USERLIMIT, STATS_MONITORING,
+               {"log_statement_stats", PGC_SUSET, STATS_MONITORING,
                        gettext_noop("Writes cumulative performance statistics to the server log."),
                        NULL
                },
@@ -1225,7 +1221,7 @@ static struct config_int ConfigureNamesInt[] =
        },
 
        {
-               {"log_min_duration_statement", PGC_USERLIMIT, LOGGING_WHEN,
+               {"log_min_duration_statement", PGC_SUSET, LOGGING_WHEN,
                        gettext_noop("Sets the minimum execution time in milliseconds above which statements will "
                                                 "be logged."),
                        gettext_noop("Zero prints all queries. The default is -1 (turning this feature off).")
@@ -1449,7 +1445,7 @@ static struct config_string ConfigureNamesString[] =
        },
 
        {
-               {"log_min_messages", PGC_USERLIMIT, LOGGING_WHEN,
+               {"log_min_messages", PGC_SUSET, LOGGING_WHEN,
                        gettext_noop("Sets the message levels that are logged."),
                        gettext_noop("Valid values are DEBUG5, DEBUG4, DEBUG3, DEBUG2, DEBUG1, "
                                                 "INFO, NOTICE, WARNING, ERROR, LOG, FATAL, and PANIC. Each level "
@@ -1468,16 +1464,16 @@ static struct config_string ConfigureNamesString[] =
                "default", assign_log_error_verbosity, NULL
        },
        {
-               {"log_statement", PGC_USERLIMIT, LOGGING_WHAT,
+               {"log_statement", PGC_SUSET, LOGGING_WHAT,
                        gettext_noop("Sets the type of statements logged."),
-                       gettext_noop("Valid values are \"none\", \"mod\", \"ddl\", and \"all\".")
+                       gettext_noop("Valid values are \"none\", \"ddl\", \"mod\", and \"all\".")
                },
                &log_statement_str,
                "none", assign_log_statement, NULL
        },
 
        {
-               {"log_min_error_statement", PGC_USERLIMIT, LOGGING_WHEN,
+               {"log_min_error_statement", PGC_SUSET, LOGGING_WHEN,
                        gettext_noop("Causes all statements generating error at or above this level to be logged."),
                        gettext_noop("All SQL statements that cause an error of the "
                                                 "specified level or a higher level are logged.")
@@ -1896,10 +1892,6 @@ static void ReportGUCOption(struct config_generic * record);
 static void ShowGUCConfigOption(const char *name, DestReceiver *dest);
 static void ShowAllGUCConfig(DestReceiver *dest);
 static char *_ShowOption(struct config_generic * record);
-static bool check_userlimit_privilege(struct config_generic *record,
-                                                                         GucSource source, int elevel);
-static bool check_userlimit_override(struct config_generic *record,
-                                                                        GucSource source);
 
 
 /*
@@ -2345,13 +2337,6 @@ InitializeGUCOptions(void)
 
                                        Assert(conf->reset_val >= conf->min);
                                        Assert(conf->reset_val <= conf->max);
-
-                                       /*
-                                        * Check to make sure we only have valid
-                                        * PGC_USERLIMITs
-                                        */
-                                       Assert(conf->gen.context != PGC_USERLIMIT ||
-                                                  strcmp(conf->gen.name, "log_min_duration_statement") == 0);
                                        if (conf->assign_hook)
                                                if (!(*conf->assign_hook) (conf->reset_val, true,
                                                                                                   PGC_S_DEFAULT))
@@ -2366,7 +2351,6 @@ InitializeGUCOptions(void)
 
                                        Assert(conf->reset_val >= conf->min);
                                        Assert(conf->reset_val <= conf->max);
-                                       Assert(conf->gen.context != PGC_USERLIMIT);
                                        if (conf->assign_hook)
                                                if (!(*conf->assign_hook) (conf->reset_val, true,
                                                                                                   PGC_S_DEFAULT))
@@ -2380,14 +2364,6 @@ InitializeGUCOptions(void)
                                        struct config_string *conf = (struct config_string *) gconf;
                                        char       *str;
 
-                                       /*
-                                        * Check to make sure we only have valid
-                                        * PGC_USERLIMITs
-                                        */
-                                       Assert(conf->gen.context != PGC_USERLIMIT ||
-                                                  conf->assign_hook == assign_log_min_messages ||
-                                          conf->assign_hook == assign_min_error_statement ||
-                                                  conf->assign_hook == assign_log_statement);
                                        *conf->variable = NULL;
                                        conf->reset_val = NULL;
                                        conf->tentative_val = NULL;
@@ -2628,7 +2604,6 @@ ResetAllOptions(void)
 
                /* Don't reset non-SET-able values */
                if (gconf->context != PGC_SUSET &&
-                       gconf->context != PGC_USERLIMIT &&
                        gconf->context != PGC_USERSET)
                        continue;
                /* Don't reset if special exclusion from RESET ALL */
@@ -3276,8 +3251,7 @@ set_config_option(const char *name, const char *value,
 {
        struct config_generic *record;
        int                     elevel;
-       bool            makeDefault,
-                               changeValOrig = changeVal;
+       bool            makeDefault;
 
        if (context == PGC_SIGHUP || source == PGC_S_DEFAULT)
        {
@@ -3383,9 +3357,6 @@ set_config_option(const char *name, const char *value,
                                return false;
                        }
                        break;
-               case PGC_USERLIMIT:
-                       /* USERLIMIT permissions checked below */
-                       break;
                case PGC_USERSET:
                        /* always okay */
                        break;
@@ -3413,14 +3384,11 @@ set_config_option(const char *name, const char *value,
                                 name);
                        return true;
                }
-               changeVal = false;              /* this might be reset in USERLIMIT */
+               changeVal = false;
        }
 
        /*
-        * Evaluate value and set variable. USERLIMIT checks two things:  1)
-        * is the user making a change that is blocked by an administrator
-        * setting.  2) is the administrator changing a setting and doing a
-        * SIGHUP that requires us to override a user setting.
+        * Evaluate value and set variable.
         */
        switch (record->vartype)
        {
@@ -3439,22 +3407,6 @@ set_config_option(const char *name, const char *value,
                                                                                name)));
                                                return false;
                                        }
-                                       if (record->context == PGC_USERLIMIT)
-                                       {
-                                               if (newval < conf->reset_val)
-                                               {
-                                                       /* Limit non-superuser changes */
-                                                       if (!check_userlimit_privilege(record, source,
-                                                                                                                  elevel))
-                                                               return false;
-                                               }
-                                               if (newval > *conf->variable)
-                                               {
-                                                       /* Allow change if admin should override */
-                                                       if (check_userlimit_override(record, source))
-                                                               changeVal = changeValOrig;
-                                               }
-                                       }
                                }
                                else
                                {
@@ -3539,30 +3491,6 @@ set_config_option(const char *name, const char *value,
                                                                   newval, name, conf->min, conf->max)));
                                                return false;
                                        }
-                                       if (record->context == PGC_USERLIMIT)
-                                       {
-                                               /*
-                                                * handle log_min_duration_statement: if it's enabled
-                                                * then either turning it off or increasing it
-                                                * requires privileges.
-                                                */
-                                               if (conf->reset_val != -1 &&
-                                                       (newval == -1 || newval > conf->reset_val))
-                                               {
-                                                       /* Limit non-superuser changes */
-                                                       if (!check_userlimit_privilege(record, source,
-                                                                                                                  elevel))
-                                                               return false;
-                                               }
-                                               /* Admin override includes turning on or decreasing */
-                                               if (newval != -1 &&
-                                                       (*conf->variable == -1 || newval < *conf->variable))
-                                               {
-                                                       /* Allow change if admin should override */
-                                                       if (check_userlimit_override(record, source))
-                                                               changeVal = changeValOrig;
-                                               }
-                                       }
                                }
                                else
                                {
@@ -3647,23 +3575,6 @@ set_config_option(const char *name, const char *value,
                                                                   newval, name, conf->min, conf->max)));
                                                return false;
                                        }
-                                       if (record->context == PGC_USERLIMIT)
-                                       {
-                                               /* No REAL PGC_USERLIMIT at present */
-                                               if (newval < conf->reset_val)
-                                               {
-                                                       /* Limit non-superuser changes */
-                                                       if (!check_userlimit_privilege(record, source,
-                                                                                                                  elevel))
-                                                               return false;
-                                               }
-                                               if (newval > *conf->variable)
-                                               {
-                                                       /* Allow change if admin should override */
-                                                       if (check_userlimit_override(record, source))
-                                                               changeVal = changeValOrig;
-                                               }
-                                       }
                                }
                                else
                                {
@@ -3735,40 +3646,6 @@ set_config_option(const char *name, const char *value,
                                        newval = guc_strdup(elevel, value);
                                        if (newval == NULL)
                                                return false;
-
-                                       if (record->context == PGC_USERLIMIT)
-                                       {
-                                               int                     var_value,
-                                                                       reset_value,
-                                                                       new_value;
-                                               const char *(*var_hook) (int *var, const char *newval,
-                                                                                       bool doit, GucSource source);
-
-                                               if (conf->assign_hook == assign_log_statement)
-                                                       var_hook = assign_log_stmtlvl;
-                                               else
-                                                       var_hook = assign_msglvl;
-
-                                               (*var_hook) (&new_value, newval, true, source);
-                                               (*var_hook) (&reset_value, conf->reset_val, true,
-                                                                        source);
-                                               (*var_hook) (&var_value, *conf->variable, true,
-                                                                        source);
-
-                                               if (new_value > reset_value)
-                                               {
-                                                       /* Limit non-superuser changes */
-                                                       if (!check_userlimit_privilege(record, source,
-                                                                                                                  elevel))
-                                                               return false;
-                                               }
-                                               if (new_value < var_value)
-                                               {
-                                                       /* Allow change if admin should override */
-                                                       if (check_userlimit_override(record, source))
-                                                               changeVal = changeValOrig;
-                                               }
-                                       }
                                }
                                else if (conf->reset_val)
                                {
@@ -3888,72 +3765,6 @@ set_config_option(const char *name, const char *value,
        return true;
 }
 
-/*
- * Check whether we should allow a USERLIMIT parameter to be set
- *
- * This is invoked only when the desired new setting is "less" than the
- * old and so appropriate privileges are needed.  If the setting should
- * be disallowed, either throw an error (in interactive case) or return false.
- */
-static bool
-check_userlimit_privilege(struct config_generic *record, GucSource source,
-                                                 int elevel)
-{
-       /* Allow if trusted source (e.g., config file) */
-       if (source < PGC_S_UNPRIVILEGED)
-               return true;
-       /*
-        * Allow if superuser.  We can only check this inside a transaction,
-        * though, so assume not-superuser otherwise.  (In practice this means
-        * that settings coming from PGOPTIONS will be treated as non-superuser)
-        */
-       if (IsTransactionState() && superuser())
-               return true;
-
-       ereport(elevel,
-                       (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
-                        errmsg("permission denied to set parameter \"%s\"",
-                                       record->name),
-                        (record->vartype == PGC_BOOL) ?
-                        errhint("Must be superuser to change this value to false.")
-                        : ((record->vartype == PGC_INT) ?
-                               errhint("Must be superuser to increase this value or turn it off.")
-                               : errhint("Must be superuser to increase this value."))));
-       return false;
-}
-
-/*
- * Check whether we should allow a USERLIMIT parameter to be overridden
- *
- * This is invoked when the desired new setting is "greater" than the
- * old; if the old setting was unprivileged and the new one is privileged,
- * we should apply it, even though the normal rule would be not to.
- */
-static bool
-check_userlimit_override(struct config_generic *record, GucSource source)
-{
-       /* Unprivileged source never gets to override this way */
-       if (source > PGC_S_UNPRIVILEGED)
-               return false;
-       /* If existing setting is from privileged source, keep it */
-       if (record->source < PGC_S_UNPRIVILEGED)
-               return false;
-       /*
-        * If user is a superuser, he gets to keep his setting.  We can't check
-        * this unless inside a transaction, though.  XXX in practice that
-        * restriction means this code is essentially worthless, because the
-        * result will depend on whether we happen to be inside a transaction
-        * block when SIGHUP arrives.  Dike out until we can think of something
-        * that actually works.
-        */
-#ifdef NOT_USED
-       if (IsTransactionState() && superuser())
-               return false;
-#endif
-       /* Otherwise override */
-       return true;
-}
-
 
 /*
  * Set a config option to the given value. See also set_config_option,
@@ -5635,32 +5446,26 @@ assign_log_error_verbosity(const char *newval, bool doit, GucSource source)
 
 static const char *
 assign_log_statement(const char *newval, bool doit, GucSource source)
-{
-       return (assign_log_stmtlvl((int *) &log_statement, newval, doit, source));
-}
-
-static const char *
-assign_log_stmtlvl(int *var, const char *newval, bool doit, GucSource source)
 {
        if (pg_strcasecmp(newval, "none") == 0)
        {
                if (doit)
-                       (*var) = LOGSTMT_NONE;
+                       log_statement = LOGSTMT_NONE;
        }
-       else if (pg_strcasecmp(newval, "mod") == 0)
+       else if (pg_strcasecmp(newval, "ddl") == 0)
        {
                if (doit)
-                       (*var) = LOGSTMT_MOD;
+                       log_statement = LOGSTMT_DDL;
        }
-       else if (pg_strcasecmp(newval, "ddl") == 0)
+       else if (pg_strcasecmp(newval, "mod") == 0)
        {
                if (doit)
-                       (*var) = LOGSTMT_DDL;
+                       log_statement = LOGSTMT_MOD;
        }
        else if (pg_strcasecmp(newval, "all") == 0)
        {
                if (doit)
-                       (*var) = LOGSTMT_ALL;
+                       log_statement = LOGSTMT_ALL;
        }
        else
                return NULL;                    /* fail */
index ec3ea9334d24b24303017441e086878342203f2a..83e36ba24e8c0372b5bd501dadb09200bc4b7aef 100644 (file)
@@ -13,7 +13,7 @@
  * Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.172 2004/10/22 22:33:58 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.173 2004/11/14 19:35:34 tgl Exp $
  *
  * NOTES
  *       some of the information in this file should be moved to other files.
@@ -302,7 +302,7 @@ extern ProcessingMode Mode;
  *****************************************************************************/
 
 /* in utils/init/postinit.c */
-extern void InitPostgres(const char *dbname, const char *username);
+extern bool InitPostgres(const char *dbname, const char *username);
 extern void BaseInit(void);
 
 /* in utils/init/miscinit.c */
index b70cc6a0737d08ee93b6bcf881543ac0650650f1..1c7825ff460cd045314fa57465372dfecb4af233 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/tcop/tcopprot.h,v 1.71 2004/08/29 05:06:58 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/tcop/tcopprot.h,v 1.72 2004/11/14 19:35:35 tgl Exp $
  *
  * OLD COMMENTS
  *       This file was created so that other c files could get the two
@@ -33,11 +33,10 @@ extern int  max_stack_depth;
 
 typedef enum
 {
-       /* Reverse order so GUC USERLIMIT is easier */
-       LOGSTMT_ALL,                            /* log all statements */
+       LOGSTMT_NONE,                           /* log no statements */
        LOGSTMT_DDL,                            /* log data definition statements */
        LOGSTMT_MOD,                            /* log modification statements, plus DDL */
-       LOGSTMT_NONE                            /* log no statements */
+       LOGSTMT_ALL                                     /* log all statements */
 } LogStmtLevel;
 
 extern LogStmtLevel log_statement;
@@ -63,5 +62,7 @@ extern void authdie(SIGNAL_ARGS);
 extern int     PostgresMain(int argc, char *argv[], const char *username);
 extern void ResetUsage(void);
 extern void ShowUsage(const char *title);
+extern void set_debug_options(int debug_flag,
+                                                         GucContext context, GucSource source);
 
 #endif   /* TCOPPROT_H */
index 19ae296559dba8cdeedf49f19ef30088b00eea9c..f5f4a78fe4d3a3bfc943bb96e46524e89efae966 100644 (file)
@@ -7,7 +7,7 @@
  * Copyright (c) 2000-2004, PostgreSQL Global Development Group
  * Written by Peter Eisentraut <peter_e@gmx.net>.
  *
- * $PostgreSQL: pgsql/src/include/utils/guc.h,v 1.55 2004/11/05 19:16:41 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/utils/guc.h,v 1.56 2004/11/14 19:35:35 tgl Exp $
  *--------------------------------------------------------------------
  */
 #ifndef GUC_H
@@ -48,9 +48,6 @@
  * be set in the connection startup packet, because when it is processed
  * we don't yet know if the user is a superuser.
  *
- * USERLIMIT options can only be manipulated in certain ways by
- * non-superusers.
- *
  * USERSET options can be set by anyone any time.
  */
 typedef enum
@@ -60,7 +57,6 @@ typedef enum
        PGC_SIGHUP,
        PGC_BACKEND,
        PGC_SUSET,
-       PGC_USERLIMIT,
        PGC_USERSET
 } GucContext;
 
@@ -74,9 +70,7 @@ typedef enum
  * as the current value.  Note that source == PGC_S_OVERRIDE should be
  * used when setting a PGC_INTERNAL option.
  *
- * PGC_S_UNPRIVILEGED isn't actually a source value, but the dividing line
- * between privileged and unprivileged sources for USERLIMIT purposes.
- * Similarly, PGC_S_INTERACTIVE isn't a real source value, but is the
+ * PGC_S_INTERACTIVE isn't actually a source value, but is the
  * dividing line between "interactive" and "non-interactive" sources for
  * error reporting purposes.
  *
@@ -92,7 +86,6 @@ typedef enum
        PGC_S_ENV_VAR,                          /* postmaster environment variable */
        PGC_S_FILE,                                     /* postgresql.conf */
        PGC_S_ARGV,                                     /* postmaster command line */
-       PGC_S_UNPRIVILEGED,                     /* dividing line for USERLIMIT */
        PGC_S_DATABASE,                         /* per-database setting */
        PGC_S_USER,                                     /* per-user setting */
        PGC_S_CLIENT,                           /* from client connection request */