本文整理汇总了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);
}
示例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;
}
示例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);
//.........这里部分代码省略.........
示例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
//.........这里部分代码省略.........
示例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
}
示例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)
//.........这里部分代码省略.........
示例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;
}
示例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);
}
示例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);
//.........这里部分代码省略.........
示例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);
}
示例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);
}
示例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);
}
示例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);
}
示例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);
}
示例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);
}