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

📄 statement.c

📁 postgresql-odbc,跨平台应用
💻 C
📖 第 1 页 / 共 5 页
字号:
					{						mylog("              preprocess: after status = FINISHED, so set PREMATURE\n");						self->status = STMT_PREMATURE;					}			}			if (res = SC_get_Curres(self), NULL != res)			{				num_fields = QR_NumResultCols(res);				return num_fields;			}		}		if (!SC_is_pre_executable(self))		{			SC_set_Result(self, QR_Constructor());			QR_set_rstatus(SC_get_Result(self), PORES_TUPLES_OK);			self->inaccurate_result = TRUE;			self->status = STMT_PREMATURE;			num_fields = 0;		}	}	return num_fields;}/* This is only called from SQLFreeStmt(SQL_UNBIND) */charSC_unbind_cols(StatementClass *self){	ARDFields	*opts = SC_get_ARDF(self);	GetDataInfo	*gdata = SC_get_GDTI(self);	BindInfoClass	*bookmark;	ARD_unbind_cols(opts, FALSE);	GDATA_unbind_cols(gdata, FALSE);	if (bookmark = opts->bookmark, bookmark != NULL)	{		bookmark->buffer = NULL;		bookmark->used = NULL;	}	return 1;}voidSC_clear_error(StatementClass *self){	QResultClass	*res;	self->__error_number = 0;	if (self->__error_message)	{		free(self->__error_message);		self->__error_message = NULL;	}	if (self->pgerror)	{		ER_Destructor(self->pgerror);		self->pgerror = NULL;	}	self->diag_row_count = 0;	if (res = SC_get_Curres(self), res)	{		QR_set_message(res, NULL);		QR_set_notice(res, NULL);		res->sqlstate[0] = '\0';	}	self->stmt_time = 0;	SC_unref_CC_error(self);}/* *	This function creates an error info which is the concatenation *	of the result, statement, connection, and socket messages. *//*	Map sql commands to statement types */static struct{	int	number;	const	char	* ver3str;	const	char	* ver2str;}	Statement_sqlstate[] ={	{ STMT_ERROR_IN_ROW, "01S01", "01S01" },	{ STMT_OPTION_VALUE_CHANGED, "01S02", "01S02" },	{ STMT_ROW_VERSION_CHANGED,  "01001", "01001" }, /* data changed */	{ STMT_POS_BEFORE_RECORDSET, "01S06", "01S06" },	{ STMT_TRUNCATED, "01004", "01004" }, /* data truncated */	{ STMT_INFO_ONLY, "00000", "00000" }, /* just an information that is returned, no error */	{ STMT_OK,  "00000", "00000" }, /* OK */	{ STMT_EXEC_ERROR, "HY000", "S1000" }, /* also a general error */	{ STMT_STATUS_ERROR, "HY010", "S1010" },	{ STMT_SEQUENCE_ERROR, "HY010", "S1010" }, /* Function sequence error */	{ STMT_NO_MEMORY_ERROR, "HY001", "S1001" }, /* memory allocation failure */	{ STMT_COLNUM_ERROR, "07009", "S1002" }, /* invalid column number */	{ STMT_NO_STMTSTRING, "HY001", "S1001" }, /* having no stmtstring is also a malloc problem */	{ STMT_ERROR_TAKEN_FROM_BACKEND, "HY000", "S1000" }, /* general error */	{ STMT_INTERNAL_ERROR, "HY000", "S1000" }, /* general error */	{ STMT_STILL_EXECUTING, "HY010", "S1010" },	{ STMT_NOT_IMPLEMENTED_ERROR, "HYC00", "S1C00" }, /* == 'driver not 							  * capable' */	{ STMT_BAD_PARAMETER_NUMBER_ERROR, "07009", "S1093" },	{ STMT_OPTION_OUT_OF_RANGE_ERROR, "HY092", "S1092" },	{ STMT_INVALID_COLUMN_NUMBER_ERROR, "07009", "S1002" },	{ STMT_RESTRICTED_DATA_TYPE_ERROR, "07006", "07006" },	{ STMT_INVALID_CURSOR_STATE_ERROR, "07005", "24000" },	{ STMT_CREATE_TABLE_ERROR, "42S01", "S0001" }, /* table already exists */	{ STMT_NO_CURSOR_NAME, "S1015", "S1015" },	{ STMT_INVALID_CURSOR_NAME, "34000", "34000" },	{ STMT_INVALID_ARGUMENT_NO, "HY024", "S1009" }, /* invalid argument value */	{ STMT_ROW_OUT_OF_RANGE, "HY107", "S1107" },	{ STMT_OPERATION_CANCELLED, "HY008", "S1008" },	{ STMT_INVALID_CURSOR_POSITION, "HY109", "S1109" },	{ STMT_VALUE_OUT_OF_RANGE, "HY019", "22003" },	{ STMT_OPERATION_INVALID, "HY011", "S1011" },	{ STMT_PROGRAM_TYPE_OUT_OF_RANGE, "?????", "?????" }, 	{ STMT_BAD_ERROR, "08S01", "08S01" }, /* communication link failure */	{ STMT_INVALID_OPTION_IDENTIFIER, "HY092", "HY092" },	{ STMT_RETURN_NULL_WITHOUT_INDICATOR, "22002", "22002" },	{ STMT_INVALID_DESCRIPTOR_IDENTIFIER, "HY091", "HY091" },	{ STMT_OPTION_NOT_FOR_THE_DRIVER, "HYC00", "HYC00" },	{ STMT_FETCH_OUT_OF_RANGE, "HY106", "S1106" },	{ STMT_COUNT_FIELD_INCORRECT, "07002", "07002" },	{ STMT_INVALID_NULL_ARG, "HY009", "S1009" }};static PG_ErrorInfo *SC_create_errorinfo(const StatementClass *self){	QResultClass *res = SC_get_Curres(self);	ConnectionClass *conn = SC_get_conn(self);	Int4	errornum;	size_t		pos;	BOOL		resmsg = FALSE, detailmsg = FALSE, msgend = FALSE;	char		msg[4096], *wmsg;	char		*ermsg = NULL, *sqlstate = NULL;	PG_ErrorInfo	*pgerror;	if (self->pgerror)		return self->pgerror;	errornum = self->__error_number;	if (errornum == 0)		return	NULL;	msg[0] = '\0';	if (res)	{		if (res->sqlstate[0])			sqlstate = res->sqlstate;		if (res->message)		{			strncpy(msg, res->message, sizeof(msg));			detailmsg = resmsg = TRUE;		}		if (msg[0])			ermsg = msg;		else if (QR_get_notice(res))		{			char *notice = QR_get_notice(res);			size_t	len = strlen(notice);			if (len < sizeof(msg))			{				memcpy(msg, notice, len);				msg[len] = '\0';				ermsg = msg;			}			else			{				ermsg = notice;				msgend = TRUE;			}		}	}	if (!msgend && (wmsg = SC_get_errormsg(self)) && wmsg[0])	{		pos = strlen(msg);		if (detailmsg)		{			msg[pos++] = ';';			msg[pos++] = '\n';		}		strncpy(msg + pos, wmsg, sizeof(msg) - pos);		ermsg = msg;		detailmsg = TRUE;	}	if (!self->ref_CC_error)		msgend = TRUE;	if (conn && !msgend)	{		SocketClass *sock = conn->sock;		const char *sockerrmsg;		if (!resmsg && (wmsg = CC_get_errormsg(conn)) && wmsg[0] != '\0')		{			pos = strlen(msg);			snprintf(&msg[pos], sizeof(msg) - pos, ";\n%s", CC_get_errormsg(conn));		}		if (sock && NULL != (sockerrmsg = SOCK_get_errmsg(sock)) && '\0' != sockerrmsg[0])		{			pos = strlen(msg);			snprintf(&msg[pos], sizeof(msg) - pos, ";\n%s", sockerrmsg);		}		ermsg = msg;	}	pgerror = ER_Constructor(self->__error_number, ermsg);	if (sqlstate)		strcpy(pgerror->sqlstate, sqlstate);	else if (conn)	{		if (!msgend && conn->sqlstate[0])			strcpy(pgerror->sqlstate, conn->sqlstate);		else		{        		EnvironmentClass *env = (EnvironmentClass *) conn->henv;			errornum -= LOWEST_STMT_ERROR;        		if (errornum < 0 ||				errornum >= sizeof(Statement_sqlstate) / sizeof(Statement_sqlstate[0]))				errornum = 1 - LOWEST_STMT_ERROR;        		strcpy(pgerror->sqlstate, EN_is_odbc3(env) ?				Statement_sqlstate[errornum].ver3str : 				Statement_sqlstate[errornum].ver2str);		}	} 	return pgerror;}StatementClass *SC_get_ancestor(StatementClass *stmt){	StatementClass	*child = stmt, *parent;inolog("SC_get_ancestor in stmt=%p\n", stmt);	for (child = stmt, parent = child->execute_parent; parent; child = parent, parent = child->execute_parent)	{		inolog("parent=%p\n", parent);	}	return child;}void SC_reset_delegate(RETCODE retcode, StatementClass *stmt){	StatementClass	*delegate = stmt->execute_delegate;	if (!delegate)		return;	PGAPI_FreeStmt(delegate, SQL_DROP);}voidSC_set_error(StatementClass *self, int number, const char *message, const char *func){	if (self->__error_message)		free(self->__error_message);	self->__error_number = number;	self->__error_message = message ? strdup(message) : NULL;	if (func && number != STMT_OK && number != STMT_INFO_ONLY)		SC_log_error(func, "", self);}voidSC_set_errormsg(StatementClass *self, const char *message){	if (self->__error_message)		free(self->__error_message);	self->__error_message = message ? strdup(message) : NULL;}voidSC_replace_error_with_res(StatementClass *self, int number, const char *message, const QResultClass *from_res, BOOL check){	QResultClass	*self_res;	BOOL	repstate;inolog("SC_set_error_from_res %p->%p check=%i\n", from_res ,self, check);	if (check)	{		if (0 == number)			return;		if (0 > number &&		/* SQL_SUCCESS_WITH_INFO */		    0 < self->__error_number)			return;	}	self->__error_number = number;	if (!check || message)	{		if (self->__error_message)			free(self->__error_message);		self->__error_message = message ? strdup(message) : NULL;	}	if (self->pgerror)	{		ER_Destructor(self->pgerror);		self->pgerror = NULL;	}	self_res = SC_get_Curres(self);	if (!self_res) return;	if (self_res == from_res)	return;	QR_add_message(self_res, QR_get_message(from_res));	QR_add_notice(self_res, QR_get_notice(from_res));	repstate = FALSE;	if (!check)		repstate = TRUE;	else if (from_res->sqlstate[0])	{		if (!self_res->sqlstate[0] || strncmp(self_res->sqlstate, "00", 2) == 0)			repstate = TRUE;		else if (strncmp(from_res->sqlstate, "01", 2) >= 0)			repstate = TRUE;	}	if (repstate)		strcpy(self_res->sqlstate, from_res->sqlstate);}voidSC_error_copy(StatementClass *self, const StatementClass *from, BOOL check){	QResultClass	*self_res, *from_res;	BOOL	repstate;inolog("SC_error_copy %p->%p check=%i\n", from ,self, check);	if (self == from)	return;	if (check)	{		if (0 == from->__error_number)	/* SQL_SUCCESS */			return;		if (0 > from->__error_number &&	/* SQL_SUCCESS_WITH_INFO */		    0 < self->__error_number)			return;	}	self->__error_number = from->__error_number;	if (!check || from->__error_message)	{		if (self->__error_message)			free(self->__error_message);		self->__error_message = from->__error_message ? strdup(from->__error_message) : NULL;	}	if (self->pgerror)	{		ER_Destructor(self->pgerror);		self->pgerror = NULL;	}	self_res = SC_get_Curres(self);	from_res = SC_get_Curres(from);	if (!self_res || !from_res)		return;	QR_add_message(self_res, QR_get_message(from_res));	QR_add_notice(self_res, QR_get_notice(from_res));	repstate = FALSE;	if (!check)		repstate = TRUE;	else if (from_res->sqlstate[0])	{		if (!self_res->sqlstate[0] || strncmp(self_res->sqlstate, "00", 2) == 0)			repstate = TRUE;		else if (strncmp(from_res->sqlstate, "01", 2) >= 0)			repstate = TRUE;	}	if (repstate)		strcpy(self_res->sqlstate, from_res->sqlstate);}voidSC_full_error_copy(StatementClass *self, const StatementClass *from, BOOL allres){	PG_ErrorInfo		*pgerror;inolog("SC_full_error_copy %p->%p\n", from ,self);	if (self->__error_message)	{		free(self->__error_message);		self->__error_message = NULL;	}	if (from->__error_message)		self->__error_message = strdup(from->__error_message);	self->__error_number = from->__error_number;	if (from->pgerror)	{		if (self->pgerror)			ER_Destructor(self->pgerror);		self->pgerror = ER_Dup(from->pgerror);		return;	}	else if (!allres)		return;	pgerror = SC_create_errorinfo(from);	if (!pgerror->__error_message[0])	{		ER_Destructor(pgerror);		return;	} 	if (self->pgerror)		ER_Destructor(self->pgerror);	self->pgerror = pgerror;}/*              Returns the next SQL error information. */RETCODE         SQL_APIPGAPI_StmtError(	SQLHSTMT	hstmt,		SQLSMALLINT RecNumber,		SQLCHAR FAR * szSqlState,		SQLINTEGER FAR * pfNativeError,		SQLCHAR FAR * szErrorMsg,		SQLSMALLINT cbErrorMsgMax,		SQLSMALLINT FAR * pcbErrorMsg,		UWORD flag){	/* CC: return an error of a hdesc  */	StatementClass *stmt = (StatementClass *) hstmt;	stmt->pgerror = SC_create_errorinfo(stmt);	return ER_ReturnError(&(stmt->pgerror), RecNumber, szSqlState,		pfNativeError, szErrorMsg, cbErrorMsgMax,		pcbErrorMsg, flag);}time_tSC_get_time(StatementClass *stmt){	if (!stmt)		return time(NULL);	if (0 == stmt->stmt_time)		stmt->stmt_time = time(NULL);	return stmt->stmt_time;}/* *	Currently, the driver offers very simple bookmark support -- it is *	just the current row number.  But it could be more sophisticated *	someday, such as mapping a key to a 32 bit value */SQLULENSC_get_bookmark(StatementClass *self){	return SC_make_bookmark(self->currTuple);}RETCODESC_fetch(StatementClass *self){	CSTR func = "SC_fetch";	QResultClass *res = SC_get_Curres(self);	ARDFields	*opts;	GetDataInfo	*gdata;	int		retval;	RETCODE		result;	Int2		num_cols,				lf;	OID			type;	char	   *value;	ColumnInfoClass *coli;	BindInfoClass	*bookmark;	/* TupleField *tupleField; */inolog("%s statement=%p ommitted=0\n", func, self);	self->last_fetch_count = self->last_fetch_count_include_ommitted = 0;	coli = QR_get_fields(res);	/* the column info */	mylog("fetch_cursor=%d, %p->total_read=%d\n", SC_is_fetchcursor(self), res, res->num_total_read);	if (!SC_is_fetchcursor(self))	{		if (self->currTuple >= (Int4) QR_get_num_total_tuples(res) - 1 ||			(self->options.maxRows > 0 && self->currTuple == self->options.maxRows - 1))		{			/*			 * if at the end of the tuples, return "no data found" and set			 * the cursor past the end of the result set			 */			self->currTuple = QR_get_num_total_tuples(res);			return SQL_NO_DATA_FOUND;		}		mylog("**** %s: non-cursor_result\n", func);		(self->currTuple)++;	}	else	{		/* read from the cache or the physical next tuple */		retval = QR_next_tuple(res, self);		if (retval < 0)		{			mylog("**** %s: end_tuples\n", func);			if (QR_get_cursor(res) &&			    SQL_CURSOR_FORWARD_ONLY == self->options.cursor_type &&			    QR_once_reached_eof(res))				QR_close(res);			return SQL_NO_DATA_FOUND;		}		else if (retval > 0)			(self->currTuple)++;	/* all is well */		else		{			ConnectionClass *conn = SC_get_conn(self);

⌨️ 快捷键说明

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