本文整理汇总了C++中RelationGetDescr函数的典型用法代码示例。如果您正苦于以下问题:C++ RelationGetDescr函数的具体用法?C++ RelationGetDescr怎么用?C++ RelationGetDescr使用的例子?那么, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了RelationGetDescr函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: logicalrep_write_tuple
/*
* Write a tuple to the outputstream, in the most efficient format possible.
*/
static void
logicalrep_write_tuple(StringInfo out, Relation rel, HeapTuple tuple)
{
TupleDesc desc;
Datum values[MaxTupleAttributeNumber];
bool isnull[MaxTupleAttributeNumber];
int i;
uint16 nliveatts = 0;
desc = RelationGetDescr(rel);
for (i = 0; i < desc->natts; i++)
{
if (TupleDescAttr(desc, i)->attisdropped)
continue;
nliveatts++;
}
pq_sendint(out, nliveatts, 2);
/* try to allocate enough memory from the get-go */
enlargeStringInfo(out, tuple->t_len +
nliveatts * (1 + 4));
heap_deform_tuple(tuple, desc, values, isnull);
/* Write the values */
for (i = 0; i < desc->natts; i++)
{
HeapTuple typtup;
Form_pg_type typclass;
Form_pg_attribute att = TupleDescAttr(desc, i);
char *outputstr;
/* skip dropped columns */
if (att->attisdropped)
continue;
if (isnull[i])
{
pq_sendbyte(out, 'n'); /* null column */
continue;
}
else if (att->attlen == -1 && VARATT_IS_EXTERNAL_ONDISK(values[i]))
{
pq_sendbyte(out, 'u'); /* unchanged toast column */
continue;
}
typtup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(att->atttypid));
if (!HeapTupleIsValid(typtup))
elog(ERROR, "cache lookup failed for type %u", att->atttypid);
typclass = (Form_pg_type) GETSTRUCT(typtup);
pq_sendbyte(out, 't'); /* 'text' data follows */
outputstr = OidOutputFunctionCall(typclass->typoutput, values[i]);
pq_sendcountedtext(out, outputstr, strlen(outputstr), false);
pfree(outputstr);
ReleaseSysCache(typtup);
}
}
示例2: _bt_load
/*
* Read tuples in correct sort order from tuplesort, and load them into
* btree leaves.
*/
static void
_bt_load(BTWriteState *wstate, BTSpool *btspool, BTSpool *btspool2)
{
BTPageState *state = NULL;
bool merge = (btspool2 != NULL);
IndexTuple itup,
itup2 = NULL;
bool should_free,
should_free2,
load1;
TupleDesc tupdes = RelationGetDescr(wstate->index);
int i,
keysz = RelationGetNumberOfAttributes(wstate->index);
ScanKey indexScanKey = NULL;
if (merge)
{
/*
* Another BTSpool for dead tuples exists. Now we have to merge
* btspool and btspool2.
*/
/* the preparation of merge */
itup = tuplesort_getindextuple(btspool->sortstate,
true, &should_free);
itup2 = tuplesort_getindextuple(btspool2->sortstate,
true, &should_free2);
indexScanKey = _bt_mkscankey_nodata(wstate->index);
for (;;)
{
load1 = true; /* load BTSpool next ? */
if (itup2 == NULL)
{
if (itup == NULL)
break;
}
else if (itup != NULL)
{
for (i = 1; i <= keysz; i++)
{
ScanKey entry;
Datum attrDatum1,
attrDatum2;
bool isNull1,
isNull2;
int32 compare;
entry = indexScanKey + i - 1;
attrDatum1 = index_getattr(itup, i, tupdes, &isNull1);
attrDatum2 = index_getattr(itup2, i, tupdes, &isNull2);
if (isNull1)
{
if (isNull2)
compare = 0; /* NULL "=" NULL */
else if (entry->sk_flags & SK_BT_NULLS_FIRST)
compare = -1; /* NULL "<" NOT_NULL */
else
compare = 1; /* NULL ">" NOT_NULL */
}
else if (isNull2)
{
if (entry->sk_flags & SK_BT_NULLS_FIRST)
compare = 1; /* NOT_NULL ">" NULL */
else
compare = -1; /* NOT_NULL "<" NULL */
}
else
{
compare =
DatumGetInt32(FunctionCall2Coll(&entry->sk_func,
entry->sk_collation,
attrDatum1,
attrDatum2));
if (entry->sk_flags & SK_BT_DESC)
compare = -compare;
}
if (compare > 0)
{
load1 = false;
break;
}
else if (compare < 0)
break;
}
}
else
load1 = false;
/* When we see first tuple, create first index page */
if (state == NULL)
state = _bt_pagestate(wstate, 0);
if (load1)
{
//.........这里部分代码省略.........
示例3: find_language_template
/*
* Look to see if we have template information for the given language name.
*/
static PLTemplate *
find_language_template(const char *languageName)
{
PLTemplate *result;
Relation rel;
SysScanDesc scan;
ScanKeyData key;
HeapTuple tup;
rel = heap_open(PLTemplateRelationId, AccessShareLock);
ScanKeyInit(&key,
Anum_pg_pltemplate_tmplname,
BTEqualStrategyNumber, F_NAMEEQ,
CStringGetDatum(languageName));
scan = systable_beginscan(rel, PLTemplateNameIndexId, true,
NULL, 1, &key);
tup = systable_getnext(scan);
if (HeapTupleIsValid(tup))
{
Form_pg_pltemplate tmpl = (Form_pg_pltemplate) GETSTRUCT(tup);
Datum datum;
bool isnull;
result = (PLTemplate *) palloc0(sizeof(PLTemplate));
result->tmpltrusted = tmpl->tmpltrusted;
result->tmpldbacreate = tmpl->tmpldbacreate;
/* Remaining fields are variable-width so we need heap_getattr */
datum = heap_getattr(tup, Anum_pg_pltemplate_tmplhandler,
RelationGetDescr(rel), &isnull);
if (!isnull)
result->tmplhandler = TextDatumGetCString(datum);
datum = heap_getattr(tup, Anum_pg_pltemplate_tmplinline,
RelationGetDescr(rel), &isnull);
if (!isnull)
result->tmplinline = TextDatumGetCString(datum);
datum = heap_getattr(tup, Anum_pg_pltemplate_tmplvalidator,
RelationGetDescr(rel), &isnull);
if (!isnull)
result->tmplvalidator = TextDatumGetCString(datum);
datum = heap_getattr(tup, Anum_pg_pltemplate_tmpllibrary,
RelationGetDescr(rel), &isnull);
if (!isnull)
result->tmpllibrary = TextDatumGetCString(datum);
/* Ignore template if handler or library info is missing */
if (!result->tmplhandler || !result->tmpllibrary)
result = NULL;
}
else
result = NULL;
systable_endscan(scan);
heap_close(rel, AccessShareLock);
return result;
}
示例4: TypeCreate
//.........这里部分代码省略.........
* NOTE: updating will not work correctly in bootstrap mode; but we don't
* expect to be overwriting any shell types in bootstrap mode.
*/
pg_type_desc = heap_open(TypeRelationId, RowExclusiveLock);
tup = SearchSysCacheCopy2(TYPENAMENSP,
CStringGetDatum(typeName),
ObjectIdGetDatum(typeNamespace));
if (HeapTupleIsValid(tup))
{
/*
* check that the type is not already defined. It may exist as a
* shell type, however.
*/
if (((Form_pg_type) GETSTRUCT(tup))->typisdefined)
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("type \"%s\" already exists", typeName)));
/*
* shell type must have been created by same owner
*/
if (((Form_pg_type) GETSTRUCT(tup))->typowner != ownerId)
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TYPE, typeName);
/* trouble if caller wanted to force the OID */
if (OidIsValid(newTypeOid))
elog(ERROR, "cannot assign new OID to existing shell type");
/*
* Okay to update existing shell type tuple
*/
tup = heap_modify_tuple(tup,
RelationGetDescr(pg_type_desc),
values,
nulls,
replaces);
simple_heap_update(pg_type_desc, &tup->t_self, tup);
typeObjectId = HeapTupleGetOid(tup);
rebuildDeps = true; /* get rid of shell type's dependencies */
}
else
{
tup = heap_form_tuple(RelationGetDescr(pg_type_desc),
values,
nulls);
/* Force the OID if requested by caller */
if (OidIsValid(newTypeOid))
HeapTupleSetOid(tup, newTypeOid);
else if (OidIsValid(binary_upgrade_next_pg_type_oid))
{
HeapTupleSetOid(tup, binary_upgrade_next_pg_type_oid);
binary_upgrade_next_pg_type_oid = InvalidOid;
}
/* else allow system to assign oid */
typeObjectId = simple_heap_insert(pg_type_desc, tup);
}
/* Update indexes */
CatalogUpdateIndexes(pg_type_desc, tup);
示例5: AlterTableSpaceOptions
/*
* Alter table space options
*/
void
AlterTableSpaceOptions(AlterTableSpaceOptionsStmt *stmt)
{
Relation rel;
ScanKeyData entry[1];
HeapScanDesc scandesc;
HeapTuple tup;
Datum datum;
Datum newOptions;
Datum repl_val[Natts_pg_tablespace];
bool isnull;
bool repl_null[Natts_pg_tablespace];
bool repl_repl[Natts_pg_tablespace];
HeapTuple newtuple;
/* Search pg_tablespace */
rel = heap_open(TableSpaceRelationId, RowExclusiveLock);
ScanKeyInit(&entry[0],
Anum_pg_tablespace_spcname,
BTEqualStrategyNumber, F_NAMEEQ,
CStringGetDatum(stmt->tablespacename));
scandesc = heap_beginscan(rel, SnapshotNow, 1, entry);
tup = heap_getnext(scandesc, ForwardScanDirection);
if (!HeapTupleIsValid(tup))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("tablespace \"%s\" does not exist",
stmt->tablespacename)));
/* Must be owner of the existing object */
if (!pg_tablespace_ownercheck(HeapTupleGetOid(tup), GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TABLESPACE,
stmt->tablespacename);
/* Generate new proposed spcoptions (text array) */
datum = heap_getattr(tup, Anum_pg_tablespace_spcoptions,
RelationGetDescr(rel), &isnull);
newOptions = transformRelOptions(isnull ? (Datum) 0 : datum,
stmt->options, NULL, NULL, false,
stmt->isReset);
(void) tablespace_reloptions(newOptions, true);
/* Build new tuple. */
memset(repl_null, false, sizeof(repl_null));
memset(repl_repl, false, sizeof(repl_repl));
if (newOptions != (Datum) 0)
repl_val[Anum_pg_tablespace_spcoptions - 1] = newOptions;
else
repl_null[Anum_pg_tablespace_spcoptions - 1] = true;
repl_repl[Anum_pg_tablespace_spcoptions - 1] = true;
newtuple = heap_modify_tuple(tup, RelationGetDescr(rel), repl_val,
repl_null, repl_repl);
/* Update system catalog. */
simple_heap_update(rel, &newtuple->t_self, newtuple);
CatalogUpdateIndexes(rel, newtuple);
heap_freetuple(newtuple);
/* Conclude heap scan. */
heap_endscan(scandesc);
heap_close(rel, NoLock);
}
示例6: _bt_compare
/*----------
* _bt_compare() -- Compare scankey to a particular tuple on the page.
*
* The passed scankey must be an insertion-type scankey (see nbtree/README),
* but it can omit the rightmost column(s) of the index.
*
* keysz: number of key conditions to be checked (might be less than the
* number of index columns!)
* page/offnum: location of btree item to be compared to.
*
* This routine returns:
* <0 if scankey < tuple at offnum;
* 0 if scankey == tuple at offnum;
* >0 if scankey > tuple at offnum.
* NULLs in the keys are treated as sortable values. Therefore
* "equality" does not necessarily mean that the item should be
* returned to the caller as a matching key!
*
* CRUCIAL NOTE: on a non-leaf page, the first data key is assumed to be
* "minus infinity": this routine will always claim it is less than the
* scankey. The actual key value stored (if any, which there probably isn't)
* does not matter. This convention allows us to implement the Lehman and
* Yao convention that the first down-link pointer is before the first key.
* See backend/access/nbtree/README for details.
*----------
*/
int32
_bt_compare(Relation rel,
int keysz,
ScanKey scankey,
Page page,
OffsetNumber offnum)
{
TupleDesc itupdesc = RelationGetDescr(rel);
BTPageOpaque opaque = (BTPageOpaque) PageGetSpecialPointer(page);
IndexTuple itup;
int i;
/*
* Force result ">" if target item is first data item on an internal page
* --- see NOTE above.
*/
if (!P_ISLEAF(opaque) && offnum == P_FIRSTDATAKEY(opaque))
return 1;
itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, offnum));
/*
* The scan key is set up with the attribute number associated with each
* term in the key. It is important that, if the index is multi-key, the
* scan contain the first k key attributes, and that they be in order. If
* you think about how multi-key ordering works, you'll understand why
* this is.
*
* We don't test for violation of this condition here, however. The
* initial setup for the index scan had better have gotten it right (see
* _bt_first).
*/
for (i = 1; i <= keysz; i++)
{
Datum datum;
bool isNull;
int32 result;
datum = index_getattr(itup, scankey->sk_attno, itupdesc, &isNull);
/* see comments about NULLs handling in btbuild */
if (scankey->sk_flags & SK_ISNULL) /* key is NULL */
{
if (isNull)
result = 0; /* NULL "=" NULL */
else if (scankey->sk_flags & SK_BT_NULLS_FIRST)
result = -1; /* NULL "<" NOT_NULL */
else
result = 1; /* NULL ">" NOT_NULL */
}
else if (isNull) /* key is NOT_NULL and item is NULL */
{
if (scankey->sk_flags & SK_BT_NULLS_FIRST)
result = 1; /* NOT_NULL ">" NULL */
else
result = -1; /* NOT_NULL "<" NULL */
}
else
{
/*
* The sk_func needs to be passed the index value as left arg and
* the sk_argument as right arg (they might be of different
* types). Since it is convenient for callers to think of
* _bt_compare as comparing the scankey to the index item, we have
* to flip the sign of the comparison result. (Unless it's a DESC
* column, in which case we *don't* flip the sign.)
*/
result = DatumGetInt32(FunctionCall2(&scankey->sk_func,
datum,
scankey->sk_argument));
if (!(scankey->sk_flags & SK_BT_DESC))
result = -result;
//.........这里部分代码省略.........
示例7: pg_shard_get_tableschemadef_string
/*
* pg_get_tableschemadef_string returns the definition of a given table. This
* definition includes table's schema, default column values, not null and check
* constraints. The definition does not include constraints that trigger index
* creations; specifically, unique and primary key constraints are excluded.
*/
static char *
pg_shard_get_tableschemadef_string(Oid tableRelationId)
{
Relation relation = NULL;
char *relationName = NULL;
char relationKind = 0;
TupleDesc tupleDescriptor = NULL;
TupleConstr *tupleConstraints = NULL;
int attributeIndex = 0;
bool firstAttributePrinted = false;
AttrNumber defaultValueIndex = 0;
AttrNumber constraintIndex = 0;
AttrNumber constraintCount = 0;
StringInfoData buffer = { NULL, 0, 0, 0 };
/*
* Instead of retrieving values from system catalogs as other functions in
* ruleutils.c do, we follow an unusual approach here: we open the relation,
* and fetch the relation's tuple descriptor. We do this because the tuple
* descriptor already contains information harnessed from pg_attrdef,
* pg_attribute, pg_constraint, and pg_class; and therefore using the
* descriptor saves us from a lot of additional work.
*/
relation = relation_open(tableRelationId, AccessShareLock);
relationName = generate_relation_name(tableRelationId);
relationKind = relation->rd_rel->relkind;
if (relationKind != RELKIND_RELATION && relationKind != RELKIND_FOREIGN_TABLE)
{
ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("%s is not a regular or foreign table", relationName)));
}
initStringInfo(&buffer);
if (relationKind == RELKIND_RELATION)
{
appendStringInfo(&buffer, "CREATE TABLE %s (", relationName);
}
else
{
appendStringInfo(&buffer, "CREATE FOREIGN TABLE %s (", relationName);
}
/*
* Iterate over the table's columns. If a particular column is not dropped
* and is not inherited from another table, print the column's name and its
* formatted type.
*/
tupleDescriptor = RelationGetDescr(relation);
tupleConstraints = tupleDescriptor->constr;
for (attributeIndex = 0; attributeIndex < tupleDescriptor->natts; attributeIndex++)
{
Form_pg_attribute attributeForm = tupleDescriptor->attrs[attributeIndex];
if (!attributeForm->attisdropped && attributeForm->attinhcount == 0)
{
const char *attributeName = NULL;
const char *attributeTypeName = NULL;
if (firstAttributePrinted)
{
appendStringInfoString(&buffer, ", ");
}
firstAttributePrinted = true;
attributeName = NameStr(attributeForm->attname);
appendStringInfo(&buffer, "%s ", quote_identifier(attributeName));
attributeTypeName = format_type_with_typemod(attributeForm->atttypid,
attributeForm->atttypmod);
appendStringInfoString(&buffer, attributeTypeName);
/* if this column has a default value, append the default value */
if (attributeForm->atthasdef)
{
AttrDefault *defaultValueList = NULL;
AttrDefault *defaultValue = NULL;
Node *defaultNode = NULL;
List *defaultContext = NULL;
char *defaultString = NULL;
Assert(tupleConstraints != NULL);
defaultValueList = tupleConstraints->defval;
Assert(defaultValueList != NULL);
defaultValue = &(defaultValueList[defaultValueIndex]);
defaultValueIndex++;
Assert(defaultValue->adnum == (attributeIndex + 1));
Assert(defaultValueIndex <= tupleConstraints->num_defval);
//.........这里部分代码省略.........
示例8: _bitmap_init_buildstate
/*
* _bitmap_init_buildstate() -- initialize the build state before building
* a bitmap index.
*/
void
_bitmap_init_buildstate(Relation index, BMBuildState *bmstate)
{
MIRROREDLOCK_BUFMGR_DECLARE;
BMMetaPage mp;
HASHCTL hash_ctl;
int hash_flags;
int i;
Buffer metabuf;
/* initialize the build state */
bmstate->bm_tupDesc = RelationGetDescr(index);
bmstate->bm_tidLocsBuffer = (BMTidBuildBuf *)
palloc(sizeof(BMTidBuildBuf));
bmstate->bm_tidLocsBuffer->byte_size = 0;
bmstate->bm_tidLocsBuffer->lov_blocks = NIL;
bmstate->bm_tidLocsBuffer->max_lov_block = InvalidBlockNumber;
// -------- MirroredLock ----------
MIRROREDLOCK_BUFMGR_LOCK;
metabuf = _bitmap_getbuf(index, BM_METAPAGE, BM_READ);
mp = _bitmap_get_metapage_data(index, metabuf);
_bitmap_open_lov_heapandindex(index, mp, &(bmstate->bm_lov_heap),
&(bmstate->bm_lov_index),
RowExclusiveLock);
_bitmap_relbuf(metabuf);
MIRROREDLOCK_BUFMGR_UNLOCK;
// -------- MirroredLock ----------
cur_bmbuild = (BMBuildHashData *)palloc(sizeof(BMBuildHashData));
cur_bmbuild->hash_funcs = (FmgrInfo *)
palloc(sizeof(FmgrInfo) * bmstate->bm_tupDesc->natts);
cur_bmbuild->eq_funcs = (FmgrInfo *)
palloc(sizeof(FmgrInfo) * bmstate->bm_tupDesc->natts);
cur_bmbuild->hash_func_is_strict = (bool *)
palloc(sizeof(bool) * bmstate->bm_tupDesc->natts);
for (i = 0; i < bmstate->bm_tupDesc->natts; i++)
{
Oid typid = bmstate->bm_tupDesc->attrs[i]->atttypid;
Operator optup;
Oid eq_opr;
Oid eq_function;
Oid left_hash_function;
Oid right_hash_function;
optup = equality_oper(typid, false);
eq_opr = oprid(optup);
eq_function = oprfuncid(optup);
ReleaseOperator(optup);
if (!get_op_hash_functions(eq_opr,
&left_hash_function,
&right_hash_function))
{
pfree(cur_bmbuild);
cur_bmbuild = NULL;
break;
}
Assert(left_hash_function == right_hash_function);
fmgr_info(eq_function, &cur_bmbuild->eq_funcs[i]);
fmgr_info(right_hash_function, &cur_bmbuild->hash_funcs[i]);
cur_bmbuild->hash_func_is_strict[i] = func_strict(right_hash_function);
}
if (cur_bmbuild)
{
cur_bmbuild->natts = bmstate->bm_tupDesc->natts;
cur_bmbuild->tmpcxt = AllocSetContextCreate(CurrentMemoryContext,
"Bitmap build temp space",
ALLOCSET_DEFAULT_MINSIZE,
ALLOCSET_DEFAULT_INITSIZE,
ALLOCSET_DEFAULT_MAXSIZE);
/* setup the hash table */
MemSet(&hash_ctl, 0, sizeof(hash_ctl));
/**
* Reserve enough space for the hash key header and then the data segments (values followed by nulls)
*/
hash_ctl.keysize = MAXALIGN(sizeof(BMBuildHashKey)) +
MAXALIGN(sizeof(Datum) * cur_bmbuild->natts) +
MAXALIGN(sizeof(bool) * cur_bmbuild->natts);
hash_ctl.entrysize = hash_ctl.keysize + sizeof(BMBuildLovData) + 200;
hash_ctl.hash = build_hash_key;
hash_ctl.match = build_match_key;
hash_ctl.keycopy = build_keycopy;
hash_ctl.hcxt = AllocSetContextCreate(CurrentMemoryContext,
"Bitmap build hash table",
//.........这里部分代码省略.........
示例9: shdepChangeDep
//.........这里部分代码省略.........
HeapTuple oldtup = NULL;
HeapTuple scantup;
ScanKeyData key[4];
SysScanDesc scan;
/*
* Make sure the new referenced object doesn't go away while we record the
* dependency.
*/
shdepLockAndCheckObject(refclassid, refobjid);
/*
* Look for a previous entry
*/
ScanKeyInit(&key[0],
Anum_pg_shdepend_dbid,
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(dbid));
ScanKeyInit(&key[1],
Anum_pg_shdepend_classid,
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(classid));
ScanKeyInit(&key[2],
Anum_pg_shdepend_objid,
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(objid));
ScanKeyInit(&key[3],
Anum_pg_shdepend_objsubid,
BTEqualStrategyNumber, F_INT4EQ,
Int32GetDatum(objsubid));
scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true,
NULL, 4, key);
while ((scantup = systable_getnext(scan)) != NULL)
{
/* Ignore if not of the target dependency type */
if (((Form_pg_shdepend) GETSTRUCT(scantup))->deptype != deptype)
continue;
/* Caller screwed up if multiple matches */
if (oldtup)
elog(ERROR,
"multiple pg_shdepend entries for object %u/%u/%d deptype %c",
classid, objid, objsubid, deptype);
oldtup = heap_copytuple(scantup);
}
systable_endscan(scan);
if (isSharedObjectPinned(refclassid, refobjid, sdepRel))
{
/* No new entry needed, so just delete existing entry if any */
if (oldtup)
simple_heap_delete(sdepRel, &oldtup->t_self);
}
else if (oldtup)
{
/* Need to update existing entry */
Form_pg_shdepend shForm = (Form_pg_shdepend) GETSTRUCT(oldtup);
/* Since oldtup is a copy, we can just modify it in-memory */
shForm->refclassid = refclassid;
shForm->refobjid = refobjid;
simple_heap_update(sdepRel, &oldtup->t_self, oldtup);
/* keep indexes current */
CatalogUpdateIndexes(sdepRel, oldtup);
}
else
{
/* Need to insert new entry */
Datum values[Natts_pg_shdepend];
bool nulls[Natts_pg_shdepend];
memset(nulls, false, sizeof(nulls));
values[Anum_pg_shdepend_dbid - 1] = ObjectIdGetDatum(dbid);
values[Anum_pg_shdepend_classid - 1] = ObjectIdGetDatum(classid);
values[Anum_pg_shdepend_objid - 1] = ObjectIdGetDatum(objid);
values[Anum_pg_shdepend_objsubid - 1] = Int32GetDatum(objsubid);
values[Anum_pg_shdepend_refclassid - 1] = ObjectIdGetDatum(refclassid);
values[Anum_pg_shdepend_refobjid - 1] = ObjectIdGetDatum(refobjid);
values[Anum_pg_shdepend_deptype - 1] = CharGetDatum(deptype);
/*
* we are reusing oldtup just to avoid declaring a new variable, but
* it's certainly a new tuple
*/
oldtup = heap_form_tuple(RelationGetDescr(sdepRel), values, nulls);
simple_heap_insert(sdepRel, oldtup);
/* keep indexes current */
CatalogUpdateIndexes(sdepRel, oldtup);
}
if (oldtup)
heap_freetuple(oldtup);
}
示例10: unique_key_recheck
//.........这里部分代码省略.........
* we still need to make the check --- effectively, we're applying the
* check against the live child row, although we can use the values from
* this row since by definition all columns of interest to us are the
* same.
*
* This might look like just an optimization, because the index AM will
* make this identical test before throwing an error. But it's actually
* needed for correctness, because the index AM will also throw an error
* if it doesn't find the index entry for the row. If the row's dead then
* it's possible the index entry has also been marked dead, and even
* removed.
*/
tmptid = new_row->t_self;
if (!heap_hot_search(&tmptid, trigdata->tg_relation, SnapshotSelf, NULL))
{
/*
* All rows in the HOT chain are dead, so skip the check.
*/
return PointerGetDatum(NULL);
}
/*
* Open the index, acquiring a RowExclusiveLock, just as if we were going
* to update it. (This protects against possible changes of the index
* schema, not against concurrent updates.)
*/
indexRel = index_open(trigdata->tg_trigger->tgconstrindid,
RowExclusiveLock);
indexInfo = BuildIndexInfo(indexRel);
/*
* The heap tuple must be put into a slot for FormIndexDatum.
*/
slot = MakeSingleTupleTableSlot(RelationGetDescr(trigdata->tg_relation));
ExecStoreHeapTuple(new_row, slot, InvalidBuffer, false);
/*
* Typically the index won't have expressions, but if it does we need an
* EState to evaluate them. We need it for exclusion constraints too,
* even if they are just on simple columns.
*/
if (indexInfo->ii_Expressions != NIL ||
indexInfo->ii_ExclusionOps != NULL)
{
estate = CreateExecutorState();
econtext = GetPerTupleExprContext(estate);
econtext->ecxt_scantuple = slot;
}
else
estate = NULL;
/*
* Form the index values and isnull flags for the index entry that we need
* to check.
*
* Note: if the index uses functions that are not as immutable as they are
* supposed to be, this could produce an index tuple different from the
* original. The index AM can catch such errors by verifying that it
* finds a matching index entry with the tuple's TID. For exclusion
* constraints we check this in check_exclusion_constraint().
*/
FormIndexDatum(indexInfo, slot, estate, values, isnull);
/*
* Now do the appropriate check.
示例11: ProcedureCreate
//.........这里部分代码省略.........
values[Anum_pg_proc_provolatile - 1] = CharGetDatum(volatility);
values[Anum_pg_proc_pronargs - 1] = UInt16GetDatum(parameterCount);
values[Anum_pg_proc_pronargdefaults - 1] = UInt16GetDatum(list_length(parameterDefaults));
values[Anum_pg_proc_prorettype - 1] = ObjectIdGetDatum(returnType);
values[Anum_pg_proc_proargtypes - 1] = PointerGetDatum(parameterTypes);
if (allParameterTypes != PointerGetDatum(NULL))
values[Anum_pg_proc_proallargtypes - 1] = allParameterTypes;
else
nulls[Anum_pg_proc_proallargtypes - 1] = true;
if (parameterModes != PointerGetDatum(NULL))
values[Anum_pg_proc_proargmodes - 1] = parameterModes;
else
nulls[Anum_pg_proc_proargmodes - 1] = true;
if (parameterNames != PointerGetDatum(NULL))
values[Anum_pg_proc_proargnames - 1] = parameterNames;
else
nulls[Anum_pg_proc_proargnames - 1] = true;
if (parameterDefaults != NIL)
values[Anum_pg_proc_proargdefaults - 1] = CStringGetTextDatum(nodeToString(parameterDefaults));
else
nulls[Anum_pg_proc_proargdefaults - 1] = true;
values[Anum_pg_proc_prosrc - 1] = CStringGetTextDatum(prosrc);
if (probin)
values[Anum_pg_proc_probin - 1] = CStringGetTextDatum(probin);
else
nulls[Anum_pg_proc_probin - 1] = true;
if (proconfig != PointerGetDatum(NULL))
values[Anum_pg_proc_proconfig - 1] = proconfig;
else
nulls[Anum_pg_proc_proconfig - 1] = true;
/* proacl will be determined later */
rel = heap_open(ProcedureRelationId, RowExclusiveLock);
tupDesc = RelationGetDescr(rel);
/* Check for pre-existing definition */
oldtup = SearchSysCache3(PROCNAMEARGSNSP,
PointerGetDatum(procedureName),
PointerGetDatum(parameterTypes),
ObjectIdGetDatum(procNamespace));
if (HeapTupleIsValid(oldtup))
{
/* There is one; okay to replace it? */
Form_pg_proc oldproc = (Form_pg_proc) GETSTRUCT(oldtup);
Datum proargnames;
bool isnull;
if (!replace)
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_FUNCTION),
errmsg("function \"%s\" already exists with same argument types",
procedureName)));
if (!pg_proc_ownercheck(HeapTupleGetOid(oldtup), proowner))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC,
procedureName);
/*
* Not okay to change the return type of the existing proc, since
* existing rules, views, etc may depend on the return type.
*/
if (returnType != oldproc->prorettype ||
returnsSet != oldproc->proretset)
ereport(ERROR,
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("cannot change return type of existing function"),
示例12: parquet_beginscan
/**
*begin scanning of a parquet relation
*/
ParquetScanDesc
parquet_beginscan(
Relation relation,
Snapshot parquetMetaDataSnapshot,
TupleDesc relationTupleDesc,
bool *proj)
{
ParquetScanDesc scan;
AppendOnlyEntry *aoEntry;
AppendOnlyStorageAttributes *attr;
/*
* increment relation ref count while scanning relation
*
* This is just to make really sure the relcache entry won't go away while
* the scan has a pointer to it. Caller should be holding the rel open
* anyway, so this is redundant in all normal scenarios...
*/
RelationIncrementReferenceCount(relation);
/* allocate scan descriptor */
scan = (ParquetScanDescData *)palloc0(sizeof(ParquetScanDescData));
/*
* Get the pg_appendonly information for this table
*/
aoEntry = GetAppendOnlyEntry(RelationGetRelid(relation), parquetMetaDataSnapshot);
scan->aoEntry = aoEntry;
Assert(aoEntry->majorversion == 1 && aoEntry->minorversion == 0);
#ifdef FAULT_INJECTOR
FaultInjector_InjectFaultIfSet(
FailQeWhenBeginParquetScan,
DDLNotSpecified,
"", // databaseName
""); // tableName
#endif
/*
* initialize the scan descriptor
*/
scan->pqs_filenamepath_maxlen = AOSegmentFilePathNameLen(relation) + 1;
scan->pqs_filenamepath = (char*)palloc0(scan->pqs_filenamepath_maxlen);
scan->pqs_rd = relation;
scan->parquetScanInitContext = CurrentMemoryContext;
/*
* Fill in Parquet Storage layer attributes.
*/
attr = &scan->storageAttributes;
/*
* These attributes describe the AppendOnly format to be scanned.
*/
if (aoEntry->compresstype == NULL || pg_strcasecmp(aoEntry->compresstype, "none") == 0)
attr->compress = false;
else
attr->compress = true;
if (aoEntry->compresstype != NULL)
attr->compressType = aoEntry->compresstype;
else
attr->compressType = "none";
attr->compressLevel = aoEntry->compresslevel;
attr->checksum = aoEntry->checksum;
attr->safeFSWriteSize = aoEntry->safefswritesize;
attr->splitsize = aoEntry->splitsize;
attr->version = aoEntry->version;
AORelationVersion_CheckValid(attr->version);
scan->proj = proj;
scan->pqs_tupDesc = (relationTupleDesc == NULL) ? RelationGetDescr(relation) : relationTupleDesc;
scan->hawqAttrToParquetColChunks = (int*)palloc0(scan->pqs_tupDesc->natts * sizeof(int));
initscan(scan);
return scan ;
}
示例13: initNextIndexToScan
/*
* This function initializes a part and returns true if a new index has been prepared for scanning.
*/
static bool
initNextIndexToScan(DynamicIndexScanState *node)
{
IndexScanState *indexState = &(node->indexScanState);
DynamicIndexScan *dynamicIndexScan = (DynamicIndexScan *)node->indexScanState.ss.ps.plan;
EState *estate = indexState->ss.ps.state;
/* Load new index when the scanning of the previous index is done. */
if (indexState->ss.scan_state == SCAN_INIT ||
indexState->ss.scan_state == SCAN_DONE)
{
/* This is the oid of a partition of the table (*not* index) */
Oid *pid = hash_seq_search(&node->pidxStatus);
if (pid == NULL)
{
/* Return if all parts have been scanned. */
node->shouldCallHashSeqTerm = false;
return false;
}
/* Collect number of partitions scanned in EXPLAIN ANALYZE */
if(NULL != indexState->ss.ps.instrument)
{
Instrumentation *instr = indexState->ss.ps.instrument;
instr->numPartScanned ++;
}
DynamicIndexScan_ReMapColumns(node, *pid);
/*
* The is the oid of the partition of an *index*. Note: a partitioned table
* has a root and a set of partitions (may be multi-level). An index
* on a partitioned table also has a root and a set of index partitions.
* We started at table level, and now we are fetching the oid of an index
* partition.
*/
Relation currentRelation = OpenScanRelationByOid(*pid);
indexState->ss.ss_currentRelation = currentRelation;
indexState->ss.ss_ScanTupleSlot->tts_tableOid = *pid;
ExecAssignScanType(&indexState->ss, RelationGetDescr(currentRelation));
/*
* Initialize result tuple type and projection info.
*/
ExecAssignResultTypeFromTL(&indexState->ss.ps);
ExecAssignScanProjectionInfo(&indexState->ss);
MemoryContextReset(node->partitionMemoryContext);
MemoryContext oldCxt = MemoryContextSwitchTo(node->partitionMemoryContext);
/* Initialize child expressions */
indexState->ss.ps.qual = (List *) ExecInitExpr((Expr *) indexState->ss.ps.plan->qual, (PlanState *) indexState);
indexState->ss.ps.targetlist = (List *) ExecInitExpr((Expr *) indexState->ss.ps.plan->targetlist, (PlanState *) indexState);
Oid pindex = getPhysicalIndexRelid(currentRelation, dynamicIndexScan->logicalIndexInfo);
Assert(OidIsValid(pindex));
indexState->iss_RelationDesc =
OpenIndexRelation(estate, pindex, *pid);
/*
* build the index scan keys from the index qualification
*/
ExecIndexBuildScanKeys((PlanState *) indexState,
indexState->iss_RelationDesc,
dynamicIndexScan->indexqual,
dynamicIndexScan->indexstrategy,
dynamicIndexScan->indexsubtype,
&indexState->iss_ScanKeys,
&indexState->iss_NumScanKeys,
&indexState->iss_RuntimeKeys,
&indexState->iss_NumRuntimeKeys,
NULL,
NULL);
MemoryContextSwitchTo(oldCxt);
if (indexState->iss_NumRuntimeKeys != 0)
{
ExecIndexEvalRuntimeKeys(indexState->iss_RuntimeContext,
indexState->iss_RuntimeKeys,
indexState->iss_NumRuntimeKeys);
}
indexState->iss_RuntimeKeysReady = true;
indexState->iss_ScanDesc = index_beginscan(currentRelation,
indexState->iss_RelationDesc,
estate->es_snapshot,
indexState->iss_NumScanKeys,
indexState->iss_ScanKeys);
indexState->ss.scan_state = SCAN_SCAN;
}
//.........这里部分代码省略.........
示例14: OperatorCreate
//.........这里部分代码省略.........
!pg_oper_ownercheck(negatorId, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_OPERATOR,
NameListToString(negatorName));
}
else
negatorId = InvalidOid;
/*
* set up values in the operator tuple
*/
for (i = 0; i < Natts_pg_operator; ++i)
{
values[i] = (Datum) NULL;
replaces[i] = true;
nulls[i] = false;
}
namestrcpy(&oname, operatorName);
values[Anum_pg_operator_oprname - 1] = NameGetDatum(&oname);
values[Anum_pg_operator_oprnamespace - 1] = ObjectIdGetDatum(operatorNamespace);
values[Anum_pg_operator_oprowner - 1] = ObjectIdGetDatum(GetUserId());
values[Anum_pg_operator_oprkind - 1] = CharGetDatum(leftTypeId ? (rightTypeId ? 'b' : 'r') : 'l');
values[Anum_pg_operator_oprcanmerge - 1] = BoolGetDatum(canMerge);
values[Anum_pg_operator_oprcanhash - 1] = BoolGetDatum(canHash);
values[Anum_pg_operator_oprleft - 1] = ObjectIdGetDatum(leftTypeId);
values[Anum_pg_operator_oprright - 1] = ObjectIdGetDatum(rightTypeId);
values[Anum_pg_operator_oprresult - 1] = ObjectIdGetDatum(operResultType);
values[Anum_pg_operator_oprcom - 1] = ObjectIdGetDatum(commutatorId);
values[Anum_pg_operator_oprnegate - 1] = ObjectIdGetDatum(negatorId);
values[Anum_pg_operator_oprcode - 1] = ObjectIdGetDatum(procedureId);
values[Anum_pg_operator_oprrest - 1] = ObjectIdGetDatum(restrictionId);
values[Anum_pg_operator_oprjoin - 1] = ObjectIdGetDatum(joinId);
pg_operator_desc = heap_open(OperatorRelationId, RowExclusiveLock);
/*
* If we are replacing an operator shell, update; else insert
*/
if (operatorObjectId)
{
isUpdate = true;
tup = SearchSysCacheCopy1(OPEROID,
ObjectIdGetDatum(operatorObjectId));
if (!HeapTupleIsValid(tup))
elog(ERROR, "cache lookup failed for operator %u",
operatorObjectId);
replaces[Anum_pg_operator_oid - 1] = false;
tup = heap_modify_tuple(tup,
RelationGetDescr(pg_operator_desc),
values,
nulls,
replaces);
CatalogTupleUpdate(pg_operator_desc, &tup->t_self, tup);
}
else
{
isUpdate = false;
operatorObjectId = GetNewOidWithIndex(pg_operator_desc,
OperatorOidIndexId,
Anum_pg_operator_oid);
values[Anum_pg_operator_oid - 1] = ObjectIdGetDatum(operatorObjectId);
tup = heap_form_tuple(RelationGetDescr(pg_operator_desc),
values, nulls);
CatalogTupleInsert(pg_operator_desc, tup);
}
/* Add dependencies for the entry */
address = makeOperatorDependencies(tup, isUpdate);
/* Post creation hook for new operator */
InvokeObjectPostCreateHook(OperatorRelationId, operatorObjectId, 0);
heap_close(pg_operator_desc, RowExclusiveLock);
/*
* If a commutator and/or negator link is provided, update the other
* operator(s) to point at this one, if they don't already have a link.
* This supports an alternative style of operator definition wherein the
* user first defines one operator without giving negator or commutator,
* then defines the other operator of the pair with the proper commutator
* or negator attribute. That style doesn't require creation of a shell,
* and it's the only style that worked right before Postgres version 6.5.
* This code also takes care of the situation where the new operator is
* its own commutator.
*/
if (selfCommutator)
commutatorId = operatorObjectId;
if (OidIsValid(commutatorId) || OidIsValid(negatorId))
OperatorUpd(operatorObjectId, commutatorId, negatorId, false);
return address;
}
示例15: AlterTableSpaceOwner
/*
* Change tablespace owner
*/
void
AlterTableSpaceOwner(const char *name, Oid newOwnerId)
{
Relation rel;
ScanKeyData entry[1];
HeapScanDesc scandesc;
Form_pg_tablespace spcForm;
HeapTuple tup;
/* Search pg_tablespace */
rel = heap_open(TableSpaceRelationId, RowExclusiveLock);
ScanKeyInit(&entry[0],
Anum_pg_tablespace_spcname,
BTEqualStrategyNumber, F_NAMEEQ,
CStringGetDatum(name));
scandesc = heap_beginscan(rel, SnapshotNow, 1, entry);
tup = heap_getnext(scandesc, ForwardScanDirection);
if (!HeapTupleIsValid(tup))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("tablespace \"%s\" does not exist", name)));
spcForm = (Form_pg_tablespace) GETSTRUCT(tup);
/*
* If the new owner is the same as the existing owner, consider the
* command to have succeeded. This is for dump restoration purposes.
*/
if (spcForm->spcowner != newOwnerId)
{
Datum repl_val[Natts_pg_tablespace];
bool repl_null[Natts_pg_tablespace];
bool repl_repl[Natts_pg_tablespace];
Acl *newAcl;
Datum aclDatum;
bool isNull;
HeapTuple newtuple;
/* Otherwise, must be owner of the existing object */
if (!pg_tablespace_ownercheck(HeapTupleGetOid(tup), GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TABLESPACE,
name);
/* Must be able to become new owner */
check_is_member_of_role(GetUserId(), newOwnerId);
/*
* Normally we would also check for create permissions here, but there
* are none for tablespaces so we follow what rename tablespace does
* and omit the create permissions check.
*
* NOTE: Only superusers may create tablespaces to begin with and so
* initially only a superuser would be able to change its ownership
* anyway.
*/
memset(repl_null, false, sizeof(repl_null));
memset(repl_repl, false, sizeof(repl_repl));
repl_repl[Anum_pg_tablespace_spcowner - 1] = true;
repl_val[Anum_pg_tablespace_spcowner - 1] = ObjectIdGetDatum(newOwnerId);
/*
* Determine the modified ACL for the new owner. This is only
* necessary when the ACL is non-null.
*/
aclDatum = heap_getattr(tup,
Anum_pg_tablespace_spcacl,
RelationGetDescr(rel),
&isNull);
if (!isNull)
{
newAcl = aclnewowner(DatumGetAclP(aclDatum),
spcForm->spcowner, newOwnerId);
repl_repl[Anum_pg_tablespace_spcacl - 1] = true;
repl_val[Anum_pg_tablespace_spcacl - 1] = PointerGetDatum(newAcl);
}
newtuple = heap_modify_tuple(tup, RelationGetDescr(rel), repl_val, repl_null, repl_repl);
simple_heap_update(rel, &newtuple->t_self, newtuple);
CatalogUpdateIndexes(rel, newtuple);
heap_freetuple(newtuple);
/* Update owner dependency reference */
changeDependencyOnOwner(TableSpaceRelationId, HeapTupleGetOid(tup),
newOwnerId);
}
heap_endscan(scandesc);
heap_close(rel, NoLock);
}