/* * Class: org_postgresql_pljava_internal_Session * Method: _setUser * Signature: (Lorg/postgresql/pljava/internal/AclId;)V */ JNIEXPORT void JNICALL Java_org_postgresql_pljava_internal_Session__1setUser(JNIEnv* env, jclass cls, jobject aclId) { /* No error checking since this might be a restore of user in * a finally block after an exception. */ BEGIN_NATIVE_NO_ERRCHECK SetUserIdAndContext(AclId_getAclId(aclId), true); END_NATIVE }
/* * CREATE SCHEMA */ void CreateSchemaCommand(CreateSchemaStmt *stmt, const char *queryString) { const char *schemaName = stmt->schemaname; const char *authId = stmt->authid; const bool istemp = stmt->istemp; Oid namespaceId = 0; List *parsetree_list; ListCell *parsetree_item; Oid owner_uid; Oid saved_uid; AclResult aclresult; bool saved_secdefcxt; /* bool shouldDispatch = (Gp_role == GP_ROLE_DISPATCH && !IsBootstrapProcessingMode());*/ GetUserIdAndContext(&saved_uid, &saved_secdefcxt); /* * Who is supposed to own the new schema? */ if (authId) owner_uid = get_roleid_checked(authId); else owner_uid = saved_uid; /* * If we are creating a temporary schema then we can skip a * bunch of checks that we would otherwise make. */ if (istemp) { /* * CDB: Delete old temp schema. * * Remove any vestigages of old temporary schema, if any. This can * happen when an old session crashes and doesn't run normal session * shutdown. * * In postgres they try to reuse existing schemas in this case, * however that does not work well for us since the schemas may exist * on a segment by segment basis and we want to keep them syncronized * on oid. The best way of dealing with this is to just delete the * old schemas. */ RemoveSchema_internal(schemaName, DROP_CASCADE, true, true); } else { /* * To create a schema, must have schema-create privilege on the current * database and must be able to become the target role (this does not * imply that the target role itself must have create-schema privilege). * The latter provision guards against "giveaway" attacks. Note that a * superuser will always have both of these privileges a fortiori. */ aclresult = pg_database_aclcheck(MyDatabaseId, saved_uid, ACL_CREATE); if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, ACL_KIND_DATABASE, get_database_name(MyDatabaseId)); check_is_member_of_role(saved_uid, owner_uid); /* Additional check to protect reserved schema names */ if (!allowSystemTableModsDDL && (IsReservedName(schemaName) || strcmp(schemaName, "madlib") == 0)) { ereport(ERROR, (errcode(ERRCODE_RESERVED_NAME), errmsg("unacceptable schema name \"%s\"", schemaName), errdetail("The prefix \"%s\" is reserved for system schemas.", GetReservedPrefix(schemaName)))); } } /* * If the requested authorization is different from the current user, * temporarily set the current user so that the object(s) will be created * with the correct ownership. * * (The setting will be restored at the end of this routine, or in case * of error, transaction abort will clean things up.) */ if (saved_uid != owner_uid) SetUserIdAndContext(owner_uid, true); /* * in hawq, should be only called on master except * UPGRADE model. */ Assert(gp_upgrade_mode || (Gp_role != GP_ROLE_EXECUTE)); /* Create the schema's namespace */ namespaceId = NamespaceCreate(schemaName, owner_uid, 0); /* MPP-6929: metadata tracking */ if (Gp_role == GP_ROLE_DISPATCH && !istemp) MetaTrackAddObject(NamespaceRelationId, namespaceId, saved_uid, "CREATE", "SCHEMA" ); /* Advance cmd counter to make the namespace visible */ CommandCounterIncrement(); /* If this is the temporary namespace we must mark it specially */ if (istemp) SetTempNamespace(namespaceId); /* * Temporarily make the new namespace be the front of the search path, as * well as the default creation target namespace. This will be undone at * the end of this routine, or upon error. */ PushSpecialNamespace(namespaceId); /* * Examine the list of commands embedded in the CREATE SCHEMA command, and * reorganize them into a sequentially executable order with no forward * references. Note that the result is still a list of raw parsetrees in * need of parse analysis --- we cannot, in general, run analyze.c on one * statement until we have actually executed the prior ones. */ parsetree_list = analyzeCreateSchemaStmt(stmt); /* * Analyze and execute each command contained in the CREATE SCHEMA */ foreach(parsetree_item, parsetree_list) { Node *parsetree = (Node *) lfirst(parsetree_item); List *querytree_list; ListCell *querytree_item; querytree_list = parse_analyze(parsetree, NULL, NULL, 0); foreach(querytree_item, querytree_list) { Query *querytree = (Query *) lfirst(querytree_item); /* schemas should contain only utility stmts */ Assert(querytree->commandType == CMD_UTILITY); /* do this step */ ProcessUtility(querytree->utilityStmt, queryString, NULL, false, /* not top level */ None_Receiver, NULL); /* make sure later steps can see the object created here */ CommandCounterIncrement(); }
/* * CREATE SCHEMA */ void CreateSchemaCommand(CreateSchemaStmt *stmt, const char *queryString) { const char *schemaName = stmt->schemaname; const char *authId = stmt->authid; Oid namespaceId; OverrideSearchPath *overridePath; List *parsetree_list; ListCell *parsetree_item; Oid owner_uid; Oid saved_uid; bool saved_secdefcxt; AclResult aclresult; GetUserIdAndContext(&saved_uid, &saved_secdefcxt); /* * Who is supposed to own the new schema? */ if (authId) owner_uid = get_roleid_checked(authId); else owner_uid = saved_uid; /* * To create a schema, must have schema-create privilege on the current * database and must be able to become the target role (this does not * imply that the target role itself must have create-schema privilege). * The latter provision guards against "giveaway" attacks. Note that a * superuser will always have both of these privileges a fortiori. */ aclresult = pg_database_aclcheck(MyDatabaseId, saved_uid, ACL_CREATE); if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, ACL_KIND_DATABASE, get_database_name(MyDatabaseId)); check_is_member_of_role(saved_uid, owner_uid); /* Additional check to protect reserved schema names */ if (!allowSystemTableMods && IsReservedName(schemaName)) ereport(ERROR, (errcode(ERRCODE_RESERVED_NAME), errmsg("unacceptable schema name \"%s\"", schemaName), errdetail("The prefix \"pg_\" is reserved for system schemas."))); /* * If the requested authorization is different from the current user, * temporarily set the current user so that the object(s) will be created * with the correct ownership. * * (The setting will be restored at the end of this routine, or in case of * error, transaction abort will clean things up.) */ if (saved_uid != owner_uid) SetUserIdAndContext(owner_uid, true); /* Create the schema's namespace */ namespaceId = NamespaceCreate(schemaName, owner_uid); /* Advance cmd counter to make the namespace visible */ CommandCounterIncrement(); /* * Temporarily make the new namespace be the front of the search path, as * well as the default creation target namespace. This will be undone at * the end of this routine, or upon error. */ overridePath = GetOverrideSearchPath(CurrentMemoryContext); overridePath->schemas = lcons_oid(namespaceId, overridePath->schemas); /* XXX should we clear overridePath->useTemp? */ PushOverrideSearchPath(overridePath); /* * Examine the list of commands embedded in the CREATE SCHEMA command, and * reorganize them into a sequentially executable order with no forward * references. Note that the result is still a list of raw parsetrees --- * we cannot, in general, run parse analysis on one statement until we * have actually executed the prior ones. */ parsetree_list = transformCreateSchemaStmt(stmt); /* * Execute each command contained in the CREATE SCHEMA. Since the grammar * allows only utility commands in CREATE SCHEMA, there is no need to pass * them through parse_analyze() or the rewriter; we can just hand them * straight to ProcessUtility. */ foreach(parsetree_item, parsetree_list) { Node *stmt = (Node *) lfirst(parsetree_item); /* do this step */ ProcessUtility(stmt, queryString, NULL, false, /* not top level */ None_Receiver, NULL); /* make sure later steps can see the object created here */ CommandCounterIncrement(); }