本文整理汇总了C++中VARDATA函数的典型用法代码示例。如果您正苦于以下问题:C++ VARDATA函数的具体用法?C++ VARDATA怎么用?C++ VARDATA使用的例子?那么, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了VARDATA函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: gin_leafpage_items
Datum
gin_leafpage_items(PG_FUNCTION_ARGS)
{
bytea *raw_page = PG_GETARG_BYTEA_P(0);
int raw_page_size;
FuncCallContext *fctx;
gin_leafpage_items_state *inter_call_data;
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;
Page page;
GinPageOpaque opaq;
if (raw_page_size < BLCKSZ)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("input page too small (%d bytes)", raw_page_size)));
page = VARDATA(raw_page);
if (PageGetSpecialSize(page) != MAXALIGN(sizeof(GinPageOpaqueData)))
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("input page is not a valid GIN data leaf page"),
errdetail("Special size %d, expected %d",
(int) PageGetSpecialSize(page),
(int) MAXALIGN(sizeof(GinPageOpaqueData)))));
opaq = (GinPageOpaque) PageGetSpecialPointer(page);
if (opaq->flags != (GIN_DATA | GIN_LEAF | GIN_COMPRESSED))
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("input page is not a compressed GIN data leaf page"),
errdetail("Flags %04X, expected %04X",
opaq->flags,
(GIN_DATA | GIN_LEAF | GIN_COMPRESSED))));
fctx = SRF_FIRSTCALL_INIT();
mctx = MemoryContextSwitchTo(fctx->multi_call_memory_ctx);
inter_call_data = palloc(sizeof(gin_leafpage_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->seg = GinDataLeafPageGetPostingList(page);
inter_call_data->lastseg = (GinPostingList *)
(((char *) inter_call_data->seg) +
GinDataLeafPageGetPostingListSize(page));
fctx->user_fctx = inter_call_data;
MemoryContextSwitchTo(mctx);
}
fctx = SRF_PERCALL_SETUP();
inter_call_data = fctx->user_fctx;
if (inter_call_data->seg != inter_call_data->lastseg)
{
GinPostingList *cur = inter_call_data->seg;
HeapTuple resultTuple;
Datum result;
Datum values[3];
bool nulls[3];
int ndecoded,
i;
ItemPointer tids;
Datum *tids_datum;
memset(nulls, 0, sizeof(nulls));
values[0] = ItemPointerGetDatum(&cur->first);
values[1] = UInt16GetDatum(cur->nbytes);
/* build an array of decoded item pointers */
tids = ginPostingListDecode(cur, &ndecoded);
tids_datum = (Datum *) palloc(ndecoded * sizeof(Datum));
for (i = 0; i < ndecoded; i++)
tids_datum[i] = ItemPointerGetDatum(&tids[i]);
values[2] = PointerGetDatum(construct_array(tids_datum,
ndecoded,
TIDOID,
sizeof(ItemPointerData),
false, 's'));
pfree(tids_datum);
pfree(tids);
/* Build and return the result tuple. */
//.........这里部分代码省略.........
示例2: printtup
/* ----------------
* printtup --- print a tuple in protocol 3.0
* ----------------
*/
static bool
printtup(TupleTableSlot *slot, DestReceiver *self)
{
TupleDesc typeinfo = slot->tts_tupleDescriptor;
DR_printtup *myState = (DR_printtup *) self;
MemoryContext oldcontext;
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);
/* Switch into per-row context so we can recover memory below */
oldcontext = MemoryContextSwitchTo(myState->tmpcontext);
/*
* Prepare a DataRow message (note buffer is in per-row context)
*/
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 attr = slot->tts_values[i];
if (slot->tts_isnull[i])
{
pq_sendint(&buf, -1, 4);
continue;
}
/*
* Here we catch undefined bytes in datums that are returned to the
* client without hitting disk; see comments at the related check in
* PageAddItem(). This test is most useful for uncompressed,
* non-external datums, but we're quite likely to see such here when
* testing new C functions.
*/
if (thisState->typisvarlena)
VALGRIND_CHECK_MEM_IS_DEFINED(DatumGetPointer(attr),
VARSIZE_ANY(attr));
if (thisState->format == 0)
{
/* Text output */
char *outputstr;
outputstr = OutputFunctionCall(&thisState->finfo, attr);
pq_sendcountedtext(&buf, outputstr, strlen(outputstr), false);
}
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);
}
}
pq_endmessage(&buf);
/* Return to caller's context, and flush row's temporary memory */
MemoryContextSwitchTo(oldcontext);
MemoryContextReset(myState->tmpcontext);
return true;
}
示例3: lookup_rowtype_tupdesc
static void *uri_char(HeapTupleHeader ud, bool hdr, bool term)
{
TupleDesc td;
HeapTupleData tuple;
Datum d[URI_LEN];
bool n[URI_LEN];
text *scheme = NULL, *host = NULL, *path = NULL;
int16 port;
char portbuf[8];
unsigned schemelen = 0, hostlen = 0, portlen = 0, pathlen = 0;
unsigned len;
void *out;
char *p;
td = lookup_rowtype_tupdesc(HeapTupleHeaderGetTypeId(ud), HeapTupleHeaderGetTypMod(ud));
tuple.t_len = HeapTupleHeaderGetDatumLength(ud);
ItemPointerSetInvalid(&(tuple.t_self));
tuple.t_tableOid = InvalidOid;
tuple.t_data = ud;
heap_deform_tuple(&tuple, td, d, n);
ReleaseTupleDesc(td);
if (!n[URI_SCHEME])
{
scheme = DatumGetTextP(d[URI_SCHEME]);
schemelen = VARSIZE_ANY_EXHDR(scheme);
}
if (!n[URI_HOST])
{
host = DatumGetTextP(d[URI_HOST]);
hostlen = VARSIZE_ANY_EXHDR(host);
}
if (!n[URI_PORT])
{
port = DatumGetInt16(d[URI_PORT]);
portlen = snprintf(portbuf, sizeof(portbuf)-1, ":%hu", port);
}
if (!n[URI_PATH])
{
path = DatumGetTextP(d[URI_PATH]);
pathlen = VARSIZE_ANY_EXHDR(path);
}
len = (hdr ? VARHDRSZ : 0) + schemelen + (scheme ? 3 : 0) + hostlen + portlen + pathlen + term;
out = palloc(len);
if (hdr)
SET_VARSIZE(out, len);
p = hdr ? VARDATA(out) : out;
if (scheme)
{
memcpy(p, VARDATA(scheme), schemelen);
p += schemelen;
*p++ = ':';
*p++ = '/';
*p++ = '/';
}
if (host)
{
domainname_flip(p, VARDATA(host), hostlen);
p += hostlen;
}
memcpy(p, portbuf, portlen);
p += portlen;
if (path)
{
memcpy(p, VARDATA(path), pathlen);
p += pathlen;
}
if (term)
*p = '\0';
return out;
}
示例4: spg_text_leaf_consistent
Datum
spg_text_leaf_consistent(PG_FUNCTION_ARGS)
{
spgLeafConsistentIn *in = (spgLeafConsistentIn *) PG_GETARG_POINTER(0);
spgLeafConsistentOut *out = (spgLeafConsistentOut *) PG_GETARG_POINTER(1);
int level = in->level;
text *leafValue,
*reconstrValue = NULL;
char *fullValue;
int fullLen;
bool res;
int j;
/* all tests are exact */
out->recheck = false;
leafValue = DatumGetTextPP(in->leafDatum);
if (DatumGetPointer(in->reconstructedValue))
reconstrValue = DatumGetTextP(in->reconstructedValue);
Assert(level == 0 ? reconstrValue == NULL :
VARSIZE_ANY_EXHDR(reconstrValue) == level);
/* Reconstruct the full string represented by this leaf tuple */
fullLen = level + VARSIZE_ANY_EXHDR(leafValue);
if (VARSIZE_ANY_EXHDR(leafValue) == 0 && level > 0)
{
fullValue = VARDATA(reconstrValue);
out->leafValue = PointerGetDatum(reconstrValue);
}
else
{
text *fullText = palloc(VARHDRSZ + fullLen);
SET_VARSIZE(fullText, VARHDRSZ + fullLen);
fullValue = VARDATA(fullText);
if (level)
memcpy(fullValue, VARDATA(reconstrValue), level);
if (VARSIZE_ANY_EXHDR(leafValue) > 0)
memcpy(fullValue + level, VARDATA_ANY(leafValue),
VARSIZE_ANY_EXHDR(leafValue));
out->leafValue = PointerGetDatum(fullText);
}
/* Perform the required comparison(s) */
res = true;
for (j = 0; j < in->nkeys; j++)
{
StrategyNumber strategy = in->scankeys[j].sk_strategy;
text *query = DatumGetTextPP(in->scankeys[j].sk_argument);
int queryLen = VARSIZE_ANY_EXHDR(query);
int r;
if (strategy > 10)
{
/* Collation-aware comparison */
strategy -= 10;
/* If asserts enabled, verify encoding of reconstructed string */
Assert(pg_verifymbstr(fullValue, fullLen, false));
r = varstr_cmp(fullValue, Min(queryLen, fullLen),
VARDATA_ANY(query), Min(queryLen, fullLen),
PG_GET_COLLATION());
}
else
{
/* Non-collation-aware comparison */
r = memcmp(fullValue, VARDATA_ANY(query), Min(queryLen, fullLen));
}
if (r == 0)
{
if (queryLen > fullLen)
r = -1;
else if (queryLen < fullLen)
r = 1;
}
switch (strategy)
{
case BTLessStrategyNumber:
res = (r < 0);
break;
case BTLessEqualStrategyNumber:
res = (r <= 0);
break;
case BTEqualStrategyNumber:
res = (r == 0);
break;
case BTGreaterEqualStrategyNumber:
res = (r >= 0);
break;
case BTGreaterStrategyNumber:
res = (r > 0);
break;
default:
elog(ERROR, "unrecognized strategy number: %d",
in->scankeys[j].sk_strategy);
//.........这里部分代码省略.........
示例5: gin_extract_query_trgm
Datum
gin_extract_query_trgm(PG_FUNCTION_ARGS)
{
text *val = (text *) PG_GETARG_TEXT_P(0);
int32 *nentries = (int32 *) PG_GETARG_POINTER(1);
StrategyNumber strategy = PG_GETARG_UINT16(2);
/* bool **pmatch = (bool **) PG_GETARG_POINTER(3); */
Pointer **extra_data = (Pointer **) PG_GETARG_POINTER(4);
/* bool **nullFlags = (bool **) PG_GETARG_POINTER(5); */
int32 *searchMode = (int32 *) PG_GETARG_POINTER(6);
Datum *entries = NULL;
TRGM *trg;
int32 trglen;
trgm *ptr;
TrgmPackedGraph *graph;
int32 i;
switch (strategy)
{
case SimilarityStrategyNumber:
trg = generate_trgm(VARDATA(val), VARSIZE(val) - VARHDRSZ);
break;
case ILikeStrategyNumber:
#ifndef IGNORECASE
elog(ERROR, "cannot handle ~~* with case-sensitive trigrams");
#endif
/* FALL THRU */
case LikeStrategyNumber:
/*
* For wildcard search we extract all the trigrams that every
* potentially-matching string must include.
*/
trg = generate_wildcard_trgm(VARDATA(val), VARSIZE(val) - VARHDRSZ);
break;
case RegExpICaseStrategyNumber:
#ifndef IGNORECASE
elog(ERROR, "cannot handle ~* with case-sensitive trigrams");
#endif
/* FALL THRU */
case RegExpStrategyNumber:
trg = createTrgmNFA(val, PG_GET_COLLATION(),
&graph, CurrentMemoryContext);
if (trg && ARRNELEM(trg) > 0)
{
/*
* Successful regex processing: store NFA-like graph as
* extra_data. GIN API requires an array of nentries
* Pointers, but we just put the same value in each element.
*/
trglen = ARRNELEM(trg);
*extra_data = (Pointer *) palloc(sizeof(Pointer) * trglen);
for (i = 0; i < trglen; i++)
(*extra_data)[i] = (Pointer) graph;
}
else
{
/* No result: have to do full index scan. */
*nentries = 0;
*searchMode = GIN_SEARCH_MODE_ALL;
PG_RETURN_POINTER(entries);
}
break;
default:
elog(ERROR, "unrecognized strategy number: %d", strategy);
trg = NULL; /* keep compiler quiet */
break;
}
trglen = ARRNELEM(trg);
*nentries = trglen;
if (trglen > 0)
{
entries = (Datum *) palloc(sizeof(Datum) * trglen);
ptr = GETARR(trg);
for (i = 0; i < trglen; i++)
{
int32 item = trgm2int(ptr);
entries[i] = Int32GetDatum(item);
ptr++;
}
}
/*
* If no trigram was extracted then we have to scan all the index.
*/
if (trglen == 0)
*searchMode = GIN_SEARCH_MODE_ALL;
PG_RETURN_POINTER(entries);
}
示例6: DeserializeTuple
/*
* Deserialize a HeapTuple's data from a byte-array.
*
* This code is based on the binary input handling functions in copy.c.
*/
HeapTuple
DeserializeTuple(SerTupInfo *pSerInfo, StringInfo serialTup)
{
MemoryContext oldCtxt;
TupleDesc tupdesc;
HeapTuple htup;
int natts;
SerAttrInfo *attrInfo;
int i;
AssertArg(pSerInfo != NULL);
AssertArg(serialTup != NULL);
tupdesc = pSerInfo->tupdesc;
natts = tupdesc->natts;
/*
* Flip to our tuple-serialization memory-context, to speed up memory
* reclamation operations.
*/
AssertState(s_tupSerMemCtxt != NULL);
oldCtxt = MemoryContextSwitchTo(s_tupSerMemCtxt);
/* Receive nulls character-array. */
pq_copymsgbytes(serialTup, pSerInfo->nulls, natts);
skipPadding(serialTup);
/* Deserialize the non-NULL attributes of this tuple */
for (i = 0; i < natts; ++i)
{
attrInfo = pSerInfo->myinfo + i;
if (pSerInfo->nulls[i]) /* NULL field. */
{
pSerInfo->values[i] = (Datum) 0;
continue;
}
if (attrInfo->typlen == -1)
{
int32 sz;
struct varlena *p;
/* Read length first */
pq_copymsgbytes(serialTup, (char *) &sz, sizeof(int32));
if (sz < 0)
elog(ERROR, "invalid length received for a varlen Datum");
p = palloc(sz + VARHDRSZ);
pq_copymsgbytes(serialTup, VARDATA(p), sz);
SET_VARSIZE(p, sz + VARHDRSZ);
pSerInfo->values[i] = PointerGetDatum(p);
}
else if (attrInfo->typlen == -2)
{
int32 sz;
char *p;
/* CString, with terminating '\0' included */
/* Read length first */
pq_copymsgbytes(serialTup, (char *) &sz, sizeof(int32));
if (sz < 0)
elog(ERROR, "invalid length received for a CString");
p = palloc(sz + VARHDRSZ);
/* Then data */
pq_copymsgbytes(serialTup, p, sz);
pSerInfo->values[i] = CStringGetDatum(p);
}
else if (attrInfo->typbyval)
{
/* Read a whole Datum */
pq_copymsgbytes(serialTup, (char *) &(pSerInfo->values[i]), sizeof(Datum));
}
else
{
/* fixed width, pass-by-ref */
char *p = palloc(attrInfo->typlen);
pq_copymsgbytes(serialTup, p, attrInfo->typlen);
pSerInfo->values[i] = PointerGetDatum(p);
}
}
/*
* Construct the tuple from the Datums and nulls values. NOTE: Switch
* out of our temporary context before we form the tuple!
*/
//.........这里部分代码省略.........
示例7: _Slony_I_logTrigger
//.........这里部分代码省略.........
case 0:
case 2:
cs->plan_active_log = cs->plan_insert_log_1;
break;
case 1:
case 3:
cs->plan_active_log = cs->plan_insert_log_2;
break;
default:
elog(ERROR, "Slony-I: illegal log status %d", log_status);
break;
}
cs->currentXid = newXid;
}
/*
* Determine cmdtype and cmddata depending on the command type
*/
if (TRIGGER_FIRED_BY_INSERT(tg->tg_event))
{
HeapTuple new_row = tg->tg_trigtuple;
TupleDesc tupdesc = tg->tg_relation->rd_att;
char *col_ident;
char *col_value;
int len_ident;
int len_value;
int i;
int need_comma = false;
char *OldDateStyle;
char *cp = VARDATA(cs->cmddata_buf);
/*
* INSERT
*
* cmdtype = 'I' cmddata = ("col" [, ...]) values ('value' [, ...])
*/
cmdtype = cs->cmdtype_I;
/*
* Specify all the columns
*/
*cp++ = '(';
for (i = 0; i < tg->tg_relation->rd_att->natts; i++)
{
/*
* Skip dropped columns
*/
if (tupdesc->attrs[i]->attisdropped)
continue;
col_ident = (char *) slon_quote_identifier(SPI_fname(tupdesc, i + 1));
cmddata_need = (cp - (char *) (cs->cmddata_buf)) + 16 +
(len_ident = strlen(col_ident));
if (cs->cmddata_size < cmddata_need)
{
int have = (cp - (char *) (cs->cmddata_buf));
while (cs->cmddata_size < cmddata_need)
cs->cmddata_size *= 2;
cs->cmddata_buf = realloc(cs->cmddata_buf, cs->cmddata_size);
cp = (char *) (cs->cmddata_buf) + have;
}
示例8: foreach
/*
* If CREATE/SET, add new options to array; if RESET, just check that the
* user didn't say RESET (option=val). (Must do this because the grammar
* doesn't enforce it.)
*/
foreach(cell, defList)
{
DefElem *def = (DefElem *) lfirst(cell);
if (isReset)
{
if (def->arg != NULL)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("RESET must not include values for parameters")));
}
else
{
text *t;
const char *value;
Size len;
/*
* Error out if the namespace is not valid. A NULL namespace is
* always valid.
*/
if (def->defnamespace != NULL)
{
bool valid = false;
int i;
if (validnsps)
{
for (i = 0; validnsps[i]; i++)
{
if (pg_strcasecmp(def->defnamespace,
validnsps[i]) == 0)
{
valid = true;
break;
}
}
}
if (!valid)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("unrecognized parameter namespace \"%s\"",
def->defnamespace)));
}
if (ignoreOids && pg_strcasecmp(def->defname, "oids") == 0)
continue;
/* ignore if not in the same namespace */
if (namspace == NULL)
{
if (def->defnamespace != NULL)
continue;
}
else if (def->defnamespace == NULL)
continue;
else if (pg_strcasecmp(def->defnamespace, namspace) != 0)
continue;
/*
* Flatten the DefElem into a text string like "name=arg". If we
* have just "name", assume "name=true" is meant. Note: the
* namespace is not output.
*/
if (def->arg != NULL)
value = defGetString(def);
else
value = "true";
len = VARHDRSZ + strlen(def->defname) + 1 + strlen(value);
/* +1 leaves room for sprintf's trailing null */
t = (text *) palloc(len + 1);
SET_VARSIZE(t, len);
sprintf(VARDATA(t), "%s=%s", def->defname, value);
astate = accumArrayResult(astate, PointerGetDatum(t),
false, TEXTOID,
CurrentMemoryContext);
}
}
示例9: cash_words
/* cash_words()
* This converts a int4 as well but to a representation using words
* Obviously way North American centric - sorry
*/
Datum
cash_words(PG_FUNCTION_ARGS)
{
Cash value = PG_GETARG_CASH(0);
uint64 val;
char buf[256];
char *p = buf;
Cash m0;
Cash m1;
Cash m2;
Cash m3;
Cash m4;
Cash m5;
Cash m6;
text *result;
/* work with positive numbers */
if (value < 0)
{
value = -value;
strcpy(buf, "minus ");
p += 6;
}
else
buf[0] = '\0';
/* Now treat as unsigned, to avoid trouble at INT_MIN */
val = (uint64) value;
m0 = val % INT64CONST(100); /* cents */
m1 = (val / INT64CONST(100)) % 1000; /* hundreds */
m2 = (val / INT64CONST(100000)) % 1000; /* thousands */
m3 = (val / INT64CONST(100000000)) % 1000; /* millions */
m4 = (val / INT64CONST(100000000000)) % 1000; /* billions */
m5 = (val / INT64CONST(100000000000000)) % 1000; /* trillions */
m6 = (val / INT64CONST(100000000000000000)) % 1000; /* quadrillions */
if (m6)
{
strcat(buf, num_word(m6));
strcat(buf, " quadrillion ");
}
if (m5)
{
strcat(buf, num_word(m5));
strcat(buf, " trillion ");
}
if (m4)
{
strcat(buf, num_word(m4));
strcat(buf, " billion ");
}
if (m3)
{
strcat(buf, num_word(m3));
strcat(buf, " million ");
}
if (m2)
{
strcat(buf, num_word(m2));
strcat(buf, " thousand ");
}
if (m1)
strcat(buf, num_word(m1));
if (!*p)
strcat(buf, "zero");
strcat(buf, (val / 100) == 1 ? " dollar and " : " dollars and ");
strcat(buf, num_word(m0));
strcat(buf, m0 == 1 ? " cent" : " cents");
/* capitalize output */
buf[0] = pg_toupper((unsigned char) buf[0]);
/* make a text type for output */
result = (text *) palloc(strlen(buf) + VARHDRSZ);
SET_VARSIZE(result, strlen(buf) + VARHDRSZ);
memcpy(VARDATA(result), buf, strlen(buf));
PG_RETURN_TEXT_P(result);
}
示例10: bpchar
/*
* Converts a CHARACTER type to the specified size.
*
* maxlen is the typmod, ie, declared length plus VARHDRSZ bytes.
* isExplicit is true if this is for an explicit cast to char(N).
*
* Truncation rules: for an explicit cast, silently truncate to the given
* length; for an implicit cast, raise error unless extra characters are
* all spaces. (This is sort-of per SQL: the spec would actually have us
* raise a "completion condition" for the explicit cast case, but Postgres
* hasn't got such a concept.)
*/
Datum
bpchar(PG_FUNCTION_ARGS)
{
BpChar *source = PG_GETARG_BPCHAR_P(0);
int32 maxlen = PG_GETARG_INT32(1);
bool isExplicit = PG_GETARG_BOOL(2);
BpChar *result;
int32 len;
char *r;
char *s;
int i;
int charlen; /* number of characters in the input string +
* VARHDRSZ */
/* No work if typmod is invalid */
if (maxlen < (int32) VARHDRSZ)
PG_RETURN_BPCHAR_P(source);
len = VARSIZE(source);
charlen = pg_mbstrlen_with_len(VARDATA(source), len - VARHDRSZ) + VARHDRSZ;
/* No work if supplied data matches typmod already */
if (charlen == maxlen)
PG_RETURN_BPCHAR_P(source);
if (charlen > maxlen)
{
/* Verify that extra characters are spaces, and clip them off */
size_t maxmblen;
maxmblen = pg_mbcharcliplen(VARDATA(source), len - VARHDRSZ,
maxlen - VARHDRSZ) + VARHDRSZ;
if (!isExplicit)
{
for (i = maxmblen - VARHDRSZ; i < len - VARHDRSZ; i++)
if (*(VARDATA(source) + i) != ' ')
ereport(ERROR,
(errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
errmsg("value too long for type character(%d)",
maxlen - VARHDRSZ)));
}
len = maxmblen;
/*
* XXX: at this point, maxlen is the necessary byte length+VARHDRSZ,
* not the number of CHARACTERS!
*/
maxlen = len;
}
else
{
/*
* XXX: at this point, maxlen is the necessary byte length+VARHDRSZ,
* not the number of CHARACTERS!
*/
maxlen = len + (maxlen - charlen);
}
s = VARDATA(source);
result = palloc(maxlen);
VARATT_SIZEP(result) = maxlen;
r = VARDATA(result);
memcpy(r, s, len - VARHDRSZ);
/* blank pad the string if necessary */
if (maxlen > len)
memset(r + len - VARHDRSZ, ' ', maxlen - len);
PG_RETURN_BPCHAR_P(result);
}
示例11: bpchar_input
/*
* bpchar_input -- common guts of bpcharin and bpcharrecv
*
* s is the input text of length len (may not be null-terminated)
* atttypmod is the typmod value to apply
*
* Note that atttypmod is measured in characters, which
* is not necessarily the same as the number of bytes.
*
* If the input string is too long, raise an error, unless the extra
* characters are spaces, in which case they're truncated. (per SQL)
*/
static BpChar *
bpchar_input(const char *s, size_t len, int32 atttypmod)
{
BpChar *result;
char *r;
size_t maxlen;
/* verify encoding */
pg_verifymbstr(s, len, false);
/* If typmod is -1 (or invalid), use the actual string length */
if (atttypmod < (int32) VARHDRSZ)
maxlen = len;
else
{
size_t charlen; /* number of CHARACTERS in the input */
maxlen = atttypmod - VARHDRSZ;
charlen = pg_mbstrlen_with_len(s, len);
if (charlen > maxlen)
{
/* Verify that extra characters are spaces, and clip them off */
size_t mbmaxlen = pg_mbcharcliplen(s, len, maxlen);
size_t j;
/*
* at this point, len is the actual BYTE length of the input
* string, maxlen is the max number of CHARACTERS allowed for this
* bpchar type, mbmaxlen is the length in BYTES of those chars.
*/
for (j = mbmaxlen; j < len; j++)
{
if (s[j] != ' ')
ereport(ERROR,
(errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
errmsg("value too long for type character(%d)",
(int) maxlen)));
}
/*
* Now we set maxlen to the necessary byte length, not the number
* of CHARACTERS!
*/
maxlen = len = mbmaxlen;
}
else
{
/*
* Now we set maxlen to the necessary byte length, not the number
* of CHARACTERS!
*/
maxlen = len + (maxlen - charlen);
}
}
result = (BpChar *) palloc(maxlen + VARHDRSZ);
VARATT_SIZEP(result) = maxlen + VARHDRSZ;
r = VARDATA(result);
memcpy(r, s, len);
/* blank pad the string if necessary */
if (maxlen > len)
memset(r + len, ' ', maxlen - len);
return result;
}
示例12: 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);
}
示例13: 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;
#ifdef PGXC
/*
* If we are having DataRow-based tuple we do not have to encode attribute
* values, just send over the DataRow message as we received it from the
* Datanode
*/
if (slot->tts_dataRow)
{
pq_putmessage('D', slot->tts_dataRow, slot->tts_dataLen);
return;
}
#endif
/* 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);
}
示例14: gin_page_opaque_info
Datum
gin_page_opaque_info(PG_FUNCTION_ARGS)
{
bytea *raw_page = PG_GETARG_BYTEA_P(0);
int raw_page_size;
TupleDesc tupdesc;
Page page;
GinPageOpaque opaq;
HeapTuple resultTuple;
Datum values[3];
bool nulls[10];
Datum flags[16];
int nflags = 0;
uint16 flagbits;
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 (raw_page_size < BLCKSZ)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("input page too small (%d bytes)", raw_page_size)));
page = VARDATA(raw_page);
opaq = (GinPageOpaque) PageGetSpecialPointer(page);
/* 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");
/* Convert the flags bitmask to an array of human-readable names */
flagbits = opaq->flags;
if (flagbits & GIN_DATA)
flags[nflags++] = CStringGetTextDatum("data");
if (flagbits & GIN_LEAF)
flags[nflags++] = CStringGetTextDatum("leaf");
if (flagbits & GIN_DELETED)
flags[nflags++] = CStringGetTextDatum("deleted");
if (flagbits & GIN_META)
flags[nflags++] = CStringGetTextDatum("meta");
if (flagbits & GIN_LIST)
flags[nflags++] = CStringGetTextDatum("list");
if (flagbits & GIN_LIST_FULLROW)
flags[nflags++] = CStringGetTextDatum("list_fullrow");
if (flagbits & GIN_INCOMPLETE_SPLIT)
flags[nflags++] = CStringGetTextDatum("incomplete_split");
if (flagbits & GIN_COMPRESSED)
flags[nflags++] = CStringGetTextDatum("compressed");
flagbits &= ~(GIN_DATA | GIN_LEAF | GIN_DELETED | GIN_META | GIN_LIST |
GIN_LIST_FULLROW | GIN_INCOMPLETE_SPLIT | GIN_COMPRESSED);
if (flagbits)
{
/* any flags we don't recognize are printed in hex */
flags[nflags++] = DirectFunctionCall1(to_hex32, Int32GetDatum(flagbits));
}
memset(nulls, 0, sizeof(nulls));
values[0] = Int64GetDatum(opaq->rightlink);
values[1] = Int64GetDatum(opaq->maxoff);
values[2] = PointerGetDatum(
construct_array(flags, nflags, TEXTOID, -1, false, 'i'));
/* Build and return the result tuple. */
resultTuple = heap_form_tuple(tupdesc, values, nulls);
return HeapTupleGetDatum(resultTuple);
}
示例15: page_header
Datum
page_header(PG_FUNCTION_ARGS)
{
bytea *raw_page = PG_GETARG_BYTEA_P(0);
int raw_page_size;
TupleDesc tupdesc;
Datum result;
HeapTuple tuple;
Datum values[9];
bool nulls[9];
PageHeader page;
XLogRecPtr lsn;
char lsnchar[64];
if (!superuser())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
(errmsg("must be superuser to use raw page functions"))));
raw_page_size = VARSIZE(raw_page) - VARHDRSZ;
/*
* Check that enough data was supplied, so that we don't try to access
* fields outside the supplied buffer.
*/
if (raw_page_size < sizeof(PageHeaderData))
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("input page too small (%d bytes)", raw_page_size)));
page = (PageHeader) VARDATA(raw_page);
/* 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");
/* Extract information from the page header */
lsn = PageGetLSN(page);
snprintf(lsnchar, sizeof(lsnchar), "%X/%X", lsn.xlogid, lsn.xrecoff);
values[0] = CStringGetTextDatum(lsnchar);
values[1] = UInt16GetDatum(PageGetTLI(page));
values[2] = UInt16GetDatum(page->pd_flags);
values[3] = UInt16GetDatum(page->pd_lower);
values[4] = UInt16GetDatum(page->pd_upper);
values[5] = UInt16GetDatum(page->pd_special);
values[6] = UInt16GetDatum(PageGetPageSize(page));
values[7] = UInt16GetDatum(PageGetPageLayoutVersion(page));
values[8] = TransactionIdGetDatum(page->pd_prune_xid);
/* Build and return the tuple. */
memset(nulls, 0, sizeof(nulls));
tuple = heap_form_tuple(tupdesc, values, nulls);
result = HeapTupleGetDatum(tuple);
PG_RETURN_DATUM(result);
}