OSDN Git Service

Remove configure tests for `signed', `volatile', and signal handler args;
[pg-rex/syncrep.git] / src / backend / tcop / postgres.c
1 /*-------------------------------------------------------------------------
2  *
3  * postgres.c
4  *        POSTGRES C Backend Interface
5  *
6  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *        $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.172 2000/08/27 19:00:31 petere Exp $
12  *
13  * NOTES
14  *        this is the "main" module of the postgres backend and
15  *        hence the main module of the "traffic cop".
16  *
17  *-------------------------------------------------------------------------
18  */
19
20 #include "postgres.h"
21
22 #include <unistd.h>
23 #include <signal.h>
24 #include <time.h>
25 #include <sys/time.h>
26 #include <sys/types.h>
27 #include <fcntl.h>
28 #include <sys/socket.h>
29 #include <errno.h>
30 #if HAVE_SYS_SELECT_H
31 #include <sys/select.h>
32 #endif   /* aix */
33 #include <netinet/in.h>
34 #include <arpa/inet.h>
35 #include <netdb.h>
36 #ifdef HAVE_GETOPT_H
37 #include <getopt.h>
38 #endif
39
40 #include "commands/async.h"
41 #include "commands/trigger.h"
42 #include "commands/variable.h"
43 #include "libpq/libpq.h"
44 #include "libpq/pqformat.h"
45 #include "libpq/pqsignal.h"
46 #include "miscadmin.h"
47 #include "nodes/print.h"
48 #include "optimizer/cost.h"
49 #include "optimizer/planner.h"
50 #include "parser/parser.h"
51 #include "rewrite/rewriteHandler.h"
52 #include "tcop/fastpath.h"
53 #include "tcop/pquery.h"
54 #include "tcop/tcopprot.h"
55 #include "tcop/utility.h"
56 #include "storage/proc.h"
57 #include "utils/exc.h"
58 #include "utils/guc.h"
59 #include "utils/memutils.h"
60 #include "utils/ps_status.h"
61 #include "utils/temprel.h"
62 #ifdef MULTIBYTE
63 #include "mb/pg_wchar.h"
64 #endif
65
66
67 /* ----------------
68  *              global variables
69  * ----------------
70  */
71
72 /*
73  * XXX For ps display. That stuff needs to be cleaned up.
74  */
75 bool HostnameLookup;
76 bool ShowPortNumber;
77
78 bool Log_connections = false;
79
80 CommandDest whereToSendOutput = Debug;
81
82
83 extern void StartupXLOG(void);
84 extern void ShutdownXLOG(void);
85
86 extern void HandleDeadLock(int signum);
87
88 extern char XLogDir[];
89 extern char ControlFilePath[];
90
91 static bool     dontExecute = false;
92
93 static bool IsEmptyQuery = false;
94
95 /* note: these declarations had better match tcopprot.h */
96 DLLIMPORT sigjmp_buf Warn_restart;
97
98 bool            Warn_restart_ready = false;
99 bool            InError = false;
100 bool            ExitAfterAbort = false;
101
102 static bool EchoQuery = false;  /* default don't echo */
103 char            pg_pathname[MAXPGPATH];
104 FILE       *StatFp = NULL;
105
106 /* ----------------
107  *              people who want to use EOF should #define DONTUSENEWLINE in
108  *              tcop/tcopdebug.h
109  * ----------------
110  */
111 #ifndef TCOP_DONTUSENEWLINE
112 int                     UseNewLine = 1;         /* Use newlines query delimiters (the
113                                                                  * default) */
114
115 #else
116 int                     UseNewLine = 0;         /* Use EOF as query delimiters */
117
118 #endif   /* TCOP_DONTUSENEWLINE */
119
120 /*
121 ** Flags for expensive function optimization -- JMH 3/9/92
122 */
123 int                     XfuncMode = 0;
124
125 /* ----------------------------------------------------------------
126  *              decls for routines only used in this file
127  * ----------------------------------------------------------------
128  */
129 static int      InteractiveBackend(StringInfo inBuf);
130 static int      SocketBackend(StringInfo inBuf);
131 static int      ReadCommand(StringInfo inBuf);
132 static void SigHupHandler(int signum);
133 static void FloatExceptionHandler(int signum);
134 static void quickdie(int signum);
135
136 /*
137  * Flag to mark SIGHUP. Whenever the main loop comes around it
138  * will reread the configuration file. (Better than doing the
139  * reading in the signal handler, ey?)
140  */
141 static volatile bool got_SIGHUP = false;
142
143
144 /* ----------------------------------------------------------------
145  *              routines to obtain user input
146  * ----------------------------------------------------------------
147  */
148
149 /* ----------------
150  *      InteractiveBackend() is called for user interactive connections
151  *      the string entered by the user is placed in its parameter inBuf.
152  *
153  *      EOF is returned if end-of-file input is seen; time to shut down.
154  * ----------------
155  */
156
157 static int
158 InteractiveBackend(StringInfo inBuf)
159 {
160         int                     c;                              /* character read from getc() */
161         bool            end = false;    /* end-of-input flag */
162         bool            backslashSeen = false;  /* have we seen a \ ? */
163
164         /* ----------------
165          *      display a prompt and obtain input from the user
166          * ----------------
167          */
168         printf("backend> ");
169         fflush(stdout);
170
171         /* Reset inBuf to empty */
172         inBuf->len = 0;
173         inBuf->data[0] = '\0';
174
175         for (;;)
176         {
177                 if (UseNewLine)
178                 {
179                         /* ----------------
180                          *      if we are using \n as a delimiter, then read
181                          *      characters until the \n.
182                          * ----------------
183                          */
184                         while ((c = getc(stdin)) != EOF)
185                         {
186                                 if (c == '\n')
187                                 {
188                                         if (backslashSeen)
189                                         {
190                                                 /* discard backslash from inBuf */
191                                                 inBuf->data[--inBuf->len] = '\0';
192                                                 backslashSeen = false;
193                                                 continue;
194                                         }
195                                         else
196                                         {
197                                                 /* keep the newline character */
198                                                 appendStringInfoChar(inBuf, '\n');
199                                                 break;
200                                         }
201                                 }
202                                 else if (c == '\\')
203                                         backslashSeen = true;
204                                 else
205                                         backslashSeen = false;
206
207                                 appendStringInfoChar(inBuf, (char) c);
208                         }
209
210                         if (c == EOF)
211                                 end = true;
212                 }
213                 else
214                 {
215                         /* ----------------
216                          *      otherwise read characters until EOF.
217                          * ----------------
218                          */
219                         while ((c = getc(stdin)) != EOF)
220                                 appendStringInfoChar(inBuf, (char) c);
221
222                         if (inBuf->len == 0)
223                                 end = true;
224                 }
225
226                 if (end)
227                         return EOF;
228
229                 /* ----------------
230                  *      otherwise we have a user query so process it.
231                  * ----------------
232                  */
233                 break;
234         }
235
236         /* ----------------
237          *      if the query echo flag was given, print the query..
238          * ----------------
239          */
240         if (EchoQuery)
241                 printf("query: %s\n", inBuf->data);
242         fflush(stdout);
243
244         return 'Q';
245 }
246
247 /* ----------------
248  *      SocketBackend()         Is called for frontend-backend connections
249  *
250  *      If the input is a query (case 'Q') then the string entered by
251  *      the user is placed in its parameter inBuf.
252  *
253  *      If the input is a fastpath function call (case 'F') then
254  *      the function call is processed in HandleFunctionRequest()
255  *      (now called from PostgresMain()).
256  *
257  *      EOF is returned if the connection is lost.
258  * ----------------
259  */
260
261 static int
262 SocketBackend(StringInfo inBuf)
263 {
264         char            qtype;
265         char            result = '\0';
266
267         /* ----------------
268          *      get input from the frontend
269          * ----------------
270          */
271         qtype = '?';
272         if (pq_getbytes(&qtype, 1) == EOF)
273                 return EOF;
274
275         switch (qtype)
276         {
277                         /* ----------------
278                          *      'Q': user entered a query
279                          * ----------------
280                          */
281                 case 'Q':
282                         if (pq_getstr(inBuf))
283                                 return EOF;
284                         result = 'Q';
285                         break;
286
287                         /* ----------------
288                          *      'F':  calling user/system functions
289                          * ----------------
290                          */
291                 case 'F':
292                         if (pq_getstr(inBuf))
293                                 return EOF;             /* ignore "string" at start of F message */
294                         result = 'F';
295                         break;
296
297                         /* ----------------
298                          *      'X':  frontend is exiting
299                          * ----------------
300                          */
301                 case 'X':
302                         result = 'X';
303                         break;
304
305                         /* ----------------
306                          *      otherwise we got garbage from the frontend.
307                          *
308                          *      XXX are we certain that we want to do an elog(FATAL) here?
309                          *              -cim 1/24/90
310                          * ----------------
311                          */
312                 default:
313                         elog(FATAL, "Socket command type %c unknown", qtype);
314                         break;
315         }
316         return result;
317 }
318
319 /* ----------------
320  *              ReadCommand reads a command from either the frontend or
321  *              standard input, places it in inBuf, and returns a char
322  *              representing whether the string is a 'Q'uery or a 'F'astpath
323  *              call.  EOF is returned if end of file.
324  * ----------------
325  */
326 static int
327 ReadCommand(StringInfo inBuf)
328 {
329         int                     result;
330
331         if (IsUnderPostmaster)
332                 result = SocketBackend(inBuf);
333         else
334                 result = InteractiveBackend(inBuf);
335         return result;
336 }
337
338
339 /*
340  * Parse a query string and pass it through the rewriter.
341  *
342  * A list of Query nodes is returned, since the string might contain
343  * multiple queries and/or the rewriter might expand one query to several.
344  */
345 List *
346 pg_parse_and_rewrite(char *query_string,        /* string to execute */
347                                          Oid *typev,                    /* parameter types */
348                                          int nargs)                             /* number of parameters */
349 {
350         List       *querytree_list;
351         List       *querytree_list_item;
352         Query      *querytree;
353         List       *new_list;
354
355         if (Debug_print_query)
356                 elog(DEBUG, "query: %s", query_string);
357
358         /* ----------------
359          *      (1) parse the request string into a list of parse trees
360          * ----------------
361          */
362         if (Show_parser_stats)
363                 ResetUsage();
364
365         querytree_list = parser(query_string, typev, nargs);
366
367         if (Show_parser_stats)
368         {
369                 fprintf(StatFp, "PARSER STATISTICS\n");
370                 ShowUsage();
371         }
372
373         /* ----------------
374          *      (2) rewrite the queries, as necessary
375          *
376          *      rewritten queries are collected in new_list.  Note there may be
377          *      more or fewer than in the original list.
378          * ----------------
379          */
380         new_list = NIL;
381         foreach(querytree_list_item, querytree_list)
382         {
383                 querytree = (Query *) lfirst(querytree_list_item);
384
385                 if (Debug_print_parse)
386                 {
387                         if (Debug_pretty_print)
388                         {
389                                 elog(DEBUG, "parse tree:");
390                                 nodeDisplay(querytree);
391                         }
392                         else
393                                 elog(DEBUG, "parse tree: %s", nodeToString(querytree));
394                 }
395
396                 if (querytree->commandType == CMD_UTILITY)
397                 {
398                         /* don't rewrite utilities, just dump 'em into new_list */
399                         new_list = lappend(new_list, querytree);
400                 }
401                 else
402                 {
403                         /* rewrite regular queries */
404                         List       *rewritten = QueryRewrite(querytree);
405
406                         new_list = nconc(new_list, rewritten);
407                 }
408         }
409
410         querytree_list = new_list;
411
412 #ifdef COPY_PARSE_PLAN_TREES
413         /* Optional debugging check: pass parsetree output through copyObject() */
414         /*
415          * Note: we run this test after rewrite, not before, because copyObject()
416          * does not handle most kinds of nodes that are used only in raw parse
417          * trees.  The present (bizarre) implementation of UNION/INTERSECT/EXCEPT
418          * doesn't run analysis of the second and later subqueries until rewrite,
419          * so we'd get false failures on these queries if we did it beforehand.
420          */
421         new_list = (List *) copyObject(querytree_list);
422         /* This checks both copyObject() and the equal() routines... */
423         if (! equal(new_list, querytree_list))
424                 elog(NOTICE, "pg_parse_and_rewrite: copyObject failed on parse tree");
425         else
426                 querytree_list = new_list;
427 #endif
428
429         if (Debug_print_rewritten)
430         {
431                 if (Debug_pretty_print)
432                 {
433                         elog(DEBUG, "rewritten parse tree:");
434                         foreach(querytree_list_item, querytree_list)
435                         {
436                                 querytree = (Query *) lfirst(querytree_list_item);
437                                 nodeDisplay(querytree);
438                                 printf("\n");
439                         }
440                 }
441                 else
442                 {
443                         elog(DEBUG, "rewritten parse tree:");
444
445                         foreach(querytree_list_item, querytree_list)
446                         {
447                                 querytree = (Query *) lfirst(querytree_list_item);
448                                 elog(DEBUG, "%s", nodeToString(querytree));
449                         }
450                 }
451         }
452
453         return querytree_list;
454 }
455
456
457 /* Generate a plan for a single query. */
458 Plan *
459 pg_plan_query(Query *querytree)
460 {
461         Plan       *plan;
462
463         /* Utility commands have no plans. */
464         if (querytree->commandType == CMD_UTILITY)
465                 return NULL;
466
467         if (Show_planner_stats)
468                 ResetUsage();
469
470         /* call that optimizer */
471         plan = planner(querytree);
472
473         if (Show_planner_stats)
474         {
475                 fprintf(stderr, "PLANNER STATISTICS\n");
476                 ShowUsage();
477         }
478
479 #ifdef COPY_PARSE_PLAN_TREES
480         /* Optional debugging check: pass plan output through copyObject() */
481         {
482                 Plan   *new_plan = (Plan *) copyObject(plan);
483
484                 /* equal() currently does not have routines to compare Plan nodes,
485                  * so don't try to test equality here.  Perhaps fix someday?
486                  */
487 #ifdef NOT_USED
488                 /* This checks both copyObject() and the equal() routines... */
489                 if (! equal(new_plan, plan))
490                         elog(NOTICE, "pg_plan_query: copyObject failed on plan tree");
491                 else
492 #endif
493                         plan = new_plan;
494         }
495 #endif
496
497         /* ----------------
498          *      Print plan if debugging.
499          * ----------------
500          */
501         if (Debug_print_plan)
502         {
503                 if (Debug_pretty_print)
504                 {
505                         elog(DEBUG, "plan:");
506                         nodeDisplay(plan);
507                 }
508                 else
509                         elog(DEBUG, "plan: %s", nodeToString(plan));
510         }
511
512         return plan;
513 }
514
515
516 /* ----------------------------------------------------------------
517  *              pg_exec_query_dest()
518  *
519  *              Takes a querystring, runs the parser/utilities or
520  *              parser/planner/executor over it as necessary.
521  *
522  * Assumptions:
523  *
524  * Caller is responsible for calling StartTransactionCommand() beforehand
525  * and CommitTransactionCommand() afterwards (if successful).
526  *
527  * The CurrentMemoryContext at entry references a context that is
528  * appropriate for execution of individual queries (typically this will be
529  * TransactionCommandContext).  Note that this routine resets that context
530  * after each individual query, so don't store anything there that
531  * must outlive the call!
532  *
533  * parse_context references a context suitable for holding the
534  * parse/rewrite trees (typically this will be QueryContext).
535  * This context *must* be longer-lived than the CurrentMemoryContext!
536  * In fact, if the query string might contain BEGIN/COMMIT commands,
537  * parse_context had better outlive TopTransactionContext!
538  *
539  * We could have hard-wired knowledge about QueryContext and
540  * TransactionCommandContext into this routine, but it seems better
541  * not to, in case callers from outside this module need to use some
542  * other contexts.
543  *
544  * ----------------------------------------------------------------
545  */
546
547 void
548 pg_exec_query_dest(char *query_string,  /* string to execute */
549                                    CommandDest dest,    /* where results should go */
550                                    MemoryContext parse_context) /* context for parsetrees */
551 {
552         MemoryContext oldcontext;
553         List       *querytree_list,
554                            *querytree_item;
555
556         /*
557          * If you called this routine with parse_context = CurrentMemoryContext,
558          * you blew it.  They *must* be different, else the context reset
559          * at the bottom of the loop will destroy the querytree list.
560          * (We really ought to check that parse_context isn't a child of
561          * CurrentMemoryContext either, but that would take more cycles than
562          * it's likely to be worth.)
563          */
564         Assert(parse_context != CurrentMemoryContext);
565
566         /*
567          * Switch to appropriate context for constructing parsetrees.
568          */
569         oldcontext = MemoryContextSwitchTo(parse_context);
570
571         /*
572          * Parse and rewrite the query or queries.
573          */
574         querytree_list = pg_parse_and_rewrite(query_string, NULL, 0);
575
576         /*
577          * Switch back to execution context for planning and execution.
578          */
579         MemoryContextSwitchTo(oldcontext);
580
581         /*
582          * Run through the query or queries and execute each one.
583          */
584         foreach(querytree_item, querytree_list)
585         {
586                 Query      *querytree = (Query *) lfirst(querytree_item);
587
588                 /* if we got a cancel signal in parsing or prior command, quit */
589                 if (QueryCancel)
590                         CancelQuery();
591
592                 if (querytree->commandType == CMD_UTILITY)
593                 {
594                         /* ----------------
595                          *       process utility functions (create, destroy, etc..)
596                          *
597                          *       Note: we do not check for the transaction aborted state
598                          *       because that is done in ProcessUtility.
599                          * ----------------
600                          */
601                         if (Debug_print_query)
602                                 elog(DEBUG, "ProcessUtility: %s", query_string);
603                         else if (DebugLvl > 1)
604                                 elog(DEBUG, "ProcessUtility");
605
606                         ProcessUtility(querytree->utilityStmt, dest);
607                 }
608                 else
609                 {
610                         Plan       *plan;
611
612                         /* If aborted transaction, skip planning and execution */
613                         if (IsAbortedTransactionBlockState())
614                         {
615                                 /* ----------------
616                                  *       the EndCommand() stuff is to tell the frontend
617                                  *       that the command ended. -cim 6/1/90
618                                  * ----------------
619                                  */
620                                 char       *tag = "*ABORT STATE*";
621
622                                 elog(NOTICE, "current transaction is aborted, "
623                                          "queries ignored until end of transaction block");
624
625                                 EndCommand(tag, dest);
626
627                                 /*
628                                  * We continue in the loop, on the off chance that there
629                                  * is a COMMIT or ROLLBACK utility command later in the
630                                  * query string.
631                                  */
632                                 continue;
633                         }
634
635                         plan = pg_plan_query(querytree);
636
637                         /* if we got a cancel signal whilst planning, quit */
638                         if (QueryCancel)
639                                 CancelQuery();
640
641                         /* Initialize snapshot state for query */
642                         SetQuerySnapshot();
643
644                         /*
645                          * execute the plan
646                          */
647                         if (Show_executor_stats)
648                                 ResetUsage();
649
650                         if (dontExecute)
651                         {
652                                 /* don't execute it, just show the query plan */
653                                 print_plan(plan, querytree);
654                         }
655                         else
656                         {
657                                 if (DebugLvl > 1)
658                                         elog(DEBUG, "ProcessQuery");
659                                 ProcessQuery(querytree, plan, dest);
660                         }
661
662                         if (Show_executor_stats)
663                         {
664                                 fprintf(stderr, "EXECUTOR STATISTICS\n");
665                                 ShowUsage();
666                         }
667                 }
668
669                 /*
670                  * In a query block, we want to increment the command counter
671                  * between queries so that the effects of early queries are
672                  * visible to subsequent ones.
673                  */
674                 CommandCounterIncrement();
675                 /*
676                  * Also, clear the execution context to recover temporary
677                  * memory used by the query.  NOTE: if query string contains
678                  * BEGIN/COMMIT transaction commands, execution context may
679                  * now be different from what we were originally passed;
680                  * so be careful to clear current context not "oldcontext".
681                  */
682                 MemoryContextResetAndDeleteChildren(CurrentMemoryContext);
683         }
684 }
685
686 /* --------------------------------
687  *              signal handler routines used in PostgresMain()
688  *
689  *              handle_warn() catches SIGQUIT.  It forces control back to the main
690  *              loop, just as if an internal error (elog(ERROR,...)) had occurred.
691  *              elog() used to actually use kill(2) to induce a SIGQUIT to get here!
692  *              But that's not 100% reliable on some systems, so now it does its own
693  *              siglongjmp() instead.
694  *              We still provide the signal catcher so that an error quit can be
695  *              forced externally.      This should be done only with great caution,
696  *              however, since an asynchronous signal could leave the system in
697  *              who-knows-what inconsistent state.
698  *
699  *              quickdie() occurs when signalled by the postmaster.
700  *              Some backend has bought the farm,
701  *              so we need to stop what we're doing and exit.
702  *
703  *              die() performs an orderly cleanup via proc_exit()
704  * --------------------------------
705  */
706
707 void
708 handle_warn(int signum)
709 {
710         siglongjmp(Warn_restart, 1);
711 }
712
713 static void
714 quickdie(int signum)
715 {
716         PG_SETMASK(&BlockSig);
717         elog(NOTICE, "Message from PostgreSQL backend:"
718                  "\n\tThe Postmaster has informed me that some other backend"
719                  " died abnormally and possibly corrupted shared memory."
720                  "\n\tI have rolled back the current transaction and am"
721                  " going to terminate your database system connection and exit."
722         "\n\tPlease reconnect to the database system and repeat your query.");
723
724
725         /*
726          * DO NOT proc_exit(0) -- we're here because shared memory may be
727          * corrupted, so we don't want to flush any shared state to stable
728          * storage.  Just nail the windows shut and get out of town.
729          */
730
731         exit(1);
732 }
733
734 /*
735  * Abort transaction and exit
736  */
737 void
738 die(int signum)
739 {
740         PG_SETMASK(&BlockSig);
741
742         /*
743          * If ERROR/FATAL is in progress...
744          */
745         if (InError)
746         {
747                 ExitAfterAbort = true;
748                 return;
749         }
750         elog(FATAL, "The system is shutting down");
751 }
752
753 /* signal handler for floating point exception */
754 static void
755 FloatExceptionHandler(int signum)
756 {
757         elog(ERROR, "floating point exception!"
758                  " The last floating point operation either exceeded legal ranges"
759                  " or was a divide by zero");
760 }
761
762 /* signal handler for query cancel signal from postmaster */
763 static void
764 QueryCancelHandler(int signum)
765 {
766         QueryCancel = true;
767         LockWaitCancel();
768 }
769
770 void
771 CancelQuery(void)
772 {
773
774         /*
775          * QueryCancel flag will be reset in main loop, which we reach by
776          * longjmp from elog().
777          */
778         elog(ERROR, "Query was cancelled.");
779 }
780
781 static void
782 SigHupHandler(int signum)
783 {
784         got_SIGHUP = true;
785 }
786
787
788 static void
789 usage(char *progname)
790 {
791         fprintf(stderr,
792                         "Usage: %s [options] [dbname]\n", progname);
793 #ifdef USE_ASSERT_CHECKING
794         fprintf(stderr, "\t-A on\t\tenable/disable assert checking\n");
795 #endif
796         fprintf(stderr, "\t-B buffers\tset number of buffers in buffer pool\n");
797         fprintf(stderr, "\t-C \t\tsuppress version info\n");
798         fprintf(stderr, "\t-D dir\t\tdata directory\n");
799         fprintf(stderr, "\t-E \t\techo query before execution\n");
800         fprintf(stderr, "\t-F \t\tturn fsync off\n");
801         fprintf(stderr, "\t-L \t\tturn off locking\n");
802         fprintf(stderr, "\t-N \t\tdon't use newline as interactive query delimiter\n");
803         fprintf(stderr, "\t-O \t\tallow system table structure changes\n");
804         fprintf(stderr, "\t-Q \t\tsuppress informational messages\n");
805         fprintf(stderr, "\t-S kbytes\tset amount of memory for sorts (in kbytes)\n");
806         fprintf(stderr, "\t-T options\tspecify pg_options\n");
807         fprintf(stderr, "\t-W sec\t\twait N seconds to allow attach from a debugger\n");
808         fprintf(stderr, "\t-d [1-5]\tset debug level\n");
809         fprintf(stderr, "\t-e \t\tturn on European date format\n");
810         fprintf(stderr, "\t-f [s|i|n|m|h]\tforbid use of some plan types\n");
811         fprintf(stderr, "\t-i \t\tdon't execute queries\n");
812         fprintf(stderr, "\t-o file\t\tsend stdout and stderr to given filename\n");
813         fprintf(stderr, "\t-p database\tbackend is started under a postmaster\n");
814         fprintf(stderr, "\t-s \t\tshow stats after each query\n");
815         fprintf(stderr, "\t-t [pa|pl|ex]\tshow timings after each query\n");
816         fprintf(stderr, "\t-v version\tset protocol version being used by frontend\n");
817 }
818
819 /* ----------------------------------------------------------------
820  *      PostgresMain
821  *              postgres main loop
822  *              all backends, interactive or otherwise start here
823  *
824  *      argc/argv are the command line arguments to be used.  When being forked
825  *      by the postmaster, these are not the original argv array of the process.
826  *      real_argc/real_argv point to the original argv array, which is needed by
827  *      PS_INIT_STATUS on some platforms.
828  * ----------------------------------------------------------------
829  */
830 int
831 PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
832 {
833         int                     flag;
834
835         char       *DBName = NULL;
836         bool            secure = true;
837         int                     errs = 0;
838
839         int                     firstchar;
840         StringInfo      parser_input;
841         char       *userName;
842
843         char       *remote_host;
844         unsigned short remote_port;
845
846         extern int      optind;
847         extern char *optarg;
848         extern int      DebugLvl;
849
850         /*
851          * Fire up essential subsystems: error and memory management
852          *
853          * If we are running under the postmaster, this is done already.
854          */
855         if (!IsUnderPostmaster)
856         {
857                 EnableExceptionHandling(true);
858                 MemoryContextInit();
859         }
860
861         /*
862          * Set default values for command-line options.
863          */
864         Noversion = false;
865         EchoQuery = false;
866
867         if (!IsUnderPostmaster)
868         {
869                 ResetAllOptions();
870                 if (getenv("PGDATA"))
871                         DataDir = strdup(getenv("PGDATA"));
872         }
873         StatFp = stderr;
874
875         SetProcessingMode(InitProcessing);
876
877         /* Check for PGDATESTYLE environment variable */
878         set_default_datestyle();
879
880         /* ----------------
881          *      parse command line arguments
882          *
883          *      There are now two styles of command line layout for the backend:
884          *
885          *      For interactive use (not started from postmaster) the format is
886          *              postgres [switches] [databasename]
887          *      If the databasename is omitted it is taken to be the user name.
888          *
889          *      When started from the postmaster, the format is
890          *              postgres [secure switches] -p databasename [insecure switches]
891          *      Switches appearing after -p came from the client (via "options"
892          *      field of connection request).  For security reasons we restrict
893          *      what these switches can do.
894          * ----------------
895          */
896
897         optind = 1;                                     /* reset after postmaster's usage */
898
899         while ((flag = getopt(argc, argv,  "A:B:CD:d:Eef:FiLNOPo:p:S:st:v:W:x:-:")) != EOF)
900                 switch (flag)
901                 {
902                         case 'A':
903 #ifdef USE_ASSERT_CHECKING
904                                 assert_enabled = atoi(optarg);
905 #else
906                                 fprintf(stderr, "Assert checking is not compiled in\n");
907 #endif
908                                 break;
909
910                         case 'B':
911                                 /* ----------------
912                                  *      specify the size of buffer pool
913                                  * ----------------
914                                  */
915                                 if (secure)
916                                         NBuffers = atoi(optarg);
917                                 break;
918
919                         case 'C':
920                                 /* ----------------
921                                  *      don't print version string
922                                  * ----------------
923                                  */
924                                 Noversion = true;
925                                 break;
926
927                         case 'D':                       /* PGDATA directory */
928                                 if (secure)
929                                 {
930                                         if (DataDir)
931                                                 free(DataDir);
932                                         DataDir = strdup(optarg);
933                                 }
934                                 break;
935
936                         case 'd':                       /* debug level */
937                                 DebugLvl = atoi(optarg);
938                                 if (DebugLvl >= 1);
939                                         Log_connections = true;
940                                 if (DebugLvl >= 2)
941                                         Debug_print_query = true;
942                                 if (DebugLvl >= 3)
943                                         Debug_print_parse = true;
944                                 if (DebugLvl >= 4)
945                                         Debug_print_plan = true;
946                                 if (DebugLvl >= 5)
947                                         Debug_print_rewritten = true;
948                                 break;
949
950                         case 'E':
951                                 /* ----------------
952                                  *      E - echo the query the user entered
953                                  * ----------------
954                                  */
955                                 EchoQuery = true;
956                                 break;
957
958                         case 'e':
959                                 /* --------------------------
960                                  * Use european date formats.
961                                  * --------------------------
962                                  */
963                                 EuroDates = true;
964                                 break;
965
966                         case 'F':
967                                 /* --------------------
968                                  *      turn off fsync
969                                  *
970                                  *      7.0 buffer manager can support different backends running
971                                  *      with different fsync settings, so this no longer needs
972                                  *      to be "if (secure)".
973                                  * --------------------
974                                  */
975                                 enableFsync = false;
976                                 break;
977
978                         case 'f':
979                                 /* -----------------
980                                  *        f - forbid generation of certain plans
981                                  * -----------------
982                                  */
983                                 switch (optarg[0])
984                                 {
985                                         case 's':       /* seqscan */
986                                                 enable_seqscan = false;
987                                                 break;
988                                         case 'i':       /* indexscan */
989                                                 enable_indexscan = false;
990                                                 break;
991                                         case 't':       /* tidscan */
992                                                 enable_tidscan = false;
993                                                 break;
994                                         case 'n':       /* nestloop */
995                                                 enable_nestloop = false;
996                                                 break;
997                                         case 'm':       /* mergejoin */
998                                                 enable_mergejoin = false;
999                                                 break;
1000                                         case 'h':       /* hashjoin */
1001                                                 enable_hashjoin = false;
1002                                                 break;
1003                                         default:
1004                                                 errs++;
1005                                 }
1006                                 break;
1007
1008                         case 'i':
1009                                 dontExecute = true;
1010                                 break;
1011
1012                         case 'L':
1013                                 /* --------------------
1014                                  *      turn off locking
1015                                  * --------------------
1016                                  */
1017                                 if (secure)
1018                                         lockingOff = 1;
1019                                 break;
1020
1021                         case 'N':
1022                                 /* ----------------
1023                                  *      N - Don't use newline as a query delimiter
1024                                  * ----------------
1025                                  */
1026                                 UseNewLine = 0;
1027                                 break;
1028
1029                         case 'O':
1030                                 /* --------------------
1031                                  *      allow system table structure modifications
1032                                  * --------------------
1033                                  */
1034                                 if (secure)             /* XXX safe to allow from client??? */
1035                                         allowSystemTableMods = true;
1036                                 break;
1037
1038                         case 'P':
1039                                 /* --------------------
1040                                  *      ignore system indexes
1041                                  * --------------------
1042                                  */
1043                                 if (secure)             /* XXX safe to allow from client??? */
1044                                         IgnoreSystemIndexes(true);
1045                                 break;
1046
1047                         case 'o':
1048                                 /* ----------------
1049                                  *      o - send output (stdout and stderr) to the given file
1050                                  * ----------------
1051                                  */
1052                                 if (secure)
1053                                         StrNCpy(OutputFileName, optarg, MAXPGPATH);
1054                                 break;
1055
1056                         case 'p':
1057                                 /* ----------------
1058                                  *      p - special flag passed if backend was forked
1059                                  *              by a postmaster.
1060                                  * ----------------
1061                                  */
1062                                 if (secure)
1063                                 {
1064                                         DBName = strdup(optarg);
1065                                         secure = false;         /* subsequent switches are NOT
1066                                                                                  * secure */
1067                                 }
1068                                 break;
1069
1070                         case 'S':
1071                                 /* ----------------
1072                                  *      S - amount of sort memory to use in 1k bytes
1073                                  * ----------------
1074                                  */
1075                                 {
1076                                         int                     S;
1077
1078                                         S = atoi(optarg);
1079                                         if (S >= 4 * BLCKSZ / 1024)
1080                                                 SortMem = S;
1081                                 }
1082                                 break;
1083
1084                         case 's':
1085                                 /* ----------------
1086                                  *        s - report usage statistics (timings) after each query
1087                                  * ----------------
1088                                  */
1089                                 Show_query_stats = 1;
1090                                 break;
1091
1092                         case 't':
1093                                 /* ----------------
1094                                  *      tell postgres to report usage statistics (timings) for
1095                                  *      each query
1096                                  *
1097                                  *      -tpa[rser] = print stats for parser time of each query
1098                                  *      -tpl[anner] = print stats for planner time of each query
1099                                  *      -te[xecutor] = print stats for executor time of each query
1100                                  *      caution: -s can not be used together with -t.
1101                                  * ----------------
1102                                  */
1103                                 switch (optarg[0])
1104                                 {
1105                                         case 'p':
1106                                                 if (optarg[1] == 'a')
1107                                                         Show_parser_stats = 1;
1108                                                 else if (optarg[1] == 'l')
1109                                                         Show_planner_stats = 1;
1110                                                 else
1111                                                         errs++;
1112                                                 break;
1113                                         case 'e':
1114                                                 Show_executor_stats = 1;
1115                                                 break;
1116                                         default:
1117                                                 errs++;
1118                                                 break;
1119                                 }
1120                                 break;
1121
1122                         case 'v':
1123                                 if (secure)
1124                                         FrontendProtocol = (ProtocolVersion) atoi(optarg);
1125                                 break;
1126
1127                         case 'W':
1128                                 /* ----------------
1129                                  *      wait N seconds to allow attach from a debugger
1130                                  * ----------------
1131                                  */
1132                                 sleep(atoi(optarg));
1133                                 break;
1134
1135                         case 'x':
1136 #ifdef NOT_USED                                 /* planner/xfunc.h */
1137
1138                                 /*
1139                                  * control joey hellerstein's expensive function
1140                                  * optimization
1141                                  */
1142                                 if (XfuncMode != 0)
1143                                 {
1144                                         fprintf(stderr, "only one -x flag is allowed\n");
1145                                         errs++;
1146                                         break;
1147                                 }
1148                                 if (strcmp(optarg, "off") == 0)
1149                                         XfuncMode = XFUNC_OFF;
1150                                 else if (strcmp(optarg, "nor") == 0)
1151                                         XfuncMode = XFUNC_NOR;
1152                                 else if (strcmp(optarg, "nopull") == 0)
1153                                         XfuncMode = XFUNC_NOPULL;
1154                                 else if (strcmp(optarg, "nopm") == 0)
1155                                         XfuncMode = XFUNC_NOPM;
1156                                 else if (strcmp(optarg, "pullall") == 0)
1157                                         XfuncMode = XFUNC_PULLALL;
1158                                 else if (strcmp(optarg, "wait") == 0)
1159                                         XfuncMode = XFUNC_WAIT;
1160                                 else
1161                                 {
1162                                         fprintf(stderr, "use -x {off,nor,nopull,nopm,pullall,wait}\n");
1163                                         errs++;
1164                                 }
1165 #endif
1166                                 break;
1167
1168                         case '-':
1169                         {
1170                                 char *name, *value;
1171
1172                                 ParseLongOption(optarg, &name, &value);
1173                                 if (!value)
1174                                         elog(ERROR, "--%s requires argument", optarg);
1175
1176                                 SetConfigOption(name, value, PGC_BACKEND);
1177                                 free(name);
1178                                 if (value)
1179                                         free(value);
1180                                 break;
1181                         }
1182
1183                         default:
1184                                 /* ----------------
1185                                  *      default: bad command line option
1186                                  * ----------------
1187                                  */
1188                                 errs++;
1189                                 break;
1190                 }
1191
1192         if (Show_query_stats &&
1193                 (Show_parser_stats || Show_planner_stats || Show_executor_stats))
1194         {
1195                 elog(NOTICE, "Query statistics are disabled because parser, planner, or executor statistics are on.");
1196                 Show_query_stats = false;
1197         }
1198
1199         if (!DataDir)
1200         {
1201                 fprintf(stderr, "%s does not know where to find the database system "
1202                                 "data.  You must specify the directory that contains the "
1203                                 "database system either by specifying the -D invocation "
1204                          "option or by setting the PGDATA environment variable.\n\n",
1205                                 argv[0]);
1206                 proc_exit(1);
1207         }
1208
1209         /*
1210          * 1. Set BlockSig and UnBlockSig masks. 2. Set up signal handlers. 3.
1211          * Allow only SIGUSR1 signal (we never block it) during
1212          * initialization.
1213          *
1214          * Note that postmaster already blocked ALL signals to make us happy.
1215          */
1216         pqinitmask();
1217
1218 #ifdef HAVE_SIGPROCMASK
1219         sigdelset(&BlockSig, SIGUSR1);
1220 #else
1221         BlockSig &= ~(sigmask(SIGUSR1));
1222 #endif
1223
1224         PG_SETMASK(&BlockSig);          /* block everything except SIGUSR1 */
1225
1226         pqsignal(SIGHUP, SigHupHandler);        /* set flag to read config file */
1227         pqsignal(SIGINT, QueryCancelHandler);           /* cancel current query */
1228         pqsignal(SIGQUIT, handle_warn);         /* handle error */
1229         pqsignal(SIGTERM, die);
1230         pqsignal(SIGALRM, HandleDeadLock);
1231
1232         /*
1233          * Ignore failure to write to frontend. Note: if frontend closes
1234          * connection, we will notice it and exit cleanly when control next
1235          * returns to outer loop.  This seems safer than forcing exit in the
1236          * midst of output during who-knows-what operation...
1237          */
1238         pqsignal(SIGPIPE, SIG_IGN);
1239         pqsignal(SIGUSR1, quickdie);
1240         pqsignal(SIGUSR2, Async_NotifyHandler);         /* flush also sinval cache */
1241         pqsignal(SIGFPE, FloatExceptionHandler);
1242         pqsignal(SIGCHLD, SIG_IGN); /* ignored, sent by LockOwners */
1243         pqsignal(SIGTTIN, SIG_DFL);
1244         pqsignal(SIGTTOU, SIG_DFL);
1245         pqsignal(SIGCONT, SIG_DFL);
1246
1247         /*
1248          * Get user name (needed now in case it is the default database name)
1249          * and check command line validity
1250          */
1251         SetPgUserName();
1252         userName = GetPgUserName();
1253
1254         if (IsUnderPostmaster)
1255         {
1256                 /* noninteractive case: nothing should be left after switches */
1257                 if (errs || argc != optind || DBName == NULL)
1258                 {
1259                         usage(argv[0]);
1260                         proc_exit(0);
1261                 }
1262                 pq_init();                              /* initialize libpq at backend startup */
1263                 whereToSendOutput = Remote;
1264                 BaseInit();
1265         }
1266         else
1267         {
1268                 /* interactive case: database name can be last arg on command line */
1269                 whereToSendOutput = Debug;
1270                 if (errs || argc - optind > 1)
1271                 {
1272                         usage(argv[0]);
1273                         proc_exit(0);
1274                 }
1275                 else if (argc - optind == 1)
1276                         DBName = argv[optind];
1277                 else if ((DBName = userName) == NULL)
1278                 {
1279                         fprintf(stderr, "%s: USER undefined and no database specified\n",
1280                                         argv[0]);
1281                         proc_exit(0);
1282                 }
1283
1284                 /*
1285                  * Try to create pid file.
1286                  */
1287                 SetPidFname(DataDir);
1288                 if (SetPidFile(-getpid()))
1289                         proc_exit(0);
1290
1291                 /*
1292                  * Register clean up proc.
1293                  */
1294                 on_proc_exit(UnlinkPidFile, NULL);
1295
1296                 BaseInit();
1297                 snprintf(XLogDir, MAXPGPATH, "%s/pg_xlog", DataDir);
1298                 snprintf(ControlFilePath, MAXPGPATH, "%s/global/pg_control", DataDir);
1299                 StartupXLOG();
1300         }
1301
1302         /*
1303          * Set up additional info.
1304          */
1305
1306 #ifdef CYR_RECODE
1307         SetCharSet();
1308 #endif
1309
1310         /* On some systems our dynloader code needs the executable's pathname */
1311         if (FindExec(pg_pathname, real_argv[0], "postgres") < 0)
1312                 elog(FATAL, "%s: could not locate executable, bailing out...",
1313                          real_argv[0]);
1314
1315         /*
1316          * Find remote host name or address.
1317          */
1318         remote_host = NULL;
1319
1320         if (IsUnderPostmaster)
1321         {
1322                 if (MyProcPort->raddr.sa.sa_family == AF_INET)
1323                 {
1324                         struct hostent *host_ent;
1325                         char * host_addr;
1326
1327                         remote_port = ntohs(MyProcPort->raddr.in.sin_port);
1328                         host_addr = inet_ntoa(MyProcPort->raddr.in.sin_addr);
1329
1330                         if (HostnameLookup)
1331                         {
1332                                 host_ent = gethostbyaddr((char *) &MyProcPort->raddr.in.sin_addr, sizeof(MyProcPort->raddr.in.sin_addr), AF_INET);
1333
1334                                 if (host_ent)
1335                                 {
1336                                         remote_host = palloc(strlen(host_addr) + strlen(host_ent->h_name) + 3);
1337                                         sprintf(remote_host, "%s[%s]", host_ent->h_name, host_addr);
1338                                 }
1339                         }
1340
1341                         if (remote_host == NULL)
1342                                 remote_host = pstrdup(host_addr);
1343
1344                         if (ShowPortNumber)
1345                         {
1346                                 char * str = palloc(strlen(remote_host) + 7);
1347                                 sprintf(str, "%s:%hu", remote_host, remote_port);
1348                                 pfree(remote_host);
1349                                 remote_host = str;
1350                         }
1351                 }
1352                 else /* not AF_INET */
1353                         remote_host = "[local]";
1354
1355
1356                 /*
1357                  * Set process parameters for ps
1358                  *
1359                  * WARNING: On some platforms the environment will be moved
1360                  * around to make room for the ps display string. So any
1361                  * references to optarg or getenv() from above will be invalid
1362                  * after this call. Better use strdup or something similar.
1363                  */
1364                 init_ps_display(real_argc, real_argv, userName, DBName, remote_host);
1365                 set_ps_display("startup");
1366         }
1367
1368         if (Log_connections)
1369                 elog(DEBUG, "connection: host=%s user=%s database=%s",
1370                          remote_host, userName, DBName);
1371
1372         /*
1373          * general initialization
1374          */
1375         if (DebugLvl > 1)
1376                 elog(DEBUG, "InitPostgres");
1377         InitPostgres(DBName);
1378
1379 #ifdef MULTIBYTE
1380         /* set default client encoding */
1381         if (DebugLvl > 1)
1382                 elog(DEBUG, "reset_client_encoding");
1383         reset_client_encoding();
1384 #endif
1385
1386         on_shmem_exit(remove_all_temp_relations, NULL);
1387
1388         /*
1389          * Send this backend's cancellation info to the frontend.
1390          */
1391         if (whereToSendOutput == Remote &&
1392                 PG_PROTOCOL_MAJOR(FrontendProtocol) >= 2)
1393         {
1394                 StringInfoData buf;
1395
1396                 pq_beginmessage(&buf);
1397                 pq_sendbyte(&buf, 'K');
1398                 pq_sendint(&buf, (int32) MyProcPid, sizeof(int32));
1399                 pq_sendint(&buf, (int32) MyCancelKey, sizeof(int32));
1400                 pq_endmessage(&buf);
1401                 /* Need not flush since ReadyForQuery will do it. */
1402         }
1403
1404         if (!IsUnderPostmaster)
1405         {
1406                 puts("\nPOSTGRES backend interactive interface ");
1407                 puts("$Revision: 1.172 $ $Date: 2000/08/27 19:00:31 $\n");
1408         }
1409
1410         /*
1411          * Initialize the deferred trigger manager
1412          */
1413         if (DeferredTriggerInit() != 0)
1414                 proc_exit(0);
1415
1416         SetProcessingMode(NormalProcessing);
1417
1418         /*
1419          * Create the memory context we will use in the main loop.
1420          *
1421          * QueryContext is reset once per iteration of the main loop,
1422          * ie, upon completion of processing of each supplied query string.
1423          * It can therefore be used for any data that should live just as
1424          * long as the query string --- parse trees, for example.
1425          */
1426         QueryContext = AllocSetContextCreate(TopMemoryContext,
1427                                                                                  "QueryContext",
1428                                                                                  ALLOCSET_DEFAULT_MINSIZE,
1429                                                                                  ALLOCSET_DEFAULT_INITSIZE,
1430                                                                                  ALLOCSET_DEFAULT_MAXSIZE);
1431
1432         /*
1433          * POSTGRES main processing loop begins here
1434          *
1435          * If an exception is encountered, processing resumes here so we abort
1436          * the current transaction and start a new one.
1437          */
1438
1439         if (sigsetjmp(Warn_restart, 1) != 0)
1440         {
1441                 /*
1442                  * Make sure we are in a valid memory context during recovery.
1443                  *
1444                  * We use ErrorContext in hopes that it will have some free space
1445                  * even if we're otherwise up against it...
1446                  */
1447                 MemoryContextSwitchTo(ErrorContext);
1448
1449                 if (DebugLvl >= 1)
1450                         elog(DEBUG, "AbortCurrentTransaction");
1451                 AbortCurrentTransaction();
1452
1453                 if (ExitAfterAbort)
1454                 {
1455                         ProcReleaseLocks(); /* Just to be sure... */
1456                         proc_exit(0);
1457                 }
1458                 /*
1459                  * If we recovered successfully, return to normal top-level context
1460                  * and clear ErrorContext for next time.
1461                  */
1462                 MemoryContextSwitchTo(TopMemoryContext);
1463                 MemoryContextResetAndDeleteChildren(ErrorContext);
1464                 InError = false;
1465         }
1466
1467         Warn_restart_ready = true;      /* we can now handle elog(ERROR) */
1468
1469         PG_SETMASK(&UnBlockSig);
1470
1471         /*
1472          * Non-error queries loop here.
1473          */
1474
1475         for (;;)
1476         {
1477                 /*
1478                  * Release storage left over from prior query cycle, and
1479                  * create a new query input buffer in the cleared QueryContext.
1480                  */
1481                 MemoryContextSwitchTo(QueryContext);
1482                 MemoryContextResetAndDeleteChildren(QueryContext);
1483
1484                 parser_input = makeStringInfo();
1485
1486                 /* XXX this could be moved after ReadCommand below to get more
1487                  * sensical behaviour */
1488                 if (got_SIGHUP)
1489                 {
1490                         got_SIGHUP = false;
1491                         ProcessConfigFile(PGC_SIGHUP);
1492                 }
1493
1494                 /* ----------------
1495                  *       (1) tell the frontend we're ready for a new query.
1496                  *
1497                  *       Note: this includes fflush()'ing the last of the prior output.
1498                  * ----------------
1499                  */
1500                 ReadyForQuery(whereToSendOutput);
1501
1502                 /* ----------------
1503                  *       (2) deal with pending asynchronous NOTIFY from other backends,
1504                  *       and enable async.c's signal handler to execute NOTIFY directly.
1505                  * ----------------
1506                  */
1507                 QueryCancel = false;    /* forget any earlier CANCEL signal */
1508                 SetWaitingForLock(false);
1509
1510                 EnableNotifyInterrupt();
1511
1512                 /* ----------------
1513                  *       (3) read a command (loop blocks here)
1514                  * ----------------
1515                  */
1516                 set_ps_display("idle");
1517
1518                 firstchar = ReadCommand(parser_input);
1519
1520                 QueryCancel = false;    /* forget any earlier CANCEL signal */
1521
1522                 /* ----------------
1523                  *       (4) disable async.c's signal handler.
1524                  * ----------------
1525                  */
1526                 DisableNotifyInterrupt();
1527
1528                 /* ----------------
1529                  *       (5) process the command.
1530                  * ----------------
1531                  */
1532                 switch (firstchar)
1533                 {
1534                                 /* ----------------
1535                                  *      'F' indicates a fastpath call.
1536                                  *              XXX HandleFunctionRequest
1537                                  * ----------------
1538                                  */
1539                         case 'F':
1540                                 IsEmptyQuery = false;
1541
1542                                 /* start an xact for this function invocation */
1543                                 if (DebugLvl >= 1)
1544                                         elog(DEBUG, "StartTransactionCommand");
1545                                 StartTransactionCommand();
1546
1547                                 if (HandleFunctionRequest() == EOF)
1548                                 {
1549                                         /* lost frontend connection during F message input */
1550                                         pq_close();
1551                                         proc_exit(0);
1552                                 }
1553                                 break;
1554
1555                                 /* ----------------
1556                                  *      'Q' indicates a user query
1557                                  * ----------------
1558                                  */
1559                         case 'Q':
1560                                 if (strspn(parser_input->data, " \t\n") == parser_input->len)
1561                                 {
1562                                         /* ----------------
1563                                          *      if there is nothing in the input buffer, don't bother
1564                                          *      trying to parse and execute anything..
1565                                          * ----------------
1566                                          */
1567                                         IsEmptyQuery = true;
1568                                 }
1569                                 else
1570                                 {
1571                                         /* ----------------
1572                                          *      otherwise, process the input string.
1573                                          * ----------------
1574                                          */
1575                                         IsEmptyQuery = false;
1576                                         if (Show_query_stats)
1577                                                 ResetUsage();
1578
1579                                         /* start an xact for this query */
1580                                         if (DebugLvl >= 1)
1581                                                 elog(DEBUG, "StartTransactionCommand");
1582                                         StartTransactionCommand();
1583
1584                                         pg_exec_query_dest(parser_input->data,
1585                                                                            whereToSendOutput,
1586                                                                            QueryContext);
1587
1588                                         /*
1589                                          * Invoke IMMEDIATE constraint triggers
1590                                          *
1591                                          */
1592                                         DeferredTriggerEndQuery();
1593
1594                                         if (Show_query_stats)
1595                                         {
1596                                                 fprintf(StatFp, "QUERY STATISTICS\n");
1597                                                 ShowUsage();
1598                                         }
1599                                 }
1600                                 break;
1601
1602                                 /* ----------------
1603                                  *      'X' means that the frontend is closing down the socket.
1604                                  *      EOF means unexpected loss of frontend connection.
1605                                  *      Either way, perform normal shutdown.
1606                                  * ----------------
1607                                  */
1608                         case 'X':
1609                         case EOF:
1610                                 if (!IsUnderPostmaster)
1611                                         ShutdownXLOG();
1612                                 pq_close();
1613                                 proc_exit(0);
1614                                 break;
1615
1616                         default:
1617                                 elog(ERROR, "unknown frontend message was received");
1618                 }
1619
1620                 /* ----------------
1621                  *       (6) commit the current transaction
1622                  *
1623                  *       Note: if we had an empty input buffer, then we didn't
1624                  *       call pg_exec_query_dest, so we don't bother to commit
1625                  *       this transaction.
1626                  * ----------------
1627                  */
1628                 if (!IsEmptyQuery)
1629                 {
1630                         if (DebugLvl >= 1)
1631                                 elog(DEBUG, "CommitTransactionCommand");
1632                         set_ps_display("commit");
1633                         CommitTransactionCommand();
1634 #ifdef SHOW_MEMORY_STATS
1635                         /* print global-context stats at each commit for leak tracking */
1636                         if (ShowStats)
1637                                 MemoryContextStats(TopMemoryContext);
1638 #endif
1639                 }
1640                 else
1641                 {
1642                         if (IsUnderPostmaster)
1643                                 NullCommand(Remote);
1644                 }
1645
1646 #ifdef MEMORY_CONTEXT_CHECKING
1647                 /*
1648                  * Check all memory after each backend loop
1649                  */
1650                 MemoryContextCheck(TopMemoryContext);   
1651 #endif
1652         }                                                       /* infinite for-loop */
1653
1654         proc_exit(0);                           /* shouldn't get here... */
1655         return 1;
1656 }
1657
1658 #ifndef HAVE_GETRUSAGE
1659 #include "rusagestub.h"
1660 #else
1661 #include <sys/resource.h>
1662 #endif   /* HAVE_GETRUSAGE */
1663
1664 struct rusage Save_r;
1665 struct timeval Save_t;
1666
1667 void
1668 ResetUsage(void)
1669 {
1670         struct timezone tz;
1671
1672         getrusage(RUSAGE_SELF, &Save_r);
1673         gettimeofday(&Save_t, &tz);
1674         ResetBufferUsage();
1675 /*        ResetTupleCount(); */
1676 }
1677
1678 void
1679 ShowUsage(void)
1680 {
1681         struct timeval user,
1682                                 sys;
1683         struct timeval elapse_t;
1684         struct timezone tz;
1685         struct rusage r;
1686
1687         getrusage(RUSAGE_SELF, &r);
1688         gettimeofday(&elapse_t, &tz);
1689         memmove((char *) &user, (char *) &r.ru_utime, sizeof(user));
1690         memmove((char *) &sys, (char *) &r.ru_stime, sizeof(sys));
1691         if (elapse_t.tv_usec < Save_t.tv_usec)
1692         {
1693                 elapse_t.tv_sec--;
1694                 elapse_t.tv_usec += 1000000;
1695         }
1696         if (r.ru_utime.tv_usec < Save_r.ru_utime.tv_usec)
1697         {
1698                 r.ru_utime.tv_sec--;
1699                 r.ru_utime.tv_usec += 1000000;
1700         }
1701         if (r.ru_stime.tv_usec < Save_r.ru_stime.tv_usec)
1702         {
1703                 r.ru_stime.tv_sec--;
1704                 r.ru_stime.tv_usec += 1000000;
1705         }
1706
1707         /*
1708          * Set output destination if not otherwise set
1709          */
1710         if (StatFp == NULL)
1711                 StatFp = stderr;
1712
1713         /*
1714          * the only stats we don't show here are for memory usage -- i can't
1715          * figure out how to interpret the relevant fields in the rusage
1716          * struct, and they change names across o/s platforms, anyway. if you
1717          * can figure out what the entries mean, you can somehow extract
1718          * resident set size, shared text size, and unshared data and stack
1719          * sizes.
1720          */
1721
1722         fprintf(StatFp, "! system usage stats:\n");
1723         fprintf(StatFp,
1724                         "!\t%ld.%06ld elapsed %ld.%06ld user %ld.%06ld system sec\n",
1725                         (long int) elapse_t.tv_sec - Save_t.tv_sec,
1726                         (long int) elapse_t.tv_usec - Save_t.tv_usec,
1727                         (long int) r.ru_utime.tv_sec - Save_r.ru_utime.tv_sec,
1728                         (long int) r.ru_utime.tv_usec - Save_r.ru_utime.tv_usec,
1729                         (long int) r.ru_stime.tv_sec - Save_r.ru_stime.tv_sec,
1730                         (long int) r.ru_stime.tv_usec - Save_r.ru_stime.tv_usec);
1731         fprintf(StatFp,
1732                         "!\t[%ld.%06ld user %ld.%06ld sys total]\n",
1733                         (long int) user.tv_sec,
1734                         (long int) user.tv_usec,
1735                         (long int) sys.tv_sec,
1736                         (long int) sys.tv_usec);
1737 #ifdef HAVE_GETRUSAGE
1738         fprintf(StatFp,
1739                         "!\t%ld/%ld [%ld/%ld] filesystem blocks in/out\n",
1740                         r.ru_inblock - Save_r.ru_inblock,
1741         /* they only drink coffee at dec */
1742                         r.ru_oublock - Save_r.ru_oublock,
1743                         r.ru_inblock, r.ru_oublock);
1744         fprintf(StatFp,
1745                   "!\t%ld/%ld [%ld/%ld] page faults/reclaims, %ld [%ld] swaps\n",
1746                         r.ru_majflt - Save_r.ru_majflt,
1747                         r.ru_minflt - Save_r.ru_minflt,
1748                         r.ru_majflt, r.ru_minflt,
1749                         r.ru_nswap - Save_r.ru_nswap,
1750                         r.ru_nswap);
1751         fprintf(StatFp,
1752          "!\t%ld [%ld] signals rcvd, %ld/%ld [%ld/%ld] messages rcvd/sent\n",
1753                         r.ru_nsignals - Save_r.ru_nsignals,
1754                         r.ru_nsignals,
1755                         r.ru_msgrcv - Save_r.ru_msgrcv,
1756                         r.ru_msgsnd - Save_r.ru_msgsnd,
1757                         r.ru_msgrcv, r.ru_msgsnd);
1758         fprintf(StatFp,
1759                  "!\t%ld/%ld [%ld/%ld] voluntary/involuntary context switches\n",
1760                         r.ru_nvcsw - Save_r.ru_nvcsw,
1761                         r.ru_nivcsw - Save_r.ru_nivcsw,
1762                         r.ru_nvcsw, r.ru_nivcsw);
1763 #endif   /* HAVE_GETRUSAGE */
1764         fprintf(StatFp, "! postgres usage stats:\n");
1765         PrintBufferUsage(StatFp);
1766 /*         DisplayTupleCount(StatFp); */
1767 }
1768
1769 #ifdef NOT_USED
1770 static int
1771 assertEnable(int val)
1772 {
1773         assert_enabled = val;
1774         return val;
1775 }
1776
1777 #ifdef ASSERT_CHECKING_TEST
1778 int
1779 assertTest(int val)
1780 {
1781         Assert(val == 0);
1782
1783         if (assert_enabled)
1784         {
1785                 /* val != 0 should be trapped by previous Assert */
1786                 elog(NOTICE, "Assert test successfull (val = %d)", val);
1787         }
1788         else
1789                 elog(NOTICE, "Assert checking is disabled (val = %d)", val);
1790
1791         return val;
1792 }
1793
1794 #endif
1795 #endif