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

📄 fe-exec.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
📖 第 1 页 / 共 4 页
字号:
	{							/* len.int4 + contents	   */		if (pqPutInt(args[i].len, 4, conn))		{			handleSendFailure(conn);			return NULL;		}		if (args[i].isint)		{			if (pqPutInt(args[i].u.integer, 4, conn))			{				handleSendFailure(conn);				return NULL;			}		}		else		{			if (pqPutnchar((char *) args[i].u.ptr, args[i].len, conn))			{				handleSendFailure(conn);				return NULL;			}		}	}	if (pqFlush(conn))	{		handleSendFailure(conn);		return NULL;	}	for (;;)	{		if (needInput)		{			/* Wait for some data to arrive (or for the channel to close) */			if (pqWait(TRUE, FALSE, conn) ||				pqReadData(conn) < 0)				break;		}		/*		 * Scan the message. If we run out of data, loop around to try		 * again.		 */		conn->inCursor = conn->inStart;		needInput = true;		if (pqGetc(&id, conn))			continue;		/*		 * We should see V or E response to the command, but might get N		 * and/or A notices first. We also need to swallow the final Z		 * before returning.		 */		switch (id)		{			case 'V':			/* function result */				if (pqGetc(&id, conn))					continue;				if (id == 'G')				{					/* function returned nonempty value */					if (pqGetInt(actual_result_len, 4, conn))						continue;					if (result_is_int)					{						if (pqGetInt(result_buf, 4, conn))							continue;					}					else					{						if (pqGetnchar((char *) result_buf,									   *actual_result_len,									   conn))							continue;					}					if (pqGetc(&id, conn))		/* get the last '0' */						continue;				}				if (id == '0')				{					/* correctly finished function result message */					status = PGRES_COMMAND_OK;				}				else				{					/* The backend violates the protocol. */					sprintf(conn->errorMessage,							"FATAL: PQfn: protocol error: id=%x\n", id);					conn->inStart = conn->inCursor;					return PQmakeEmptyPGresult(conn, PGRES_FATAL_ERROR);				}				break;			case 'E':			/* error return */				if (pqGets(conn->errorMessage, ERROR_MSG_LENGTH, conn))					continue;				status = PGRES_FATAL_ERROR;				break;			case 'A':			/* notify message */				/* handle notify and go back to processing return values */				if (getNotify(conn))					continue;				break;			case 'N':			/* notice */				/* handle notice and go back to processing return values */				if (getNotice(conn))					continue;				break;			case 'Z':			/* backend is ready for new query */				/* consume the message and exit */				conn->inStart = conn->inCursor;				return PQmakeEmptyPGresult(conn, status);			default:				/* The backend violates the protocol. */				sprintf(conn->errorMessage,						"FATAL: PQfn: protocol error: id=%x\n", id);				conn->inStart = conn->inCursor;				return PQmakeEmptyPGresult(conn, PGRES_FATAL_ERROR);		}		/* Completed this message, keep going */		conn->inStart = conn->inCursor;		needInput = false;	}	/* we fall out of the loop only upon failing to read data */	return PQmakeEmptyPGresult(conn, PGRES_FATAL_ERROR);}/* ====== accessor funcs for PGresult ======== */ExecStatusTypePQresultStatus(PGresult *res){	if (!res)		return PGRES_NONFATAL_ERROR;	return res->resultStatus;}const char *PQresStatus(ExecStatusType status){	if (((int) status) < 0 ||		((int) status) >= (sizeof(pgresStatus) / sizeof(pgresStatus[0])))		return "Invalid ExecStatusType code";	return pgresStatus[status];}const char *PQresultErrorMessage(PGresult *res){	if (!res || !res->errMsg)		return "";	return res->errMsg;}intPQntuples(PGresult *res){	if (!res)		return 0;	return res->ntups;}intPQnfields(PGresult *res){	if (!res)		return 0;	return res->numAttributes;}intPQbinaryTuples(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 char *routineName, PGresult *res, int field_num){	if (!res)		return FALSE;			/* no way to display error message... */	if (field_num < 0 || field_num >= res->numAttributes)	{		if (res->conn)		{			sprintf(res->conn->errorMessage,					"%s: ERROR! field number %d is out of range 0..%d\n",					routineName, field_num, res->numAttributes - 1);			DONOTICE(res->conn, res->conn->errorMessage);		}		return FALSE;	}	return TRUE;}static intcheck_tuple_field_number(const char *routineName, 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)	{		if (res->conn)		{			sprintf(res->conn->errorMessage,					"%s: ERROR! tuple number %d is out of range 0..%d\n",					routineName, tup_num, res->ntups - 1);			DONOTICE(res->conn, res->conn->errorMessage);		}		return FALSE;	}	if (field_num < 0 || field_num >= res->numAttributes)	{		if (res->conn)		{			sprintf(res->conn->errorMessage,					"%s: ERROR! field number %d is out of range 0..%d\n",					routineName, field_num, res->numAttributes - 1);			DONOTICE(res->conn, res->conn->errorMessage);		}		return FALSE;	}	return TRUE;}/*   returns NULL if the field_num is invalid*/char *PQfname(PGresult *res, int field_num){	if (!check_field_number("PQfname", res, field_num))		return NULL;	if (res->attDescs)		return res->attDescs[field_num].name;	else		return NULL;}/*   returns -1 on a bad field name*/intPQfnumber(PGresult *res, const char *field_name){	int			i;	char	   *field_case;	if (!res)		return -1;	if (field_name == NULL ||		field_name[0] == '\0' ||		res->attDescs == NULL)		return -1;	field_case = strdup(field_name);	if (*field_case == '"')	{		strcpy(field_case, field_case + 1);		*(field_case + strlen(field_case) - 1) = '\0';	}	else		for (i = 0; field_case[i]; i++)			if (isascii((unsigned char) field_case[i]) &&				isupper(field_case[i]))				field_case[i] = tolower(field_case[i]);	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;}OidPQftype(PGresult *res, int field_num){	if (!check_field_number("PQftype", res, field_num))		return InvalidOid;	if (res->attDescs)		return res->attDescs[field_num].typid;	else		return InvalidOid;}intPQfsize(PGresult *res, int field_num){	if (!check_field_number("PQfsize", res, field_num))		return 0;	if (res->attDescs)		return res->attDescs[field_num].typlen;	else		return 0;}intPQfmod(PGresult *res, int field_num){	if (!check_field_number("PQfmod", 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 ""*/const char *PQoidStatus(PGresult *res){	char	   *p,			   *e,			   *scan;	int			slen,				olen;	if (!res)		return "";	if (strncmp(res->cmdStatus, "INSERT ", 7) != 0)		return "";	/*----------	 * The cmdStatus string looks like	 *	   INSERT oid count\0	 * In order to be able to return an ordinary C string without	 * damaging the result for PQcmdStatus or PQcmdTuples, we copy	 * the oid part of the string to just after the null, so that	 * cmdStatus looks like	 *	   INSERT oid count\0oid\0	 *						 ^ our return value points here	 * Pretty klugy eh?  This routine should've just returned an Oid value.	 *----------	 */	slen = strlen(res->cmdStatus);	p = res->cmdStatus + 7;		/* where oid is now */	e = res->cmdStatus + slen + 1;		/* where to put the oid string */	for (scan = p; *scan && *scan != ' ';)		scan++;	olen = scan - p;	if (slen + olen + 2 > sizeof(res->cmdStatus))		return "";				/* something very wrong if it doesn't fit */	strncpy(e, p, olen);	e[olen] = '\0';	return e;}/*   PQcmdTuples -	if the last command was an INSERT/UPDATE/DELETE, return number	of inserted/affected tuples, if not, return ""*/const char *PQcmdTuples(PGresult *res){	if (!res)		return "";	if (strncmp(res->cmdStatus, "INSERT", 6) == 0 ||		strncmp(res->cmdStatus, "DELETE", 6) == 0 ||		strncmp(res->cmdStatus, "UPDATE", 6) == 0)	{		char	   *p = res->cmdStatus + 6;		if (*p == 0)		{			if (res->conn)			{				sprintf(res->conn->errorMessage,						"PQcmdTuples (%s) -- bad input from server\n",						res->cmdStatus);				DONOTICE(res->conn, res->conn->errorMessage);			}			return "";		}		p++;		if (*(res->cmdStatus) != 'I')	/* UPDATE/DELETE */			return p;		while (*p != ' ' && *p)			p++;				/* INSERT: skip oid */		if (*p == 0)		{			if (res->conn)			{				sprintf(res->conn->errorMessage,					 "PQcmdTuples (INSERT) -- there's no # of tuples\n");				DONOTICE(res->conn, res->conn->errorMessage);			}			return "";		}		p++;		return p;	}	return "";}/*   PQgetvalue:	return the value of field 'field_num' of row 'tup_num'	If res is binary, then the value returned is NOT a null-terminated	ASCII string, but the binary representation in the server's native	format.	if res is not binary, a null-terminated ASCII string is returned.*/char *PQgetvalue(PGresult *res, int tup_num, int field_num){	if (!check_tuple_field_number("PQgetvalue", res, tup_num, field_num))		return NULL;	return res->tuples[tup_num][field_num].value;}/* PQgetlength:	 returns the length of a field value in bytes.	If res is binary,	 i.e. a result of a binary portal, then the length returned does	 NOT include the size field of the varlena.  (The data returned	 by PQgetvalue doesn't either.)*/intPQgetlength(PGresult *res, int tup_num, int field_num){	if (!check_tuple_field_number("PQgetlength", res, tup_num, field_num))		return 0;	if (res->tuples[tup_num][field_num].len != NULL_LEN)		return res->tuples[tup_num][field_num].len;	else		return 0;}/* PQgetisnull:	 returns the null status of a field value.*/intPQgetisnull(PGresult *res, int tup_num, int field_num){	if (!check_tuple_field_number("PQgetisnull", res, tup_num, field_num))		return 1;				/* pretend it is null */	if (res->tuples[tup_num][field_num].len == NULL_LEN)		return 1;	else		return 0;}

⌨️ 快捷键说明

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