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

📄 fe-exec.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
📖 第 1 页 / 共 4 页
字号:
		}		/* Parse it. */		parseInput(conn);	}	/* Return the appropriate thing. */	switch (conn->asyncStatus)	{		case PGASYNC_IDLE:			res = NULL;			/* query is complete */			break;		case PGASYNC_READY:			/*			 * conn->result is the PGresult to return.	If it is NULL			 * (which probably shouldn't happen) we assume there is an			 * appropriate error message in conn->errorMessage.			 */			res = conn->result;			conn->result = NULL;/* handing over ownership to caller */			conn->curTuple = NULL;		/* just in case */			if (!res)				res = PQmakeEmptyPGresult(conn, PGRES_FATAL_ERROR);			else			{				/*				 * Make sure PQerrorMessage agrees with result; it could				 * be that we have done other operations that changed				 * errorMessage since the result's error message was				 * saved.				 */				strcpy(conn->errorMessage, PQresultErrorMessage(res));			}			/* Set the state back to BUSY, allowing parsing to proceed. */			conn->asyncStatus = PGASYNC_BUSY;			break;		case PGASYNC_COPY_IN:			res = PQmakeEmptyPGresult(conn, PGRES_COPY_IN);			break;		case PGASYNC_COPY_OUT:			res = PQmakeEmptyPGresult(conn, PGRES_COPY_OUT);			break;		default:			sprintf(conn->errorMessage,					"PQgetResult: Unexpected asyncStatus %d\n",					(int) conn->asyncStatus);			res = PQmakeEmptyPGresult(conn, PGRES_FATAL_ERROR);			break;	}	return res;}/* * PQexec *	  send a query to the backend and package up the result in a PGresult * * If the query was not even sent, return NULL; conn->errorMessage is set to * a relevant message. * If the query was sent, a new PGresult is returned (which could indicate * either success or failure). * The user is responsible for freeing the PGresult via PQclear() * when done with it. */PGresult   *PQexec(PGconn *conn, const char *query){	PGresult   *result;	PGresult   *lastResult;	/*	 * Silently discard any prior query result that application didn't	 * eat. This is probably poor design, but it's here for backward	 * compatibility.	 */	while ((result = PQgetResult(conn)) != NULL)	{		if (result->resultStatus == PGRES_COPY_IN ||			result->resultStatus == PGRES_COPY_OUT)		{			PQclear(result);			sprintf(conn->errorMessage,				"PQexec: you gotta get out of a COPY state yourself.\n");			return NULL;		}		PQclear(result);	}	/* OK to send the message */	if (!PQsendQuery(conn, query))		return NULL;	/*	 * For backwards compatibility, return the last result if there are	 * more than one.  We have to stop if we see copy in/out, however. We	 * will resume parsing when application calls PQendcopy.	 */	lastResult = NULL;	while ((result = PQgetResult(conn)) != NULL)	{		if (lastResult)			PQclear(lastResult);		lastResult = result;		if (result->resultStatus == PGRES_COPY_IN ||			result->resultStatus == PGRES_COPY_OUT)			break;	}	return lastResult;}/* * Attempt to read a Notice response message. * This is possible in several places, so we break it out as a subroutine. * Entry: 'N' flag character has already been consumed. * Exit: returns 0 if successfully consumed Notice message. *		 returns EOF if not enough data. */static intgetNotice(PGconn *conn){	if (pqGets(conn->errorMessage, ERROR_MSG_LENGTH, conn))		return EOF;	DONOTICE(conn, conn->errorMessage);	return 0;}/* * Attempt to read a Notify response message. * This is possible in several places, so we break it out as a subroutine. * Entry: 'A' flag character has already been consumed. * Exit: returns 0 if successfully consumed Notify message. *		 returns EOF if not enough data. */static intgetNotify(PGconn *conn){	PGnotify	tempNotify;	PGnotify   *newNotify;	if (pqGetInt(&(tempNotify.be_pid), 4, conn))		return EOF;	if (pqGets(tempNotify.relname, NAMEDATALEN, conn))		return EOF;	newNotify = (PGnotify *) malloc(sizeof(PGnotify));	memcpy(newNotify, &tempNotify, sizeof(PGnotify));	DLAddTail(conn->notifyList, DLNewElem(newNotify));	return 0;}/* * PQnotifies *	  returns a PGnotify* structure of the latest async notification * that has not yet been handled * * returns NULL, if there is currently * no unhandled async notification from the backend * * the CALLER is responsible for FREE'ing the structure returned */PGnotify   *PQnotifies(PGconn *conn){	Dlelem	   *e;	PGnotify   *event;	if (!conn)		return NULL;	/* Parse any available data to see if we can extract NOTIFY messages. */	parseInput(conn);	/* RemHead returns NULL if list is empty */	e = DLRemHead(conn->notifyList);	if (!e)		return NULL;	event = (PGnotify *) DLE_VAL(e);	DLFreeElem(e);	return event;}/* * PQgetline - gets a newline-terminated string from the backend. * * Chiefly here so that applications can use "COPY <rel> to stdout" * and read the output string.	Returns a null-terminated string in s. * * PQgetline reads up to maxlen-1 characters (like fgets(3)) but strips * the terminating \n (like gets(3)). * * CAUTION: the caller is responsible for detecting the end-of-copy signal * (a line containing just "\.") when using this routine. * * RETURNS: *		EOF if it is detected or invalid arguments are given *		0 if EOL is reached (i.e., \n has been read) *				(this is required for backward-compatibility -- this *				 routine used to always return EOF or 0, assuming that *				 the line ended within maxlen bytes.) *		1 in other cases (i.e., the buffer was filled before \n is reached) */intPQgetline(PGconn *conn, char *s, int maxlen){	int			result = 1;		/* return value if buffer overflows */	if (!s || maxlen <= 0)		return EOF;	if (!conn || conn->sock < 0)	{		*s = '\0';		return EOF;	}	/*	 * Since this is a purely synchronous routine, we don't bother to	 * maintain conn->inCursor; there is no need to back up.	 */	while (maxlen > 1)	{		if (conn->inStart < conn->inEnd)		{			char		c = conn->inBuffer[conn->inStart++];			if (c == '\n')			{				result = 0;		/* success exit */				break;			}			*s++ = c;			maxlen--;		}		else		{			/* need to load more data */			if (pqWait(TRUE, FALSE, conn) ||				pqReadData(conn) < 0)			{				result = EOF;				break;			}		}	}	*s = '\0';	return result;}/* * PQgetlineAsync - gets a newline-terminated string without blocking. * * This routine is for applications that want to do "COPY <rel> to stdout" * asynchronously, that is without blocking.  Having issued the COPY command * and gotten a PGRES_COPY_OUT response, the app should call PQconsumeInput * and this routine until the end-of-data signal is detected.  Unlike * PQgetline, this routine takes responsibility for detecting end-of-data. * * On each call, PQgetlineAsync will return data if a complete newline- * terminated data line is available in libpq's input buffer, or if the * incoming data line is too long to fit in the buffer offered by the caller. * Otherwise, no data is returned until the rest of the line arrives. * * If -1 is returned, the end-of-data signal has been recognized (and removed * from libpq's input buffer).  The caller *must* next call PQendcopy and * then return to normal processing. * * RETURNS: *	 -1    if the end-of-copy-data marker has been recognized *	 0	   if no data is available *	 >0    the number of bytes returned. * The data returned will not extend beyond a newline character.  If possible * a whole line will be returned at one time.  But if the buffer offered by * the caller is too small to hold a line sent by the backend, then a partial * data line will be returned.	This can be detected by testing whether the * last returned byte is '\n' or not. * The returned string is *not* null-terminated. */intPQgetlineAsync(PGconn *conn, char *buffer, int bufsize){	int			avail;	if (!conn || conn->asyncStatus != PGASYNC_COPY_OUT)		return -1;				/* we are not doing a copy... */	/*	 * Move data from libpq's buffer to the caller's. We want to accept	 * data only in units of whole lines, not partial lines.  This ensures	 * that we can recognize the terminator line "\\.\n".  (Otherwise, if	 * it happened to cross a packet/buffer boundary, we might hand the	 * first one or two characters off to the caller, which we shouldn't.)	 */	conn->inCursor = conn->inStart;	avail = bufsize;	while (avail > 0 && conn->inCursor < conn->inEnd)	{		char		c = conn->inBuffer[conn->inCursor++];		*buffer++ = c;		--avail;		if (c == '\n')		{			/* Got a complete line; mark the data removed from libpq */			conn->inStart = conn->inCursor;			/* Is it the endmarker line? */			if (bufsize - avail == 3 && buffer[-3] == '\\' && buffer[-2] == '.')				return -1;			/* No, return the data line to the caller */			return bufsize - avail;		}	}	/*	 * We don't have a complete line. We'd prefer to leave it in libpq's	 * buffer until the rest arrives, but there is a special case: what if	 * the line is longer than the buffer the caller is offering us?  In	 * that case we'd better hand over a partial line, else we'd get into	 * an infinite loop. Do this in a way that ensures we can't	 * misrecognize a terminator line later: leave last 3 characters in	 * libpq buffer.	 */	if (avail == 0 && bufsize > 3)	{		conn->inStart = conn->inCursor - 3;		return bufsize - 3;	}	return 0;}/* * PQputline -- sends a string to the backend. * Returns 0 if OK, EOF if not. * * Chiefly here so that applications can use "COPY <rel> from stdin". */intPQputline(PGconn *conn, const char *s){	if (!conn || conn->sock < 0)		return EOF;	return pqPutnchar(s, strlen(s), conn);}/* * PQputnbytes -- like PQputline, but buffer need not be null-terminated. * Returns 0 if OK, EOF if not. */intPQputnbytes(PGconn *conn, const char *buffer, int nbytes){	if (!conn || conn->sock < 0)		return EOF;	return pqPutnchar(buffer, nbytes, conn);}/* * PQendcopy *		After completing the data transfer portion of a copy in/out, *		the application must call this routine to finish the command protocol. * * RETURNS: *		0 on success *		1 on failure */intPQendcopy(PGconn *conn){	PGresult   *result;	if (!conn)		return 0;	if (conn->asyncStatus != PGASYNC_COPY_IN &&		conn->asyncStatus != PGASYNC_COPY_OUT)	{		sprintf(conn->errorMessage,			 "PQendcopy() -- I don't think there's a copy in progress.");		return 1;	}	(void) pqFlush(conn);		/* make sure no data is waiting to be sent */	/* Return to active duty */	conn->asyncStatus = PGASYNC_BUSY;	conn->errorMessage[0] = '\0';	/* Wait for the completion response */	result = PQgetResult(conn);	/* Expecting a successful result */	if (result && result->resultStatus == PGRES_COMMAND_OK)	{		PQclear(result);		return 0;	}	/*	 * Trouble. The worst case is that we've lost sync with the backend	 * entirely due to application screwup of the copy in/out protocol. To	 * recover, reset the connection (talk about using a sledgehammer...)	 */	PQclear(result);	if (conn->errorMessage[0])		DONOTICE(conn, conn->errorMessage);	DONOTICE(conn, "PQendcopy: resetting connection\n");	PQreset(conn);	return 1;}/* ---------------- *		PQfn -	Send a function call to the POSTGRES backend. * *		conn			: backend connection *		fnid			: function id *		result_buf		: pointer to result buffer (&int if integer) *		result_len		: length of return value. *		actual_result_len: actual length returned. (differs from result_len *						  for varlena structures.) *		result_type		: If the result is an integer, this must be 1, *						  otherwise this should be 0 *		args			: pointer to an array of function arguments. *						  (each has length, if integer, and value/pointer) *		nargs			: # of arguments in args array. * * RETURNS *		PGresult with status = PGRES_COMMAND_OK if successful. *			*actual_result_len is > 0 if there is a return value, 0 if not. *		PGresult with status = PGRES_FATAL_ERROR if backend returns an error. *		NULL on communications failure.  conn->errorMessage will be set. * ---------------- */PGresult   *PQfn(PGconn *conn,	 int fnid,	 int *result_buf,	 int *actual_result_len,	 int result_is_int,	 PQArgBlock *args,	 int nargs){	bool		needInput = false;	ExecStatusType status = PGRES_FATAL_ERROR;	char		id;	int			i;	*actual_result_len = 0;	if (!conn)		return NULL;	if (conn->sock < 0 || conn->asyncStatus != PGASYNC_IDLE)	{		sprintf(conn->errorMessage, "PQfn() -- connection in wrong state\n");		return NULL;	}	/* clear the error string */	conn->errorMessage[0] = '\0';	if (pqPuts("F ", conn) ||			/* function */		pqPutInt(fnid, 4, conn) ||		/* function id */		pqPutInt(nargs, 4, conn))		/* # of args */	{		handleSendFailure(conn);		return NULL;	}	for (i = 0; i < nargs; ++i)

⌨️ 快捷键说明

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