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

📄 results.c

📁 postgresql-odbc,跨平台应用
💻 C
📖 第 1 页 / 共 5 页
字号:
inolog("ReplaceCachedRows %p num_fields=%d num_rows=%d\n", otuple, num_fields, num_rows);	for (i = 0; i < num_fields * num_rows; i++, ituple++, otuple++)	{		if (otuple->value)		{			free(otuple->value);			otuple->value = NULL;		}		if (ituple->value){			otuple->value = strdup(ituple->value);inolog("[%d,%d] %s copied\n", i / num_fields, i % num_fields, otuple->value);}		otuple->len = ituple->len;	}	return i;}staticint MoveCachedRows(TupleField *otuple, TupleField *ituple, Int2 num_fields, SQLLEN num_rows){	int	i;inolog("MoveCachedRows %p num_fields=%d num_rows=%d\n", otuple, num_fields, num_rows);	for (i = 0; i < num_fields * num_rows; i++, ituple++, otuple++)	{		if (otuple->value)		{			free(otuple->value);			otuple->value = NULL;		}		if (ituple->value)		{			otuple->value = ituple->value;			ituple->value = NULL;inolog("[%d,%d] %s copied\n", i / num_fields, i % num_fields, otuple->value);		}		otuple->len = ituple->len;		ituple->len = -1;	}	return i;}static BOOL	tupleExists(const StatementClass *stmt, const KeySet *keyset){	char	selstr[256];	const TABLE_INFO	*ti = stmt->ti[0];	QResultClass	*res;	RETCODE		ret = FALSE;	if (NAME_IS_VALID(ti->schema_name))		snprintf(selstr, sizeof(selstr), "select 1 from \"%s\".\"%s\" where ctid = '(%d,%d)'",			SAFE_NAME(ti->schema_name), SAFE_NAME(ti->table_name), keyset->blocknum, keyset->offset);	else		snprintf(selstr, sizeof(selstr), "select 1 from \"%s\" where ctid = '(%d,%d)'",			SAFE_NAME(ti->table_name), keyset->blocknum, keyset->offset);	res = CC_send_query(SC_get_conn(stmt), selstr, NULL, 0, NULL);	if (QR_command_maybe_successful(res) && 1 == res->num_cached_rows)		ret = TRUE;	QR_Destructor(res);	return ret;}static BOOL	tupleIsAdding(const StatementClass *stmt, const QResultClass *res, SQLLEN index){	SQLLEN	i;	BOOL	ret = FALSE;	UWORD	status;	if (!res->added_keyset)		return ret;	if (index < res->num_total_read || index >= QR_get_num_total_read(res))		return ret;	i = index - res->num_total_read; 	status = res->added_keyset[i].status;	if (0 == (status & CURS_SELF_ADDING))		return ret;	if (tupleExists(stmt, res->added_keyset + i))		ret = TRUE;	return ret;}static BOOL	tupleIsUpdating(const StatementClass *stmt, const QResultClass *res, SQLLEN index){	int	i;	BOOL	ret = FALSE;	UWORD	status;	if (!res->updated || !res->updated_keyset)		return ret;	for (i = res->up_count - 1; i >= 0; i--)	{		if (index == res->updated[i])		{			status = res->updated_keyset[i].status;			if (0 == (status & CURS_SELF_UPDATING))				continue;			if (tupleExists(stmt, res->updated_keyset + i))			{				ret = TRUE;				break;			}		} 	}	return ret;}static BOOL	tupleIsDeleting(const StatementClass *stmt, const QResultClass *res, SQLLEN index){	int	i;	BOOL	ret = FALSE;	UWORD	status;	if (!res->deleted || !res->deleted_keyset)		return ret;	for (i = 0; i < res->dl_count; i++)	{		if (index == res->deleted[i])		{			status = res->deleted_keyset[i].status;			if (0 == (status & CURS_SELF_DELETING))				;			else if (tupleExists(stmt, res->deleted_keyset + i))				;			else				ret = TRUE;			break;		} 	}	return ret;}static BOOL enlargeAdded(QResultClass *res, UInt4 number, const StatementClass *stmt){	UInt4	alloc;	int	num_fields = res->num_fields;	alloc = res->ad_alloc;	if (0 == alloc)		alloc = number > 10 ? number : 10;	else		while (alloc < number)		{			alloc *= 2;		} 	if (alloc <= res->ad_alloc)		return TRUE;	QR_REALLOC_return_with_error(res->added_keyset, KeySet, sizeof(KeySet) * alloc, res, "enlargeAdded failed", FALSE);	if (SQL_CURSOR_KEYSET_DRIVEN != stmt->options.cursor_type)		QR_REALLOC_return_with_error(res->added_tuples, TupleField, sizeof(TupleField) * num_fields * alloc, res, "enlargeAdded failed 2", FALSE);	res->ad_alloc = alloc;	return TRUE;}static void AddAdded(StatementClass *stmt, QResultClass *res, SQLLEN index, const TupleField *tuple_added){	KeySet	*added_keyset, *keyset, keys;	TupleField	*added_tuples = NULL, *tuple;	UInt4	ad_count;	Int2	num_fields;	if (!res)	return;	num_fields = res->num_fields;inolog("AddAdded index=%d, tuple=%p, num_fields=%d\n", index, tuple_added, num_fields);	ad_count = res->ad_count;	res->ad_count++;	if (QR_get_cursor(res))		index = -(SQLLEN)res->ad_count;	if (!tuple_added)		return;	KeySetSet(tuple_added, num_fields + res->num_key_fields, res->num_key_fields, &keys);	keys.status = SQL_ROW_ADDED;	if (CC_is_in_trans(SC_get_conn(stmt)))		keys.status |= CURS_SELF_ADDING;	else		keys.status |= CURS_SELF_ADDED;	AddRollback(stmt, res, index, &keys, SQL_ADD);	if (!QR_get_cursor(res))		return;	if (ad_count > 0 && 0 == res->ad_alloc)		return;	if (!enlargeAdded(res, ad_count + 1, stmt))		return;	added_keyset = res->added_keyset; 	added_tuples = res->added_tuples;	keyset = added_keyset + ad_count;	*keyset = keys; 	if (added_tuples)	{		tuple = added_tuples + num_fields * ad_count;		memset(tuple, 0, sizeof(TupleField) * num_fields);		ReplaceCachedRows(tuple, tuple_added, num_fields, 1);	}}static	void RemoveAdded(QResultClass *, SQLLEN);static	void RemoveUpdated(QResultClass *, SQLLEN);static	void RemoveUpdatedAfterTheKey(QResultClass *, SQLLEN, const KeySet*);static	void RemoveDeleted(QResultClass *, SQLLEN);static	void RemoveAdded(QResultClass *res, SQLLEN index){	SQLLEN	rmidx, mv_count;	Int2	num_fields = res->num_fields;	KeySet	*added_keyset;	TupleField	*added_tuples;	mylog("RemoveAdded index=%d\n", index);	if (index < 0)		rmidx = -index - 1;	else		rmidx = index - res->num_total_read;	if (rmidx >= res->ad_count)		return;	added_keyset = res->added_keyset + rmidx;	added_tuples = res->added_tuples + num_fields * rmidx;	ClearCachedRows(added_tuples, num_fields, 1);	mv_count = res->ad_count - rmidx - 1;	if (mv_count > 0)	{		memmove(added_keyset, added_keyset + 1, mv_count * sizeof(KeySet));		memmove(added_tuples, added_tuples + num_fields, mv_count * num_fields * sizeof(TupleField));	}	RemoveDeleted(res, index);	RemoveUpdated(res, index);	res->ad_count--;	mylog("RemoveAdded removed=1 count=%d\n", res->ad_count);}static void CommitAdded(QResultClass *res){	KeySet	*added_keyset;	int	i;	UWORD	status;	mylog("CommitAdded res=%p\n", res);	if (!res || !res->added_keyset)	return;	added_keyset = res->added_keyset;	for (i = res->ad_count - 1; i >= 0; i--)	{		status = added_keyset[i].status;		if (0 != (status & CURS_SELF_ADDING))		{			status |= CURS_SELF_ADDED;			status &= ~CURS_SELF_ADDING;		}		if (0 != (status & CURS_SELF_UPDATING))		{			status |= CURS_SELF_UPDATED;			status &= ~CURS_SELF_UPDATING;		}		if (0 != (status & CURS_SELF_DELETING))		{			status |= CURS_SELF_DELETED;			status &= ~CURS_SELF_DELETING;		}		if (status != added_keyset[i].status)		{inolog("!!Commit Added=%d(%d)\n", QR_get_num_total_read(res) + i, i);			added_keyset[i].status = status;		}	}}int AddDeleted(QResultClass *res, SQLULEN index, KeySet *keyset){	int	i;	Int2	dl_count, new_alloc;	SQLULEN	*deleted;	KeySet	*deleted_keyset;	UWORD	status;	Int2	num_fields = res->num_fields;inolog("AddDeleted %d\n", index);	if (!res)	return FALSE;	dl_count = res->dl_count;	res->dl_count++;	if (!QR_get_cursor(res))		return TRUE;	if (!res->deleted)	{		dl_count = 0;		new_alloc = 10;		QR_MALLOC_return_with_error(res->deleted, SQLULEN, sizeof(SQLULEN) * new_alloc, res, "Deleted index malloc error", FALSE);		QR_MALLOC_return_with_error(res->deleted_keyset, KeySet, sizeof(KeySet) * new_alloc, res, "Deleted keyset malloc error", FALSE);		deleted = res->deleted;		deleted_keyset = res->deleted_keyset;		res->dl_alloc = new_alloc;	}	else	{		if (dl_count >= res->dl_alloc)		{			new_alloc = res->dl_alloc * 2;			res->dl_alloc = 0;			QR_REALLOC_return_with_error(res->deleted, SQLULEN, sizeof(SQLULEN) * new_alloc, res, "Dleted index realloc error", FALSE);			deleted = res->deleted;			QR_REALLOC_return_with_error(res->deleted_keyset, KeySet, sizeof(KeySet) * new_alloc, res, "Dleted KeySet realloc error", FALSE);			deleted_keyset = res->deleted_keyset;			res->dl_alloc = new_alloc; 		}		/* sort deleted indexes in ascending order */		for (i = 0, deleted = res->deleted, deleted_keyset = res->deleted_keyset; i < dl_count; i++, deleted++, deleted_keyset += num_fields)		{			if (index < *deleted)				break;		}		memmove(deleted + 1, deleted, sizeof(SQLLEN) * (dl_count - i)); 		memmove(deleted_keyset + 1, deleted_keyset, sizeof(KeySet) * (dl_count - i)); 	}	*deleted = index;	*deleted_keyset = *keyset;	status = keyset->status;	status &= (~KEYSET_INFO_PUBLIC);	status |= SQL_ROW_DELETED;	if (CC_is_in_trans(QR_get_conn(res)))	{		status |= CURS_SELF_DELETING;		QR_get_conn(res)->result_uncommitted = 1;	}	else	{		status &= ~(CURS_SELF_ADDING | CURS_SELF_UPDATING | CURS_SELF_DELETING);		status |= CURS_SELF_DELETED;	}	deleted_keyset->status = status;	res->dl_count = dl_count + 1;	return TRUE;}static void RemoveDeleted(QResultClass *res, SQLLEN index){	int	i, mv_count, rm_count = 0;	SQLLEN	pidx, midx;	SQLULEN	*deleted, num_read = QR_get_num_total_read(res);	KeySet	*deleted_keyset;	mylog("RemoveDeleted index=%d\n", index);	if (index < 0)	{		midx = index;		pidx = num_read - index - 1;	}	else	{		pidx = index;		if (index >= num_read)			midx = num_read - index - 1;		else			midx = index;	}	for (i = 0; i < res->dl_count; i++)	{		if (pidx == res->deleted[i] ||		    midx == res->deleted[i])		{			mv_count = res->dl_count - i - 1;			if (mv_count > 0)			{				deleted = res->deleted + i;				deleted_keyset = res->deleted_keyset + i;				memmove(deleted, deleted + 1, mv_count * sizeof(SQLULEN));				memmove(deleted_keyset, deleted_keyset + 1, mv_count * sizeof(KeySet));			}			res->dl_count--;			rm_count++;				}	}	mylog("RemoveDeleted removed count=%d,%d\n", rm_count, res->dl_count);}static void CommitDeleted(QResultClass *res){	int	i;	SQLULEN	*deleted;	KeySet	*deleted_keyset;	UWORD	status;	if (!res->deleted)		return;	for (i = 0, deleted = res->deleted, deleted_keyset = res->deleted_keyset; i < res->dl_count; i++, deleted++, deleted_keyset++)	{		status = deleted_keyset->status;		if (0 != (status & CURS_SELF_ADDING))		{			status |= CURS_SELF_ADDED;			status &= ~CURS_SELF_ADDING;		}		if (0 != (status & CURS_SELF_UPDATING))		{			status |= CURS_SELF_UPDATED;			status &= ~CURS_SELF_UPDATING;		}		if (0 != (status & CURS_SELF_DELETING))		{			status |= CURS_SELF_DELETED;			status &= ~CURS_SELF_DELETING;		}		if (status != deleted_keyset->status)		{inolog("!!Commit Deleted=%d(%d)\n", *deleted, i);			deleted_keyset->status = status;		}	} }static BOOL enlargeUpdated(QResultClass *res, Int4 number, const StatementClass *stmt){	Int2	alloc;	alloc = res->up_alloc;	if (0 == alloc)		alloc = number > 10 ? number : 10;	else		while (alloc < number)		{			alloc *= 2;		}	if (alloc <= res->up_alloc)		return TRUE; 	QR_REALLOC_return_with_error(res->updated, UInt4, sizeof(UInt4) * alloc, res, "enlargeUpdated failed", FALSE);	QR_REALLOC_return_with_error(res->updated_keyset, KeySet, sizeof(KeySet) * alloc, res, "enlargeUpdated failed 2", FALSE);	if (SQL_CURSOR_KEYSET_DRIVEN != stmt->options.cursor_type)		QR_REALLOC_return_with_error(res->updated_tuples, TupleField, sizeof(TupleField) * res->num_fields * alloc, res, "enlargeUpdated 3", FALSE);	res->up_alloc = alloc;	return TRUE;}static void AddUpdated(StatementClass *stmt, SQLLEN index){	QResultClass	*res;	SQLULEN	*updated;	KeySet	*updated_keyset, *keyset;	TupleField	*updated_tuples = NULL, *tuple_updated,  *tuple;	SQLULEN	kres_ridx;	UInt2	up_count;	BOOL	is_in_trans;	SQLLEN	upd_idx, upd_add_idx;	Int2	num_fields;	int	i;	UWORD	status;inolog("AddUpdated index=%d\n", index);	if (!stmt)	return;	if (res = SC_get_Curres(stmt), !res)	return;	if (!res->keyset)		return;	kres_ridx = GIdx2KResIdx(index, stmt, res);	if (kres_ridx < 0 || kres_ridx >= res->num_cached_keys)		return;	keyset = res->keyset + kres_ridx;	if (0 != (keyset->status & CURS_SELF_ADDING))		AddRollback(stmt, res, index, res->keyset + kres_ridx, SQL_REFRESH);	if (!QR_get_cursor(res))	return;	up_count = res->up_count;	if (up_count > 0 && 0 == res->up_alloc)	return;	num_fields = res->num_fields;	tuple_updated = res->backend_tuples + kres_ridx * num_fields;	if (!tuple_updated)		return;	upd_idx = -1;	upd_add_idx = -1;	updated = res->updated;	is_in_trans = CC_is_in_trans(SC_get_conn(stmt));	updated_keyset = res->updated_keyset;		status = keyset->status;	status &= (~KEYSET_INFO_PUBLIC);	status |= SQL_ROW_UPDATED;	if (is_in_trans)		status |= CURS_SELF_UPDATING;	else	{		for (i = up_count - 1; i >= 0; i--)		{			if (updated[i] == index)				break;		}		if (i >= 0)			upd_idx = i;		else		{			SQLLEN	num_totals = QR_get_num_total_tuples(res);			if (index >= num_totals)				upd_add_idx = num_totals - index;		}		status |= CURS_SELF_UPDATED;		status &= ~(CURS_SELF_ADDING | CURS_SELF_UPDATING | CURS_SELF_DELETING);	}	tuple = NULL;	/* update the corresponding add(updat)ed info */	if (upd_add_idx >= 0)	{		res->added_keyset[upd_add_idx].status = status;		if (res->added_tuples)		{			tuple

⌨️ 快捷键说明

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