Header And Logo

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

Functions | Variables

postgres.c File Reference

#include "postgres.h"
#include <fcntl.h>
#include <limits.h>
#include <signal.h>
#include <time.h>
#include <unistd.h>
#include <sys/socket.h>
#include "rusagestub.h"
#include "access/printtup.h"
#include "access/xact.h"
#include "catalog/pg_type.h"
#include "commands/async.h"
#include "commands/prepare.h"
#include "libpq/libpq.h"
#include "libpq/pqformat.h"
#include "libpq/pqsignal.h"
#include "miscadmin.h"
#include "nodes/print.h"
#include "optimizer/planner.h"
#include "pgstat.h"
#include "pg_trace.h"
#include "parser/analyze.h"
#include "parser/parser.h"
#include "postmaster/autovacuum.h"
#include "postmaster/postmaster.h"
#include "replication/walsender.h"
#include "rewrite/rewriteHandler.h"
#include "storage/bufmgr.h"
#include "storage/ipc.h"
#include "storage/proc.h"
#include "storage/procsignal.h"
#include "storage/sinval.h"
#include "tcop/fastpath.h"
#include "tcop/pquery.h"
#include "tcop/tcopprot.h"
#include "tcop/utility.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/ps_status.h"
#include "utils/snapmgr.h"
#include "utils/timeout.h"
#include "utils/timestamp.h"
#include "mb/pg_wchar.h"
Include dependency graph for postgres.c:

Go to the source code of this file.

Functions

static int InteractiveBackend (StringInfo inBuf)
static int interactive_getc (void)
static int SocketBackend (StringInfo inBuf)
static int ReadCommand (StringInfo inBuf)
static void forbidden_in_wal_sender (char firstchar)
static Listpg_rewrite_query (Query *query)
static bool check_log_statement (List *stmt_list)
static int errdetail_execute (List *raw_parsetree_list)
static int errdetail_params (ParamListInfo params)
static int errdetail_abort (void)
static int errdetail_recovery_conflict (void)
static void start_xact_command (void)
static void finish_xact_command (void)
static bool IsTransactionExitStmt (Node *parsetree)
static bool IsTransactionExitStmtList (List *parseTrees)
static bool IsTransactionStmtList (List *parseTrees)
static void drop_unnamed_stmt (void)
static void SigHupHandler (SIGNAL_ARGS)
static void log_disconnections (int code, Datum arg)
void prepare_for_client_read (void)
void client_read_ended (void)
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)
static void exec_simple_query (const char *query_string)
static void exec_parse_message (const char *query_string, const char *stmt_name, Oid *paramTypes, int numParams)
static void exec_bind_message (StringInfo input_message)
static void exec_execute_message (const char *portal_name, long max_rows)
int check_log_duration (char *msec_str, bool was_logged)
static void exec_describe_statement_message (const char *stmt_name)
static void exec_describe_portal_message (const char *portal_name)
void quickdie (SIGNAL_ARGS)
void die (SIGNAL_ARGS)
void StatementCancelHandler (SIGNAL_ARGS)
void FloatExceptionHandler (SIGNAL_ARGS)
void RecoveryConflictInterrupt (ProcSignalReason reason)
void ProcessInterrupts (void)
pg_stack_base_t set_stack_base (void)
void restore_stack_base (pg_stack_base_t base)
void check_stack_depth (void)
bool check_max_stack_depth (int *newval, void **extra, GucSource source)
void assign_max_stack_depth (int newval, void *extra)
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)
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)
long get_stack_depth_rlimit (void)
void ResetUsage (void)
void ShowUsage (const char *title)

Variables

char * optarg
int optind
const char * debug_query_string
CommandDest whereToSendOutput = DestDebug
bool Log_disconnections = false
int log_statement = LOGSTMT_NONE
int max_stack_depth = 100
int PostAuthDelay = 0
static long max_stack_depth_bytes = 100 * 1024L
char * stack_base_ptr = NULL
static volatile sig_atomic_t got_SIGHUP = false
static bool xact_started = false
static bool DoingCommandRead = false
static bool doing_extended_query_message = false
static bool ignore_till_sync = false
static CachedPlanSourceunnamed_stmt_psrc = NULL
static const char * userDoption = NULL
static bool EchoQuery = false
static int UseNewLine = 1
static bool RecoveryConflictPending = false
static bool RecoveryConflictRetryable = true
static ProcSignalReason RecoveryConflictReason
static struct rusage Save_r
static struct timeval Save_t

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

static bool check_log_statement ( List stmt_list  )  [static]

Definition at line 2009 of file postgres.c.

References GetCommandLogLevel(), lfirst, log_statement, LOGSTMT_ALL, and LOGSTMT_NONE.

Referenced by exec_execute_message(), and exec_simple_query().

{
    ListCell   *stmt_item;

    if (log_statement == LOGSTMT_NONE)
        return false;
    if (log_statement == LOGSTMT_ALL)
        return true;

    /* Else we have to inspect the statement(s) to see whether to log */
    foreach(stmt_item, stmt_list)
    {
        Node       *stmt = (Node *) lfirst(stmt_item);

        if (GetCommandLogLevel(stmt) <= log_statement)
            return true;
    }

    return false;
}

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 check_stack_depth ( void   ) 

Definition at line 3051 of file postgres.c.

References ereport, errcode(), errhint(), errmsg(), ERROR, max_stack_depth, max_stack_depth_bytes, NULL, and stack_base_ptr.

Referenced by addone(), clean_fakeval_intree(), clean_NOT_intree(), cntsize(), contains_required_value(), copyObject(), Cover(), dofindsubquery(), EventTriggerInvoke(), ExecInitExpr(), ExecMakeFunctionResult(), ExecMakeFunctionResultNoSets(), execute(), expression_tree_mutator(), expression_tree_walker(), fillQT(), findoprnd_recurse(), freetree(), infix(), inline_set_returning_function(), JumbleExpr(), makepol(), plainnode(), plperl_hash_from_tuple(), plperl_sv_to_datum(), QT2QTN(), QTNBinary(), QTNClearFlags(), QTNCopy(), QTNFree(), QTNodeCompare(), QTNSort(), QTNTernary(), raw_expression_tree_walker(), split_array(), transformExprRecurse(), transformSetOperationTree(), TS_execute(), tsquery_opr_selec(), and tsquery_requires_match().

{
    char        stack_top_loc;
    long        stack_depth;

    /*
     * Compute distance from reference point to my local variables
     */
    stack_depth = (long) (stack_base_ptr - &stack_top_loc);

    /*
     * Take abs value, since stacks grow up on some machines, down on others
     */
    if (stack_depth < 0)
        stack_depth = -stack_depth;

    /*
     * Trouble?
     *
     * The test on stack_base_ptr prevents us from erroring out if called
     * during process setup or in a non-backend process.  Logically it should
     * be done first, but putting it here avoids wasting cycles during normal
     * cases.
     */
    if (stack_depth > max_stack_depth_bytes &&
        stack_base_ptr != NULL)
    {
        ereport(ERROR,
                (errcode(ERRCODE_STATEMENT_TOO_COMPLEX),
                 errmsg("stack depth limit exceeded"),
                 errhint("Increase the configuration parameter \"max_stack_depth\" (currently %dkB), "
              "after ensuring the platform's stack depth limit is adequate.",
                         max_stack_depth)));
    }

    /*
     * On IA64 there is a separate "register" stack that requires its own
     * independent check.  For this, we have to measure the change in the
     * "BSP" pointer from PostgresMain to here.  Logic is just as above,
     * except that we know IA64's register stack grows up.
     *
     * Note we assume that the same max_stack_depth applies to both stacks.
     */
#if defined(__ia64__) || defined(__ia64)
    stack_depth = (long) (ia64_get_bsp() - register_stack_base_ptr);

    if (stack_depth > max_stack_depth_bytes &&
        register_stack_base_ptr != NULL)
    {
        ereport(ERROR,
                (errcode(ERRCODE_STATEMENT_TOO_COMPLEX),
                 errmsg("stack depth limit exceeded"),
                 errhint("Increase the configuration parameter \"max_stack_depth\" (currently %dkB), "
              "after ensuring the platform's stack depth limit is adequate.",
                         max_stack_depth)));
    }
#endif   /* IA64 */
}

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

static void drop_unnamed_stmt ( void   )  [static]

Definition at line 2497 of file postgres.c.

References DropCachedPlan().

Referenced by exec_parse_message(), exec_simple_query(), and PostgresMain().

{
    /* paranoia to avoid a dangling pointer in case of error */
    if (unnamed_stmt_psrc)
    {
        CachedPlanSource *psrc = unnamed_stmt_psrc;

        unnamed_stmt_psrc = NULL;
        DropCachedPlan(psrc);
    }
}

static int errdetail_abort ( void   )  [static]
static int errdetail_execute ( List raw_parsetree_list  )  [static]

Definition at line 2091 of file postgres.c.

References errdetail(), FetchPreparedStatement(), IsA, lfirst, ExecuteStmt::name, PreparedStatement::plansource, and CachedPlanSource::query_string.

Referenced by exec_simple_query().

{
    ListCell   *parsetree_item;

    foreach(parsetree_item, raw_parsetree_list)
    {
        Node       *parsetree = (Node *) lfirst(parsetree_item);

        if (IsA(parsetree, ExecuteStmt))
        {
            ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
            PreparedStatement *pstmt;

            pstmt = FetchPreparedStatement(stmt->name, false);
            if (pstmt)
            {
                errdetail("prepare: %s", pstmt->plansource->query_string);
                return 0;
            }
        }
    }

    return 0;
}

static int errdetail_params ( ParamListInfo  params  )  [static]

Definition at line 2122 of file postgres.c.

References appendStringInfo(), appendStringInfoCharMacro, appendStringInfoString(), StringInfoData::data, errdetail(), getTypeOutputInfo(), initStringInfo(), IsAbortedTransactionBlockState(), ParamExternData::isnull, MemoryContextSwitchTo(), MessageContext, ParamListInfoData::numParams, OidIsValid, OidOutputFunctionCall(), ParamListInfoData::params, pfree(), ParamExternData::ptype, and ParamExternData::value.

Referenced by exec_bind_message(), and exec_execute_message().

{
    /* We mustn't call user-defined I/O functions when in an aborted xact */
    if (params && params->numParams > 0 && !IsAbortedTransactionBlockState())
    {
        StringInfoData param_str;
        MemoryContext oldcontext;
        int         paramno;

        /* Make sure any trash is generated in MessageContext */
        oldcontext = MemoryContextSwitchTo(MessageContext);

        initStringInfo(&param_str);

        for (paramno = 0; paramno < params->numParams; paramno++)
        {
            ParamExternData *prm = &params->params[paramno];
            Oid         typoutput;
            bool        typisvarlena;
            char       *pstring;
            char       *p;

            appendStringInfo(&param_str, "%s$%d = ",
                             paramno > 0 ? ", " : "",
                             paramno + 1);

            if (prm->isnull || !OidIsValid(prm->ptype))
            {
                appendStringInfoString(&param_str, "NULL");
                continue;
            }

            getTypeOutputInfo(prm->ptype, &typoutput, &typisvarlena);

            pstring = OidOutputFunctionCall(typoutput, prm->value);

            appendStringInfoCharMacro(&param_str, '\'');
            for (p = pstring; *p; p++)
            {
                if (*p == '\'') /* double single quotes */
                    appendStringInfoCharMacro(&param_str, *p);
                appendStringInfoCharMacro(&param_str, *p);
            }
            appendStringInfoCharMacro(&param_str, '\'');

            pfree(pstring);
        }

        errdetail("parameters: %s", param_str.data);

        pfree(param_str.data);

        MemoryContextSwitchTo(oldcontext);
    }

    return 0;
}

static int errdetail_recovery_conflict ( void   )  [static]

Definition at line 2200 of file postgres.c.

References errdetail(), 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, and RecoveryConflictReason.

Referenced by ProcessInterrupts().

{
    switch (RecoveryConflictReason)
    {
        case PROCSIG_RECOVERY_CONFLICT_BUFFERPIN:
            errdetail("User was holding shared buffer pin for too long.");
            break;
        case PROCSIG_RECOVERY_CONFLICT_LOCK:
            errdetail("User was holding a relation lock for too long.");
            break;
        case PROCSIG_RECOVERY_CONFLICT_TABLESPACE:
            errdetail("User was or might have been using tablespace that must be dropped.");
            break;
        case PROCSIG_RECOVERY_CONFLICT_SNAPSHOT:
            errdetail("User query might have needed to see row versions that must be removed.");
            break;
        case PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK:
            errdetail("User transaction caused buffer deadlock with recovery.");
            break;
        case PROCSIG_RECOVERY_CONFLICT_DATABASE:
            errdetail("User was connected to a database that must be dropped.");
            break;
        default:
            break;
            /* no errdetail */
    }

    return 0;
}

static void exec_bind_message ( StringInfo  input_message  )  [static]

Definition at line 1407 of file postgres.c.

References analyze_requires_snapshot(), check_log_duration(), CachedPlanSource::commandTag, CreatePortal(), StringInfoData::cursor, StringInfoData::data, DEBUG2, debug_query_string, DestRemote, ereport, errcode(), errdetail_abort(), errdetail_params(), errhidestmt(), errmsg(), ERROR, FetchPreparedStatement(), GetCachedPlan(), GetTransactionSnapshot(), getTypeBinaryInputInfo(), getTypeInputInfo(), i, InvalidSnapshot, IsAbortedTransactionBlockState(), ParamExternData::isnull, IsTransactionExitStmt(), StringInfoData::len, LOG, log_statement_stats, StringInfoData::maxlen, MemoryContextSwitchTo(), MessageContext, CachedPlanSource::num_params, ParamListInfoData::numParams, OidInputFunctionCall(), OidReceiveFunctionCall(), palloc(), CachedPlanSource::param_types, ParamListInfoData::paramFetch, ParamListInfoData::paramFetchArg, ParamListInfoData::params, ParamListInfoData::parserSetup, ParamListInfoData::parserSetupArg, ParamExternData::pflags, pfree(), pg_client_to_server(), pgstat_report_activity(), PreparedStatement::plansource, PopActiveSnapshot(), PortalDefineQuery(), PortalGetHeapMemory, PortalSetResultFormat(), PortalStart(), pq_getmsgbytes(), pq_getmsgend(), pq_getmsgint(), pq_getmsgstring(), pq_putemptymessage(), pstrdup(), ParamExternData::ptype, PushActiveSnapshot(), CachedPlanSource::query_string, CachedPlanSource::raw_parse_tree, ResetUsage(), set_ps_display(), ShowUsage(), start_xact_command(), STATE_RUNNING, CachedPlan::stmt_list, ParamExternData::value, and whereToSendOutput.

Referenced by PostgresMain().

{
    const char *portal_name;
    const char *stmt_name;
    int         numPFormats;
    int16      *pformats = NULL;
    int         numParams;
    int         numRFormats;
    int16      *rformats = NULL;
    CachedPlanSource *psrc;
    CachedPlan *cplan;
    Portal      portal;
    char       *query_string;
    char       *saved_stmt_name;
    ParamListInfo params;
    MemoryContext oldContext;
    bool        save_log_statement_stats = log_statement_stats;
    bool        snapshot_set = false;
    char        msec_str[32];

    /* Get the fixed part of the message */
    portal_name = pq_getmsgstring(input_message);
    stmt_name = pq_getmsgstring(input_message);

    ereport(DEBUG2,
            (errmsg("bind %s to %s",
                    *portal_name ? portal_name : "<unnamed>",
                    *stmt_name ? stmt_name : "<unnamed>")));

    /* Find prepared statement */
    if (stmt_name[0] != '\0')
    {
        PreparedStatement *pstmt;

        pstmt = FetchPreparedStatement(stmt_name, true);
        psrc = pstmt->plansource;
    }
    else
    {
        /* special-case the unnamed statement */
        psrc = unnamed_stmt_psrc;
        if (!psrc)
            ereport(ERROR,
                    (errcode(ERRCODE_UNDEFINED_PSTATEMENT),
                     errmsg("unnamed prepared statement does not exist")));
    }

    /*
     * Report query to various monitoring facilities.
     */
    debug_query_string = psrc->query_string;

    pgstat_report_activity(STATE_RUNNING, psrc->query_string);

    set_ps_display("BIND", false);

    if (save_log_statement_stats)
        ResetUsage();

    /*
     * Start up a transaction command so we can call functions etc. (Note that
     * this will normally change current memory context.) Nothing happens if
     * we are already in one.
     */
    start_xact_command();

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

    /* Get the parameter format codes */
    numPFormats = pq_getmsgint(input_message, 2);
    if (numPFormats > 0)
    {
        int         i;

        pformats = (int16 *) palloc(numPFormats * sizeof(int16));
        for (i = 0; i < numPFormats; i++)
            pformats[i] = pq_getmsgint(input_message, 2);
    }

    /* Get the parameter value count */
    numParams = pq_getmsgint(input_message, 2);

    if (numPFormats > 1 && numPFormats != numParams)
        ereport(ERROR,
                (errcode(ERRCODE_PROTOCOL_VIOLATION),
            errmsg("bind message has %d parameter formats but %d parameters",
                   numPFormats, numParams)));

    if (numParams != psrc->num_params)
        ereport(ERROR,
                (errcode(ERRCODE_PROTOCOL_VIOLATION),
                 errmsg("bind message supplies %d parameters, but prepared statement \"%s\" requires %d",
                        numParams, stmt_name, psrc->num_params)));

    /*
     * If we are in aborted transaction state, the only portals we can
     * actually run are those containing COMMIT or ROLLBACK commands. We
     * disallow binding anything else to avoid problems with infrastructure
     * that expects to run inside a valid transaction.  We also disallow
     * binding any parameters, since we can't risk calling user-defined I/O
     * functions.
     */
    if (IsAbortedTransactionBlockState() &&
        (!IsTransactionExitStmt(psrc->raw_parse_tree) ||
         numParams != 0))
        ereport(ERROR,
                (errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION),
                 errmsg("current transaction is aborted, "
                        "commands ignored until end of transaction block"),
                 errdetail_abort()));

    /*
     * Create the portal.  Allow silent replacement of an existing portal only
     * if the unnamed portal is specified.
     */
    if (portal_name[0] == '\0')
        portal = CreatePortal(portal_name, true, true);
    else
        portal = CreatePortal(portal_name, false, false);

    /*
     * Prepare to copy stuff into the portal's memory context.  We do all this
     * copying first, because it could possibly fail (out-of-memory) and we
     * don't want a failure to occur between GetCachedPlan and
     * PortalDefineQuery; that would result in leaking our plancache refcount.
     */
    oldContext = MemoryContextSwitchTo(PortalGetHeapMemory(portal));

    /* Copy the plan's query string into the portal */
    query_string = pstrdup(psrc->query_string);

    /* Likewise make a copy of the statement name, unless it's unnamed */
    if (stmt_name[0])
        saved_stmt_name = pstrdup(stmt_name);
    else
        saved_stmt_name = NULL;

    /*
     * Set a snapshot if we have parameters to fetch (since the input
     * functions might need it) or the query isn't a utility command (and
     * hence could require redoing parse analysis and planning).  We keep the
     * snapshot active till we're done, so that plancache.c doesn't have to
     * take new ones.
     */
    if (numParams > 0 || analyze_requires_snapshot(psrc->raw_parse_tree))
    {
        PushActiveSnapshot(GetTransactionSnapshot());
        snapshot_set = true;
    }

    /*
     * Fetch parameters, if any, and store in the portal's memory context.
     */
    if (numParams > 0)
    {
        int         paramno;

        /* sizeof(ParamListInfoData) includes the first array element */
        params = (ParamListInfo) palloc(sizeof(ParamListInfoData) +
                                  (numParams - 1) * sizeof(ParamExternData));
        /* we have static list of params, so no hooks needed */
        params->paramFetch = NULL;
        params->paramFetchArg = NULL;
        params->parserSetup = NULL;
        params->parserSetupArg = NULL;
        params->numParams = numParams;

        for (paramno = 0; paramno < numParams; paramno++)
        {
            Oid         ptype = psrc->param_types[paramno];
            int32       plength;
            Datum       pval;
            bool        isNull;
            StringInfoData pbuf;
            char        csave;
            int16       pformat;

            plength = pq_getmsgint(input_message, 4);
            isNull = (plength == -1);

            if (!isNull)
            {
                const char *pvalue = pq_getmsgbytes(input_message, plength);

                /*
                 * Rather than copying data around, we just set up a phony
                 * StringInfo pointing to the correct portion of the message
                 * buffer.  We assume we can scribble on the message buffer so
                 * as to maintain the convention that StringInfos have a
                 * trailing null.  This is grotty but is a big win when
                 * dealing with very large parameter strings.
                 */
                pbuf.data = (char *) pvalue;
                pbuf.maxlen = plength + 1;
                pbuf.len = plength;
                pbuf.cursor = 0;

                csave = pbuf.data[plength];
                pbuf.data[plength] = '\0';
            }
            else
            {
                pbuf.data = NULL;       /* keep compiler quiet */
                csave = 0;
            }

            if (numPFormats > 1)
                pformat = pformats[paramno];
            else if (numPFormats > 0)
                pformat = pformats[0];
            else
                pformat = 0;    /* default = text */

            if (pformat == 0)   /* text mode */
            {
                Oid         typinput;
                Oid         typioparam;
                char       *pstring;

                getTypeInputInfo(ptype, &typinput, &typioparam);

                /*
                 * We have to do encoding conversion before calling the
                 * typinput routine.
                 */
                if (isNull)
                    pstring = NULL;
                else
                    pstring = pg_client_to_server(pbuf.data, plength);

                pval = OidInputFunctionCall(typinput, pstring, typioparam, -1);

                /* Free result of encoding conversion, if any */
                if (pstring && pstring != pbuf.data)
                    pfree(pstring);
            }
            else if (pformat == 1)      /* binary mode */
            {
                Oid         typreceive;
                Oid         typioparam;
                StringInfo  bufptr;

                /*
                 * Call the parameter type's binary input converter
                 */
                getTypeBinaryInputInfo(ptype, &typreceive, &typioparam);

                if (isNull)
                    bufptr = NULL;
                else
                    bufptr = &pbuf;

                pval = OidReceiveFunctionCall(typreceive, bufptr, typioparam, -1);

                /* Trouble if it didn't eat the whole buffer */
                if (!isNull && pbuf.cursor != pbuf.len)
                    ereport(ERROR,
                            (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
                             errmsg("incorrect binary data format in bind parameter %d",
                                    paramno + 1)));
            }
            else
            {
                ereport(ERROR,
                        (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                         errmsg("unsupported format code: %d",
                                pformat)));
                pval = 0;       /* keep compiler quiet */
            }

            /* Restore message buffer contents */
            if (!isNull)
                pbuf.data[plength] = csave;

            params->params[paramno].value = pval;
            params->params[paramno].isnull = isNull;

            /*
             * We mark the params as CONST.  This ensures that any custom plan
             * makes full use of the parameter values.
             */
            params->params[paramno].pflags = PARAM_FLAG_CONST;
            params->params[paramno].ptype = ptype;
        }
    }
    else
        params = NULL;

    /* Done storing stuff in portal's context */
    MemoryContextSwitchTo(oldContext);

    /* Get the result format codes */
    numRFormats = pq_getmsgint(input_message, 2);
    if (numRFormats > 0)
    {
        int         i;

        rformats = (int16 *) palloc(numRFormats * sizeof(int16));
        for (i = 0; i < numRFormats; i++)
            rformats[i] = pq_getmsgint(input_message, 2);
    }

    pq_getmsgend(input_message);

    /*
     * Obtain a plan from the CachedPlanSource.  Any cruft from (re)planning
     * will be generated in MessageContext.  The plan refcount will be
     * assigned to the Portal, so it will be released at portal destruction.
     */
    cplan = GetCachedPlan(psrc, params, false);

    /*
     * Now we can define the portal.
     *
     * DO NOT put any code that could possibly throw an error between the
     * above GetCachedPlan call and here.
     */
    PortalDefineQuery(portal,
                      saved_stmt_name,
                      query_string,
                      psrc->commandTag,
                      cplan->stmt_list,
                      cplan);

    /* Done with the snapshot used for parameter I/O and parsing/planning */
    if (snapshot_set)
        PopActiveSnapshot();

    /*
     * And we're ready to start portal execution.
     */
    PortalStart(portal, params, 0, InvalidSnapshot);

    /*
     * Apply the result format requests to the portal.
     */
    PortalSetResultFormat(portal, numRFormats, rformats);

    /*
     * Send BindComplete.
     */
    if (whereToSendOutput == DestRemote)
        pq_putemptymessage('2');

    /*
     * Emit duration logging if appropriate.
     */
    switch (check_log_duration(msec_str, false))
    {
        case 1:
            ereport(LOG,
                    (errmsg("duration: %s ms", msec_str),
                     errhidestmt(true)));
            break;
        case 2:
            ereport(LOG,
                    (errmsg("duration: %s ms  bind %s%s%s: %s",
                            msec_str,
                            *stmt_name ? stmt_name : "<unnamed>",
                            *portal_name ? "/" : "",
                            *portal_name ? portal_name : "",
                            psrc->query_string),
                     errhidestmt(true),
                     errdetail_params(params)));
            break;
    }

    if (save_log_statement_stats)
        ShowUsage("BIND MESSAGE STATISTICS");

    debug_query_string = NULL;
}

static void exec_describe_portal_message ( const char *  portal_name  )  [static]

Definition at line 2329 of file postgres.c.

References DestRemote, ereport, errcode(), errdetail_abort(), errmsg(), ERROR, FetchPortalTargetList(), PortalData::formats, GetPortalByName(), IsAbortedTransactionBlockState(), MemoryContextSwitchTo(), MessageContext, PortalIsValid, pq_putemptymessage(), SendRowDescriptionMessage(), start_xact_command(), PortalData::tupDesc, and whereToSendOutput.

Referenced by PostgresMain().

{
    Portal      portal;

    /*
     * Start up a transaction command. (Note that this will normally change
     * current memory context.) Nothing happens if we are already in one.
     */
    start_xact_command();

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

    portal = GetPortalByName(portal_name);
    if (!PortalIsValid(portal))
        ereport(ERROR,
                (errcode(ERRCODE_UNDEFINED_CURSOR),
                 errmsg("portal \"%s\" does not exist", portal_name)));

    /*
     * If we are in aborted transaction state, we can't run
     * SendRowDescriptionMessage(), because that needs catalog accesses.
     * Hence, refuse to Describe portals that return data.  (We shouldn't just
     * refuse all Describes, since that might break the ability of some
     * clients to issue COMMIT or ROLLBACK commands, if they use code that
     * blindly Describes whatever it does.)
     */
    if (IsAbortedTransactionBlockState() &&
        portal->tupDesc)
        ereport(ERROR,
                (errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION),
                 errmsg("current transaction is aborted, "
                        "commands ignored until end of transaction block"),
                 errdetail_abort()));

    if (whereToSendOutput != DestRemote)
        return;                 /* can't actually do anything... */

    if (portal->tupDesc)
        SendRowDescriptionMessage(portal->tupDesc,
                                  FetchPortalTargetList(portal),
                                  portal->formats);
    else
        pq_putemptymessage('n');    /* NoData */
}

static void exec_describe_statement_message ( const char *  stmt_name  )  [static]

Definition at line 2236 of file postgres.c.

References Assert, buf, CachedPlanGetTargetList(), DestRemote, ereport, errcode(), errdetail_abort(), errmsg(), ERROR, FetchPreparedStatement(), CachedPlanSource::fixed_result, i, IsAbortedTransactionBlockState(), MemoryContextSwitchTo(), MessageContext, NULL, CachedPlanSource::num_params, CachedPlanSource::param_types, PreparedStatement::plansource, pq_beginmessage(), pq_endmessage(), pq_putemptymessage(), pq_sendint(), CachedPlanSource::resultDesc, SendRowDescriptionMessage(), start_xact_command(), and whereToSendOutput.

Referenced by PostgresMain().

{
    CachedPlanSource *psrc;
    StringInfoData buf;
    int         i;

    /*
     * Start up a transaction command. (Note that this will normally change
     * current memory context.) Nothing happens if we are already in one.
     */
    start_xact_command();

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

    /* Find prepared statement */
    if (stmt_name[0] != '\0')
    {
        PreparedStatement *pstmt;

        pstmt = FetchPreparedStatement(stmt_name, true);
        psrc = pstmt->plansource;
    }
    else
    {
        /* special-case the unnamed statement */
        psrc = unnamed_stmt_psrc;
        if (!psrc)
            ereport(ERROR,
                    (errcode(ERRCODE_UNDEFINED_PSTATEMENT),
                     errmsg("unnamed prepared statement does not exist")));
    }

    /* Prepared statements shouldn't have changeable result descs */
    Assert(psrc->fixed_result);

    /*
     * If we are in aborted transaction state, we can't run
     * SendRowDescriptionMessage(), because that needs catalog accesses.
     * Hence, refuse to Describe statements that return data.  (We shouldn't
     * just refuse all Describes, since that might break the ability of some
     * clients to issue COMMIT or ROLLBACK commands, if they use code that
     * blindly Describes whatever it does.)  We can Describe parameters
     * without doing anything dangerous, so we don't restrict that.
     */
    if (IsAbortedTransactionBlockState() &&
        psrc->resultDesc)
        ereport(ERROR,
                (errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION),
                 errmsg("current transaction is aborted, "
                        "commands ignored until end of transaction block"),
                 errdetail_abort()));

    if (whereToSendOutput != DestRemote)
        return;                 /* can't actually do anything... */

    /*
     * First describe the parameters...
     */
    pq_beginmessage(&buf, 't'); /* parameter description message type */
    pq_sendint(&buf, psrc->num_params, 2);

    for (i = 0; i < psrc->num_params; i++)
    {
        Oid         ptype = psrc->param_types[i];

        pq_sendint(&buf, (int) ptype, 4);
    }
    pq_endmessage(&buf);

    /*
     * Next send RowDescription or NoData to describe the result...
     */
    if (psrc->resultDesc)
    {
        List       *tlist;

        /* Get the plan's primary targetlist */
        tlist = CachedPlanGetTargetList(psrc);

        SendRowDescriptionMessage(psrc->resultDesc, tlist, NULL);
    }
    else
        pq_putemptymessage('n');    /* NoData */

}

static void exec_execute_message ( const char *  portal_name,
long  max_rows 
) [static]

Definition at line 1787 of file postgres.c.

References _, Assert, PortalData::atStart, BeginCommand(), CHECK_FOR_INTERRUPTS, check_log_duration(), check_log_statement(), CommandCounterIncrement(), PortalData::commandTag, CreateDestReceiver(), debug_query_string, DestRemote, DestRemoteExecute, EndCommand(), ereport, errcode(), errdetail_abort(), errdetail_params(), errhidestmt(), errmsg(), ERROR, finish_xact_command(), GetPortalByName(), IsAbortedTransactionBlockState(), IsTransactionExitStmtList(), IsTransactionStmtList(), LOG, log_statement_stats, NIL, NULL, NullCommand(), pgstat_report_activity(), PortalIsValid, PortalData::portalParams, PortalRun(), pq_putemptymessage(), PortalData::prepStmtName, pstrdup(), _DestReceiver::rDestroy, ResetUsage(), set_ps_display(), SetRemoteDestReceiverParams(), ShowUsage(), PortalData::sourceText, start_xact_command(), STATE_RUNNING, PortalData::stmts, and whereToSendOutput.

Referenced by PostgresMain().

{
    CommandDest dest;
    DestReceiver *receiver;
    Portal      portal;
    bool        completed;
    char        completionTag[COMPLETION_TAG_BUFSIZE];
    const char *sourceText;
    const char *prepStmtName;
    ParamListInfo portalParams;
    bool        save_log_statement_stats = log_statement_stats;
    bool        is_xact_command;
    bool        execute_is_fetch;
    bool        was_logged = false;
    char        msec_str[32];

    /* Adjust destination to tell printtup.c what to do */
    dest = whereToSendOutput;
    if (dest == DestRemote)
        dest = DestRemoteExecute;

    portal = GetPortalByName(portal_name);
    if (!PortalIsValid(portal))
        ereport(ERROR,
                (errcode(ERRCODE_UNDEFINED_CURSOR),
                 errmsg("portal \"%s\" does not exist", portal_name)));

    /*
     * If the original query was a null string, just return
     * EmptyQueryResponse.
     */
    if (portal->commandTag == NULL)
    {
        Assert(portal->stmts == NIL);
        NullCommand(dest);
        return;
    }

    /* Does the portal contain a transaction command? */
    is_xact_command = IsTransactionStmtList(portal->stmts);

    /*
     * We must copy the sourceText and prepStmtName into MessageContext in
     * case the portal is destroyed during finish_xact_command. Can avoid the
     * copy if it's not an xact command, though.
     */
    if (is_xact_command)
    {
        sourceText = pstrdup(portal->sourceText);
        if (portal->prepStmtName)
            prepStmtName = pstrdup(portal->prepStmtName);
        else
            prepStmtName = "<unnamed>";

        /*
         * An xact command shouldn't have any parameters, which is a good
         * thing because they wouldn't be around after finish_xact_command.
         */
        portalParams = NULL;
    }
    else
    {
        sourceText = portal->sourceText;
        if (portal->prepStmtName)
            prepStmtName = portal->prepStmtName;
        else
            prepStmtName = "<unnamed>";
        portalParams = portal->portalParams;
    }

    /*
     * Report query to various monitoring facilities.
     */
    debug_query_string = sourceText;

    pgstat_report_activity(STATE_RUNNING, sourceText);

    set_ps_display(portal->commandTag, false);

    if (save_log_statement_stats)
        ResetUsage();

    BeginCommand(portal->commandTag, dest);

    /*
     * Create dest receiver in MessageContext (we don't want it in transaction
     * context, because that may get deleted if portal contains VACUUM).
     */
    receiver = CreateDestReceiver(dest);
    if (dest == DestRemoteExecute)
        SetRemoteDestReceiverParams(receiver, portal);

    /*
     * Ensure we are in a transaction command (this should normally be the
     * case already due to prior BIND).
     */
    start_xact_command();

    /*
     * If we re-issue an Execute protocol request against an existing portal,
     * then we are only fetching more rows rather than completely re-executing
     * the query from the start. atStart is never reset for a v3 portal, so we
     * are safe to use this check.
     */
    execute_is_fetch = !portal->atStart;

    /* Log immediately if dictated by log_statement */
    if (check_log_statement(portal->stmts))
    {
        ereport(LOG,
                (errmsg("%s %s%s%s: %s",
                        execute_is_fetch ?
                        _("execute fetch from") :
                        _("execute"),
                        prepStmtName,
                        *portal_name ? "/" : "",
                        *portal_name ? portal_name : "",
                        sourceText),
                 errhidestmt(true),
                 errdetail_params(portalParams)));
        was_logged = true;
    }

    /*
     * If we are in aborted transaction state, the only portals we can
     * actually run are those containing COMMIT or ROLLBACK commands.
     */
    if (IsAbortedTransactionBlockState() &&
        !IsTransactionExitStmtList(portal->stmts))
        ereport(ERROR,
                (errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION),
                 errmsg("current transaction is aborted, "
                        "commands ignored until end of transaction block"),
                 errdetail_abort()));

    /* Check for cancel signal before we start execution */
    CHECK_FOR_INTERRUPTS();

    /*
     * Okay to run the portal.
     */
    if (max_rows <= 0)
        max_rows = FETCH_ALL;

    completed = PortalRun(portal,
                          max_rows,
                          true, /* always top level */
                          receiver,
                          receiver,
                          completionTag);

    (*receiver->rDestroy) (receiver);

    if (completed)
    {
        if (is_xact_command)
        {
            /*
             * If this was a transaction control statement, commit it.  We
             * will start a new xact command for the next command (if any).
             */
            finish_xact_command();
        }
        else
        {
            /*
             * We need a CommandCounterIncrement after every query, except
             * those that start or end a transaction block.
             */
            CommandCounterIncrement();
        }

        /* Send appropriate CommandComplete to client */
        EndCommand(completionTag, dest);
    }
    else
    {
        /* Portal run not complete, so send PortalSuspended */
        if (whereToSendOutput == DestRemote)
            pq_putemptymessage('s');
    }

    /*
     * Emit duration logging if appropriate.
     */
    switch (check_log_duration(msec_str, was_logged))
    {
        case 1:
            ereport(LOG,
                    (errmsg("duration: %s ms", msec_str),
                     errhidestmt(true)));
            break;
        case 2:
            ereport(LOG,
                    (errmsg("duration: %s ms  %s %s%s%s: %s",
                            msec_str,
                            execute_is_fetch ?
                            _("execute fetch from") :
                            _("execute"),
                            prepStmtName,
                            *portal_name ? "/" : "",
                            *portal_name ? portal_name : "",
                            sourceText),
                     errhidestmt(true),
                     errdetail_params(portalParams)));
            break;
    }

    if (save_log_statement_stats)
        ShowUsage("EXECUTE MESSAGE STATISTICS");

    debug_query_string = NULL;
}

static void exec_parse_message ( const char *  query_string,
const char *  stmt_name,
Oid paramTypes,
int  numParams 
) [static]

Definition at line 1143 of file postgres.c.

References ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE, ALLOCSET_DEFAULT_MINSIZE, AllocSetContextCreate(), analyze_requires_snapshot(), CHECK_FOR_INTERRUPTS, check_log_duration(), CommandCounterIncrement(), CompleteCachedPlan(), CachedPlanSource::context, CreateCachedPlan(), CreateCommandTag(), DEBUG2, debug_query_string, DestRemote, drop_unnamed_stmt(), ereport, errcode(), errdetail_abort(), errhidestmt(), errmsg(), ERROR, GetTransactionSnapshot(), i, InvalidOid, IsAbortedTransactionBlockState(), IsTransactionExitStmt(), linitial, list_length(), LOG, log_parser_stats, log_statement_stats, MemoryContextSetParent(), MemoryContextSwitchTo(), MessageContext, NIL, NULL, parse_analyze_varparams(), pg_parse_query(), pg_rewrite_query(), pgstat_report_activity(), PopActiveSnapshot(), pq_putemptymessage(), PushActiveSnapshot(), ResetUsage(), SaveCachedPlan(), set_ps_display(), ShowUsage(), start_xact_command(), STATE_RUNNING, StorePreparedStatement(), UNKNOWNOID, and whereToSendOutput.

Referenced by PostgresMain().

{
    MemoryContext unnamed_stmt_context = NULL;
    MemoryContext oldcontext;
    List       *parsetree_list;
    Node       *raw_parse_tree;
    const char *commandTag;
    List       *querytree_list;
    CachedPlanSource *psrc;
    bool        is_named;
    bool        save_log_statement_stats = log_statement_stats;
    char        msec_str[32];

    /*
     * Report query to various monitoring facilities.
     */
    debug_query_string = query_string;

    pgstat_report_activity(STATE_RUNNING, query_string);

    set_ps_display("PARSE", false);

    if (save_log_statement_stats)
        ResetUsage();

    ereport(DEBUG2,
            (errmsg("parse %s: %s",
                    *stmt_name ? stmt_name : "<unnamed>",
                    query_string)));

    /*
     * Start up a transaction command so we can run parse analysis etc. (Note
     * that this will normally change current memory context.) Nothing happens
     * if we are already in one.
     */
    start_xact_command();

    /*
     * Switch to appropriate context for constructing parsetrees.
     *
     * We have two strategies depending on whether the prepared statement is
     * named or not.  For a named prepared statement, we do parsing in
     * MessageContext and copy the finished trees into the prepared
     * statement's plancache entry; then the reset of MessageContext releases
     * temporary space used by parsing and rewriting. For an unnamed prepared
     * statement, we assume the statement isn't going to hang around long, so
     * getting rid of temp space quickly is probably not worth the costs of
     * copying parse trees.  So in this case, we create the plancache entry's
     * query_context here, and do all the parsing work therein.
     */
    is_named = (stmt_name[0] != '\0');
    if (is_named)
    {
        /* Named prepared statement --- parse in MessageContext */
        oldcontext = MemoryContextSwitchTo(MessageContext);
    }
    else
    {
        /* Unnamed prepared statement --- release any prior unnamed stmt */
        drop_unnamed_stmt();
        /* Create context for parsing */
        unnamed_stmt_context =
            AllocSetContextCreate(MessageContext,
                                  "unnamed prepared statement",
                                  ALLOCSET_DEFAULT_MINSIZE,
                                  ALLOCSET_DEFAULT_INITSIZE,
                                  ALLOCSET_DEFAULT_MAXSIZE);
        oldcontext = MemoryContextSwitchTo(unnamed_stmt_context);
    }

    /*
     * Do basic parsing of the query or queries (this should be safe even if
     * we are in aborted transaction state!)
     */
    parsetree_list = pg_parse_query(query_string);

    /*
     * We only allow a single user statement in a prepared statement. This is
     * mainly to keep the protocol simple --- otherwise we'd need to worry
     * about multiple result tupdescs and things like that.
     */
    if (list_length(parsetree_list) > 1)
        ereport(ERROR,
                (errcode(ERRCODE_SYNTAX_ERROR),
        errmsg("cannot insert multiple commands into a prepared statement")));

    if (parsetree_list != NIL)
    {
        Query      *query;
        bool        snapshot_set = false;
        int         i;

        raw_parse_tree = (Node *) linitial(parsetree_list);

        /*
         * Get the command name for possible use in status display.
         */
        commandTag = CreateCommandTag(raw_parse_tree);

        /*
         * If we are in an aborted transaction, reject all commands except
         * COMMIT/ROLLBACK.  It is important that this test occur before we
         * try to do parse analysis, rewrite, or planning, since all those
         * phases try to do database accesses, which may fail in abort state.
         * (It might be safe to allow some additional utility commands in this
         * state, but not many...)
         */
        if (IsAbortedTransactionBlockState() &&
            !IsTransactionExitStmt(raw_parse_tree))
            ereport(ERROR,
                    (errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION),
                     errmsg("current transaction is aborted, "
                          "commands ignored until end of transaction block"),
                     errdetail_abort()));

        /*
         * Create the CachedPlanSource before we do parse analysis, since it
         * needs to see the unmodified raw parse tree.
         */
        psrc = CreateCachedPlan(raw_parse_tree, query_string, commandTag);

        /*
         * Set up a snapshot if parse analysis will need one.
         */
        if (analyze_requires_snapshot(raw_parse_tree))
        {
            PushActiveSnapshot(GetTransactionSnapshot());
            snapshot_set = true;
        }

        /*
         * Analyze and rewrite the query.  Note that the originally specified
         * parameter set is not required to be complete, so we have to use
         * parse_analyze_varparams().
         */
        if (log_parser_stats)
            ResetUsage();

        query = parse_analyze_varparams(raw_parse_tree,
                                        query_string,
                                        &paramTypes,
                                        &numParams);

        /*
         * Check all parameter types got determined.
         */
        for (i = 0; i < numParams; i++)
        {
            Oid         ptype = paramTypes[i];

            if (ptype == InvalidOid || ptype == UNKNOWNOID)
                ereport(ERROR,
                        (errcode(ERRCODE_INDETERMINATE_DATATYPE),
                     errmsg("could not determine data type of parameter $%d",
                            i + 1)));
        }

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

        querytree_list = pg_rewrite_query(query);

        /* Done with the snapshot used for parsing */
        if (snapshot_set)
            PopActiveSnapshot();
    }
    else
    {
        /* Empty input string.  This is legal. */
        raw_parse_tree = NULL;
        commandTag = NULL;
        psrc = CreateCachedPlan(raw_parse_tree, query_string, commandTag);
        querytree_list = NIL;
    }

    /*
     * CachedPlanSource must be a direct child of MessageContext before we
     * reparent unnamed_stmt_context under it, else we have a disconnected
     * circular subgraph.  Klugy, but less so than flipping contexts even more
     * above.
     */
    if (unnamed_stmt_context)
        MemoryContextSetParent(psrc->context, MessageContext);

    /* Finish filling in the CachedPlanSource */
    CompleteCachedPlan(psrc,
                       querytree_list,
                       unnamed_stmt_context,
                       paramTypes,
                       numParams,
                       NULL,
                       NULL,
                       0,       /* default cursor options */
                       true);   /* fixed result */

    /* If we got a cancel signal during analysis, quit */
    CHECK_FOR_INTERRUPTS();

    if (is_named)
    {
        /*
         * Store the query as a prepared statement.
         */
        StorePreparedStatement(stmt_name, psrc, false);
    }
    else
    {
        /*
         * We just save the CachedPlanSource into unnamed_stmt_psrc.
         */
        SaveCachedPlan(psrc);
        unnamed_stmt_psrc = psrc;
    }

    MemoryContextSwitchTo(oldcontext);

    /*
     * We do NOT close the open transaction command here; that only happens
     * when the client sends Sync.  Instead, do CommandCounterIncrement just
     * in case something happened during parse/plan.
     */
    CommandCounterIncrement();

    /*
     * Send ParseComplete.
     */
    if (whereToSendOutput == DestRemote)
        pq_putemptymessage('1');

    /*
     * Emit duration logging if appropriate.
     */
    switch (check_log_duration(msec_str, false))
    {
        case 1:
            ereport(LOG,
                    (errmsg("duration: %s ms", msec_str),
                     errhidestmt(true)));
            break;
        case 2:
            ereport(LOG,
                    (errmsg("duration: %s ms  parse %s: %s",
                            msec_str,
                            *stmt_name ? stmt_name : "<unnamed>",
                            query_string),
                     errhidestmt(true)));
            break;
    }

    if (save_log_statement_stats)
        ShowUsage("PARSE MESSAGE STATISTICS");

    debug_query_string = NULL;
}

static void exec_simple_query ( const char *  query_string  )  [static]

Definition at line 828 of file postgres.c.

References analyze_requires_snapshot(), BeginCommand(), CHECK_FOR_INTERRUPTS, check_log_duration(), check_log_statement(), CommandCounterIncrement(), CreateCommandTag(), CreateDestReceiver(), CreatePortal(), CURSOR_OPT_BINARY, PortalData::cursorOptions, debug_query_string, DestRemote, drop_unnamed_stmt(), EndCommand(), ereport, errcode(), errdetail_abort(), errdetail_execute(), errhidestmt(), errmsg(), ERROR, FETCH_ALL, finish_xact_command(), format, GetPortalByName(), GetTransactionSnapshot(), InvalidSnapshot, IsA, IsAbortedTransactionBlockState(), FetchStmt::ismove, IsTransactionExitStmt(), lfirst, list_length(), lnext, LOG, log_statement_stats, MemoryContextSwitchTo(), MessageContext, NULL, NullCommand(), pg_analyze_and_rewrite(), pg_parse_query(), pg_plan_queries(), pgstat_report_activity(), PopActiveSnapshot(), PortalDefineQuery(), PortalDrop(), PortalIsValid, FetchStmt::portalname, PortalRun(), PortalSetResultFormat(), PortalStart(), PushActiveSnapshot(), _DestReceiver::rDestroy, ResetUsage(), set_ps_display(), SetRemoteDestReceiverParams(), ShowUsage(), start_xact_command(), STATE_RUNNING, PortalData::visible, and whereToSendOutput.

Referenced by PostgresMain().

{
    CommandDest dest = whereToSendOutput;
    MemoryContext oldcontext;
    List       *parsetree_list;
    ListCell   *parsetree_item;
    bool        save_log_statement_stats = log_statement_stats;
    bool        was_logged = false;
    bool        isTopLevel;
    char        msec_str[32];


    /*
     * Report query to various monitoring facilities.
     */
    debug_query_string = query_string;

    pgstat_report_activity(STATE_RUNNING, query_string);

    TRACE_POSTGRESQL_QUERY_START(query_string);

    /*
     * We use save_log_statement_stats so ShowUsage doesn't report incorrect
     * results because ResetUsage wasn't called.
     */
    if (save_log_statement_stats)
        ResetUsage();

    /*
     * Start up a transaction command.  All queries generated by the
     * query_string will be in this same command block, *unless* we find a
     * BEGIN/COMMIT/ABORT statement; we have to force a new xact command after
     * one of those, else bad things will happen in xact.c. (Note that this
     * will normally change current memory context.)
     */
    start_xact_command();

    /*
     * Zap any pre-existing unnamed statement.  (While not strictly necessary,
     * it seems best to define simple-Query mode as if it used the unnamed
     * statement and portal; this ensures we recover any storage used by prior
     * unnamed operations.)
     */
    drop_unnamed_stmt();

    /*
     * Switch to appropriate context for constructing parsetrees.
     */
    oldcontext = MemoryContextSwitchTo(MessageContext);

    /*
     * Do basic parsing of the query or queries (this should be safe even if
     * we are in aborted transaction state!)
     */
    parsetree_list = pg_parse_query(query_string);

    /* Log immediately if dictated by log_statement */
    if (check_log_statement(parsetree_list))
    {
        ereport(LOG,
                (errmsg("statement: %s", query_string),
                 errhidestmt(true),
                 errdetail_execute(parsetree_list)));
        was_logged = true;
    }

    /*
     * Switch back to transaction context to enter the loop.
     */
    MemoryContextSwitchTo(oldcontext);

    /*
     * We'll tell PortalRun it's a top-level command iff there's exactly one
     * raw parsetree.  If more than one, it's effectively a transaction block
     * and we want PreventTransactionChain to reject unsafe commands. (Note:
     * we're assuming that query rewrite cannot add commands that are
     * significant to PreventTransactionChain.)
     */
    isTopLevel = (list_length(parsetree_list) == 1);

    /*
     * Run through the raw parsetree(s) and process each one.
     */
    foreach(parsetree_item, parsetree_list)
    {
        Node       *parsetree = (Node *) lfirst(parsetree_item);
        bool        snapshot_set = false;
        const char *commandTag;
        char        completionTag[COMPLETION_TAG_BUFSIZE];
        List       *querytree_list,
                   *plantree_list;
        Portal      portal;
        DestReceiver *receiver;
        int16       format;

        /*
         * Get the command name for use in status display (it also becomes the
         * default completion tag, down inside PortalRun).  Set ps_status and
         * do any special start-of-SQL-command processing needed by the
         * destination.
         */
        commandTag = CreateCommandTag(parsetree);

        set_ps_display(commandTag, false);

        BeginCommand(commandTag, dest);

        /*
         * If we are in an aborted transaction, reject all commands except
         * COMMIT/ABORT.  It is important that this test occur before we try
         * to do parse analysis, rewrite, or planning, since all those phases
         * try to do database accesses, which may fail in abort state. (It
         * might be safe to allow some additional utility commands in this
         * state, but not many...)
         */
        if (IsAbortedTransactionBlockState() &&
            !IsTransactionExitStmt(parsetree))
            ereport(ERROR,
                    (errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION),
                     errmsg("current transaction is aborted, "
                          "commands ignored until end of transaction block"),
                     errdetail_abort()));

        /* Make sure we are in a transaction command */
        start_xact_command();

        /* If we got a cancel signal in parsing or prior command, quit */
        CHECK_FOR_INTERRUPTS();

        /*
         * Set up a snapshot if parse analysis/planning will need one.
         */
        if (analyze_requires_snapshot(parsetree))
        {
            PushActiveSnapshot(GetTransactionSnapshot());
            snapshot_set = true;
        }

        /*
         * OK to analyze, rewrite, and plan this query.
         *
         * Switch to appropriate context for constructing querytrees (again,
         * these must outlive the execution context).
         */
        oldcontext = MemoryContextSwitchTo(MessageContext);

        querytree_list = pg_analyze_and_rewrite(parsetree, query_string,
                                                NULL, 0);

        plantree_list = pg_plan_queries(querytree_list, 0, NULL);

        /* Done with the snapshot used for parsing/planning */
        if (snapshot_set)
            PopActiveSnapshot();

        /* If we got a cancel signal in analysis or planning, quit */
        CHECK_FOR_INTERRUPTS();

        /*
         * Create unnamed portal to run the query or queries in. If there
         * already is one, silently drop it.
         */
        portal = CreatePortal("", true, true);
        /* Don't display the portal in pg_cursors */
        portal->visible = false;

        /*
         * We don't have to copy anything into the portal, because everything
         * we are passing here is in MessageContext, which will outlive the
         * portal anyway.
         */
        PortalDefineQuery(portal,
                          NULL,
                          query_string,
                          commandTag,
                          plantree_list,
                          NULL);

        /*
         * Start the portal.  No parameters here.
         */
        PortalStart(portal, NULL, 0, InvalidSnapshot);

        /*
         * Select the appropriate output format: text unless we are doing a
         * FETCH from a binary cursor.  (Pretty grotty to have to do this here
         * --- but it avoids grottiness in other places.  Ah, the joys of
         * backward compatibility...)
         */
        format = 0;             /* TEXT is default */
        if (IsA(parsetree, FetchStmt))
        {
            FetchStmt  *stmt = (FetchStmt *) parsetree;

            if (!stmt->ismove)
            {
                Portal      fportal = GetPortalByName(stmt->portalname);

                if (PortalIsValid(fportal) &&
                    (fportal->cursorOptions & CURSOR_OPT_BINARY))
                    format = 1; /* BINARY */
            }
        }
        PortalSetResultFormat(portal, 1, &format);

        /*
         * Now we can create the destination receiver object.
         */
        receiver = CreateDestReceiver(dest);
        if (dest == DestRemote)
            SetRemoteDestReceiverParams(receiver, portal);

        /*
         * Switch back to transaction context for execution.
         */
        MemoryContextSwitchTo(oldcontext);

        /*
         * Run the portal to completion, and then drop it (and the receiver).
         */
        (void) PortalRun(portal,
                         FETCH_ALL,
                         isTopLevel,
                         receiver,
                         receiver,
                         completionTag);

        (*receiver->rDestroy) (receiver);

        PortalDrop(portal, false);

        if (IsA(parsetree, TransactionStmt))
        {
            /*
             * If this was a transaction control statement, commit it. We will
             * start a new xact command for the next command (if any).
             */
            finish_xact_command();
        }
        else if (lnext(parsetree_item) == NULL)
        {
            /*
             * If this is the last parsetree of the query string, close down
             * transaction statement before reporting command-complete.  This
             * is so that any end-of-transaction errors are reported before
             * the command-complete message is issued, to avoid confusing
             * clients who will expect either a command-complete message or an
             * error, not one and then the other.  But for compatibility with
             * historical Postgres behavior, we do not force a transaction
             * boundary between queries appearing in a single query string.
             */
            finish_xact_command();
        }
        else
        {
            /*
             * We need a CommandCounterIncrement after every query, except
             * those that start or end a transaction block.
             */
            CommandCounterIncrement();
        }

        /*
         * Tell client that we're done with this query.  Note we emit exactly
         * one EndCommand report for each raw parsetree, thus one for each SQL
         * command the client sent, regardless of rewriting. (But a command
         * aborted by error will not send an EndCommand report at all.)
         */
        EndCommand(completionTag, dest);
    }                           /* end loop over parsetrees */

    /*
     * Close down transaction statement, if one is open.
     */
    finish_xact_command();

    /*
     * If there were no parsetrees, return EmptyQueryResponse message.
     */
    if (!parsetree_list)
        NullCommand(dest);

    /*
     * Emit duration logging if appropriate.
     */
    switch (check_log_duration(msec_str, was_logged))
    {
        case 1:
            ereport(LOG,
                    (errmsg("duration: %s ms", msec_str),
                     errhidestmt(true)));
            break;
        case 2:
            ereport(LOG,
                    (errmsg("duration: %s ms  statement: %s",
                            msec_str, query_string),
                     errhidestmt(true),
                     errdetail_execute(parsetree_list)));
            break;
    }

    if (save_log_statement_stats)
        ShowUsage("QUERY STATISTICS");

    TRACE_POSTGRESQL_QUERY_DONE(query_string);

    debug_query_string = NULL;
}

static void finish_xact_command ( void   )  [static]

Definition at line 2400 of file postgres.c.

References CommitTransactionCommand(), DEBUG3, disable_timeout(), ereport, errmsg_internal(), MemoryContextStats(), STATEMENT_TIMEOUT, TopMemoryContext, and xact_started.

Referenced by exec_execute_message(), exec_simple_query(), and PostgresMain().

{
    if (xact_started)
    {
        /* Cancel any active statement timeout before committing */
        disable_timeout(STATEMENT_TIMEOUT, false);

        /* Now commit the command */
        ereport(DEBUG3,
                (errmsg_internal("CommitTransactionCommand")));

        CommitTransactionCommand();

#ifdef MEMORY_CONTEXT_CHECKING
        /* Check all memory contexts that weren't freed during commit */
        /* (those that were, were checked before being deleted) */
        MemoryContextCheck(TopMemoryContext);
#endif

#ifdef SHOW_MEMORY_STATS
        /* Print mem stats after each commit for leak tracking */
        MemoryContextStats(TopMemoryContext);
#endif

        xact_started = false;
    }
}

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.")));
}

static void forbidden_in_wal_sender ( char  firstchar  )  [static]

Definition at line 4237 of file postgres.c.

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

Referenced by PostgresMain().

{
    if (am_walsender)
    {
        if (firstchar == 'F')
            ereport(ERROR,
                    (errcode(ERRCODE_PROTOCOL_VIOLATION),
                     errmsg("fastpath function calls not supported in a replication connection")));
        else
            ereport(ERROR,
                    (errcode(ERRCODE_PROTOCOL_VIOLATION),
                     errmsg("extended query protocol not supported in a replication connection")));
    }
}

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

static int interactive_getc ( void   )  [static]

Definition at line 318 of file postgres.c.

References client_read_ended(), and prepare_for_client_read().

Referenced by InteractiveBackend().

{
    int         c;

    prepare_for_client_read();
    c = getc(stdin);
    client_read_ended();
    return c;
}

static int InteractiveBackend ( StringInfo  inBuf  )  [static]

Definition at line 228 of file postgres.c.

References appendStringInfoChar(), StringInfoData::data, EchoQuery, end, interactive_getc(), StringInfoData::len, resetStringInfo(), and UseNewLine.

Referenced by ReadCommand().

{
    int         c;              /* character read from getc() */
    bool        end = false;    /* end-of-input flag */
    bool        backslashSeen = false;  /* have we seen a \ ? */

    /*
     * display a prompt and obtain input from the user
     */
    printf("backend> ");
    fflush(stdout);

    resetStringInfo(inBuf);

    if (UseNewLine)
    {
        /*
         * if we are using \n as a delimiter, then read characters until the
         * \n.
         */
        while ((c = interactive_getc()) != EOF)
        {
            if (c == '\n')
            {
                if (backslashSeen)
                {
                    /* discard backslash from inBuf */
                    inBuf->data[--inBuf->len] = '\0';
                    backslashSeen = false;
                    continue;
                }
                else
                {
                    /* keep the newline character */
                    appendStringInfoChar(inBuf, '\n');
                    break;
                }
            }
            else if (c == '\\')
                backslashSeen = true;
            else
                backslashSeen = false;

            appendStringInfoChar(inBuf, (char) c);
        }

        if (c == EOF)
            end = true;
    }
    else
    {
        /*
         * otherwise read characters until EOF.
         */
        while ((c = interactive_getc()) != EOF)
            appendStringInfoChar(inBuf, (char) c);

        /* No input before EOF signal means time to quit. */
        if (inBuf->len == 0)
            end = true;
    }

    if (end)
        return EOF;

    /*
     * otherwise we have a user query so process it.
     */

    /* Add '\0' to make it look the same as message case. */
    appendStringInfoChar(inBuf, (char) '\0');

    /*
     * if the query echo flag was given, print the query..
     */
    if (EchoQuery)
        printf("statement: %s\n", inBuf->data);
    fflush(stdout);

    return 'Q';
}

static bool IsTransactionExitStmt ( Node parsetree  )  [static]

Definition at line 2436 of file postgres.c.

References IsA, TransactionStmt::kind, TRANS_STMT_COMMIT, TRANS_STMT_PREPARE, TRANS_STMT_ROLLBACK, and TRANS_STMT_ROLLBACK_TO.

Referenced by exec_bind_message(), exec_parse_message(), exec_simple_query(), and IsTransactionExitStmtList().

{
    if (parsetree && IsA(parsetree, TransactionStmt))
    {
        TransactionStmt *stmt = (TransactionStmt *) parsetree;

        if (stmt->kind == TRANS_STMT_COMMIT ||
            stmt->kind == TRANS_STMT_PREPARE ||
            stmt->kind == TRANS_STMT_ROLLBACK ||
            stmt->kind == TRANS_STMT_ROLLBACK_TO)
            return true;
    }
    return false;
}

static bool IsTransactionExitStmtList ( List parseTrees  )  [static]

Definition at line 2453 of file postgres.c.

References CMD_UTILITY, Query::commandType, IsA, IsTransactionExitStmt(), linitial, list_length(), and Query::utilityStmt.

Referenced by exec_execute_message().

{
    if (list_length(parseTrees) == 1)
    {
        Node       *stmt = (Node *) linitial(parseTrees);

        if (IsA(stmt, Query))
        {
            Query      *query = (Query *) stmt;

            if (query->commandType == CMD_UTILITY &&
                IsTransactionExitStmt(query->utilityStmt))
                return true;
        }
        else if (IsTransactionExitStmt(stmt))
            return true;
    }
    return false;
}

static bool IsTransactionStmtList ( List parseTrees  )  [static]

Definition at line 2475 of file postgres.c.

References CMD_UTILITY, Query::commandType, IsA, linitial, list_length(), and Query::utilityStmt.

Referenced by exec_execute_message().

{
    if (list_length(parseTrees) == 1)
    {
        Node       *stmt = (Node *) linitial(parseTrees);

        if (IsA(stmt, Query))
        {
            Query      *query = (Query *) stmt;

            if (query->commandType == CMD_UTILITY &&
                IsA(query->utilityStmt, TransactionStmt))
                return true;
        }
        else if (IsA(stmt, TransactionStmt))
            return true;
    }
    return false;
}

static void log_disconnections ( int  code,
Datum  arg 
) [static]

Definition at line 4397 of file postgres.c.

References Port::database_name, ereport, errmsg(), GetCurrentTimestamp(), LOG, MyProcPort, port, Port::remote_host, Port::remote_port, Port::SessionStartTime, TimestampDifference(), and Port::user_name.

Referenced by PostgresMain().

{
    Port       *port = MyProcPort;
    long        secs;
    int         usecs;
    int         msecs;
    int         hours,
                minutes,
                seconds;

    TimestampDifference(port->SessionStartTime,
                        GetCurrentTimestamp(),
                        &secs, &usecs);
    msecs = usecs / 1000;

    hours = secs / SECS_PER_HOUR;
    secs %= SECS_PER_HOUR;
    minutes = secs / SECS_PER_MINUTE;
    seconds = secs % SECS_PER_MINUTE;

    ereport(LOG,
            (errmsg("disconnection: session time: %d:%02d:%02d.%03d "
                    "user=%s database=%s host=%s%s%s",
                    hours, minutes, seconds, msecs,
                    port->user_name, port->database_name, port->remote_host,
                  port->remote_port[0] ? " port=" : "", port->remote_port)));
}

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

static List * pg_rewrite_query ( Query query  )  [static]

Definition at line 684 of file postgres.c.

References CMD_UTILITY, Query::commandType, copyObject(), Debug_pretty_print, Debug_print_parse, Debug_print_rewritten, elog, elog_node_display(), equal(), list_make1, LOG, log_parser_stats, QueryRewrite(), ResetUsage(), ShowUsage(), and WARNING.

Referenced by exec_parse_message(), pg_analyze_and_rewrite(), and pg_analyze_and_rewrite_params().

{
    List       *querytree_list;

    if (Debug_print_parse)
        elog_node_display(LOG, "parse tree", query,
                          Debug_pretty_print);

    if (log_parser_stats)
        ResetUsage();

    if (query->commandType == CMD_UTILITY)
    {
        /* don't rewrite utilities, just dump 'em into result list */
        querytree_list = list_make1(query);
    }
    else
    {
        /* rewrite regular queries */
        querytree_list = QueryRewrite(query);
    }

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

#ifdef COPY_PARSE_PLAN_TREES
    /* Optional debugging check: pass querytree output through copyObject() */
    {
        List       *new_list;

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

    if (Debug_print_rewritten)
        elog_node_display(LOG, "rewritten parse tree", querytree_list,
                          Debug_pretty_print);

    return querytree_list;
}

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 ProcessInterrupts ( void   ) 

Definition at line 2816 of file postgres.c.

References Assert, ClientAuthInProgress, ClientConnectionLost, CritSectionCount, DestRemote, DisableCatchupInterrupt(), DisableNotifyInterrupt(), DoingCommandRead, ereport, errcode(), errdetail_recovery_conflict(), errhint(), errmsg(), ERROR, FATAL, get_timeout_indicator(), ImmediateInterruptOK, InterruptHoldoffCount, InterruptPending, IsAutoVacuumWorkerProcess(), LOCK_TIMEOUT, pgstat_report_recovery_conflict(), ProcDiePending, PROCSIG_RECOVERY_CONFLICT_DATABASE, QueryCancelPending, RecoveryConflictPending, RecoveryConflictReason, RecoveryConflictRetryable, STATEMENT_TIMEOUT, and whereToSendOutput.

{
    /* OK to accept interrupt now? */
    if (InterruptHoldoffCount != 0 || CritSectionCount != 0)
        return;
    InterruptPending = false;
    if (ProcDiePending)
    {
        ProcDiePending = false;
        QueryCancelPending = false;     /* ProcDie trumps QueryCancel */
        ImmediateInterruptOK = false;   /* not idle anymore */
        DisableNotifyInterrupt();
        DisableCatchupInterrupt();
        /* As in quickdie, don't risk sending to client during auth */
        if (ClientAuthInProgress && whereToSendOutput == DestRemote)
            whereToSendOutput = DestNone;
        if (IsAutoVacuumWorkerProcess())
            ereport(FATAL,
                    (errcode(ERRCODE_ADMIN_SHUTDOWN),
                     errmsg("terminating autovacuum process due to administrator command")));
        else if (RecoveryConflictPending && RecoveryConflictRetryable)
        {
            pgstat_report_recovery_conflict(RecoveryConflictReason);
            ereport(FATAL,
                    (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
              errmsg("terminating connection due to conflict with recovery"),
                     errdetail_recovery_conflict()));
        }
        else if (RecoveryConflictPending)
        {
            /* Currently there is only one non-retryable recovery conflict */
            Assert(RecoveryConflictReason == PROCSIG_RECOVERY_CONFLICT_DATABASE);
            pgstat_report_recovery_conflict(RecoveryConflictReason);
            ereport(FATAL,
                    (errcode(ERRCODE_DATABASE_DROPPED),
              errmsg("terminating connection due to conflict with recovery"),
                     errdetail_recovery_conflict()));
        }
        else
            ereport(FATAL,
                    (errcode(ERRCODE_ADMIN_SHUTDOWN),
             errmsg("terminating connection due to administrator command")));
    }
    if (ClientConnectionLost)
    {
        QueryCancelPending = false;     /* lost connection trumps QueryCancel */
        ImmediateInterruptOK = false;   /* not idle anymore */
        DisableNotifyInterrupt();
        DisableCatchupInterrupt();
        /* don't send to client, we already know the connection to be dead. */
        whereToSendOutput = DestNone;
        ereport(FATAL,
                (errcode(ERRCODE_CONNECTION_FAILURE),
                 errmsg("connection to client lost")));
    }
    if (QueryCancelPending)
    {
        QueryCancelPending = false;
        if (ClientAuthInProgress)
        {
            ImmediateInterruptOK = false;       /* not idle anymore */
            DisableNotifyInterrupt();
            DisableCatchupInterrupt();
            /* As in quickdie, don't risk sending to client during auth */
            if (whereToSendOutput == DestRemote)
                whereToSendOutput = DestNone;
            ereport(ERROR,
                    (errcode(ERRCODE_QUERY_CANCELED),
                     errmsg("canceling authentication due to timeout")));
        }

        /*
         * If LOCK_TIMEOUT and STATEMENT_TIMEOUT indicators are both set, we
         * prefer to report the former; but be sure to clear both.
         */
        if (get_timeout_indicator(LOCK_TIMEOUT, true))
        {
            ImmediateInterruptOK = false;       /* not idle anymore */
            (void) get_timeout_indicator(STATEMENT_TIMEOUT, true);
            DisableNotifyInterrupt();
            DisableCatchupInterrupt();
            ereport(ERROR,
                    (errcode(ERRCODE_QUERY_CANCELED),
                     errmsg("canceling statement due to lock timeout")));
        }
        if (get_timeout_indicator(STATEMENT_TIMEOUT, true))
        {
            ImmediateInterruptOK = false;       /* not idle anymore */
            DisableNotifyInterrupt();
            DisableCatchupInterrupt();
            ereport(ERROR,
                    (errcode(ERRCODE_QUERY_CANCELED),
                     errmsg("canceling statement due to statement timeout")));
        }
        if (IsAutoVacuumWorkerProcess())
        {
            ImmediateInterruptOK = false;       /* not idle anymore */
            DisableNotifyInterrupt();
            DisableCatchupInterrupt();
            ereport(ERROR,
                    (errcode(ERRCODE_QUERY_CANCELED),
                     errmsg("canceling autovacuum task")));
        }
        if (RecoveryConflictPending)
        {
            ImmediateInterruptOK = false;       /* not idle anymore */
            RecoveryConflictPending = false;
            DisableNotifyInterrupt();
            DisableCatchupInterrupt();
            pgstat_report_recovery_conflict(RecoveryConflictReason);
            if (DoingCommandRead)
                ereport(FATAL,
                        (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
                         errmsg("terminating connection due to conflict with recovery"),
                         errdetail_recovery_conflict(),
                 errhint("In a moment you should be able to reconnect to the"
                         " database and repeat your command.")));
            else
                ereport(ERROR,
                        (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
                 errmsg("canceling statement due to conflict with recovery"),
                         errdetail_recovery_conflict()));
        }

        /*
         * If we are reading a command from the client, just ignore the cancel
         * request --- sending an extra error message won't accomplish
         * anything.  Otherwise, go ahead and throw the error.
         */
        if (!DoingCommandRead)
        {
            ImmediateInterruptOK = false;       /* not idle anymore */
            DisableNotifyInterrupt();
            DisableCatchupInterrupt();
            ereport(ERROR,
                    (errcode(ERRCODE_QUERY_CANCELED),
                     errmsg("canceling statement due to user request")));
        }
    }
    /* If we get here, do nothing (probably, QueryCancelPending was reset) */
}

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

static int ReadCommand ( StringInfo  inBuf  )  [static]

Definition at line 487 of file postgres.c.

References DestRemote, InteractiveBackend(), SocketBackend(), and whereToSendOutput.

Referenced by PostgresMain().

{
    int         result;

    if (whereToSendOutput == DestRemote)
        result = SocketBackend(inBuf);
    else
        result = InteractiveBackend(inBuf);
    return result;
}

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 restore_stack_base ( pg_stack_base_t  base  ) 

Definition at line 3032 of file postgres.c.

References stack_base_ptr.

{
#if defined(__ia64__) || defined(__ia64)
    stack_base_ptr = base.stack_base_ptr;
    register_stack_base_ptr = base.register_stack_base_ptr;
#else
    stack_base_ptr = base;
#endif
}

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

pg_stack_base_t set_stack_base ( void   ) 

Definition at line 3001 of file postgres.c.

References stack_base_ptr.

Referenced by PostmasterMain().

{
    char        stack_base;
    pg_stack_base_t old;

#if defined(__ia64__) || defined(__ia64)
    old.stack_base_ptr = stack_base_ptr;
    old.register_stack_base_ptr = register_stack_base_ptr;
#else
    old = stack_base_ptr;
#endif

    /* Set up reference point for stack depth checking */
    stack_base_ptr = &stack_base;
#if defined(__ia64__) || defined(__ia64)
    register_stack_base_ptr = ia64_get_bsp();
#endif

    return old;
}

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

static void SigHupHandler ( SIGNAL_ARGS   )  [static]

Definition at line 2668 of file postgres.c.

References got_SIGHUP, MyProc, PGPROC::procLatch, and SetLatch().

Referenced by PostgresMain().

{
    int         save_errno = errno;

    got_SIGHUP = true;
    if (MyProc)
        SetLatch(&MyProc->procLatch);

    errno = save_errno;
}

static int SocketBackend ( StringInfo  inBuf  )  [static]

Definition at line 337 of file postgres.c.

References COMMERROR, DEBUG1, doing_extended_query_message, ereport, errcode(), errmsg(), FATAL, FrontendProtocol, ignore_till_sync, IsTransactionState(), PG_PROTOCOL_MAJOR, pq_getbyte(), pq_getmessage(), pq_getstring(), and whereToSendOutput.

Referenced by ReadCommand().

{
    int         qtype;

    /*
     * Get message type code from the frontend.
     */
    qtype = pq_getbyte();

    if (qtype == EOF)           /* frontend disconnected */
    {
        if (IsTransactionState())
            ereport(COMMERROR,
                    (errcode(ERRCODE_CONNECTION_FAILURE),
                     errmsg("unexpected EOF on client connection with an open transaction")));
        else
        {
            /*
             * Can't send DEBUG log messages to client at this point. Since
             * we're disconnecting right away, we don't need to restore
             * whereToSendOutput.
             */
            whereToSendOutput = DestNone;
            ereport(DEBUG1,
                    (errcode(ERRCODE_CONNECTION_DOES_NOT_EXIST),
                     errmsg("unexpected EOF on client connection")));
        }
        return qtype;
    }

    /*
     * Validate message type code before trying to read body; if we have lost
     * sync, better to say "command unknown" than to run out of memory because
     * we used garbage as a length word.
     *
     * This also gives us a place to set the doing_extended_query_message flag
     * as soon as possible.
     */
    switch (qtype)
    {
        case 'Q':               /* simple query */
            doing_extended_query_message = false;
            if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3)
            {
                /* old style without length word; convert */
                if (pq_getstring(inBuf))
                {
                    if (IsTransactionState())
                        ereport(COMMERROR,
                                (errcode(ERRCODE_CONNECTION_FAILURE),
                                 errmsg("unexpected EOF on client connection with an open transaction")));
                    else
                    {
                        /*
                         * Can't send DEBUG log messages to client at this
                         * point.Since we're disconnecting right away, we
                         * don't need to restore whereToSendOutput.
                         */
                        whereToSendOutput = DestNone;
                        ereport(DEBUG1,
                                (errcode(ERRCODE_CONNECTION_DOES_NOT_EXIST),
                             errmsg("unexpected EOF on client connection")));
                    }
                    return EOF;
                }
            }
            break;

        case 'F':               /* fastpath function call */
            /* we let fastpath.c cope with old-style input of this */
            doing_extended_query_message = false;
            break;

        case 'X':               /* terminate */
            doing_extended_query_message = false;
            ignore_till_sync = false;
            break;

        case 'B':               /* bind */
        case 'C':               /* close */
        case 'D':               /* describe */
        case 'E':               /* execute */
        case 'H':               /* flush */
        case 'P':               /* parse */
            doing_extended_query_message = true;
            /* these are only legal in protocol 3 */
            if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3)
                ereport(FATAL,
                        (errcode(ERRCODE_PROTOCOL_VIOLATION),
                         errmsg("invalid frontend message type %d", qtype)));
            break;

        case 'S':               /* sync */
            /* stop any active skip-till-Sync */
            ignore_till_sync = false;
            /* mark not-extended, so that a new error doesn't begin skip */
            doing_extended_query_message = false;
            /* only legal in protocol 3 */
            if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3)
                ereport(FATAL,
                        (errcode(ERRCODE_PROTOCOL_VIOLATION),
                         errmsg("invalid frontend message type %d", qtype)));
            break;

        case 'd':               /* copy data */
        case 'c':               /* copy done */
        case 'f':               /* copy fail */
            doing_extended_query_message = false;
            /* these are only legal in protocol 3 */
            if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3)
                ereport(FATAL,
                        (errcode(ERRCODE_PROTOCOL_VIOLATION),
                         errmsg("invalid frontend message type %d", qtype)));
            break;

        default:

            /*
             * Otherwise we got garbage from the frontend.  We treat this as
             * fatal because we have probably lost message boundary sync, and
             * there's no good way to recover.
             */
            ereport(FATAL,
                    (errcode(ERRCODE_PROTOCOL_VIOLATION),
                     errmsg("invalid frontend message type %d", qtype)));
            break;
    }

    /*
     * In protocol version 3, all frontend messages have a length word next
     * after the type code; we can read the message contents independently of
     * the type.
     */
    if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3)
    {
        if (pq_getmessage(inBuf, 0))
            return EOF;         /* suitable message already logged */
    }

    return qtype;
}

static void start_xact_command ( void   )  [static]
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

const char* debug_query_string

Definition at line 157 of file postgres.c.

Referenced by PostgresMain(), and SocketBackend().

bool DoingCommandRead = false [static]
bool EchoQuery = false [static]

Definition at line 170 of file postgres.c.

Referenced by InteractiveBackend(), and process_postgres_switches().

volatile sig_atomic_t got_SIGHUP = false [static]

Definition at line 138 of file postgres.c.

Referenced by PostgresMain(), and SigHupHandler().

bool ignore_till_sync = false [static]

Definition at line 158 of file postgres.c.

Referenced by PostgresMain(), and SocketBackend().

Definition at line 98 of file postgres.c.

Referenced by PostgresMain().

int log_statement = LOGSTMT_NONE

Definition at line 100 of file postgres.c.

Referenced by check_log_statement(), and HandleFunctionRequest().

int max_stack_depth = 100

Definition at line 103 of file postgres.c.

Referenced by check_stack_depth().

long max_stack_depth_bytes = 100 * 1024L [static]

Definition at line 116 of file postgres.c.

Referenced by assign_max_stack_depth(), and check_stack_depth().

char* optarg

Definition at line 51 of file getopt.c.

int optind

Definition at line 49 of file getopt.c.

int PostAuthDelay = 0
bool RecoveryConflictPending = false [static]

Definition at line 183 of file postgres.c.

Referenced by ProcessInterrupts(), and RecoveryConflictInterrupt().

Definition at line 184 of file postgres.c.

Referenced by ProcessInterrupts(), and RecoveryConflictInterrupt().

struct rusage Save_r [static]

Definition at line 4291 of file postgres.c.

Referenced by ResetUsage(), and ShowUsage().

struct timeval Save_t [static]

Definition at line 4292 of file postgres.c.

Referenced by ResetUsage(), and ShowUsage().

char* stack_base_ptr = NULL

Definition at line 124 of file postgres.c.

Referenced by check_stack_depth(), restore_stack_base(), and set_stack_base().

Definition at line 165 of file postgres.c.

int UseNewLine = 1 [static]

Definition at line 177 of file postgres.c.

Referenced by InteractiveBackend(), and process_postgres_switches().

const char* userDoption = NULL [static]
bool xact_started = false [static]

Definition at line 144 of file postgres.c.

Referenced by finish_xact_command(), PostgresMain(), and start_xact_command().