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

📄 pquery.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
字号:
/*------------------------------------------------------------------------- * * pquery.c *	  POSTGRES process query command code * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION *	  $Header: /usr/local/cvsroot/pgsql/src/backend/tcop/pquery.c,v 1.23 1999/05/25 16:11:41 momjian Exp $ * *------------------------------------------------------------------------- */#include <string.h>#include "postgres.h"#include "tcop/tcopdebug.h"#include "utils/palloc.h"#include "nodes/nodes.h"#include "utils/mcxt.h"#include "miscadmin.h"#include "utils/portal.h"#include "nodes/pg_list.h"#include "nodes/primnodes.h"#include "nodes/plannodes.h"#include "nodes/execnodes.h"#include "nodes/memnodes.h"#include "tcop/dest.h"#include "executor/execdefs.h"#include "executor/execdesc.h"#include "executor/executor.h"#include "tcop/pquery.h"#include "utils/ps_status.h"#include "commands/command.h"static char *CreateOperationTag(int operationType);static void ProcessQueryDesc(QueryDesc *queryDesc, Node *limoffset,				 Node *limcount);/* ---------------------------------------------------------------- *		CreateQueryDesc * ---------------------------------------------------------------- */QueryDesc  *CreateQueryDesc(Query *parsetree,				Plan *plantree,				CommandDest dest){	QueryDesc  *qd = (QueryDesc *) palloc(sizeof(QueryDesc));	qd->operation = parsetree->commandType;		/* operation */	qd->parsetree = parsetree;	/* parse tree */	qd->plantree = plantree;	/* plan */	qd->dest = dest;			/* output dest */	return qd;}/* ---------------------------------------------------------------- *		CreateExecutorState * *		Note: this may someday take parameters -cim 9/18/89 * ---------------------------------------------------------------- */EState *CreateExecutorState(void){	EState	   *state;	extern int	NBuffers;	long	   *refcount;	/* ----------------	 *	create a new executor state	 * ----------------	 */	state = makeNode(EState);	/* ----------------	 *	initialize the Executor State structure	 * ----------------	 */	state->es_direction = ForwardScanDirection;	state->es_range_table = NIL;	state->es_into_relation_descriptor = NULL;	state->es_result_relation_info = NULL;	state->es_param_list_info = NULL;	state->es_param_exec_vals = NULL;	state->es_BaseId = 0;	state->es_tupleTable = NULL;	state->es_junkFilter = NULL;	refcount = (long *) palloc(NBuffers * sizeof(long));	MemSet((char *) refcount, 0, NBuffers * sizeof(long));	state->es_refcount = (int *) refcount;	/* ----------------	 *	return the executor state structure	 * ----------------	 */	return state;}/* ---------------------------------------------------------------- *		CreateOperationTag * *		utility to get a string representation of the *		query operation. * ---------------------------------------------------------------- */static char *CreateOperationTag(int operationType){	char	   *tag;	switch (operationType)	{		case CMD_SELECT:			tag = "SELECT";			break;		case CMD_INSERT:			tag = "INSERT";			break;		case CMD_DELETE:			tag = "DELETE";			break;		case CMD_UPDATE:			tag = "UPDATE";			break;		default:			elog(DEBUG, "CreateOperationTag: unknown operation type %d",				 operationType);			tag = NULL;			break;	}	return tag;}/* ---------------- *		ProcessPortal * ---------------- */voidProcessPortal(char *portalName,			  Query *parseTree,			  Plan *plan,			  EState *state,			  TupleDesc attinfo,			  CommandDest dest){	Portal		portal;	MemoryContext portalContext;	/* ----------------	 *	 convert the current blank portal into the user-specified	 *	 portal and initialize the state and query descriptor.	 * ----------------	 */	if (PortalNameIsSpecial(portalName))		elog(ERROR,			 "The portal name %s is reserved for internal use",			 portalName);	portal = BlankPortalAssignName(portalName);	PortalSetQuery(portal,				   CreateQueryDesc(parseTree, plan, dest),				   attinfo,				   state,				   PortalCleanup);	/* ----------------	 *	now create a new blank portal and switch to it.	 *	Otherwise, the new named portal will be cleaned.	 *	 *	Note: portals will only be supported within a BEGIN...END	 *	block in the near future.  Later, someone will fix it to	 *	do what is possible across transaction boundries. -hirohama	 * ----------------	 */	portalContext = (MemoryContext) PortalGetHeapMemory(GetPortalByName(NULL));	MemoryContextSwitchTo(portalContext);	StartPortalAllocMode(DefaultAllocMode, 0);}/* ---------------------------------------------------------------- *		ProcessQueryDesc * *		Read the comments for ProcessQuery() below... * ---------------------------------------------------------------- */static voidProcessQueryDesc(QueryDesc *queryDesc, Node *limoffset, Node *limcount){	Query	   *parseTree;	Plan	   *plan;	int			operation;	char	   *tag = NULL;	EState	   *state;	TupleDesc	attinfo;	bool		isRetrieveIntoPortal;	bool		isRetrieveIntoRelation;	char	   *intoName = NULL;	CommandDest dest;	/* ----------------	 *	get info from the query desc	 * ----------------	 */	parseTree = queryDesc->parsetree;	plan = queryDesc->plantree;	operation = queryDesc->operation;	PS_SET_STATUS(tag = CreateOperationTag(operation));	dest = queryDesc->dest;	/* ----------------	 *	initialize portal/into relation status	 * ----------------	 */	isRetrieveIntoPortal = false;	isRetrieveIntoRelation = false;	if (operation == CMD_SELECT)	{		if (parseTree->isPortal)		{			isRetrieveIntoPortal = true;			intoName = parseTree->into;			if (parseTree->isBinary)			{				/*				 * For internal format portals, we change Remote				 * (externalized form) to RemoteInternal (internalized				 * form)				 */				dest = queryDesc->dest = RemoteInternal;			}		}		else if (parseTree->into != NULL)		{			/* select into table */			isRetrieveIntoRelation = true;		}	}	/* ----------------	 *	when performing a retrieve into, we override the normal	 *	communication destination during the processing of the	 *	the query.	This only affects the tuple-output function	 *	- the correct destination will still see BeginCommand()	 *	and EndCommand() messages.	 * ----------------	 */	if (isRetrieveIntoRelation)		queryDesc->dest = (int) None;	/* ----------------	 *	create a default executor state..	 * ----------------	 */	state = CreateExecutorState();	/* ----------------	 *	call ExecStart to prepare the plan for execution	 * ----------------	 */	attinfo = ExecutorStart(queryDesc, state);	/* ----------------	 *	 report the query's result type information	 *	 back to the front end or to whatever destination	 *	 we're dealing with.	 * ----------------	 */	BeginCommand(NULL,				 operation,				 attinfo,				 isRetrieveIntoRelation,				 isRetrieveIntoPortal,				 tag,				 dest);	/* ----------------	 *	Named portals do not do a "fetch all" initially, so now	 *	we return since ExecMain has been called with EXEC_START	 *	to initialize the query plan.	 *	 *	Note: ProcessPortal transforms the current "blank" portal	 *		  into a named portal and creates a new blank portal so	 *		  everything we allocated in the current "blank" memory	 *		  context will be preserved across queries.  -cim 2/22/91	 * ----------------	 */	if (isRetrieveIntoPortal)	{		PortalExecutorHeapMemory = NULL;		ProcessPortal(intoName,					  parseTree,					  plan,					  state,					  attinfo,					  dest);		EndCommand(tag, dest);		return;	}	/* ----------------	 *	 Now we get to the important call to ExecutorRun() where we	 *	 actually run the plan..	 * ----------------	 */	ExecutorRun(queryDesc, state, EXEC_RUN, limoffset, limcount);	/* save infos for EndCommand */	UpdateCommandInfo(operation, state->es_lastoid, state->es_processed);	/* ----------------	 *	 now, we close down all the scans and free allocated resources...	 * with ExecutorEnd()	 * ----------------	 */	ExecutorEnd(queryDesc, state);	/* ----------------	 *	Notify the destination of end of processing.	 * ----------------	 */	EndCommand(tag, dest);}/* ---------------------------------------------------------------- *		ProcessQuery * *		Execute a plan, the non-parallel version * ---------------------------------------------------------------- */voidProcessQuery(Query *parsetree,			 Plan *plan,			 CommandDest dest){	QueryDesc  *queryDesc;	extern int	dontExecute;	/* from postgres.c */	extern void print_plan(Plan *p, Query *parsetree);	/* from print.c */	queryDesc = CreateQueryDesc(parsetree, plan, dest);	if (dontExecute)	{		/* don't execute it, just show the query plan */		print_plan(plan, parsetree);	}	else		ProcessQueryDesc(queryDesc, parsetree->limitOffset,						 parsetree->limitCount);}

⌨️ 快捷键说明

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