Header And Logo

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

Defines | Enumerations | Functions | Variables

tcopprot.h File Reference

#include "nodes/params.h"
#include "nodes/parsenodes.h"
#include "nodes/plannodes.h"
#include "storage/procsignal.h"
#include "utils/guc.h"
Include dependency graph for tcopprot.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Defines

#define STACK_DEPTH_SLOP   (512 * 1024L)

Enumerations

enum  LogStmtLevel { LOGSTMT_NONE, LOGSTMT_DDL, LOGSTMT_MOD, LOGSTMT_ALL }

Functions

Listpg_parse_query (const char *query_string)
Listpg_analyze_and_rewrite (Node *parsetree, const char *query_string, Oid *paramTypes, int numParams)
Listpg_analyze_and_rewrite_params (Node *parsetree, const char *query_string, ParserSetupHook parserSetup, void *parserSetupArg)
PlannedStmtpg_plan_query (Query *querytree, int cursorOptions, ParamListInfo boundParams)
Listpg_plan_queries (List *querytrees, int cursorOptions, ParamListInfo boundParams)
bool check_max_stack_depth (int *newval, void **extra, GucSource source)
void assign_max_stack_depth (int newval, void *extra)
void die (SIGNAL_ARGS)
void quickdie (SIGNAL_ARGS) __attribute__((noreturn))
void StatementCancelHandler (SIGNAL_ARGS)
void FloatExceptionHandler (SIGNAL_ARGS) __attribute__((noreturn))
void RecoveryConflictInterrupt (ProcSignalReason reason)
void prepare_for_client_read (void)
void client_read_ended (void)
void process_postgres_switches (int argc, char *argv[], GucContext ctx, const char **dbname)
void PostgresMain (int argc, char *argv[], const char *dbname, const char *username) __attribute__((noreturn))
long get_stack_depth_rlimit (void)
void ResetUsage (void)
void ShowUsage (const char *title)
int check_log_duration (char *msec_str, bool was_logged)
void set_debug_options (int debug_flag, GucContext context, GucSource source)
bool set_plan_disabling_options (const char *arg, GucContext context, GucSource source)
const char * get_stats_option_name (const char *arg)

Variables

CommandDest whereToSendOutput
PGDLLIMPORT const char * debug_query_string
int max_stack_depth
int PostAuthDelay
int log_statement

Define Documentation

#define STACK_DEPTH_SLOP   (512 * 1024L)

Definition at line 30 of file tcopprot.h.

Referenced by check_max_stack_depth().


Enumeration Type Documentation

Enumerator:
LOGSTMT_NONE 
LOGSTMT_DDL 
LOGSTMT_MOD 
LOGSTMT_ALL 

Definition at line 39 of file tcopprot.h.

{
    LOGSTMT_NONE,               /* log no statements */
    LOGSTMT_DDL,                /* log data definition statements */
    LOGSTMT_MOD,                /* log modification statements, plus DDL */
    LOGSTMT_ALL                 /* log all statements */
} LogStmtLevel;


Function Documentation

void assign_max_stack_depth ( int  newval,
void *  extra 
)

Definition at line 3129 of file postgres.c.

References max_stack_depth_bytes.

{
    long        newval_bytes = newval * 1024L;

    max_stack_depth_bytes = newval_bytes;
}

int check_log_duration ( char *  msec_str,
bool  was_logged 
)

Definition at line 2046 of file postgres.c.

References GetCurrentStatementStartTimestamp(), GetCurrentTimestamp(), log_duration, log_min_duration_statement, snprintf(), and TimestampDifference().

Referenced by exec_bind_message(), exec_execute_message(), exec_parse_message(), exec_simple_query(), and HandleFunctionRequest().

{
    if (log_duration || log_min_duration_statement >= 0)
    {
        long        secs;
        int         usecs;
        int         msecs;
        bool        exceeded;

        TimestampDifference(GetCurrentStatementStartTimestamp(),
                            GetCurrentTimestamp(),
                            &secs, &usecs);
        msecs = usecs / 1000;

        /*
         * This odd-looking test for log_min_duration_statement being exceeded
         * is designed to avoid integer overflow with very long durations:
         * don't compute secs * 1000 until we've verified it will fit in int.
         */
        exceeded = (log_min_duration_statement == 0 ||
                    (log_min_duration_statement > 0 &&
                     (secs > log_min_duration_statement / 1000 ||
                      secs * 1000 + msecs >= log_min_duration_statement)));

        if (exceeded || log_duration)
        {
            snprintf(msec_str, 32, "%ld.%03d",
                     secs * 1000 + msecs, usecs % 1000);
            if (exceeded && !was_logged)
                return 2;
            else
                return 1;
        }
    }

    return 0;
}

bool check_max_stack_depth ( int *  newval,
void **  extra,
GucSource  source 
)

Definition at line 3112 of file postgres.c.

References get_stack_depth_rlimit(), GUC_check_errdetail, GUC_check_errhint, and STACK_DEPTH_SLOP.

{
    long        newval_bytes = *newval * 1024L;
    long        stack_rlimit = get_stack_depth_rlimit();

    if (stack_rlimit > 0 && newval_bytes > stack_rlimit - STACK_DEPTH_SLOP)
    {
        GUC_check_errdetail("\"max_stack_depth\" must not exceed %ldkB.",
                            (stack_rlimit - STACK_DEPTH_SLOP) / 1024L);
        GUC_check_errhint("Increase the platform's stack depth limit via \"ulimit -s\" or local equivalent.");
        return false;
    }
    return true;
}

void client_read_ended ( void   ) 
void die ( SIGNAL_ARGS   ) 

Definition at line 2576 of file postgres.c.

References CritSectionCount, DisableCatchupInterrupt(), DisableNotifyInterrupt(), ImmediateInterruptOK, InterruptHoldoffCount, InterruptPending, LockErrorCleanup(), MyProc, proc_exit_inprogress, ProcDiePending, ProcessInterrupts(), PGPROC::procLatch, and SetLatch().

{
    int         save_errno = errno;

    /* Don't joggle the elbow of proc_exit */
    if (!proc_exit_inprogress)
    {
        InterruptPending = true;
        ProcDiePending = true;

        /*
         * If it's safe to interrupt, and we're waiting for input or a lock,
         * service the interrupt immediately
         */
        if (ImmediateInterruptOK && InterruptHoldoffCount == 0 &&
            CritSectionCount == 0)
        {
            /* bump holdoff count to make ProcessInterrupts() a no-op */
            /* until we are done getting ready for it */
            InterruptHoldoffCount++;
            LockErrorCleanup(); /* prevent CheckDeadLock from running */
            DisableNotifyInterrupt();
            DisableCatchupInterrupt();
            InterruptHoldoffCount--;
            ProcessInterrupts();
        }
    }

    /* If we're still here, waken anything waiting on the process latch */
    if (MyProc)
        SetLatch(&MyProc->procLatch);

    errno = save_errno;
}

void FloatExceptionHandler ( SIGNAL_ARGS   ) 

Definition at line 2655 of file postgres.c.

References ereport, errcode(), errdetail(), errmsg(), and ERROR.

Referenced by AutoVacLauncherMain(), AutoVacWorkerMain(), do_start_bgworker(), plperl_init_interp(), and PostgresMain().

{
    /* We're not returning, so no need to save errno */
    ereport(ERROR,
            (errcode(ERRCODE_FLOATING_POINT_EXCEPTION),
             errmsg("floating-point exception"),
             errdetail("An invalid floating-point operation was signaled. "
                       "This probably means an out-of-range result or an "
                       "invalid operation, such as division by zero.")));
}

long get_stack_depth_rlimit ( void   ) 

Definition at line 4259 of file postgres.c.

References val.

Referenced by check_max_stack_depth(), and InitializeGUCOptionsFromEnvironment().

{
#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_STACK)
    static long val = 0;

    /* This won't change after process launch, so check just once */
    if (val == 0)
    {
        struct rlimit rlim;

        if (getrlimit(RLIMIT_STACK, &rlim) < 0)
            val = -1;
        else if (rlim.rlim_cur == RLIM_INFINITY)
            val = LONG_MAX;
        /* rlim_cur is probably of an unsigned type, so check for overflow */
        else if (rlim.rlim_cur >= LONG_MAX)
            val = LONG_MAX;
        else
            val = rlim.rlim_cur;
    }
    return val;
#else                           /* no getrlimit */
#if defined(WIN32) || defined(__CYGWIN__)
    /* On Windows we set the backend stack size in src/backend/Makefile */
    return WIN32_STACK_RLIMIT;
#else                           /* not windows ... give up */
    return -1;
#endif
#endif
}

const char* get_stats_option_name ( const char *  arg  ) 

Definition at line 3215 of file postgres.c.

References optarg.

Referenced by PostmasterMain(), and process_postgres_switches().

{
    switch (arg[0])
    {
        case 'p':
            if (optarg[1] == 'a')       /* "parser" */
                return "log_parser_stats";
            else if (optarg[1] == 'l')  /* "planner" */
                return "log_planner_stats";
            break;

        case 'e':               /* "executor" */
            return "log_executor_stats";
            break;
    }

    return NULL;
}

List* pg_analyze_and_rewrite ( Node parsetree,
const char *  query_string,
Oid paramTypes,
int  numParams 
)

Definition at line 599 of file postgres.c.

References log_parser_stats, parse_analyze(), pg_rewrite_query(), ResetUsage(), and ShowUsage().

Referenced by _SPI_execute_plan(), _SPI_prepare_plan(), BeginCopy(), exec_simple_query(), execute_sql_string(), and RevalidateCachedQuery().

{
    Query      *query;
    List       *querytree_list;

    TRACE_POSTGRESQL_QUERY_REWRITE_START(query_string);

    /*
     * (1) Perform parse analysis.
     */
    if (log_parser_stats)
        ResetUsage();

    query = parse_analyze(parsetree, query_string, paramTypes, numParams);

    if (log_parser_stats)
        ShowUsage("PARSE ANALYSIS STATISTICS");

    /*
     * (2) Rewrite the queries, as necessary
     */
    querytree_list = pg_rewrite_query(query);

    TRACE_POSTGRESQL_QUERY_REWRITE_DONE(query_string);

    return querytree_list;
}

List* pg_analyze_and_rewrite_params ( Node parsetree,
const char *  query_string,
ParserSetupHook  parserSetup,
void *  parserSetupArg 
)

Definition at line 634 of file postgres.c.

References Assert, free_parsestate(), log_parser_stats, make_parsestate(), NULL, ParseState::p_sourcetext, pg_rewrite_query(), post_parse_analyze_hook, ResetUsage(), ShowUsage(), and transformTopLevelStmt().

Referenced by _SPI_execute_plan(), _SPI_prepare_plan(), fmgr_sql_validator(), init_sql_fcache(), inline_set_returning_function(), and RevalidateCachedQuery().

{
    ParseState *pstate;
    Query      *query;
    List       *querytree_list;

    Assert(query_string != NULL);       /* required as of 8.4 */

    TRACE_POSTGRESQL_QUERY_REWRITE_START(query_string);

    /*
     * (1) Perform parse analysis.
     */
    if (log_parser_stats)
        ResetUsage();

    pstate = make_parsestate(NULL);
    pstate->p_sourcetext = query_string;
    (*parserSetup) (pstate, parserSetupArg);

    query = transformTopLevelStmt(pstate, parsetree);

    if (post_parse_analyze_hook)
        (*post_parse_analyze_hook) (pstate, query);

    free_parsestate(pstate);

    if (log_parser_stats)
        ShowUsage("PARSE ANALYSIS STATISTICS");

    /*
     * (2) Rewrite the queries, as necessary
     */
    querytree_list = pg_rewrite_query(query);

    TRACE_POSTGRESQL_QUERY_REWRITE_DONE(query_string);

    return querytree_list;
}

List* pg_parse_query ( const char *  query_string  ) 

Definition at line 557 of file postgres.c.

References copyObject(), elog, equal(), log_parser_stats, new_list(), raw_parser(), ResetUsage(), ShowUsage(), and WARNING.

Referenced by _SPI_prepare_oneshot_plan(), _SPI_prepare_plan(), exec_parse_message(), exec_simple_query(), execute_sql_string(), fmgr_sql_validator(), init_sql_fcache(), inline_function(), and inline_set_returning_function().

{
    List       *raw_parsetree_list;

    TRACE_POSTGRESQL_QUERY_PARSE_START(query_string);

    if (log_parser_stats)
        ResetUsage();

    raw_parsetree_list = raw_parser(query_string);

    if (log_parser_stats)
        ShowUsage("PARSER STATISTICS");

#ifdef COPY_PARSE_PLAN_TREES
    /* Optional debugging check: pass raw parsetrees through copyObject() */
    {
        List       *new_list = (List *) copyObject(raw_parsetree_list);

        /* This checks both copyObject() and the equal() routines... */
        if (!equal(new_list, raw_parsetree_list))
            elog(WARNING, "copyObject() failed to produce an equal raw parse tree");
        else
            raw_parsetree_list = new_list;
    }
#endif

    TRACE_POSTGRESQL_QUERY_PARSE_DONE(query_string);

    return raw_parsetree_list;
}

List* pg_plan_queries ( List querytrees,
int  cursorOptions,
ParamListInfo  boundParams 
)

Definition at line 795 of file postgres.c.

References CMD_UTILITY, Query::commandType, lappend(), lfirst, pg_plan_query(), and Query::utilityStmt.

Referenced by BuildCachedPlan(), exec_simple_query(), and execute_sql_string().

{
    List       *stmt_list = NIL;
    ListCell   *query_list;

    foreach(query_list, querytrees)
    {
        Query      *query = (Query *) lfirst(query_list);
        Node       *stmt;

        if (query->commandType == CMD_UTILITY)
        {
            /* Utility commands have no plans. */
            stmt = query->utilityStmt;
        }
        else
        {
            stmt = (Node *) pg_plan_query(query, cursorOptions, boundParams);
        }

        stmt_list = lappend(stmt_list, stmt);
    }

    return stmt_list;
}

PlannedStmt* pg_plan_query ( Query querytree,
int  cursorOptions,
ParamListInfo  boundParams 
)

Definition at line 736 of file postgres.c.

References ActiveSnapshotSet(), Assert, CMD_UTILITY, Query::commandType, copyObject(), Debug_pretty_print, Debug_print_plan, elog, elog_node_display(), equal(), LOG, log_planner_stats, planner(), ResetUsage(), ShowUsage(), and WARNING.

Referenced by ExecCreateTableAs(), ExplainOneQuery(), init_execution_state(), pg_plan_queries(), and refresh_matview_datafill().

{
    PlannedStmt *plan;

    /* Utility commands have no plans. */
    if (querytree->commandType == CMD_UTILITY)
        return NULL;

    /* Planner must have a snapshot in case it calls user-defined functions. */
    Assert(ActiveSnapshotSet());

    TRACE_POSTGRESQL_QUERY_PLAN_START();

    if (log_planner_stats)
        ResetUsage();

    /* call the optimizer */
    plan = planner(querytree, cursorOptions, boundParams);

    if (log_planner_stats)
        ShowUsage("PLANNER STATISTICS");

#ifdef COPY_PARSE_PLAN_TREES
    /* Optional debugging check: pass plan output through copyObject() */
    {
        PlannedStmt *new_plan = (PlannedStmt *) copyObject(plan);

        /*
         * equal() currently does not have routines to compare Plan nodes, so
         * don't try to test equality here.  Perhaps fix someday?
         */
#ifdef NOT_USED
        /* This checks both copyObject() and the equal() routines... */
        if (!equal(new_plan, plan))
            elog(WARNING, "copyObject() failed to produce an equal plan tree");
        else
#endif
            plan = new_plan;
    }
#endif

    /*
     * Print plan if debugging.
     */
    if (Debug_print_plan)
        elog_node_display(LOG, "plan", plan, Debug_pretty_print);

    TRACE_POSTGRESQL_QUERY_PLAN_DONE();

    return plan;
}

void PostgresMain ( int  argc,
char *  argv[],
const char *  dbname,
const char *  username 
)

Definition at line 3518 of file postgres.c.

References AbortCurrentTransaction(), ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE, ALLOCSET_DEFAULT_MINSIZE, AllocSetContextCreate(), am_walsender, Assert, BaseInit(), BeginReportingGUCOptions(), BlockSig, buf, ChangeToDataDir(), CreateDataDirLockFile(), DataDir, debug_query_string, DestDebug, DestRemote, die(), disable_all_timeouts(), DisableCatchupInterrupt(), DisableNotifyInterrupt(), doing_extended_query_message, DoingCommandRead, drop_unnamed_stmt(), DropPreparedStatement(), elog, EmitErrorReport(), ereport, errcode(), errmsg(), ERROR, error_context_stack, exec_bind_message(), exec_describe_portal_message(), exec_describe_statement_message(), exec_execute_message(), exec_parse_message(), exec_replication_command(), exec_simple_query(), FATAL, find_my_exec(), finish_xact_command(), FloatExceptionHandler(), FlushErrorState(), forbidden_in_wal_sender(), FrontendProtocol, get_pkglib_path(), GetCurrentTimestamp(), GetPortalByName(), got_SIGHUP, HandleFunctionRequest(), HOLD_INTERRUPTS, i, ignore_till_sync, InitializeGUCOptions(), InitializeMaxBackends(), InitializeTimeouts(), InitPostgres(), InitProcess(), InitProcessing, initStringInfo(), InitWalSender(), InvalidOid, IsAbortedTransactionBlockState(), IsTransactionOrTransactionBlock(), IsUnderPostmaster, log_disconnections(), Log_disconnections, MemoryContextDelete(), MemoryContextInit(), MemoryContextResetAndDeleteChildren(), MemoryContextSwitchTo(), MessageContext, my_exec_path, MyCancelKey, MyProcPid, MyStartTime, NormalProcessing, NULL, on_proc_exit(), palloc(), PG_exception_stack, PG_PROTOCOL_MAJOR, PG_SETMASK, PGC_POSTMASTER, PGC_SIGHUP, PgStartTime, pgstat_report_activity(), pgstat_report_stat(), pkglib_path, PortalDrop(), PortalIsValid, PostmasterContext, pq_beginmessage(), pq_comm_reset(), pq_endmessage(), pq_flush(), pq_getmsgbyte(), pq_getmsgend(), pq_getmsgint(), pq_getmsgstring(), pq_putemptymessage(), pq_sendint(), pqinitmask(), pqsignal(), proc_exit(), process_local_preload_libraries(), process_postgres_switches(), ProcessCompletedNotifies(), ProcessConfigFile(), procsignal_sigusr1_handler(), progname, QueryCancelPending, quickdie(), ReadCommand(), ReadyForQuery(), RESUME_INTERRUPTS, SelectConfigFiles(), set_ps_display(), SetCurrentStatementStartTimestamp(), SetProcessingMode, SIG_DFL, SIG_IGN, SIGCHLD, sigdelset, SIGHUP, SigHupHandler(), sigjmp_buf, SIGPIPE, SIGQUIT, sigsetjmp, SIGUSR1, SIGUSR2, start_xact_command(), STATE_FASTPATH, STATE_IDLE, STATE_IDLEINTRANSACTION, STATE_IDLEINTRANSACTION_ABORTED, StatementCancelHandler(), TopMemoryContext, UnBlockSig, userDoption, ValidatePgVersion(), WalSndErrorCleanup(), WalSndSignals(), whereToSendOutput, and xact_started.

Referenced by BackendRun(), and main().

{
    int         firstchar;
    StringInfoData input_message;
    sigjmp_buf  local_sigjmp_buf;
    volatile bool send_ready_for_query = true;

    /*
     * Initialize globals (already done if under postmaster, but not if
     * standalone).
     */
    if (!IsUnderPostmaster)
    {
        MyProcPid = getpid();

        MyStartTime = time(NULL);
    }

    /*
     * Fire up essential subsystems: error and memory management
     *
     * If we are running under the postmaster, this is done already.
     */
    if (!IsUnderPostmaster)
        MemoryContextInit();

    SetProcessingMode(InitProcessing);

    /* Compute paths, if we didn't inherit them from postmaster */
    if (my_exec_path[0] == '\0')
    {
        if (find_my_exec(argv[0], my_exec_path) < 0)
            elog(FATAL, "%s: could not locate my own executable path",
                 argv[0]);
    }

    if (pkglib_path[0] == '\0')
        get_pkglib_path(my_exec_path, pkglib_path);

    /*
     * Set default values for command-line options.
     */
    if (!IsUnderPostmaster)
        InitializeGUCOptions();

    /*
     * Parse command-line options.
     */
    process_postgres_switches(argc, argv, PGC_POSTMASTER, &dbname);

    /* Must have gotten a database name, or have a default (the username) */
    if (dbname == NULL)
    {
        dbname = username;
        if (dbname == NULL)
            ereport(FATAL,
                    (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                     errmsg("%s: no database nor user name specified",
                            progname)));
    }

    /* Acquire configuration parameters, unless inherited from postmaster */
    if (!IsUnderPostmaster)
    {
        if (!SelectConfigFiles(userDoption, progname))
            proc_exit(1);
    }

    /*
     * You might expect to see a setsid() call here, but it's not needed,
     * because if we are under a postmaster then BackendInitialize() did it.
     */

    /*
     * Set up signal handlers and masks.
     *
     * Note that postmaster blocked all signals before forking child process,
     * so there is no race condition whereby we might receive a signal before
     * we have set up the handler.
     *
     * Also note: it's best not to use any signals that are SIG_IGNored in the
     * postmaster.  If such a signal arrives before we are able to change the
     * handler to non-SIG_IGN, it'll get dropped.  Instead, make a dummy
     * handler in the postmaster to reserve the signal. (Of course, this isn't
     * an issue for signals that are locally generated, such as SIGALRM and
     * SIGPIPE.)
     */
    if (am_walsender)
        WalSndSignals();
    else
    {
        pqsignal(SIGHUP, SigHupHandler);        /* set flag to read config
                                                 * file */
        pqsignal(SIGINT, StatementCancelHandler);       /* cancel current query */
        pqsignal(SIGTERM, die); /* cancel current query and exit */

        /*
         * In a standalone backend, SIGQUIT can be generated from the keyboard
         * easily, while SIGTERM cannot, so we make both signals do die()
         * rather than quickdie().
         */
        if (IsUnderPostmaster)
            pqsignal(SIGQUIT, quickdie);        /* hard crash time */
        else
            pqsignal(SIGQUIT, die);     /* cancel current query and exit */
        InitializeTimeouts();       /* establishes SIGALRM handler */

        /*
         * Ignore failure to write to frontend. Note: if frontend closes
         * connection, we will notice it and exit cleanly when control next
         * returns to outer loop.  This seems safer than forcing exit in the
         * midst of output during who-knows-what operation...
         */
        pqsignal(SIGPIPE, SIG_IGN);
        pqsignal(SIGUSR1, procsignal_sigusr1_handler);
        pqsignal(SIGUSR2, SIG_IGN);
        pqsignal(SIGFPE, FloatExceptionHandler);

        /*
         * Reset some signals that are accepted by postmaster but not by
         * backend
         */
        pqsignal(SIGCHLD, SIG_DFL);     /* system() requires this on some
                                         * platforms */
    }

    pqinitmask();

    if (IsUnderPostmaster)
    {
        /* We allow SIGQUIT (quickdie) at all times */
        sigdelset(&BlockSig, SIGQUIT);
    }

    PG_SETMASK(&BlockSig);      /* block everything except SIGQUIT */

    if (!IsUnderPostmaster)
    {
        /*
         * Validate we have been given a reasonable-looking DataDir (if under
         * postmaster, assume postmaster did this already).
         */
        Assert(DataDir);
        ValidatePgVersion(DataDir);

        /* Change into DataDir (if under postmaster, was done already) */
        ChangeToDataDir();

        /*
         * Create lockfile for data directory.
         */
        CreateDataDirLockFile(false);

        /* Initialize MaxBackends (if under postmaster, was done already) */
        InitializeMaxBackends();
    }

    /* Early initialization */
    BaseInit();

    /*
     * Create a per-backend PGPROC struct in shared memory, except in the
     * EXEC_BACKEND case where this was done in SubPostmasterMain. We must do
     * this before we can use LWLocks (and in the EXEC_BACKEND case we already
     * had to do some stuff with LWLocks).
     */
#ifdef EXEC_BACKEND
    if (!IsUnderPostmaster)
        InitProcess();
#else
    InitProcess();
#endif

    /* We need to allow SIGINT, etc during the initial transaction */
    PG_SETMASK(&UnBlockSig);

    /*
     * General initialization.
     *
     * NOTE: if you are tempted to add code in this vicinity, consider putting
     * it inside InitPostgres() instead.  In particular, anything that
     * involves database access should be there, not here.
     */
    InitPostgres(dbname, InvalidOid, username, NULL);

    /*
     * If the PostmasterContext is still around, recycle the space; we don't
     * need it anymore after InitPostgres completes.  Note this does not trash
     * *MyProcPort, because ConnCreate() allocated that space with malloc()
     * ... else we'd need to copy the Port data first.  Also, subsidiary data
     * such as the username isn't lost either; see ProcessStartupPacket().
     */
    if (PostmasterContext)
    {
        MemoryContextDelete(PostmasterContext);
        PostmasterContext = NULL;
    }

    SetProcessingMode(NormalProcessing);

    /*
     * Now all GUC states are fully set up.  Report them to client if
     * appropriate.
     */
    BeginReportingGUCOptions();

    /*
     * Also set up handler to log session end; we have to wait till now to be
     * sure Log_disconnections has its final value.
     */
    if (IsUnderPostmaster && Log_disconnections)
        on_proc_exit(log_disconnections, 0);

    /* Perform initialization specific to a WAL sender process. */
    if (am_walsender)
        InitWalSender();

    /*
     * process any libraries that should be preloaded at backend start (this
     * likewise can't be done until GUC settings are complete)
     */
    process_local_preload_libraries();

    /*
     * Send this backend's cancellation info to the frontend.
     */
    if (whereToSendOutput == DestRemote &&
        PG_PROTOCOL_MAJOR(FrontendProtocol) >= 2)
    {
        StringInfoData buf;

        pq_beginmessage(&buf, 'K');
        pq_sendint(&buf, (int32) MyProcPid, sizeof(int32));
        pq_sendint(&buf, (int32) MyCancelKey, sizeof(int32));
        pq_endmessage(&buf);
        /* Need not flush since ReadyForQuery will do it. */
    }

    /* Welcome banner for standalone case */
    if (whereToSendOutput == DestDebug)
        printf("\nPostgreSQL stand-alone backend %s\n", PG_VERSION);

    /*
     * Create the memory context we will use in the main loop.
     *
     * MessageContext is reset once per iteration of the main loop, ie, upon
     * completion of processing of each command message from the client.
     */
    MessageContext = AllocSetContextCreate(TopMemoryContext,
                                           "MessageContext",
                                           ALLOCSET_DEFAULT_MINSIZE,
                                           ALLOCSET_DEFAULT_INITSIZE,
                                           ALLOCSET_DEFAULT_MAXSIZE);

    /*
     * Remember stand-alone backend startup time
     */
    if (!IsUnderPostmaster)
        PgStartTime = GetCurrentTimestamp();

    /*
     * POSTGRES main processing loop begins here
     *
     * If an exception is encountered, processing resumes here so we abort the
     * current transaction and start a new one.
     *
     * You might wonder why this isn't coded as an infinite loop around a
     * PG_TRY construct.  The reason is that this is the bottom of the
     * exception stack, and so with PG_TRY there would be no exception handler
     * in force at all during the CATCH part.  By leaving the outermost setjmp
     * always active, we have at least some chance of recovering from an error
     * during error recovery.  (If we get into an infinite loop thereby, it
     * will soon be stopped by overflow of elog.c's internal state stack.)
     */

    if (sigsetjmp(local_sigjmp_buf, 1) != 0)
    {
        /*
         * NOTE: if you are tempted to add more code in this if-block,
         * consider the high probability that it should be in
         * AbortTransaction() instead.  The only stuff done directly here
         * should be stuff that is guaranteed to apply *only* for outer-level
         * error recovery, such as adjusting the FE/BE protocol status.
         */

        /* Since not using PG_TRY, must reset error stack by hand */
        error_context_stack = NULL;

        /* Prevent interrupts while cleaning up */
        HOLD_INTERRUPTS();

        /*
         * Forget any pending QueryCancel request, since we're returning to
         * the idle loop anyway, and cancel any active timeout requests.
         */
        QueryCancelPending = false;
        disable_all_timeouts(false);
        QueryCancelPending = false;     /* again in case timeout occurred */

        /*
         * Turn off these interrupts too.  This is only needed here and not in
         * other exception-catching places since these interrupts are only
         * enabled while we wait for client input.
         */
        DoingCommandRead = false;
        DisableNotifyInterrupt();
        DisableCatchupInterrupt();

        /* Make sure libpq is in a good state */
        pq_comm_reset();

        /* Report the error to the client and/or server log */
        EmitErrorReport();

        /*
         * Make sure debug_query_string gets reset before we possibly clobber
         * the storage it points at.
         */
        debug_query_string = NULL;

        /*
         * Abort the current transaction in order to recover.
         */
        AbortCurrentTransaction();

        if (am_walsender)
            WalSndErrorCleanup();

        /*
         * Now return to normal top-level context and clear ErrorContext for
         * next time.
         */
        MemoryContextSwitchTo(TopMemoryContext);
        FlushErrorState();

        /*
         * If we were handling an extended-query-protocol message, initiate
         * skip till next Sync.  This also causes us not to issue
         * ReadyForQuery (until we get Sync).
         */
        if (doing_extended_query_message)
            ignore_till_sync = true;

        /* We don't have a transaction command open anymore */
        xact_started = false;

        /* Now we can allow interrupts again */
        RESUME_INTERRUPTS();
    }

    /* We can now handle ereport(ERROR) */
    PG_exception_stack = &local_sigjmp_buf;

    if (!ignore_till_sync)
        send_ready_for_query = true;    /* initially, or after error */

    /*
     * Non-error queries loop here.
     */

    for (;;)
    {
        /*
         * At top of loop, reset extended-query-message flag, so that any
         * errors encountered in "idle" state don't provoke skip.
         */
        doing_extended_query_message = false;

        /*
         * Release storage left over from prior query cycle, and create a new
         * query input buffer in the cleared MessageContext.
         */
        MemoryContextSwitchTo(MessageContext);
        MemoryContextResetAndDeleteChildren(MessageContext);

        initStringInfo(&input_message);

        /*
         * (1) If we've reached idle state, tell the frontend we're ready for
         * a new query.
         *
         * Note: this includes fflush()'ing the last of the prior output.
         *
         * This is also a good time to send collected statistics to the
         * collector, and to update the PS stats display.  We avoid doing
         * those every time through the message loop because it'd slow down
         * processing of batched messages, and because we don't want to report
         * uncommitted updates (that confuses autovacuum).  The notification
         * processor wants a call too, if we are not in a transaction block.
         */
        if (send_ready_for_query)
        {
            if (IsAbortedTransactionBlockState())
            {
                set_ps_display("idle in transaction (aborted)", false);
                pgstat_report_activity(STATE_IDLEINTRANSACTION_ABORTED, NULL);
            }
            else if (IsTransactionOrTransactionBlock())
            {
                set_ps_display("idle in transaction", false);
                pgstat_report_activity(STATE_IDLEINTRANSACTION, NULL);
            }
            else
            {
                ProcessCompletedNotifies();
                pgstat_report_stat(false);

                set_ps_display("idle", false);
                pgstat_report_activity(STATE_IDLE, NULL);
            }

            ReadyForQuery(whereToSendOutput);
            send_ready_for_query = false;
        }

        /*
         * (2) Allow asynchronous signals to be executed immediately if they
         * come in while we are waiting for client input. (This must be
         * conditional since we don't want, say, reads on behalf of COPY FROM
         * STDIN doing the same thing.)
         */
        DoingCommandRead = true;

        /*
         * (3) read a command (loop blocks here)
         */
        firstchar = ReadCommand(&input_message);

        /*
         * (4) disable async signal conditions again.
         */
        DoingCommandRead = false;

        /*
         * (5) check for any other interesting events that happened while we
         * slept.
         */
        if (got_SIGHUP)
        {
            got_SIGHUP = false;
            ProcessConfigFile(PGC_SIGHUP);
        }

        /*
         * (6) process the command.  But ignore it if we're skipping till
         * Sync.
         */
        if (ignore_till_sync && firstchar != EOF)
            continue;

        switch (firstchar)
        {
            case 'Q':           /* simple query */
                {
                    const char *query_string;

                    /* Set statement_timestamp() */
                    SetCurrentStatementStartTimestamp();

                    query_string = pq_getmsgstring(&input_message);
                    pq_getmsgend(&input_message);

                    if (am_walsender)
                        exec_replication_command(query_string);
                    else
                        exec_simple_query(query_string);

                    send_ready_for_query = true;
                }
                break;

            case 'P':           /* parse */
                {
                    const char *stmt_name;
                    const char *query_string;
                    int         numParams;
                    Oid        *paramTypes = NULL;

                    forbidden_in_wal_sender(firstchar);

                    /* Set statement_timestamp() */
                    SetCurrentStatementStartTimestamp();

                    stmt_name = pq_getmsgstring(&input_message);
                    query_string = pq_getmsgstring(&input_message);
                    numParams = pq_getmsgint(&input_message, 2);
                    if (numParams > 0)
                    {
                        int         i;

                        paramTypes = (Oid *) palloc(numParams * sizeof(Oid));
                        for (i = 0; i < numParams; i++)
                            paramTypes[i] = pq_getmsgint(&input_message, 4);
                    }
                    pq_getmsgend(&input_message);

                    exec_parse_message(query_string, stmt_name,
                                       paramTypes, numParams);
                }
                break;

            case 'B':           /* bind */
                forbidden_in_wal_sender(firstchar);

                /* Set statement_timestamp() */
                SetCurrentStatementStartTimestamp();

                /*
                 * this message is complex enough that it seems best to put
                 * the field extraction out-of-line
                 */
                exec_bind_message(&input_message);
                break;

            case 'E':           /* execute */
                {
                    const char *portal_name;
                    int         max_rows;

                    forbidden_in_wal_sender(firstchar);

                    /* Set statement_timestamp() */
                    SetCurrentStatementStartTimestamp();

                    portal_name = pq_getmsgstring(&input_message);
                    max_rows = pq_getmsgint(&input_message, 4);
                    pq_getmsgend(&input_message);

                    exec_execute_message(portal_name, max_rows);
                }
                break;

            case 'F':           /* fastpath function call */
                forbidden_in_wal_sender(firstchar);

                /* Set statement_timestamp() */
                SetCurrentStatementStartTimestamp();

                /* Report query to various monitoring facilities. */
                pgstat_report_activity(STATE_FASTPATH, NULL);
                set_ps_display("<FASTPATH>", false);

                /* start an xact for this function invocation */
                start_xact_command();

                /*
                 * Note: we may at this point be inside an aborted
                 * transaction.  We can't throw error for that until we've
                 * finished reading the function-call message, so
                 * HandleFunctionRequest() must check for it after doing so.
                 * Be careful not to do anything that assumes we're inside a
                 * valid transaction here.
                 */

                /* switch back to message context */
                MemoryContextSwitchTo(MessageContext);

                if (HandleFunctionRequest(&input_message) == EOF)
                {
                    /* lost frontend connection during F message input */

                    /*
                     * Reset whereToSendOutput to prevent ereport from
                     * attempting to send any more messages to client.
                     */
                    if (whereToSendOutput == DestRemote)
                        whereToSendOutput = DestNone;

                    proc_exit(0);
                }

                /* commit the function-invocation transaction */
                finish_xact_command();

                send_ready_for_query = true;
                break;

            case 'C':           /* close */
                {
                    int         close_type;
                    const char *close_target;

                    forbidden_in_wal_sender(firstchar);

                    close_type = pq_getmsgbyte(&input_message);
                    close_target = pq_getmsgstring(&input_message);
                    pq_getmsgend(&input_message);

                    switch (close_type)
                    {
                        case 'S':
                            if (close_target[0] != '\0')
                                DropPreparedStatement(close_target, false);
                            else
                            {
                                /* special-case the unnamed statement */
                                drop_unnamed_stmt();
                            }
                            break;
                        case 'P':
                            {
                                Portal      portal;

                                portal = GetPortalByName(close_target);
                                if (PortalIsValid(portal))
                                    PortalDrop(portal, false);
                            }
                            break;
                        default:
                            ereport(ERROR,
                                    (errcode(ERRCODE_PROTOCOL_VIOLATION),
                                   errmsg("invalid CLOSE message subtype %d",
                                          close_type)));
                            break;
                    }

                    if (whereToSendOutput == DestRemote)
                        pq_putemptymessage('3');        /* CloseComplete */
                }
                break;

            case 'D':           /* describe */
                {
                    int         describe_type;
                    const char *describe_target;

                    forbidden_in_wal_sender(firstchar);

                    /* Set statement_timestamp() (needed for xact) */
                    SetCurrentStatementStartTimestamp();

                    describe_type = pq_getmsgbyte(&input_message);
                    describe_target = pq_getmsgstring(&input_message);
                    pq_getmsgend(&input_message);

                    switch (describe_type)
                    {
                        case 'S':
                            exec_describe_statement_message(describe_target);
                            break;
                        case 'P':
                            exec_describe_portal_message(describe_target);
                            break;
                        default:
                            ereport(ERROR,
                                    (errcode(ERRCODE_PROTOCOL_VIOLATION),
                                errmsg("invalid DESCRIBE message subtype %d",
                                       describe_type)));
                            break;
                    }
                }
                break;

            case 'H':           /* flush */
                pq_getmsgend(&input_message);
                if (whereToSendOutput == DestRemote)
                    pq_flush();
                break;

            case 'S':           /* sync */
                pq_getmsgend(&input_message);
                finish_xact_command();
                send_ready_for_query = true;
                break;

                /*
                 * 'X' means that the frontend is closing down the socket. EOF
                 * means unexpected loss of frontend connection. Either way,
                 * perform normal shutdown.
                 */
            case 'X':
            case EOF:

                /*
                 * Reset whereToSendOutput to prevent ereport from attempting
                 * to send any more messages to client.
                 */
                if (whereToSendOutput == DestRemote)
                    whereToSendOutput = DestNone;

                /*
                 * NOTE: if you are tempted to add more code here, DON'T!
                 * Whatever you had in mind to do should be set up as an
                 * on_proc_exit or on_shmem_exit callback, instead. Otherwise
                 * it will fail to be called during other backend-shutdown
                 * scenarios.
                 */
                proc_exit(0);

            case 'd':           /* copy data */
            case 'c':           /* copy done */
            case 'f':           /* copy fail */

                /*
                 * Accept but ignore these messages, per protocol spec; we
                 * probably got here because a COPY failed, and the frontend
                 * is still sending data.
                 */
                break;

            default:
                ereport(FATAL,
                        (errcode(ERRCODE_PROTOCOL_VIOLATION),
                         errmsg("invalid frontend message type %d",
                                firstchar)));
        }
    }                           /* end of input-reading loop */
}

void prepare_for_client_read ( void   ) 

Definition at line 511 of file postgres.c.

References CHECK_FOR_INTERRUPTS, DoingCommandRead, EnableCatchupInterrupt(), EnableNotifyInterrupt(), and ImmediateInterruptOK.

Referenced by interactive_getc(), and secure_read().

{
    if (DoingCommandRead)
    {
        /* Enable immediate processing of asynchronous signals */
        EnableNotifyInterrupt();
        EnableCatchupInterrupt();

        /* Allow cancel/die interrupts to be processed while waiting */
        ImmediateInterruptOK = true;

        /* And don't forget to detect one that already arrived */
        CHECK_FOR_INTERRUPTS();
    }
}

void process_postgres_switches ( int  argc,
char *  argv[],
GucContext  ctx,
const char **  dbname 
)

Definition at line 3255 of file postgres.c.

References EchoQuery, ereport, errcode(), errhint(), errmsg(), ERROR, FATAL, free, FrontendProtocol, get_stats_option_name(), getopt(), IsBinaryUpgrade, IsUnderPostmaster, MAXPGPATH, name, NULL, optarg, opterr, optind, OutputFileName, ParseLongOption(), progname, set_debug_options(), set_plan_disabling_options(), SetConfigOption(), strlcpy(), UseNewLine, userDoption, and value.

Referenced by PostgresMain(), and process_startup_options().

{
    bool        secure = (ctx == PGC_POSTMASTER);
    int         errs = 0;
    GucSource   gucsource;
    int         flag;

    if (secure)
    {
        gucsource = PGC_S_ARGV; /* switches came from command line */

        /* Ignore the initial --single argument, if present */
        if (argc > 1 && strcmp(argv[1], "--single") == 0)
        {
            argv++;
            argc--;
        }
    }
    else
    {
        gucsource = PGC_S_CLIENT;       /* switches came from client */
    }

#ifdef HAVE_INT_OPTERR

    /*
     * Turn this off because it's either printed to stderr and not the log
     * where we'd want it, or argv[0] is now "--single", which would make for
     * a weird error message.  We print our own error message below.
     */
    opterr = 0;
#endif

    /*
     * Parse command-line options.  CAUTION: keep this in sync with
     * postmaster/postmaster.c (the option sets should not conflict) and with
     * the common help() function in main/main.c.
     */
    while ((flag = getopt(argc, argv, "A:B:bc:C:D:d:EeFf:h:ijk:lN:nOo:Pp:r:S:sTt:v:W:-:")) != -1)
    {
        switch (flag)
        {
            case 'A':
                SetConfigOption("debug_assertions", optarg, ctx, gucsource);
                break;

            case 'B':
                SetConfigOption("shared_buffers", optarg, ctx, gucsource);
                break;

            case 'b':
                /* Undocumented flag used for binary upgrades */
                if (secure)
                    IsBinaryUpgrade = true;
                break;

            case 'C':
                /* ignored for consistency with the postmaster */
                break;

            case 'D':
                if (secure)
                    userDoption = strdup(optarg);
                break;

            case 'd':
                set_debug_options(atoi(optarg), ctx, gucsource);
                break;

            case 'E':
                if (secure)
                    EchoQuery = true;
                break;

            case 'e':
                SetConfigOption("datestyle", "euro", ctx, gucsource);
                break;

            case 'F':
                SetConfigOption("fsync", "false", ctx, gucsource);
                break;

            case 'f':
                if (!set_plan_disabling_options(optarg, ctx, gucsource))
                    errs++;
                break;

            case 'h':
                SetConfigOption("listen_addresses", optarg, ctx, gucsource);
                break;

            case 'i':
                SetConfigOption("listen_addresses", "*", ctx, gucsource);
                break;

            case 'j':
                if (secure)
                    UseNewLine = 0;
                break;

            case 'k':
                SetConfigOption("unix_socket_directories", optarg, ctx, gucsource);
                break;

            case 'l':
                SetConfigOption("ssl", "true", ctx, gucsource);
                break;

            case 'N':
                SetConfigOption("max_connections", optarg, ctx, gucsource);
                break;

            case 'n':
                /* ignored for consistency with postmaster */
                break;

            case 'O':
                SetConfigOption("allow_system_table_mods", "true", ctx, gucsource);
                break;

            case 'o':
                errs++;
                break;

            case 'P':
                SetConfigOption("ignore_system_indexes", "true", ctx, gucsource);
                break;

            case 'p':
                SetConfigOption("port", optarg, ctx, gucsource);
                break;

            case 'r':
                /* send output (stdout and stderr) to the given file */
                if (secure)
                    strlcpy(OutputFileName, optarg, MAXPGPATH);
                break;

            case 'S':
                SetConfigOption("work_mem", optarg, ctx, gucsource);
                break;

            case 's':
                SetConfigOption("log_statement_stats", "true", ctx, gucsource);
                break;

            case 'T':
                /* ignored for consistency with the postmaster */
                break;

            case 't':
                {
                    const char *tmp = get_stats_option_name(optarg);

                    if (tmp)
                        SetConfigOption(tmp, "true", ctx, gucsource);
                    else
                        errs++;
                    break;
                }

            case 'v':

                /*
                 * -v is no longer used in normal operation, since
                 * FrontendProtocol is already set before we get here. We keep
                 * the switch only for possible use in standalone operation,
                 * in case we ever support using normal FE/BE protocol with a
                 * standalone backend.
                 */
                if (secure)
                    FrontendProtocol = (ProtocolVersion) atoi(optarg);
                break;

            case 'W':
                SetConfigOption("post_auth_delay", optarg, ctx, gucsource);
                break;

            case 'c':
            case '-':
                {
                    char       *name,
                               *value;

                    ParseLongOption(optarg, &name, &value);
                    if (!value)
                    {
                        if (flag == '-')
                            ereport(ERROR,
                                    (errcode(ERRCODE_SYNTAX_ERROR),
                                     errmsg("--%s requires a value",
                                            optarg)));
                        else
                            ereport(ERROR,
                                    (errcode(ERRCODE_SYNTAX_ERROR),
                                     errmsg("-c %s requires a value",
                                            optarg)));
                    }
                    SetConfigOption(name, value, ctx, gucsource);
                    free(name);
                    if (value)
                        free(value);
                    break;
                }

            default:
                errs++;
                break;
        }

        if (errs)
            break;
    }

    /*
     * Optional database name should be there only if *dbname is NULL.
     */
    if (!errs && dbname && *dbname == NULL && argc - optind >= 1)
        *dbname = strdup(argv[optind++]);

    if (errs || argc != optind)
    {
        if (errs)
            optind--;           /* complain about the previous argument */

        /* spell the error message a bit differently depending on context */
        if (IsUnderPostmaster)
            ereport(FATAL,
                    (errcode(ERRCODE_SYNTAX_ERROR),
                     errmsg("invalid command-line argument for server process: %s", argv[optind]),
              errhint("Try \"%s --help\" for more information.", progname)));
        else
            ereport(FATAL,
                    (errcode(ERRCODE_SYNTAX_ERROR),
                     errmsg("%s: invalid command-line argument: %s",
                            progname, argv[optind]),
              errhint("Try \"%s --help\" for more information.", progname)));
    }

    /*
     * Reset getopt(3) library so that it will work correctly in subprocesses
     * or when this function is called a second time with another array.
     */
    optind = 1;
#ifdef HAVE_INT_OPTRESET
    optreset = 1;               /* some systems need this too */
#endif
}

void quickdie ( SIGNAL_ARGS   ) 

Definition at line 2522 of file postgres.c.

References BlockSig, ClientAuthInProgress, DestRemote, ereport, errcode(), errdetail(), errhint(), errmsg(), on_exit_reset(), PG_SETMASK, sigaddset, SIGQUIT, WARNING, and whereToSendOutput.

Referenced by AutoVacLauncherMain(), AutoVacWorkerMain(), bootstrap_signals(), PostgresMain(), and WalSndSignals().

{
    sigaddset(&BlockSig, SIGQUIT);      /* prevent nested calls */
    PG_SETMASK(&BlockSig);

    /*
     * If we're aborting out of client auth, don't risk trying to send
     * anything to the client; we will likely violate the protocol, not to
     * mention that we may have interrupted the guts of OpenSSL or some
     * authentication library.
     */
    if (ClientAuthInProgress && whereToSendOutput == DestRemote)
        whereToSendOutput = DestNone;

    /*
     * Ideally this should be ereport(FATAL), but then we'd not get control
     * back...
     */
    ereport(WARNING,
            (errcode(ERRCODE_CRASH_SHUTDOWN),
             errmsg("terminating connection because of crash of another server process"),
    errdetail("The postmaster has commanded this server process to roll back"
              " the current transaction and exit, because another"
              " server process exited abnormally and possibly corrupted"
              " shared memory."),
             errhint("In a moment you should be able to reconnect to the"
                     " database and repeat your command.")));

    /*
     * We DO NOT want to run proc_exit() callbacks -- we're here because
     * shared memory may be corrupted, so we don't want to try to clean up our
     * transaction.  Just nail the windows shut and get out of town.  Now that
     * there's an atexit callback to prevent third-party code from breaking
     * things by calling exit() directly, we have to reset the callbacks
     * explicitly to make this work as intended.
     */
    on_exit_reset();

    /*
     * Note we do exit(2) not exit(0).  This is to force the postmaster into a
     * system reset cycle if some idiot DBA sends a manual SIGQUIT to a random
     * backend.  This is necessary precisely because we don't clean up our
     * shared memory state.  (The "dead man switch" mechanism in pmsignal.c
     * should ensure the postmaster sees this as a crash, too, but no harm in
     * being doubly sure.)
     */
    exit(2);
}

void RecoveryConflictInterrupt ( ProcSignalReason  reason  ) 

Definition at line 2686 of file postgres.c.

References Assert, CritSectionCount, DisableCatchupInterrupt(), DisableNotifyInterrupt(), elog, FATAL, HoldingBufferPinThatDelaysRecovery(), ImmediateInterruptOK, InterruptHoldoffCount, InterruptPending, IsAbortedTransactionBlockState(), IsSubTransaction(), IsTransactionOrTransactionBlock(), IsWaitingForLock(), LockErrorCleanup(), MyProc, proc_exit_inprogress, ProcDiePending, ProcessInterrupts(), PROCSIG_RECOVERY_CONFLICT_BUFFERPIN, PROCSIG_RECOVERY_CONFLICT_DATABASE, PROCSIG_RECOVERY_CONFLICT_LOCK, PROCSIG_RECOVERY_CONFLICT_SNAPSHOT, PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK, PROCSIG_RECOVERY_CONFLICT_TABLESPACE, QueryCancelPending, RecoveryConflictPending, PGPROC::recoveryConflictPending, RecoveryConflictReason, and RecoveryConflictRetryable.

Referenced by procsignal_sigusr1_handler().

{
    int         save_errno = errno;

    /*
     * Don't joggle the elbow of proc_exit
     */
    if (!proc_exit_inprogress)
    {
        RecoveryConflictReason = reason;
        switch (reason)
        {
            case PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK:

                /*
                 * If we aren't waiting for a lock we can never deadlock.
                 */
                if (!IsWaitingForLock())
                    return;

                /* Intentional drop through to check wait for pin */

            case PROCSIG_RECOVERY_CONFLICT_BUFFERPIN:

                /*
                 * If we aren't blocking the Startup process there is nothing
                 * more to do.
                 */
                if (!HoldingBufferPinThatDelaysRecovery())
                    return;

                MyProc->recoveryConflictPending = true;

                /* Intentional drop through to error handling */

            case PROCSIG_RECOVERY_CONFLICT_LOCK:
            case PROCSIG_RECOVERY_CONFLICT_TABLESPACE:
            case PROCSIG_RECOVERY_CONFLICT_SNAPSHOT:

                /*
                 * If we aren't in a transaction any longer then ignore.
                 */
                if (!IsTransactionOrTransactionBlock())
                    return;

                /*
                 * If we can abort just the current subtransaction then we are
                 * OK to throw an ERROR to resolve the conflict. Otherwise
                 * drop through to the FATAL case.
                 *
                 * XXX other times that we can throw just an ERROR *may* be
                 * PROCSIG_RECOVERY_CONFLICT_LOCK if no locks are held in
                 * parent transactions
                 *
                 * PROCSIG_RECOVERY_CONFLICT_SNAPSHOT if no snapshots are held
                 * by parent transactions and the transaction is not
                 * transaction-snapshot mode
                 *
                 * PROCSIG_RECOVERY_CONFLICT_TABLESPACE if no temp files or
                 * cursors open in parent transactions
                 */
                if (!IsSubTransaction())
                {
                    /*
                     * If we already aborted then we no longer need to cancel.
                     * We do this here since we do not wish to ignore aborted
                     * subtransactions, which must cause FATAL, currently.
                     */
                    if (IsAbortedTransactionBlockState())
                        return;

                    RecoveryConflictPending = true;
                    QueryCancelPending = true;
                    InterruptPending = true;
                    break;
                }

                /* Intentional drop through to session cancel */

            case PROCSIG_RECOVERY_CONFLICT_DATABASE:
                RecoveryConflictPending = true;
                ProcDiePending = true;
                InterruptPending = true;
                break;

            default:
                elog(FATAL, "unrecognized conflict mode: %d",
                     (int) reason);
        }

        Assert(RecoveryConflictPending && (QueryCancelPending || ProcDiePending));

        /*
         * All conflicts apart from database cause dynamic errors where the
         * command or transaction can be retried at a later point with some
         * potential for success. No need to reset this, since non-retryable
         * conflict errors are currently FATAL.
         */
        if (reason == PROCSIG_RECOVERY_CONFLICT_DATABASE)
            RecoveryConflictRetryable = false;

        /*
         * If it's safe to interrupt, and we're waiting for input or a lock,
         * service the interrupt immediately
         */
        if (ImmediateInterruptOK && InterruptHoldoffCount == 0 &&
            CritSectionCount == 0)
        {
            /* bump holdoff count to make ProcessInterrupts() a no-op */
            /* until we are done getting ready for it */
            InterruptHoldoffCount++;
            LockErrorCleanup(); /* prevent CheckDeadLock from running */
            DisableNotifyInterrupt();
            DisableCatchupInterrupt();
            InterruptHoldoffCount--;
            ProcessInterrupts();
        }
    }

    errno = save_errno;
}

void ResetUsage ( void   ) 
void set_debug_options ( int  debug_flag,
GucContext  context,
GucSource  source 
)

Definition at line 3144 of file postgres.c.

References PGC_POSTMASTER, and SetConfigOption().

Referenced by PostmasterMain(), and process_postgres_switches().

{
    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);
}

bool set_plan_disabling_options ( const char *  arg,
GucContext  context,
GucSource  source 
)

Definition at line 3173 of file postgres.c.

References SetConfigOption().

Referenced by PostmasterMain(), and process_postgres_switches().

{
    const char *tmp = NULL;

    switch (arg[0])
    {
        case 's':               /* seqscan */
            tmp = "enable_seqscan";
            break;
        case 'i':               /* indexscan */
            tmp = "enable_indexscan";
            break;
        case 'o':               /* indexonlyscan */
            tmp = "enable_indexonlyscan";
            break;
        case 'b':               /* bitmapscan */
            tmp = "enable_bitmapscan";
            break;
        case 't':               /* tidscan */
            tmp = "enable_tidscan";
            break;
        case 'n':               /* nestloop */
            tmp = "enable_nestloop";
            break;
        case 'm':               /* mergejoin */
            tmp = "enable_mergejoin";
            break;
        case 'h':               /* hashjoin */
            tmp = "enable_hashjoin";
            break;
    }
    if (tmp)
    {
        SetConfigOption(tmp, "false", context, source);
        return true;
    }
    else
        return false;
}

void ShowUsage ( const char *  title  ) 

Definition at line 4302 of file postgres.c.

References appendStringInfo(), StringInfoData::data, ereport, errdetail_internal(), errmsg_internal(), getrusage(), gettimeofday(), initStringInfo(), StringInfoData::len, LOG, NULL, pfree(), rusage::ru_stime, rusage::ru_utime, RUSAGE_SELF, Save_r, and Save_t.

Referenced by _bt_leafbuild(), _SPI_pquery(), btbuild(), exec_bind_message(), exec_execute_message(), exec_parse_message(), exec_simple_query(), pg_analyze_and_rewrite(), pg_analyze_and_rewrite_params(), pg_parse_query(), pg_plan_query(), pg_rewrite_query(), PortalRun(), and PortalRunMulti().

{
    StringInfoData str;
    struct timeval user,
                sys;
    struct timeval elapse_t;
    struct rusage r;

    getrusage(RUSAGE_SELF, &r);
    gettimeofday(&elapse_t, NULL);
    memcpy((char *) &user, (char *) &r.ru_utime, sizeof(user));
    memcpy((char *) &sys, (char *) &r.ru_stime, sizeof(sys));
    if (elapse_t.tv_usec < Save_t.tv_usec)
    {
        elapse_t.tv_sec--;
        elapse_t.tv_usec += 1000000;
    }
    if (r.ru_utime.tv_usec < Save_r.ru_utime.tv_usec)
    {
        r.ru_utime.tv_sec--;
        r.ru_utime.tv_usec += 1000000;
    }
    if (r.ru_stime.tv_usec < Save_r.ru_stime.tv_usec)
    {
        r.ru_stime.tv_sec--;
        r.ru_stime.tv_usec += 1000000;
    }

    /*
     * the only stats we don't show here are for memory usage -- i can't
     * figure out how to interpret the relevant fields in the rusage struct,
     * and they change names across o/s platforms, anyway. if you can figure
     * out what the entries mean, you can somehow extract resident set size,
     * shared text size, and unshared data and stack sizes.
     */
    initStringInfo(&str);

    appendStringInfo(&str, "! system usage stats:\n");
    appendStringInfo(&str,
                "!\t%ld.%06ld elapsed %ld.%06ld user %ld.%06ld system sec\n",
                     (long) (elapse_t.tv_sec - Save_t.tv_sec),
                     (long) (elapse_t.tv_usec - Save_t.tv_usec),
                     (long) (r.ru_utime.tv_sec - Save_r.ru_utime.tv_sec),
                     (long) (r.ru_utime.tv_usec - Save_r.ru_utime.tv_usec),
                     (long) (r.ru_stime.tv_sec - Save_r.ru_stime.tv_sec),
                     (long) (r.ru_stime.tv_usec - Save_r.ru_stime.tv_usec));
    appendStringInfo(&str,
                     "!\t[%ld.%06ld user %ld.%06ld sys total]\n",
                     (long) user.tv_sec,
                     (long) user.tv_usec,
                     (long) sys.tv_sec,
                     (long) sys.tv_usec);
#if defined(HAVE_GETRUSAGE)
    appendStringInfo(&str,
                     "!\t%ld/%ld [%ld/%ld] filesystem blocks in/out\n",
                     r.ru_inblock - Save_r.ru_inblock,
    /* they only drink coffee at dec */
                     r.ru_oublock - Save_r.ru_oublock,
                     r.ru_inblock, r.ru_oublock);
    appendStringInfo(&str,
              "!\t%ld/%ld [%ld/%ld] page faults/reclaims, %ld [%ld] swaps\n",
                     r.ru_majflt - Save_r.ru_majflt,
                     r.ru_minflt - Save_r.ru_minflt,
                     r.ru_majflt, r.ru_minflt,
                     r.ru_nswap - Save_r.ru_nswap,
                     r.ru_nswap);
    appendStringInfo(&str,
         "!\t%ld [%ld] signals rcvd, %ld/%ld [%ld/%ld] messages rcvd/sent\n",
                     r.ru_nsignals - Save_r.ru_nsignals,
                     r.ru_nsignals,
                     r.ru_msgrcv - Save_r.ru_msgrcv,
                     r.ru_msgsnd - Save_r.ru_msgsnd,
                     r.ru_msgrcv, r.ru_msgsnd);
    appendStringInfo(&str,
             "!\t%ld/%ld [%ld/%ld] voluntary/involuntary context switches\n",
                     r.ru_nvcsw - Save_r.ru_nvcsw,
                     r.ru_nivcsw - Save_r.ru_nivcsw,
                     r.ru_nvcsw, r.ru_nivcsw);
#endif   /* HAVE_GETRUSAGE */

    /* remove trailing newline */
    if (str.data[str.len - 1] == '\n')
        str.data[--str.len] = '\0';

    ereport(LOG,
            (errmsg_internal("%s", title),
             errdetail_internal("%s", str.data)));

    pfree(str.data);
}

void StatementCancelHandler ( SIGNAL_ARGS   ) 

Definition at line 2616 of file postgres.c.

References CritSectionCount, DisableCatchupInterrupt(), DisableNotifyInterrupt(), ImmediateInterruptOK, InterruptHoldoffCount, InterruptPending, LockErrorCleanup(), MyProc, proc_exit_inprogress, ProcessInterrupts(), PGPROC::procLatch, QueryCancelPending, and SetLatch().

Referenced by AutoVacLauncherMain(), AutoVacWorkerMain(), do_start_bgworker(), and PostgresMain().

{
    int         save_errno = errno;

    /*
     * Don't joggle the elbow of proc_exit
     */
    if (!proc_exit_inprogress)
    {
        InterruptPending = true;
        QueryCancelPending = true;

        /*
         * If it's safe to interrupt, and we're waiting for input or a lock,
         * service the interrupt immediately
         */
        if (ImmediateInterruptOK && InterruptHoldoffCount == 0 &&
            CritSectionCount == 0)
        {
            /* bump holdoff count to make ProcessInterrupts() a no-op */
            /* until we are done getting ready for it */
            InterruptHoldoffCount++;
            LockErrorCleanup(); /* prevent CheckDeadLock from running */
            DisableNotifyInterrupt();
            DisableCatchupInterrupt();
            InterruptHoldoffCount--;
            ProcessInterrupts();
        }
    }

    /* If we're still here, waken anything waiting on the process latch */
    if (MyProc)
        SetLatch(&MyProc->procLatch);

    errno = save_errno;
}


Variable Documentation

PGDLLIMPORT const char* debug_query_string

Definition at line 100 of file postgres.c.

Referenced by check_log_statement(), and HandleFunctionRequest().

Definition at line 103 of file postgres.c.

Referenced by check_stack_depth().