// // constructor // StmtDDLDropSchema::StmtDDLDropSchema(//const SchemaName & schemaName, const ElemDDLSchemaName & aSchemaNameParseNode, ComDropBehavior dropBehavior, ComBoolean cleanupMode, ComBoolean dropObjectsOnly) : StmtDDLNode(DDL_DROP_SCHEMA), schemaQualName_(aSchemaNameParseNode.getSchemaName(), PARSERHEAP()), dropBehavior_(dropBehavior), cleanupMode_(cleanupMode), dropObjectsOnly_(dropObjectsOnly), dropIfExists_(FALSE), schemaName_(PARSERHEAP()) { if (schemaQualName_.getCatalogName().isNull()) { schemaName_ = ToAnsiIdentifier(schemaQualName_.getSchemaName()); } else { schemaName_ = ToAnsiIdentifier(schemaQualName_.getCatalogName()) + "." + ToAnsiIdentifier(schemaQualName_.getSchemaName()); } // If the schema name specified is reserved name, users cannot drop them. // They can only be dropped internally. if ((! Get_SqlParser_Flags(INTERNAL_QUERY_FROM_EXEUTIL)) && (ComIsTrafodionReservedSchemaName(schemaQualName_.getSchemaName()))) { // error. *SqlParser_Diags << DgSqlCode(-1430) << DgSchemaName(schemaName_); } }
NABoolean CmpSqlSession::validateVolatileSchemaName(NAString &schName) { if (NOT schName.isNull()) { ComSchemaName csn(schName); if (NOT csn.isValid()) { // Schema name $0~SchemaName is not valid. *CmpCommon::diags() << DgSqlCode(-8009) << DgSchemaName(schName); return FALSE; } Lng32 len = MINOF(strlen(csn.getSchemaNamePartAsAnsiString().data()), strlen(COM_VOLATILE_SCHEMA_PREFIX)); NAString upSch(csn.getSchemaNamePartAsAnsiString().data()); upSch.toUpper(); if ((NOT Get_SqlParser_Flags(ALLOW_VOLATILE_SCHEMA_IN_TABLE_NAME)) && (len > 0) && (strncmp(upSch.data(), COM_VOLATILE_SCHEMA_PREFIX, len) == 0)) { *CmpCommon::diags() << DgSqlCode(-4193) << DgString0(COM_VOLATILE_SCHEMA_PREFIX); return FALSE; } } return TRUE; }
// ***************************************************************************** // * * // * Function: CmpSeabaseDDL::giveSeabaseSchema * // * * // * Implements the GIVE SCHEMA command. * // * * // ***************************************************************************** // * * // * Parameters: * // * * // * <giveSchemaNode> StmtDDLGiveSchema * In * // * is a pointer to a create schema parser node. * // * * // * <currentCatalogName> NAString & In * // * is the name of the current catalog. * // * * // ***************************************************************************** void CmpSeabaseDDL::giveSeabaseSchema( StmtDDLGiveSchema * giveSchemaNode, NAString & currentCatalogName) { ComDropBehavior dropBehavior = giveSchemaNode->getDropBehavior(); NAString catalogName = giveSchemaNode->getCatalogName(); NAString schemaName = giveSchemaNode->getSchemaName(); if (catalogName.isNull()) catalogName = currentCatalogName; ExeCliInterface cliInterface(STMTHEAP, NULL, NULL, CmpCommon::context()->sqlSession()->getParentQid()); Int32 objectOwnerID = 0; Int32 schemaOwnerID = 0; ComObjectType objectType; Int64 schemaUID = getObjectTypeandOwner(&cliInterface,catalogName.data(), schemaName.data(),SEABASE_SCHEMA_OBJECTNAME, objectType,schemaOwnerID); if (schemaUID == -1) { // A Trafodion schema does not exist if the schema object row is not // present: CATALOG-NAME.SCHEMA-NAME.__SCHEMA__. *CmpCommon::diags() << DgSqlCode(-CAT_SCHEMA_DOES_NOT_EXIST_ERROR) << DgSchemaName(schemaName.data()); return; } // ***************************************************************************** // * * // * A schema owner can give their own schema to another authID, but they * // * cannot give the objects in a shared schema to another authID. Only * // * DB__ROOT or a user with the ALTER_SCHEMA privilege can change the owners * // * of objects in a shared schema. So if the schema is private, or if only * // * the schema is being given, we do standard authentication checking. But * // * if giving all the objects in a shared schema, we change the check ID to * // * the default user to force the ALTER_SCHEMA privilege check. * // * * // ***************************************************************************** int32_t checkID = schemaOwnerID; if (objectType == COM_SHARED_SCHEMA_OBJECT && dropBehavior == COM_CASCADE_DROP_BEHAVIOR) checkID = NA_UserIdDefault; if (!isDDLOperationAuthorized(SQLOperation::ALTER_SCHEMA,checkID,checkID)) { *CmpCommon::diags() << DgSqlCode(-CAT_NOT_AUTHORIZED); return; } ComObjectName objName(catalogName,schemaName,NAString("dummy"),COM_TABLE_NAME,TRUE); if (isSeabaseReservedSchema(objName) && !Get_SqlParser_Flags(INTERNAL_QUERY_FROM_EXEUTIL)) { *CmpCommon::diags() << DgSqlCode(-CAT_USER_CANNOT_DROP_SMD_SCHEMA) << DgSchemaName(schemaName.data()); return; } bool isVolatile = (memcmp(schemaName.data(),"VOLATILE_SCHEMA",strlen("VOLATILE_SCHEMA")) == 0); // Can't give a schema whose name begins with VOLATILE_SCHEMA. if (isVolatile) { *CmpCommon::diags() << DgSqlCode(-CAT_RESERVED_METADATA_SCHEMA_NAME) << DgTableName(schemaName); return; } int32_t newOwnerID = -1; if (ComUser::getAuthIDFromAuthName(giveSchemaNode->getAuthID().data(), newOwnerID) != 0) { *CmpCommon::diags() << DgSqlCode(-CAT_AUTHID_DOES_NOT_EXIST_ERROR) << DgString0(giveSchemaNode->getAuthID().data()); return; } // ***************************************************************************** // * * // * Drop behavior is only relevant for shared schemas. For shared schemas, * // * ownership of the schema OR the schema and all its objects may be given to * // * another authorization ID. For private schemas, all objects are owned by * // * the schema owner, so the drop behavior is always CASCADE. * // * * // * NOTE: The syntax for drop behavior always defaults to RESTRICT; for * // * private schemas this is simply ignored, as opposed to requiring * // * users to always specify CASCASE. * // * * // ***************************************************************************** Lng32 cliRC = 0; char buf[4000]; if (objectType == COM_SHARED_SCHEMA_OBJECT && dropBehavior == COM_RESTRICT_DROP_BEHAVIOR) { str_sprintf(buf,"UPDATE %s.\"%s\".%s " "SET object_owner = %d " "WHERE object_UID = %Ld", getSystemCatalog(),SEABASE_MD_SCHEMA,SEABASE_OBJECTS, newOwnerID,schemaUID); cliRC = cliInterface.executeImmediate(buf); if (cliRC < 0) cliInterface.retrieveSQLDiagnostics(CmpCommon::diags()); return; } // // At this point, we are giving all objects in the schema (as well as the // schema itself) to the new authorization ID. If authentication is enabled, // update the privileges first. // if (isAuthorizationEnabled()) { int32_t rc = transferObjectPrivs(getSystemCatalog(),catalogName.data(), schemaName.data(),newOwnerID, giveSchemaNode->getAuthID().data()); if (rc != 0) { if (CmpCommon::diags()->getNumber(DgSqlCode::ERROR_) == 0) { //TODO: add error } return; } } // Now update the object owner for all objects in the schema. str_sprintf(buf,"UPDATE %s.\"%s\".%s " "SET object_owner = %d " "WHERE catalog_name = '%s' AND schema_name = '%s'", getSystemCatalog(),SEABASE_MD_SCHEMA,SEABASE_OBJECTS, newOwnerID,catalogName.data(),schemaName.data()); cliRC = cliInterface.executeImmediate(buf); if (cliRC < 0) { cliInterface.retrieveSQLDiagnostics(CmpCommon::diags()); return; } // Verify all objects in the schema have been given to the new owner. str_sprintf(buf,"SELECT COUNT(*) " "FROM %s.\"%s\".%s " "WHERE catalog_name = '%s' AND schema_name = '%s' AND " "object_name <> '"SEABASE_SCHEMA_OBJECTNAME"' AND " "object_owner <> %d " "FOR READ COMMITTED ACCESS", getSystemCatalog(),SEABASE_MD_SCHEMA,SEABASE_OBJECTS, catalogName.data(),schemaName.data(),newOwnerID); int32_t length = 0; int32_t rowCount = 0; cliRC = cliInterface.executeImmediate(buf,(char*)&rowCount,&length,NULL); if (cliRC < 0) { cliInterface.retrieveSQLDiagnostics(CmpCommon::diags()); return; } if (rowCount > 0) { SEABASEDDL_INTERNAL_ERROR("Not all objects in schema were given"); return; } }
// ***************************************************************************** // * * // * Function: CmpSeabaseDDL::dropSeabaseSchema * // * * // * Implements the DROP SCHEMA command. * // * * // ***************************************************************************** // * * // * Parameters: * // * * // * <dropSchemaNode> StmtDDLDropSchema * In * // * is a pointer to a create schema parser node. * // * * // ***************************************************************************** void CmpSeabaseDDL::dropSeabaseSchema(StmtDDLDropSchema * dropSchemaNode) { Lng32 cliRC = 0; ComSchemaName schemaName(dropSchemaNode->getSchemaName()); NAString catName = schemaName.getCatalogNamePartAsAnsiString(); ComAnsiNamePart schNameAsComAnsi = schemaName.getSchemaNamePart(); NAString schName = schNameAsComAnsi.getInternalName(); ExeCliInterface cliInterface(STMTHEAP, NULL, NULL, CmpCommon::context()->sqlSession()->getParentQid()); Int32 objectOwnerID = 0; Int32 schemaOwnerID = 0; ComObjectType objectType; Int64 schemaUID = getObjectTypeandOwner(&cliInterface,catName.data(),schName.data(), SEABASE_SCHEMA_OBJECTNAME,objectType,schemaOwnerID); // if schemaUID == -1, then either the schema does not exist or an unexpected error occurred if (schemaUID == -1) { // If an error occurred, return if (CmpCommon::diags()->getNumber(DgSqlCode::ERROR_) > 0) return; // schema does not exist and IF EXISTS specified, then ignore and continue if (dropSchemaNode->dropIfExists()) return; // A Trafodion schema does not exist if the schema object row is not // present: CATALOG-NAME.SCHEMA-NAME.__SCHEMA__. *CmpCommon::diags() << DgSqlCode(-CAT_SCHEMA_DOES_NOT_EXIST_ERROR) << DgSchemaName(schemaName.getExternalName().data()); return; } if (!isDDLOperationAuthorized(SQLOperation::DROP_SCHEMA, schemaOwnerID,schemaOwnerID)) { *CmpCommon::diags() << DgSqlCode(-CAT_NOT_AUTHORIZED); return; } ComObjectName objName(catName,schName,NAString("dummy"),COM_TABLE_NAME,TRUE); if ((isSeabaseReservedSchema(objName) || (schName == SEABASE_SYSTEM_SCHEMA)) && !Get_SqlParser_Flags(INTERNAL_QUERY_FROM_EXEUTIL)) { *CmpCommon::diags() << DgSqlCode(-CAT_USER_CANNOT_DROP_SMD_SCHEMA) << DgSchemaName(schemaName.getExternalName().data()); return; } bool isVolatile = (memcmp(schName.data(),"VOLATILE_SCHEMA",strlen("VOLATILE_SCHEMA")) == 0); // Can't drop a schema whose name begins with VOLATILE_SCHEMA unless the // keyword VOLATILE was specified in the DROP SCHEMA command. if (isVolatile && !dropSchemaNode->isVolatile()) { *CmpCommon::diags() << DgSqlCode(-CAT_RESERVED_METADATA_SCHEMA_NAME) << DgTableName(schName); return; } // Get a list of all objects in the schema, excluding the schema object itself. char query[4000]; str_sprintf(query,"SELECT TRIM(object_name), TRIM(object_type) " "FROM %s.\"%s\".%s " "WHERE catalog_name = '%s' AND schema_name = '%s' AND " "object_name <> '"SEABASE_SCHEMA_OBJECTNAME"'" "FOR READ COMMITTED ACCESS", getSystemCatalog(),SEABASE_MD_SCHEMA,SEABASE_OBJECTS, (char*)catName.data(),(char*)schName.data()); Queue * objectsQueue = NULL; cliRC = cliInterface.fetchAllRows(objectsQueue, query, 0, FALSE, FALSE, TRUE); if (cliRC < 0) { cliInterface.retrieveSQLDiagnostics(CmpCommon::diags()); return; } objectsQueue->position(); if ((dropSchemaNode->getDropBehavior() == COM_RESTRICT_DROP_BEHAVIOR) && (objectsQueue->numEntries() > 0)) { OutputInfo * oi = (OutputInfo*)objectsQueue->getCurr(); *CmpCommon::diags() << DgSqlCode(-CAT_SCHEMA_IS_NOT_EMPTY) << DgTableName(oi->get(0)); return; } bool someObjectsCouldNotBeDropped = false; // Drop libraries, procedures (SPJs), UDFs (functions), and views objectsQueue->position(); for (int idx = 0; idx < objectsQueue->numEntries(); idx++) { OutputInfo * vi = (OutputInfo*)objectsQueue->getNext(); char * objName = vi->get(0); NAString objectTypeLit = vi->get(1); ComObjectType objectType = PrivMgr::ObjectLitToEnum(objectTypeLit.data()); char buf[1000]; NAString objectTypeString; NAString cascade = " "; switch (objectType) { // These object types are handled later and can be ignored for now. case COM_BASE_TABLE_OBJECT: case COM_INDEX_OBJECT: case COM_CHECK_CONSTRAINT_OBJECT: case COM_NOT_NULL_CONSTRAINT_OBJECT: case COM_PRIMARY_KEY_CONSTRAINT_OBJECT: case COM_REFERENTIAL_CONSTRAINT_OBJECT: case COM_SEQUENCE_GENERATOR_OBJECT: case COM_UNIQUE_CONSTRAINT_OBJECT: { continue; } case COM_LIBRARY_OBJECT: { objectTypeString = "LIBRARY"; cascade = "CASCADE"; break; } case COM_STORED_PROCEDURE_OBJECT: { objectTypeString = "PROCEDURE"; break; } case COM_USER_DEFINED_ROUTINE_OBJECT: { objectTypeString = "FUNCTION"; cascade = "CASCADE"; break; } case COM_VIEW_OBJECT: { objectTypeString = "VIEW"; cascade = "CASCADE"; break; } // These object types should not be seen. case COM_MV_OBJECT: case COM_MVRG_OBJECT: case COM_TRIGGER_OBJECT: case COM_LOB_TABLE_OBJECT: case COM_TRIGGER_TABLE_OBJECT: case COM_SYNONYM_OBJECT: case COM_PRIVATE_SCHEMA_OBJECT: case COM_SHARED_SCHEMA_OBJECT: case COM_EXCEPTION_TABLE_OBJECT: case COM_LOCK_OBJECT: case COM_MODULE_OBJECT: default: SEABASEDDL_INTERNAL_ERROR("Unrecognized object type in schema"); return; } str_sprintf(buf, "drop %s \"%s\".\"%s\".\"%s\" %s", objectTypeString.data(),(char*)catName.data(),(char*)schName.data(), objName,cascade.data()); cliRC = cliInterface.executeImmediate(buf); if (cliRC < 0 && cliRC != -CAT_OBJECT_DOES_NOT_EXIST_IN_TRAFODION) someObjectsCouldNotBeDropped = true; } // Drop all tables in the schema. This will also drop any associated constraints. // Drop of histogram tables is deferred. bool histExists = false; objectsQueue->position(); for (int idx = 0; idx < objectsQueue->numEntries(); idx++) { OutputInfo * vi = (OutputInfo*)objectsQueue->getNext(); NAString objName = vi->get(0); NAString objType = vi->get(1); // drop user objects first if (objType == COM_BASE_TABLE_OBJECT_LIT) { if (!(objName == HBASE_HIST_NAME || objName == HBASE_HISTINT_NAME)) { if (dropOneTable(cliInterface,(char*)catName.data(), (char*)schName.data(),(char*)objName.data(), isVolatile)) someObjectsCouldNotBeDropped = true; } else histExists = true; } } // Drop any remaining indexes. str_sprintf(query,"SELECT TRIM(object_name), TRIM(object_type) " "FROM %s.\"%s\".%s " "WHERE catalog_name = '%s' AND " " schema_name = '%s' AND " " object_type = '%s' " "FOR READ COMMITTED ACCESS ", getSystemCatalog(),SEABASE_MD_SCHEMA,SEABASE_OBJECTS, (char*)catName.data(),(char*)schName.data(), COM_INDEX_OBJECT_LIT); cliRC = cliInterface.fetchAllRows(objectsQueue,query,0,FALSE,FALSE,TRUE); if (cliRC < 0) { cliInterface.retrieveSQLDiagnostics(CmpCommon::diags()); return; } objectsQueue->position(); for (int idx = 0; idx < objectsQueue->numEntries(); idx++) { OutputInfo * vi = (OutputInfo*)objectsQueue->getNext(); char * objName = vi->get(0); NAString objType = vi->get(1); if (objType == COM_INDEX_OBJECT_LIT) { char buf [1000]; str_sprintf(buf, "DROP INDEX \"%s\".\"%s\".\"%s\" CASCADE", (char*)catName.data(), (char*)schName.data(), objName); cliRC = cliInterface.executeImmediate(buf); if (cliRC < 0 && cliRC != -CAT_OBJECT_DOES_NOT_EXIST_IN_TRAFODION) someObjectsCouldNotBeDropped = true; } } // Drop any remaining sequences. str_sprintf(query,"SELECT TRIM(object_name), TRIM(object_type) " "FROM %s.\"%s\".%s " "WHERE catalog_name = '%s' AND " " schema_name = '%s' AND " " object_type = '%s' " "FOR READ COMMITTED ACCESS ", getSystemCatalog(),SEABASE_MD_SCHEMA,SEABASE_OBJECTS, (char*)catName.data(),(char*)schName.data(), COM_SEQUENCE_GENERATOR_OBJECT_LIT); cliRC = cliInterface.fetchAllRows(objectsQueue,query,0,FALSE,FALSE,TRUE); if (cliRC < 0) { cliInterface.retrieveSQLDiagnostics(CmpCommon::diags()); return; } objectsQueue->position(); for (int idx = 0; idx < objectsQueue->numEntries(); idx++) { OutputInfo * vi = (OutputInfo*)objectsQueue->getNext(); char * objName = vi->get(0); NAString objType = vi->get(1); if (objType == COM_SEQUENCE_GENERATOR_OBJECT_LIT) { char buf [1000]; str_sprintf(buf, "DROP SEQUENCE \"%s\".\"%s\".\"%s\"", (char*)catName.data(), (char*)schName.data(), objName); cliRC = cliInterface.executeImmediate(buf); if (cliRC < 0 && cliRC != -CAT_OBJECT_DOES_NOT_EXIST_IN_TRAFODION) someObjectsCouldNotBeDropped = true; } } // For volatile schemas, sometimes only the objects get dropped. // If the dropObjectsOnly flag is set, just exit now, we are done. if (dropSchemaNode->dropObjectsOnly()) return; // Now drop any histogram objects if (histExists) { if (dropOneTable(cliInterface,(char*)catName.data(),(char*)schName.data(), (char*)HBASE_HISTINT_NAME,false)) someObjectsCouldNotBeDropped = true; if (dropOneTable(cliInterface,(char*)catName.data(),(char*)schName.data(), (char*)HBASE_HIST_NAME,false)) someObjectsCouldNotBeDropped = true; } if (someObjectsCouldNotBeDropped) { CmpCommon::diags()->clear(); *CmpCommon::diags() << DgSqlCode(-CAT_UNABLE_TO_DROP_SCHEMA) << DgSchemaName(catName + "." + schName); return; } // Verify all objects in the schema have been dropped. str_sprintf(query,"SELECT COUNT(*) " "FROM %s.\"%s\".%s " "WHERE catalog_name = '%s' AND schema_name = '%s' AND " "object_name <> '"SEABASE_SCHEMA_OBJECTNAME"'" "FOR READ COMMITTED ACCESS", getSystemCatalog(),SEABASE_MD_SCHEMA,SEABASE_OBJECTS, (char*)catName.data(),(char*)schName.data()); int32_t length = 0; int32_t rowCount = 0; cliRC = cliInterface.executeImmediate(query,(char*)&rowCount,&length,NULL); if (cliRC < 0) { cliInterface.retrieveSQLDiagnostics(CmpCommon::diags()); return; } if (rowCount > 0) { CmpCommon::diags()->clear(); *CmpCommon::diags() << DgSqlCode(-CAT_UNABLE_TO_DROP_SCHEMA) << DgSchemaName(catName + "." + schName); return; } // After all objects in the schema have been dropped, drop the schema object itself. char buf [1000]; str_sprintf(buf,"DELETE FROM %s.\"%s\".%s " "WHERE CATALOG_NAME = '%s' AND SCHEMA_NAME = '%s' AND " "OBJECT_NAME = '"SEABASE_SCHEMA_OBJECTNAME"'", getSystemCatalog(),SEABASE_MD_SCHEMA,SEABASE_OBJECTS, (char*)catName.data(),(char*)schName.data()); cliRC = cliInterface.executeImmediate(buf); if (cliRC < 0) *CmpCommon::diags() << DgSqlCode(-CAT_UNABLE_TO_DROP_SCHEMA) << DgSchemaName(catName + "." + schName); }
// ***************************************************************************** // * * // * Function: CmpSeabaseDDL::describeSchema * // * * // * Provides text for SHOWDDL SCHEMA comnmand. * // * * // ***************************************************************************** // * * // * Parameters: * // * * // * <catalogName> const NAString & In * // * is a reference to a catalog name. * // * * // * <schemaName> const NAString & In * // * is a reference to a schema name. * // * * // * <output> NAString & Out * // * passes back text for the SHOWDDL SCHEMA command, specifically the * // * command to create the specified schema. * // * * // ***************************************************************************** // * * // * Returns: bool * // * * // * true: Text returned for specified schema. * // * false: Could not retrieve information for specified schema. * // * * // ***************************************************************************** bool CmpSeabaseDDL::describeSchema( const NAString & catalogName, const NAString & schemaName, NAString & output) { ExeCliInterface cliInterface(STMTHEAP, NULL, NULL, CmpCommon::context()->sqlSession()->getParentQid()); ComSchemaClass schemaClass; Int32 objectOwner; Int32 schemaOwner; ComObjectType objectType; CmpSeabaseDDL cmpSBD(STMTHEAP); if (cmpSBD.switchCompiler()) { *CmpCommon::diags() << DgSqlCode(-CAT_UNABLE_TO_RETRIEVE_PRIVS); return false; } Int64 schemaUID = getObjectTypeandOwner(&cliInterface, catalogName.data(), schemaName.data(), SEABASE_SCHEMA_OBJECTNAME, objectType, objectOwner); if (schemaUID < 0) { *CmpCommon::diags() << DgSqlCode(-CAT_SCHEMA_DOES_NOT_EXIST_ERROR) << DgSchemaName(catalogName + "." + schemaName); cmpSBD.switchBackCompiler(); return false; } char username[MAX_USERNAME_LEN+1]; Int32 lActualLen = 0; Int16 status = ComUser::getAuthNameFromAuthID(objectOwner,username, MAX_USERNAME_LEN,lActualLen); if (status != FEOK) { *CmpCommon::diags() << DgSqlCode(-20235) // Error converting user ID. << DgInt0(status) << DgInt1(objectOwner); cmpSBD.switchBackCompiler(); return false; } // Generate output text output = "CREATE "; switch (objectType) { case COM_PRIVATE_SCHEMA_OBJECT: output += "PRIVATE"; break; case COM_SHARED_SCHEMA_OBJECT: output += "SHARED"; break; default: return false; } output += " SCHEMA \""; output += catalogName.data(); output += "\".\""; output += schemaName.data(); // AUTHORIZATION clause is rarely used, but include it for replay. output += "\" AUTHORIZATION \""; output += username; output += "\";"; cmpSBD.switchBackCompiler(); return true; }
// ***************************************************************************** // * * // * Function: CmpSeabaseDDL::addSchemaObject * // * * // * Inserts a schema object row into the OBJECTS table. * // * * // ***************************************************************************** // * * // * Parameters: * // * * // * <cliInterface> ExeCliInterface & In * // * is a reference to an Executor CLI interface handle. * // * * // * <schemaName> const ComSchemaName & In * // * is a reference to a ComSchemaName instance. The catalog name must be * // * set. * // * * // * <schemaClass> ComSchemaClass In * // * is the class (private or shared) of the schema to be added. * // * * // * <ownerID> Int32 In * // * is the authorization ID that will own the schema. * // * * // * <ignoreIfExists> NABoolean In * // * do not return an error is schema already exists * // ***************************************************************************** // * * // * Returns: PrivStatus * // * * // * 0: Schema as added * // * -1: Schema was not added. A CLI error is put into the diags area. * // * * // ***************************************************************************** int CmpSeabaseDDL::addSchemaObject( ExeCliInterface & cliInterface, const ComSchemaName & schemaName, ComSchemaClass schemaClass, Int32 ownerID, NABoolean ignoreIfExists) { NAString catalogName = schemaName.getCatalogNamePartAsAnsiString(); ComAnsiNamePart schemaNameAsComAnsi = schemaName.getSchemaNamePart(); NAString schemaNamePart = schemaNameAsComAnsi.getInternalName(); ComObjectName objName(catalogName,schemaNamePart,NAString(SEABASE_SCHEMA_OBJECTNAME), COM_TABLE_NAME,TRUE); if (isSeabaseReservedSchema(objName) && !Get_SqlParser_Flags(INTERNAL_QUERY_FROM_EXEUTIL)) { *CmpCommon::diags() << DgSqlCode(-CAT_RESERVED_METADATA_SCHEMA_NAME) << DgSchemaName(schemaName.getExternalName().data()); return -1; } NAString objectNamePart = objName.getObjectNamePartAsAnsiString(TRUE); Lng32 retcode = existsInSeabaseMDTable(&cliInterface,catalogName,schemaNamePart, objectNamePart, COM_UNKNOWN_OBJECT, FALSE); if (retcode < 0) return -1; if (retcode == 1 ) // already exists { if (ignoreIfExists) return 0; else *CmpCommon::diags() << DgSqlCode(-CAT_SCHEMA_ALREADY_EXISTS) << DgSchemaName(schemaName.getExternalName().data()); return -1; } char buf[4000]; ComUID schemaUID; schemaUID.make_UID(); Int64 schemaObjectUID = schemaUID.get_value(); Int64 createTime = NA_JulianTimestamp(); NAString quotedSchName; NAString quotedObjName; ToQuotedString(quotedSchName,schemaNamePart,FALSE); ToQuotedString(quotedObjName,NAString(SEABASE_SCHEMA_OBJECTNAME),FALSE); char schemaObjectLit[3] = {0}; switch (schemaClass) { case COM_SCHEMA_CLASS_PRIVATE: { strncpy(schemaObjectLit,COM_PRIVATE_SCHEMA_OBJECT_LIT,2); break; } case COM_SCHEMA_CLASS_SHARED: { strncpy(schemaObjectLit,COM_SHARED_SCHEMA_OBJECT_LIT,2); break; } case COM_SCHEMA_CLASS_DEFAULT: default: { // Schemas are private by default, but could choose a different // default class here based on CQD or other attribute. strncpy(schemaObjectLit,COM_PRIVATE_SCHEMA_OBJECT_LIT,2); break; } } str_sprintf(buf, "insert into %s.\"%s\".%s values ('%s', '%s', '%s', '%s', %Ld, %Ld, %Ld, '%s', '%s', %d, %d, 0)", getSystemCatalog(),SEABASE_MD_SCHEMA,SEABASE_OBJECTS, catalogName.data(), quotedSchName.data(), quotedObjName.data(), schemaObjectLit, schemaObjectUID, createTime, createTime, COM_YES_LIT, // valid_def COM_NO_LIT, // droppable ownerID,ownerID); Int32 cliRC = cliInterface.executeImmediate(buf); if (cliRC < 0) { cliInterface.retrieveSQLDiagnostics(CmpCommon::diags()); return -1; } return 0; }