⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 postgres.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
📖 第 1 页 / 共 3 页
字号:
					TPRINTF(TRACE_PRETTY_PLAN, "plan:");					nodeDisplay(plan);				}				else				{					TPRINTF(TRACE_PLAN, "plan:");					printf("\n%s\n\n", nodeToString(plan));				}			}#endif		}		/*		 * If the command is an utility append a null plan. This is needed		 * to keep the plan_list aligned with the querytree_list or the		 * function executor will crash.  DZ - 30-8-1996		 */		else			plan_list = lappend(plan_list, NULL);	}	if (queryListP)		*queryListP = querytree_list;	return plan_list;}/* ---------------------------------------------------------------- *		pg_exec_query() * *		Takes a querystring, runs the parser/utilities or *		parser/planner/executor over it as necessary *		Begin Transaction Should have been called before this *		and CommitTransaction After this is called *		This is strictly because we do not allow for nested xactions. * *		NON-OBVIOUS-RESTRICTIONS *		this function _MUST_ allocate a new "parsetree" each time, *		since it may be stored in a named portal and should not *		change its value. * * ---------------------------------------------------------------- */static voidpg_exec_query(char *query_string){	pg_exec_query_dest(query_string, whereToSendOutput, FALSE);}voidpg_exec_query_acl_override(char *query_string){	pg_exec_query_dest(query_string, whereToSendOutput, TRUE);}voidpg_exec_query_dest(char *query_string,	/* string to execute */				   CommandDest dest,	/* where results should go */				   bool aclOverride)	/* to give utility commands power										 * of superusers */{	List	   *querytree_list;	List	   *plan_list;	Query	   *querytree;	Plan	   *plan;	int			j;	/* plan the queries */	plan_list = pg_parse_and_plan(query_string, NULL, 0,								  &querytree_list, dest, aclOverride);	/* if we got a cancel signal whilst planning, quit */	if (QueryCancel)		CancelQuery();	/* OK, do it to it! */	/*	 * NOTE: we do not use "foreach" here because we want to be sure the	 * list pointers have been advanced before the query is executed. We	 * need to do that because VACUUM has a nasty little habit of doing	 * CommitTransactionCommand at startup, and that will release the	 * memory holding our parse/plan lists :-(.  This needs a better	 * solution --- currently, the code will crash if someone submits	 * "vacuum; something-else" in a single query string.  But memory	 * allocation needs redesigned anyway, so this will have to do for	 * now.	 */	while (querytree_list)	{		querytree = (Query *) lfirst(querytree_list);		querytree_list = lnext(querytree_list);		plan = (Plan *) lfirst(plan_list);		plan_list = lnext(plan_list);		if (querytree->commandType == CMD_UTILITY)		{			/* ----------------			 *	 process utility functions (create, destroy, etc..)			 *			 *	 Note: we do not check for the transaction aborted state			 *	 because that is done in ProcessUtility.			 * ----------------			 */			if (DebugPrintQuery)				TPRINTF(TRACE_QUERY, "ProcessUtility: %s", query_string);			else if (Verbose)				TPRINTF(TRACE_VERBOSE, "ProcessUtility");			/*			 * We have to set query SnapShot in the case of FETCH or COPY TO.			 */			if (nodeTag(querytree->utilityStmt) == T_FetchStmt ||				(nodeTag(querytree->utilityStmt) == T_CopyStmt && 				((CopyStmt *)(querytree->utilityStmt))->direction != FROM))				SetQuerySnapshot();			ProcessUtility(querytree->utilityStmt, dest);		}		else		{#ifdef INDEXSCAN_PATCH			/*			 * Print moved in pg_parse_and_plan.	DZ - 27-8-1996			 */#else			/* ----------------			 *	print plan if debugging			 * ----------------			 */			if (DebugPrintPlan || DebugPPrintPlan)			{				if (DebugPPrintPlan)				{					TPRINTF(TRACE_PRETTY_PLAN, "plan:");					nodeDisplay(plan);				}				else				{					TPRINTF(TRACE_PLAN, "plan:");					printf("\n%s\n\n", nodeToString(plan));				}			}#endif			SetQuerySnapshot();			/*			 * execute the plan			 */			if (ShowExecutorStats)				ResetUsage();			for (j = 0; j < _exec_repeat_; j++)			{				if (Verbose)					TPRINTF(TRACE_VERBOSE, "ProcessQuery");				ProcessQuery(querytree, plan, dest);			}			if (ShowExecutorStats)			{				fprintf(stderr, "! Executor Stats:\n");				ShowUsage();			}		}		/*		 * In a query block, we want to increment the command counter		 * between queries so that the effects of early queries are		 * visible to subsequent ones.		 */		CommandCounterIncrement();	}}/* -------------------------------- *		signal handler routines used in PostgresMain() * *		handle_warn() catches SIGQUIT.	It forces control back to the main *		loop, just as if an internal error (elog(ERROR,...)) had occurred. *		elog() used to actually use kill(2) to induce a SIGQUIT to get here! *		But that's not 100% reliable on some systems, so now it does its own *		siglongjmp() instead. *		We still provide the signal catcher so that an error quit can be *		forced externally.	This should be done only with great caution, *		however, since an asynchronous signal could leave the system in *		who-knows-what inconsistent state. * *		quickdie() occurs when signalled by the postmaster. *		Some backend has bought the farm, *		so we need to stop what we're doing and exit. * *		die() performs an orderly cleanup via ExitPostgres() * -------------------------------- */voidhandle_warn(SIGNAL_ARGS){	siglongjmp(Warn_restart, 1);}voidquickdie(SIGNAL_ARGS){	elog(NOTICE, "Message from PostgreSQL backend:"		 "\n\tThe Postmaster has informed me that some other backend"		 " died abnormally and possibly corrupted shared memory."		 "\n\tI have rolled back the current transaction and am"		 " going to terminate your database system connection and exit."	"\n\tPlease reconnect to the database system and repeat your query.");	/*	 * DO NOT ExitPostgres(0) -- we're here because shared memory may be	 * corrupted, so we don't want to flush any shared state to stable	 * storage.  Just nail the windows shut and get out of town.	 */	exit(0);}voiddie(SIGNAL_ARGS){	ExitPostgres(0);}/* signal handler for floating point exception */voidFloatExceptionHandler(SIGNAL_ARGS){	elog(ERROR, "floating point exception!"		 " The last floating point operation either exceeded legal ranges"		 " or was a divide by zero");}/* signal handler for query cancel signal from postmaster */static voidQueryCancelHandler(SIGNAL_ARGS){	QueryCancel = true;}voidCancelQuery(void){	/*	 * QueryCancel flag will be reset in main loop, which we reach by	 * longjmp from elog().	 */	elog(ERROR, "Query was cancelled.");}static voidusage(char *progname){	fprintf(stderr,			"Usage: %s [options] [dbname]\n", progname);#ifdef USE_ASSERT_CHECKING	fprintf(stderr, "\t-A on\t\tenable/disable assert checking\n");#endif	fprintf(stderr, "\t-B buffers\tset number of buffers in buffer pool\n");	fprintf(stderr, "\t-C \t\tsuppress version info\n");	fprintf(stderr, "\t-D dir\t\tdata directory\n");	fprintf(stderr, "\t-E \t\techo query before execution\n");	fprintf(stderr, "\t-F \t\tturn off fsync\n");#ifdef LOCK_MGR_DEBUG	fprintf(stderr, "\t-K lev\t\tset locking debug level [0|1|2]\n");#endif	fprintf(stderr, "\t-L \t\tturn off locking\n");	fprintf(stderr, "\t-N \t\tdon't use newline as interactive query delimiter\n");	fprintf(stderr, "\t-O \t\tallow system table structure changes\n");	fprintf(stderr, "\t-Q \t\tsuppress informational messages\n");	fprintf(stderr, "\t-S kbytes\tset amount of memory for sorts (in kbytes)\n");	fprintf(stderr, "\t-T options\tspecify pg_options\n");	fprintf(stderr, "\t-W sec\t\twait N seconds to allow attach from a debugger\n");	fprintf(stderr, "\t-d [1|2|3]\tset debug level\n");	fprintf(stderr, "\t-e \t\tturn on European date format\n");	fprintf(stderr, "\t-f [s|i|n|m|h]\tforbid use of some plan types\n");	fprintf(stderr, "\t-i \t\tdon't execute queries\n");	fprintf(stderr, "\t-o file\t\tsend stdout and stderr to given filename\n");	fprintf(stderr, "\t-p database\tbackend is started under a postmaster\n");	fprintf(stderr, "\t-s \t\tshow stats after each query\n");	fprintf(stderr, "\t-t [pa|pl|ex]\tshow timings after each query\n");	fprintf(stderr, "\t-v version\tset protocol version being used by frontend\n");}/* ---------------------------------------------------------------- *	PostgresMain *		postgres main loop *		all backends, interactive or otherwise start here * *	argc/argv are the command line arguments to be used.  When being forked *	by the postmaster, these are not the original argv array of the process. *	real_argc/real_argv point to the original argv array, which is needed by *	PS_INIT_STATUS on some platforms. * ---------------------------------------------------------------- */intPostgresMain(int argc, char *argv[], int real_argc, char *real_argv[]){	int			flag;	char	   *DBName = NULL;	bool		secure = true;	int			errs = 0;	char		firstchar;	char		parser_input[MAX_PARSE_BUFFER];	char	   *userName;	/* Used if verbose is set, must be initialized */	char	   *remote_info = "interactive";	char	   *remote_host = "";	unsigned short remote_port = 0;	char	   *DBDate = NULL;	extern int	optind;	extern char *optarg;	extern short DebugLvl;	/*	 * Set default values for command-line options.	 */	IsUnderPostmaster = false;	ShowStats = 0;	ShowParserStats = ShowPlannerStats = ShowExecutorStats = 0;	DeadlockCheckTimer = DEADLOCK_CHECK_TIMER;	Noversion = false;	EchoQuery = false;#ifdef LOCK_MGR_DEBUG	LockDebug = 0;#endif	DataDir = getenv("PGDATA");	/*	 * Try to get initial values for date styles and formats. Does not do	 * a complete job, but should be good enough for backend. Cannot call	 * parse_date() since palloc/pfree memory is not set up yet.	 */	DBDate = getenv("PGDATESTYLE");	if (DBDate != NULL)	{		if (strcasecmp(DBDate, "ISO") == 0)			DateStyle = USE_ISO_DATES;		else if (strcasecmp(DBDate, "SQL") == 0)			DateStyle = USE_SQL_DATES;		else if (strcasecmp(DBDate, "POSTGRES") == 0)			DateStyle = USE_POSTGRES_DATES;		else if (strcasecmp(DBDate, "GERMAN") == 0)		{			DateStyle = USE_GERMAN_DATES;			EuroDates = TRUE;		}		else if (strcasecmp(DBDate, "NONEURO") == 0)			EuroDates = FALSE;		else if (strcasecmp(DBDate, "EURO") == 0)			EuroDates = TRUE;	}	/*	 * Read default pg_options from file $DATADIR/pg_options.	 */	if (DataDir)		read_pg_options(0);	/* ----------------	 *	parse command line arguments	 *	 *	There are now two styles of command line layout for the backend:	 *	 *	For interactive use (not started from postmaster) the format is	 *		postgres [switches] [databasename]	 *	If the databasename is omitted it is taken to be the user name.	 *	 *	When started from the postmaster, the format is	 *		postgres [secure switches] -p databasename [insecure switches]	 *	Switches appearing after -p came from the client (via "options"	 *	field of connection request).  For security reasons we restrict	 *	what these switches can do.	 * ----------------	 */	optind = 1;					/* reset after postmaster's usage */	while ((flag = getopt(argc, argv,						  "A:B:CD:d:EeFf:iK:LNOo:p:QS:sT:t:v:W:x:"))		   != EOF)		switch (flag)		{			case 'A':				/* ----------------				 *	enable/disable assert checking.				 * ----------------				 */#ifdef USE_ASSERT_CHECKING				assert_enabled = atoi(optarg);#else				fprintf(stderr, "Assert checking is not enabled\n");#endif				break;			case 'B':				/* ----------------				 *	specify the size of buffer pool				 * ----------------				 */				if (secure)					NBuffers = atoi(optarg);				break;			case 'C':				/* ----------------				 *	don't print version string				 * ----------------				 */				Noversion = true;				break;			case 'D':			/* PGDATA directory */				if (secure)				{					if (!DataDir)					{						DataDir = optarg;						/* must be done after DataDir is defined */						read_pg_options(0);					}					DataDir = optarg;				}				break;			case 'd':			/* debug level */				DebugLvl = (short) atoi(optarg);				if (DebugLvl >= 1)					Verbose = DebugLvl;				if (DebugLvl >= 2)					DebugPrintQuery = true;				if (DebugLvl >= 3)					DebugPrintQuery = DebugLvl;				if (DebugLvl >= 4)				{					DebugPrintParse = true;					DebugPrintPlan = true;					DebugPrintRewrittenParsetree = true;				}				if (DebugLvl >= 5)				{					DebugPPrintParse = true;					DebugPPrintPlan = true;					DebugPPrintRewrittenParsetree = true;				}				break;			case 'E':				/* ----------------				 *	E - echo the query the user entered				 * ----------------				 */				EchoQuery = true;				break;			case 'e':				/* --------------------------				 * Use european date formats.				 * --------------------------				 */				EuroDates = true;				break;			case 'F':				/* --------------------				 *	turn off fsync				 * --------------------				 */				if (secure)					disableFsync = true;				break;			case 'f':				/* -----------------				 *	  f - forbid generation of certain plans				 * -----------------				 */				switch (optarg[0])				{					case 's':	/* seqscan */						_enable_seqscan_ = false;						break;					case 'i':	/* indexscan */						_enable_indexscan_ = false;						break;					case 'n':	/* nestloop */						_enable_nestloop_ = false;						break;					case 'm':	/* mergejoin */						_enable_mergejoin_ = false;						break;					case 'h':	/* hashjoin */						_enable_hashjoin_ = false;						break;					default:						errs++;				}				break;			case 'i':				dontExecute = 1;				break;			case 'K':#ifdef LOCK_MGR_DEBUG				LockDebug = atoi(optarg);#else				fprintf(stderr, "Lock debug not compiled in\n");#endif				break;			case 'L':				/* --------------------				 *	turn off locking				 * --------------------				 */				if (secure)					lockingOff = 1;				break;			case 'N':				/* ----------------				 *	N - Don't use newline as a query delimiter				 * ----------------				 */				UseNewLine = 0;				break;			case 'O':				/* --------------------				 *	allow system table structure modifications				 * --------------------				 */				if (secure)		/* XXX safe to allow from client??? */					allowSystemTableMods = true;				break;			case 'o':				/* ----------------				 *	o - send output (stdout and stderr) to the given file				 * ----------------				 */				if (secure)					StrNCpy(OutputFileName, optarg, MAXPGPATH);				break;			case 'p':				/* ----------------				 *	p - special flag passed if backend was forked				 *		by a postmaster.				 * ----------------				 */				if (secure)				{					IsUnderPostmaster = true;					DBName = optarg;					secure = false;		/* subsequent switches are NOT										 * secure */				}				break;			case 'Q':				/* ----------------				 *	Q - set Quiet mode (reduce debugging output)				 * ----------------				 */				Verbose = 0;				break;			case 'S':				/* ----------------				 *	S - amount of sort memory to use in 1k bytes				 * ----------------				 */				{					int			S;					S = atoi(optarg);					if (S >= 4 * BLCKSZ / 1024)						SortMem = S;				}				break;			case 's':				/* ----------------				 *	  s - report usage statistics (timings) after each query				 * ----------------				 */				ShowStats = 1;				StatFp = stderr;				break;			case 'T':

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -