您当前的位置:首页 > IT编程 > C++
| C语言 | Java | VB | VC | python | Android | TensorFlow | C++ | oracle | 学术与代码 | cnn卷积神经网络 | gnn | 图像修复 | Keras | 数据集 | Neo4j | 自然语言处理 | 深度学习 | 医学CAD | 医学影像 | 超参数 | pointnet | pytorch | 异常检测 | Transformers | 情感分类 | 知识图谱 |

自学教程:C++ HeapTupleHeaderGetXmin函数代码示例

51自学网 2021-06-01 21:25:59
  C++
这篇教程C++ HeapTupleHeaderGetXmin函数代码示例写得很实用,希望能帮到您。

本文整理汇总了C++中HeapTupleHeaderGetXmin函数的典型用法代码示例。如果您正苦于以下问题:C++ HeapTupleHeaderGetXmin函数的具体用法?C++ HeapTupleHeaderGetXmin怎么用?C++ HeapTupleHeaderGetXmin使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。

在下文中一共展示了HeapTupleHeaderGetXmin函数的30个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。

示例1: PLy_procedure_valid

/* * Decide whether a cached PLyProcedure struct is still valid */static boolPLy_procedure_valid(PLyProcedure *proc, HeapTuple procTup){	int			i;	bool		valid;	Assert(proc != NULL);	/* If the pg_proc tuple has changed, it's not valid */	if (!(proc->fn_xmin == HeapTupleHeaderGetXmin(procTup->t_data) &&		  ItemPointerEquals(&proc->fn_tid, &procTup->t_self)))		return false;	/* Else check the input argument datatypes */	valid = true;	for (i = 0; i < proc->nargs; i++)	{		valid = PLy_procedure_argument_valid(&proc->args[i]);		/* Short-circuit on first changed argument */		if (!valid)			break;	}	/* if the output type is composite, it might have changed */	if (valid)		valid = PLy_procedure_argument_valid(&proc->result);	return valid;}
开发者ID:AllenDou,项目名称:postgresql,代码行数:33,


示例2: PLy_procedure_argument_valid

/* * Check if our cached information about a datatype is still valid */static boolPLy_procedure_argument_valid(PLyTypeInfo *arg){	HeapTuple	relTup;	bool		valid;	/* Nothing to cache unless type is composite */	if (arg->is_rowtype != 1)		return true;	/*	 * Zero typ_relid means that we got called on an output argument of a	 * function returning a unnamed record type; the info for it can't change.	 */	if (!OidIsValid(arg->typ_relid))		return true;	/* Else we should have some cached data */	Assert(TransactionIdIsValid(arg->typrel_xmin));	Assert(ItemPointerIsValid(&arg->typrel_tid));	/* Get the pg_class tuple for the data type */	relTup = SearchSysCache1(RELOID, ObjectIdGetDatum(arg->typ_relid));	if (!HeapTupleIsValid(relTup))		elog(ERROR, "cache lookup failed for relation %u", arg->typ_relid);	/* If it has changed, the cached data is not valid */	valid = (arg->typrel_xmin == HeapTupleHeaderGetXmin(relTup->t_data) &&			 ItemPointerEquals(&arg->typrel_tid, &relTup->t_self));	ReleaseSysCache(relTup);	return valid;}
开发者ID:AllenDou,项目名称:postgresql,代码行数:37,


示例3: XLogIsValidTuple

/* * MUST BE CALLED ONLY ON RECOVERY. * * Check if exists valid (inserted by not aborted xaction) heap tuple * for given item pointer */boolXLogIsValidTuple(RelFileNode hnode, ItemPointer iptr){	Relation	reln;	Buffer		buffer;	Page		page;	ItemId		lp;	HeapTupleHeader htup;	reln = XLogOpenRelation(false, RM_HEAP_ID, hnode);	if (!RelationIsValid(reln))		return (false);	buffer = ReadBuffer(reln, ItemPointerGetBlockNumber(iptr));	if (!BufferIsValid(buffer))		return (false);	LockBuffer(buffer, BUFFER_LOCK_SHARE);	page = (Page) BufferGetPage(buffer);	if (PageIsNew((PageHeader) page) ||		ItemPointerGetOffsetNumber(iptr) > PageGetMaxOffsetNumber(page))	{		UnlockAndReleaseBuffer(buffer);		return (false);	}	if (PageGetSUI(page) != ThisStartUpID)	{		Assert(PageGetSUI(page) < ThisStartUpID);		UnlockAndReleaseBuffer(buffer);		return (true);	}	lp = PageGetItemId(page, ItemPointerGetOffsetNumber(iptr));	if (!ItemIdIsUsed(lp) || ItemIdDeleted(lp))	{		UnlockAndReleaseBuffer(buffer);		return (false);	}	htup = (HeapTupleHeader) PageGetItem(page, lp);	/* MUST CHECK WASN'T TUPLE INSERTED IN PREV STARTUP */	if (!(htup->t_infomask & HEAP_XMIN_COMMITTED))	{		if (htup->t_infomask & HEAP_XMIN_INVALID ||			(htup->t_infomask & HEAP_MOVED_IN &&			 TransactionIdDidAbort(HeapTupleHeaderGetXvac(htup))) ||			TransactionIdDidAbort(HeapTupleHeaderGetXmin(htup)))		{			UnlockAndReleaseBuffer(buffer);			return (false);		}	}	UnlockAndReleaseBuffer(buffer);	return (true);}
开发者ID:sunyangkobe,项目名称:cscd43,代码行数:65,


示例4: CrossCheckTuple

/* * This function performs checks for certain system tables to validate tuple * fetched from table has the key, using which it was fetched from index. */static voidCrossCheckTuple(int cacheId,		Datum key1,		Datum key2,		Datum key3,		Datum key4,		HeapTuple tuple){	Form_pg_class rd_rel;	switch (cacheId)	{		case RELOID:			if (HeapTupleGetOid(tuple) != DatumGetObjectId(key1))			{				elog(ERROR, "pg_class_oid_index is broken, oid=%d is pointing to tuple with oid=%d (xmin:%u xmax:%u)",					DatumGetObjectId(key1), HeapTupleGetOid(tuple),					HeapTupleHeaderGetXmin((tuple)->t_data),					HeapTupleHeaderGetXmax((tuple)->t_data));			}			break;		case RELNAMENSP:			rd_rel = (Form_pg_class) GETSTRUCT(tuple);			if (strncmp(rd_rel->relname.data, DatumGetCString(key1), NAMEDATALEN) != 0)			{				elog(ERROR, "pg_class_relname_nsp_index is broken, intended tuple with name /"%s/" fetched /"%s/""					" (xmin:%u xmax:%u)",					DatumGetCString(key1), rd_rel->relname.data,					HeapTupleHeaderGetXmin((tuple)->t_data),					HeapTupleHeaderGetXmax((tuple)->t_data));			}			break;		case TYPEOID:			if (HeapTupleGetOid(tuple) != DatumGetObjectId(key1))			{				elog(ERROR, "pg_type_oid_index is broken, oid=%d is pointing to tuple with oid=%d (xmin:%u xmax:%u)",					DatumGetObjectId(key1), HeapTupleGetOid(tuple),					HeapTupleHeaderGetXmin((tuple)->t_data),					HeapTupleHeaderGetXmax((tuple)->t_data));			}			break;	}}
开发者ID:PengJi,项目名称:gpdb-comments,代码行数:47,


示例5: heap_getsysattr

/* ---------------- *		heap_getsysattr * *		Fetch the value of a system attribute for a tuple. * * This is a support routine for the heap_getattr macro.  The macro * has already determined that the attnum refers to a system attribute. * ---------------- */Datumheap_getsysattr(HeapTuple tup, int attnum, bool *isnull){	Datum		result;	Assert(tup);	Assert(!is_heaptuple_memtuple(tup));	/* Currently, no sys attribute ever reads as NULL. */	if (isnull)		*isnull = false;	switch (attnum)	{		case SelfItemPointerAttributeNumber:			/* pass-by-reference datatype */			result = PointerGetDatum(&(tup->t_self));			break;		case ObjectIdAttributeNumber:			result = ObjectIdGetDatum(HeapTupleGetOid(tup));			break;		case MinTransactionIdAttributeNumber:			result = TransactionIdGetDatum(HeapTupleHeaderGetXmin(tup->t_data));			break;		case MaxTransactionIdAttributeNumber:			result = TransactionIdGetDatum(HeapTupleHeaderGetXmax(tup->t_data));			break;		case MinCommandIdAttributeNumber:		case MaxCommandIdAttributeNumber:			/*			 * cmin and cmax are now both aliases for the same field, which			 * can in fact also be a combo command id.	XXX perhaps we should			 * return the "real" cmin or cmax if possible, that is if we are			 * inside the originating transaction?			 */			result = CommandIdGetDatum(HeapTupleHeaderGetRawCommandId(tup->t_data));			break;		case TableOidAttributeNumber:            /* CDB: Must now use a TupleTableSlot to access the 'tableoid'. */			result = ObjectIdGetDatum(InvalidOid);			elog(ERROR, "Invalid reference to /"tableoid/" system attribute");			break;		case GpSegmentIdAttributeNumber:                       /*CDB*/			result = Int32GetDatum(Gp_segment);			break;		default:			elog(ERROR, "invalid attnum: %d", attnum);			result = 0;			/* keep compiler quiet */			break;	}	return result;}
开发者ID:chrishajas,项目名称:gpdb,代码行数:62,


示例6: HeapTupleHeaderGetCmin

CommandIdHeapTupleHeaderGetCmin(HeapTupleHeader tup){	CommandId	cid = HeapTupleHeaderGetRawCommandId(tup);	Assert(!(tup->t_infomask & HEAP_MOVED));	if (tup->t_infomask & HEAP_COMBOCID)		return GetRealCmin(HeapTupleHeaderGetXmin(tup), cid);	else		return cid;}
开发者ID:phan-pivotal,项目名称:gpdb,代码行数:12,


示例7: HeapTupleHeaderAdjustCmax

/* * Given a tuple we are about to delete, determine the correct value to store * into its t_cid field. * * If we don't need a combo CID, *cmax is unchanged and *iscombo is set to * FALSE.  If we do need one, *cmax is replaced by a combo CID and *iscombo * is set to TRUE. * * The reason this is separate from the actual HeapTupleHeaderSetCmax() * operation is that this could fail due to out-of-memory conditions.  Hence * we need to do this before entering the critical section that actually * changes the tuple in shared buffers. */voidHeapTupleHeaderAdjustCmax(HeapTupleHeader tup,						  CommandId *cmax,						  bool *iscombo){	/*	 * If we're marking a tuple deleted that was inserted by (any	 * subtransaction of) our transaction, we need to use a combo command id.	 * Test for HEAP_XMIN_COMMITTED first, because it's cheaper than a	 * TransactionIdIsCurrentTransactionId call.	 */	if (!(tup->t_infomask & HEAP_XMIN_COMMITTED) &&		TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmin(tup)))	{		CommandId	cmin = HeapTupleHeaderGetRawCommandId(tup);		*cmax = GetComboCommandId(HeapTupleHeaderGetXmin(tup), cmin, *cmax);		*iscombo = true;	}	else	{		*iscombo = false;	}}
开发者ID:phan-pivotal,项目名称:gpdb,代码行数:37,


示例8: XLogIsOwnerOfTuple

/* * Check if specified heap tuple was inserted by given * xaction/command and return * * - -1 if not * - 0	if there is no tuple at all * - 1	if yes */intXLogIsOwnerOfTuple(RelFileNode hnode, ItemPointer iptr,				   TransactionId xid, CommandId cid){	Relation	reln;	Buffer		buffer;	Page		page;	ItemId		lp;	HeapTupleHeader htup;	reln = XLogOpenRelation(false, RM_HEAP_ID, hnode);	if (!RelationIsValid(reln))		return (0);	buffer = ReadBuffer(reln, ItemPointerGetBlockNumber(iptr));	if (!BufferIsValid(buffer))		return (0);	LockBuffer(buffer, BUFFER_LOCK_SHARE);	page = (Page) BufferGetPage(buffer);	if (PageIsNew((PageHeader) page) ||		ItemPointerGetOffsetNumber(iptr) > PageGetMaxOffsetNumber(page))	{		UnlockAndReleaseBuffer(buffer);		return (0);	}	lp = PageGetItemId(page, ItemPointerGetOffsetNumber(iptr));	if (!ItemIdIsUsed(lp) || ItemIdDeleted(lp))	{		UnlockAndReleaseBuffer(buffer);		return (0);	}	htup = (HeapTupleHeader) PageGetItem(page, lp);	Assert(PageGetSUI(page) == ThisStartUpID);	if (!TransactionIdEquals(HeapTupleHeaderGetXmin(htup), xid) ||		HeapTupleHeaderGetCmin(htup) != cid)	{		UnlockAndReleaseBuffer(buffer);		return (-1);	}	UnlockAndReleaseBuffer(buffer);	return (1);}
开发者ID:sunyangkobe,项目名称:cscd43,代码行数:54,


示例9: HeapTupleHeaderGetCmax

CommandIdHeapTupleHeaderGetCmax(HeapTupleHeader tup){	CommandId	cid = HeapTupleHeaderGetRawCommandId(tup);	/* We do not store cmax when locking a tuple */	Assert(!(tup->t_infomask & (HEAP_MOVED | HEAP_IS_LOCKED)));	/*	 * MPP-8317: cursors can't always *tell* that this is the current transaction.	 */	Assert(QEDtxContextInfo.cursorContext || TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(tup)));	if (tup->t_infomask & HEAP_COMBOCID)		return GetRealCmax(HeapTupleHeaderGetXmin(tup), cid);	else		return cid;}
开发者ID:phan-pivotal,项目名称:gpdb,代码行数:18,


示例10: rewrite_heap_dead_tuple

/* * Register a dead tuple with an ongoing rewrite. Dead tuples are not * copied to the new table, but we still make note of them so that we * can release some resources earlier. * * Returns true if a tuple was removed from the unresolved_tups table. * This indicates that that tuple, previously thought to be "recently dead", * is now known really dead and won't be written to the output. */boolrewrite_heap_dead_tuple(RewriteState state, HeapTuple old_tuple){	/*	 * If we have already seen an earlier tuple in the update chain that	 * points to this tuple, let's forget about that earlier tuple. It's in	 * fact dead as well, our simple xmax < OldestXmin test in	 * HeapTupleSatisfiesVacuum just wasn't enough to detect it. It happens	 * when xmin of a tuple is greater than xmax, which sounds	 * counter-intuitive but is perfectly valid.	 *	 * We don't bother to try to detect the situation the other way round,	 * when we encounter the dead tuple first and then the recently dead one	 * that points to it. If that happens, we'll have some unmatched entries	 * in the UnresolvedTups hash table at the end. That can happen anyway,	 * because a vacuum might have removed the dead tuple in the chain before	 * us.	 */	UnresolvedTup unresolved;	TidHashKey	hashkey;	bool		found;	memset(&hashkey, 0, sizeof(hashkey));	hashkey.xmin = HeapTupleHeaderGetXmin(old_tuple->t_data);	hashkey.tid = old_tuple->t_self;	unresolved = hash_search(state->rs_unresolved_tups, &hashkey,							 HASH_FIND, NULL);	if (unresolved != NULL)	{		/* Need to free the contained tuple as well as the hashtable entry */		heap_freetuple(unresolved->tuple);		hash_search(state->rs_unresolved_tups, &hashkey,					HASH_REMOVE, &found);		Assert(found);		return true;	}	return false;}
开发者ID:AlexHill,项目名称:postgres,代码行数:50,


示例11: PyPgFunction_IsCurrent

/* * PyPgFunction_IsCurrent - determine if the current pg_proc entry is newer than 'func' */boolPyPgFunction_IsCurrent(PyObj func){	HeapTuple ht;	ItemPointerData fn_tid;	TransactionId fn_xmin, last_fn_xmin;	last_fn_xmin = PyPgFunction_GetXMin(func);	if (last_fn_xmin == InvalidTransactionId)	{		/* pseudo-function */		return(true);	}	ht = SearchSysCache(PROCOID, PyPgFunction_GetOid(func), 0, 0, 0);	if (!HeapTupleIsValid(ht))		return(false);	fn_xmin = HeapTupleHeaderGetXmin(ht->t_data);	fn_tid = ht->t_self;	ReleaseSysCache(ht);	if (last_fn_xmin != fn_xmin ||		!ItemPointerEquals(PyPgFunction_GetItemPointer(func), &fn_tid))	{		return(false);	}	if (!PyPgTupleDesc_IsCurrent(PyPgFunction_GetInput(func)))	{		return(false);	}	if (!PyPgType_IsCurrent(PyPgFunction_GetOutput(func)))		return(false);	return(true);}
开发者ID:fdr,项目名称:pg-python,代码行数:41,


示例12: tuple_all_visible

/* * Check whether a tuple is all-visible relative to a given OldestXmin value. * The buffer should contain the tuple and should be locked and pinned. */static booltuple_all_visible(HeapTuple tup, TransactionId OldestXmin, Buffer buffer){    HTSV_Result state;    TransactionId xmin;    state = HeapTupleSatisfiesVacuum(tup, OldestXmin, buffer);    if (state != HEAPTUPLE_LIVE)        return false;			/* all-visible implies live */    /*     * Neither lazy_scan_heap nor heap_page_is_all_visible will mark a page     * all-visible unless every tuple is hinted committed. However, those hint     * bits could be lost after a crash, so we can't be certain that they'll     * be set here.  So just check the xmin.     */    xmin = HeapTupleHeaderGetXmin(tup->t_data);    if (!TransactionIdPrecedes(xmin, OldestXmin))        return false;			/* xmin not old enough for all to see */    return true;}
开发者ID:RingsC,项目名称:postgres,代码行数:27,


示例13: HeapTupleSatisfiesItself

/* * HeapTupleSatisfiesItself *		True iff heap tuple is valid "for itself". * *	Here, we consider the effects of: *		all committed transactions (as of the current instant) *		previous commands of this transaction *		changes made by the current command * * Note: *		Assumes heap tuple is valid. * * The satisfaction of "itself" requires the following: * * ((Xmin == my-transaction &&				the row was updated by the current transaction, and *		(Xmax is null						it was not deleted *		 [|| Xmax != my-transaction)])			[or it was deleted by another transaction] * || * * (Xmin is committed &&					the row was modified by a committed transaction, and *		(Xmax is null ||					the row has not been deleted, or *			(Xmax != my-transaction &&			the row was deleted by another transaction *			 Xmax is not committed)))			that has not been committed */boolHeapTupleSatisfiesItself(HeapTupleHeader tuple){	if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED))	{		if (tuple->t_infomask & HEAP_XMIN_INVALID)			return false;		if (tuple->t_infomask & HEAP_MOVED_OFF)		{			TransactionId xvac = HeapTupleHeaderGetXvac(tuple);			if (TransactionIdIsCurrentTransactionId(xvac))				return false;			if (!TransactionIdIsInProgress(xvac))			{				if (TransactionIdDidCommit(xvac))				{					tuple->t_infomask |= HEAP_XMIN_INVALID;					return false;				}				tuple->t_infomask |= HEAP_XMIN_COMMITTED;			}		}		else if (tuple->t_infomask & HEAP_MOVED_IN)		{			TransactionId xvac = HeapTupleHeaderGetXvac(tuple);			if (!TransactionIdIsCurrentTransactionId(xvac))			{				if (TransactionIdIsInProgress(xvac))					return false;				if (TransactionIdDidCommit(xvac))					tuple->t_infomask |= HEAP_XMIN_COMMITTED;				else				{					tuple->t_infomask |= HEAP_XMIN_INVALID;					return false;				}			}		}		else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmin(tuple)))		{			if (tuple->t_infomask & HEAP_XMAX_INVALID)	/* xid invalid */				return true;			Assert(TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(tuple)));			if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)				return true;			return false;		}		else if (TransactionIdIsInProgress(HeapTupleHeaderGetXmin(tuple)))			return false;		else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))			tuple->t_infomask |= HEAP_XMIN_COMMITTED;		else		{			/* it must have aborted or crashed */			tuple->t_infomask |= HEAP_XMIN_INVALID;			return false;		}	}	/* by here, the inserting transaction has committed */	if (tuple->t_infomask & HEAP_XMAX_INVALID)	/* xid invalid or aborted */		return true;	if (tuple->t_infomask & HEAP_XMAX_COMMITTED)	{		if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)			return true;		return false;			/* updated by other */	}//.........这里部分代码省略.........
开发者ID:sunyangkobe,项目名称:cscd43,代码行数:101,


示例14: rewrite_heap_tuple

//.........这里部分代码省略.........			/*			 * We can't do anything more now, since we don't know where the			 * tuple will be written.			 */			MemoryContextSwitchTo(old_cxt);			return;		}	}	/*	 * Now we will write the tuple, and then check to see if it is the B tuple	 * in any new or known pair.  When we resolve a known pair, we will be	 * able to write that pair's A tuple, and then we have to check if it	 * resolves some other pair.  Hence, we need a loop here.	 */	old_tid = old_tuple->t_self;	free_new = false;	for (;;)	{		ItemPointerData new_tid;		/* Insert the tuple and find out where it's put in new_heap */		raw_heap_insert(state, new_tuple);		new_tid = new_tuple->t_self;		/*		 * If the tuple is the updated version of a row, and the prior version		 * wouldn't be DEAD yet, then we need to either resolve the prior		 * version (if it's waiting in rs_unresolved_tups), or make an entry		 * in rs_old_new_tid_map (so we can resolve it when we do see it). The		 * previous tuple's xmax would equal this one's xmin, so it's		 * RECENTLY_DEAD if and only if the xmin is not before OldestXmin.		 */		if ((new_tuple->t_data->t_infomask & HEAP_UPDATED) &&			!TransactionIdPrecedes(HeapTupleHeaderGetXmin(new_tuple->t_data),								   state->rs_oldest_xmin))		{			/*			 * Okay, this is B in an update pair.  See if we've seen A.			 */			UnresolvedTup unresolved;			memset(&hashkey, 0, sizeof(hashkey));			hashkey.xmin = HeapTupleHeaderGetXmin(new_tuple->t_data);			hashkey.tid = old_tid;			unresolved = hash_search(state->rs_unresolved_tups, &hashkey,									 HASH_FIND, NULL);			if (unresolved != NULL)			{				/*				 * We have seen and memorized the previous tuple already. Now				 * that we know where we inserted the tuple its t_ctid points				 * to, fix its t_ctid and insert it to the new heap.				 */				if (free_new)					heap_freetuple(new_tuple);				new_tuple = unresolved->tuple;				free_new = true;				old_tid = unresolved->old_tid;				new_tuple->t_data->t_ctid = new_tid;				/*				 * We don't need the hash entry anymore, but don't free its				 * tuple just yet.				 */				hash_search(state->rs_unresolved_tups, &hashkey,							HASH_REMOVE, &found);				Assert(found);				/* loop back to insert the previous tuple in the chain */				continue;			}			else			{				/*				 * Remember the new tid of this tuple. We'll use it to set the				 * ctid when we find the previous tuple in the chain.				 */				OldToNewMapping mapping;				mapping = hash_search(state->rs_old_new_tid_map, &hashkey,									  HASH_ENTER, &found);				Assert(!found);				mapping->new_tid = new_tid;			}		}		/* Done with this (chain of) tuples, for now */		if (free_new)			heap_freetuple(new_tuple);		break;	}	MemoryContextSwitchTo(old_cxt);}
开发者ID:AlexHill,项目名称:postgres,代码行数:101,


示例15: HeapTupleSatisfiesHistoricMVCC

/* * See the comments for HeapTupleSatisfiesMVCC for the semantics this function * obeys. * * Only usable on tuples from catalog tables! * * We don't need to support HEAP_MOVED_(IN|OFF) for now because we only support * reading catalog pages which couldn't have been created in an older version. * * We don't set any hint bits in here as it seems unlikely to be beneficial as * those should already be set by normal access and it seems to be too * dangerous to do so as the semantics of doing so during timetravel are more * complicated than when dealing "only" with the present. */boolHeapTupleSatisfiesHistoricMVCC(HeapTuple htup, Snapshot snapshot,							   Buffer buffer){	HeapTupleHeader tuple = htup->t_data;	TransactionId xmin = HeapTupleHeaderGetXmin(tuple);	TransactionId xmax = HeapTupleHeaderGetRawXmax(tuple);	Assert(ItemPointerIsValid(&htup->t_self));	Assert(htup->t_tableOid != InvalidOid);	/* inserting transaction aborted */	if (HeapTupleHeaderXminInvalid(tuple))	{		Assert(!TransactionIdDidCommit(xmin));		return false;	}	/* check if it's one of our txids, toplevel is also in there */	else if (TransactionIdInArray(xmin, snapshot->subxip, snapshot->subxcnt))	{		bool		resolved;		CommandId	cmin = HeapTupleHeaderGetRawCommandId(tuple);		CommandId	cmax = InvalidCommandId;		/*		 * another transaction might have (tried to) delete this tuple or		 * cmin/cmax was stored in a combocid. So we need to lookup the actual		 * values externally.		 */		resolved = ResolveCminCmaxDuringDecoding(HistoricSnapshotGetTupleCids(), snapshot,												 htup, buffer,												 &cmin, &cmax);		if (!resolved)			elog(ERROR, "could not resolve cmin/cmax of catalog tuple");		Assert(cmin != InvalidCommandId);		if (cmin >= snapshot->curcid)			return false;		/* inserted after scan started */		/* fall through */	}	/* committed before our xmin horizon. Do a normal visibility check. */	else if (TransactionIdPrecedes(xmin, snapshot->xmin))	{		Assert(!(HeapTupleHeaderXminCommitted(tuple) &&				 !TransactionIdDidCommit(xmin)));		/* check for hint bit first, consult clog afterwards */		if (!HeapTupleHeaderXminCommitted(tuple) &&			!TransactionIdDidCommit(xmin))			return false;		/* fall through */	}	/* beyond our xmax horizon, i.e. invisible */	else if (TransactionIdFollowsOrEquals(xmin, snapshot->xmax))	{		return false;	}	/* check if it's a committed transaction in [xmin, xmax) */	else if (TransactionIdInArray(xmin, snapshot->xip, snapshot->xcnt))	{		/* fall through */	}	/*	 * none of the above, i.e. between [xmin, xmax) but hasn't committed. I.e.	 * invisible.	 */	else	{		return false;	}	/* at this point we know xmin is visible, go on to check xmax */	/* xid invalid or aborted */	if (tuple->t_infomask & HEAP_XMAX_INVALID)		return true;	/* locked tuples are always visible */	else if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))		return true;	/*	 * We can see multis here if we're looking at user tables or if somebody	 * SELECT ... FOR SHARE/UPDATE a system table.//.........这里部分代码省略.........
开发者ID:Deepakkothandan,项目名称:postgres,代码行数:101,


示例16: HeapTupleSatisfiesMVCC

/* * HeapTupleSatisfiesMVCC *		True iff heap tuple is valid for the given MVCC snapshot. * *	Here, we consider the effects of: *		all transactions committed as of the time of the given snapshot *		previous commands of this transaction * *	Does _not_ include: *		transactions shown as in-progress by the snapshot *		transactions started after the snapshot was taken *		changes made by the current command * * This is the same as HeapTupleSatisfiesNow, except that transactions that * were in progress or as yet unstarted when the snapshot was taken will * be treated as uncommitted, even if they have committed by now. * * (Notice, however, that the tuple status hint bits will be updated on the * basis of the true state of the transaction, even if we then pretend we * can't see it.) */boolHeapTupleSatisfiesMVCC(HeapTupleHeader tuple, Snapshot snapshot,					   Buffer buffer){	if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED))	{		if (tuple->t_infomask & HEAP_XMIN_INVALID)			return false;		if (tuple->t_infomask & HEAP_MOVED_OFF)		{			TransactionId xvac = HeapTupleHeaderGetXvac(tuple);			if (TransactionIdIsCurrentTransactionId(xvac))				return false;			if (!TransactionIdIsInProgress(xvac))			{				if (TransactionIdDidCommit(xvac))				{					SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,								InvalidTransactionId);					return false;				}				SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,							InvalidTransactionId);			}		}		else if (tuple->t_infomask & HEAP_MOVED_IN)		{			TransactionId xvac = HeapTupleHeaderGetXvac(tuple);			if (!TransactionIdIsCurrentTransactionId(xvac))			{				if (TransactionIdIsInProgress(xvac))					return false;				if (TransactionIdDidCommit(xvac))					SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,								InvalidTransactionId);				else				{					SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,								InvalidTransactionId);					return false;				}			}		}		else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmin(tuple)))		{			if (HeapTupleHeaderGetCmin(tuple) >= snapshot->curcid)				return false;	/* inserted after scan started */			if (tuple->t_infomask & HEAP_XMAX_INVALID)	/* xid invalid */				return true;			if (tuple->t_infomask & HEAP_IS_LOCKED)		/* not deleter */				return true;			Assert(!(tuple->t_infomask & HEAP_XMAX_IS_MULTI));			if (!TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(tuple)))			{				/* deleting subtransaction must have aborted */				SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,							InvalidTransactionId);				return true;			}			if (HeapTupleHeaderGetCmax(tuple) >= snapshot->curcid)				return true;	/* deleted after scan started */			else				return false;	/* deleted before scan started */		}		else if (TransactionIdIsInProgress(HeapTupleHeaderGetXmin(tuple)))			return false;		else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))			SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,						HeapTupleHeaderGetXmin(tuple));		else		{//.........这里部分代码省略.........
开发者ID:Khalefa,项目名称:PostgreSQL_hierarchical,代码行数:101,


示例17: HeapTupleSatisfiesDirty

/* * HeapTupleSatisfiesDirty *		True iff heap tuple is valid including effects of open transactions. * *	Here, we consider the effects of: *		all committed and in-progress transactions (as of the current instant) *		previous commands of this transaction *		changes made by the current command * * This is essentially like HeapTupleSatisfiesSelf as far as effects of * the current transaction and committed/aborted xacts are concerned. * However, we also include the effects of other xacts still in progress. * * A special hack is that the passed-in snapshot struct is used as an * output argument to return the xids of concurrent xacts that affected the * tuple.  snapshot->xmin is set to the tuple's xmin if that is another * transaction that's still in progress; or to InvalidTransactionId if the * tuple's xmin is committed good, committed dead, or my own xact.  Similarly * for snapshot->xmax and the tuple's xmax. */boolHeapTupleSatisfiesDirty(HeapTupleHeader tuple, Snapshot snapshot,						Buffer buffer){		snapshot->xmin = snapshot->xmax = InvalidTransactionId;	if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED))	{		if (tuple->t_infomask & HEAP_XMIN_INVALID)			return false;		if (tuple->t_infomask & HEAP_MOVED_OFF)		{			TransactionId xvac = HeapTupleHeaderGetXvac(tuple);			if (TransactionIdIsCurrentTransactionId(xvac))				return false;			if (!TransactionIdIsInProgress(xvac))			{				if (TransactionIdDidCommit(xvac))				{					SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,								InvalidTransactionId);					return false;				}				SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,							InvalidTransactionId);			}		}		else if (tuple->t_infomask & HEAP_MOVED_IN)		{			TransactionId xvac = HeapTupleHeaderGetXvac(tuple);			if (!TransactionIdIsCurrentTransactionId(xvac))			{				if (TransactionIdIsInProgress(xvac))					return false;				if (TransactionIdDidCommit(xvac))					SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,								InvalidTransactionId);				else				{					SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,								InvalidTransactionId);					return false;				}			}		}		else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmin(tuple)))		{			if (tuple->t_infomask & HEAP_XMAX_INVALID)	/* xid invalid */				return true;			if (tuple->t_infomask & HEAP_IS_LOCKED)		/* not deleter */				return true;			Assert(!(tuple->t_infomask & HEAP_XMAX_IS_MULTI));			if (!TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(tuple)))			{				/* deleting subtransaction must have aborted */				SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,							InvalidTransactionId);				return true;			}			return false;		}		else if (TransactionIdIsInProgress(HeapTupleHeaderGetXmin(tuple)))		{			snapshot->xmin = HeapTupleHeaderGetXmin(tuple);			/* XXX shouldn't we fall through to look at xmax? */			return true;		/* in insertion by other */		}		else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))			SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,						HeapTupleHeaderGetXmin(tuple));//.........这里部分代码省略.........
开发者ID:Khalefa,项目名称:PostgreSQL_hierarchical,代码行数:101,


示例18: HeapTupleSatisfiesUpdate

/* * HeapTupleSatisfiesUpdate * *	Same logic as HeapTupleSatisfiesNow, but returns a more detailed result *	code, since UPDATE needs to know more than "is it visible?".  Also, *	tuples of my own xact are tested against the passed CommandId not *	CurrentCommandId. * *	The possible return codes are: * *	HeapTupleInvisible: the tuple didn't exist at all when the scan started, *	e.g. it was created by a later CommandId. * *	HeapTupleMayBeUpdated: The tuple is valid and visible, so it may be *	updated. * *	HeapTupleSelfUpdated: The tuple was updated by the current transaction, *	after the current scan started. * *	HeapTupleUpdated: The tuple was updated by a committed transaction. * *	HeapTupleBeingUpdated: The tuple is being updated by an in-progress *	transaction other than the current transaction.  (Note: this includes *	the case where the tuple is share-locked by a MultiXact, even if the *	MultiXact includes the current transaction.  Callers that want to *	distinguish that case must test for it themselves.) */HTSU_ResultHeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid,						 Buffer buffer){	if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED))	{		if (tuple->t_infomask & HEAP_XMIN_INVALID)			return HeapTupleInvisible;		if (tuple->t_infomask & HEAP_MOVED_OFF)		{			TransactionId xvac = HeapTupleHeaderGetXvac(tuple);			if (TransactionIdIsCurrentTransactionId(xvac))				return HeapTupleInvisible;			if (!TransactionIdIsInProgress(xvac))			{				if (TransactionIdDidCommit(xvac))				{					SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,								InvalidTransactionId);					return HeapTupleInvisible;				}				SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,							InvalidTransactionId);			}		}		else if (tuple->t_infomask & HEAP_MOVED_IN)		{			TransactionId xvac = HeapTupleHeaderGetXvac(tuple);			if (!TransactionIdIsCurrentTransactionId(xvac))			{				if (TransactionIdIsInProgress(xvac))					return HeapTupleInvisible;				if (TransactionIdDidCommit(xvac))					SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,								InvalidTransactionId);				else				{					SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,								InvalidTransactionId);					return HeapTupleInvisible;				}			}		}		else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmin(tuple)))		{			if (HeapTupleHeaderGetCmin(tuple) >= curcid)				return HeapTupleInvisible;		/* inserted after scan started */			if (tuple->t_infomask & HEAP_XMAX_INVALID)	/* xid invalid */				return HeapTupleMayBeUpdated;			if (tuple->t_infomask & HEAP_IS_LOCKED)		/* not deleter */				return HeapTupleMayBeUpdated;			Assert(!(tuple->t_infomask & HEAP_XMAX_IS_MULTI));			if (!TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(tuple)))			{				/* deleting subtransaction must have aborted */				SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,							InvalidTransactionId);				return HeapTupleMayBeUpdated;			}			if (HeapTupleHeaderGetCmax(tuple) >= curcid)				return HeapTupleSelfUpdated;	/* updated after scan started */			else				return HeapTupleInvisible;		/* updated before scan started */		}		else if (TransactionIdIsInProgress(HeapTupleHeaderGetXmin(tuple)))//.........这里部分代码省略.........
开发者ID:Khalefa,项目名称:PostgreSQL_hierarchical,代码行数:101,


示例19: HeapTupleSatisfiesVacuum

/* * HeapTupleSatisfiesVacuum * *	Determine the status of tuples for VACUUM purposes.  Here, what *	we mainly want to know is if a tuple is potentially visible to *any* *	running transaction.  If so, it can't be removed yet by VACUUM. * * OldestXmin is a cutoff XID (obtained from GetOldestXmin()).	Tuples * deleted by XIDs >= OldestXmin are deemed "recently dead"; they might * still be visible to some open transaction, so we can't remove them, * even if we see that the deleting transaction has committed. */HTSV_ResultHeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin,						 Buffer buffer){	/*	 * Has inserting transaction committed?	 *	 * If the inserting transaction aborted, then the tuple was never visible	 * to any other transaction, so we can delete it immediately.	 */	if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED))	{		if (tuple->t_infomask & HEAP_XMIN_INVALID)			return HEAPTUPLE_DEAD;		else if (tuple->t_infomask & HEAP_MOVED_OFF)		{			TransactionId xvac = HeapTupleHeaderGetXvac(tuple);			if (TransactionIdIsCurrentTransactionId(xvac))				return HEAPTUPLE_DELETE_IN_PROGRESS;			if (TransactionIdIsInProgress(xvac))				return HEAPTUPLE_DELETE_IN_PROGRESS;			if (TransactionIdDidCommit(xvac))			{				SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,							InvalidTransactionId);				return HEAPTUPLE_DEAD;			}			SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,						InvalidTransactionId);		}		else if (tuple->t_infomask & HEAP_MOVED_IN)		{			TransactionId xvac = HeapTupleHeaderGetXvac(tuple);			if (TransactionIdIsCurrentTransactionId(xvac))				return HEAPTUPLE_INSERT_IN_PROGRESS;			if (TransactionIdIsInProgress(xvac))				return HEAPTUPLE_INSERT_IN_PROGRESS;			if (TransactionIdDidCommit(xvac))				SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,							InvalidTransactionId);			else			{				SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,							InvalidTransactionId);				return HEAPTUPLE_DEAD;			}		}		else if (TransactionIdIsInProgress(HeapTupleHeaderGetXmin(tuple)))		{			if (tuple->t_infomask & HEAP_XMAX_INVALID)	/* xid invalid */				return HEAPTUPLE_INSERT_IN_PROGRESS;			if (tuple->t_infomask & HEAP_IS_LOCKED)				return HEAPTUPLE_INSERT_IN_PROGRESS;			/* inserted and then deleted by same xact */			return HEAPTUPLE_DELETE_IN_PROGRESS;		}		else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))			SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,						HeapTupleHeaderGetXmin(tuple));		else		{			/*			 * Not in Progress, Not Committed, so either Aborted or crashed			 */			SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,						InvalidTransactionId);			return HEAPTUPLE_DEAD;		}		/*		 * At this point the xmin is known committed, but we might not have		 * been able to set the hint bit yet; so we can no longer Assert that		 * it's set.		 */	}	/*	 * Okay, the inserter committed, so it was good at some point.	Now what	 * about the deleting transaction?	 */	if (tuple->t_infomask & HEAP_XMAX_INVALID)		return HEAPTUPLE_LIVE;	if (tuple->t_infomask & HEAP_IS_LOCKED)	{		/*//.........这里部分代码省略.........
开发者ID:Khalefa,项目名称:PostgreSQL_hierarchical,代码行数:101,


示例20: heap_page_items

Datumheap_page_items(PG_FUNCTION_ARGS){	bytea	   *raw_page = PG_GETARG_BYTEA_P(0);	heap_page_items_state *inter_call_data = NULL;	FuncCallContext *fctx;	int			raw_page_size;	if (!superuser())		ereport(ERROR,				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),				 (errmsg("must be superuser to use raw page functions"))));	raw_page_size = VARSIZE(raw_page) - VARHDRSZ;	if (SRF_IS_FIRSTCALL())	{		TupleDesc	tupdesc;		MemoryContext mctx;		if (raw_page_size < SizeOfPageHeaderData)			ereport(ERROR,					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),				  errmsg("input page too small (%d bytes)", raw_page_size)));		fctx = SRF_FIRSTCALL_INIT();		mctx = MemoryContextSwitchTo(fctx->multi_call_memory_ctx);		inter_call_data = palloc(sizeof(heap_page_items_state));		/* Build a tuple descriptor for our result type */		if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)			elog(ERROR, "return type must be a row type");		inter_call_data->tupd = tupdesc;		inter_call_data->offset = FirstOffsetNumber;		inter_call_data->page = VARDATA(raw_page);		fctx->max_calls = PageGetMaxOffsetNumber(inter_call_data->page);		fctx->user_fctx = inter_call_data;		MemoryContextSwitchTo(mctx);	}	fctx = SRF_PERCALL_SETUP();	inter_call_data = fctx->user_fctx;	if (fctx->call_cntr < fctx->max_calls)	{		Page		page = inter_call_data->page;		HeapTuple	resultTuple;		Datum		result;		ItemId		id;		Datum		values[13];		bool		nulls[13];		uint16		lp_offset;		uint16		lp_flags;		uint16		lp_len;		memset(nulls, 0, sizeof(nulls));		/* Extract information from the line pointer */		id = PageGetItemId(page, inter_call_data->offset);		lp_offset = ItemIdGetOffset(id);		lp_flags = ItemIdGetFlags(id);		lp_len = ItemIdGetLength(id);		values[0] = UInt16GetDatum(inter_call_data->offset);		values[1] = UInt16GetDatum(lp_offset);		values[2] = UInt16GetDatum(lp_flags);		values[3] = UInt16GetDatum(lp_len);		/*		 * We do just enough validity checking to make sure we don't reference		 * data outside the page passed to us. The page could be corrupt in		 * many other ways, but at least we won't crash.		 */		if (ItemIdHasStorage(id) &&			lp_len >= sizeof(HeapTupleHeader) &&			lp_offset == MAXALIGN(lp_offset) &&			lp_offset + lp_len <= raw_page_size)		{			HeapTupleHeader tuphdr;			int			bits_len;			/* Extract information from the tuple header */			tuphdr = (HeapTupleHeader) PageGetItem(page, id);			values[4] = UInt32GetDatum(HeapTupleHeaderGetXmin(tuphdr));			values[5] = UInt32GetDatum(HeapTupleHeaderGetRawXmax(tuphdr));			values[6] = UInt32GetDatum(HeapTupleHeaderGetRawCommandId(tuphdr)); /* shared with xvac */			values[7] = PointerGetDatum(&tuphdr->t_ctid);			values[8] = UInt32GetDatum(tuphdr->t_infomask2);			values[9] = UInt32GetDatum(tuphdr->t_infomask);			values[10] = UInt8GetDatum(tuphdr->t_hoff);//.........这里部分代码省略.........
开发者ID:42penguins,项目名称:postgres,代码行数:101,


示例21: check_safe_enum_use

/* * Disallow use of an uncommitted pg_enum tuple. * * We need to make sure that uncommitted enum values don't get into indexes. * If they did, and if we then rolled back the pg_enum addition, we'd have * broken the index because value comparisons will not work reliably without * an underlying pg_enum entry.  (Note that removal of the heap entry * containing an enum value is not sufficient to ensure that it doesn't appear * in upper levels of indexes.)  To do this we prevent an uncommitted row from * being used for any SQL-level purpose.  This is stronger than necessary, * since the value might not be getting inserted into a table or there might * be no index on its column, but it's easy to enforce centrally. * * However, it's okay to allow use of uncommitted values belonging to enum * types that were themselves created in the same transaction, because then * any such index would also be new and would go away altogether on rollback. * (This case is required by pg_upgrade.) * * This function needs to be called (directly or indirectly) in any of the * functions below that could return an enum value to SQL operations. */static voidcheck_safe_enum_use(HeapTuple enumval_tup){	TransactionId xmin;	Form_pg_enum en;	HeapTuple	enumtyp_tup;	/*	 * If the row is hinted as committed, it's surely safe.  This provides a	 * fast path for all normal use-cases.	 */	if (HeapTupleHeaderXminCommitted(enumval_tup->t_data))		return;	/*	 * Usually, a row would get hinted as committed when it's read or loaded	 * into syscache; but just in case not, let's check the xmin directly.	 */	xmin = HeapTupleHeaderGetXmin(enumval_tup->t_data);	if (!TransactionIdIsInProgress(xmin) &&		TransactionIdDidCommit(xmin))		return;	/* It is a new enum value, so check to see if the whole enum is new */	en = (Form_pg_enum) GETSTRUCT(enumval_tup);	enumtyp_tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(en->enumtypid));	if (!HeapTupleIsValid(enumtyp_tup))		elog(ERROR, "cache lookup failed for type %u", en->enumtypid);	/*	 * We insist that the type have been created in the same (sub)transaction	 * as the enum value.  It would be safe to allow the type's originating	 * xact to be a subcommitted child of the enum value's xact, but not vice	 * versa (since we might now be in a subxact of the type's originating	 * xact, which could roll back along with the enum value's subxact).  The	 * former case seems a sufficiently weird usage pattern as to not be worth	 * spending code for, so we're left with a simple equality check.	 *	 * We also insist that the type's pg_type row not be HEAP_UPDATED.  If it	 * is, we can't tell whether the row was created or only modified in the	 * apparent originating xact, so it might be older than that xact.  (We do	 * not worry whether the enum value is HEAP_UPDATED; if it is, we might	 * think it's too new and throw an unnecessary error, but we won't allow	 * an unsafe case.)	 */	if (xmin == HeapTupleHeaderGetXmin(enumtyp_tup->t_data) &&		!(enumtyp_tup->t_data->t_infomask & HEAP_UPDATED))	{		/* same (sub)transaction, so safe */		ReleaseSysCache(enumtyp_tup);		return;	}	/*	 * There might well be other tests we could do here to narrow down the	 * unsafe conditions, but for now just raise an exception.	 */	ereport(ERROR,			(errcode(ERRCODE_UNSAFE_NEW_ENUM_VALUE_USAGE),			 errmsg("unsafe use of new value /"%s/" of enum type %s",					NameStr(en->enumlabel),					format_type_be(en->enumtypid)),	 errhint("New enum values must be committed before they can be used.")));}
开发者ID:Tao-Ma,项目名称:postgres,代码行数:85,


示例22: compile_plperl_function

static plperl_proc_desc *compile_plperl_function(Oid fn_oid, bool is_trigger){	HeapTuple	procTup;	Form_pg_proc procStruct;	char		internal_proname[64];	int			proname_len;	plperl_proc_desc *prodesc = NULL;	int			i;	SV		  **svp;	/* We'll need the pg_proc tuple in any case... */	procTup = SearchSysCache(PROCOID,							 ObjectIdGetDatum(fn_oid),							 0, 0, 0);	if (!HeapTupleIsValid(procTup))		elog(ERROR, "cache lookup failed for function %u", fn_oid);	procStruct = (Form_pg_proc) GETSTRUCT(procTup);	/************************************************************	 * Build our internal proc name from the functions Oid	 ************************************************************/	if (!is_trigger)		sprintf(internal_proname, "__PLPerl_proc_%u", fn_oid);	else		sprintf(internal_proname, "__PLPerl_proc_%u_trigger", fn_oid);	proname_len = strlen(internal_proname);	/************************************************************	 * Lookup the internal proc name in the hashtable	 ************************************************************/	svp = hv_fetch(plperl_proc_hash, internal_proname, proname_len, FALSE);	if (svp)	{		bool		uptodate;		prodesc = (plperl_proc_desc *) SvIV(*svp);		/************************************************************		 * If it's present, must check whether it's still up to date.		 * This is needed because CREATE OR REPLACE FUNCTION can modify the		 * function's pg_proc entry without changing its OID.		 ************************************************************/		uptodate = (prodesc->fn_xmin == HeapTupleHeaderGetXmin(procTup->t_data) &&				prodesc->fn_cmin == HeapTupleHeaderGetCmin(procTup->t_data));		if (!uptodate)		{			/* need we delete old entry? */			prodesc = NULL;		}	}	/************************************************************	 * If we haven't found it in the hashtable, we analyze	 * the functions arguments and returntype and store	 * the in-/out-functions in the prodesc block and create	 * a new hashtable entry for it.	 *	 * Then we load the procedure into the Perl interpreter.	 ************************************************************/	if (prodesc == NULL)	{		HeapTuple	langTup;		HeapTuple	typeTup;		Form_pg_language langStruct;		Form_pg_type typeStruct;		Datum		prosrcdatum;		bool		isnull;		char	   *proc_source;		/************************************************************		 * Allocate a new procedure description block		 ************************************************************/		prodesc = (plperl_proc_desc *) malloc(sizeof(plperl_proc_desc));		if (prodesc == NULL)			ereport(ERROR,					(errcode(ERRCODE_OUT_OF_MEMORY),					 errmsg("out of memory")));		MemSet(prodesc, 0, sizeof(plperl_proc_desc));		prodesc->proname = strdup(internal_proname);		prodesc->fn_xmin = HeapTupleHeaderGetXmin(procTup->t_data);		prodesc->fn_cmin = HeapTupleHeaderGetCmin(procTup->t_data);		/* Remember if function is STABLE/IMMUTABLE */		prodesc->fn_readonly =			(procStruct->provolatile != PROVOLATILE_VOLATILE);		/************************************************************		 * Lookup the pg_language tuple by Oid		 ************************************************************/		langTup = SearchSysCache(LANGOID,								 ObjectIdGetDatum(procStruct->prolang),								 0, 0, 0);		if (!HeapTupleIsValid(langTup))		{			free(prodesc->proname);			free(prodesc);			elog(ERROR, "cache lookup failed for language %u",//.........这里部分代码省略.........
开发者ID:shubham2094,项目名称:postgresql_8.1,代码行数:101,


示例23: get_relation_info

//.........这里部分代码省略.........		foreach(l, indexoidlist)		{			Oid			indexoid = lfirst_oid(l);			Relation	indexRelation;			Form_pg_index index;			IndexOptInfo *info;			int			ncolumns;			int			i;			/*			 * Extract info from the relation descriptor for the index.			 */			indexRelation = index_open(indexoid, lmode);			index = indexRelation->rd_index;			/*			 * Ignore invalid indexes, since they can't safely be used for			 * queries.  Note that this is OK because the data structure we			 * are constructing is only used by the planner --- the executor			 * still needs to insert into "invalid" indexes!			 */			if (!index->indisvalid)			{				index_close(indexRelation, NoLock);				continue;			}			/*			 * If the index is valid, but cannot yet be used, ignore it; but			 * mark the plan we are generating as transient. See			 * src/backend/access/heap/README.HOT for discussion.			 */			if (index->indcheckxmin &&				!TransactionIdPrecedes(HeapTupleHeaderGetXmin(indexRelation->rd_indextuple->t_data),									   TransactionXmin))			{				root->glob->transientPlan = true;				index_close(indexRelation, NoLock);				continue;			}			info = makeNode(IndexOptInfo);			info->indexoid = index->indexrelid;			info->reltablespace =				RelationGetForm(indexRelation)->reltablespace;			info->rel = rel;			info->ncolumns = ncolumns = index->indnatts;			info->indexkeys = (int *) palloc(sizeof(int) * ncolumns);			info->indexcollations = (Oid *) palloc(sizeof(Oid) * ncolumns);			info->opfamily = (Oid *) palloc(sizeof(Oid) * ncolumns);			info->opcintype = (Oid *) palloc(sizeof(Oid) * ncolumns);			for (i = 0; i < ncolumns; i++)			{				info->indexkeys[i] = index->indkey.values[i];				info->indexcollations[i] = indexRelation->rd_indcollation[i];				info->opfamily[i] = indexRelation->rd_opfamily[i];				info->opcintype[i] = indexRelation->rd_opcintype[i];			}			info->relam = indexRelation->rd_rel->relam;			info->amcostestimate = indexRelation->rd_am->amcostestimate;			info->canreturn = index_can_return(indexRelation);			info->amcanorderbyop = indexRelation->rd_am->amcanorderbyop;			info->amoptionalkey = indexRelation->rd_am->amoptionalkey;
开发者ID:a1exsh,项目名称:postgres,代码行数:67,


示例24: HeapTupleSatisfiesVacuum

/* * HeapTupleSatisfiesVacuum * *	Determine the status of tuples for VACUUM purposes.  Here, what *	we mainly want to know is if a tuple is potentially visible to *any* *	running transaction.  If so, it can't be removed yet by VACUUM. * * OldestXmin is a cutoff XID (obtained from GetOldestXmin()).	Tuples * deleted by XIDs >= OldestXmin are deemed "recently dead"; they might * still be visible to some open transaction, so we can't remove them, * even if we see that the deleting transaction has committed. */HTSV_ResultHeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin){	/*	 * Has inserting transaction committed?	 *	 * If the inserting transaction aborted, then the tuple was never visible	 * to any other transaction, so we can delete it immediately.	 */	if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED))	{		if (tuple->t_infomask & HEAP_XMIN_INVALID)			return HEAPTUPLE_DEAD;		else if (tuple->t_infomask & HEAP_MOVED_OFF)		{			TransactionId xvac = HeapTupleHeaderGetXvac(tuple);			if (TransactionIdIsCurrentTransactionId(xvac))				return HEAPTUPLE_DELETE_IN_PROGRESS;			if (TransactionIdIsInProgress(xvac))				return HEAPTUPLE_DELETE_IN_PROGRESS;			if (TransactionIdDidCommit(xvac))			{				tuple->t_infomask |= HEAP_XMIN_INVALID;				return HEAPTUPLE_DEAD;			}			tuple->t_infomask |= HEAP_XMIN_COMMITTED;		}		else if (tuple->t_infomask & HEAP_MOVED_IN)		{			TransactionId xvac = HeapTupleHeaderGetXvac(tuple);			if (TransactionIdIsCurrentTransactionId(xvac))				return HEAPTUPLE_INSERT_IN_PROGRESS;			if (TransactionIdIsInProgress(xvac))				return HEAPTUPLE_INSERT_IN_PROGRESS;			if (TransactionIdDidCommit(xvac))				tuple->t_infomask |= HEAP_XMIN_COMMITTED;			else			{				tuple->t_infomask |= HEAP_XMIN_INVALID;				return HEAPTUPLE_DEAD;			}		}		else if (TransactionIdIsInProgress(HeapTupleHeaderGetXmin(tuple)))		{			if (tuple->t_infomask & HEAP_XMAX_INVALID)	/* xid invalid */				return HEAPTUPLE_INSERT_IN_PROGRESS;			Assert(HeapTupleHeaderGetXmin(tuple) ==				   HeapTupleHeaderGetXmax(tuple));			if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)				return HEAPTUPLE_INSERT_IN_PROGRESS;			/* inserted and then deleted by same xact */			return HEAPTUPLE_DELETE_IN_PROGRESS;		}		else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))			tuple->t_infomask |= HEAP_XMIN_COMMITTED;		else		{			/*			 * Not in Progress, Not Committed, so either Aborted or			 * crashed			 */			tuple->t_infomask |= HEAP_XMIN_INVALID;			return HEAPTUPLE_DEAD;		}		/* Should only get here if we set XMIN_COMMITTED */		Assert(tuple->t_infomask & HEAP_XMIN_COMMITTED);	}	/*	 * Okay, the inserter committed, so it was good at some point.	Now	 * what about the deleting transaction?	 */	if (tuple->t_infomask & HEAP_XMAX_INVALID)		return HEAPTUPLE_LIVE;	if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)	{		/*		 * "Deleting" xact really only marked it for update, so the tuple		 * is live in any case.  However, we must make sure that either		 * XMAX_COMMITTED or XMAX_INVALID gets set once the xact is gone;		 * otherwise it is unsafe to recycle CLOG status after vacuuming.		 */		if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))		{			if (TransactionIdIsInProgress(HeapTupleHeaderGetXmax(tuple)))//.........这里部分代码省略.........
开发者ID:sunyangkobe,项目名称:cscd43,代码行数:101,


示例25: HeapTupleSatisfiesSnapshot

/* * HeapTupleSatisfiesSnapshot *		True iff heap tuple is valid for the given snapshot. * *	Here, we consider the effects of: *		all transactions committed as of the time of the given snapshot *		previous commands of this transaction * *	Does _not_ include: *		transactions shown as in-progress by the snapshot *		transactions started after the snapshot was taken *		changes made by the current command * * This is the same as HeapTupleSatisfiesNow, except that transactions that * were in progress or as yet unstarted when the snapshot was taken will * be treated as uncommitted, even if they have committed by now. * * (Notice, however, that the tuple status hint bits will be updated on the * basis of the true state of the transaction, even if we then pretend we * can't see it.) */boolHeapTupleSatisfiesSnapshot(HeapTupleHeader tuple, Snapshot snapshot){	if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED))	{		if (tuple->t_infomask & HEAP_XMIN_INVALID)			return false;		if (tuple->t_infomask & HEAP_MOVED_OFF)		{			TransactionId xvac = HeapTupleHeaderGetXvac(tuple);			if (TransactionIdIsCurrentTransactionId(xvac))				return false;			if (!TransactionIdIsInProgress(xvac))			{				if (TransactionIdDidCommit(xvac))				{					tuple->t_infomask |= HEAP_XMIN_INVALID;					return false;				}				tuple->t_infomask |= HEAP_XMIN_COMMITTED;			}		}		else if (tuple->t_infomask & HEAP_MOVED_IN)		{			TransactionId xvac = HeapTupleHeaderGetXvac(tuple);			if (!TransactionIdIsCurrentTransactionId(xvac))			{				if (TransactionIdIsInProgress(xvac))					return false;				if (TransactionIdDidCommit(xvac))					tuple->t_infomask |= HEAP_XMIN_COMMITTED;				else				{					tuple->t_infomask |= HEAP_XMIN_INVALID;					return false;				}			}		}		else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmin(tuple)))		{			if (HeapTupleHeaderGetCmin(tuple) >= snapshot->curcid)				return false;	/* inserted after scan started */			if (tuple->t_infomask & HEAP_XMAX_INVALID)	/* xid invalid */				return true;			Assert(TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(tuple)));			if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)				return true;			if (HeapTupleHeaderGetCmax(tuple) >= snapshot->curcid)				return true;	/* deleted after scan started */			else				return false;	/* deleted before scan started */		}		else if (TransactionIdIsInProgress(HeapTupleHeaderGetXmin(tuple)))			return false;		else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))			tuple->t_infomask |= HEAP_XMIN_COMMITTED;		else		{			/* it must have aborted or crashed */			tuple->t_infomask |= HEAP_XMIN_INVALID;			return false;		}	}	/*	 * By here, the inserting transaction has committed - have to check	 * when...	 */	if (TransactionIdFollowsOrEquals(HeapTupleHeaderGetXmin(tuple),									 snapshot->xmin))	{		uint32		i;//.........这里部分代码省略.........
开发者ID:sunyangkobe,项目名称:cscd43,代码行数:101,


示例26: HeapTupleSatisfiesDirty

/* * HeapTupleSatisfiesDirty *		True iff heap tuple is valid including effects of open transactions. * *	Here, we consider the effects of: *		all committed and in-progress transactions (as of the current instant) *		previous commands of this transaction *		changes made by the current command * * This is essentially like HeapTupleSatisfiesItself as far as effects of * the current transaction and committed/aborted xacts are concerned. * However, we also include the effects of other xacts still in progress. * * Returns extra information in the global variable SnapshotDirty, namely * xids of concurrent xacts that affected the tuple.  Also, the tuple's * t_ctid (forward link) is returned if it's being updated. */boolHeapTupleSatisfiesDirty(HeapTupleHeader tuple){	SnapshotDirty->xmin = SnapshotDirty->xmax = InvalidTransactionId;	ItemPointerSetInvalid(&(SnapshotDirty->tid));	if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED))	{		if (tuple->t_infomask & HEAP_XMIN_INVALID)			return false;		if (tuple->t_infomask & HEAP_MOVED_OFF)		{			TransactionId xvac = HeapTupleHeaderGetXvac(tuple);			if (TransactionIdIsCurrentTransactionId(xvac))				return false;			if (!TransactionIdIsInProgress(xvac))			{				if (TransactionIdDidCommit(xvac))				{					tuple->t_infomask |= HEAP_XMIN_INVALID;					return false;				}				tuple->t_infomask |= HEAP_XMIN_COMMITTED;			}		}		else if (tuple->t_infomask & HEAP_MOVED_IN)		{			TransactionId xvac = HeapTupleHeaderGetXvac(tuple);			if (!TransactionIdIsCurrentTransactionId(xvac))			{				if (TransactionIdIsInProgress(xvac))					return false;				if (TransactionIdDidCommit(xvac))					tuple->t_infomask |= HEAP_XMIN_COMMITTED;				else				{					tuple->t_infomask |= HEAP_XMIN_INVALID;					return false;				}			}		}		else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmin(tuple)))		{			if (tuple->t_infomask & HEAP_XMAX_INVALID)	/* xid invalid */				return true;			Assert(TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(tuple)));			if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)				return true;			return false;		}		else if (TransactionIdIsInProgress(HeapTupleHeaderGetXmin(tuple)))		{			SnapshotDirty->xmin = HeapTupleHeaderGetXmin(tuple);			/* XXX shouldn't we fall through to look at xmax? */			return true;		/* in insertion by other */		}		else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))			tuple->t_infomask |= HEAP_XMIN_COMMITTED;		else		{			/* it must have aborted or crashed */			tuple->t_infomask |= HEAP_XMIN_INVALID;			return false;		}	}	/* by here, the inserting transaction has committed */	if (tuple->t_infomask & HEAP_XMAX_INVALID)	/* xid invalid or aborted */		return true;	if (tuple->t_infomask & HEAP_XMAX_COMMITTED)	{		if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)			return true;		SnapshotDirty->tid = tuple->t_ctid;		return false;			/* updated by other *///.........这里部分代码省略.........
开发者ID:sunyangkobe,项目名称:cscd43,代码行数:101,


示例27: get_relation_info

//.........这里部分代码省略.........		foreach(l, indexoidlist)		{			Oid			indexoid = lfirst_oid(l);			Relation	indexRelation;			Form_pg_index index;			IndexOptInfo *info;			int			ncolumns;			int			i;			/*			 * Extract info from the relation descriptor for the index.			 */			indexRelation = index_open(indexoid, lmode);			index = indexRelation->rd_index;			/*			 * Ignore invalid indexes, since they can't safely be used for			 * queries.  Note that this is OK because the data structure we			 * are constructing is only used by the planner --- the executor			 * still needs to insert into "invalid" indexes!			 */			if (!index->indisvalid)			{				index_close(indexRelation, NoLock);				continue;			}			/*			 * If the index is valid, but cannot yet be used, ignore it; but			 * mark the plan we are generating as transient. See			 * src/backend/access/heap/README.HOT for discussion.			 */			if (index->indcheckxmin &&				!TransactionIdPrecedes(HeapTupleHeaderGetXmin(indexRelation->rd_indextuple->t_data),									   TransactionXmin))			{				root->glob->transientPlan = true;				index_close(indexRelation, NoLock);				continue;			}			info = makeNode(IndexOptInfo);			info->indexoid = index->indexrelid;			info->reltablespace =				RelationGetForm(indexRelation)->reltablespace;			info->rel = rel;			info->ncolumns = ncolumns = index->indnatts;			/*			 * Allocate per-column info arrays.  To save a few palloc cycles			 * we allocate all the Oid-type arrays in one request.	Note that			 * the opfamily array needs an extra, terminating zero at the end.			 * We pre-zero the ordering info in case the index is unordered.			 */			info->indexkeys = (int *) palloc(sizeof(int) * ncolumns);			info->opfamily = (Oid *) palloc0(sizeof(Oid) * (4 * ncolumns + 1));			info->opcintype = info->opfamily + (ncolumns + 1);			info->fwdsortop = info->opcintype + ncolumns;			info->revsortop = info->fwdsortop + ncolumns;			info->nulls_first = (bool *) palloc0(sizeof(bool) * ncolumns);			for (i = 0; i < ncolumns; i++)			{				info->indexkeys[i] = index->indkey.values[i];				info->opfamily[i] = indexRelation->rd_opfamily[i];
开发者ID:HeyMendy,项目名称:9315ass2,代码行数:67,


示例28: heap_prune_chain

//.........这里部分代码省略.........		/* Unused item obviously isn't part of the chain */		if (!ItemIdIsUsed(lp))			break;		/*		 * If we are looking at the redirected root line pointer, jump to the		 * first normal tuple in the chain.  If we find a redirect somewhere		 * else, stop --- it must not be same chain.		 */		if (ItemIdIsRedirected(lp))		{			if (nchain > 0)				break;			/* not at start of chain */			chainitems[nchain++] = offnum;			offnum = ItemIdGetRedirect(rootlp);			continue;		}		/*		 * Likewise, a dead item pointer can't be part of the chain. (We		 * already eliminated the case of dead root tuple outside this		 * function.)		 */		if (ItemIdIsDead(lp))			break;		Assert(ItemIdIsNormal(lp));		htup = (HeapTupleHeader) PageGetItem(dp, lp);		/*		 * Check the tuple XMIN against prior XMAX, if any		 */		if (TransactionIdIsValid(priorXmax) &&			!TransactionIdEquals(HeapTupleHeaderGetXmin(htup), priorXmax))			break;		/*		 * OK, this tuple is indeed a member of the chain.		 */		chainitems[nchain++] = offnum;		/*		 * Check tuple's visibility status.		 */		tupdead = recent_dead = false;		switch (HeapTupleSatisfiesVacuum(relation, htup, OldestXmin, buffer))		{			case HEAPTUPLE_DEAD:				tupdead = true;				break;			case HEAPTUPLE_RECENTLY_DEAD:				recent_dead = true;				/*				 * This tuple may soon become DEAD.  Update the hint field so				 * that the page is reconsidered for pruning in future.				 */				heap_prune_record_prunable(prstate,										   HeapTupleHeaderGetXmax(htup));				break;			case HEAPTUPLE_DELETE_IN_PROGRESS:				/*
开发者ID:PengJi,项目名称:gpdb-comments,代码行数:67,


示例29: lazy_scan_heap

//.........这里部分代码省略.........						tupgone = true; /* we can delete the tuple */					all_visible = false;					break;				case HEAPTUPLE_LIVE:					/* Tuple is good --- but let's do some validity checks */					if (onerel->rd_rel->relhasoids &&						!OidIsValid(HeapTupleGetOid(&tuple)))						elog(WARNING, "relation /"%s/" TID %u/%u: OID is invalid",							 relname, blkno, offnum);					/*					 * Is the tuple definitely visible to all transactions?					 *					 * NB: Like with per-tuple hint bits, we can't set the					 * PD_ALL_VISIBLE flag if the inserter committed					 * asynchronously. See SetHintBits for more info. Check					 * that the HEAP_XMIN_COMMITTED hint bit is set because of					 * that.					 */					if (all_visible)					{						TransactionId xmin;						if (!(tuple.t_data->t_infomask & HEAP_XMIN_COMMITTED))						{							all_visible = false;							break;						}						/*						 * The inserter definitely committed. But is it old						 * enough that everyone sees it as committed?						 */						xmin = HeapTupleHeaderGetXmin(tuple.t_data);						if (!TransactionIdPrecedes(xmin, OldestXmin))						{							all_visible = false;							break;						}					}					break;				case HEAPTUPLE_RECENTLY_DEAD:					/*					 * If tuple is recently deleted then we must not remove it					 * from relation.					 */					nkeep += 1;					all_visible = false;					break;				case HEAPTUPLE_INSERT_IN_PROGRESS:					/* This is an expected case during concurrent vacuum */					all_visible = false;					break;				case HEAPTUPLE_DELETE_IN_PROGRESS:					/* This is an expected case during concurrent vacuum */					all_visible = false;					break;				default:					elog(ERROR, "unexpected HeapTupleSatisfiesVacuum result");					break;			}			if (tupgone)			{				lazy_record_dead_tuple(vacrelstats, &(tuple.t_self));
开发者ID:hl0103,项目名称:pgxc,代码行数:67,


示例30: heap_get_root_tuples

/* * For all items in this page, find their respective root line pointers. * If item k is part of a HOT-chain with root at item j, then we set * root_offsets[k - 1] = j. * * The passed-in root_offsets array must have MaxHeapTuplesPerPage entries. * We zero out all unused entries. * * The function must be called with at least share lock on the buffer, to * prevent concurrent prune operations. * * Note: The information collected here is valid only as long as the caller * holds a pin on the buffer. Once pin is released, a tuple might be pruned * and reused by a completely unrelated tuple. */voidheap_get_root_tuples(Page page, OffsetNumber *root_offsets){	OffsetNumber offnum,				maxoff;	MemSet(root_offsets, 0, MaxHeapTuplesPerPage * sizeof(OffsetNumber));	maxoff = PageGetMaxOffsetNumber(page);	for (offnum = FirstOffsetNumber; offnum <= maxoff; offnum = OffsetNumberNext(offnum))	{		ItemId		lp = PageGetItemId(page, offnum);		HeapTupleHeader htup;		OffsetNumber nextoffnum;		TransactionId priorXmax;		/* skip unused and dead items */		if (!ItemIdIsUsed(lp) || ItemIdIsDead(lp))			continue;		if (ItemIdIsNormal(lp))		{			htup = (HeapTupleHeader) PageGetItem(page, lp);			/*			 * Check if this tuple is part of a HOT-chain rooted at some other			 * tuple. If so, skip it for now; we'll process it when we find			 * its root.			 */			if (HeapTupleHeaderIsHeapOnly(htup))				continue;			/*			 * This is either a plain tuple or the root of a HOT-chain.			 * Remember it in the mapping.			 */			root_offsets[offnum - 1] = offnum;			/* If it's not the start of a HOT-chain, we're done with it */			if (!HeapTupleHeaderIsHotUpdated(htup))				continue;			/* Set up to scan the HOT-chain */			nextoffnum = ItemPointerGetOffsetNumber(&htup->t_ctid);			priorXmax = HeapTupleHeaderGetXmax(htup);		}		else		{			/* Must be a redirect item. We do not set its root_offsets entry */			Assert(ItemIdIsRedirected(lp));			/* Set up to scan the HOT-chain */			nextoffnum = ItemIdGetRedirect(lp);			priorXmax = InvalidTransactionId;		}		/*		 * Now follow the HOT-chain and collect other tuples in the chain.		 *		 * Note: Even though this is a nested loop, the complexity of the		 * function is O(N) because a tuple in the page should be visited not		 * more than twice, once in the outer loop and once in HOT-chain		 * chases.		 */		for (;;)		{			lp = PageGetItemId(page, nextoffnum);			/* Check for broken chains */			if (!ItemIdIsNormal(lp))				break;			htup = (HeapTupleHeader) PageGetItem(page, lp);			if (TransactionIdIsValid(priorXmax) &&				!TransactionIdEquals(priorXmax, HeapTupleHeaderGetXmin(htup)))				break;			/* Remember the root line pointer for this item */			root_offsets[nextoffnum - 1] = offnum;			/* Advance to next chain member, if any */			if (!HeapTupleHeaderIsHotUpdated(htup))				break;			nextoffnum = ItemPointerGetOffsetNumber(&htup->t_ctid);//.........这里部分代码省略.........
开发者ID:PengJi,项目名称:gpdb-comments,代码行数:101,



注:本文中的HeapTupleHeaderGetXmin函数示例整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。


C++ HeapTupleIsValid函数代码示例
C++ HeapTupleGetOid函数代码示例
万事OK自学网:51自学网_软件自学网_CAD自学网自学excel、自学PS、自学CAD、自学C语言、自学css3实例,是一个通过网络自主学习工作技能的自学平台,网友喜欢的软件自学网站。