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

📄 execute.c

📁 postgresql8.3.4源码,开源数据库
💻 C
📖 第 1 页 / 共 4 页
字号:
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.76.2.1 2008/03/01 03:26:44 tgl Exp $ *//* * The aim is to get a simpler inteface to the database routines. * All the tidieous messing around with tuples is supposed to be hidden * by this function. *//* Author: Linus Tolke   (actually most if the code is "borrowed" from the distribution and just   slightly modified) *//* Taken over as part of PostgreSQL by Michael Meskes <meskes@postgresql.org>   on Feb. 5th, 1998 */#define POSTGRES_ECPG_INTERNAL#include "postgres_fe.h"#include <locale.h>#include "pg_type.h"#include "ecpgtype.h"#include "ecpglib.h"#include "ecpgerrno.h"#include "extern.h"#include "sqlca.h"#include "sql3types.h"#include "pgtypes_numeric.h"#include "pgtypes_date.h"#include "pgtypes_timestamp.h"#include "pgtypes_interval.h"/* *	This function returns a newly malloced string that has ' and \ *	escaped. */static char *quote_postgres(char *arg, bool quote, int lineno){	char	   *res;	size_t		length;	size_t		escaped_len;	size_t		buffer_len;	/*	 * if quote is false we just need to store things in a descriptor they	 * will be quoted once they are inserted in a statement	 */	if (!quote)		return arg;	else	{		length = strlen(arg);		buffer_len = 2 * length + 1;		res = (char *) ecpg_alloc(buffer_len + 3, lineno);		if (!res)			return (res);		escaped_len = PQescapeString(res + 1, arg, buffer_len);		if (length == escaped_len)		{			res[0] = res[escaped_len + 1] = '\'';			res[escaped_len + 2] = '\0';		}		else		{			/*			 * We don't know if the target database is using			 * standard_conforming_strings, so we always use E'' strings.			 */			memmove(res + 2, res + 1, escaped_len);			res[0] = ESCAPE_STRING_SYNTAX;			res[1] = res[escaped_len + 2] = '\'';			res[escaped_len + 3] = '\0';		}		ecpg_free(arg);		return res;	}}static voidfree_variable(struct variable * var){	struct variable *var_next;	if (var == NULL)		return;	var_next = var->next;	ecpg_free(var);	while (var_next)	{		var = var_next;		var_next = var->next;		ecpg_free(var);	}}static voidfree_statement(struct statement * stmt){	if (stmt == NULL)		return;	free_variable(stmt->inlist);	free_variable(stmt->outlist);	ecpg_free(stmt->command);	ecpg_free(stmt->name);	ecpg_free(stmt);}static intnext_insert(char *text, int pos, bool questionmarks){	bool		string = false;	int			p = pos;	for (; text[p] != '\0'; p++)	{		if (text[p] == '\\')	/* escape character */			p++;		else if (text[p] == '\'')			string = string ? false : true;		else if (!string)		{			if (text[p] == '$' && isdigit((unsigned char) text[p + 1]))			{				/* this can be either a dollar quote or a variable */				int			i;				for (i = p + 1; isdigit((unsigned char) text[i]); i++)					/* empty loop body */ ;				if (!isalpha((unsigned char) text[i]) &&					isascii((unsigned char) text[i]) && text[i] != '_')					/* not dollar delimited quote */					return p;			}			else if (questionmarks && text[p] == '?')			{				/* also allow old style placeholders */				return p;			}		}	}	return -1;}static boolecpg_type_infocache_push(struct ECPGtype_information_cache ** cache, int oid, bool isarray, int lineno){	struct ECPGtype_information_cache *new_entry	= (struct ECPGtype_information_cache *) ecpg_alloc(sizeof(struct ECPGtype_information_cache), lineno);	if (new_entry == NULL)		return (false);	new_entry->oid = oid;	new_entry->isarray = isarray;	new_entry->next = *cache;	*cache = new_entry;	return (true);}static enum ARRAY_TYPEecpg_is_type_an_array(int type, const struct statement * stmt, const struct variable * var){	char	   *array_query;	enum ARRAY_TYPE isarray = ECPG_ARRAY_NOT_SET;	PGresult   *query;	struct ECPGtype_information_cache *cache_entry;	if ((stmt->connection->cache_head) == NULL)	{		/*		 * Text like types are not an array for ecpg, but postgres counts them		 * as an array. This define reminds you to not 'correct' these values.		 */#define not_an_array_in_ecpg ECPG_ARRAY_NONE		/* populate cache with well known types to speed things up */		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), BOOLOID, ECPG_ARRAY_NONE, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), BYTEAOID, ECPG_ARRAY_NONE, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), CHAROID, ECPG_ARRAY_NONE, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), NAMEOID, not_an_array_in_ecpg, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), INT8OID, ECPG_ARRAY_NONE, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), INT2OID, ECPG_ARRAY_NONE, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), INT2VECTOROID, ECPG_ARRAY_VECTOR, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), INT4OID, ECPG_ARRAY_NONE, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), REGPROCOID, ECPG_ARRAY_NONE, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), TEXTOID, ECPG_ARRAY_NONE, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), OIDOID, ECPG_ARRAY_NONE, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), TIDOID, ECPG_ARRAY_NONE, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), XIDOID, ECPG_ARRAY_NONE, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), CIDOID, ECPG_ARRAY_NONE, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), OIDVECTOROID, ECPG_ARRAY_VECTOR, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), POINTOID, ECPG_ARRAY_VECTOR, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), LSEGOID, ECPG_ARRAY_VECTOR, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), PATHOID, ECPG_ARRAY_NONE, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), BOXOID, ECPG_ARRAY_VECTOR, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), POLYGONOID, ECPG_ARRAY_NONE, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), LINEOID, ECPG_ARRAY_VECTOR, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), FLOAT4OID, ECPG_ARRAY_NONE, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), FLOAT8OID, ECPG_ARRAY_NONE, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), ABSTIMEOID, ECPG_ARRAY_NONE, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), RELTIMEOID, ECPG_ARRAY_NONE, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), TINTERVALOID, ECPG_ARRAY_NONE, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), UNKNOWNOID, ECPG_ARRAY_NONE, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), CIRCLEOID, ECPG_ARRAY_NONE, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), CASHOID, ECPG_ARRAY_NONE, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), INETOID, ECPG_ARRAY_NONE, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), CIDROID, ECPG_ARRAY_NONE, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), BPCHAROID, ECPG_ARRAY_NONE, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), VARCHAROID, ECPG_ARRAY_NONE, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), DATEOID, ECPG_ARRAY_NONE, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), TIMEOID, ECPG_ARRAY_NONE, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), TIMESTAMPOID, ECPG_ARRAY_NONE, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), TIMESTAMPTZOID, ECPG_ARRAY_NONE, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), INTERVALOID, ECPG_ARRAY_NONE, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), TIMETZOID, ECPG_ARRAY_NONE, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), ZPBITOID, ECPG_ARRAY_NONE, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), VARBITOID, ECPG_ARRAY_NONE, stmt->lineno))			return (ECPG_ARRAY_ERROR);		if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), NUMERICOID, ECPG_ARRAY_NONE, stmt->lineno))			return (ECPG_ARRAY_ERROR);	}	for (cache_entry = (stmt->connection->cache_head); cache_entry != NULL; cache_entry = cache_entry->next)	{		if (cache_entry->oid == type)			return cache_entry->isarray;	}	array_query = (char *) ecpg_alloc(strlen("select typlen from pg_type where oid= and typelem<>0") + 11, stmt->lineno);	if (array_query == NULL)		return (ECPG_ARRAY_ERROR);	sprintf(array_query, "select typlen from pg_type where oid=%d and typelem<>0", type);	query = PQexec(stmt->connection->connection, array_query);	ecpg_free(array_query);	if (!ecpg_check_PQresult(query, stmt->lineno, stmt->connection->connection, stmt->compat))		return (ECPG_ARRAY_ERROR);	else if (PQresultStatus(query) == PGRES_TUPLES_OK)	{		if (PQntuples(query) == 0)			isarray = ECPG_ARRAY_NONE;		else		{			isarray = (atol((char *) PQgetvalue(query, 0, 0)) == -1) ? ECPG_ARRAY_ARRAY : ECPG_ARRAY_VECTOR;			if (ecpg_dynamic_type(type) == SQL3_CHARACTER ||				ecpg_dynamic_type(type) == SQL3_CHARACTER_VARYING)			{				/*				 * arrays of character strings are not yet implemented				 */				isarray = ECPG_ARRAY_NONE;			}		}		PQclear(query);	}	else		return (ECPG_ARRAY_ERROR);	ecpg_type_infocache_push(&(stmt->connection->cache_head), type, isarray, stmt->lineno);	ecpg_log("ecpg_is_type_an_array line %d: TYPE database: %d C: %d array: %s\n", stmt->lineno, type, var->type, isarray ? "Yes" : "No");	return isarray;}boolecpg_store_result(const PGresult *results, int act_field,				  const struct statement * stmt, struct variable * var){	enum ARRAY_TYPE isarray;	int			act_tuple,				ntuples = PQntuples(results);	bool		status = true;	if ((isarray = ecpg_is_type_an_array(PQftype(results, act_field), stmt, var)) == ECPG_ARRAY_ERROR)	{		ecpg_raise(stmt->lineno, ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);		return false;	}	if (isarray == ECPG_ARRAY_NONE)	{		/*		 * if we don't have enough space, we cannot read all tuples		 */		if ((var->arrsize > 0 && ntuples > var->arrsize) || (var->ind_arrsize > 0 && ntuples > var->ind_arrsize))		{			ecpg_log("ecpg_store_result line %d: Incorrect number of matches: %d don't fit into array of %d\n",					 stmt->lineno, ntuples, var->arrsize);			ecpg_raise(stmt->lineno, INFORMIX_MODE(stmt->compat) ? ECPG_INFORMIX_SUBSELECT_NOT_ONE : ECPG_TOO_MANY_MATCHES, ECPG_SQLSTATE_CARDINALITY_VIOLATION, NULL);			return false;		}	}	else	{		/*		 * since we read an array, the variable has to be an array too		 */		if (var->arrsize == 0)		{			ecpg_raise(stmt->lineno, ECPG_NO_ARRAY, ECPG_SQLSTATE_DATATYPE_MISMATCH, NULL);			return false;		}	}	/*	 * allocate memory for NULL pointers	 */	if ((var->arrsize == 0 || var->varcharsize == 0) && var->value == NULL)	{		int			len = 0;		switch (var->type)		{			case ECPGt_char:			case ECPGt_unsigned_char:				if (!var->varcharsize && !var->arrsize)				{					/* special mode for handling char**foo=0 */					for (act_tuple = 0; act_tuple < ntuples; act_tuple++)						len += strlen(PQgetvalue(results, act_tuple, act_field)) + 1;					len *= var->offset; /* should be 1, but YMNK */					len += (ntuples + 1) * sizeof(char *);				}				else				{					var->varcharsize = 0;					/* check strlen for each tuple */					for (act_tuple = 0; act_tuple < ntuples; act_tuple++)					{						int			len = strlen(PQgetvalue(results, act_tuple, act_field)) + 1;						if (len > var->varcharsize)							var->varcharsize = len;					}					var->offset *= var->varcharsize;					len = var->offset * ntuples;				}				break;			case ECPGt_varchar:				len = ntuples * (var->varcharsize + sizeof(int));				break;			default:				len = var->offset * ntuples;				break;		}		ecpg_log("ecpg_store_result: line %d: allocating memory for %d tuples\n", stmt->lineno, ntuples);		var->value = (char *) ecpg_alloc(len, stmt->lineno);		if (!var->value)			return false;		*((char **) var->pointer) = var->value;		ecpg_add_mem(var->value, stmt->lineno);	}	/* allocate indicator variable if needed */	if ((var->ind_arrsize == 0 || var->ind_varcharsize == 0) && var->ind_value == NULL && var->ind_pointer != NULL)	{		int			len = var->ind_offset * ntuples;		var->ind_value = (char *) ecpg_alloc(len, stmt->lineno);		if (!var->ind_value)			return false;		*((char **) var->ind_pointer) = var->ind_value;		ecpg_add_mem(var->ind_value, stmt->lineno);	}	/* fill the variable with the tuple(s) */	if (!var->varcharsize && !var->arrsize &&		(var->type == ECPGt_char || var->type == ECPGt_unsigned_char))	{		/* special mode for handling char**foo=0 */

⌨️ 快捷键说明

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