本文整理汇总了C++中IsBootstrapProcessingMode函数的典型用法代码示例。如果您正苦于以下问题:C++ IsBootstrapProcessingMode函数的具体用法?C++ IsBootstrapProcessingMode怎么用?C++ IsBootstrapProcessingMode使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了IsBootstrapProcessingMode函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: needs_toast_table
/*
* Check to see whether the table needs a TOAST table. It does only if
* (1) there are any toastable attributes, and (2) the maximum length
* of a tuple could exceed TOAST_TUPLE_THRESHOLD. (We don't want to
* create a toast table for something like "f1 varchar(20)".)
*/
static bool
needs_toast_table(Relation rel)
{
int32 data_length = 0;
bool maxlength_unknown = false;
bool has_toastable_attrs = false;
TupleDesc tupdesc;
int32 tuple_length;
int i;
/*
* No need to create a TOAST table for partitioned tables.
*/
if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
return false;
/*
* We cannot allow toasting a shared relation after initdb (because
* there's no way to mark it toasted in other databases' pg_class).
*/
if (rel->rd_rel->relisshared && !IsBootstrapProcessingMode())
return false;
/*
* Ignore attempts to create toast tables on catalog tables after initdb.
* Which catalogs get toast tables is explicitly chosen in
* catalog/toasting.h. (We could get here via some ALTER TABLE command if
* the catalog doesn't have a toast table.)
*/
if (IsCatalogRelation(rel) && !IsBootstrapProcessingMode())
return false;
tupdesc = rel->rd_att;
for (i = 0; i < tupdesc->natts; i++)
{
Form_pg_attribute att = TupleDescAttr(tupdesc, i);
if (att->attisdropped)
continue;
data_length = att_align_nominal(data_length, att->attalign);
if (att->attlen > 0)
{
/* Fixed-length types are never toastable */
data_length += att->attlen;
}
else
{
int32 maxlen = type_maximum_size(att->atttypid,
att->atttypmod);
if (maxlen < 0)
maxlength_unknown = true;
else
data_length += maxlen;
if (att->attstorage != 'p')
has_toastable_attrs = true;
}
}
if (!has_toastable_attrs)
return false; /* nothing to toast? */
if (maxlength_unknown)
return true; /* any unlimited-length attrs? */
tuple_length = MAXALIGN(SizeofHeapTupleHeader +
BITMAPLEN(tupdesc->natts)) +
MAXALIGN(data_length);
return (tuple_length > TOAST_TUPLE_THRESHOLD);
}
示例2: CacheInvalidateHeapTuple
/*
* CacheInvalidateHeapTuple
* Register the given tuple for invalidation at end of command
* (ie, current command is creating or outdating this tuple).
* Also, detect whether a relcache invalidation is implied.
*
* For an insert or delete, tuple is the target tuple and newtuple is NULL.
* For an update, we are called just once, with tuple being the old tuple
* version and newtuple the new version. This allows avoidance of duplicate
* effort during an update.
*/
void
CacheInvalidateHeapTuple(Relation relation,
HeapTuple tuple,
HeapTuple newtuple)
{
Oid tupleRelId;
Oid databaseId;
Oid relationId;
/* Do nothing during bootstrap */
if (IsBootstrapProcessingMode())
return;
/*
* We only need to worry about invalidation for tuples that are in system
* relations; user-relation tuples are never in catcaches and can't affect
* the relcache either.
*/
if (!IsSystemRelation(relation))
return;
/*
* TOAST tuples can likewise be ignored here. Note that TOAST tables are
* considered system relations so they are not filtered by the above test.
*/
if (IsToastRelation(relation))
return;
/*
* First let the catcache do its thing
*/
PrepareToInvalidateCacheTuple(relation, tuple, newtuple,
RegisterCatcacheInvalidation);
/*
* Now, is this tuple one of the primary definers of a relcache entry?
*
* Note we ignore newtuple here; we assume an update cannot move a tuple
* from being part of one relcache entry to being part of another.
*/
tupleRelId = RelationGetRelid(relation);
if (tupleRelId == RelationRelationId)
{
Form_pg_class classtup = (Form_pg_class) GETSTRUCT(tuple);
relationId = HeapTupleGetOid(tuple);
if (classtup->relisshared)
databaseId = InvalidOid;
else
databaseId = MyDatabaseId;
}
else if (tupleRelId == AttributeRelationId)
{
Form_pg_attribute atttup = (Form_pg_attribute) GETSTRUCT(tuple);
relationId = atttup->attrelid;
/*
* KLUGE ALERT: we always send the relcache event with MyDatabaseId,
* even if the rel in question is shared (which we can't easily tell).
* This essentially means that only backends in this same database
* will react to the relcache flush request. This is in fact
* appropriate, since only those backends could see our pg_attribute
* change anyway. It looks a bit ugly though. (In practice, shared
* relations can't have schema changes after bootstrap, so we should
* never come here for a shared rel anyway.)
*/
databaseId = MyDatabaseId;
}
else if (tupleRelId == IndexRelationId)
{
Form_pg_index indextup = (Form_pg_index) GETSTRUCT(tuple);
/*
* When a pg_index row is updated, we should send out a relcache inval
* for the index relation. As above, we don't know the shared status
* of the index, but in practice it doesn't matter since indexes of
* shared catalogs can't have such updates.
*/
relationId = indextup->indexrelid;
databaseId = MyDatabaseId;
}
else
return;
/*
* Yes. We need to register a relcache invalidation event.
*/
//.........这里部分代码省略.........
示例3: regoperout
/*
* regoperout - converts operator OID to "opr_name"
*/
Datum
regoperout(PG_FUNCTION_ARGS)
{
Oid oprid = PG_GETARG_OID(0);
char *result;
HeapTuple opertup;
cqContext *pcqCtx;
if (oprid == InvalidOid)
{
result = pstrdup("0");
PG_RETURN_CSTRING(result);
}
pcqCtx = caql_beginscan(
NULL,
cql("SELECT * FROM pg_operator "
" WHERE oid = :1 ",
ObjectIdGetDatum(oprid)));
opertup = caql_getnext(pcqCtx);
/* XXX XXX select oprname, oprnamespace from pg_operator */
if (HeapTupleIsValid(opertup))
{
Form_pg_operator operform = (Form_pg_operator) GETSTRUCT(opertup);
char *oprname = NameStr(operform->oprname);
/*
* In bootstrap mode, skip the fancy namespace stuff and just return
* the oper name. (This path is only needed for debugging output
* anyway.)
*/
if (IsBootstrapProcessingMode())
result = pstrdup(oprname);
else
{
FuncCandidateList clist;
/*
* Would this oper be found (uniquely!) by regoperin? If not,
* qualify it.
*/
clist = OpernameGetCandidates(list_make1(makeString(oprname)),
'\0');
if (clist != NULL && clist->next == NULL &&
clist->oid == oprid)
result = pstrdup(oprname);
else
{
const char *nspname;
nspname = get_namespace_name(operform->oprnamespace);
nspname = quote_identifier(nspname);
result = (char *) palloc(strlen(nspname) + strlen(oprname) + 2);
sprintf(result, "%s.%s", nspname, oprname);
}
}
}
else
{
/*
* If OID doesn't match any pg_operator entry, return it numerically
*/
result = (char *) palloc(NAMEDATALEN);
snprintf(result, NAMEDATALEN, "%u", oprid);
}
caql_endscan(pcqCtx);
PG_RETURN_CSTRING(result);
}
示例4: InitPostgres
/* --------------------------------
* InitPostgres
* Initialize POSTGRES.
*
* The database can be specified by name, using the in_dbname parameter, or by
* OID, using the dboid parameter. In the latter case, the actual database
* name can be returned to the caller in out_dbname. If out_dbname isn't
* NULL, it must point to a buffer of size NAMEDATALEN.
*
* In bootstrap mode no parameters are used.
*
* The return value indicates whether the userID is a superuser. (That
* can only be tested inside a transaction, so we want to do it during
* the startup transaction rather than doing a separate one in postgres.c.)
*
* As of PostgreSQL 8.2, we expect InitProcess() was already called, so we
* already have a PGPROC struct ... but it's not filled in yet.
*
* Note:
* Be very careful with the order of calls in the InitPostgres function.
* --------------------------------
*/
void
InitPostgres(const char *in_dbname, Oid dboid, const char *username,
char *out_dbname)
{
bool bootstrap = IsBootstrapProcessingMode();
bool autovacuum = IsAutoVacuumProcess();
bool am_superuser;
char *fullpath;
char dbname[NAMEDATALEN];
/*
* Add my PGPROC struct to the ProcArray.
*
* Once I have done this, I am visible to other backends!
*/
InitProcessPhase2();
/* Initialize SessionState entry */
SessionState_Init();
/* Initialize memory protection */
GPMemoryProtect_Init();
/*
* Initialize my entry in the shared-invalidation manager's array of
* per-backend data.
*
* Sets up MyBackendId, a unique backend identifier.
*/
MyBackendId = InvalidBackendId;
SharedInvalBackendInit(false);
if (MyBackendId > MaxBackends || MyBackendId <= 0)
elog(FATAL, "bad backend id: %d", MyBackendId);
/* Now that we have a BackendId, we can participate in ProcSignal */
ProcSignalInit(MyBackendId);
/*
* bufmgr needs another initialization call too
*/
InitBufferPoolBackend();
/*
* Initialize local process's access to XLOG. In bootstrap case we may
* skip this since StartupXLOG() was run instead.
*/
if (!bootstrap)
InitXLOGAccess();
/*
* Initialize the relation cache and the system catalog caches. Note that
* no catalog access happens here; we only set up the hashtable structure.
* We must do this before starting a transaction because transaction abort
* would try to touch these hashtables.
*/
RelationCacheInitialize();
InitCatalogCache();
/* Initialize portal manager */
EnablePortalManager();
/* Initialize stats collection --- must happen before first xact */
if (!bootstrap)
pgstat_initialize();
/*
* Load relcache entries for the shared system catalogs. This must create
* at least entries for pg_database and catalogs used for authentication.
*/
RelationCacheInitializePhase2();
/*
* Set up process-exit callback to do pre-shutdown cleanup. This has to
* be after we've initialized all the low-level modules like the buffer
* manager, because during shutdown this has to run before the low-level
* modules start to close down. On the other hand, we want it in place
* before we begin our first transaction --- if we fail during the
//.........这里部分代码省略.........
示例5: TypeShellMake
//.........这里部分代码省略.........
for (i = 0; i < Natts_pg_type; ++i)
{
nulls[i] = false;
values[i] = (Datum) NULL; /* redundant, but safe */
}
/*
* initialize *values with the type name and dummy values
*
* The representational details are the same as int4 ... it doesn't really
* matter what they are so long as they are consistent. Also note that we
* give it typtype = TYPTYPE_PSEUDO as extra insurance that it won't be
* mistaken for a usable type.
*/
namestrcpy(&name, typeName);
values[Anum_pg_type_typname - 1] = NameGetDatum(&name);
values[Anum_pg_type_typnamespace - 1] = ObjectIdGetDatum(typeNamespace);
values[Anum_pg_type_typowner - 1] = ObjectIdGetDatum(ownerId);
values[Anum_pg_type_typlen - 1] = Int16GetDatum(sizeof(int32));
values[Anum_pg_type_typbyval - 1] = BoolGetDatum(true);
values[Anum_pg_type_typtype - 1] = CharGetDatum(TYPTYPE_PSEUDO);
values[Anum_pg_type_typcategory - 1] = CharGetDatum(TYPCATEGORY_PSEUDOTYPE);
values[Anum_pg_type_typispreferred - 1] = BoolGetDatum(false);
values[Anum_pg_type_typisdefined - 1] = BoolGetDatum(false);
values[Anum_pg_type_typdelim - 1] = CharGetDatum(DEFAULT_TYPDELIM);
values[Anum_pg_type_typrelid - 1] = ObjectIdGetDatum(InvalidOid);
values[Anum_pg_type_typelem - 1] = ObjectIdGetDatum(InvalidOid);
values[Anum_pg_type_typarray - 1] = ObjectIdGetDatum(InvalidOid);
values[Anum_pg_type_typinput - 1] = ObjectIdGetDatum(F_SHELL_IN);
values[Anum_pg_type_typoutput - 1] = ObjectIdGetDatum(F_SHELL_OUT);
values[Anum_pg_type_typreceive - 1] = ObjectIdGetDatum(InvalidOid);
values[Anum_pg_type_typsend - 1] = ObjectIdGetDatum(InvalidOid);
values[Anum_pg_type_typmodin - 1] = ObjectIdGetDatum(InvalidOid);
values[Anum_pg_type_typmodout - 1] = ObjectIdGetDatum(InvalidOid);
values[Anum_pg_type_typanalyze - 1] = ObjectIdGetDatum(InvalidOid);
values[Anum_pg_type_typalign - 1] = CharGetDatum('i');
values[Anum_pg_type_typstorage - 1] = CharGetDatum('p');
values[Anum_pg_type_typnotnull - 1] = BoolGetDatum(false);
values[Anum_pg_type_typbasetype - 1] = ObjectIdGetDatum(InvalidOid);
values[Anum_pg_type_typtypmod - 1] = Int32GetDatum(-1);
values[Anum_pg_type_typndims - 1] = Int32GetDatum(0);
values[Anum_pg_type_typcollation - 1] = ObjectIdGetDatum(InvalidOid);
nulls[Anum_pg_type_typdefaultbin - 1] = true;
nulls[Anum_pg_type_typdefault - 1] = true;
nulls[Anum_pg_type_typacl - 1] = true;
/*
* create a new type tuple
*/
tup = heap_form_tuple(tupDesc, values, nulls);
/* Use binary-upgrade override for pg_type.oid, if supplied. */
if (IsBinaryUpgrade && OidIsValid(binary_upgrade_next_pg_type_oid))
{
HeapTupleSetOid(tup, binary_upgrade_next_pg_type_oid);
binary_upgrade_next_pg_type_oid = InvalidOid;
}
/*
* insert the tuple in the relation and get the tuple's oid.
*/
typoid = simple_heap_insert(pg_type_desc, tup);
CatalogUpdateIndexes(pg_type_desc, tup);
/*
* Create dependencies. We can/must skip this in bootstrap mode.
*/
if (!IsBootstrapProcessingMode())
GenerateTypeDependencies(typeNamespace,
typoid,
InvalidOid,
0,
ownerId,
F_SHELL_IN,
F_SHELL_OUT,
InvalidOid,
InvalidOid,
InvalidOid,
InvalidOid,
InvalidOid,
InvalidOid,
false,
InvalidOid,
InvalidOid,
NULL,
false);
/* Post creation hook for new shell type */
InvokeObjectAccessHook(OAT_POST_CREATE,
TypeRelationId, typoid, 0, NULL);
/*
* clean up and return the type-oid
*/
heap_freetuple(tup);
heap_close(pg_type_desc, RowExclusiveLock);
return typoid;
}
示例6: CreateAOAuxiliaryTable
/*
* Create append-only auxiliary relations for target relation rel.
* Returns true if they are newly created. If pg_appendonly has already
* known those tables, don't create them and returns false.
*/
bool
CreateAOAuxiliaryTable(
Relation rel,
const char *auxiliaryNamePrefix,
char relkind,
TupleDesc tupledesc,
IndexInfo *indexInfo,
Oid *classObjectId,
int16 *coloptions)
{
char aoauxiliary_relname[NAMEDATALEN];
char aoauxiliary_idxname[NAMEDATALEN];
bool shared_relation;
Oid relOid, aoauxiliary_relid = InvalidOid;
Oid aoauxiliary_idxid = InvalidOid;
ObjectAddress baseobject;
ObjectAddress aoauxiliaryobject;
Assert(RelationIsValid(rel));
Assert(RelationIsAoRows(rel) || RelationIsAoCols(rel));
Assert(auxiliaryNamePrefix);
Assert(tupledesc);
Assert(classObjectId);
if (relkind != RELKIND_AOSEGMENTS)
Assert(indexInfo);
shared_relation = rel->rd_rel->relisshared;
/*
* We cannot allow creating an auxiliary table for a shared relation
* after initdb (because there's no way to let other databases know
* this visibility map.
*/
if (shared_relation && !IsBootstrapProcessingMode())
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("shared tables cannot have append-only auxiliary relations after initdb")));
relOid = RelationGetRelid(rel);
switch(relkind)
{
case RELKIND_AOVISIMAP:
GetAppendOnlyEntryAuxOids(relOid, SnapshotNow, NULL,
NULL, NULL, &aoauxiliary_relid, &aoauxiliary_idxid);
break;
case RELKIND_AOBLOCKDIR:
GetAppendOnlyEntryAuxOids(relOid, SnapshotNow, NULL,
&aoauxiliary_relid, &aoauxiliary_idxid, NULL, NULL);
break;
case RELKIND_AOSEGMENTS:
GetAppendOnlyEntryAuxOids(relOid, SnapshotNow,
&aoauxiliary_relid,
NULL, NULL, NULL, NULL);
break;
default:
elog(ERROR, "unsupported auxiliary relkind '%c'", relkind);
}
/*
* Does it have the auxiliary relation?
*/
if (OidIsValid(aoauxiliary_relid))
{
return false;
}
snprintf(aoauxiliary_relname, sizeof(aoauxiliary_relname),
"%s_%u", auxiliaryNamePrefix, relOid);
snprintf(aoauxiliary_idxname, sizeof(aoauxiliary_idxname),
"%s_%u_index", auxiliaryNamePrefix, relOid);
/*
* We place auxiliary relation in the pg_aoseg namespace
* even if its master relation is a temp table. There cannot be
* any naming collision, and the auxiliary relation will be
* destroyed when its master is, so there is no need to handle
* the aovisimap relation as temp.
*/
aoauxiliary_relid = heap_create_with_catalog(aoauxiliary_relname,
PG_AOSEGMENT_NAMESPACE,
rel->rd_rel->reltablespace,
InvalidOid,
rel->rd_rel->relowner,
tupledesc,
/* relam */ InvalidOid,
relkind,
RELSTORAGE_HEAP,
shared_relation,
true,
/* bufferPoolBulkLoad */ false,
0,
ONCOMMIT_NOOP,
NULL, /* GP Policy */
(Datum) 0,
true,
//.........这里部分代码省略.........
示例7: CheckNewRelFileNodeIsOk
bool
CheckNewRelFileNodeIsOk(Oid newOid, Oid reltablespace, bool relisshared,
Relation pg_class)
{
RelFileNode rnode;
char *rpath;
int fd;
bool collides;
if (pg_class)
{
Oid oidIndex;
Relation indexrel;
IndexScanDesc scan;
ScanKeyData key;
Assert(!IsBootstrapProcessingMode());
Assert(pg_class->rd_rel->relhasoids);
/* The relcache will cache the identity of the OID index for us */
oidIndex = RelationGetOidIndex(pg_class);
Assert(OidIsValid(oidIndex));
indexrel = index_open(oidIndex, AccessShareLock);
ScanKeyInit(&key,
(AttrNumber) 1,
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(newOid));
scan = index_beginscan(pg_class, indexrel, SnapshotDirty, 1, &key);
collides = HeapTupleIsValid(index_getnext(scan, ForwardScanDirection));
index_endscan(scan);
index_close(indexrel, AccessShareLock);
if (collides)
elog(ERROR, "relfilenode %d already in use in \"pg_class\"",
newOid);
}
/* This should match RelationInitPhysicalAddr */
rnode.spcNode = reltablespace ? reltablespace : MyDatabaseTableSpace;
rnode.dbNode = relisshared ? InvalidOid : MyDatabaseId;
rnode.relNode = newOid;
/* Check for existing file of same name */
rpath = relpath(rnode);
fd = BasicOpenFile(rpath, O_RDONLY | PG_BINARY, 0);
if (fd >= 0)
{
/* definite collision */
gp_retry_close(fd);
collides = true;
}
else
collides = false;
pfree(rpath);
if (collides && !relisshared)
elog(ERROR, "oid %d already in use", newOid);
while(GetNewObjectId() < newOid);
return !collides;
}
示例8: ExecUpdate
/* ----------------------------------------------------------------
* ExecUpdate
*
* note: we can't run UPDATE queries with transactions
* off because UPDATEs are actually INSERTs and our
* scan will mistakenly loop forever, updating the tuple
* it just inserted.. This should be fixed but until it
* is, we don't want to get stuck in an infinite loop
* which corrupts your database..
* ----------------------------------------------------------------
*/
void
ExecUpdate(TupleTableSlot *slot,
ItemPointer tupleid,
TupleTableSlot *planSlot,
DestReceiver *dest,
EState *estate)
{
HeapTuple tuple;
ResultRelInfo *resultRelInfo;
Relation resultRelationDesc;
HTSU_Result result;
ItemPointerData update_ctid;
TransactionId update_xmax;
/*
* abort the operation if not running transactions
*/
if (IsBootstrapProcessingMode())
elog(ERROR, "cannot UPDATE during bootstrap");
/*
* get the heap tuple out of the tuple table slot, making sure we have a
* writable copy
*/
tuple = ExecFetchSlotHeapTuple(slot);
/*
* get information on the (current) result relation
*/
resultRelInfo = estate->es_result_relation_info;
resultRelationDesc = resultRelInfo->ri_RelationDesc;
/* see if this update would move the tuple to a different partition */
if (estate->es_result_partitions)
{
AttrNumber max_attr;
Datum *values;
bool *nulls;
Oid targetid;
Assert(estate->es_partition_state != NULL &&
estate->es_partition_state->accessMethods != NULL);
if (!estate->es_partition_state->accessMethods->part_cxt)
estate->es_partition_state->accessMethods->part_cxt =
GetPerTupleExprContext(estate)->ecxt_per_tuple_memory;
Assert(PointerIsValid(estate->es_result_partitions));
max_attr = estate->es_partition_state->max_partition_attr;
slot_getsomeattrs(slot, max_attr);
values = slot_get_values(slot);
nulls = slot_get_isnull(slot);
targetid = selectPartition(estate->es_result_partitions, values,
nulls, slot->tts_tupleDescriptor,
estate->es_partition_state->accessMethods);
if (!OidIsValid(targetid))
ereport(ERROR,
(errcode(ERRCODE_NO_PARTITION_FOR_PARTITIONING_KEY),
errmsg("no partition for partitioning key")));
if (RelationGetRelid(resultRelationDesc) != targetid)
{
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("moving tuple from partition \"%s\" to "
"partition \"%s\" not supported",
get_rel_name(RelationGetRelid(resultRelationDesc)),
get_rel_name(targetid)),
errOmitLocation(true)));
}
}
/* BEFORE ROW UPDATE Triggers */
if (resultRelInfo->ri_TrigDesc &&
resultRelInfo->ri_TrigDesc->n_before_row[TRIGGER_EVENT_UPDATE] > 0)
{
HeapTuple newtuple;
newtuple = ExecBRUpdateTriggers(estate, resultRelInfo,
tupleid, tuple,
estate->es_snapshot->curcid);
if (newtuple == NULL) /* "do nothing" */
return;
if (newtuple != tuple) /* modified by Trigger(s) */
//.........这里部分代码省略.........
示例9: create_toast_table
/*
* create_toast_table --- internal workhorse
*
* rel is already opened and exclusive-locked
* toastOid and toastIndexOid are normally InvalidOid, but during
* bootstrap they can be nonzero to specify hand-assigned OIDs
*/
static bool
create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
bool is_part_child)
{
Oid relOid = RelationGetRelid(rel);
HeapTuple reltup;
TupleDesc tupdesc;
bool shared_relation;
Relation class_rel;
Oid toast_relid;
Oid toast_idxid;
Oid namespaceid;
char toast_relname[NAMEDATALEN];
char toast_idxname[NAMEDATALEN];
IndexInfo *indexInfo;
Oid classObjectId[2];
int16 coloptions[2];
ObjectAddress baseobject,
toastobject;
/*
* Is it already toasted?
*/
if (rel->rd_rel->reltoastrelid != InvalidOid)
return false;
/*
* Check to see whether the table actually needs a TOAST table.
*/
if (!RelationNeedsToastTable(rel))
return false;
/*
* Toast table is shared if and only if its parent is.
*
* We cannot allow toasting a shared relation after initdb (because
* there's no way to mark it toasted in other databases' pg_class).
*/
shared_relation = rel->rd_rel->relisshared;
if (shared_relation && !IsBootstrapProcessingMode())
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("shared tables cannot be toasted after initdb")));
/*
* Create the toast table and its index
*/
snprintf(toast_relname, sizeof(toast_relname),
"pg_toast_%u", relOid);
snprintf(toast_idxname, sizeof(toast_idxname),
"pg_toast_%u_index", relOid);
/* this is pretty painful... need a tuple descriptor */
tupdesc = CreateTemplateTupleDesc(3, false);
TupleDescInitEntry(tupdesc, (AttrNumber) 1,
"chunk_id",
OIDOID,
-1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 2,
"chunk_seq",
INT4OID,
-1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 3,
"chunk_data",
BYTEAOID,
-1, 0);
/*
* Ensure that the toast table doesn't itself get toasted, or we'll be
* toast :-(. This is essential for chunk_data because type bytea is
* toastable; hit the other two just to be sure.
*/
tupdesc->attrs[0]->attstorage = 'p';
tupdesc->attrs[1]->attstorage = 'p';
tupdesc->attrs[2]->attstorage = 'p';
/*
* Toast tables for regular relations go in pg_toast; those for temp
* relations go into the per-backend temp-toast-table namespace.
*/
if (rel->rd_istemp)
namespaceid = GetTempToastNamespace();
else
namespaceid = PG_TOAST_NAMESPACE;
/*
* XXX would it make sense to apply the master's reloptions to the toast
* table? Or maybe some toast-specific reloptions?
*/
toast_relid = heap_create_with_catalog(toast_relname,
namespaceid,
rel->rd_rel->reltablespace,
toastOid,
//.........这里部分代码省略.........
示例10: PrepareForTupleInvalidation
/*
* PrepareForTupleInvalidation
* Detect whether invalidation of this tuple implies invalidation
* of catalog/relation cache entries; if so, register inval events.
*/
static void
PrepareForTupleInvalidation(Relation relation, HeapTuple tuple)
{
Oid tupleRelId;
Oid databaseId;
Oid relationId;
/* Do nothing during bootstrap */
if (IsBootstrapProcessingMode())
return;
/*
* We only need to worry about invalidation for tuples that are in system
* relations; user-relation tuples are never in catcaches and can't affect
* the relcache either.
*/
if (!IsSystemRelation(relation))
return;
/*
* TOAST tuples can likewise be ignored here. Note that TOAST tables are
* considered system relations so they are not filtered by the above test.
*/
if (IsToastRelation(relation))
return;
/*
* First let the catcache do its thing
*/
PrepareToInvalidateCacheTuple(relation, tuple,
RegisterCatcacheInvalidation);
/*
* Now, is this tuple one of the primary definers of a relcache entry?
*/
tupleRelId = RelationGetRelid(relation);
if (tupleRelId == RelationRelationId)
{
Form_pg_class classtup = (Form_pg_class) GETSTRUCT(tuple);
RelFileNode rnode;
relationId = HeapTupleGetOid(tuple);
if (classtup->relisshared)
databaseId = InvalidOid;
else
databaseId = MyDatabaseId;
/*
* We need to send out an smgr inval as well as a relcache inval. This
* is needed because other backends might possibly possess smgr cache
* but not relcache entries for the target relation.
*
* Note: during a pg_class row update that assigns a new relfilenode
* or reltablespace value, we will be called on both the old and new
* tuples, and thus will broadcast invalidation messages showing both
* the old and new RelFileNode values. This ensures that other
* backends will close smgr references to the old file.
*
* XXX possible future cleanup: it might be better to trigger smgr
* flushes explicitly, rather than indirectly from pg_class updates.
*/
if (classtup->reltablespace)
rnode.spcNode = classtup->reltablespace;
else
rnode.spcNode = MyDatabaseTableSpace;
rnode.dbNode = databaseId;
rnode.relNode = classtup->relfilenode;
RegisterSmgrInvalidation(rnode);
}
else if (tupleRelId == AttributeRelationId)
{
Form_pg_attribute atttup = (Form_pg_attribute) GETSTRUCT(tuple);
relationId = atttup->attrelid;
/*
* KLUGE ALERT: we always send the relcache event with MyDatabaseId,
* even if the rel in question is shared (which we can't easily tell).
* This essentially means that only backends in this same database
* will react to the relcache flush request. This is in fact
* appropriate, since only those backends could see our pg_attribute
* change anyway. It looks a bit ugly though.
*/
databaseId = MyDatabaseId;
}
else
return;
/*
* Yes. We need to register a relcache invalidation event.
*/
RegisterRelcacheInvalidation(databaseId, relationId);
}
示例11: recordMultipleDependencies
/*
* Record multiple dependencies (of the same kind) for a single dependent
* object. This has a little less overhead than recording each separately.
*/
void
recordMultipleDependencies(const ObjectAddress *depender,
const ObjectAddress *referenced,
int nreferenced,
DependencyType behavior)
{
Relation dependDesc;
CatalogIndexState indstate;
HeapTuple tup;
int i;
bool nulls[Natts_pg_depend];
Datum values[Natts_pg_depend];
if (nreferenced <= 0)
return; /* nothing to do */
/*
* During bootstrap, do nothing since pg_depend may not exist yet. initdb
* will fill in appropriate pg_depend entries after bootstrap.
*/
if (IsBootstrapProcessingMode())
return;
dependDesc = heap_open(DependRelationId, RowExclusiveLock);
/* Don't open indexes unless we need to make an update */
indstate = NULL;
memset(nulls, false, sizeof(nulls));
for (i = 0; i < nreferenced; i++, referenced++)
{
/*
* If the referenced object is pinned by the system, there's no real
* need to record dependencies on it. This saves lots of space in
* pg_depend, so it's worth the time taken to check.
*/
if (!isObjectPinned(referenced, dependDesc))
{
/*
* Record the Dependency. Note we don't bother to check for
* duplicate dependencies; there's no harm in them.
*/
values[Anum_pg_depend_classid - 1] = ObjectIdGetDatum(depender->classId);
values[Anum_pg_depend_objid - 1] = ObjectIdGetDatum(depender->objectId);
values[Anum_pg_depend_objsubid - 1] = Int32GetDatum(depender->objectSubId);
values[Anum_pg_depend_refclassid - 1] = ObjectIdGetDatum(referenced->classId);
values[Anum_pg_depend_refobjid - 1] = ObjectIdGetDatum(referenced->objectId);
values[Anum_pg_depend_refobjsubid - 1] = Int32GetDatum(referenced->objectSubId);
values[Anum_pg_depend_deptype - 1] = CharGetDatum((char) behavior);
tup = heap_form_tuple(dependDesc->rd_att, values, nulls);
simple_heap_insert(dependDesc, tup);
/* keep indexes current */
if (indstate == NULL)
indstate = CatalogOpenIndexes(dependDesc);
CatalogIndexInsert(indstate, tup);
heap_freetuple(tup);
}
}
if (indstate != NULL)
CatalogCloseIndexes(indstate);
heap_close(dependDesc, RowExclusiveLock);
}
示例12: systable_beginscan
/*
* systable_beginscan --- set up for heap-or-index scan
*
* rel: catalog to scan, already opened and suitably locked
* indexId: OID of index to conditionally use
* indexOK: if false, forces a heap scan (see notes below)
* snapshot: time qual to use (usually should be SnapshotNow)
* nkeys, key: scan keys
*
* The attribute numbers in the scan key should be set for the heap case.
* If we choose to index, we reset them to 1..n to reference the index
* columns. Note this means there must be one scankey qualification per
* index column! This is checked by the Asserts in the normal, index-using
* case, but won't be checked if the heapscan path is taken.
*
* The routine checks the normal cases for whether an indexscan is safe,
* but caller can make additional checks and pass indexOK=false if needed.
* In standard case indexOK can simply be constant TRUE.
*/
SysScanDesc
systable_beginscan(Relation heapRelation,
Oid indexId,
bool indexOK,
Snapshot snapshot,
int nkeys, ScanKey key)
{
SysScanDesc sysscan;
Relation irel;
if (indexOK &&
!IgnoreSystemIndexes &&
!ReindexIsProcessingIndex(indexId))
irel = index_open(indexId, AccessShareLock);
else
irel = NULL;
sysscan = (SysScanDesc) palloc(sizeof(SysScanDescData));
sysscan->heap_rel = heapRelation;
sysscan->irel = irel;
if (irel)
{
int i;
if (!IsBootstrapProcessingMode())
{
Insist(RelationGetRelid(heapRelation) == irel->rd_index->indrelid);
}
/* Change attribute numbers to be index column numbers. */
for (i = 0; i < nkeys; i++)
{
int j;
for (j = 0; j < irel->rd_index->indnatts; j++)
{
if (key[i].sk_attno == irel->rd_index->indkey.values[j])
{
key[i].sk_attno = j + 1;
break;
}
}
if (j == irel->rd_index->indnatts)
elog(ERROR, "column is not in index");
}
sysscan->iscan = index_beginscan(heapRelation, irel,
snapshot, nkeys, key);
sysscan->scan = NULL;
}
else
{
/*
* We disallow synchronized scans when forced to use a heapscan on a
* catalog. In most cases the desired rows are near the front, so
* that the unpredictable start point of a syncscan is a serious
* disadvantage; and there are no compensating advantages, because
* it's unlikely that such scans will occur in parallel.
*/
sysscan->scan = heap_beginscan_strat(heapRelation, snapshot,
nkeys, key,
true, false);
sysscan->iscan = NULL;
}
return sysscan;
}
示例13: InitPostgres
void
InitPostgres(char *name) /* database name */
{
bool bootstrap; /* true if BootstrapProcessing */
/* ----------------
* see if we're running in BootstrapProcessing mode
* ----------------
*/
bootstrap = IsBootstrapProcessingMode();
/* ----------------
* turn on the exception handler. Note: we cannot use elog, Assert,
* AssertState, etc. until after exception handling is on.
* ----------------
*/
EnableExceptionHandling(true);
/* ----------------
* A stupid check to make sure we don't call this more than once.
* But things like ReinitPostgres() get around this by just diddling
* the PostgresIsInitialized flag.
* ----------------
*/
AssertState(!PostgresIsInitialized);
/* ----------------
* Memory system initialization.
* (we may call palloc after EnableMemoryContext())
*
* Note EnableMemoryContext() must happen before EnablePortalManager().
* ----------------
*/
EnableMemoryContext(true); /* initializes the "top context" */
EnablePortalManager(true); /* memory for portal/transaction stuff */
/* ----------------
* initialize the backend local portal stack used by
* internal PQ function calls. see src/lib/libpq/be-dumpdata.c
* This is different from the "portal manager" so this goes here.
* -cim 2/12/91
* ----------------
*/
be_portalinit();
/* ----------------
* attach to shared memory and semaphores, and initialize our
* input/output/debugging file descriptors.
* ----------------
*/
InitCommunication();
InitStdio();
/*
* initialize the local buffer manager
*/
InitLocalBuffer();
if (!TransactionFlushEnabled())
on_exitpg(FlushBufferPool, (caddr_t) NULL);
/* ----------------
* check for valid "meta gunk" (??? -cim 10/5/90) and change to
* database directory.
*
* Note: DatabaseName, MyDatabaseName, and DatabasePath are all
* initialized with DatabaseMetaGunkIsConsistent(), strncpy() and
* DoChdirAndInitDatabase() below! XXX clean this crap up!
* -cim 10/5/90
* ----------------
*/
{
char myPath[MAXPGPATH] = "."; /* DatabasePath points here! */
/* ----------------
* DatabaseMetaGunkIsConsistent fills in myPath, but what about
* when bootstrap or Noversion is true?? -cim 10/5/90
* ----------------
*/
if (! bootstrap &&
! DatabaseMetaGunkIsConsistent(name, myPath) &&
! Noversion) {
elog(NOTICE, "InitPostgres: could not locate valid PG_VERSION\n");
elog(NOTICE, "files for %s and %s.", DataDir, name);
elog(FATAL, "Have you run initdb/createdb and set PGDATA properly?");
}
/* ----------------
* ok, we've figured out myName and myPath, now save these
* and chdir to myPath.
* ----------------
*/
DoChdirAndInitDatabaseNameAndPath(name, myPath);
}
/* ********************************
* code after this point assumes we are in the proper directory!
* ********************************
*/
//.........这里部分代码省略.........
示例14: InitMyDatabaseId
/* --------------------------------
* InitMyDatabaseId() -- Find and record the OID of the database we are
* to open.
*
* The database's oid forms half of the unique key for the system
* caches and lock tables. We therefore want it initialized before
* we open any relations, since opening relations puts things in the
* cache. To get around this problem, this code opens and scans the
* pg_database relation by hand.
*
* This algorithm relies on the fact that first attribute in the
* pg_database relation schema is the database name. It also knows
* about the internal format of tuples on disk and the length of
* the datname attribute. It knows the location of the pg_database
* file.
*
* This code is called from InitDatabase(), after we chdir() to the
* database directory but before we open any relations.
* --------------------------------
*/
void
InitMyDatabaseId()
{
int dbfd;
int fileflags;
int nbytes;
int max, i;
HeapTuple tup;
Page pg;
PageHeader ph;
char *dbfname;
Form_pg_database tup_db;
/*
* At bootstrap time, we don't need to check the oid of the database
* in use, since we're not using shared memory. This is lucky, since
* the database may not be in the tables yet.
*/
if (IsBootstrapProcessingMode()) {
LockDisable(true);
return;
}
dbfname = (char *) palloc(strlen(DataDir) + strlen("pg_database") + 2);
sprintf(dbfname, "%s%cpg_database", DataDir, SEP_CHAR);
fileflags = O_RDONLY;
#ifdef WIN32
fileflags |= _O_BINARY;
#endif /* WIN32 */
if ((dbfd = open(dbfname, O_RDONLY, 0666)) < 0)
elog(FATAL, "Cannot open %s", dbfname);
pfree(dbfname);
/* ----------------
* read and examine every page in pg_database
*
* Raw I/O! Read those tuples the hard way! Yow!
*
* Why don't we use the access methods or move this code
* someplace else? This is really pg_database schema dependent
* code. Perhaps it should go in lib/catalog/pg_database?
* -cim 10/3/90
*
* mao replies 4 apr 91: yeah, maybe this should be moved to
* lib/catalog. however, we CANNOT use the access methods since
* those use the buffer cache, which uses the relation cache, which
* requires that the dbid be set, which is what we're trying to do
* here.
* ----------------
*/
pg = (Page) palloc(BLCKSZ);
ph = (PageHeader) pg;
while ((nbytes = read(dbfd, pg, BLCKSZ)) == BLCKSZ) {
max = PageGetMaxOffsetNumber(pg);
/* look at each tuple on the page */
for (i = 0; i <= max; i++) {
int offset;
/* if it's a freed tuple, ignore it */
if (!(ph->pd_linp[i].lp_flags & LP_USED))
continue;
/* get a pointer to the tuple itself */
offset = (int) ph->pd_linp[i].lp_off;
tup = (HeapTuple) (((char *) pg) + offset);
/*
* if the tuple has been deleted (the database was destroyed),
* skip this tuple. XXX warning, will robinson: violation of
* transaction semantics happens right here. we should check
* to be sure that the xact that deleted this tuple actually
* committed. only way to do this at init time is to paw over
* the log relation by hand, too. let's be optimistic.
*
* XXX This is an evil type cast. tup->t_xmax is char[5] while
//.........这里部分代码省略.........
示例15: regclassout
/*
* regclassout - converts class OID to "class_name"
*/
Datum
regclassout(PG_FUNCTION_ARGS)
{
Oid classid = PG_GETARG_OID(0);
char *result;
HeapTuple classtup;
cqContext *pcqCtx;
if (classid == InvalidOid)
{
result = pstrdup("-");
PG_RETURN_CSTRING(result);
}
pcqCtx = caql_beginscan(
NULL,
cql("SELECT * FROM pg_class "
" WHERE oid = :1 ",
ObjectIdGetDatum(classid)));
classtup = caql_getnext(pcqCtx);
/* XXX XXX select relname, relnamespace from pg_class */
if (HeapTupleIsValid(classtup))
{
Form_pg_class classform = (Form_pg_class) GETSTRUCT(classtup);
char *classname = NameStr(classform->relname);
/*
* In bootstrap mode, skip the fancy namespace stuff and just return
* the class name. (This path is only needed for debugging output
* anyway.)
*/
if (IsBootstrapProcessingMode())
result = pstrdup(classname);
else
{
char *nspname;
/*
* Would this class be found by regclassin? If not, qualify it.
*/
if (RelationIsVisible(classid))
nspname = NULL;
else
nspname = get_namespace_name(classform->relnamespace);
result = quote_qualified_identifier(nspname, classname);
}
}
else
{
/* If OID doesn't match any pg_class entry, return it numerically */
result = (char *) palloc(NAMEDATALEN);
snprintf(result, NAMEDATALEN, "%u", classid);
}
caql_endscan(pcqCtx);
PG_RETURN_CSTRING(result);
}