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

📄 fe-exec.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 5 页
字号:
PQoidStatus(const PGresult *res){	/*	 * This must be enough to hold the result. Don't laugh, this is better	 * than what this function used to do.	 */	static char buf[24];	size_t		len;	if (!res || !res->cmdStatus || strncmp(res->cmdStatus, "INSERT ", 7) != 0)		return "";	len = strspn(res->cmdStatus + 7, "0123456789");	if (len > 23)		len = 23;	strncpy(buf, res->cmdStatus + 7, len);	buf[len] = '\0';	return buf;}/* * PQoidValue - *	a perhaps preferable form of the above which just returns *	an Oid type */OidPQoidValue(const PGresult *res){	char	   *endptr = NULL;	unsigned long result;	if (!res ||		!res->cmdStatus ||		strncmp(res->cmdStatus, "INSERT ", 7) != 0 ||		res->cmdStatus[7] < '0' ||		res->cmdStatus[7] > '9')		return InvalidOid;	result = strtoul(res->cmdStatus + 7, &endptr, 10);	if (!endptr || (*endptr != ' ' && *endptr != '\0'))		return InvalidOid;	else		return (Oid) result;}/* * PQcmdTuples - *	If the last command was an INSERT/UPDATE/DELETE/MOVE/FETCH, return a *	string containing the number of inserted/affected tuples. If not, *	return "". * *	XXX: this should probably return an int */char *PQcmdTuples(PGresult *res){	char	   *p;	if (!res)		return "";	if (strncmp(res->cmdStatus, "INSERT ", 7) == 0)	{		p = res->cmdStatus + 6;		p++;		/* INSERT: skip oid */		while (*p != ' ' && *p)			p++;	}	else if (strncmp(res->cmdStatus, "DELETE ", 7) == 0 ||			 strncmp(res->cmdStatus, "UPDATE ", 7) == 0)		p = res->cmdStatus + 6;	else if (strncmp(res->cmdStatus, "FETCH ", 6) == 0)		p = res->cmdStatus + 5;	else if (strncmp(res->cmdStatus, "MOVE ", 5) == 0)		p = res->cmdStatus + 4;	else		return "";	p++;	if (*p == 0)	{		pqInternalNotice(&res->noticeHooks,						 "could not interpret result from server: %s",						 res->cmdStatus);		return "";	}	return p;}/* * PQgetvalue: *	return the value of field 'field_num' of row 'tup_num' */char *PQgetvalue(const PGresult *res, int tup_num, int field_num){	if (!check_tuple_field_number(res, tup_num, field_num))		return NULL;	return res->tuples[tup_num][field_num].value;}/* PQgetlength: *	returns the actual length of a field value in bytes. */intPQgetlength(const PGresult *res, int tup_num, int field_num){	if (!check_tuple_field_number(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(const PGresult *res, int tup_num, int field_num){	if (!check_tuple_field_number(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;}/* PQsetnonblocking: *	sets the PGconn's database connection non-blocking if the arg is TRUE *	or makes it non-blocking if the arg is FALSE, this will not protect *	you from PQexec(), you'll only be safe when using the non-blocking API. *	Needs to be called only on a connected database connection. */intPQsetnonblocking(PGconn *conn, int arg){	bool		barg;	if (!conn || conn->status == CONNECTION_BAD)		return -1;	barg = (arg ? TRUE : FALSE);	/* early out if the socket is already in the state requested */	if (barg == conn->nonblocking)		return (0);	/*	 * to guarantee constancy for flushing/query/result-polling behavior we	 * need to flush the send queue at this point in order to guarantee proper	 * behavior. this is ok because either they are making a transition _from_	 * or _to_ blocking mode, either way we can block them.	 */	/* if we are going from blocking to non-blocking flush here */	if (pqFlush(conn))		return (-1);	conn->nonblocking = barg;	return (0);}/* * return the blocking status of the database connection *		TRUE == nonblocking, FALSE == blocking */intPQisnonblocking(const PGconn *conn){	return (pqIsnonblocking(conn));}/* try to force data out, really only useful for non-blocking users */intPQflush(PGconn *conn){	return pqFlush(conn);}/* *		PQfreemem - safely frees memory allocated * * Needed mostly by Win32, unless multithreaded DLL (/MD in VC6) * Used for freeing memory from PQescapeByte()a/PQunescapeBytea() */voidPQfreemem(void *ptr){	free(ptr);}/* * PQfreeNotify - free's the memory associated with a PGnotify * * This function is here only for binary backward compatibility. * New code should use PQfreemem().  A macro will automatically map * calls to PQfreemem.	It should be removed in the future.  bjm 2003-03-24 */#undef PQfreeNotifyvoid		PQfreeNotify(PGnotify *notify);voidPQfreeNotify(PGnotify *notify){	PQfreemem(notify);}/* * Escaping arbitrary strings to get valid SQL literal strings. * * Replaces "'" with "''", and if not std_strings, replaces "\" with "\\". * * length is the length of the source string.  (Note: if a terminating NUL * is encountered sooner, PQescapeString stops short of "length"; the behavior * is thus rather like strncpy.) * * For safety the buffer at "to" must be at least 2*length + 1 bytes long. * A terminating NUL character is added to the output string, whether the * input is NUL-terminated or not. * * Returns the actual length of the output (not counting the terminating NUL). */static size_tPQescapeStringInternal(PGconn *conn,					   char *to, const char *from, size_t length,					   int *error,					   int encoding, bool std_strings){	const char *source = from;	char	   *target = to;	size_t		remaining = length;	if (error)		*error = 0;	while (remaining > 0 && *source != '\0')	{		char	c = *source;		int		len;		int		i;		/* Fast path for plain ASCII */		if (!IS_HIGHBIT_SET(c))		{			/* Apply quoting if needed */			if (c == '\'' ||				(c == '\\' && !std_strings))				*target++ = c;			/* Copy the character */			*target++ = c;			source++;			remaining--;			continue;		}		/* Slow path for possible multibyte characters */		len = pg_encoding_mblen(encoding, source);		/* Copy the character */		for (i = 0; i < len; i++)		{			if (remaining == 0 || *source == '\0')				break;			*target++ = *source++;			remaining--;		}		/*		 * If we hit premature end of string (ie, incomplete multibyte		 * character), try to pad out to the correct length with spaces.		 * We may not be able to pad completely, but we will always be able		 * to insert at least one pad space (since we'd not have quoted a		 * multibyte character).  This should be enough to make a string that		 * the server will error out on.		 */		if (i < len)		{			if (error)				*error = 1;			if (conn)				printfPQExpBuffer(&conn->errorMessage,						libpq_gettext("incomplete multibyte character\n"));			for (; i < len; i++)			{				if (((size_t) (target - to)) / 2 >= length)					break;				*target++ = ' ';			}			break;		}	}	/* Write the terminating NUL character. */	*target = '\0';	return target - to;}size_tPQescapeStringConn(PGconn *conn,				   char *to, const char *from, size_t length,				   int *error){	if (!conn)	{		/* force empty-string result */		*to = '\0';		if (error)			*error = 1;		return 0;	}	return PQescapeStringInternal(conn, to, from, length, error,								  conn->client_encoding,								  conn->std_strings);}size_tPQescapeString(char *to, const char *from, size_t length){	return PQescapeStringInternal(NULL, to, from, length, NULL,								  static_client_encoding,								  static_std_strings);}/* *		PQescapeBytea	- converts from binary string to the *		minimal encoding necessary to include the string in an SQL *		INSERT statement with a bytea type column as the target. * *		The following transformations are applied *		'\0' == ASCII  0 == \000 *		'\'' == ASCII 39 == '' *		'\\' == ASCII 92 == \\ *		anything < 0x20, or > 0x7e ---> \ooo *										(where ooo is an octal expression) *		If not std_strings, all backslashes sent to the output are doubled. */static unsigned char *PQescapeByteaInternal(PGconn *conn,					  const unsigned char *from, size_t from_length,					  size_t *to_length, bool std_strings){	const unsigned char *vp;	unsigned char *rp;	unsigned char *result;	size_t		i;	size_t		len;	size_t		bslash_len = (std_strings ? 1 : 2);	/*	 * empty string has 1 char ('\0')	 */	len = 1;	vp = from;	for (i = from_length; i > 0; i--, vp++)	{		if (*vp < 0x20 || *vp > 0x7e)			len += bslash_len + 3;		else if (*vp == '\'')			len += 2;		else if (*vp == '\\')			len += bslash_len + bslash_len;		else			len++;	}	*to_length = len;	rp = result = (unsigned char *) malloc(len);	if (rp == NULL)	{		if (conn)			printfPQExpBuffer(&conn->errorMessage,							  libpq_gettext("out of memory\n"));		return NULL;	}	vp = from;	for (i = from_length; i > 0; i--, vp++)	{		if (*vp < 0x20 || *vp > 0x7e)		{			if (!std_strings)				*rp++ = '\\';			(void) sprintf((char *) rp, "\\%03o", *vp);			rp += 4;		}		else if (*vp == '\'')		{			*rp++ = '\'';			*rp++ = '\'';		}		else if (*vp == '\\')		{			if (!std_strings)			{				*rp++ = '\\';				*rp++ = '\\';			}			*rp++ = '\\';			*rp++ = '\\';		}		else			*rp++ = *vp;	}	*rp = '\0';	return result;}unsigned char *PQescapeByteaConn(PGconn *conn,				  const unsigned char *from, size_t from_length,				  size_t *to_length){	if (!conn)		return NULL;	return PQescapeByteaInternal(conn, from, from_length, to_length,								 conn->std_strings);}unsigned char *PQescapeBytea(const unsigned char *from, size_t from_length, size_t *to_length){	return PQescapeByteaInternal(NULL, from, from_length, to_length,								 static_std_strings);}#define ISFIRSTOCTDIGIT(CH) ((CH) >= '0' && (CH) <= '3')#define ISOCTDIGIT(CH) ((CH) >= '0' && (CH) <= '7')#define OCTVAL(CH) ((CH) - '0')/* *		PQunescapeBytea - converts the null terminated string representation *		of a bytea, strtext, into binary, filling a buffer. It returns a *		pointer to the buffer (or NULL on error), and the size of the *		buffer in retbuflen. The pointer may subsequently be used as an *		argument to the function PQfreemem. * *		The following transformations are made: *		\\	 == ASCII 92 == \ *		\ooo == a byte whose value = ooo (ooo is an octal number) *		\x	 == x (x is any character not matched by the above transformations) */unsigned char *PQunescapeBytea(const unsigned char *strtext, size_t *retbuflen){	size_t		strtextlen,				buflen;	unsigned char *buffer,			   *tmpbuf;	size_t		i,				j;	if (strtext == NULL)		return NULL;	strtextlen = strlen((const char *) strtext);	/*	 * Length of input is max length of output, but add one to avoid	 * unportable malloc(0) if input is zero-length.	 */	buffer = (unsigned char *) malloc(strtextlen + 1);	if (buffer == NULL)		return NULL;	for (i = j = 0; i < strtextlen;)	{		switch (strtext[i])		{			case '\\':				i++;				if (strtext[i] == '\\')					buffer[j++] = strtext[i++];				else				{					if ((ISFIRSTOCTDIGIT(strtext[i])) &&						(ISOCTDIGIT(strtext[i + 1])) &&						(ISOCTDIGIT(strtext[i + 2])))					{						int			byte;						byte = OCTVAL(strtext[i++]);						byte = (byte << 3) + OCTVAL(strtext[i++]);						byte = (byte << 3) + OCTVAL(strtext[i++]);						buffer[j++] = byte;					}				}				/*				 * Note: if we see '\' followed by something that isn't a				 * recognized escape sequence, we loop around having done				 * nothing except advance i.  Therefore the something will be				 * emitted as ordinary data on the next cycle. Corner case:				 * '\' at end of string will just be discarded.				 */				break;			default:				buffer[j++] = strtext[i++];				break;		}	}	buflen = j;					/* buflen is the length of the dequoted data */	/* Shrink the buffer to be no larger than necessary */	/* +1 avoids unportable behavior when buflen==0 */	tmpbuf = realloc(buffer, buflen + 1);	/* It would only be a very brain-dead realloc that could fail, but... */	if (!tmpbuf)	{		free(buffer);		return NULL;	}	*retbuflen = buflen;	return tmpbuf;}

⌨️ 快捷键说明

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