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

📄 statement.c

📁 postgresql-odbc,跨平台应用
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (option == STMT_FREE_PARAMS_ALL)	{		self->exec_start_row = -1;		self->exec_end_row = -1;		self->exec_current_row = -1;	}}intstatement_type(const char *statement){	int			i;	/* ignore leading whitespace in query string */	while (*statement && (isspace((UCHAR) *statement) || *statement == '('))		statement++;	for (i = 0; Statement_Type[i].s; i++)		if (!strnicmp(statement, Statement_Type[i].s, strlen(Statement_Type[i].s)))			return Statement_Type[i].type;	return STMT_TYPE_OTHER;}voidSC_set_planname(StatementClass *stmt, const char *plan_name){	if (stmt->plan_name)		free(stmt->plan_name);	if (plan_name && plan_name[0])		stmt->plan_name = strdup(plan_name);	else		stmt->plan_name = NULL;}voidSC_set_rowset_start(StatementClass *stmt, SQLLEN start, BOOL valid_base){	QResultClass	*res = SC_get_Curres(stmt);	SQLLEN		incr = start - stmt->rowset_start;inolog("%p->SC_set_rowstart " FORMAT_LEN "->" FORMAT_LEN "(%s) ", stmt, stmt->rowset_start, start, valid_base ? "valid" : "unknown");	if (res != NULL)	{		BOOL	valid = QR_has_valid_base(res);inolog(":QR is %s", QR_has_valid_base(res) ? "valid" : "unknown");		if (valid)		{			if (valid_base)				QR_inc_rowstart_in_cache(res, incr);			else				QR_set_no_valid_base(res);		}		else if (valid_base)		{				QR_set_has_valid_base(res);			if (start < 0)				QR_set_rowstart_in_cache(res, -1);			else				QR_set_rowstart_in_cache(res, 0);		}		if (!QR_get_cursor(res))			res->key_base = start;inolog(":QR result=" FORMAT_LEN "(%s)", QR_get_rowstart_in_cache(res), QR_has_valid_base(res) ? "valid" : "unknown");	}	stmt->rowset_start = start;inolog(":stmt result=" FORMAT_LEN "\n", stmt->rowset_start);}voidSC_inc_rowset_start(StatementClass *stmt, SQLLEN inc){	SQLLEN	start = stmt->rowset_start + inc;		SC_set_rowset_start(stmt, start, TRUE);}intSC_set_current_col(StatementClass *stmt, int col){	if (col == stmt->current_col)		return col;	if (col >= 0)		reset_a_getdata_info(SC_get_GDTI(stmt), col + 1);	stmt->current_col = col;	return stmt->current_col;}voidSC_set_prepared(StatementClass *stmt, BOOL prepared){	if (prepared == stmt->prepared)		;	else if (NOT_YET_PREPARED == prepared && PREPARED_PERMANENTLY == stmt->prepared)	{		ConnectionClass *conn = SC_get_conn(stmt);		if (conn && CONN_CONNECTED == conn->status)		{			if (CC_is_in_error_trans(conn))			{				CC_mark_a_object_to_discard(conn, 's',  stmt->plan_name);			}			else			{				QResultClass	*res;				char dealloc_stmt[128];				sprintf(dealloc_stmt, "DEALLOCATE \"%s\"", stmt->plan_name);				res = CC_send_query(conn, dealloc_stmt, NULL, IGNORE_ABORT_ON_CONN | ROLLBACK_ON_ERROR, NULL);				QR_Destructor(res);			} 		}	}	if (NOT_YET_PREPARED == prepared)		SC_set_planname(stmt, NULL);	stmt->prepared = prepared;}/* *	Initialize stmt_with_params, load_statement and execute_statement *		member pointer deallocating corresponding prepared plan. *	Also initialize statement member pointer if specified. */RETCODESC_initialize_stmts(StatementClass *self, BOOL initializeOriginal){	ConnectionClass *conn = SC_get_conn(self);	if (self->lock_CC_for_rb > 0)	{		while (self->lock_CC_for_rb > 0)		{			LEAVE_CONN_CS(conn);			self->lock_CC_for_rb--;		}	}	if (initializeOriginal)	{		if (self->statement)		{			free(self->statement);			self->statement = NULL;		}		if (self->execute_statement)		{			free(self->execute_statement);			self->execute_statement = NULL;		}		self->prepare = NON_PREPARE_STATEMENT;		SC_set_prepared(self, NOT_YET_PREPARED);		self->statement_type = STMT_TYPE_UNKNOWN; /* unknown */		self->multi_statement = -1; /* unknown */		self->num_params = -1; /* unknown */		self->proc_return = -1; /* unknown */		self->join_info = 0;		SC_init_parse_method(self);		SC_init_discard_output_params(self);	}	if (self->stmt_with_params)	{		free(self->stmt_with_params);		self->stmt_with_params = NULL;	}	if (self->load_statement)	{		free(self->load_statement);		self->load_statement = NULL;	}	return 0;}BOOL	SC_opencheck(StatementClass *self, const char *func){	QResultClass	*res;	if (!self)		return FALSE;	if (self->status == STMT_EXECUTING)	{        	SC_set_error(self, STMT_SEQUENCE_ERROR, "Statement is currently executing a transaction.", func);		return TRUE;	}	/*	 * We can dispose the result of PREMATURE execution any time.	 */	if (self->prepare && self->status == STMT_PREMATURE)	{		mylog("SC_opencheck: self->prepare && self->status == STMT_PREMATURE\n");		return FALSE;	}	if (res = SC_get_Curres(self), NULL != res)	{		if (QR_command_maybe_successful(res) && res->backend_tuples)		{        		SC_set_error(self, STMT_SEQUENCE_ERROR, "The cursor is open.", func);			return TRUE;		}	}	return	FALSE;}RETCODESC_initialize_and_recycle(StatementClass *self){	SC_initialize_stmts(self, TRUE);	if (!SC_recycle_statement(self))		return SQL_ERROR;	return SQL_SUCCESS;}/* *	Called from SQLPrepare if STMT_PREMATURE, or *	from SQLExecute if STMT_FINISHED, or *	from SQLFreeStmt(SQL_CLOSE) */charSC_recycle_statement(StatementClass *self){	CSTR	func = "SC_recycle_statement";	ConnectionClass *conn;	QResultClass	*res;	mylog("%s: self= %p\n", func, self);	SC_clear_error(self);	/* This would not happen */	if (self->status == STMT_EXECUTING)	{		SC_set_error(self, STMT_SEQUENCE_ERROR, "Statement is currently executing a transaction.", func);		return FALSE;	}	conn = SC_get_conn(self);	switch (self->status)	{		case STMT_ALLOCATED:			/* this statement does not need to be recycled */			return TRUE;		case STMT_READY:			break;		case STMT_PREMATURE:			/*			 * Premature execution of the statement might have caused the			 * start of a transaction. If so, we have to rollback that			 * transaction.			 */			if (!CC_is_in_autocommit(conn) && CC_is_in_trans(conn))			{				if (SC_is_pre_executable(self) && !SC_is_parse_tricky(self))					CC_abort(conn);			}			break;		case STMT_FINISHED:			break;		default:			SC_set_error(self, STMT_INTERNAL_ERROR, "An internal error occured while recycling statements", func);			return FALSE;	}	switch (self->prepared)	{		case NOT_YET_PREPARED:		case ONCE_DESCRIBED:        		/* Free the parsed table/field information */			SC_initialize_cols_info(self, TRUE, TRUE);inolog("SC_clear_parse_status\n");			SC_clear_parse_status(self, conn);			break;	}	/* Free any cursors */	if (res = SC_get_Result(self), res)	{		if (PREPARED_PERMANENTLY == self->prepared)			QR_close_result(res, FALSE);		else		{			QR_Destructor(res);			SC_init_Result(self);		}	}	self->inaccurate_result = FALSE;	self->miscinfo = 0;	/* self->rbonerr = 0; Never clear the bits here */	/*	 * Reset only parameters that have anything to do with results	 */	self->status = STMT_READY;	self->catalog_result = FALSE;	/* not very important */	self->currTuple = -1;	SC_set_rowset_start(self, -1, FALSE);	SC_set_current_col(self, -1);	self->bind_row = 0;inolog("%s statement=%p ommitted=0\n", func, self);	self->last_fetch_count = self->last_fetch_count_include_ommitted = 0;	self->__error_message = NULL;	self->__error_number = 0;	self->lobj_fd = -1;	/*	 * Free any data at exec params before the statement is executed	 * again.  If not, then there will be a memory leak when the next	 * SQLParamData/SQLPutData is called.	 */	SC_free_params(self, STMT_FREE_PARAMS_DATA_AT_EXEC_ONLY);	SC_initialize_stmts(self, FALSE);	cancelNeedDataState(self);	self->cancel_info = 0;	/*	 *	reset the current attr setting to the original one.	 */	self->options.scroll_concurrency = self->options_orig.scroll_concurrency;	self->options.cursor_type = self->options_orig.cursor_type;	self->options.keyset_size = self->options_orig.keyset_size;	self->options.maxLength = self->options_orig.maxLength;	self->options.maxRows = self->options_orig.maxRows;	return TRUE;}/* *	Scan the query wholly or partially (if specifed next_cmd). *	Also count the number of parameters respectviely. */voidSC_scanQueryAndCountParams(const char *query, const ConnectionClass *conn,		Int4 *next_cmd, SQLSMALLINT * pcpar,		char *multi_st, char *proc_return){	CSTR func = "SC_scanQueryAndCountParams";	char	literal_quote = LITERAL_QUOTE, identifier_quote = IDENTIFIER_QUOTE, dollar_quote = DOLLAR_QUOTE;	const	char *sptr, *tstr, *tag = NULL;	size_t	taglen = 0;	char	tchar, bchar, escape_in_literal = '\0';	char	in_literal = FALSE, in_identifier = FALSE,		in_dollar_quote = FALSE, in_escape = FALSE,		del_found = FALSE, multi = FALSE;	SQLSMALLINT	num_p;	encoded_str	encstr;	mylog("%s: entering...\n", func);	num_p = 0;	if (proc_return)		*proc_return = 0;	if (next_cmd)		*next_cmd = -1;	tstr = query;	make_encoded_str(&encstr, conn, tstr);	for (sptr = tstr, bchar = '\0'; *sptr; sptr++)	{		tchar = encoded_nextchar(&encstr);		if (ENCODE_STATUS(encstr) != 0) /* multibyte char */		{			if ((UCHAR) tchar >= 0x80)				bchar = tchar;			continue;		}		if (!multi && del_found)		{			if (!isspace(tchar))			{				multi = TRUE;				if (next_cmd)					break;			}		}		if (in_dollar_quote)		{			if (tchar == dollar_quote)			{				if (strncmp(sptr, tag, taglen) == 0)				{					in_dollar_quote = FALSE;					tag = NULL;					sptr += taglen;					sptr--;					encoded_position_shift(&encstr, taglen - 1);				}			}		}		else if (in_literal)		{			if (in_escape)				in_escape = FALSE;			else if (tchar == escape_in_literal)				in_escape = TRUE;			else if (tchar == literal_quote)				in_literal = FALSE;		}		else if (in_identifier)		{			if (tchar == identifier_quote)				in_identifier = FALSE;		}		else		{			if (tchar == '?')			{				if (0 == num_p && bchar == '{')				{					if (proc_return)						*proc_return = 1;				}				num_p++;			}			else if (tchar == ';')			{				del_found = TRUE;				if (next_cmd)					*next_cmd = sptr - query;			}			else if (tchar == dollar_quote)			{				taglen = findTag(sptr, dollar_quote, encstr.ccsc);				if (taglen > 0)				{					in_dollar_quote = TRUE;					tag = sptr;					sptr += (taglen - 1);					encoded_position_shift(&encstr, taglen - 1);				}				else					num_p++;			}			else if (tchar == literal_quote)			{				in_literal = TRUE;				escape_in_literal = CC_get_escape(conn);				if (!escape_in_literal)				{					if (LITERAL_EXT == sptr[-1])						escape_in_literal = ESCAPE_IN_LITERAL;				}			}			else if (tchar == identifier_quote)				in_identifier = TRUE;			if (!isspace(tchar))				bchar = tchar;		}	}	if (pcpar)		*pcpar = num_p;	if (multi_st)		*multi_st = multi;}/* * Pre-execute a statement (for SQLPrepare/SQLDescribeCol)  */Int4	/* returns # of fields if successful */SC_pre_execute(StatementClass *self){	Int4		num_fields = -1;	QResultClass	*res;	mylog("SC_pre_execute: status = %d\n", self->status);	res = SC_get_Curres(self);	if (res && (num_fields = QR_NumResultCols(res)) > 0)		return num_fields;	if (self->status == STMT_READY)	{		mylog("              preprocess: status = READY\n");		self->miscinfo = 0;		if (self->statement_type == STMT_TYPE_SELECT)		{			char		old_pre_executing = self->pre_executing;			decideHowToPrepare(self, FALSE);			self->inaccurate_result = FALSE;			switch (SC_get_prepare_method(self))			{				case NAMED_PARSE_REQUEST:				case PARSE_TO_EXEC_ONCE:					if (SQL_SUCCESS != prepareParameters(self))						return num_fields;					break;				case PARSE_REQ_FOR_INFO:					if (SQL_SUCCESS != prepareParameters(self))						return num_fields;					self->status = STMT_PREMATURE;					self->inaccurate_result = TRUE;					break;				default:					self->pre_executing = TRUE;					PGAPI_Execute(self, 0);					self->pre_executing = old_pre_executing;					if (self->status == STMT_FINISHED)

⌨️ 快捷键说明

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