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

📄 fe-exec.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 5 页
字号:
		{			/* Send old-style end-of-data marker */			if (pqPutMsgStart(0, false, conn) < 0 ||				pqPutnchar("\\.\n", 3, conn) < 0 ||				pqPutMsgEnd(conn) < 0)				return -1;		}	}	/* Return to active duty */	conn->asyncStatus = PGASYNC_BUSY;	resetPQExpBuffer(&conn->errorMessage);	/* Try to flush data */	if (pqFlush(conn) < 0)		return -1;	return 1;}/* * PQgetCopyData - read a row of data from the backend during COPY OUT * * If successful, sets *buffer to point to a malloc'd row of data, and * returns row length (always > 0) as result. * Returns 0 if no row available yet (only possible if async is true), * -1 if end of copy (consult PQgetResult), or -2 if error (consult * PQerrorMessage). */intPQgetCopyData(PGconn *conn, char **buffer, int async){	*buffer = NULL;				/* for all failure cases */	if (!conn)		return -2;	if (conn->asyncStatus != PGASYNC_COPY_OUT)	{		printfPQExpBuffer(&conn->errorMessage,						  libpq_gettext("no COPY in progress\n"));		return -2;	}	if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)		return pqGetCopyData3(conn, buffer, async);	else		return pqGetCopyData2(conn, buffer, async);}/* * 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. * * XXX this routine is now deprecated, because it can't handle binary data. * If called during a COPY BINARY we return EOF. * * 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 error (eg, 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){	if (!s || maxlen <= 0)		return EOF;	*s = '\0';	/* maxlen must be at least 3 to hold the \. terminator! */	if (maxlen < 3)		return EOF;	if (!conn)		return EOF;	if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)		return pqGetline3(conn, s, maxlen);	else		return pqGetline2(conn, s, maxlen);}/* * PQgetlineAsync - gets a COPY data row 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 data row * is available in libpq's input buffer.  Otherwise, no data is returned * until the rest of the row 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 data-row boundary.  If possible * a whole row will be returned at one time.  But if the buffer offered by * the caller is too small to hold a row sent by the backend, then a partial * data row will be returned.  In text mode this can be detected by testing * whether the last returned byte is '\n' or not. * * The returned data is *not* null-terminated. */intPQgetlineAsync(PGconn *conn, char *buffer, int bufsize){	if (!conn)		return -1;	if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)		return pqGetlineAsync3(conn, buffer, bufsize);	else		return pqGetlineAsync2(conn, buffer, bufsize);}/* * PQputline -- sends a string to the backend during COPY IN. * Returns 0 if OK, EOF if not. * * This is deprecated primarily because the return convention doesn't allow * caller to tell the difference between a hard error and a nonblock-mode * send failure. */intPQputline(PGconn *conn, const char *s){	return PQputnbytes(conn, s, strlen(s));}/* * 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 (PQputCopyData(conn, buffer, nbytes) > 0)		return 0;	else		return EOF;}/* * PQendcopy *		After completing the data transfer portion of a copy in/out, *		the application must call this routine to finish the command protocol. * * When using protocol 3.0 this is deprecated; it's cleaner to use PQgetResult * to get the transfer status.	Note however that when using 2.0 protocol, * recovering from a copy failure often requires a PQreset.  PQendcopy will * take care of that, PQgetResult won't. * * RETURNS: *		0 on success *		1 on failure */intPQendcopy(PGconn *conn){	if (!conn)		return 0;	if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)		return pqEndcopy3(conn);	else		return pqEndcopy2(conn);}/* ---------------- *		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,	 const PQArgBlock *args,	 int nargs){	*actual_result_len = 0;	if (!conn)		return NULL;	/* clear the error string */	resetPQExpBuffer(&conn->errorMessage);	if (conn->sock < 0 || conn->asyncStatus != PGASYNC_IDLE ||		conn->result != NULL)	{		printfPQExpBuffer(&conn->errorMessage,						  libpq_gettext("connection in wrong state\n"));		return NULL;	}	if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)		return pqFunctionCall3(conn, fnid,							   result_buf, actual_result_len,							   result_is_int,							   args, nargs);	else		return pqFunctionCall2(conn, fnid,							   result_buf, actual_result_len,							   result_is_int,							   args, nargs);}/* ====== accessor funcs for PGresult ======== */ExecStatusTypePQresultStatus(const PGresult *res){	if (!res)		return PGRES_FATAL_ERROR;	return res->resultStatus;}char *PQresStatus(ExecStatusType status){	if (status < 0 || status >= sizeof pgresStatus / sizeof pgresStatus[0])		return libpq_gettext("invalid ExecStatusType code");	return pgresStatus[status];}char *PQresultErrorMessage(const PGresult *res){	if (!res || !res->errMsg)		return "";	return res->errMsg;}char *PQresultErrorField(const PGresult *res, int fieldcode){	PGMessageField *pfield;	if (!res)		return NULL;	for (pfield = res->errFields; pfield != NULL; pfield = pfield->next)	{		if (pfield->code == fieldcode)			return pfield->contents;	}	return NULL;}intPQntuples(const PGresult *res){	if (!res)		return 0;	return res->ntups;}intPQnfields(const PGresult *res){	if (!res)		return 0;	return res->numAttributes;}intPQbinaryTuples(const PGresult *res){	if (!res)		return 0;	return res->binary;}/* * Helper routines to range-check field numbers and tuple numbers. * Return TRUE if OK, FALSE if not */static intcheck_field_number(const PGresult *res, int field_num){	if (!res)		return FALSE;			/* no way to display error message... */	if (field_num < 0 || field_num >= res->numAttributes)	{		pqInternalNotice(&res->noticeHooks,						 "column number %d is out of range 0..%d",						 field_num, res->numAttributes - 1);		return FALSE;	}	return TRUE;}static intcheck_tuple_field_number(const PGresult *res,						 int tup_num, int field_num){	if (!res)		return FALSE;			/* no way to display error message... */	if (tup_num < 0 || tup_num >= res->ntups)	{		pqInternalNotice(&res->noticeHooks,						 "row number %d is out of range 0..%d",						 tup_num, res->ntups - 1);		return FALSE;	}	if (field_num < 0 || field_num >= res->numAttributes)	{		pqInternalNotice(&res->noticeHooks,						 "column number %d is out of range 0..%d",						 field_num, res->numAttributes - 1);		return FALSE;	}	return TRUE;}/* * returns NULL if the field_num is invalid */char *PQfname(const PGresult *res, int field_num){	if (!check_field_number(res, field_num))		return NULL;	if (res->attDescs)		return res->attDescs[field_num].name;	else		return NULL;}/* * PQfnumber: find column number given column name * * The column name is parsed as if it were in a SQL statement, including * case-folding and double-quote processing.  But note a possible gotcha: * downcasing in the frontend might follow different locale rules than * downcasing in the backend... * * Returns -1 if no match.	In the present backend it is also possible * to have multiple matches, in which case the first one is found. */intPQfnumber(const PGresult *res, const char *field_name){	char	   *field_case;	bool		in_quotes;	char	   *iptr;	char	   *optr;	int			i;	if (!res)		return -1;	/*	 * Note: it is correct to reject a zero-length input string; the proper	 * input to match a zero-length field name would be "".	 */	if (field_name == NULL ||		field_name[0] == '\0' ||		res->attDescs == NULL)		return -1;	/*	 * Note: this code will not reject partially quoted strings, eg	 * foo"BAR"foo will become fooBARfoo when it probably ought to be an error	 * condition.	 */	field_case = strdup(field_name);	if (field_case == NULL)		return -1;				/* grotty */	in_quotes = false;	optr = field_case;	for (iptr = field_case; *iptr; iptr++)	{		char		c = *iptr;		if (in_quotes)		{			if (c == '"')			{				if (iptr[1] == '"')				{					/* doubled quotes become a single quote */					*optr++ = '"';					iptr++;				}				else					in_quotes = false;			}			else				*optr++ = c;		}		else if (c == '"')			in_quotes = true;		else		{			c = pg_tolower((unsigned char) c);			*optr++ = c;		}	}	*optr = '\0';	for (i = 0; i < res->numAttributes; i++)	{		if (strcmp(field_case, res->attDescs[i].name) == 0)		{			free(field_case);			return i;		}	}	free(field_case);	return -1;}OidPQftable(const PGresult *res, int field_num){	if (!check_field_number(res, field_num))		return InvalidOid;	if (res->attDescs)		return res->attDescs[field_num].tableid;	else		return InvalidOid;}intPQftablecol(const PGresult *res, int field_num){	if (!check_field_number(res, field_num))		return 0;	if (res->attDescs)		return res->attDescs[field_num].columnid;	else		return 0;}intPQfformat(const PGresult *res, int field_num){	if (!check_field_number(res, field_num))		return 0;	if (res->attDescs)		return res->attDescs[field_num].format;	else		return 0;}OidPQftype(const PGresult *res, int field_num){	if (!check_field_number(res, field_num))		return InvalidOid;	if (res->attDescs)		return res->attDescs[field_num].typid;	else		return InvalidOid;}intPQfsize(const PGresult *res, int field_num){	if (!check_field_number(res, field_num))		return 0;	if (res->attDescs)		return res->attDescs[field_num].typlen;	else		return 0;}intPQfmod(const PGresult *res, int field_num){	if (!check_field_number(res, field_num))		return 0;	if (res->attDescs)		return res->attDescs[field_num].atttypmod;	else		return 0;}char *PQcmdStatus(PGresult *res){	if (!res)		return NULL;	return res->cmdStatus;}/* * PQoidStatus - *	if the last command was an INSERT, return the oid string *	if not, return "" */char *

⌨️ 快捷键说明

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