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

📄 execute.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 3 页
字号:
				break;			case ECPGt_date:				{					char	   *str = NULL;					int			slen;					if (var->arrsize > 1)					{						for (element = 0; element < var->arrsize; element++)						{							str = quote_postgres(PGTYPESdate_to_asc(*(date *) ((var + var->offset * element)->value)), lineno);							slen = strlen(str);							if (!(mallocedval = ECPGrealloc(mallocedval, strlen(mallocedval) + slen + sizeof("array [],date "), lineno)))								return false;							if (!element)								strcpy(mallocedval, "array [");							strcpy(mallocedval + strlen(mallocedval), "date ");							strncpy(mallocedval + strlen(mallocedval), str, slen + 1);							strcpy(mallocedval + strlen(mallocedval), ",");						}						strcpy(mallocedval + strlen(mallocedval) - 1, "]");					}					else					{						str = quote_postgres(PGTYPESdate_to_asc(*(date *) (var->value)), lineno);						slen = strlen(str);						if (!(mallocedval = ECPGalloc(slen + sizeof("date ") + 1, lineno)))							return false;						strcpy(mallocedval, "date ");						/* also copy trailing '\0' */						strncpy(mallocedval + strlen(mallocedval), str, slen + 1);					}					*tobeinserted_p = mallocedval;					*malloced_p = true;					free(str);				}				break;			case ECPGt_timestamp:				{					char	   *str = NULL;					int			slen;					if (var->arrsize > 1)					{						for (element = 0; element < var->arrsize; element++)						{							str = quote_postgres(PGTYPEStimestamp_to_asc(*(timestamp *) ((var + var->offset * element)->value)), lineno);							slen = strlen(str);							if (!(mallocedval = ECPGrealloc(mallocedval, strlen(mallocedval) + slen + sizeof("array [], timestamp "), lineno)))								return false;							if (!element)								strcpy(mallocedval, "array [");							strcpy(mallocedval + strlen(mallocedval), "timestamp ");							strncpy(mallocedval + strlen(mallocedval), str, slen + 1);							strcpy(mallocedval + strlen(mallocedval), ",");						}						strcpy(mallocedval + strlen(mallocedval) - 1, "]");					}					else					{						str = quote_postgres(PGTYPEStimestamp_to_asc(*(timestamp *) (var->value)), lineno);						slen = strlen(str);						if (!(mallocedval = ECPGalloc(slen + sizeof("timestamp") + 1, lineno)))							return false;						strcpy(mallocedval, "timestamp ");						/* also copy trailing '\0' */						strncpy(mallocedval + strlen(mallocedval), str, slen + 1);					}					*tobeinserted_p = mallocedval;					*malloced_p = true;					free(str);				}				break;			case ECPGt_descriptor:				break;			default:				/* Not implemented yet */				ECPGraise(lineno, ECPG_UNSUPPORTED, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, (char *) ECPGtype_name(var->type));				return false;				break;		}	}	return true;}static boolECPGexecute(struct statement * stmt){	bool		status = false;	char	   *copiedquery;	char	   *cmdstat;	PGresult   *results;	PGnotify   *notify;	struct variable *var;	int			desc_counter = 0;	copiedquery = ECPGstrdup(stmt->command, stmt->lineno);	/*	 * Now, if the type is one of the fill in types then we take the argument	 * and enter that in the string at the first %s position. Then if there	 * are any more fill in types we fill in at the next and so on.	 */	var = stmt->inlist;	while (var)	{		char	   *newcopy = NULL;		const char *tobeinserted;		char	   *p;		bool		malloced = FALSE;		int			hostvarl = 0;		tobeinserted = NULL;		/*		 * A descriptor is a special case since it contains many variables but		 * is listed only once.		 */		if (var->type == ECPGt_descriptor)		{			/*			 * We create an additional variable list here, so the same logic			 * applies.			 */			struct variable desc_inlist;			struct descriptor *desc;			struct descriptor_item *desc_item;			for (desc = all_descriptors; desc; desc = desc->next)			{				if (strcmp(var->pointer, desc->name) == 0)					break;			}			if (desc == NULL)			{				ECPGraise(stmt->lineno, ECPG_UNKNOWN_DESCRIPTOR, ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME, var->pointer);				return false;			}			desc_counter++;			if (desc->count < 0 || desc->count >= desc_counter)			{				for (desc_item = desc->items; desc_item; desc_item = desc_item->next)				{					if (desc_item->num == desc_counter)					{						desc_inlist.type = ECPGt_char;						desc_inlist.value = desc_item->data;						desc_inlist.pointer = &(desc_item->data);						desc_inlist.varcharsize = strlen(desc_item->data);						desc_inlist.arrsize = 1;						desc_inlist.offset = 0;						if (!desc_item->indicator)						{							desc_inlist.ind_type = ECPGt_NO_INDICATOR;							desc_inlist.ind_value = desc_inlist.ind_pointer = NULL;							desc_inlist.ind_varcharsize = desc_inlist.ind_arrsize = desc_inlist.ind_offset = 0;						}						else						{							desc_inlist.ind_type = ECPGt_int;							desc_inlist.ind_value = &(desc_item->indicator);							desc_inlist.ind_pointer = &(desc_inlist.ind_value);							desc_inlist.ind_varcharsize = desc_inlist.ind_arrsize = 1;							desc_inlist.ind_offset = 0;						}						if (!ECPGstore_input(stmt->lineno, stmt->force_indicator, &desc_inlist, &tobeinserted, &malloced))							return false;						break;					}				}				if (!desc_item) /* no more entries found in descriptor */					desc_counter = 0;			}			else				desc_counter = 0;		}		else		{			if (!ECPGstore_input(stmt->lineno, stmt->force_indicator, var, &tobeinserted, &malloced))				return false;		}		if (tobeinserted)		{			/*			 * Now tobeinserted points to an area that is to be inserted at			 * the first %s			 */			if (!(newcopy = (char *) ECPGalloc(strlen(copiedquery) + strlen(tobeinserted) + 1, stmt->lineno)))				return false;			strcpy(newcopy, copiedquery);			if ((p = next_insert(newcopy + hostvarl)) == NULL)			{				/*				 * We have an argument but we dont have the matched up string				 * in the string				 */				ECPGraise(stmt->lineno, ECPG_TOO_MANY_ARGUMENTS, ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_PARAMETERS, NULL);				return false;			}			else			{				strcpy(p, tobeinserted);				hostvarl = strlen(newcopy);				/*				 * The strange thing in the second argument is the rest of the				 * string from the old string				 */				strcat(newcopy,					   copiedquery					   + (p - newcopy)					   + sizeof("?") - 1 /* don't count the '\0' */ );			}			/*			 * Now everything is safely copied to the newcopy. Lets free the			 * oldcopy and let the copiedquery get the var->value from the			 * newcopy.			 */			if (malloced)			{				ECPGfree((char *) tobeinserted);				tobeinserted = NULL;			}			ECPGfree(copiedquery);			copiedquery = newcopy;		}		if (desc_counter == 0)			var = var->next;	}	/* Check if there are unmatched things left. */	if (next_insert(copiedquery) != NULL)	{		ECPGraise(stmt->lineno, ECPG_TOO_FEW_ARGUMENTS, ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_PARAMETERS, NULL);		return false;	}	/* Now the request is built. */	if (stmt->connection->committed && !stmt->connection->autocommit)	{		if ((results = PQexec(stmt->connection->connection, "begin transaction")) == NULL)		{			ECPGraise(stmt->lineno, ECPG_TRANS, ECPG_SQLSTATE_TRANSACTION_RESOLUTION_UNKNOWN, NULL);			return false;		}		PQclear(results);		stmt->connection->committed = false;	}	ECPGlog("ECPGexecute line %d: QUERY: %s on connection %s\n", stmt->lineno, copiedquery, stmt->connection->name);	results = PQexec(stmt->connection->connection, copiedquery);	ECPGfree(copiedquery);	if (results == NULL)	{		ECPGlog("ECPGexecute line %d: error: %s", stmt->lineno, PQerrorMessage(stmt->connection->connection));		ECPGraise_backend(stmt->lineno, NULL, stmt->connection->connection, stmt->compat);	}	else		/*		 * note: since some of the following code is duplicated in		 * descriptor.c it should go into a separate function		 */	{		bool		clear_result = TRUE;		struct sqlca_t *sqlca = ECPGget_sqlca();		var = stmt->outlist;		switch (PQresultStatus(results))		{				int			nfields,							ntuples,							act_field;			case PGRES_TUPLES_OK:				nfields = PQnfields(results);				sqlca->sqlerrd[2] = ntuples = PQntuples(results);				ECPGlog("ECPGexecute line %d: Correctly got %d tuples with %d fields\n", stmt->lineno, ntuples, nfields);				status = true;				if (ntuples < 1)				{					if (ntuples)						ECPGlog("ECPGexecute line %d: Incorrect number of matches: %d\n",								stmt->lineno, ntuples);					ECPGraise(stmt->lineno, ECPG_NOT_FOUND, ECPG_SQLSTATE_NO_DATA, NULL);					status = false;					break;				}				if (var != NULL && var->type == ECPGt_descriptor)				{					PGresult  **resultpp = ECPGdescriptor_lvalue(stmt->lineno, (const char *) var->pointer);					if (resultpp == NULL)						status = false;					else					{						if (*resultpp)							PQclear(*resultpp);						*resultpp = results;						clear_result = FALSE;						ECPGlog("ECPGexecute putting result (%d tuples) into descriptor '%s'\n", PQntuples(results), (const char *) var->pointer);					}					var = var->next;				}				else					for (act_field = 0; act_field < nfields && status; act_field++)					{						if (var != NULL)						{							status = ECPGstore_result(results, act_field, stmt, var);							var = var->next;						}						else if (!INFORMIX_MODE(stmt->compat))						{							ECPGraise(stmt->lineno, ECPG_TOO_FEW_ARGUMENTS, ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_TARGETS, NULL);							return (false);						}					}				if (status && var != NULL)				{					ECPGraise(stmt->lineno, ECPG_TOO_MANY_ARGUMENTS, ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_TARGETS, NULL);					status = false;				}				break;			case PGRES_EMPTY_QUERY:				/* do nothing */				ECPGraise(stmt->lineno, ECPG_EMPTY, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, NULL);				break;			case PGRES_COMMAND_OK:				status = true;				cmdstat = PQcmdStatus(results);				sqlca->sqlerrd[1] = PQoidValue(results);				sqlca->sqlerrd[2] = atol(PQcmdTuples(results));				ECPGlog("ECPGexecute line %d Ok: %s\n", stmt->lineno, cmdstat);				if (stmt->compat != ECPG_COMPAT_INFORMIX_SE &&					!sqlca->sqlerrd[2] &&					(!strncmp(cmdstat, "UPDATE", 6)					 || !strncmp(cmdstat, "INSERT", 6)					 || !strncmp(cmdstat, "DELETE", 6)))					ECPGraise(stmt->lineno, ECPG_NOT_FOUND, ECPG_SQLSTATE_NO_DATA, NULL);				break;			case PGRES_NONFATAL_ERROR:			case PGRES_FATAL_ERROR:			case PGRES_BAD_RESPONSE:				ECPGlog("ECPGexecute line %d: Error: %s", stmt->lineno, PQresultErrorMessage(results));				ECPGraise_backend(stmt->lineno, results, stmt->connection->connection, stmt->compat);				status = false;				break;			case PGRES_COPY_OUT:				ECPGlog("ECPGexecute line %d: Got PGRES_COPY_OUT ... tossing.\n", stmt->lineno);				PQendcopy(stmt->connection->connection);				break;			case PGRES_COPY_IN:				ECPGlog("ECPGexecute line %d: Got PGRES_COPY_IN ... tossing.\n", stmt->lineno);				PQendcopy(stmt->connection->connection);				break;			default:				ECPGlog("ECPGexecute line %d: Got something else, postgres error.\n",						stmt->lineno);				ECPGraise_backend(stmt->lineno, results, stmt->connection->connection, stmt->compat);				status = false;				break;		}		if (clear_result)			PQclear(results);	}	/* check for asynchronous returns */	notify = PQnotifies(stmt->connection->connection);	if (notify)	{		ECPGlog("ECPGexecute line %d: ASYNC NOTIFY of '%s' from backend pid '%d' received\n",				stmt->lineno, notify->relname, notify->be_pid);		PQfreemem(notify);	}	return status;}boolECPGdo(int lineno, int compat, int force_indicator, const char *connection_name, const char *query,...){	va_list		args;	struct statement *stmt;	struct connection *con = ECPGget_connection(connection_name);	bool		status;	char	   *oldlocale;	/* Make sure we do NOT honor the locale for numeric input/output */	/* since the database wants the standard decimal point */	oldlocale = ECPGstrdup(setlocale(LC_NUMERIC, NULL), lineno);	setlocale(LC_NUMERIC, "C");	if (!ECPGinit(con, connection_name, lineno))	{		setlocale(LC_NUMERIC, oldlocale);		ECPGfree(oldlocale);		return (false);	}	/* construct statement in our own structure */	va_start(args, query);	if (create_statement(lineno, compat, force_indicator, con, &stmt, query, args) == false)	{		setlocale(LC_NUMERIC, oldlocale);		ECPGfree(oldlocale);		return (false);	}	va_end(args);	/* are we connected? */	if (con == NULL || con->connection == NULL)	{		free_statement(stmt);		ECPGraise(lineno, ECPG_NOT_CONN, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, (con) ? con->name : "<empty>");		setlocale(LC_NUMERIC, oldlocale);		ECPGfree(oldlocale);		return false;	}	/* initialize auto_mem struct */	ECPGclear_auto_mem();	status = ECPGexecute(stmt);	free_statement(stmt);	/* and reset locale value so our application is not affected */	setlocale(LC_NUMERIC, oldlocale);	ECPGfree(oldlocale);	return (status);}/* old descriptor interface */boolECPGdo_descriptor(int line, const char *connection,				  const char *descriptor, const char *query){	return ECPGdo(line, ECPG_COMPAT_PGSQL, true, connection, (char *) query, ECPGt_EOIT,				  ECPGt_descriptor, descriptor, 0L, 0L, 0L,				  ECPGt_NO_INDICATOR, NULL, 0L, 0L, 0L, ECPGt_EORT);}

⌨️ 快捷键说明

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