postgres.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:43k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. /*-------------------------------------------------------------------------
  2.  *
  3.  * postgres.c
  4.  *   POSTGRES C Backend Interface
  5.  *
  6.  * Copyright (c) 1994, Regents of the University of California
  7.  *
  8.  *
  9.  * IDENTIFICATION
  10.  *   $Header: /usr/local/cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.119 1999/07/02 18:09:27 momjian Exp $
  11.  *
  12.  * NOTES
  13.  *   this is the "main" module of the postgres backend and
  14.  *   hence the main module of the "traffic cop".
  15.  *
  16.  *-------------------------------------------------------------------------
  17.  */
  18. #include <unistd.h>
  19. #include <stdio.h>
  20. #include <string.h>
  21. #include <signal.h>
  22. #include <time.h>
  23. #include <sys/time.h>
  24. #include <sys/types.h>
  25. #include <fcntl.h>
  26. #include <sys/param.h> /* for MAXHOSTNAMELEN on most */
  27. #ifndef MAXHOSTNAMELEN
  28. #include <netdb.h> /* for MAXHOSTNAMELEN on some */
  29. #endif
  30. #ifndef MAXHOSTNAMELEN /* for MAXHOSTNAMELEN under sco3.2v5.0.2 */
  31. #include <sys/socket.h>
  32. #endif
  33. #include <errno.h>
  34. #if HAVE_SYS_SELECT_H
  35. #include <sys/select.h>
  36. #endif  /* aix */
  37. #include <netinet/in.h>
  38. #include <arpa/inet.h>
  39. #include <netdb.h>
  40. #ifdef __CYGWIN32__
  41. #include <getopt.h>
  42. #endif
  43. #include "postgres.h"
  44. #include "miscadmin.h"
  45. #include "fmgr.h"
  46. #include "access/xact.h"
  47. #include "catalog/catname.h"
  48. #include "commands/async.h"
  49. #include "executor/execdebug.h"
  50. #include "executor/executor.h"
  51. #include "libpq/libpq.h"
  52. #include "libpq/pqformat.h"
  53. #include "libpq/libpq-be.h"
  54. #include "libpq/pqsignal.h"
  55. #include "nodes/pg_list.h"
  56. #include "nodes/print.h"
  57. #include "optimizer/cost.h"
  58. #include "optimizer/planner.h"
  59. #include "optimizer/prep.h"
  60. #include "parser/parser.h"
  61. #include "rewrite/rewriteHandler.h" /* for QueryRewrite() */
  62. #include "storage/bufmgr.h"
  63. #include "tcop/dest.h"
  64. #include "tcop/fastpath.h"
  65. #include "tcop/pquery.h"
  66. #include "tcop/tcopdebug.h"
  67. #include "tcop/tcopprot.h" /* where declarations for this file go */
  68. #include "tcop/utility.h"
  69. #include "utils/mcxt.h"
  70. #include "utils/rel.h"
  71. #include "utils/ps_status.h"
  72. #include "utils/temprel.h"
  73. #include "nodes/parsenodes.h"
  74. #include "../backend/parser/parse.h"
  75. #ifdef NOT_USED
  76. #include "nodes/relation.h"
  77. #endif
  78. #ifdef NOT_USED
  79. #include "optimizer/xfunc.h"
  80. #endif
  81. #ifdef NOT_USED
  82. #include "nodes/plannodes.h"
  83. #endif
  84. #ifdef NOT_USED
  85. #include "nodes/memnodes.h"
  86. #endif
  87. #include "utils/trace.h"
  88. #ifdef MULTIBYTE
  89. #include "mb/pg_wchar.h"
  90. #endif
  91. /*
  92.  * Trace flags, see backend/utils/misc/trace.c
  93.  */
  94. #define Verbose pg_options[TRACE_VERBOSE]
  95. #define DebugPrintQuery pg_options[TRACE_QUERY]
  96. #define DebugPrintPlan pg_options[TRACE_PLAN]
  97. #define DebugPrintParse pg_options[TRACE_PARSE]
  98. #define DebugPrintRewrittenParsetree 
  99. pg_options[TRACE_REWRITTEN]
  100. #define DebugPPrintPlan pg_options[TRACE_PRETTY_PLAN]
  101. #define DebugPPrintParse pg_options[TRACE_PRETTY_PARSE]
  102. #define DebugPPrintRewrittenParsetree 
  103. pg_options[TRACE_PRETTY_REWRITTEN]
  104. #define ShowParserStats pg_options[TRACE_PARSERSTATS]
  105. #define ShowPlannerStats pg_options[TRACE_PLANNERSTATS]
  106. #define ShowExecutorStats pg_options[TRACE_EXECUTORSTATS]
  107. #ifdef LOCK_MGR_DEBUG
  108. #define LockDebug pg_options[TRACE_LOCKS]
  109. #endif
  110. #define DeadlockCheckTimer pg_options[OPT_DEADLOCKTIMEOUT]
  111. #define HostnameLookup pg_options[OPT_HOSTLOOKUP]
  112. #define ShowPortNumber pg_options[OPT_SHOWPORTNUMBER]
  113. /* ----------------
  114.  * global variables
  115.  * ----------------
  116.  */
  117. /*static bool EnableRewrite = true; , never changes why have it*/
  118. CommandDest whereToSendOutput;
  119. /* Define status buffer needed by PS_SET_STATUS */
  120. PS_DEFINE_BUFFER;
  121. extern int lockingOff;
  122. extern int NBuffers;
  123. int dontExecute = 0;
  124. static int ShowStats;
  125. static bool IsEmptyQuery = false;
  126. char relname[80]; /* current relation name */
  127. /* note: these declarations had better match tcopprot.h */
  128. DLLIMPORT sigjmp_buf Warn_restart;
  129. bool InError;
  130. extern int NBuffers;
  131. static int EchoQuery = 0; /* default don't echo */
  132. time_t tim;
  133. char pg_pathname[256];
  134. FILE    *StatFp;
  135. /* ----------------
  136.  * people who want to use EOF should #define DONTUSENEWLINE in
  137.  * tcop/tcopdebug.h
  138.  * ----------------
  139.  */
  140. #ifndef TCOP_DONTUSENEWLINE
  141. int UseNewLine = 1; /* Use newlines query delimiters (the
  142.  * default) */
  143. #else
  144. int UseNewLine = 0; /* Use EOF as query delimiters */
  145. #endif  /* TCOP_DONTUSENEWLINE */
  146. /*
  147. ** Flags for expensive function optimization -- JMH 3/9/92
  148. */
  149. int XfuncMode = 0;
  150. /*
  151.  * ----------------
  152.  *  Note: _exec_repeat_ defaults to 1 but may be changed
  153.  *    by a DEBUG command.  If you set this to a large
  154.  *    number N, run a single query, and then set it
  155.  *    back to 1 and run N queries, you can get an idea
  156.  *    of how much time is being spent in the parser and
  157.  *    planner b/c in the first case this overhead only
  158.  *    happens once.  -cim 6/9/91
  159.  * ----------------
  160. */
  161. int _exec_repeat_ = 1;
  162. /* ----------------------------------------------------------------
  163.  * decls for routines only used in this file
  164.  * ----------------------------------------------------------------
  165.  */
  166. static char InteractiveBackend(char *inBuf);
  167. static char SocketBackend(char *inBuf);
  168. static char ReadCommand(char *inBuf);
  169. static void pg_exec_query(char *query_string);
  170. /* ----------------------------------------------------------------
  171.  * routines to obtain user input
  172.  * ----------------------------------------------------------------
  173.  */
  174. /* ----------------
  175.  * InteractiveBackend() is called for user interactive connections
  176.  * the string entered by the user is placed in its parameter inBuf.
  177.  * ----------------
  178.  */
  179. static char
  180. InteractiveBackend(char *inBuf)
  181. {
  182. char    *stuff = inBuf; /* current place in input buffer */
  183. int c; /* character read from getc() */
  184. bool end = false; /* end-of-input flag */
  185. bool backslashSeen = false; /* have we seen a  ? */
  186. /* ----------------
  187.  * display a prompt and obtain input from the user
  188.  * ----------------
  189.  */
  190. printf("backend> ");
  191. fflush(stdout);
  192. for (;;)
  193. {
  194. if (UseNewLine)
  195. {
  196. /* ----------------
  197.  * if we are using n as a delimiter, then read
  198.  * characters until the n.
  199.  * ----------------
  200.  */
  201. while ((c = getc(stdin)) != EOF)
  202. {
  203. if (c == 'n')
  204. {
  205. if (backslashSeen)
  206. {
  207. stuff--;
  208. continue;
  209. }
  210. else
  211. {
  212. /* keep the newline character */
  213. *stuff++ = 'n';
  214. *stuff++ = '';
  215. break;
  216. }
  217. }
  218. else if (c == '\')
  219. backslashSeen = true;
  220. else
  221. backslashSeen = false;
  222. *stuff++ = (char) c;
  223. }
  224. if (c == EOF)
  225. end = true;
  226. }
  227. else
  228. {
  229. /* ----------------
  230.  * otherwise read characters until EOF.
  231.  * ----------------
  232.  */
  233. while ((c = getc(stdin)) != EOF)
  234. *stuff++ = (char) c;
  235. if (stuff == inBuf)
  236. end = true;
  237. }
  238. if (end)
  239. {
  240. if (Verbose)
  241. puts("EOF");
  242. IsEmptyQuery = true;
  243. proc_exit(0);
  244. }
  245. /* ----------------
  246.  * otherwise we have a user query so process it.
  247.  * ----------------
  248.  */
  249. break;
  250. }
  251. /* ----------------
  252.  * if the query echo flag was given, print the query..
  253.  * ----------------
  254.  */
  255. if (EchoQuery)
  256. printf("query: %sn", inBuf);
  257. fflush(stdout);
  258. return 'Q';
  259. }
  260. /* ----------------
  261.  * SocketBackend() Is called for frontend-backend connections
  262.  *
  263.  * If the input is a query (case 'Q') then the string entered by
  264.  * the user is placed in its parameter inBuf.
  265.  *
  266.  * If the input is a fastpath function call (case 'F') then
  267.  * the function call is processed in HandleFunctionRequest().
  268.  * (now called from PostgresMain())
  269.  * ----------------
  270.  */
  271. static char
  272. SocketBackend(char *inBuf)
  273. {
  274. char qtype;
  275. char result = '';
  276. /* ----------------
  277.  * get input from the frontend
  278.  * ----------------
  279.  */
  280. qtype = '?';
  281. if (pq_getbytes(&qtype, 1) == EOF)
  282. {
  283. /* ------------
  284.  * when front-end applications quits/dies
  285.  * ------------
  286.  */
  287. proc_exit(0);
  288. }
  289. switch (qtype)
  290. {
  291. /* ----------------
  292.  * 'Q': user entered a query
  293.  * ----------------
  294.  */
  295. case 'Q':
  296. pq_getstr(inBuf, MAX_PARSE_BUFFER);
  297. result = 'Q';
  298. break;
  299. /* ----------------
  300.  * 'F':  calling user/system functions
  301.  * ----------------
  302.  */
  303. case 'F':
  304. pq_getstr(inBuf, MAX_PARSE_BUFFER); /* ignore the rest of the
  305.  * line */
  306. result = 'F';
  307. break;
  308. /* ----------------
  309.  * 'X':  frontend is exiting
  310.  * ----------------
  311.  */
  312. case 'X':
  313. result = 'X';
  314. break;
  315. /* ----------------
  316.  * otherwise we got garbage from the frontend.
  317.  *
  318.  * XXX are we certain that we want to do an elog(FATAL) here?
  319.  * -cim 1/24/90
  320.  * ----------------
  321.  */
  322. default:
  323. elog(FATAL, "Socket command type %c unknown", qtype);
  324. break;
  325. }
  326. return result;
  327. }
  328. /* ----------------
  329.  * ReadCommand reads a command from either the frontend or
  330.  * standard input, places it in inBuf, and returns a char
  331.  * representing whether the string is a 'Q'uery or a 'F'astpath
  332.  * call.
  333.  * ----------------
  334.  */
  335. static char
  336. ReadCommand(char *inBuf)
  337. {
  338. if (IsUnderPostmaster)
  339. return SocketBackend(inBuf);
  340. else
  341. return InteractiveBackend(inBuf);
  342. }
  343. List *
  344. pg_parse_and_plan(char *query_string, /* string to execute */
  345.   Oid *typev, /* argument types */
  346.   int nargs, /* number of arguments */
  347.   List **queryListP, /* returned pointer to the parse
  348.  * trees */
  349.   CommandDest dest, /* where results should go */
  350.   bool aclOverride)
  351. {
  352. List    *querytree_list = NIL;
  353. List    *plan_list = NIL;
  354. List    *querytree_list_item;
  355. Query    *querytree;
  356. Plan    *plan;
  357. List    *new_list;
  358. List    *rewritten;
  359. if (DebugPrintQuery)
  360. {
  361. if (DebugPrintQuery > 3)
  362. {
  363. /* Print the query string as is if query debug level > 3 */
  364. TPRINTF(TRACE_QUERY, "query: %s", query_string);
  365. }
  366. else
  367. {
  368. /* Print condensed query string to fit in one log line */
  369. char buff[MAX_QUERY_SIZE + 1];
  370. char c,
  371.    *s,
  372.    *d;
  373. int n,
  374. is_space = 1;
  375. for (s = query_string, d = buff, n = 0; (c = *s) && (n < MAX_QUERY_SIZE); s++)
  376. {
  377. switch (c)
  378. {
  379. case 'r':
  380. case 'n':
  381. case 't':
  382. c = ' ';
  383. /* fall through */
  384. case ' ':
  385. if (is_space)
  386. continue;
  387. is_space = 1;
  388. break;
  389. default:
  390. is_space = 0;
  391. break;
  392. }
  393. *d++ = c;
  394. n++;
  395. }
  396. *d = '';
  397. TPRINTF(TRACE_QUERY, "query: %s", buff);
  398. }
  399. }
  400. /* ----------------
  401.  * (1) parse the request string into a list of parse trees
  402.  * ----------------
  403.  */
  404. if (ShowParserStats)
  405. ResetUsage();
  406. querytree_list = parser(query_string, typev, nargs);
  407. if (ShowParserStats)
  408. {
  409. fprintf(stderr, "! Parser Stats:n");
  410. ShowUsage();
  411. }
  412. /* ----------------
  413.  * (2) rewrite the queries, as necessary
  414.  *
  415.  * rewritten queries are collected in new_list.  Note there may be
  416.  * more or fewer than in the original list.
  417.  * ----------------
  418.  */
  419. new_list = NIL;
  420. foreach(querytree_list_item, querytree_list)
  421. {
  422. querytree = (Query *) lfirst(querytree_list_item);
  423. if (DebugPrintParse || DebugPPrintParse)
  424. {
  425. if (DebugPPrintParse)
  426. {
  427. TPRINTF(TRACE_PRETTY_PARSE, "parser outputs:");
  428. nodeDisplay(querytree);
  429. }
  430. else
  431. {
  432. TPRINTF(TRACE_PARSE, "parser outputs:");
  433. printf("n%snn", nodeToString(querytree));
  434. }
  435. }
  436. if (querytree->commandType == CMD_UTILITY)
  437. {
  438. /* don't rewrite utilities, just dump 'em into new_list */
  439. new_list = lappend(new_list, querytree);
  440. }
  441. else
  442. {
  443. /* rewrite regular queries */
  444. rewritten = QueryRewrite(querytree);
  445. new_list = nconc(new_list, rewritten);
  446. }
  447. }
  448. querytree_list = new_list;
  449. /*
  450.  * Override ACL checking if requested
  451.  */
  452. if (aclOverride)
  453. {
  454. foreach(querytree_list_item, querytree_list)
  455. {
  456. List    *l;
  457. querytree = (Query *) lfirst(querytree_list_item);
  458. if (querytree->commandType == CMD_UTILITY)
  459. continue;
  460. foreach(l, querytree->rtable)
  461. {
  462. RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
  463. rte->skipAcl = TRUE;
  464. }
  465. }
  466. }
  467. if (DebugPrintRewrittenParsetree || DebugPPrintRewrittenParsetree)
  468. {
  469. if (DebugPPrintRewrittenParsetree)
  470. {
  471. TPRINTF(TRACE_PRETTY_REWRITTEN, "after rewriting:");
  472. foreach(querytree_list_item, querytree_list)
  473. {
  474. querytree = (Query *) lfirst(querytree_list_item);
  475. nodeDisplay(querytree);
  476. printf("n");
  477. }
  478. }
  479. else
  480. {
  481. TPRINTF(TRACE_REWRITTEN, "after rewriting:");
  482. foreach(querytree_list_item, querytree_list)
  483. {
  484. querytree = (Query *) lfirst(querytree_list_item);
  485. printf("n%snn", nodeToString(querytree));
  486. }
  487. }
  488. }
  489. foreach(querytree_list_item, querytree_list)
  490. {
  491. querytree = (Query *) lfirst(querytree_list_item);
  492. /*
  493.  * For each query that isn't a utility invocation, generate a
  494.  * plan.
  495.  */
  496. if (querytree->commandType != CMD_UTILITY)
  497. {
  498. if (IsAbortedTransactionBlockState())
  499. {
  500. /* ----------------
  501.  *  the EndCommand() stuff is to tell the frontend
  502.  *  that the command ended. -cim 6/1/90
  503.  * ----------------
  504.  */
  505. char    *tag = "*ABORT STATE*";
  506. EndCommand(tag, dest);
  507. elog(NOTICE, "(transaction aborted): %s",
  508.  "queries ignored until END");
  509. if (queryListP)
  510. *queryListP = NIL;
  511. return NIL;
  512. }
  513. if (ShowPlannerStats)
  514. ResetUsage();
  515. /* call that optimizer */
  516. plan = planner(querytree);
  517. if (ShowPlannerStats)
  518. {
  519. fprintf(stderr, "! Planner Stats:n");
  520. ShowUsage();
  521. }
  522. plan_list = lappend(plan_list, plan);
  523. #ifdef INDEXSCAN_PATCH
  524. /* ----------------
  525.  * Print plan if debugging.
  526.  * This has been moved here to get debugging output
  527.  * also for queries in functions. DZ - 27-8-1996
  528.  * ----------------
  529.  */
  530. if (DebugPrintPlan || DebugPPrintPlan)
  531. {
  532. if (DebugPPrintPlan)
  533. {
  534. TPRINTF(TRACE_PRETTY_PLAN, "plan:");
  535. nodeDisplay(plan);
  536. }
  537. else
  538. {
  539. TPRINTF(TRACE_PLAN, "plan:");
  540. printf("n%snn", nodeToString(plan));
  541. }
  542. }
  543. #endif
  544. }
  545. /*
  546.  * If the command is an utility append a null plan. This is needed
  547.  * to keep the plan_list aligned with the querytree_list or the
  548.  * function executor will crash.  DZ - 30-8-1996
  549.  */
  550. else
  551. plan_list = lappend(plan_list, NULL);
  552. }
  553. if (queryListP)
  554. *queryListP = querytree_list;
  555. return plan_list;
  556. }
  557. /* ----------------------------------------------------------------
  558.  * pg_exec_query()
  559.  *
  560.  * Takes a querystring, runs the parser/utilities or
  561.  * parser/planner/executor over it as necessary
  562.  * Begin Transaction Should have been called before this
  563.  * and CommitTransaction After this is called
  564.  * This is strictly because we do not allow for nested xactions.
  565.  *
  566.  * NON-OBVIOUS-RESTRICTIONS
  567.  * this function _MUST_ allocate a new "parsetree" each time,
  568.  * since it may be stored in a named portal and should not
  569.  * change its value.
  570.  *
  571.  * ----------------------------------------------------------------
  572.  */
  573. static void
  574. pg_exec_query(char *query_string)
  575. {
  576. pg_exec_query_dest(query_string, whereToSendOutput, FALSE);
  577. }
  578. void
  579. pg_exec_query_acl_override(char *query_string)
  580. {
  581. pg_exec_query_dest(query_string, whereToSendOutput, TRUE);
  582. }
  583. void
  584. pg_exec_query_dest(char *query_string, /* string to execute */
  585.    CommandDest dest, /* where results should go */
  586.    bool aclOverride) /* to give utility commands power
  587.  * of superusers */
  588. {
  589. List    *querytree_list;
  590. List    *plan_list;
  591. Query    *querytree;
  592. Plan    *plan;
  593. int j;
  594. /* plan the queries */
  595. plan_list = pg_parse_and_plan(query_string, NULL, 0,
  596.   &querytree_list, dest, aclOverride);
  597. /* if we got a cancel signal whilst planning, quit */
  598. if (QueryCancel)
  599. CancelQuery();
  600. /* OK, do it to it! */
  601. /*
  602.  * NOTE: we do not use "foreach" here because we want to be sure the
  603.  * list pointers have been advanced before the query is executed. We
  604.  * need to do that because VACUUM has a nasty little habit of doing
  605.  * CommitTransactionCommand at startup, and that will release the
  606.  * memory holding our parse/plan lists :-(.  This needs a better
  607.  * solution --- currently, the code will crash if someone submits
  608.  * "vacuum; something-else" in a single query string.  But memory
  609.  * allocation needs redesigned anyway, so this will have to do for
  610.  * now.
  611.  */
  612. while (querytree_list)
  613. {
  614. querytree = (Query *) lfirst(querytree_list);
  615. querytree_list = lnext(querytree_list);
  616. plan = (Plan *) lfirst(plan_list);
  617. plan_list = lnext(plan_list);
  618. if (querytree->commandType == CMD_UTILITY)
  619. {
  620. /* ----------------
  621.  *  process utility functions (create, destroy, etc..)
  622.  *
  623.  *  Note: we do not check for the transaction aborted state
  624.  *  because that is done in ProcessUtility.
  625.  * ----------------
  626.  */
  627. if (DebugPrintQuery)
  628. TPRINTF(TRACE_QUERY, "ProcessUtility: %s", query_string);
  629. else if (Verbose)
  630. TPRINTF(TRACE_VERBOSE, "ProcessUtility");
  631. /*
  632.  * We have to set query SnapShot in the case of FETCH or COPY TO.
  633.  */
  634. if (nodeTag(querytree->utilityStmt) == T_FetchStmt ||
  635. (nodeTag(querytree->utilityStmt) == T_CopyStmt && 
  636. ((CopyStmt *)(querytree->utilityStmt))->direction != FROM))
  637. SetQuerySnapshot();
  638. ProcessUtility(querytree->utilityStmt, dest);
  639. }
  640. else
  641. {
  642. #ifdef INDEXSCAN_PATCH
  643. /*
  644.  * Print moved in pg_parse_and_plan. DZ - 27-8-1996
  645.  */
  646. #else
  647. /* ----------------
  648.  * print plan if debugging
  649.  * ----------------
  650.  */
  651. if (DebugPrintPlan || DebugPPrintPlan)
  652. {
  653. if (DebugPPrintPlan)
  654. {
  655. TPRINTF(TRACE_PRETTY_PLAN, "plan:");
  656. nodeDisplay(plan);
  657. }
  658. else
  659. {
  660. TPRINTF(TRACE_PLAN, "plan:");
  661. printf("n%snn", nodeToString(plan));
  662. }
  663. }
  664. #endif
  665. SetQuerySnapshot();
  666. /*
  667.  * execute the plan
  668.  */
  669. if (ShowExecutorStats)
  670. ResetUsage();
  671. for (j = 0; j < _exec_repeat_; j++)
  672. {
  673. if (Verbose)
  674. TPRINTF(TRACE_VERBOSE, "ProcessQuery");
  675. ProcessQuery(querytree, plan, dest);
  676. }
  677. if (ShowExecutorStats)
  678. {
  679. fprintf(stderr, "! Executor Stats:n");
  680. ShowUsage();
  681. }
  682. }
  683. /*
  684.  * In a query block, we want to increment the command counter
  685.  * between queries so that the effects of early queries are
  686.  * visible to subsequent ones.
  687.  */
  688. CommandCounterIncrement();
  689. }
  690. }
  691. /* --------------------------------
  692.  * signal handler routines used in PostgresMain()
  693.  *
  694.  * handle_warn() catches SIGQUIT. It forces control back to the main
  695.  * loop, just as if an internal error (elog(ERROR,...)) had occurred.
  696.  * elog() used to actually use kill(2) to induce a SIGQUIT to get here!
  697.  * But that's not 100% reliable on some systems, so now it does its own
  698.  * siglongjmp() instead.
  699.  * We still provide the signal catcher so that an error quit can be
  700.  * forced externally. This should be done only with great caution,
  701.  * however, since an asynchronous signal could leave the system in
  702.  * who-knows-what inconsistent state.
  703.  *
  704.  * quickdie() occurs when signalled by the postmaster.
  705.  * Some backend has bought the farm,
  706.  * so we need to stop what we're doing and exit.
  707.  *
  708.  * die() performs an orderly cleanup via ExitPostgres()
  709.  * --------------------------------
  710.  */
  711. void
  712. handle_warn(SIGNAL_ARGS)
  713. {
  714. siglongjmp(Warn_restart, 1);
  715. }
  716. void
  717. quickdie(SIGNAL_ARGS)
  718. {
  719. elog(NOTICE, "Message from PostgreSQL backend:"
  720.  "ntThe Postmaster has informed me that some other backend"
  721.  " died abnormally and possibly corrupted shared memory."
  722.  "ntI have rolled back the current transaction and am"
  723.  " going to terminate your database system connection and exit."
  724. "ntPlease reconnect to the database system and repeat your query.");
  725. /*
  726.  * DO NOT ExitPostgres(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. exit(0);
  731. }
  732. void
  733. die(SIGNAL_ARGS)
  734. {
  735. ExitPostgres(0);
  736. }
  737. /* signal handler for floating point exception */
  738. void
  739. FloatExceptionHandler(SIGNAL_ARGS)
  740. {
  741. elog(ERROR, "floating point exception!"
  742.  " The last floating point operation either exceeded legal ranges"
  743.  " or was a divide by zero");
  744. }
  745. /* signal handler for query cancel signal from postmaster */
  746. static void
  747. QueryCancelHandler(SIGNAL_ARGS)
  748. {
  749. QueryCancel = true;
  750. }
  751. void
  752. CancelQuery(void)
  753. {
  754. /*
  755.  * QueryCancel flag will be reset in main loop, which we reach by
  756.  * longjmp from elog().
  757.  */
  758. elog(ERROR, "Query was cancelled.");
  759. }
  760. static void
  761. usage(char *progname)
  762. {
  763. fprintf(stderr,
  764. "Usage: %s [options] [dbname]n", progname);
  765. #ifdef USE_ASSERT_CHECKING
  766. fprintf(stderr, "t-A onttenable/disable assert checkingn");
  767. #endif
  768. fprintf(stderr, "t-B bufferstset number of buffers in buffer pooln");
  769. fprintf(stderr, "t-C ttsuppress version infon");
  770. fprintf(stderr, "t-D dirttdata directoryn");
  771. fprintf(stderr, "t-E ttecho query before executionn");
  772. fprintf(stderr, "t-F ttturn off fsyncn");
  773. #ifdef LOCK_MGR_DEBUG
  774. fprintf(stderr, "t-K levttset locking debug level [0|1|2]n");
  775. #endif
  776. fprintf(stderr, "t-L ttturn off lockingn");
  777. fprintf(stderr, "t-N ttdon't use newline as interactive query delimitern");
  778. fprintf(stderr, "t-O ttallow system table structure changesn");
  779. fprintf(stderr, "t-Q ttsuppress informational messagesn");
  780. fprintf(stderr, "t-S kbytestset amount of memory for sorts (in kbytes)n");
  781. fprintf(stderr, "t-T optionstspecify pg_optionsn");
  782. fprintf(stderr, "t-W secttwait N seconds to allow attach from a debuggern");
  783. fprintf(stderr, "t-d [1|2|3]tset debug leveln");
  784. fprintf(stderr, "t-e ttturn on European date formatn");
  785. fprintf(stderr, "t-f [s|i|n|m|h]tforbid use of some plan typesn");
  786. fprintf(stderr, "t-i ttdon't execute queriesn");
  787. fprintf(stderr, "t-o filettsend stdout and stderr to given filenamen");
  788. fprintf(stderr, "t-p databasetbackend is started under a postmastern");
  789. fprintf(stderr, "t-s ttshow stats after each queryn");
  790. fprintf(stderr, "t-t [pa|pl|ex]tshow timings after each queryn");
  791. fprintf(stderr, "t-v versiontset protocol version being used by frontendn");
  792. }
  793. /* ----------------------------------------------------------------
  794.  * PostgresMain
  795.  * postgres main loop
  796.  * all backends, interactive or otherwise start here
  797.  *
  798.  * argc/argv are the command line arguments to be used.  When being forked
  799.  * by the postmaster, these are not the original argv array of the process.
  800.  * real_argc/real_argv point to the original argv array, which is needed by
  801.  * PS_INIT_STATUS on some platforms.
  802.  * ----------------------------------------------------------------
  803.  */
  804. int
  805. PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
  806. {
  807. int flag;
  808. char    *DBName = NULL;
  809. bool secure = true;
  810. int errs = 0;
  811. char firstchar;
  812. char parser_input[MAX_PARSE_BUFFER];
  813. char    *userName;
  814. /* Used if verbose is set, must be initialized */
  815. char    *remote_info = "interactive";
  816. char    *remote_host = "";
  817. unsigned short remote_port = 0;
  818. char    *DBDate = NULL;
  819. extern int optind;
  820. extern char *optarg;
  821. extern short DebugLvl;
  822. /*
  823.  * Set default values for command-line options.
  824.  */
  825. IsUnderPostmaster = false;
  826. ShowStats = 0;
  827. ShowParserStats = ShowPlannerStats = ShowExecutorStats = 0;
  828. DeadlockCheckTimer = DEADLOCK_CHECK_TIMER;
  829. Noversion = false;
  830. EchoQuery = false;
  831. #ifdef LOCK_MGR_DEBUG
  832. LockDebug = 0;
  833. #endif
  834. DataDir = getenv("PGDATA");
  835. /*
  836.  * Try to get initial values for date styles and formats. Does not do
  837.  * a complete job, but should be good enough for backend. Cannot call
  838.  * parse_date() since palloc/pfree memory is not set up yet.
  839.  */
  840. DBDate = getenv("PGDATESTYLE");
  841. if (DBDate != NULL)
  842. {
  843. if (strcasecmp(DBDate, "ISO") == 0)
  844. DateStyle = USE_ISO_DATES;
  845. else if (strcasecmp(DBDate, "SQL") == 0)
  846. DateStyle = USE_SQL_DATES;
  847. else if (strcasecmp(DBDate, "POSTGRES") == 0)
  848. DateStyle = USE_POSTGRES_DATES;
  849. else if (strcasecmp(DBDate, "GERMAN") == 0)
  850. {
  851. DateStyle = USE_GERMAN_DATES;
  852. EuroDates = TRUE;
  853. }
  854. else if (strcasecmp(DBDate, "NONEURO") == 0)
  855. EuroDates = FALSE;
  856. else if (strcasecmp(DBDate, "EURO") == 0)
  857. EuroDates = TRUE;
  858. }
  859. /*
  860.  * Read default pg_options from file $DATADIR/pg_options.
  861.  */
  862. if (DataDir)
  863. read_pg_options(0);
  864. /* ----------------
  865.  * parse command line arguments
  866.  *
  867.  * There are now two styles of command line layout for the backend:
  868.  *
  869.  * For interactive use (not started from postmaster) the format is
  870.  * postgres [switches] [databasename]
  871.  * If the databasename is omitted it is taken to be the user name.
  872.  *
  873.  * When started from the postmaster, the format is
  874.  * postgres [secure switches] -p databasename [insecure switches]
  875.  * Switches appearing after -p came from the client (via "options"
  876.  * field of connection request).  For security reasons we restrict
  877.  * what these switches can do.
  878.  * ----------------
  879.  */
  880. optind = 1; /* reset after postmaster's usage */
  881. while ((flag = getopt(argc, argv,
  882.   "A:B:CD:d:EeFf:iK:LNOo:p:QS:sT:t:v:W:x:"))
  883.    != EOF)
  884. switch (flag)
  885. {
  886. case 'A':
  887. /* ----------------
  888.  * enable/disable assert checking.
  889.  * ----------------
  890.  */
  891. #ifdef USE_ASSERT_CHECKING
  892. assert_enabled = atoi(optarg);
  893. #else
  894. fprintf(stderr, "Assert checking is not enabledn");
  895. #endif
  896. break;
  897. case 'B':
  898. /* ----------------
  899.  * specify the size of buffer pool
  900.  * ----------------
  901.  */
  902. if (secure)
  903. NBuffers = atoi(optarg);
  904. break;
  905. case 'C':
  906. /* ----------------
  907.  * don't print version string
  908.  * ----------------
  909.  */
  910. Noversion = true;
  911. break;
  912. case 'D': /* PGDATA directory */
  913. if (secure)
  914. {
  915. if (!DataDir)
  916. {
  917. DataDir = optarg;
  918. /* must be done after DataDir is defined */
  919. read_pg_options(0);
  920. }
  921. DataDir = optarg;
  922. }
  923. break;
  924. case 'd': /* debug level */
  925. DebugLvl = (short) atoi(optarg);
  926. if (DebugLvl >= 1)
  927. Verbose = DebugLvl;
  928. if (DebugLvl >= 2)
  929. DebugPrintQuery = true;
  930. if (DebugLvl >= 3)
  931. DebugPrintQuery = DebugLvl;
  932. if (DebugLvl >= 4)
  933. {
  934. DebugPrintParse = true;
  935. DebugPrintPlan = true;
  936. DebugPrintRewrittenParsetree = true;
  937. }
  938. if (DebugLvl >= 5)
  939. {
  940. DebugPPrintParse = true;
  941. DebugPPrintPlan = true;
  942. DebugPPrintRewrittenParsetree = true;
  943. }
  944. break;
  945. case 'E':
  946. /* ----------------
  947.  * E - echo the query the user entered
  948.  * ----------------
  949.  */
  950. EchoQuery = true;
  951. break;
  952. case 'e':
  953. /* --------------------------
  954.  * Use european date formats.
  955.  * --------------------------
  956.  */
  957. EuroDates = true;
  958. break;
  959. case 'F':
  960. /* --------------------
  961.  * turn off fsync
  962.  * --------------------
  963.  */
  964. if (secure)
  965. disableFsync = true;
  966. break;
  967. case 'f':
  968. /* -----------------
  969.  *   f - forbid generation of certain plans
  970.  * -----------------
  971.  */
  972. switch (optarg[0])
  973. {
  974. case 's': /* seqscan */
  975. _enable_seqscan_ = false;
  976. break;
  977. case 'i': /* indexscan */
  978. _enable_indexscan_ = false;
  979. break;
  980. case 'n': /* nestloop */
  981. _enable_nestloop_ = false;
  982. break;
  983. case 'm': /* mergejoin */
  984. _enable_mergejoin_ = false;
  985. break;
  986. case 'h': /* hashjoin */
  987. _enable_hashjoin_ = false;
  988. break;
  989. default:
  990. errs++;
  991. }
  992. break;
  993. case 'i':
  994. dontExecute = 1;
  995. break;
  996. case 'K':
  997. #ifdef LOCK_MGR_DEBUG
  998. LockDebug = atoi(optarg);
  999. #else
  1000. fprintf(stderr, "Lock debug not compiled inn");
  1001. #endif
  1002. break;
  1003. case 'L':
  1004. /* --------------------
  1005.  * turn off locking
  1006.  * --------------------
  1007.  */
  1008. if (secure)
  1009. lockingOff = 1;
  1010. break;
  1011. case 'N':
  1012. /* ----------------
  1013.  * N - Don't use newline as a query delimiter
  1014.  * ----------------
  1015.  */
  1016. UseNewLine = 0;
  1017. break;
  1018. case 'O':
  1019. /* --------------------
  1020.  * allow system table structure modifications
  1021.  * --------------------
  1022.  */
  1023. if (secure) /* XXX safe to allow from client??? */
  1024. allowSystemTableMods = true;
  1025. break;
  1026. case 'o':
  1027. /* ----------------
  1028.  * o - send output (stdout and stderr) to the given file
  1029.  * ----------------
  1030.  */
  1031. if (secure)
  1032. StrNCpy(OutputFileName, optarg, MAXPGPATH);
  1033. break;
  1034. case 'p':
  1035. /* ----------------
  1036.  * p - special flag passed if backend was forked
  1037.  * by a postmaster.
  1038.  * ----------------
  1039.  */
  1040. if (secure)
  1041. {
  1042. IsUnderPostmaster = true;
  1043. DBName = optarg;
  1044. secure = false; /* subsequent switches are NOT
  1045.  * secure */
  1046. }
  1047. break;
  1048. case 'Q':
  1049. /* ----------------
  1050.  * Q - set Quiet mode (reduce debugging output)
  1051.  * ----------------
  1052.  */
  1053. Verbose = 0;
  1054. break;
  1055. case 'S':
  1056. /* ----------------
  1057.  * S - amount of sort memory to use in 1k bytes
  1058.  * ----------------
  1059.  */
  1060. {
  1061. int S;
  1062. S = atoi(optarg);
  1063. if (S >= 4 * BLCKSZ / 1024)
  1064. SortMem = S;
  1065. }
  1066. break;
  1067. case 's':
  1068. /* ----------------
  1069.  *   s - report usage statistics (timings) after each query
  1070.  * ----------------
  1071.  */
  1072. ShowStats = 1;
  1073. StatFp = stderr;
  1074. break;
  1075. case 'T':
  1076. /* ----------------
  1077.  * T - tracing options
  1078.  * ----------------
  1079.  */
  1080. parse_options(optarg, secure);
  1081. break;
  1082. case 't':
  1083. /* ----------------
  1084.  * tell postgres to report usage statistics (timings) for
  1085.  * each query
  1086.  *
  1087.  * -tpa[rser] = print stats for parser time of each query
  1088.  * -tpl[anner] = print stats for planner time of each query
  1089.  * -te[xecutor] = print stats for executor time of each query
  1090.  * caution: -s can not be used together with -t.
  1091.  * ----------------
  1092.  */
  1093. StatFp = stderr;
  1094. switch (optarg[0])
  1095. {
  1096. case 'p':
  1097. if (optarg[1] == 'a')
  1098. ShowParserStats = 1;
  1099. else if (optarg[1] == 'l')
  1100. ShowPlannerStats = 1;
  1101. else
  1102. errs++;
  1103. break;
  1104. case 'e':
  1105. ShowExecutorStats = 1;
  1106. break;
  1107. default:
  1108. errs++;
  1109. break;
  1110. }
  1111. break;
  1112. case 'v':
  1113. if (secure)
  1114. FrontendProtocol = (ProtocolVersion) atoi(optarg);
  1115. break;
  1116. case 'W':
  1117. /* ----------------
  1118.  * wait N seconds to allow attach from a debugger
  1119.  * ----------------
  1120.  */
  1121. sleep(atoi(optarg));
  1122. break;
  1123. case 'x':
  1124. #ifdef NOT_USED /* planner/xfunc.h */
  1125. /*
  1126.  * control joey hellerstein's expensive function
  1127.  * optimization
  1128.  */
  1129. if (XfuncMode != 0)
  1130. {
  1131. fprintf(stderr, "only one -x flag is allowedn");
  1132. errs++;
  1133. break;
  1134. }
  1135. if (strcmp(optarg, "off") == 0)
  1136. XfuncMode = XFUNC_OFF;
  1137. else if (strcmp(optarg, "nor") == 0)
  1138. XfuncMode = XFUNC_NOR;
  1139. else if (strcmp(optarg, "nopull") == 0)
  1140. XfuncMode = XFUNC_NOPULL;
  1141. else if (strcmp(optarg, "nopm") == 0)
  1142. XfuncMode = XFUNC_NOPM;
  1143. else if (strcmp(optarg, "pullall") == 0)
  1144. XfuncMode = XFUNC_PULLALL;
  1145. else if (strcmp(optarg, "wait") == 0)
  1146. XfuncMode = XFUNC_WAIT;
  1147. else
  1148. {
  1149. fprintf(stderr, "use -x {off,nor,nopull,nopm,pullall,wait}n");
  1150. errs++;
  1151. }
  1152. #endif
  1153. break;
  1154. default:
  1155. /* ----------------
  1156.  * default: bad command line option
  1157.  * ----------------
  1158.  */
  1159. errs++;
  1160. break;
  1161. }
  1162. /* ----------------
  1163.  * get user name (needed now in case it is the default database name)
  1164.  * and check command line validity
  1165.  * ----------------
  1166.  */
  1167. SetPgUserName();
  1168. userName = GetPgUserName();
  1169. if (IsUnderPostmaster)
  1170. {
  1171. /* noninteractive case: nothing should be left after switches */
  1172. if (errs || argc != optind || DBName == NULL)
  1173. {
  1174. usage(argv[0]);
  1175. proc_exit(1);
  1176. }
  1177. }
  1178. else
  1179. {
  1180. /* interactive case: database name can be last arg on command line */
  1181. if (errs || argc - optind > 1)
  1182. {
  1183. usage(argv[0]);
  1184. proc_exit(1);
  1185. }
  1186. else if (argc - optind == 1)
  1187. DBName = argv[optind];
  1188. else if ((DBName = userName) == NULL)
  1189. {
  1190. fprintf(stderr, "%s: USER undefined and no database specifiedn",
  1191. argv[0]);
  1192. proc_exit(1);
  1193. }
  1194. }
  1195. if (ShowStats &&
  1196. (ShowParserStats || ShowPlannerStats || ShowExecutorStats))
  1197. {
  1198. fprintf(stderr, "-s can not be used together with -t.n");
  1199. proc_exit(1);
  1200. }
  1201. if (!DataDir)
  1202. {
  1203. fprintf(stderr, "%s does not know where to find the database system "
  1204. "data.  You must specify the directory that contains the "
  1205. "database system either by specifying the -D invocation "
  1206.  "option or by setting the PGDATA environment variable.nn",
  1207. argv[0]);
  1208. proc_exit(1);
  1209. }
  1210. /*
  1211.  * Set up additional info.
  1212.  */
  1213. #ifdef CYR_RECODE
  1214. SetCharSet();
  1215. #endif
  1216. if (FindExec(pg_pathname, argv[0], "postgres") < 0)
  1217. elog(FATAL, "%s: could not locate executable, bailing out...",
  1218.  argv[0]);
  1219. /*
  1220.  * Find remote host name or address.
  1221.  */
  1222. if (IsUnderPostmaster)
  1223. {
  1224. switch (MyProcPort->raddr.sa.sa_family)
  1225. {
  1226. struct hostent *host_ent;
  1227. case AF_INET:
  1228. remote_info = remote_host = malloc(48);
  1229. remote_port = ntohs(MyProcPort->raddr.in.sin_port);
  1230. strcpy(remote_host, inet_ntoa(MyProcPort->raddr.in.sin_addr));
  1231. if (HostnameLookup)
  1232. {
  1233. host_ent = 
  1234. gethostbyaddr((char *) &MyProcPort->raddr.in.sin_addr,
  1235.    sizeof(MyProcPort->raddr.in.sin_addr),
  1236.   AF_INET);
  1237. if (host_ent)
  1238. {
  1239. strncpy(remote_host, host_ent->h_name, 48);
  1240. *(remote_host + 47) = '';
  1241. }
  1242. }
  1243. if (ShowPortNumber)
  1244. {
  1245. remote_info = malloc(strlen(remote_host) + 6);
  1246. sprintf(remote_info, "%s:%d", remote_host, remote_port);
  1247. }
  1248. break;
  1249. case AF_UNIX:
  1250. remote_info = remote_host = "localhost";
  1251. break;
  1252. default:
  1253. remote_info = remote_host = "unknown";
  1254. break;
  1255. }
  1256. }
  1257. /* ----------------
  1258.  * set process params for ps
  1259.  * ----------------
  1260.  */
  1261. if (IsUnderPostmaster)
  1262. {
  1263. PS_INIT_STATUS(real_argc, real_argv, argv[0],
  1264.    remote_info, userName, DBName);
  1265. PS_SET_STATUS("startup");
  1266. }
  1267. /* ----------------
  1268.  * print flags
  1269.  * ----------------
  1270.  */
  1271. if (Verbose)
  1272. {
  1273. if (Verbose == 1)
  1274. {
  1275. TPRINTF(TRACE_VERBOSE, "started: host=%s user=%s database=%s",
  1276. remote_host, userName, DBName);
  1277. }
  1278. else
  1279. {
  1280. TPRINTF(TRACE_VERBOSE, "debug info:");
  1281. TPRINTF(TRACE_VERBOSE, "tUser         = %s", userName);
  1282. TPRINTF(TRACE_VERBOSE, "tRemoteHost   = %s", remote_host);
  1283. TPRINTF(TRACE_VERBOSE, "tRemotePort   = %d", remote_port);
  1284. TPRINTF(TRACE_VERBOSE, "tDatabaseName = %s", DBName);
  1285. TPRINTF(TRACE_VERBOSE, "tVerbose      = %d", Verbose);
  1286. TPRINTF(TRACE_VERBOSE, "tNoversion    = %c", Noversion ? 't' : 'f');
  1287. TPRINTF(TRACE_VERBOSE, "ttimings      = %c", ShowStats ? 't' : 'f');
  1288. TPRINTF(TRACE_VERBOSE, "tdates        = %s",
  1289. EuroDates ? "European" : "Normal");
  1290. TPRINTF(TRACE_VERBOSE, "tbufsize      = %d", NBuffers);
  1291. TPRINTF(TRACE_VERBOSE, "tsortmem      = %d", SortMem);
  1292. TPRINTF(TRACE_VERBOSE, "tquery echo   = %c", EchoQuery ? 't' : 'f');
  1293. }
  1294. }
  1295. /* ----------------
  1296.  * initialize I/O
  1297.  * ----------------
  1298.  */
  1299. if (IsUnderPostmaster)
  1300. {
  1301. pq_init(); /* initialize libpq at backend startup */
  1302. whereToSendOutput = Remote;
  1303. }
  1304. else
  1305. whereToSendOutput = Debug;
  1306. /* ----------------
  1307.  * general initialization
  1308.  * ----------------
  1309.  */
  1310. SetProcessingMode(InitProcessing);
  1311. if (Verbose)
  1312. TPRINTF(TRACE_VERBOSE, "InitPostgres");
  1313. InitPostgres(DBName);
  1314. #ifdef MULTIBYTE
  1315. /* set default client encoding */
  1316. if (Verbose)
  1317. puts("treset_client_encoding()..");
  1318. reset_client_encoding();
  1319. if (Verbose)
  1320. puts("treset_client_encoding() done.");
  1321. #endif
  1322. on_shmem_exit(remove_all_temp_relations, NULL);
  1323. /* ----------------
  1324.  * Set up handler for cancel-request signal, and
  1325.  * send this backend's cancellation info to the frontend.
  1326.  * This should not be done until we are sure startup is successful.
  1327.  * ----------------
  1328.  */
  1329. pqsignal(SIGHUP, read_pg_options); /* update pg_options from file */
  1330. pqsignal(SIGINT, QueryCancelHandler); /* cancel current query */
  1331. pqsignal(SIGQUIT, handle_warn); /* handle error */
  1332. pqsignal(SIGTERM, die);
  1333. pqsignal(SIGPIPE, SIG_IGN); /* ignore failure to write to frontend */
  1334. /*
  1335.  * Note: if frontend closes connection, we will notice it and exit
  1336.  * cleanly when control next returns to outer loop.  This seems safer
  1337.  * than forcing exit in the midst of output during who-knows-what
  1338.  * operation...
  1339.  */
  1340. pqsignal(SIGUSR1, quickdie);
  1341. pqsignal(SIGUSR2, Async_NotifyHandler); /* flush also sinval cache */
  1342. pqsignal(SIGCHLD, SIG_IGN); /* ignored, sent by LockOwners */
  1343. pqsignal(SIGFPE, FloatExceptionHandler);
  1344. if (whereToSendOutput == Remote &&
  1345. PG_PROTOCOL_MAJOR(FrontendProtocol) >= 2)
  1346. {
  1347. StringInfoData buf;
  1348. pq_beginmessage(&buf);
  1349. pq_sendbyte(&buf, 'K');
  1350. pq_sendint(&buf, (int32) MyProcPid, sizeof(int32));
  1351. pq_sendint(&buf, (int32) MyCancelKey, sizeof(int32));
  1352. pq_endmessage(&buf);
  1353. /* Need not flush since ReadyForQuery will do it. */
  1354. }
  1355. if (!IsUnderPostmaster)
  1356. {
  1357. puts("nPOSTGRES backend interactive interface ");
  1358. puts("$Revision: 1.119 $ $Date: 1999/07/02 18:09:27 $n");
  1359. }
  1360. /* ----------------
  1361.  * POSTGRES main processing loop begins here
  1362.  *
  1363.  * if an exception is encountered, processing resumes here
  1364.  * so we abort the current transaction and start a new one.
  1365.  *
  1366.  * Note:  elog(ERROR) does a siglongjmp() to transfer control here.
  1367.  * ----------------
  1368.  */
  1369. if (sigsetjmp(Warn_restart, 1) != 0)
  1370. {
  1371. InError = true;
  1372. time(&tim);
  1373. if (Verbose)
  1374. TPRINTF(TRACE_VERBOSE, "AbortCurrentTransaction");
  1375. AbortCurrentTransaction();
  1376. }
  1377. InError = false;
  1378. /*
  1379.  * Non-error queries loop here.
  1380.  */
  1381. for (;;)
  1382. {
  1383. PS_SET_STATUS("idle");
  1384. /* ----------------
  1385.  *  (1) tell the frontend we're ready for a new query.
  1386.  *
  1387.  *  Note: this includes fflush()'ing the last of the prior output.
  1388.  * ----------------
  1389.  */
  1390. ReadyForQuery(whereToSendOutput);
  1391. /* ----------------
  1392.  *  (2) deal with pending asynchronous NOTIFY from other backends,
  1393.  *  and enable async.c's signal handler to execute NOTIFY directly.
  1394.  * ----------------
  1395.  */
  1396. QueryCancel = false; /* forget any earlier CANCEL signal */
  1397. EnableNotifyInterrupt();
  1398. /* ----------------
  1399.  *  (3) read a command.
  1400.  * ----------------
  1401.  */
  1402. MemSet(parser_input, 0, MAX_PARSE_BUFFER);
  1403. firstchar = ReadCommand(parser_input);
  1404. QueryCancel = false; /* forget any earlier CANCEL signal */
  1405. /* ----------------
  1406.  *  (4) disable async.c's signal handler.
  1407.  * ----------------
  1408.  */
  1409. DisableNotifyInterrupt();
  1410. /* ----------------
  1411.  *  (5) process the command.
  1412.  * ----------------
  1413.  */
  1414. switch (firstchar)
  1415. {
  1416. /* ----------------
  1417.  * 'F' indicates a fastpath call.
  1418.  * XXX HandleFunctionRequest
  1419.  * ----------------
  1420.  */
  1421. case 'F':
  1422. IsEmptyQuery = false;
  1423. /* start an xact for this function invocation */
  1424. if (Verbose)
  1425. TPRINTF(TRACE_VERBOSE, "StartTransactionCommand");
  1426. StartTransactionCommand();
  1427. HandleFunctionRequest();
  1428. break;
  1429. /* ----------------
  1430.  * 'Q' indicates a user query
  1431.  * ----------------
  1432.  */
  1433. case 'Q':
  1434. if (strspn(parser_input, " tn") == strlen(parser_input))
  1435. {
  1436. /* ----------------
  1437.  * if there is nothing in the input buffer, don't bother
  1438.  * trying to parse and execute anything..
  1439.  * ----------------
  1440.  */
  1441. IsEmptyQuery = true;
  1442. }
  1443. else
  1444. {
  1445. /* ----------------
  1446.  * otherwise, process the input string.
  1447.  * ----------------
  1448.  */
  1449. IsEmptyQuery = false;
  1450. if (ShowStats)
  1451. ResetUsage();
  1452. /* start an xact for this query */
  1453. if (Verbose)
  1454. TPRINTF(TRACE_VERBOSE, "StartTransactionCommand");
  1455. StartTransactionCommand();
  1456. pg_exec_query(parser_input);
  1457. if (ShowStats)
  1458. ShowUsage();
  1459. }
  1460. break;
  1461. /* ----------------
  1462.  * 'X' means that the frontend is closing down the socket
  1463.  * ----------------
  1464.  */
  1465. case 'X':
  1466. pq_close();
  1467. proc_exit(0);
  1468. break;
  1469. default:
  1470. elog(ERROR, "unknown frontend message was received");
  1471. }
  1472. /* ----------------
  1473.  *  (6) commit the current transaction
  1474.  *
  1475.  *  Note: if we had an empty input buffer, then we didn't
  1476.  *  call pg_exec_query, so we don't bother to commit this transaction.
  1477.  * ----------------
  1478.  */
  1479. if (!IsEmptyQuery)
  1480. {
  1481. if (Verbose)
  1482. TPRINTF(TRACE_VERBOSE, "CommitTransactionCommand");
  1483. PS_SET_STATUS("commit");
  1484. CommitTransactionCommand();
  1485. }
  1486. else
  1487. {
  1488. if (IsUnderPostmaster)
  1489. NullCommand(Remote);
  1490. }
  1491. } /* infinite for-loop */
  1492. proc_exit(0); /* shouldn't get here... */
  1493. return 1;
  1494. }
  1495. #ifndef HAVE_GETRUSAGE
  1496. #include "rusagestub.h"
  1497. #else /* HAVE_GETRUSAGE */
  1498. #include <sys/resource.h>
  1499. #endif  /* HAVE_GETRUSAGE */
  1500. struct rusage Save_r;
  1501. struct timeval Save_t;
  1502. void
  1503. ResetUsage(void)
  1504. {
  1505. struct timezone tz;
  1506. getrusage(RUSAGE_SELF, &Save_r);
  1507. gettimeofday(&Save_t, &tz);
  1508. ResetBufferUsage();
  1509. /*   ResetTupleCount(); */
  1510. }
  1511. void
  1512. ShowUsage(void)
  1513. {
  1514. struct timeval user,
  1515. sys;
  1516. struct timeval elapse_t;
  1517. struct timezone tz;
  1518. struct rusage r;
  1519. getrusage(RUSAGE_SELF, &r);
  1520. gettimeofday(&elapse_t, &tz);
  1521. memmove((char *) &user, (char *) &r.ru_utime, sizeof(user));
  1522. memmove((char *) &sys, (char *) &r.ru_stime, sizeof(sys));
  1523. if (elapse_t.tv_usec < Save_t.tv_usec)
  1524. {
  1525. elapse_t.tv_sec--;
  1526. elapse_t.tv_usec += 1000000;
  1527. }
  1528. if (r.ru_utime.tv_usec < Save_r.ru_utime.tv_usec)
  1529. {
  1530. r.ru_utime.tv_sec--;
  1531. r.ru_utime.tv_usec += 1000000;
  1532. }
  1533. if (r.ru_stime.tv_usec < Save_r.ru_stime.tv_usec)
  1534. {
  1535. r.ru_stime.tv_sec--;
  1536. r.ru_stime.tv_usec += 1000000;
  1537. }
  1538. /*
  1539.  * the only stats we don't show here are for memory usage -- i can't
  1540.  * figure out how to interpret the relevant fields in the rusage
  1541.  * struct, and they change names across o/s platforms, anyway. if you
  1542.  * can figure out what the entries mean, you can somehow extract
  1543.  * resident set size, shared text size, and unshared data and stack
  1544.  * sizes.
  1545.  */
  1546. fprintf(StatFp, "! system usage stats:n");
  1547. fprintf(StatFp,
  1548. "!t%ld.%06ld elapsed %ld.%06ld user %ld.%06ld system secn",
  1549. (long int) elapse_t.tv_sec - Save_t.tv_sec,
  1550. (long int) elapse_t.tv_usec - Save_t.tv_usec,
  1551. (long int) r.ru_utime.tv_sec - Save_r.ru_utime.tv_sec,
  1552. (long int) r.ru_utime.tv_usec - Save_r.ru_utime.tv_usec,
  1553. (long int) r.ru_stime.tv_sec - Save_r.ru_stime.tv_sec,
  1554. (long int) r.ru_stime.tv_usec - Save_r.ru_stime.tv_usec);
  1555. fprintf(StatFp,
  1556. "!t[%ld.%06ld user %ld.%06ld sys total]n",
  1557. (long int) user.tv_sec,
  1558. (long int) user.tv_usec,
  1559. (long int) sys.tv_sec,
  1560. (long int) sys.tv_usec);
  1561. #ifdef HAVE_GETRUSAGE
  1562. fprintf(StatFp,
  1563. "!t%ld/%ld [%ld/%ld] filesystem blocks in/outn",
  1564. r.ru_inblock - Save_r.ru_inblock,
  1565. /* they only drink coffee at dec */
  1566. r.ru_oublock - Save_r.ru_oublock,
  1567. r.ru_inblock, r.ru_oublock);
  1568. fprintf(StatFp,
  1569.   "!t%ld/%ld [%ld/%ld] page faults/reclaims, %ld [%ld] swapsn",
  1570. r.ru_majflt - Save_r.ru_majflt,
  1571. r.ru_minflt - Save_r.ru_minflt,
  1572. r.ru_majflt, r.ru_minflt,
  1573. r.ru_nswap - Save_r.ru_nswap,
  1574. r.ru_nswap);
  1575. fprintf(StatFp,
  1576.  "!t%ld [%ld] signals rcvd, %ld/%ld [%ld/%ld] messages rcvd/sentn",
  1577. r.ru_nsignals - Save_r.ru_nsignals,
  1578. r.ru_nsignals,
  1579. r.ru_msgrcv - Save_r.ru_msgrcv,
  1580. r.ru_msgsnd - Save_r.ru_msgsnd,
  1581. r.ru_msgrcv, r.ru_msgsnd);
  1582. fprintf(StatFp,
  1583.  "!t%ld/%ld [%ld/%ld] voluntary/involuntary context switchesn",
  1584. r.ru_nvcsw - Save_r.ru_nvcsw,
  1585. r.ru_nivcsw - Save_r.ru_nivcsw,
  1586. r.ru_nvcsw, r.ru_nivcsw);
  1587. #endif  /* HAVE_GETRUSAGE */
  1588. fprintf(StatFp, "! postgres usage stats:n");
  1589. PrintBufferUsage(StatFp);
  1590. /*    DisplayTupleCount(StatFp); */
  1591. }
  1592. #ifdef USE_ASSERT_CHECKING
  1593. int
  1594. assertEnable(int val)
  1595. {
  1596. assert_enabled = val;
  1597. return val;
  1598. }
  1599. #ifdef ASSERT_CHECKING_TEST
  1600. int
  1601. assertTest(int val)
  1602. {
  1603. Assert(val == 0);
  1604. if (assert_enabled)
  1605. {
  1606. /* val != 0 should be trapped by previous Assert */
  1607. elog(NOTICE, "Assert test successfull (val = %d)", val);
  1608. }
  1609. else
  1610. elog(NOTICE, "Assert checking is disabled (val = %d)", val);
  1611. return val;
  1612. }
  1613. #endif
  1614. #endif