本文整理匯總了C++中DatumGetPointer函數的典型用法代碼示例。如果您正苦於以下問題:C++ DatumGetPointer函數的具體用法?C++ DatumGetPointer怎麽用?C++ DatumGetPointer使用的例子?那麽, 這裏精選的函數代碼示例或許可以為您提供幫助。
在下文中一共展示了DatumGetPointer函數的15個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的C++代碼示例。
示例1: heap_fill_tuple
/*
* heap_fill_tuple
* Load data portion of a tuple from values/isnull arrays
*
* We also fill the null bitmap (if any) and set the infomask bits
* that reflect the tuple's data contents.
*
* NOTE: it is now REQUIRED that the caller have pre-zeroed the data area.
*/
void
heap_fill_tuple(TupleDesc tupleDesc,
Datum *values, bool *isnull,
char *data, Size data_size,
uint16 *infomask, bits8 *bit)
{
bits8 *bitP;
int bitmask;
int i;
int numberOfAttributes = tupleDesc->natts;
Form_pg_attribute *att = tupleDesc->attrs;
#ifdef USE_ASSERT_CHECKING
char *start = data;
#endif
if (bit != NULL)
{
bitP = &bit[-1];
bitmask = HIGHBIT;
}
else
{
/* just to keep compiler quiet */
bitP = NULL;
bitmask = 0;
}
*infomask &= ~(HEAP_HASNULL | HEAP_HASVARWIDTH | HEAP_HASEXTERNAL);
for (i = 0; i < numberOfAttributes; i++)
{
Size data_length;
if (bit != NULL)
{
if (bitmask != HIGHBIT)
bitmask <<= 1;
else
{
bitP += 1;
*bitP = 0x0;
bitmask = 1;
}
if (isnull[i])
{
*infomask |= HEAP_HASNULL;
continue;
}
*bitP |= bitmask;
}
/*
* XXX we use the att_align macros on the pointer value itself, not on
* an offset. This is a bit of a hack.
*/
if (att[i]->attbyval)
{
/* pass-by-value */
data = (char *) att_align_nominal(data, att[i]->attalign);
store_att_byval(data, values[i], att[i]->attlen);
data_length = att[i]->attlen;
}
else if (att[i]->attlen == -1)
{
/* varlena */
Pointer val = DatumGetPointer(values[i]);
*infomask |= HEAP_HASVARWIDTH;
if (VARATT_IS_EXTERNAL(val))
{
*infomask |= HEAP_HASEXTERNAL;
/* no alignment, since it's short by definition */
data_length = VARSIZE_EXTERNAL(val);
memcpy(data, val, data_length);
}
else if (VARATT_IS_SHORT(val))
{
/* no alignment for short varlenas */
data_length = VARSIZE_SHORT(val);
memcpy(data, val, data_length);
}
else if (VARLENA_ATT_IS_PACKABLE(att[i]) &&
VARATT_CAN_MAKE_SHORT(val))
{
/* convert to short varlena -- no alignment */
data_length = VARATT_CONVERTED_SHORT_SIZE(val);
SET_VARSIZE_SHORT(data, data_length);
//.........這裏部分代碼省略.........
示例2: compileTheSubstitute
static void
compileTheSubstitute(DictThesaurus *d)
{
int i;
for (i = 0; i < d->nsubst; i++)
{
TSLexeme *rem = d->subst[i].res,
*outptr,
*inptr;
int n = 2;
outptr = d->subst[i].res = (TSLexeme *) palloc(sizeof(TSLexeme) * n);
outptr->lexeme = NULL;
inptr = rem;
while (inptr && inptr->lexeme)
{
TSLexeme *lexized,
tmplex[2];
if (inptr->flags & DT_USEASIS)
{ /* do not lexize */
tmplex[0] = *inptr;
tmplex[0].flags = 0;
tmplex[1].lexeme = NULL;
lexized = tmplex;
}
else
{
lexized = (TSLexeme *) DatumGetPointer(
FunctionCall4(
&(d->subdict->lexize),
PointerGetDatum(d->subdict->dictData),
PointerGetDatum(inptr->lexeme),
Int32GetDatum(strlen(inptr->lexeme)),
PointerGetDatum(NULL)
)
);
}
if (lexized && lexized->lexeme)
{
int toset = (lexized->lexeme && outptr != d->subst[i].res) ? (outptr - d->subst[i].res) : -1;
while (lexized->lexeme)
{
if (outptr - d->subst[i].res + 1 >= n)
{
int diff = outptr - d->subst[i].res;
n *= 2;
d->subst[i].res = (TSLexeme *) repalloc(d->subst[i].res, sizeof(TSLexeme) * n);
outptr = d->subst[i].res + diff;
}
*outptr = *lexized;
outptr->lexeme = pstrdup(lexized->lexeme);
outptr++;
lexized++;
}
if (toset > 0)
d->subst[i].res[toset].flags |= TSL_ADDPOS;
}
else if (lexized)
{
ereport(ERROR,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("thesaurus substitute word \"%s\" is a stop word (rule %d)",
inptr->lexeme, i + 1)));
}
else
{
ereport(ERROR,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("thesaurus substitute word \"%s\" isn't recognized by subdictionary (rule %d)",
inptr->lexeme, i + 1)));
}
if (inptr->lexeme)
pfree(inptr->lexeme);
inptr++;
}
if (outptr == d->subst[i].res)
ereport(ERROR,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("thesaurus substitute phrase is empty (rule %d)",
i + 1)));
d->subst[i].reslen = outptr - d->subst[i].res;
pfree(rem);
}
}
示例3: TidListCreate
/*
* Compute the list of TIDs to be visited, by evaluating the expressions
* for them.
*
* (The result is actually an array, not a list.)
*/
static void
TidListCreate(TidScanState *tidstate)
{
List *evalList = tidstate->tss_tidquals;
ExprContext *econtext = tidstate->ss.ps.ps_ExprContext;
BlockNumber nblocks;
ItemPointerData *tidList;
int numAllocTids;
int numTids;
ListCell *l;
/*
* We silently discard any TIDs that are out of range at the time of scan
* start. (Since we hold at least AccessShareLock on the table, it won't
* be possible for someone to truncate away the blocks we intend to
* visit.)
*/
nblocks = RelationGetNumberOfBlocks(tidstate->ss.ss_currentRelation);
/*
* We initialize the array with enough slots for the case that all quals
* are simple OpExprs or CurrentOfExprs. If there are any
* ScalarArrayOpExprs, we may have to enlarge the array.
*/
numAllocTids = list_length(evalList);
tidList = (ItemPointerData *)
palloc(numAllocTids * sizeof(ItemPointerData));
numTids = 0;
tidstate->tss_isCurrentOf = false;
foreach(l, evalList)
{
ExprState *exstate = (ExprState *) lfirst(l);
Expr *expr = exstate->expr;
ItemPointer itemptr;
bool isNull;
if (is_opclause(expr))
{
FuncExprState *fexstate = (FuncExprState *) exstate;
Node *arg1;
Node *arg2;
arg1 = get_leftop(expr);
arg2 = get_rightop(expr);
if (IsCTIDVar(arg1))
exstate = (ExprState *) lsecond(fexstate->args);
else if (IsCTIDVar(arg2))
exstate = (ExprState *) linitial(fexstate->args);
else
elog(ERROR, "could not identify CTID variable");
itemptr = (ItemPointer)
DatumGetPointer(ExecEvalExprSwitchContext(exstate,
econtext,
&isNull,
NULL));
if (!isNull &&
ItemPointerIsValid(itemptr) &&
ItemPointerGetBlockNumber(itemptr) < nblocks)
{
if (numTids >= numAllocTids)
{
numAllocTids *= 2;
tidList = (ItemPointerData *)
repalloc(tidList,
numAllocTids * sizeof(ItemPointerData));
}
tidList[numTids++] = *itemptr;
}
}
else if (expr && IsA(expr, ScalarArrayOpExpr))
{
ScalarArrayOpExprState *saexstate = (ScalarArrayOpExprState *) exstate;
Datum arraydatum;
ArrayType *itemarray;
Datum *ipdatums;
bool *ipnulls;
int ndatums;
int i;
exstate = (ExprState *) lsecond(saexstate->fxprstate.args);
arraydatum = ExecEvalExprSwitchContext(exstate,
econtext,
&isNull,
NULL);
if (isNull)
continue;
itemarray = DatumGetArrayTypeP(arraydatum);
deconstruct_array(itemarray,
TIDOID, SizeOfIptrData, false, 's',
&ipdatums, &ipnulls, &ndatums);
if (numTids + ndatums > numAllocTids)
{
//.........這裏部分代碼省略.........
示例4: SerializeTupleIntoChunks
//.........這裏部分代碼省略.........
/*
* send the attributes of this tuple: NOTE anything which allocates
* temporary space (e.g. could result in a PG_DETOAST_DATUM) should be
* executed with the memory context set to s_tupSerMemCtxt
*/
for (i = 0; i < natts; ++i)
{
SerAttrInfo *attrInfo = pSerInfo->myinfo + i;
Datum origattr = pSerInfo->values[i],
attr;
/* skip null attributes (already taken care of above) */
if (pSerInfo->nulls[i])
continue;
if (attrInfo->typlen == -1)
{
int32 sz;
char *data;
/*
* If we have a toasted datum, forcibly detoast it here to avoid
* memory leakage: we want to force the detoast allocation(s) to
* happen in our reset-able serialization context.
*/
oldCtxt = MemoryContextSwitchTo(s_tupSerMemCtxt);
attr = PointerGetDatum(PG_DETOAST_DATUM_PACKED(origattr));
MemoryContextSwitchTo(oldCtxt);
sz = VARSIZE_ANY_EXHDR(attr);
data = VARDATA_ANY(attr);
/* Send length first, then data */
addInt32ToChunkList(tcList, sz, &pSerInfo->chunkCache);
addByteStringToChunkList(tcList, data, sz, &pSerInfo->chunkCache);
addPadding(tcList, &pSerInfo->chunkCache, sz);
}
else if (attrInfo->typlen == -2)
{
int32 sz;
char *data;
/* CString, we would send the string with the terminating '\0' */
data = DatumGetCString(origattr);
sz = strlen(data) + 1;
/* Send length first, then data */
addInt32ToChunkList(tcList, sz, &pSerInfo->chunkCache);
addByteStringToChunkList(tcList, data, sz, &pSerInfo->chunkCache);
addPadding(tcList, &pSerInfo->chunkCache, sz);
}
else if (attrInfo->typbyval)
{
/*
* We send a full-width Datum for all pass-by-value types, regardless of
* the actual size.
*/
addByteStringToChunkList(tcList, (char *) &origattr, sizeof(Datum), &pSerInfo->chunkCache);
addPadding(tcList, &pSerInfo->chunkCache, sizeof(Datum));
}
else
{
addByteStringToChunkList(tcList, DatumGetPointer(origattr), attrInfo->typlen, &pSerInfo->chunkCache);
addPadding(tcList, &pSerInfo->chunkCache, attrInfo->typlen);
attr = origattr;
}
}
MemoryContextReset(s_tupSerMemCtxt);
}
}
/*
* if we have more than 1 chunk we have to set the chunk types on our
* first chunk and last chunk
*/
if (tcList->num_chunks > 1)
{
TupleChunkListItem first,
last;
first = tcList->p_first;
last = tcList->p_last;
Assert(first != NULL);
Assert(first != last);
Assert(last != NULL);
SetChunkType(first->chunk_data, TC_PARTIAL_START);
SetChunkType(last->chunk_data, TC_PARTIAL_END);
/*
* any intervening chunks are already set to TC_PARTIAL_MID when
* allocated
*/
}
return;
}
示例5: 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;
/* Return immediately if no conversion needed */
if (hs->size_ & HS_FLAG_NEWVERSION)
return hs;
/* Do we have a writable copy? If not, make one. */
if ((void *) hs == (void *) DatumGetPointer(orig))
hs = (HStore *) PG_DETOAST_DATUM_COPY(orig);
if (hs->size_ == 0 ||
(VARSIZE(hs) < 32768 && HSE_ISFIRST((ARRPTR(hs)[0]))))
{
HS_SETCOUNT(hs, HS_COUNT(hs));
HS_FIXSIZE(hs, HS_COUNT(hs));
return hs;
}
valid_new = hstoreValidNewFormat(hs);
valid_old = hstoreValidOldFormat(hs);
if (!valid_old || hs->size_ == 0)
{
if (valid_new)
{
/*
* force the "new version" flag and the correct varlena length.
*/
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.
*/
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.
*/
{
int count = hs->size_;
HEntry *new_entries = ARRPTR(hs);
HOldEntry *old_entries = (HOldEntry *) ARRPTR(hs);
int i;
for (i = 0; i < count; ++i)
{
uint32 pos = old_entries[i].pos;
uint32 keylen = old_entries[i].keylen;
uint32 vallen = old_entries[i].vallen;
bool isnull = old_entries[i].valisnull;
//.........這裏部分代碼省略.........
示例6: _numeric_weighted_stddev_samp_intermediate
Datum
_numeric_weighted_stddev_samp_intermediate(PG_FUNCTION_ARGS)
{
WeightedStddevSampInternalState *state;
Datum value,
weight,
old_s_0,
old_s_1,
old_s_2,
w_v,
w_v2;
MemoryContext aggcontext,
oldcontext;
if (!AggCheckCallContext(fcinfo, &aggcontext))
/* cannot be called directly because of internal-type argument */
elog(ERROR, "_weighted_stddev_samp_intermediate called in non-aggregate context");
if (PG_ARGISNULL(0))
{
oldcontext = MemoryContextSwitchTo(aggcontext);
state = (WeightedStddevSampInternalState *) palloc(sizeof(WeightedStddevSampInternalState));
state->s_2 = make_numeric(0);
state->s_1 = make_numeric(0);
state->s_0 = make_numeric(0);
state->zero = make_numeric(0);
state->n_prime = 0;
MemoryContextSwitchTo(oldcontext);
}
else
state = (WeightedStddevSampInternalState *) PG_GETARG_POINTER(0);
/*
* We're non-strict, so we MUST check args for nullity ourselves before
* using them. To preserve the behaviour of null inputs, we skip updating
* on them.
*/
if (PG_ARGISNULL(1) || PG_ARGISNULL(2))
PG_RETURN_POINTER(state);
/*
* We fetch and process the input in the shortlived calling context to
* avoid leaking memory in aggcontext per cycle. We force the input to be
* detoasted here, too, in the shortlived context. (PG_GETARG_DATUM does
* not detoast, but PG_GETARG_NUMERIC does.)
*/
value = NumericGetDatum(PG_GETARG_NUMERIC(1));
weight = NumericGetDatum(PG_GETARG_NUMERIC(2));
/*
* We also skip updating when the weight is zero.
*/
if (DatumGetBool(DirectFunctionCall2(numeric_eq, weight, state->zero)))
PG_RETURN_POINTER(state);
/*
* Compute intermediate values w*v and w*(v^2) in the short-lived context
*/
w_v = DirectFunctionCall2(numeric_mul, weight, value);
w_v2 = DirectFunctionCall2(numeric_mul, w_v, value);
/*
* The new running totals must be allocated in the long-lived context. We
* rely on the numeric_* functions to clean up after themselves (which they
* currently do, but only if the input is already detoasted); we could play
* safe and copy only the final results into aggcontext, but this turns out
* to have a measurable performance hit.
*/
oldcontext = MemoryContextSwitchTo(aggcontext);
old_s_2 = state->s_2;
old_s_1 = state->s_1;
old_s_0 = state->s_0;
state->s_0 = DirectFunctionCall2(numeric_add, old_s_0, weight);
state->s_1 = DirectFunctionCall2(numeric_add, old_s_1, w_v);
state->s_2 = DirectFunctionCall2(numeric_add, old_s_2, w_v2);
state->n_prime += 1;
pfree(DatumGetPointer(old_s_2));
pfree(DatumGetPointer(old_s_1));
pfree(DatumGetPointer(old_s_0));
MemoryContextSwitchTo(oldcontext);
PG_RETURN_POINTER(state);
}
示例7: pgstrom_create_kern_parambuf
/*
* pgstrom_create_param_buffer
*
* It construct a param-buffer on the shared memory segment, according to
* the supplied Const/Param list. Its initial reference counter is 1, so
* this buffer can be released using pgstrom_put_param_buffer().
*/
kern_parambuf *
pgstrom_create_kern_parambuf(List *used_params,
ExprContext *econtext)
{
StringInfoData str;
kern_parambuf *kpbuf;
char padding[STROMALIGN_LEN];
ListCell *cell;
Size offset;
int index = 0;
int nparams = list_length(used_params);
/* seek to the head of variable length field */
offset = STROMALIGN(offsetof(kern_parambuf, poffset[nparams]));
initStringInfo(&str);
enlargeStringInfo(&str, offset);
memset(str.data, 0, offset);
str.len = offset;
/* walks on the Para/Const list */
foreach (cell, used_params)
{
Node *node = lfirst(cell);
if (IsA(node, Const))
{
Const *con = (Const *) node;
kpbuf = (kern_parambuf *)str.data;
if (con->constisnull)
kpbuf->poffset[index] = 0; /* null */
else
{
kpbuf->poffset[index] = str.len;
if (con->constlen > 0)
appendBinaryStringInfo(&str,
(char *)&con->constvalue,
con->constlen);
else
appendBinaryStringInfo(&str,
DatumGetPointer(con->constvalue),
VARSIZE(con->constvalue));
}
}
else if (IsA(node, Param))
{
ParamListInfo param_info = econtext->ecxt_param_list_info;
Param *param = (Param *) node;
if (param_info &&
param->paramid > 0 && param->paramid <= param_info->numParams)
{
ParamExternData *prm = ¶m_info->params[param->paramid - 1];
/* give hook a chance in case parameter is dynamic */
if (!OidIsValid(prm->ptype) && param_info->paramFetch != NULL)
(*param_info->paramFetch) (param_info, param->paramid);
kpbuf = (kern_parambuf *)str.data;
if (!OidIsValid(prm->ptype))
{
elog(INFO, "debug: Param has no particular data type");
kpbuf->poffset[index++] = 0; /* null */
continue;
}
/* safety check in case hook did something unexpected */
if (prm->ptype != param->paramtype)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("type of parameter %d (%s) does not match that when preparing the plan (%s)",
param->paramid,
format_type_be(prm->ptype),
format_type_be(param->paramtype))));
if (prm->isnull)
kpbuf->poffset[index] = 0; /* null */
else
{
int typlen = get_typlen(prm->ptype);
if (typlen == 0)
elog(ERROR, "cache lookup failed for type %u",
prm->ptype);
if (typlen > 0)
appendBinaryStringInfo(&str,
(char *)&prm->value,
typlen);
else
appendBinaryStringInfo(&str,
DatumGetPointer(prm->value),
VARSIZE(prm->value));
}
}
}
else
//.........這裏部分代碼省略.........
示例8: gtsvector_compress
Datum
gtsvector_compress(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
GISTENTRY *retval = entry;
if (entry->leafkey)
{ /* tsvector */
SignTSVector *res;
TSVector val = DatumGetTSVector(entry->key);
int32 len;
int32 *arr;
WordEntry *ptr = ARRPTR(val);
char *words = STRPTR(val);
len = CALCGTSIZE(ARRKEY, val->size);
res = (SignTSVector *) palloc(len);
SET_VARSIZE(res, len);
res->flag = ARRKEY;
arr = GETARR(res);
len = val->size;
while (len--)
{
pg_crc32 c;
INIT_LEGACY_CRC32(c);
COMP_LEGACY_CRC32(c, words + ptr->pos, ptr->len);
FIN_LEGACY_CRC32(c);
*arr = *(int32 *) &c;
arr++;
ptr++;
}
len = uniqueint(GETARR(res), val->size);
if (len != val->size)
{
/*
* there is a collision of hash-function; len is always less than
* val->size
*/
len = CALCGTSIZE(ARRKEY, len);
res = (SignTSVector *) repalloc((void *) res, len);
SET_VARSIZE(res, len);
}
/* make signature, if array is too long */
if (VARSIZE(res) > TOAST_INDEX_TARGET)
{
SignTSVector *ressign;
len = CALCGTSIZE(SIGNKEY, 0);
ressign = (SignTSVector *) palloc(len);
SET_VARSIZE(ressign, len);
ressign->flag = SIGNKEY;
makesign(GETSIGN(ressign), res);
res = ressign;
}
retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
gistentryinit(*retval, PointerGetDatum(res),
entry->rel, entry->page,
entry->offset, FALSE);
}
else if (ISSIGNKEY(DatumGetPointer(entry->key)) &&
!ISALLTRUE(DatumGetPointer(entry->key)))
{
int32 i,
len;
SignTSVector *res;
BITVECP sign = GETSIGN(DatumGetPointer(entry->key));
LOOPBYTE
{
if ((sign[i] & 0xff) != 0xff)
PG_RETURN_POINTER(retval);
}
len = CALCGTSIZE(SIGNKEY | ALLISTRUE, 0);
res = (SignTSVector *) palloc(len);
SET_VARSIZE(res, len);
res->flag = SIGNKEY | ALLISTRUE;
retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
gistentryinit(*retval, PointerGetDatum(res),
entry->rel, entry->page,
entry->offset, FALSE);
}
示例9: composite_to_json
/*
* Turn a composite / record into JSON.
*/
static void
composite_to_json(Datum composite, StringInfo result, bool use_line_feeds)
{
HeapTupleHeader td;
Oid tupType;
int32 tupTypmod;
TupleDesc tupdesc;
HeapTupleData tmptup, *tuple;
int i;
bool needsep = false;
char *sep;
sep = use_line_feeds ? ",\n " : ",";
td = DatumGetHeapTupleHeader(composite);
/* Extract rowtype info and find a tupdesc */
tupType = HeapTupleHeaderGetTypeId(td);
tupTypmod = HeapTupleHeaderGetTypMod(td);
tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
/* Build a temporary HeapTuple control structure */
tmptup.t_len = HeapTupleHeaderGetDatumLength(td);
tmptup.t_data = td;
tuple = &tmptup;
appendStringInfoChar(result,'{');
for (i = 0; i < tupdesc->natts; i++)
{
Datum val, origval;
bool isnull;
char *attname;
TYPCATEGORY tcategory;
Oid typoutput;
bool typisvarlena;
if (tupdesc->attrs[i]->attisdropped)
continue;
if (needsep)
appendStringInfoString(result,sep);
needsep = true;
attname = NameStr(tupdesc->attrs[i]->attname);
escape_json(result,attname);
appendStringInfoChar(result,':');
origval = heap_getattr(tuple, i + 1, tupdesc, &isnull);
if (tupdesc->attrs[i]->atttypid == RECORDARRAYOID)
tcategory = TYPCATEGORY_ARRAY;
else if (tupdesc->attrs[i]->atttypid == RECORDOID)
tcategory = TYPCATEGORY_COMPOSITE;
else
tcategory = TypeCategory(tupdesc->attrs[i]->atttypid);
getTypeOutputInfo(tupdesc->attrs[i]->atttypid,
&typoutput, &typisvarlena);
/*
* If we have a toasted datum, forcibly detoast it here to avoid memory
* leakage inside the type's output routine.
*/
if (typisvarlena && ! isnull)
val = PointerGetDatum(PG_DETOAST_DATUM(origval));
else
val = origval;
datum_to_json(val, result, tcategory, typoutput);
/* Clean up detoasted copy, if any */
if (val != origval)
pfree(DatumGetPointer(val));
}
appendStringInfoChar(result,'}');
ReleaseTupleDesc(tupdesc);
}
示例10: gin_extract_jsonb_query
Datum
gin_extract_jsonb_query(PG_FUNCTION_ARGS)
{
int32 *nentries = (int32 *) PG_GETARG_POINTER(1);
StrategyNumber strategy = PG_GETARG_UINT16(2);
int32 *searchMode = (int32 *) PG_GETARG_POINTER(6);
Datum *entries;
if (strategy == JsonbContainsStrategyNumber)
{
/* Query is a jsonb, so just apply gin_extract_jsonb... */
entries = (Datum *)
DatumGetPointer(DirectFunctionCall2(gin_extract_jsonb,
PG_GETARG_DATUM(0),
PointerGetDatum(nentries)));
/* ...although "contains {}" requires a full index scan */
if (*nentries == 0)
*searchMode = GIN_SEARCH_MODE_ALL;
}
else if (strategy == JsonbExistsStrategyNumber)
{
/* Query is a text string, which we treat as a key */
text *query = PG_GETARG_TEXT_PP(0);
*nentries = 1;
entries = (Datum *) palloc(sizeof(Datum));
entries[0] = make_text_key(JGINFLAG_KEY,
VARDATA_ANY(query),
VARSIZE_ANY_EXHDR(query));
}
else if (strategy == JsonbExistsAnyStrategyNumber ||
strategy == JsonbExistsAllStrategyNumber)
{
/* Query is a text array; each element is treated as a key */
ArrayType *query = PG_GETARG_ARRAYTYPE_P(0);
Datum *key_datums;
bool *key_nulls;
int key_count;
int i,
j;
deconstruct_array(query,
TEXTOID, -1, false, 'i',
&key_datums, &key_nulls, &key_count);
entries = (Datum *) palloc(sizeof(Datum) * key_count);
for (i = 0, j = 0; i < key_count; i++)
{
/* Nulls in the array are ignored */
if (key_nulls[i])
continue;
entries[j++] = make_text_key(JGINFLAG_KEY,
VARDATA_ANY(key_datums[i]),
VARSIZE_ANY_EXHDR(key_datums[i]));
}
*nentries = j;
/* ExistsAll with no keys should match everything */
if (j == 0 && strategy == JsonbExistsAllStrategyNumber)
*searchMode = GIN_SEARCH_MODE_ALL;
}
else
{
elog(ERROR, "unrecognized strategy number: %d", strategy);
entries = NULL; /* keep compiler quiet */
}
PG_RETURN_POINTER(entries);
}
示例11: g_int_compress
/*
** GiST Compress and Decompress methods
*/
Datum
g_int_compress(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
GISTENTRY *retval;
ArrayType *r;
int len;
int *dr;
int i,
min,
cand;
if (entry->leafkey)
{
r = (ArrayType *) PG_DETOAST_DATUM_COPY(entry->key);
PREPAREARR(r);
r->flags |= LEAFKEY;
retval = palloc(sizeof(GISTENTRY));
gistentryinit(*retval, PointerGetDatum(r),
entry->rel, entry->page, entry->offset, VARSIZE(r), FALSE);
PG_RETURN_POINTER(retval);
}
r = (ArrayType *) PG_DETOAST_DATUM(entry->key);
if (ISLEAFKEY(r) || ARRISVOID(r))
{
if (r != (ArrayType *) DatumGetPointer(entry->key))
pfree(r);
PG_RETURN_POINTER(entry);
}
if ((len = ARRNELEMS(r)) >= 2 * MAXNUMRANGE)
{ /* compress */
if (r == (ArrayType *) DatumGetPointer(entry->key))
r = (ArrayType *) PG_DETOAST_DATUM_COPY(entry->key);
r = resize_intArrayType(r, 2 * (len));
dr = ARRPTR(r);
for (i = len - 1; i >= 0; i--)
dr[2 * i] = dr[2 * i + 1] = dr[i];
len *= 2;
cand = 1;
while (len > MAXNUMRANGE * 2)
{
min = 0x7fffffff;
for (i = 2; i < len; i += 2)
if (min > (dr[i] - dr[i - 1]))
{
min = (dr[i] - dr[i - 1]);
cand = i;
}
memmove((void *) &dr[cand - 1], (void *) &dr[cand + 1], (len - cand - 1) * sizeof(int));
len -= 2;
}
r = resize_intArrayType(r, len);
retval = palloc(sizeof(GISTENTRY));
gistentryinit(*retval, PointerGetDatum(r),
entry->rel, entry->page, entry->offset, VARSIZE(r), FALSE);
PG_RETURN_POINTER(retval);
}
else
PG_RETURN_POINTER(entry);
PG_RETURN_POINTER(entry);
}
示例12: gtsvector_compress
Datum
gtsvector_compress(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
GISTENTRY *retval = entry;
if (entry->leafkey)
{ /* tsvector */
GISTTYPE *res;
tsvector *val = (tsvector *) PG_DETOAST_DATUM(entry->key);
int4 len;
int4 *arr;
WordEntry *ptr = ARRPTR(val);
char *words = STRPTR(val);
len = CALCGTSIZE(ARRKEY, val->size);
res = (GISTTYPE *) palloc(len);
SET_VARSIZE(res, len);
res->flag = ARRKEY;
arr = GETARR(res);
len = val->size;
while (len--)
{
*arr = crc32_sz(&words[ptr->pos], ptr->len);
arr++;
ptr++;
}
len = uniqueint(GETARR(res), val->size);
if (len != val->size)
{
/*
* there is a collision of hash-function; len is always less than
* val->size
*/
len = CALCGTSIZE(ARRKEY, len);
res = (GISTTYPE *) repalloc((void *) res, len);
SET_VARSIZE(res, len);
}
/* make signature, if array is too long */
if (VARSIZE(res) > TOAST_INDEX_TARGET)
{
GISTTYPE *ressign;
len = CALCGTSIZE(SIGNKEY, 0);
ressign = (GISTTYPE *) palloc(len);
SET_VARSIZE(ressign, len);
ressign->flag = SIGNKEY;
makesign(GETSIGN(ressign), res);
res = ressign;
}
retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
gistentryinit(*retval, PointerGetDatum(res),
entry->rel, entry->page,
entry->offset, FALSE);
}
else if (ISSIGNKEY(DatumGetPointer(entry->key)) &&
!ISALLTRUE(DatumGetPointer(entry->key)))
{
int4 i,
len;
GISTTYPE *res;
BITVECP sign = GETSIGN(DatumGetPointer(entry->key));
LOOPBYTE(
if ((sign[i] & 0xff) != 0xff)
PG_RETURN_POINTER(retval);
);
示例13: ghstore_compress
Datum
ghstore_compress(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
GISTENTRY *retval = entry;
if (entry->leafkey)
{
GISTTYPE *res = (GISTTYPE *) palloc0(CALCGTSIZE(0));
HStore *toastedval = (HStore *) DatumGetPointer(entry->key);
HStore *val = (HStore *) DatumGetPointer(PG_DETOAST_DATUM(entry->key));
HEntry *ptr = ARRPTR(val);
char *words = STRPTR(val);
SET_VARSIZE(res, CALCGTSIZE(0));
while (ptr - ARRPTR(val) < val->size)
{
int h;
h = crc32_sz((char *) (words + ptr->pos), ptr->keylen);
HASH(GETSIGN(res), h);
if (!ptr->valisnull)
{
h = crc32_sz((char *) (words + ptr->pos + ptr->keylen), ptr->vallen);
HASH(GETSIGN(res), h);
}
ptr++;
}
if (val != toastedval)
pfree(val);
retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
gistentryinit(*retval, PointerGetDatum(res),
entry->rel, entry->page,
entry->offset,
FALSE);
}
else if (!ISALLTRUE(DatumGetPointer(entry->key)))
{
int4 i;
GISTTYPE *res;
BITVECP sign = GETSIGN(DatumGetPointer(entry->key));
LOOPBYTE
{
if ((sign[i] & 0xff) != 0xff)
PG_RETURN_POINTER(retval);
}
res = (GISTTYPE *) palloc(CALCGTSIZE(ALLISTRUE));
SET_VARSIZE(res, CALCGTSIZE(ALLISTRUE));
res->flag = ALLISTRUE;
retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
gistentryinit(*retval, PointerGetDatum(res),
entry->rel, entry->page,
entry->offset,
FALSE);
}
示例14: lookup_ts_dictionary_cache
//.........這裏部分代碼省略.........
tpdict = SearchSysCache1(TSDICTOID, ObjectIdGetDatum(dictId));
if (!HeapTupleIsValid(tpdict))
elog(ERROR, "cache lookup failed for text search dictionary %u",
dictId);
dict = (Form_pg_ts_dict) GETSTRUCT(tpdict);
/*
* Sanity checks
*/
if (!OidIsValid(dict->dicttemplate))
elog(ERROR, "text search dictionary %u has no ctemplate", dictId);
/*
* Retrieve dictionary's ctemplate
*/
tptmpl = SearchSysCache1(TSTEMPLATEOID,
ObjectIdGetDatum(dict->dicttemplate));
if (!HeapTupleIsValid(tptmpl))
elog(ERROR, "cache lookup failed for text search ctemplate %u",
dict->dicttemplate);
ctemplate = (Form_pg_ts_template) GETSTRUCT(tptmpl);
/*
* Sanity checks
*/
if (!OidIsValid(ctemplate->tmpllexize))
elog(ERROR, "text search ctemplate %u has no lexize method",
ctemplate->tmpllexize);
if (entry == NULL)
{
bool found;
/* Now make the cache entry */
entry = (TSDictionaryCacheEntry *)
hash_search(TSDictionaryCacheHash,
(void *) &dictId,
HASH_ENTER, &found);
Assert(!found); /* it wasn't there a moment ago */
/* Create private___ memory context the first time through */
saveCtx = AllocSetContextCreate(CacheMemoryContext,
NameStr(dict->dictname),
ALLOCSET_SMALL_MINSIZE,
ALLOCSET_SMALL_INITSIZE,
ALLOCSET_SMALL_MAXSIZE);
}
else
{
/* Clear the existing entry's private___ context */
saveCtx = entry->dictCtx;
MemoryContextResetAndDeleteChildren(saveCtx);
}
MemSet(entry, 0, sizeof(TSDictionaryCacheEntry));
entry->dictId = dictId;
entry->dictCtx = saveCtx;
entry->lexizeOid = ctemplate->tmpllexize;
if (OidIsValid(ctemplate->tmplinit))
{
List *dictoptions;
Datum opt;
bool isnull;
MemoryContext oldcontext;
/*
* Init method runs in dictionary's private___ memory context, and we
* make sure the options are stored there too
*/
oldcontext = MemoryContextSwitchTo(entry->dictCtx);
opt = SysCacheGetAttr(TSDICTOID, tpdict,
Anum_pg_ts_dict_dictinitoption,
&isnull);
if (isnull)
dictoptions = NIL;
else
dictoptions = deserialize_deflist(opt);
entry->dictData =
DatumGetPointer(OidFunctionCall1(ctemplate->tmplinit,
PointerGetDatum(dictoptions)));
MemoryContextSwitchTo(oldcontext);
}
ReleaseSysCache(tptmpl);
ReleaseSysCache(tpdict);
fmgr_info_cxt(entry->lexizeOid, &entry->lexize, entry->dictCtx);
entry->isvalid = true;
}
lastUsedDictionary = entry;
return entry;
}
示例15: gseg_picksplit
/*
** The GiST PickSplit method for segments
** We use Guttman's poly time split algorithm
*/
GIST_SPLITVEC *
gseg_picksplit(GistEntryVector *entryvec,
GIST_SPLITVEC *v)
{
OffsetNumber i,
j;
SEG *datum_alpha,
*datum_beta;
SEG *datum_l,
*datum_r;
SEG *union_d,
*union_dl,
*union_dr;
SEG *inter_d;
bool firsttime;
float size_alpha,
size_beta,
size_union,
size_inter;
float size_waste,
waste;
float size_l,
size_r;
int nbytes;
OffsetNumber seed_1 = 1,
seed_2 = 2;
OffsetNumber *left,
*right;
OffsetNumber maxoff;
#ifdef GIST_DEBUG
fprintf(stderr, "picksplit\n");
#endif
maxoff = entryvec->n - 2;
nbytes = (maxoff + 2) * sizeof(OffsetNumber);
v->spl_left = (OffsetNumber *) palloc(nbytes);
v->spl_right = (OffsetNumber *) palloc(nbytes);
firsttime = true;
waste = 0.0;
for (i = FirstOffsetNumber; i < maxoff; i = OffsetNumberNext(i))
{
datum_alpha = (SEG *) DatumGetPointer(entryvec->vector[i].key);
for (j = OffsetNumberNext(i); j <= maxoff; j = OffsetNumberNext(j))
{
datum_beta = (SEG *) DatumGetPointer(entryvec->vector[j].key);
/* compute the wasted space by unioning these guys */
/* size_waste = size_union - size_inter; */
union_d = seg_union(datum_alpha, datum_beta);
rt_seg_size(union_d, &size_union);
inter_d = seg_inter(datum_alpha, datum_beta);
rt_seg_size(inter_d, &size_inter);
size_waste = size_union - size_inter;
/*
* are these a more promising split that what we've already seen?
*/
if (size_waste > waste || firsttime)
{
waste = size_waste;
seed_1 = i;
seed_2 = j;
firsttime = false;
}
}
}
left = v->spl_left;
v->spl_nleft = 0;
right = v->spl_right;
v->spl_nright = 0;
datum_alpha = (SEG *) DatumGetPointer(entryvec->vector[seed_1].key);
datum_l = seg_union(datum_alpha, datum_alpha);
rt_seg_size(datum_l, &size_l);
datum_beta = (SEG *) DatumGetPointer(entryvec->vector[seed_2].key);
datum_r = seg_union(datum_beta, datum_beta);
rt_seg_size(datum_r, &size_r);
/*
* Now split up the regions between the two seeds. An important property
* of this split algorithm is that the split vector v has the indices of
* items to be split in order in its left and right vectors. We exploit
* this property by doing a merge in the code that actually splits the
* page.
*
* For efficiency, we also place the new index tuple in this loop. This is
* handled at the very end, when we have placed all the existing tuples
* and i == maxoff + 1.
*/
maxoff = OffsetNumberNext(maxoff);
for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
//.........這裏部分代碼省略.........