Пример #1
0
/*
 * Returns true iff there are entries stored for the
 * given segment file num.
 */ 
bool
AppendOnlyVisimapStore_IsSegmentFileFullyVisible(
	AppendOnlyVisimapStore *visiMapStore,
	int segmentFileNum)
{
	ScanKeyData scanKey;
	IndexScanDesc indexScan;
	bool found_visimap_entry;

	Assert(visiMapStore);
	Assert(RelationIsValid(visiMapStore->visimapRelation));
	Assert(RelationIsValid(visiMapStore->visimapIndex));
	
	ScanKeyInit(&scanKey,
			Anum_pg_aovisimap_segno, /* segno */
			BTEqualStrategyNumber,
			F_INT4EQ,
			Int32GetDatum(segmentFileNum));

	indexScan = AppendOnlyVisimapStore_BeginScan(
			visiMapStore,
			1,
			&scanKey);
	
	found_visimap_entry = AppendOnlyVisimapStore_GetNext(
			visiMapStore,
			indexScan,
			ForwardScanDirection,
			NULL, NULL);
	AppendOnlyVisimapStore_EndScan(visiMapStore, indexScan);
	return !found_visimap_entry;
}
Пример #2
0
/*
 * Returns the number of hidden tuples in a given releation
 */ 
int64
AppendOnlyVisimapStore_GetRelationHiddenTupleCount(
	AppendOnlyVisimapStore *visiMapStore,
	AppendOnlyVisimapEntry *visiMapEntry)
{
	IndexScanDesc indexScan;
	int64 hiddenTupcount = 0;

	Assert(visiMapStore);
	Assert(visiMapEntry);
	Assert(RelationIsValid(visiMapStore->visimapRelation));
	Assert(RelationIsValid(visiMapStore->visimapIndex));
	
	indexScan = AppendOnlyVisimapStore_BeginScan(
			visiMapStore,
			0,
			NULL);
	
	while (AppendOnlyVisimapStore_GetNext(visiMapStore,
		indexScan, ForwardScanDirection,
		visiMapEntry, NULL))
	{
		hiddenTupcount += AppendOnlyVisimapEntry_GetHiddenTupleCount(visiMapEntry);
	}
	AppendOnlyVisimapStore_EndScan(visiMapStore, indexScan);
	return hiddenTupcount;
}
Пример #3
0
/*
 * Returns the number of hidden tuples in a given segment file
 */ 
int64
AppendOnlyVisimapStore_GetSegmentFileHiddenTupleCount(
	AppendOnlyVisimapStore *visiMapStore,
	AppendOnlyVisimapEntry *visiMapEntry,
	int segmentFileNum)
{
	ScanKeyData scanKey;
	IndexScanDesc indexScan;
	int64 hiddenTupcount = 0;

	Assert(visiMapStore);
	Assert(visiMapEntry);
	Assert(RelationIsValid(visiMapStore->visimapRelation));
	Assert(RelationIsValid(visiMapStore->visimapIndex));
	
	ScanKeyInit(&scanKey,
			Anum_pg_aovisimap_segno, /* segno */
			BTEqualStrategyNumber,
			F_INT4EQ,
			Int32GetDatum(segmentFileNum));

	indexScan = AppendOnlyVisimapStore_BeginScan(
			visiMapStore,
			1,
			&scanKey);
	
	while (AppendOnlyVisimapStore_GetNext(visiMapStore,
		indexScan, ForwardScanDirection,
		visiMapEntry, NULL))
	{
		hiddenTupcount += AppendOnlyVisimapEntry_GetHiddenTupleCount(visiMapEntry);
	}
	AppendOnlyVisimapStore_EndScan(visiMapStore, indexScan);
	return hiddenTupcount;
}
Пример #4
0
/**
 * Finds the visibility map entry tuple for a given
 * segmentFileNum and firstRowNum.
 *
 * Note: The firstRowNum needs to be a valid firstRowNum. It is
 * especially not the tuple id of the append-only tuple checked, updated, 
 * or deleted.
 *
 * Returns true if there is such a tuple and
 * the tuple is used as current tuple.
 * Otherwise false is returned.
 *
 * Assumes that the store data structure has been initialized, but not finished.
 */
bool
AppendOnlyVisimapStore_Find(
		AppendOnlyVisimapStore* visiMapStore,
		int32 segmentFileNum,
		int64 firstRowNum,
		AppendOnlyVisimapEntry* visiMapEntry)
{
	ScanKey scanKeys;
	IndexScanDesc indexScan;

	Assert(visiMapStore);
	Assert(visiMapEntry);
	Assert(RelationIsValid(visiMapStore->visimapRelation));
	Assert(RelationIsValid(visiMapStore->visimapIndex));
	
	elogif (Debug_appendonly_print_visimap, LOG, 
			"Append-only visi map store: Load entry: "
			"(segFileNum, firstRowNum) = (%u, " INT64_FORMAT ")",
			segmentFileNum, firstRowNum);

	scanKeys = visiMapStore->scanKeys;
	scanKeys[0].sk_argument = Int32GetDatum(segmentFileNum);
	scanKeys[1].sk_argument = Int64GetDatum(firstRowNum);

	indexScan = AppendOnlyVisimapStore_BeginScan(
			visiMapStore,
			APPENDONLY_VISIMAP_INDEX_SCAN_KEY_NUM,
			scanKeys);

	if (!AppendOnlyVisimapStore_GetNext(
				visiMapStore,
				indexScan,
				BackwardScanDirection,
				visiMapEntry,
				&visiMapEntry->tupleTid))
	{
		elogif(Debug_appendonly_print_visimap, LOG, 
				"Append-only visi map store: Visimap entry does not exist: "
				"(segFileNum, firstRowNum) = (%u, " INT64_FORMAT ")",
				segmentFileNum, firstRowNum);
		
		// failed to lookup row
		AppendOnlyVisimapStore_EndScan(visiMapStore, indexScan);
		return false;
	}
	AppendOnlyVisimapStore_EndScan(visiMapStore, indexScan);
	return true;
}
Пример #5
0
/*
 * Deletes all visibility map information from a given
 * segment file.
 */ 
void
AppendOnlyVisimapStore_DeleteSegmentFile(
	AppendOnlyVisimapStore *visiMapStore,
	int segmentFileNum)
{
	ScanKeyData scanKey;
	IndexScanDesc indexScan;
	ItemPointerData tid;

	Assert(visiMapStore);
	Assert(RelationIsValid(visiMapStore->visimapRelation));
	Assert(RelationIsValid(visiMapStore->visimapIndex));
	
	elogif(Debug_appendonly_print_visimap, LOG, 
			"Append-only visi map store: Delete segment file: "
			"(segFileNum) = (%u)", segmentFileNum);

	ScanKeyInit(&scanKey,
			Anum_pg_aovisimap_segno, /* segno */
			BTEqualStrategyNumber,
			F_INT4EQ,
			Int32GetDatum(segmentFileNum));

	indexScan = AppendOnlyVisimapStore_BeginScan(
			visiMapStore,
			1,
			&scanKey);

	while (AppendOnlyVisimapStore_GetNext(visiMapStore,
				indexScan,
				ForwardScanDirection,
				NULL,
				&tid))
	{
		simple_heap_delete(visiMapStore->visimapRelation,
				&tid);
	}
	AppendOnlyVisimapStore_EndScan(visiMapStore, indexScan);
}
Пример #6
0
/*
 * Returns true iff there are entries of the relation are visible
 */ 
bool
AppendOnlyVisimapStore_IsRelationFullyVisible(
	AppendOnlyVisimapStore *visiMapStore)
{
	IndexScanDesc indexScan;
	bool found_visimap_entry;

	Assert(visiMapStore);
	Assert(RelationIsValid(visiMapStore->visimapRelation));
	Assert(RelationIsValid(visiMapStore->visimapIndex));
	
	indexScan = AppendOnlyVisimapStore_BeginScan(
			visiMapStore,
			0,
			NULL);
	found_visimap_entry = AppendOnlyVisimapStore_GetNext(
			visiMapStore,
			indexScan,
			ForwardScanDirection,
			NULL, NULL);
	AppendOnlyVisimapStore_EndScan(visiMapStore, indexScan);
	return !found_visimap_entry;
}
Пример #7
0
static Datum
gp_aovisimap_entry_internal(PG_FUNCTION_ARGS, Oid aoRelOid)
{
	Datum		values[4];
	bool		nulls[4];
	HeapTuple tuple;
	Datum result;

	typedef struct Context
	{
		AppendOnlyVisimap visiMap;

		Relation parentRelation;

		IndexScanDesc indexScan;

		text *bitmapBuffer;
	} Context;
	
	FuncCallContext *funcctx;
	Context *context;

	if (SRF_IS_FIRSTCALL())
	{
		TupleDesc	tupdesc;
		MemoryContext oldcontext;
		
		/* create a function context for cross-call persistence */
		funcctx = SRF_FIRSTCALL_INIT();

		/*
		 * switch to memory context appropriate for multiple function
		 * calls
		 */
		oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);

		/* build tupdesc for result tuples */
		tupdesc = CreateTemplateTupleDesc(4, false);
		TupleDescInitEntry(tupdesc, (AttrNumber) 1, "segno",
						   INT4OID, -1, 0);
		TupleDescInitEntry(tupdesc, (AttrNumber) 2, "first_row_num",
						   INT8OID, -1, 0);
		TupleDescInitEntry(tupdesc, (AttrNumber) 3, "hidden_tupcount",
						   INT4OID, -1, 0);
		TupleDescInitEntry(tupdesc, (AttrNumber) 4, "bitmap",
						   TEXTOID, -1, 0);

		funcctx->tuple_desc = BlessTupleDesc(tupdesc);

		/*
		 * Collect all the locking information that we will format and send
		 * out as a result set.
		 */
		context = (Context *) palloc0(sizeof(Context));

		context->parentRelation = heap_open(aoRelOid, AccessShareLock);
		if (!(RelationIsAoRows(context->parentRelation) || RelationIsAoCols(context->parentRelation)))
		{
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
					 errmsg("Function not supported on relation")));
		}

		AppendOnlyVisimap_Init(&context->visiMap,
				context->parentRelation->rd_appendonly->visimaprelid,
				context->parentRelation->rd_appendonly->visimapidxid,
				AccessShareLock,
				SnapshotNow);

		context->indexScan = AppendOnlyVisimapStore_BeginScan(&
			context->visiMap.visimapStore, 0, NULL);

		context->bitmapBuffer = palloc0(VARHDRSZ + APPENDONLY_VISIMAP_MAX_RANGE + 1);

		funcctx->user_fctx = (void *) context;

		MemoryContextSwitchTo(oldcontext);
	}

	funcctx = SRF_PERCALL_SETUP();
	context = (Context *) funcctx->user_fctx;

	if (AppendOnlyVisimapStore_GetNext(&context->visiMap.visimapStore,
				context->indexScan,
				ForwardScanDirection,
				&context->visiMap.visimapEntry,
				NULL))
	{
		AppendOnlyVisimapEntry *visimapEntry = &context->visiMap.visimapEntry;

		MemSet(values, 0, sizeof(values));
		MemSet(nulls, false, sizeof(nulls));
		values[0] = Int32GetDatum(visimapEntry->segmentFileNum);
		values[1] = Int64GetDatum(visimapEntry->firstRowNum);
		values[2] = Int32GetDatum(
				(int32)AppendOnlyVisimapEntry_GetHiddenTupleCount(visimapEntry));
		
		gp_aovisimap_encode_bitmap(VARDATA(context->bitmapBuffer), 
				visimapEntry->bitmap);
		SET_VARSIZE(context->bitmapBuffer, APPENDONLY_VISIMAP_MAX_RANGE);
		values[3] = PointerGetDatum(context->bitmapBuffer);

		tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
		result = HeapTupleGetDatum(tuple);

		SRF_RETURN_NEXT(funcctx, result);
	}
	
	AppendOnlyVisimapStore_EndScan(&context->visiMap.visimapStore,
			context->indexScan);
	AppendOnlyVisimap_Finish(&context->visiMap, AccessShareLock);
	heap_close(context->parentRelation, AccessShareLock);

	pfree(context->bitmapBuffer);
	pfree(context);
	funcctx->user_fctx = NULL;

	SRF_RETURN_DONE(funcctx);
}