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

📄 fe-exec.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 5 页
字号:
		else			newTuples = (PGresAttValue **)				realloc(res->tuples, newSize * sizeof(PGresAttValue *));		if (!newTuples)			return FALSE;		/* malloc or realloc failed */		res->tupArrSize = newSize;		res->tuples = newTuples;	}	res->tuples[res->ntups] = tup;	res->ntups++;	return TRUE;}/* * pqSaveMessageField - save one field of an error or notice message */voidpqSaveMessageField(PGresult *res, char code, const char *value){	PGMessageField *pfield;	pfield = (PGMessageField *)		pqResultAlloc(res,					  sizeof(PGMessageField) + strlen(value),					  TRUE);	if (!pfield)		return;					/* out of memory? */	pfield->code = code;	strcpy(pfield->contents, value);	pfield->next = res->errFields;	res->errFields = pfield;}/* * pqSaveParameterStatus - remember parameter status sent by backend */voidpqSaveParameterStatus(PGconn *conn, const char *name, const char *value){	pgParameterStatus *pstatus;	pgParameterStatus *prev;	if (conn->Pfdebug)		fprintf(conn->Pfdebug, "pqSaveParameterStatus: '%s' = '%s'\n",				name, value);	/*	 * Forget any old information about the parameter	 */	for (pstatus = conn->pstatus, prev = NULL;		 pstatus != NULL;		 prev = pstatus, pstatus = pstatus->next)	{		if (strcmp(pstatus->name, name) == 0)		{			if (prev)				prev->next = pstatus->next;			else				conn->pstatus = pstatus->next;			free(pstatus);		/* frees name and value strings too */			break;		}	}	/*	 * Store new info as a single malloc block	 */	pstatus = (pgParameterStatus *) malloc(sizeof(pgParameterStatus) +										   strlen(name) +strlen(value) + 2);	if (pstatus)	{		char	   *ptr;		ptr = ((char *) pstatus) + sizeof(pgParameterStatus);		pstatus->name = ptr;		strcpy(ptr, name);		ptr += strlen(name) + 1;		pstatus->value = ptr;		strcpy(ptr, value);		pstatus->next = conn->pstatus;		conn->pstatus = pstatus;	}	/*	 * Special hacks: remember client_encoding and standard_conforming_strings,	 * and convert server version to a numeric form.  We keep the first two of	 * these in static variables as well, so that PQescapeString and	 * PQescapeBytea can behave somewhat sanely (at least in single-	 * connection-using programs).	 */	if (strcmp(name, "client_encoding") == 0)	{		conn->client_encoding = pg_char_to_encoding(value);		static_client_encoding = conn->client_encoding;	}	else if (strcmp(name, "standard_conforming_strings") == 0)	{		conn->std_strings = (strcmp(value, "on") == 0);		static_std_strings = conn->std_strings;	}	else if (strcmp(name, "server_version") == 0)	{		int			cnt;		int			vmaj,					vmin,					vrev;		cnt = sscanf(value, "%d.%d.%d", &vmaj, &vmin, &vrev);		if (cnt < 2)			conn->sversion = 0; /* unknown */		else		{			if (cnt == 2)				vrev = 0;			conn->sversion = (100 * vmaj + vmin) * 100 + vrev;		}	}}/* * PQsendQuery *	 Submit a query, but don't wait for it to finish * * Returns: 1 if successfully submitted *			0 if error (conn->errorMessage is set) */intPQsendQuery(PGconn *conn, const char *query){	if (!PQsendQueryStart(conn))		return 0;	if (!query)	{		printfPQExpBuffer(&conn->errorMessage,						libpq_gettext("command string is a null pointer\n"));		return 0;	}	/* construct the outgoing Query message */	if (pqPutMsgStart('Q', false, conn) < 0 ||		pqPuts(query, conn) < 0 ||		pqPutMsgEnd(conn) < 0)	{		pqHandleSendFailure(conn);		return 0;	}	/* remember we are using simple query protocol */	conn->queryclass = PGQUERY_SIMPLE;	/*	 * Give the data a push.  In nonblock mode, don't complain if we're unable	 * to send it all; PQgetResult() will do any additional flushing needed.	 */	if (pqFlush(conn) < 0)	{		pqHandleSendFailure(conn);		return 0;	}	/* OK, it's launched! */	conn->asyncStatus = PGASYNC_BUSY;	return 1;}/* * PQsendQueryParams *		Like PQsendQuery, but use protocol 3.0 so we can pass parameters */intPQsendQueryParams(PGconn *conn,				  const char *command,				  int nParams,				  const Oid *paramTypes,				  const char *const * paramValues,				  const int *paramLengths,				  const int *paramFormats,				  int resultFormat){	if (!PQsendQueryStart(conn))		return 0;	if (!command)	{		printfPQExpBuffer(&conn->errorMessage,						libpq_gettext("command string is a null pointer\n"));		return 0;	}	return PQsendQueryGuts(conn,						   command,						   "",	/* use unnamed statement */						   nParams,						   paramTypes,						   paramValues,						   paramLengths,						   paramFormats,						   resultFormat);}/* * PQsendPrepare *	 Submit a Parse message, but don't wait for it to finish * * Returns: 1 if successfully submitted *			0 if error (conn->errorMessage is set) */intPQsendPrepare(PGconn *conn,			  const char *stmtName, const char *query,			  int nParams, const Oid *paramTypes){	if (!PQsendQueryStart(conn))		return 0;	if (!stmtName)	{		printfPQExpBuffer(&conn->errorMessage,						libpq_gettext("statement name is a null pointer\n"));		return 0;	}	if (!query)	{		printfPQExpBuffer(&conn->errorMessage,						libpq_gettext("command string is a null pointer\n"));		return 0;	}	/* This isn't gonna work on a 2.0 server */	if (PG_PROTOCOL_MAJOR(conn->pversion) < 3)	{		printfPQExpBuffer(&conn->errorMessage,		 libpq_gettext("function requires at least protocol version 3.0\n"));		return 0;	}	/* construct the Parse message */	if (pqPutMsgStart('P', false, conn) < 0 ||		pqPuts(stmtName, conn) < 0 ||		pqPuts(query, conn) < 0)		goto sendFailed;	if (nParams > 0 && paramTypes)	{		int			i;		if (pqPutInt(nParams, 2, conn) < 0)			goto sendFailed;		for (i = 0; i < nParams; i++)		{			if (pqPutInt(paramTypes[i], 4, conn) < 0)				goto sendFailed;		}	}	else	{		if (pqPutInt(0, 2, conn) < 0)			goto sendFailed;	}	if (pqPutMsgEnd(conn) < 0)		goto sendFailed;	/* construct the Sync message */	if (pqPutMsgStart('S', false, conn) < 0 ||		pqPutMsgEnd(conn) < 0)		goto sendFailed;	/* remember we are doing just a Parse */	conn->queryclass = PGQUERY_PREPARE;	/*	 * Give the data a push.  In nonblock mode, don't complain if we're unable	 * to send it all; PQgetResult() will do any additional flushing needed.	 */	if (pqFlush(conn) < 0)		goto sendFailed;	/* OK, it's launched! */	conn->asyncStatus = PGASYNC_BUSY;	return 1;sendFailed:	pqHandleSendFailure(conn);	return 0;}/* * PQsendQueryPrepared *		Like PQsendQuery, but execute a previously prepared statement, *		using protocol 3.0 so we can pass parameters */intPQsendQueryPrepared(PGconn *conn,					const char *stmtName,					int nParams,					const char *const * paramValues,					const int *paramLengths,					const int *paramFormats,					int resultFormat){	if (!PQsendQueryStart(conn))		return 0;	if (!stmtName)	{		printfPQExpBuffer(&conn->errorMessage,						libpq_gettext("statement name is a null pointer\n"));		return 0;	}	return PQsendQueryGuts(conn,						   NULL,	/* no command to parse */						   stmtName,						   nParams,						   NULL,	/* no param types */						   paramValues,						   paramLengths,						   paramFormats,						   resultFormat);}/* * Common startup code for PQsendQuery and sibling routines */static boolPQsendQueryStart(PGconn *conn){	if (!conn)		return false;	/* clear the error string */	resetPQExpBuffer(&conn->errorMessage);	/* Don't try to send if we know there's no live connection. */	if (conn->status != CONNECTION_OK)	{		printfPQExpBuffer(&conn->errorMessage,						  libpq_gettext("no connection to the server\n"));		return false;	}	/* Can't send while already busy, either. */	if (conn->asyncStatus != PGASYNC_IDLE)	{		printfPQExpBuffer(&conn->errorMessage,				  libpq_gettext("another command is already in progress\n"));		return false;	}	/* initialize async result-accumulation state */	conn->result = NULL;	conn->curTuple = NULL;	/* ready to send command message */	return true;}/* * PQsendQueryGuts *		Common code for protocol-3.0 query sending *		PQsendQueryStart should be done already * * command may be NULL to indicate we use an already-prepared statement */static intPQsendQueryGuts(PGconn *conn,				const char *command,				const char *stmtName,				int nParams,				const Oid *paramTypes,				const char *const * paramValues,				const int *paramLengths,				const int *paramFormats,				int resultFormat){	int			i;	/* This isn't gonna work on a 2.0 server */	if (PG_PROTOCOL_MAJOR(conn->pversion) < 3)	{		printfPQExpBuffer(&conn->errorMessage,		 libpq_gettext("function requires at least protocol version 3.0\n"));		return 0;	}	/*	 * We will send Parse (if needed), Bind, Describe Portal, Execute, Sync,	 * using specified statement name and the unnamed portal.	 */	if (command)	{		/* construct the Parse message */		if (pqPutMsgStart('P', false, conn) < 0 ||			pqPuts(stmtName, conn) < 0 ||			pqPuts(command, conn) < 0)			goto sendFailed;		if (nParams > 0 && paramTypes)		{			if (pqPutInt(nParams, 2, conn) < 0)				goto sendFailed;			for (i = 0; i < nParams; i++)			{				if (pqPutInt(paramTypes[i], 4, conn) < 0)					goto sendFailed;			}		}		else		{			if (pqPutInt(0, 2, conn) < 0)				goto sendFailed;		}		if (pqPutMsgEnd(conn) < 0)			goto sendFailed;	}	/* construct the Bind message */	if (pqPutMsgStart('B', false, conn) < 0 ||		pqPuts("", conn) < 0 ||		pqPuts(stmtName, conn) < 0)		goto sendFailed;	if (nParams > 0 && paramFormats)	{		if (pqPutInt(nParams, 2, conn) < 0)			goto sendFailed;		for (i = 0; i < nParams; i++)		{			if (pqPutInt(paramFormats[i], 2, conn) < 0)				goto sendFailed;		}	}	else	{		if (pqPutInt(0, 2, conn) < 0)			goto sendFailed;	}	if (pqPutInt(nParams, 2, conn) < 0)		goto sendFailed;	for (i = 0; i < nParams; i++)	{		if (paramValues && paramValues[i])		{			int			nbytes;			if (paramFormats && paramFormats[i] != 0)			{				/* binary parameter */				if (paramLengths)					nbytes = paramLengths[i];				else				{					printfPQExpBuffer(&conn->errorMessage,									  libpq_gettext("length must be given for binary parameter\n"));					goto sendFailed;				}			}			else			{				/* text parameter, do not use paramLengths */				nbytes = strlen(paramValues[i]);			}			if (pqPutInt(nbytes, 4, conn) < 0 ||				pqPutnchar(paramValues[i], nbytes, conn) < 0)				goto sendFailed;		}		else		{			/* take the param as NULL */			if (pqPutInt(-1, 4, conn) < 0)				goto sendFailed;		}	}	if (pqPutInt(1, 2, conn) < 0 ||		pqPutInt(resultFormat, 2, conn))		goto sendFailed;	if (pqPutMsgEnd(conn) < 0)		goto sendFailed;	/* construct the Describe Portal message */	if (pqPutMsgStart('D', false, conn) < 0 ||		pqPutc('P', conn) < 0 ||		pqPuts("", conn) < 0 ||		pqPutMsgEnd(conn) < 0)		goto sendFailed;	/* construct the Execute message */	if (pqPutMsgStart('E', false, conn) < 0 ||		pqPuts("", conn) < 0 ||		pqPutInt(0, 4, conn) < 0 ||		pqPutMsgEnd(conn) < 0)		goto sendFailed;	/* construct the Sync message */	if (pqPutMsgStart('S', false, conn) < 0 ||		pqPutMsgEnd(conn) < 0)		goto sendFailed;	/* remember we are using extended query protocol */	conn->queryclass = PGQUERY_EXTENDED;	/*	 * Give the data a push.  In nonblock mode, don't complain if we're unable	 * to send it all; PQgetResult() will do any additional flushing needed.	 */	if (pqFlush(conn) < 0)		goto sendFailed;	/* OK, it's launched! */	conn->asyncStatus = PGASYNC_BUSY;	return 1;sendFailed:	pqHandleSendFailure(conn);	return 0;}/* * pqHandleSendFailure: try to clean up after failure to send command. * * Primarily, what we want to accomplish here is to process an async * NOTICE message that the backend might have sent just before it died. * * NOTE: this routine should only be called in PGASYNC_IDLE state. */voidpqHandleSendFailure(PGconn *conn){	/*	 * Accept any available input data, ignoring errors.  Note that if	 * pqReadData decides the backend has closed the channel, it will close	 * our side of the socket --- that's just what we want here.

⌨️ 快捷键说明

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