descriptor.c

来自「postgresql8.3.4源码,开源数据库」· C语言 代码 · 共 730 行 · 第 1/2 页

C
730
字号
				ecpg_log("ECPGget_desc: TYPE = %d\n", ecpg_dynamic_type_DDT(PQftype(ECPGresult, index)));				break;			case ECPGd_cardinality:				if (!get_int_item(lineno, var, vartype, PQntuples(ECPGresult)))					return (false);				ecpg_log("ECPGget_desc: CARDINALITY = %d\n", PQntuples(ECPGresult));				break;			case ECPGd_ret_length:			case ECPGd_ret_octet:				/*				 * this is like ECPGstore_result				 */				if (arrsize > 0 && ntuples > arrsize)				{					ecpg_log("ECPGget_desc line %d: Incorrect number of matches: %d don't fit into array of %d\n",							 lineno, ntuples, arrsize);					ecpg_raise(lineno, ECPG_TOO_MANY_MATCHES, ECPG_SQLSTATE_CARDINALITY_VIOLATION, NULL);					return false;				}				/* allocate storage if needed */				if (arrsize == 0 && *(void **) var == NULL)				{					void	   *mem = (void *) ecpg_alloc(offset * ntuples, lineno);					if (!mem)						return false;					*(void **) var = mem;					ecpg_add_mem(mem, lineno);					var = mem;				}				for (act_tuple = 0; act_tuple < ntuples; act_tuple++)				{					if (!get_int_item(lineno, var, vartype, PQgetlength(ECPGresult, act_tuple, index)))						return (false);					var = (char *) var + offset;					ecpg_log("ECPGget_desc: RETURNED[%d] = %d\n", act_tuple, PQgetlength(ECPGresult, act_tuple, index));				}				break;			default:				snprintf(type_str, sizeof(type_str), "%d", type);				ecpg_raise(lineno, ECPG_UNKNOWN_DESCRIPTOR_ITEM, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, type_str);				return (false);		}		type = va_arg(args, enum ECPGdtype);	}	if (data_var.type != ECPGt_EORT)	{		struct statement stmt;		char	   *oldlocale;		/* Make sure we do NOT honor the locale for numeric input */		/* since the database gives the standard decimal point */		oldlocale = ecpg_strdup(setlocale(LC_NUMERIC, NULL), lineno);		setlocale(LC_NUMERIC, "C");		memset(&stmt, 0, sizeof stmt);		stmt.lineno = lineno;		/* desparate try to guess something sensible */		stmt.connection = ecpg_get_connection(NULL);		ecpg_store_result(ECPGresult, index, &stmt, &data_var);		setlocale(LC_NUMERIC, oldlocale);		ecpg_free(oldlocale);	}	else if (data_var.ind_type != ECPGt_NO_INDICATOR && data_var.ind_pointer != NULL)		/*		 * ind_type != NO_INDICATOR should always have ind_pointer != NULL but		 * since this might be changed manually in the .c file let's play it		 * safe		 */	{		/*		 * this is like ECPGstore_result but since we don't have a data		 * variable at hand, we can't call it		 */		if (data_var.ind_arrsize > 0 && ntuples > data_var.ind_arrsize)		{			ecpg_log("ECPGget_desc line %d: Incorrect number of matches (indicator): %d don't fit into array of %d\n",					 lineno, ntuples, data_var.ind_arrsize);			ecpg_raise(lineno, ECPG_TOO_MANY_MATCHES, ECPG_SQLSTATE_CARDINALITY_VIOLATION, NULL);			return false;		}		/* allocate storage if needed */		if (data_var.ind_arrsize == 0 && data_var.ind_value == NULL)		{			void	   *mem = (void *) ecpg_alloc(data_var.ind_offset * ntuples, lineno);			if (!mem)				return false;			*(void **) data_var.ind_pointer = mem;			ecpg_add_mem(mem, lineno);			data_var.ind_value = mem;		}		for (act_tuple = 0; act_tuple < ntuples; act_tuple++)		{			if (!get_int_item(lineno, data_var.ind_value, data_var.ind_type, -PQgetisnull(ECPGresult, act_tuple, index)))				return (false);			data_var.ind_value = (char *) data_var.ind_value + data_var.ind_offset;			ecpg_log("ECPGget_desc: INDICATOR[%d] = %d\n", act_tuple, -PQgetisnull(ECPGresult, act_tuple, index));		}	}	sqlca->sqlerrd[2] = ntuples;	return (true);}boolECPGset_desc_header(int lineno, const char *desc_name, int count){	struct descriptor *desc = ecpg_find_desc(lineno, desc_name);	if (desc == NULL)		return false;	desc->count = count;	return true;}boolECPGset_desc(int lineno, const char *desc_name, int index,...){	va_list		args;	struct descriptor *desc;	struct descriptor_item *desc_item;	struct variable *var;	desc = ecpg_find_desc(lineno, desc_name);	if (desc == NULL)		return false;	for (desc_item = desc->items; desc_item; desc_item = desc_item->next)	{		if (desc_item->num == index)			break;	}	if (desc_item == NULL)	{		desc_item = (struct descriptor_item *) ecpg_alloc(sizeof(*desc_item), lineno);		if (!desc_item)			return false;		desc_item->num = index;		if (desc->count < index)			desc->count = index;		desc_item->next = desc->items;		desc->items = desc_item;	}	if (!(var = (struct variable *) ecpg_alloc(sizeof(struct variable), lineno)))		return false;	va_start(args, index);	for (;;)	{		enum ECPGdtype itemtype;		char *tobeinserted = NULL;		itemtype = va_arg(args, enum ECPGdtype);		if (itemtype == ECPGd_EODT)			break;		var->type = va_arg(args, enum ECPGttype);		var->pointer = va_arg(args, char *);		var->varcharsize = va_arg(args, long);		var->arrsize = va_arg(args, long);		var->offset = va_arg(args, long);		if (var->arrsize == 0 || var->varcharsize == 0)			var->value = *((char **) (var->pointer));		else			var->value = var->pointer;		/*		 * negative values are used to indicate an array without given bounds		 */		/* reset to zero for us */		if (var->arrsize < 0)			var->arrsize = 0;		if (var->varcharsize < 0)			var->varcharsize = 0;		var->next = NULL;		switch (itemtype)		{			case ECPGd_data:				{					if (!ecpg_store_input(lineno, true, var, &tobeinserted, false))					{						ecpg_free(var);						return false;					}					ecpg_free(desc_item->data); /* free() takes care of a												 * potential NULL value */					desc_item->data = (char *) tobeinserted;					tobeinserted = NULL;					break;				}			case ECPGd_indicator:				set_int_item(lineno, &desc_item->indicator, var->pointer, var->type);				break;			case ECPGd_length:				set_int_item(lineno, &desc_item->length, var->pointer, var->type);				break;			case ECPGd_precision:				set_int_item(lineno, &desc_item->precision, var->pointer, var->type);				break;			case ECPGd_scale:				set_int_item(lineno, &desc_item->scale, var->pointer, var->type);				break;			case ECPGd_type:				set_int_item(lineno, &desc_item->type, var->pointer, var->type);				break;			default:				{					char		type_str[20];					snprintf(type_str, sizeof(type_str), "%d", itemtype);					ecpg_raise(lineno, ECPG_UNKNOWN_DESCRIPTOR_ITEM, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, type_str);					ecpg_free(var);					return false;				}		}	}	ecpg_free(var);	return true;}/* Free the descriptor and items in it. */static voiddescriptor_free(struct descriptor * desc){	struct descriptor_item *desc_item;	for (desc_item = desc->items; desc_item;)	{		struct descriptor_item *di;		ecpg_free(desc_item->data);		di = desc_item;		desc_item = desc_item->next;		ecpg_free(di);	}	ecpg_free(desc->name);	PQclear(desc->result);	ecpg_free(desc);}boolECPGdeallocate_desc(int line, const char *name){	struct descriptor *desc;	struct descriptor *prev;	struct sqlca_t *sqlca = ECPGget_sqlca();	ecpg_init_sqlca(sqlca);	for (desc = get_descriptors(), prev = NULL; desc; prev = desc, desc = desc->next)	{		if (!strcmp(name, desc->name))		{			if (prev)				prev->next = desc->next;			else				set_descriptors(desc->next);			descriptor_free(desc);			return true;		}	}	ecpg_raise(line, ECPG_UNKNOWN_DESCRIPTOR, ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME, name);	return false;}#ifdef ENABLE_THREAD_SAFETY/* Deallocate all descriptors in the list */static voiddescriptor_deallocate_all(struct descriptor * list){	while (list)	{		struct descriptor *next = list->next;		descriptor_free(list);		list = next;	}}#endif   /* ENABLE_THREAD_SAFETY */boolECPGallocate_desc(int line, const char *name){	struct descriptor *new;	struct sqlca_t *sqlca = ECPGget_sqlca();	ecpg_init_sqlca(sqlca);	new = (struct descriptor *) ecpg_alloc(sizeof(struct descriptor), line);	if (!new)		return false;	new->next = get_descriptors();	new->name = ecpg_alloc(strlen(name) + 1, line);	if (!new->name)	{		ecpg_free(new);		return false;	}	new->count = -1;	new->items = NULL;	new->result = PQmakeEmptyPGresult(NULL, 0);	if (!new->result)	{		ecpg_free(new->name);		ecpg_free(new);		ecpg_raise(line, ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);		return false;	}	strcpy(new->name, name);	set_descriptors(new);	return true;}/* Find descriptor with name in the connection. */struct descriptor *ecpg_find_desc(int line, const char *name){	struct descriptor *desc;	for (desc = get_descriptors(); desc; desc = desc->next)	{		if (strcmp(name, desc->name) == 0)			return desc;	}	ecpg_raise(line, ECPG_UNKNOWN_DESCRIPTOR, ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME, name);	return NULL;				/* not found */}boolECPGdescribe(int line, bool input, const char *statement,...){	ecpg_log("ECPGdescribe called on line %d for %s in %s\n", line, (input) ? "input" : "output", statement);	return false;}

⌨️ 快捷键说明

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