/* * CreateJobSchema creates a job schema with the given schema name. Note that * this function ensures that our pg_ prefixed schema names can be created. * Further note that the created schema does not become visible to other * processes until the transaction commits. */ static void CreateJobSchema(StringInfo schemaName) { const char *queryString = NULL; bool oldAllowSystemTableMods = false; Oid savedUserId = InvalidOid; int savedSecurityContext = 0; /* build a CREATE SCHEMA statement */ CreateSchemaStmt *createSchemaStmt = makeNode(CreateSchemaStmt); createSchemaStmt->schemaname = schemaName->data; createSchemaStmt->authrole = NULL; createSchemaStmt->schemaElts = NIL; /* allow schema names that start with pg_ */ oldAllowSystemTableMods = allowSystemTableMods; allowSystemTableMods = true; /* ensure we're allowed to create this schema */ GetUserIdAndSecContext(&savedUserId, &savedSecurityContext); SetUserIdAndSecContext(CitusExtensionOwner(), SECURITY_LOCAL_USERID_CHANGE); /* actually create schema, and make it visible */ CreateSchemaCommand(createSchemaStmt, queryString); CommandCounterIncrement(); /* and reset environment */ SetUserIdAndSecContext(savedUserId, savedSecurityContext); allowSystemTableMods = oldAllowSystemTableMods; }
/* * GetNextPlacementId allocates and returns a unique placementId for * the placement to be created. This allocation occurs both in shared memory * and in write ahead logs; writing to logs avoids the risk of having shardId * collisions. * * NB: This can be called by any user; for now we have decided that that's * ok. We might want to restrict this to users part of a specific role or such * at some later point. */ uint64 GetNextPlacementId(void) { text *sequenceName = NULL; Oid sequenceId = InvalidOid; Datum sequenceIdDatum = 0; Oid savedUserId = InvalidOid; int savedSecurityContext = 0; Datum placementIdDatum = 0; uint64 placementId = 0; /* * In regression tests, we would like to generate placement IDs consistently * even if the tests run in parallel. Instead of the sequence, we can use * the next_placement_id GUC to specify which shard ID the current session * should generate next. The GUC is automatically increased by 1 every time * a new placement ID is generated. */ if (NextPlacementId > 0) { placementId = NextPlacementId; NextPlacementId += 1; return placementId; } sequenceName = cstring_to_text(PLACEMENTID_SEQUENCE_NAME); sequenceId = ResolveRelationId(sequenceName); sequenceIdDatum = ObjectIdGetDatum(sequenceId); GetUserIdAndSecContext(&savedUserId, &savedSecurityContext); SetUserIdAndSecContext(CitusExtensionOwner(), SECURITY_LOCAL_USERID_CHANGE); /* generate new and unique placement id from sequence */ placementIdDatum = DirectFunctionCall1(nextval_oid, sequenceIdDatum); SetUserIdAndSecContext(savedUserId, savedSecurityContext); placementId = DatumGetInt64(placementIdDatum); return placementId; }
/* * master_get_new_shardid allocates and returns a unique shardId for the shard * to be created. This allocation occurs both in shared memory and in write * ahead logs; writing to logs avoids the risk of having shardId collisions. * * Please note that the caller is still responsible for finalizing shard data * and the shardId with the master node. Further note that this function relies * on an internal sequence created in initdb to generate unique identifiers. * * NB: This can be called by any user; for now we have decided that that's * ok. We might want to restrict this to users part of a specific role or such * at some later point. */ Datum master_get_new_shardid(PG_FUNCTION_ARGS) { text *sequenceName = cstring_to_text(SHARDID_SEQUENCE_NAME); Oid sequenceId = ResolveRelationId(sequenceName); Datum sequenceIdDatum = ObjectIdGetDatum(sequenceId); Oid savedUserId = InvalidOid; int savedSecurityContext = 0; Datum shardIdDatum = 0; GetUserIdAndSecContext(&savedUserId, &savedSecurityContext); SetUserIdAndSecContext(CitusExtensionOwner(), SECURITY_LOCAL_USERID_CHANGE); /* generate new and unique shardId from sequence */ shardIdDatum = DirectFunctionCall1(nextval_oid, sequenceIdDatum); SetUserIdAndSecContext(savedUserId, savedSecurityContext); PG_RETURN_DATUM(shardIdDatum); }