当前位置: 首页>>代码示例>>C++>>正文


C++ VARSIZE函数代码示例

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


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

示例1: each

Datum
each(PG_FUNCTION_ARGS)
{
	FuncCallContext *funcctx;
	AKStore    *st;

	if (SRF_IS_FIRSTCALL())
	{
		TupleDesc	tupdesc;
		MemoryContext oldcontext;
		HStore	   *hs = PG_GETARG_HS(0);

		funcctx = SRF_FIRSTCALL_INIT();
		oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
		st = (AKStore *) palloc(sizeof(AKStore));
		st->i = 0;
		st->hs = (HStore *) palloc(VARSIZE(hs));
		memcpy(st->hs, hs, VARSIZE(hs));
		funcctx->user_fctx = (void *) st;

		/* 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");

		funcctx->attinmeta = TupleDescGetAttInMetadata(tupdesc);

		MemoryContextSwitchTo(oldcontext);
		PG_FREE_IF_COPY(hs, 0);
	}

	funcctx = SRF_PERCALL_SETUP();
	st = (AKStore *) funcctx->user_fctx;

	if (st->i < st->hs->size)
	{
		HEntry	   *ptr = &(ARRPTR(st->hs)[st->i]);
		Datum		res,
					dvalues[2];
		char		nulls[] = {' ', ' '};
		text	   *item;
		HeapTuple	tuple;

		item = (text *) palloc(VARHDRSZ + ptr->keylen);
		SET_VARSIZE(item, VARHDRSZ + ptr->keylen);
		memcpy(VARDATA(item), STRPTR(st->hs) + ptr->pos, ptr->keylen);
		dvalues[0] = PointerGetDatum(item);

		if (ptr->valisnull)
		{
			dvalues[1] = (Datum) 0;
			nulls[1] = 'n';
		}
		else
		{
			int			vallen = ptr->vallen;

			item = (text *) palloc(VARHDRSZ + vallen);
			SET_VARSIZE(item, VARHDRSZ + vallen);
			memcpy(VARDATA(item), STRPTR(st->hs) + ptr->pos + ptr->keylen, vallen);
			dvalues[1] = PointerGetDatum(item);
		}
		st->i++;

		tuple = heap_formtuple(funcctx->attinmeta->tupdesc, dvalues, nulls);
		res = HeapTupleGetDatum(tuple);

		pfree(DatumGetPointer(dvalues[0]));
		if (nulls[1] != 'n')
			pfree(DatumGetPointer(dvalues[1]));

		SRF_RETURN_NEXT(funcctx, res);
	}

	pfree(st->hs);
	pfree(st);

	SRF_RETURN_DONE(funcctx);
}
开发者ID:AnLingm,项目名称:gpdb,代码行数:78,代码来源:hstore_op.c

示例2: printtup_internal_20

/* ----------------
 *		printtup_internal_20 --- print a binary tuple in protocol 2.0
 *
 * We use a different message type, i.e. 'B' instead of 'D' to
 * indicate a tuple in internal (binary) form.
 *
 * This is largely same as printtup_20, except we use binary formatting.
 * ----------------
 */
static bool
printtup_internal_20(TupleTableSlot *slot, DestReceiver *self)
{
	TupleDesc	typeinfo = slot->tts_tupleDescriptor;
	DR_printtup *myState = (DR_printtup *) self;
	MemoryContext oldcontext;
	StringInfo	buf = &myState->buf;
	int			natts = typeinfo->natts;
	int			i,
				j,
				k;

	/* Set or update my derived attribute info, if needed */
	if (myState->attrinfo != typeinfo || myState->nattrs != natts)
		printtup_prepare_info(myState, typeinfo, natts);

	/* Make sure the tuple is fully deconstructed */
	slot_getallattrs(slot);

	/* Switch into per-row context so we can recover memory below */
	oldcontext = MemoryContextSwitchTo(myState->tmpcontext);

	/*
	 * tell the frontend to expect new tuple data (in binary style)
	 */
	pq_beginmessage_reuse(buf, 'B');

	/*
	 * send a bitmap of which attributes are not null
	 */
	j = 0;
	k = 1 << 7;
	for (i = 0; i < natts; ++i)
	{
		if (!slot->tts_isnull[i])
			j |= k;				/* set bit if not null */
		k >>= 1;
		if (k == 0)				/* end of byte? */
		{
			pq_sendint8(buf, j);
			j = 0;
			k = 1 << 7;
		}
	}
	if (k != (1 << 7))			/* flush last partial byte */
		pq_sendint8(buf, j);

	/*
	 * send the attributes of this tuple
	 */
	for (i = 0; i < natts; ++i)
	{
		PrinttupAttrInfo *thisState = myState->myinfo + i;
		Datum		attr = slot->tts_values[i];
		bytea	   *outputbytes;

		if (slot->tts_isnull[i])
			continue;

		Assert(thisState->format == 1);

		outputbytes = SendFunctionCall(&thisState->finfo, attr);
		pq_sendint32(buf, VARSIZE(outputbytes) - VARHDRSZ);
		pq_sendbytes(buf, VARDATA(outputbytes),
					 VARSIZE(outputbytes) - VARHDRSZ);
	}

	pq_endmessage_reuse(buf);

	/* Return to caller's context, and flush row's temporary memory */
	MemoryContextSwitchTo(oldcontext);
	MemoryContextReset(myState->tmpcontext);

	return true;
}
开发者ID:Brar,项目名称:postgres,代码行数:84,代码来源:printtup.c

示例3: heap_page_items

Datum
heap_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,代码来源:heapfuncs.c

示例4: index_form_tuple

/* ----------------
 *		index_form_tuple
 *
 *		This shouldn't leak any memory; otherwise, callers such as
 *		tuplesort_putindextuplevalues() will be very unhappy.
 * ----------------
 */
IndexTuple
index_form_tuple(TupleDesc tupleDescriptor,
				 Datum *values,
				 bool *isnull)
{
	char	   *tp;				/* tuple pointer */
	IndexTuple	tuple;			/* return tuple */
	Size		size,
				data_size,
				hoff;
	int			i;
	unsigned short infomask = 0;
	bool		hasnull = false;
	uint16		tupmask = 0;
	int			numberOfAttributes = tupleDescriptor->natts;

#ifdef TOAST_INDEX_HACK
	Datum		untoasted_values[INDEX_MAX_KEYS];
	bool		untoasted_free[INDEX_MAX_KEYS];
#endif

	if (numberOfAttributes > INDEX_MAX_KEYS)
		ereport(ERROR,
				(errcode(ERRCODE_TOO_MANY_COLUMNS),
				 errmsg("number of index columns (%d) exceeds limit (%d)",
						numberOfAttributes, INDEX_MAX_KEYS)));

#ifdef TOAST_INDEX_HACK
	for (i = 0; i < numberOfAttributes; i++)
	{
		Form_pg_attribute att = tupleDescriptor->attrs[i];

		untoasted_values[i] = values[i];
		untoasted_free[i] = false;

		/* Do nothing if value is NULL or not of varlena type */
		if (isnull[i] || att->attlen != -1)
			continue;

		/*
		 * If value is stored EXTERNAL, must fetch it so we are not depending
		 * on outside storage.  This should be improved someday.
		 */
		if (VARATT_IS_EXTERNAL(DatumGetPointer(values[i])))
		{
			untoasted_values[i] =
				PointerGetDatum(heap_tuple_fetch_attr((struct varlena *)
												DatumGetPointer(values[i])));
			untoasted_free[i] = true;
		}

		/*
		 * If value is above size target, and is of a compressible datatype,
		 * try to compress it in-line.
		 */
		if (!VARATT_IS_EXTENDED(DatumGetPointer(untoasted_values[i])) &&
		VARSIZE(DatumGetPointer(untoasted_values[i])) > TOAST_INDEX_TARGET &&
			(att->attstorage == 'x' || att->attstorage == 'm'))
		{
			Datum		cvalue = toast_compress_datum(untoasted_values[i]);

			if (DatumGetPointer(cvalue) != NULL)
			{
				/* successful compression */
				if (untoasted_free[i])
					pfree(DatumGetPointer(untoasted_values[i]));
				untoasted_values[i] = cvalue;
				untoasted_free[i] = true;
			}
		}
	}
#endif

	for (i = 0; i < numberOfAttributes; i++)
	{
		if (isnull[i])
		{
			hasnull = true;
			break;
		}
	}

	if (hasnull)
		infomask |= INDEX_NULL_MASK;

	hoff = IndexInfoFindDataOffset(infomask);
#ifdef TOAST_INDEX_HACK
	data_size = heap_compute_data_size(tupleDescriptor,
									   untoasted_values, isnull);
#else
	data_size = heap_compute_data_size(tupleDescriptor,
									   values, isnull);
#endif
//.........这里部分代码省略.........
开发者ID:ArgenBarbie,项目名称:postgresql-9.5.0,代码行数:101,代码来源:indextuple.c

示例5: geom_from_geojson

Datum geom_from_geojson(PG_FUNCTION_ARGS)
{
#ifndef HAVE_LIBJSON
	elog(ERROR, "You need JSON-C for ST_GeomFromGeoJSON");
	PG_RETURN_NULL();
#else /* HAVE_LIBJSON  */

	GSERIALIZED *geom;
	LWGEOM *lwgeom;
	text *geojson_input;
	int geojson_size;
	char *geojson;
	int root_srid=0;
	bool hasz=true;
	json_tokener* jstok = NULL;
	json_object* poObj = NULL;
	json_object* poObjSrs = NULL;

	/* Get the geojson stream */
	if (PG_ARGISNULL(0)) PG_RETURN_NULL();
	geojson_input = PG_GETARG_TEXT_P(0);
	geojson = text2cstring(geojson_input);
	geojson_size = VARSIZE(geojson_input) - VARHDRSZ;

	/* Begin to Parse json */
	jstok = json_tokener_new();
	poObj = json_tokener_parse_ex(jstok, geojson, -1);
	if( jstok->err != json_tokener_success)
	{
		char err[256];
		snprintf(err, 256, "%s (at offset %d)", json_tokener_errors[jstok->err], jstok->char_offset);
		json_tokener_free(jstok);
		geojson_lwerror(err, 1);
	}
	json_tokener_free(jstok);

	poObjSrs = findMemberByName( poObj, "crs" );
	if (poObjSrs != NULL)
	{
		json_object* poObjSrsType = findMemberByName( poObjSrs, "type" );
		if (poObjSrsType != NULL)
		{
			json_object* poObjSrsProps = findMemberByName( poObjSrs, "properties" );
			json_object* poNameURL = findMemberByName( poObjSrsProps, "name" );
			const char* pszName = json_object_get_string( poNameURL );
			root_srid = getSRIDbySRS(pszName);
			POSTGIS_DEBUGF(3, "getSRIDbySRS returned root_srid = %d.", root_srid );
		}
	}

	lwgeom = parse_geojson(poObj, &hasz, &root_srid);

	lwgeom_add_bbox(lwgeom);
	if (root_srid && lwgeom->srid == -1) lwgeom->srid = root_srid;

	if (!hasz)
	{
		LWGEOM *tmp = lwgeom_force_2d(lwgeom);
		lwgeom_free(lwgeom);
		lwgeom = tmp;

		POSTGIS_DEBUG(2, "geom_from_geojson called.");
	}

	geom = geometry_serialize(lwgeom);
	lwgeom_free(lwgeom);

	PG_RETURN_POINTER(geom);
#endif
}
开发者ID:gravitystorm,项目名称:postgis,代码行数:70,代码来源:lwgeom_in_geojson.c

示例6: toast_fetch_datum

/* ----------
 * toast_fetch_datum -
 *
 *	Reconstruct an in memory Datum from the chunks saved
 *	in the toast relation
 * ----------
 */
static struct varlena *
toast_fetch_datum(struct varlena * attr)
{
	Relation	toastrel;
	Relation	toastidx;
	ScanKeyData toastkey;
	SysScanDesc toastscan;
	HeapTuple	ttup;
	TupleDesc	toasttupDesc;
	struct varlena *result;
	struct varatt_external toast_pointer;
	int32		ressize;
	int32		residx,
				nextidx;
	int32		numchunks;
	Pointer		chunk;
	bool		isnull;
	char	   *chunkdata;
	int32		chunksize;

	/* Must copy to access aligned fields */
	VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr);

	ressize = toast_pointer.va_extsize;
	numchunks = ((ressize - 1) / TOAST_MAX_CHUNK_SIZE) + 1;

	result = (struct varlena *) palloc(ressize + VARHDRSZ);

	if (VARATT_EXTERNAL_IS_COMPRESSED(toast_pointer))
		SET_VARSIZE_COMPRESSED(result, ressize + VARHDRSZ);
	else
		SET_VARSIZE(result, ressize + VARHDRSZ);

	/*
	 * Open the toast relation and its index
	 */
	toastrel = heap_open(toast_pointer.va_toastrelid, AccessShareLock);
	toasttupDesc = toastrel->rd_att;
	toastidx = index_open(toastrel->rd_rel->reltoastidxid, AccessShareLock);

	/*
	 * Setup a scan key to fetch from the index by va_valueid
	 */
	ScanKeyInit(&toastkey,
				(AttrNumber) 1,
				BTEqualStrategyNumber, F_OIDEQ,
				ObjectIdGetDatum(toast_pointer.va_valueid));

	/*
	 * Read the chunks by index
	 *
	 * Note that because the index is actually on (valueid, chunkidx) we will
	 * see the chunks in chunkidx order, even though we didn't explicitly ask
	 * for it.
	 */
	nextidx = 0;

	toastscan = systable_beginscan_ordered(toastrel, toastidx,
										   SnapshotToast, 1, &toastkey);
	while ((ttup = systable_getnext_ordered(toastscan, ForwardScanDirection)) != NULL)
	{
		/*
		 * Have a chunk, extract the sequence number and the data
		 */
		residx = DatumGetInt32(fastgetattr(ttup, 2, toasttupDesc, &isnull));
		Assert(!isnull);
		chunk = DatumGetPointer(fastgetattr(ttup, 3, toasttupDesc, &isnull));
		Assert(!isnull);
		if (!VARATT_IS_EXTENDED(chunk))
		{
			chunksize = VARSIZE(chunk) - VARHDRSZ;
			chunkdata = VARDATA(chunk);
		}
		else if (VARATT_IS_SHORT(chunk))
		{
			/* could happen due to heap_form_tuple doing its thing */
			chunksize = VARSIZE_SHORT(chunk) - VARHDRSZ_SHORT;
			chunkdata = VARDATA_SHORT(chunk);
		}
		else
		{
			/* should never happen */
			elog(ERROR, "found toasted toast chunk for toast value %u in %s",
				 toast_pointer.va_valueid,
				 RelationGetRelationName(toastrel));
			chunksize = 0;		/* keep compiler quiet */
			chunkdata = NULL;
		}

		/*
		 * Some checks on the data we've found
		 */
		if (residx != nextidx)
//.........这里部分代码省略.........
开发者ID:Aldizh,项目名称:buffer_manager,代码行数:101,代码来源:tuptoaster.c

示例7: heap_tuple_untoast_attr_slice

/* ----------
 * heap_tuple_untoast_attr_slice -
 *
 *		Public entry point to get back part of a toasted value
 *		from compression or external storage.
 * ----------
 */
struct varlena *
heap_tuple_untoast_attr_slice(struct varlena * attr,
							  int32 sliceoffset, int32 slicelength)
{
	struct varlena *preslice;
	struct varlena *result;
	char	   *attrdata;
	int32		attrsize;

	if (VARATT_IS_EXTERNAL(attr))
	{
		struct varatt_external toast_pointer;

		VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr);

		/* fast path for non-compressed external datums */
		if (!VARATT_EXTERNAL_IS_COMPRESSED(toast_pointer))
			return toast_fetch_datum_slice(attr, sliceoffset, slicelength);

		/* fetch it back (compressed marker will get set automatically) */
		preslice = toast_fetch_datum(attr);
	}
	else
		preslice = attr;

	if (VARATT_IS_COMPRESSED(preslice))
	{
		PGLZ_Header *tmp = (PGLZ_Header *) preslice;
		Size		size = PGLZ_RAW_SIZE(tmp) + VARHDRSZ;

		preslice = (struct varlena *) palloc(size);
		SET_VARSIZE(preslice, size);
		pglz_decompress(tmp, VARDATA(preslice));

		if (tmp != (PGLZ_Header *) attr)
			pfree(tmp);
	}

	if (VARATT_IS_SHORT(preslice))
	{
		attrdata = VARDATA_SHORT(preslice);
		attrsize = VARSIZE_SHORT(preslice) - VARHDRSZ_SHORT;
	}
	else
	{
		attrdata = VARDATA(preslice);
		attrsize = VARSIZE(preslice) - VARHDRSZ;
	}

	/* slicing of datum for compressed cases and plain value */

	if (sliceoffset >= attrsize)
	{
		sliceoffset = 0;
		slicelength = 0;
	}

	if (((sliceoffset + slicelength) > attrsize) || slicelength < 0)
		slicelength = attrsize - sliceoffset;

	result = (struct varlena *) palloc(slicelength + VARHDRSZ);
	SET_VARSIZE(result, slicelength + VARHDRSZ);

	memcpy(VARDATA(result), attrdata + sliceoffset, slicelength);

	if (preslice != attr)
		pfree(preslice);

	return result;
}
开发者ID:Aldizh,项目名称:buffer_manager,代码行数:77,代码来源:tuptoaster.c

示例8: tuple_data_split

Datum
tuple_data_split(PG_FUNCTION_ARGS)
{
	Oid			relid;
	bytea	   *raw_data;
	uint16		t_infomask;
	uint16		t_infomask2;
	char	   *t_bits_str;
	bool		do_detoast = false;
	bits8	   *t_bits = NULL;
	Datum		res;

	relid = PG_GETARG_OID(0);
	raw_data = PG_ARGISNULL(1) ? NULL : PG_GETARG_BYTEA_P(1);
	t_infomask = PG_GETARG_INT16(2);
	t_infomask2 = PG_GETARG_INT16(3);
	t_bits_str = PG_ARGISNULL(4) ? NULL :
		text_to_cstring(PG_GETARG_TEXT_PP(4));

	if (PG_NARGS() >= 6)
		do_detoast = PG_GETARG_BOOL(5);

	if (!superuser())
		ereport(ERROR,
				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
				 errmsg("must be superuser to use raw page functions")));

	if (!raw_data)
		PG_RETURN_NULL();

	/*
	 * Convert t_bits string back to the bits8 array as represented in the
	 * tuple header.
	 */
	if (t_infomask & HEAP_HASNULL)
	{
		int			bits_str_len;
		int			bits_len;

		bits_len = BITMAPLEN(t_infomask2 & HEAP_NATTS_MASK) * BITS_PER_BYTE;
		if (!t_bits_str)
			ereport(ERROR,
					(errcode(ERRCODE_DATA_CORRUPTED),
					 errmsg("argument of t_bits is null, but it is expected to be null and %d character long",
							bits_len)));

		bits_str_len = strlen(t_bits_str);
		if (bits_len != bits_str_len)
			ereport(ERROR,
					(errcode(ERRCODE_DATA_CORRUPTED),
					 errmsg("unexpected length of t_bits %u, expected %d",
							bits_str_len, bits_len)));

		/* do the conversion */
		t_bits = text_to_bits(t_bits_str, bits_str_len);
	}
	else
	{
		if (t_bits_str)
			ereport(ERROR,
					(errcode(ERRCODE_DATA_CORRUPTED),
					 errmsg("t_bits string is expected to be NULL, but instead it is %zu bytes length",
							strlen(t_bits_str))));
	}

	/* Split tuple data */
	res = tuple_data_split_internal(relid, (char *) raw_data + VARHDRSZ,
									VARSIZE(raw_data) - VARHDRSZ,
									t_infomask, t_infomask2, t_bits,
									do_detoast);

	if (t_bits)
		pfree(t_bits);

	PG_RETURN_ARRAYTYPE_P(res);
}
开发者ID:adityavs,项目名称:postgres,代码行数:76,代码来源:heapfuncs.c

示例9: hstoreUpgrade

/*
 * hstoreUpgrade: PG_DETOAST_DATUM plus support for conversion of old hstores
 */
HStore *
hstoreUpgrade(Datum orig)
{
    HStore	   *hs = (HStore *) PG_DETOAST_DATUM(orig);
    int			valid_new;
    int			valid_old;
    bool		writable;

    /* Return immediately if no conversion needed */
    if ((hs->size_ & HS_FLAG_NEWVERSION) ||
            hs->size_ == 0 ||
            (VARSIZE(hs) < 32768 && HSE_ISFIRST((ARRPTR(hs)[0]))))
        return hs;

    valid_new = hstoreValidNewFormat(hs);
    valid_old = hstoreValidOldFormat(hs);
    /* Do we have a writable copy? */
    writable = ((void *) hs != (void *) DatumGetPointer(orig));

    if (!valid_old || hs->size_ == 0)
    {
        if (valid_new)
        {
            /*
             * force the "new version" flag and the correct varlena length,
             * but only if we have a writable copy already (which we almost
             * always will, since short new-format values won't come through
             * here)
             */
            if (writable)
            {
                HS_SETCOUNT(hs, HS_COUNT(hs));
                HS_FIXSIZE(hs, HS_COUNT(hs));
            }
            return hs;
        }
        else
        {
            elog(ERROR, "invalid hstore value found");
        }
    }

    /*
     * this is the tricky edge case. It is only possible in some quite extreme
     * cases (the hstore must have had a lot of wasted padding space at the
     * end). But the only way a "new" hstore value could get here is if we're
     * upgrading in place from a pre-release version of hstore-new (NOT
     * contrib/hstore), so we work off the following assumptions: 1. If you're
     * moving from old contrib/hstore to hstore-new, you're required to fix up
     * any potential conflicts first, e.g. by running ALTER TABLE ... USING
     * col::text::hstore; on all hstore columns before upgrading. 2. If you're
     * moving from old contrib/hstore to new contrib/hstore, then "new" values
     * are impossible here 3. If you're moving from pre-release hstore-new to
     * hstore-new, then "old" values are impossible here 4. If you're moving
     * from pre-release hstore-new to new contrib/hstore, you're not doing so
     * as an in-place upgrade, so there is no issue So the upshot of all this
     * is that we can treat all the edge cases as "new" if we're being built
     * as hstore-new, and "old" if we're being built as contrib/hstore.
     *
     * XXX the WARNING can probably be downgraded to DEBUG1 once this has been
     * beta-tested. But for now, it would be very useful to know if anyone can
     * actually reach this case in a non-contrived setting.
     */

    if (valid_new)
    {
#if HSTORE_IS_HSTORE_NEW
        elog(WARNING, "ambiguous hstore value resolved as hstore-new");

        /*
         * force the "new version" flag and the correct varlena length, but
         * only if we have a writable copy already (which we almost always
         * will, since short new-format values won't come through here)
         */
        if (writable)
        {
            HS_SETCOUNT(hs, HS_COUNT(hs));
            HS_FIXSIZE(hs, HS_COUNT(hs));
        }
        return hs;
#else
        elog(WARNING, "ambiguous hstore value resolved as hstore-old");
#endif
    }

    /*
     * must have an old-style value. Overwrite it in place as a new-style one,
     * making sure we have a writable copy first.
     */

    if (!writable)
        hs = (HStore *) PG_DETOAST_DATUM_COPY(orig);

    {
        int			count = hs->size_;
        HEntry	   *new_entries = ARRPTR(hs);
        HOldEntry  *old_entries = (HOldEntry *) ARRPTR(hs);
//.........这里部分代码省略.........
开发者ID:kasoku,项目名称:jpug-doc,代码行数:101,代码来源:hstore_compat.c

示例10: hstore_delete_hstore

Datum
hstore_delete_hstore(PG_FUNCTION_ARGS)
{
    HStore	   *hs = PG_GETARG_HS(0);
    HStore	   *hs2 = PG_GETARG_HS(1);
    HStore	   *out = palloc(VARSIZE(hs));
    int			hs_count = HS_COUNT(hs);
    int			hs2_count = HS_COUNT(hs2);
    char	   *ps,
               *ps2,
               *bufd,
               *pd;
    HEntry	   *es,
               *es2,
               *ed;
    int			i,
                j;
    int			outcount = 0;

    SET_VARSIZE(out, VARSIZE(hs));
    HS_SETCOUNT(out, hs_count); /* temporary! */

    ps = STRPTR(hs);
    es = ARRPTR(hs);
    ps2 = STRPTR(hs2);
    es2 = ARRPTR(hs2);
    bufd = pd = STRPTR(out);
    ed = ARRPTR(out);

    if (hs2_count == 0)
    {
        /* return a copy of the input, unchanged */
        memcpy(out, hs, VARSIZE(hs));
        HS_FIXSIZE(out, hs_count);
        HS_SETCOUNT(out, hs_count);
        PG_RETURN_POINTER(out);
    }

    /*
     * this is in effect a merge between hs and hs2, both of which are already
     * sorted by (keylen,key); we take keys from hs only; for equal keys, we
     * take the value from hs unless the values are equal
     */

    for (i = j = 0; i < hs_count;)
    {
        int			difference;

        if (j >= hs2_count)
            difference = -1;
        else
        {
            int			skeylen = HS_KEYLEN(es, i);
            int			s2keylen = HS_KEYLEN(es2, j);

            if (skeylen == s2keylen)
                difference = memcmp(HS_KEY(es, ps, i),
                                    HS_KEY(es2, ps2, j),
                                    skeylen);
            else
                difference = (skeylen > s2keylen) ? 1 : -1;
        }

        if (difference > 0)
            ++j;
        else if (difference == 0)
        {
            int			svallen = HS_VALLEN(es, i);
            int			snullval = HS_VALISNULL(es, i);

            if (snullval != HS_VALISNULL(es2, j)
                    || (!snullval
                        && (svallen != HS_VALLEN(es2, j)
                            || memcmp(HS_VAL(es, ps, i), HS_VAL(es2, ps2, j), svallen) != 0)))
            {
                HS_COPYITEM(ed, bufd, pd,
                            HS_KEY(es, ps, i), HS_KEYLEN(es, i),
                            svallen, snullval);
                ++outcount;
            }
            ++i, ++j;
        }
        else
        {
            HS_COPYITEM(ed, bufd, pd,
                        HS_KEY(es, ps, i), HS_KEYLEN(es, i),
                        HS_VALLEN(es, i), HS_VALISNULL(es, i));
            ++outcount;
            ++i;
        }
    }

    HS_FINALIZE(out, outcount, bufd, pd);

    PG_RETURN_POINTER(out);
}
开发者ID:nathanwadhwani,项目名称:recdb-postgresql,代码行数:96,代码来源:hstore_op.c

示例11: hstore_concat

Datum
hstore_concat(PG_FUNCTION_ARGS)
{
    HStore	   *s1 = PG_GETARG_HS(0);
    HStore	   *s2 = PG_GETARG_HS(1);
    HStore	   *out = palloc(VARSIZE(s1) + VARSIZE(s2));
    char	   *ps1,
               *ps2,
               *bufd,
               *pd;
    HEntry	   *es1,
               *es2,
               *ed;
    int			s1idx;
    int			s2idx;
    int			s1count = HS_COUNT(s1);
    int			s2count = HS_COUNT(s2);
    int			outcount = 0;

    SET_VARSIZE(out, VARSIZE(s1) + VARSIZE(s2) - HSHRDSIZE);
    HS_SETCOUNT(out, s1count + s2count);

    if (s1count == 0)
    {
        /* return a copy of the input, unchanged */
        memcpy(out, s2, VARSIZE(s2));
        HS_FIXSIZE(out, s2count);
        HS_SETCOUNT(out, s2count);
        PG_RETURN_POINTER(out);
    }

    if (s2count == 0)
    {
        /* return a copy of the input, unchanged */
        memcpy(out, s1, VARSIZE(s1));
        HS_FIXSIZE(out, s1count);
        HS_SETCOUNT(out, s1count);
        PG_RETURN_POINTER(out);
    }

    ps1 = STRPTR(s1);
    ps2 = STRPTR(s2);
    bufd = pd = STRPTR(out);
    es1 = ARRPTR(s1);
    es2 = ARRPTR(s2);
    ed = ARRPTR(out);

    /*
     * this is in effect a merge between s1 and s2, both of which are already
     * sorted by (keylen,key); we take s2 for equal keys
     */

    for (s1idx = s2idx = 0; s1idx < s1count || s2idx < s2count; ++outcount)
    {
        int			difference;

        if (s1idx >= s1count)
            difference = 1;
        else if (s2idx >= s2count)
            difference = -1;
        else
        {
            int			s1keylen = HS_KEYLEN(es1, s1idx);
            int			s2keylen = HS_KEYLEN(es2, s2idx);

            if (s1keylen == s2keylen)
                difference = memcmp(HS_KEY(es1, ps1, s1idx),
                                    HS_KEY(es2, ps2, s2idx),
                                    s1keylen);
            else
                difference = (s1keylen > s2keylen) ? 1 : -1;
        }

        if (difference >= 0)
        {
            HS_COPYITEM(ed, bufd, pd,
                        HS_KEY(es2, ps2, s2idx), HS_KEYLEN(es2, s2idx),
                        HS_VALLEN(es2, s2idx), HS_VALISNULL(es2, s2idx));
            ++s2idx;
            if (difference == 0)
                ++s1idx;
        }
        else
        {
            HS_COPYITEM(ed, bufd, pd,
                        HS_KEY(es1, ps1, s1idx), HS_KEYLEN(es1, s1idx),
                        HS_VALLEN(es1, s1idx), HS_VALISNULL(es1, s1idx));
            ++s1idx;
        }
    }

    HS_FINALIZE(out, outcount, bufd, pd);

    PG_RETURN_POINTER(out);
}
开发者ID:nathanwadhwani,项目名称:recdb-postgresql,代码行数:95,代码来源:hstore_op.c

示例12: hstore_delete_array

Datum
hstore_delete_array(PG_FUNCTION_ARGS)
{
    HStore	   *hs = PG_GETARG_HS(0);
    HStore	   *out = palloc(VARSIZE(hs));
    int			hs_count = HS_COUNT(hs);
    char	   *ps,
               *bufd,
               *pd;
    HEntry	   *es,
               *ed;
    int			i,
                j;
    int			outcount = 0;
    ArrayType  *key_array = PG_GETARG_ARRAYTYPE_P(1);
    int			nkeys;
    Pairs	   *key_pairs = hstoreArrayToPairs(key_array, &nkeys);

    SET_VARSIZE(out, VARSIZE(hs));
    HS_SETCOUNT(out, hs_count); /* temporary! */

    ps = STRPTR(hs);
    es = ARRPTR(hs);
    bufd = pd = STRPTR(out);
    ed = ARRPTR(out);

    if (nkeys == 0)
    {
        /* return a copy of the input, unchanged */
        memcpy(out, hs, VARSIZE(hs));
        HS_FIXSIZE(out, hs_count);
        HS_SETCOUNT(out, hs_count);
        PG_RETURN_POINTER(out);
    }

    /*
     * this is in effect a merge between hs and key_pairs, both of which are
     * already sorted by (keylen,key); we take keys from hs only
     */

    for (i = j = 0; i < hs_count;)
    {
        int			difference;

        if (j >= nkeys)
            difference = -1;
        else
        {
            int			skeylen = HS_KEYLEN(es, i);

            if (skeylen == key_pairs[j].keylen)
                difference = memcmp(HS_KEY(es, ps, i),
                                    key_pairs[j].key,
                                    key_pairs[j].keylen);
            else
                difference = (skeylen > key_pairs[j].keylen) ? 1 : -1;
        }

        if (difference > 0)
            ++j;
        else if (difference == 0)
            ++i, ++j;
        else
        {
            HS_COPYITEM(ed, bufd, pd,
                        HS_KEY(es, ps, i), HS_KEYLEN(es, i),
                        HS_VALLEN(es, i), HS_VALISNULL(es, i));
            ++outcount;
            ++i;
        }
    }

    HS_FINALIZE(out, outcount, bufd, pd);

    PG_RETURN_POINTER(out);
}
开发者ID:nathanwadhwani,项目名称:recdb-postgresql,代码行数:76,代码来源:hstore_op.c

示例13: printtup_internal_20

/* ----------------
 *		printtup_internal_20 --- print a binary tuple in protocol 2.0
 *
 * We use a different message type, i.e. 'B' instead of 'D' to
 * indicate a tuple in internal (binary) form.
 *
 * This is largely same as printtup_20, except we use binary formatting.
 * ----------------
 */
static void
printtup_internal_20(TupleTableSlot *slot, DestReceiver *self)
{
	TupleDesc	typeinfo = slot->tts_tupleDescriptor;
	DR_printtup *myState = (DR_printtup *) self;
	StringInfoData buf;
	int			natts = typeinfo->natts;
	int			i,
				j,
				k;

	/* Set or update my derived attribute info, if needed */
	if (myState->attrinfo != typeinfo || myState->nattrs != natts)
		printtup_prepare_info(myState, typeinfo, natts);

	/* Make sure the tuple is fully deconstructed */
	slot_getallattrs(slot);

	/*
	 * tell the frontend to expect new tuple data (in binary style)
	 */
	pq_beginmessage(&buf, 'B');

	/*
	 * send a bitmap of which attributes are not null
	 */
	j = 0;
	k = 1 << 7;
	for (i = 0; i < natts; ++i)
	{
		if (!slot->tts_isnull[i])
			j |= k;				/* set bit if not null */
		k >>= 1;
		if (k == 0)				/* end of byte? */
		{
			pq_sendint(&buf, j, 1);
			j = 0;
			k = 1 << 7;
		}
	}
	if (k != (1 << 7))			/* flush last partial byte */
		pq_sendint(&buf, j, 1);

	/*
	 * send the attributes of this tuple
	 */
	for (i = 0; i < natts; ++i)
	{
		PrinttupAttrInfo *thisState = myState->myinfo + i;
		Datum		origattr = slot->tts_values[i],
					attr;
		bytea	   *outputbytes;

		if (slot->tts_isnull[i])
			continue;

		Assert(thisState->format == 1);

		/*
		 * If we have a toasted datum, forcibly detoast it here to avoid
		 * memory leakage inside the type's output routine.
		 */
		if (thisState->typisvarlena)
			attr = PointerGetDatum(PG_DETOAST_DATUM(origattr));
		else
			attr = origattr;

		outputbytes = SendFunctionCall(&thisState->finfo, attr);
		/* We assume the result will not have been toasted */
		pq_sendint(&buf, VARSIZE(outputbytes) - VARHDRSZ, 4);
		pq_sendbytes(&buf, VARDATA(outputbytes),
					 VARSIZE(outputbytes) - VARHDRSZ);
		pfree(outputbytes);

		/* Clean up detoasted copy, if any */
		if (DatumGetPointer(attr) != DatumGetPointer(origattr))
			pfree(DatumGetPointer(attr));
	}

	pq_endmessage(&buf);
}
开发者ID:Yuan-Yuan,项目名称:postgresql-GPU,代码行数:90,代码来源:printtup.c

示例14: printtup

/* ----------------
 *		printtup --- print a tuple in protocol 3.0
 * ----------------
 */
static void
printtup(TupleTableSlot *slot, DestReceiver *self)
{
	TupleDesc	typeinfo = slot->tts_tupleDescriptor;
	DR_printtup *myState = (DR_printtup *) self;
	StringInfoData buf;
	int			natts = typeinfo->natts;
	int			i;

	/* Set or update my derived attribute info, if needed */
	if (myState->attrinfo != typeinfo || myState->nattrs != natts)
		printtup_prepare_info(myState, typeinfo, natts);

	/* Make sure the tuple is fully deconstructed */
	slot_getallattrs(slot);

	/*
	 * Prepare a DataRow message
	 */
	pq_beginmessage(&buf, 'D');

	pq_sendint(&buf, natts, 2);

	/*
	 * send the attributes of this tuple
	 */
	for (i = 0; i < natts; ++i)
	{
		PrinttupAttrInfo *thisState = myState->myinfo + i;
		Datum		origattr = slot->tts_values[i],
					attr;

		if (slot->tts_isnull[i])
		{
			pq_sendint(&buf, -1, 4);
			continue;
		}

		/*
		 * If we have a toasted datum, forcibly detoast it here to avoid
		 * memory leakage inside the type's output routine.
		 */
		if (thisState->typisvarlena)
			attr = PointerGetDatum(PG_DETOAST_DATUM(origattr));
		else
			attr = origattr;

		if (thisState->format == 0)
		{
			/* Text output */
			char	   *outputstr;

			outputstr = OutputFunctionCall(&thisState->finfo, attr);
			pq_sendcountedtext(&buf, outputstr, strlen(outputstr), false);
			pfree(outputstr);
		}
		else
		{
			/* Binary output */
			bytea	   *outputbytes;

			outputbytes = SendFunctionCall(&thisState->finfo, attr);
			pq_sendint(&buf, VARSIZE(outputbytes) - VARHDRSZ, 4);
			pq_sendbytes(&buf, VARDATA(outputbytes),
						 VARSIZE(outputbytes) - VARHDRSZ);
			pfree(outputbytes);
		}

		/* Clean up detoasted copy, if any */
		if (DatumGetPointer(attr) != DatumGetPointer(origattr))
			pfree(DatumGetPointer(attr));
	}

	pq_endmessage(&buf);
}
开发者ID:Yuan-Yuan,项目名称:postgresql-GPU,代码行数:79,代码来源:printtup.c

示例15: xmlnode_to_xmldoc

Datum
xmlnode_to_xmldoc(PG_FUNCTION_ARGS)
{
	XMLCompNodeHdr rootNode,
				rootDoc;
	unsigned int sizeNew,
				dataSizeNew;
	xmlnode		node = (xmlnode) PG_GETARG_VARLENA_P(0);
	xmldoc		document = NULL;
	char	   *docData;
	unsigned int sizeOrig = VARSIZE(node);
	unsigned int dataSizeOrig = sizeOrig - VARHDRSZ;
	char	   *nodeData = (char *) VARDATA(node);

	/*
	 * The new root will start where last value of the array (i.e. offset of
	 * the current root) was so far
	 */
	XMLNodeOffset rootOffsetNew = dataSizeOrig - sizeof(XMLNodeOffset);

	/* Find that 'old last (root offset) value' ... */
	XMLNodeOffset *rootOffPtrOrig = (XMLNodeOffset *) (nodeData + rootOffsetNew);

	/* ... and read it */
	XMLNodeOffset rootOffsetOrig = *rootOffPtrOrig;

	/*
	 * Compute 'relative reference' of the 'old root' that the document ('new
	 * root') will remember
	 */
	XMLNodeOffset dist = rootOffsetNew - rootOffsetOrig;
	XMLNodeOffset *rootOffPtrNew;

	char		bwidth = getXMLNodeOffsetByteWidth(dist);

	rootNode = (XMLCompNodeHdr) (nodeData + rootOffsetOrig);
	if (rootNode->common.kind == XMLNODE_ELEMENT)
	{
		/*
		 * If document should contain only one node, it must be element. See
		 * http://www.w3.org/TR/2008/REC-xml-20081126/#NT-document
		 */
		char	   *refTargPtr;

		sizeNew = sizeOrig + sizeof(XMLCompNodeHdrData) + bwidth;
		dataSizeNew = sizeNew - VARHDRSZ;
		document = (xmldoc) palloc(sizeNew);
		docData = (char *) VARDATA(document);
		memcpy(docData, nodeData, rootOffsetNew);
		rootDoc = (XMLCompNodeHdr) (docData + rootOffsetNew);
		rootDoc->common.kind = XMLNODE_DOC;
		rootDoc->common.flags = 0;
		XNODE_SET_REF_BWIDTH(rootDoc, bwidth);
		rootDoc->children = 1;
		refTargPtr = (char *) rootDoc + sizeof(XMLCompNodeHdrData);
		writeXMLNodeOffset(dist, &refTargPtr, bwidth, false);
		rootOffPtrNew = (XMLNodeOffset *) (docData + dataSizeNew - sizeof(XMLNodeOffset));
		*rootOffPtrNew = rootOffsetNew;
		SET_VARSIZE(document, sizeNew);
	}
	else if (rootNode->common.kind == XMLNODE_DOC_FRAGMENT)
	{
		checkXMLWellFormedness(rootNode);
		document = (xmldoc) palloc(sizeOrig);
		docData = (char *) VARDATA(document);
		memcpy(document, node, sizeOrig);
		rootDoc = (XMLCompNodeHdr) (docData + rootOffsetOrig);
		rootDoc->common.kind = XMLNODE_DOC;
		SET_VARSIZE(document, sizeOrig);
	}
	else
	{
		elog(ERROR, "%s can't be cast to XML document", getXMLNodeKindStr(rootNode->common.kind));
	}
	PG_RETURN_POINTER(document);
}
开发者ID:andreypopp,项目名称:pg_xnode,代码行数:76,代码来源:xmlnode.c


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