short CmpSeabaseDDL::getUsingRoutines(ExeCliInterface *cliInterface, Int64 objUID, Queue * & usingRoutinesQueue) { Lng32 retcode = 0; Lng32 cliRC = 0; char buf[4000]; str_sprintf(buf, "select trim(catalog_name) || '.' || trim(schema_name) || '.' || trim(object_name), object_type " "from %s.\"%s\".%s T, %s.\"%s\".%s LU " "where LU.using_library_uid = %Ld and " "T.object_uid = LU.used_udr_uid and T.valid_def = 'Y' ", getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_OBJECTS, getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_LIBRARIES_USAGE, objUID); usingRoutinesQueue = NULL; cliRC = cliInterface->fetchAllRows(usingRoutinesQueue, buf, 0, FALSE, FALSE, TRUE); if (cliRC < 0) { cliInterface->retrieveSQLDiagnostics(CmpCommon::diags()); return cliRC; } if (usingRoutinesQueue->numEntries() == 0) return 100; return 0; }
short CmpSeabaseDDL::dropMetadataViews(ExeCliInterface * cliInterface) { Lng32 cliRC = 0; Lng32 retcode = 0; char queryBuf[5000]; for (Int32 i = 0; i < sizeof(allMDviewsInfo)/sizeof(MDViewInfo); i++) { const MDViewInfo &mdi = allMDviewsInfo[i]; if (! mdi.viewName) continue; str_sprintf(queryBuf, "drop view %s.\"%s\".%s", getSystemCatalog(), SEABASE_MD_SCHEMA, mdi.viewName); NABoolean xnWasStartedHere = FALSE; if (beginXnIfNotInProgress(cliInterface, xnWasStartedHere)) return -1; cliRC = cliInterface->executeImmediate(queryBuf); if (cliRC < 0) { cliInterface->retrieveSQLDiagnostics(CmpCommon::diags()); } if (endXnIfStartedHere(cliInterface, xnWasStartedHere, cliRC) < 0) return -1; } // for return 0; }
// **************************************************************************** // method: getListOfDirectlyReferencedObjects // // Returns a list of objects that are being directly referenced by the passed // in objectUID // // Parameters: // cliInterface - used to get the list of object usages // objectUID - the UID being processed // objectList - a list of objectRefdByMe structures describing each usage // // returns: // 0 - successful // -1 - unexpected error occurred // **************************************************************************** short CmpSeabaseDDL::getListOfDirectlyReferencedObjects ( ExeCliInterface *cliInterface, const Int64 objectUID, NAList<objectRefdByMe> &objectsList) { // Select all the rows from views_usage associated with the passed in // objectUID Lng32 cliRC = 0; char buf[4000]; str_sprintf(buf, "select object_type, object_uid, catalog_name," "schema_name, object_name from %s.\"%s\".%s T, %s.\"%s\".%s VU " "where VU.using_view_uid = %Ld " "and T.object_uid = VU.used_object_uid", getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_OBJECTS, getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_VIEWS_USAGE, objectUID); Queue * usingObjectsQueue = NULL; cliRC = cliInterface->fetchAllRows(usingObjectsQueue, buf, 0, FALSE, FALSE, TRUE); if (cliRC < 0) { cliInterface->retrieveSQLDiagnostics(CmpCommon::diags()); return -1; } // set up an objectRefdByMe struct for each returned row usingObjectsQueue->position(); for (int idx = 0; idx < usingObjectsQueue->numEntries(); idx++) { OutputInfo * oi = (OutputInfo*)usingObjectsQueue->getNext(); objectRefdByMe objectInfo; objectInfo.objectType = NAString(oi->get(0)); objectInfo.objectUID = *(Int64*)oi->get(1); objectInfo.catalogName = NAString(oi->get(2)); objectInfo.schemaName = NAString(oi->get(3)); objectInfo.objectName = NAString(oi->get(4)); objectsList.insert(objectInfo); } return 0; }
// ***************************************************************************** // * * // * 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::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; }
void CmpSeabaseDDL::createSeabaseRoutine( StmtDDLCreateRoutine * createRoutineNode, NAString &currCatName, NAString &currSchName) { Lng32 retcode = 0; ComObjectName routineName(createRoutineNode->getRoutineName()); ComAnsiNamePart currCatAnsiName(currCatName); ComAnsiNamePart currSchAnsiName(currSchName); routineName.applyDefaults(currCatAnsiName, currSchAnsiName); const NAString catalogNamePart = routineName.getCatalogNamePartAsAnsiString(); const NAString schemaNamePart = routineName.getSchemaNamePartAsAnsiString(TRUE); const NAString objectNamePart = routineName.getObjectNamePartAsAnsiString(TRUE); const NAString extRoutineName = routineName.getExternalName(TRUE); ComRoutineType rType = createRoutineNode->getRoutineType(); ComRoutineLanguage language = createRoutineNode->getLanguageType(); ComRoutineParamStyle ddlStyle = createRoutineNode->getParamStyle(); ComRoutineParamStyle style = ddlStyle; NABoolean isJava = (language == COM_LANGUAGE_JAVA); // Check to see if user has the authority to create the routine ExeCliInterface cliInterface(STMTHEAP, NULL, NULL, CmpCommon::context()->sqlSession()->getParentQid()); Int32 objectOwnerID = SUPER_USER; Int32 schemaOwnerID = SUPER_USER; ComSchemaClass schemaClass; retcode = verifyDDLCreateOperationAuthorized(&cliInterface, SQLOperation::CREATE_ROUTINE, catalogNamePart, schemaNamePart, schemaClass, objectOwnerID, schemaOwnerID); if (retcode != 0) { handleDDLCreateAuthorizationError(retcode,catalogNamePart,schemaNamePart); return; } ExpHbaseInterface * ehi = NULL; ehi = allocEHI(); if (ehi == NULL) { processReturn(); return; } retcode = existsInSeabaseMDTable(&cliInterface, catalogNamePart, schemaNamePart, objectNamePart, COM_USER_DEFINED_ROUTINE_OBJECT, TRUE, FALSE); if (retcode < 0) { deallocEHI(ehi); processReturn(); return; } if (retcode == 1) // already exists { *CmpCommon::diags() << DgSqlCode(-1390) << DgString0(extRoutineName); deallocEHI(ehi); processReturn(); return; } ComObjectName libName(createRoutineNode-> getLibraryName().getQualifiedNameAsAnsiString()); libName.applyDefaults(currCatAnsiName, currSchAnsiName); NAString libCatNamePart = libName.getCatalogNamePartAsAnsiString(); NAString libSchNamePart = libName.getSchemaNamePartAsAnsiString(TRUE); NAString libObjNamePart = libName.getObjectNamePartAsAnsiString(TRUE); const NAString extLibraryName = libName.getExternalName(TRUE); char externalPath[512] ; Lng32 cliRC = 0; // this call needs to change Int64 libUID = getObjectUID(&cliInterface, libCatNamePart, libSchNamePart, libObjNamePart, COM_LIBRARY_OBJECT_LIT); if (libUID < 0) { processReturn(); return; } if (libUID == 0) // does not exist { *CmpCommon::diags() << DgSqlCode(-1361) << DgString0(extLibraryName); deallocEHI(ehi); processReturn(); return; } // read the library path name from the LIBRARIES metadata table char * buf = new(STMTHEAP) char[200]; str_sprintf(buf, "select library_filename from %s.\"%s\".%s" " where library_uid = %Ld for read uncommitted access", getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_LIBRARIES, libUID); cliRC = cliInterface.fetchRowsPrologue(buf, TRUE/*no exec*/); if (cliRC < 0) { cliInterface.retrieveSQLDiagnostics(CmpCommon::diags()); deallocEHI(ehi); processReturn(); return; } cliRC = cliInterface.clearExecFetchClose(NULL, 0); if (cliRC < 0) { cliInterface.retrieveSQLDiagnostics(CmpCommon::diags()); deallocEHI(ehi); processReturn(); return; } if (cliRC == 100) // did not find the row { *CmpCommon::diags() << DgSqlCode(-1231) << DgString0(extRoutineName); deallocEHI(ehi); processReturn(); return; } char * ptr = NULL; Lng32 len = 0; cliInterface.getPtrAndLen(1, ptr, len); str_cpy_all(externalPath, ptr, len); externalPath[len] = '\0'; // determine language and parameter styles based on the library // type, unless already specified if (!createRoutineNode->isLanguageTypeSpecified()) { NAString extPath(externalPath); size_t lastDot = extPath.last('.'); NAString libSuffix; if (lastDot != NA_NPOS) libSuffix = extPath(lastDot,extPath.length()-lastDot); libSuffix.toUpper(); if (libSuffix == ".JAR") { isJava = TRUE; language = COM_LANGUAGE_JAVA; } else if (libSuffix == ".SO" || libSuffix == ".DLL") { // a known C/C++ library, set // language and parameter style below } else { // language not specified and library name // is inconclusive, issue an error *CmpCommon::diags() << DgSqlCode( -3284 ) << DgString0( externalPath ); processReturn(); } } // set parameter style and also language, if not already // specified, based on routine type and type of library if (isJava) { // library is a jar file if (rType == COM_PROCEDURE_TYPE) // Java stored procedures use the older Java style style = COM_STYLE_JAVA_CALL; else // Java UDFs use the newer Java object style style = COM_STYLE_JAVA_OBJ; } else { // assume the library is a DLL with C or C++ code if (rType == COM_TABLE_UDF_TYPE && (language == COM_LANGUAGE_CPP || !createRoutineNode->isLanguageTypeSpecified())) { // Table UDFs (TMUDFs) default to the C++ interface language = COM_LANGUAGE_CPP; style = COM_STYLE_CPP_OBJ; } else if (rType == COM_SCALAR_UDF_TYPE && (language == COM_LANGUAGE_C || !createRoutineNode->isLanguageTypeSpecified())) { // scalar UDFs default to C and SQL parameter style language = COM_LANGUAGE_C; style = COM_STYLE_SQL; } else { // some invalid combination of routine type, language and // library type *CmpCommon::diags() << DgSqlCode(-3286); processReturn(); return; } } // C/C++ DLL if (createRoutineNode->isParamStyleSpecified() && ddlStyle != style) { // An unsupported PARAMETER STYLE was specified *CmpCommon::diags() << DgSqlCode(-3280); processReturn(); return; } NAString externalName; if (language == COM_LANGUAGE_JAVA && style == COM_STYLE_JAVA_CALL) { // the external name is a Java method signature externalName = createRoutineNode->getJavaClassName(); externalName += "." ; externalName += createRoutineNode->getJavaMethodName(); } else // the external name is a C/C++ entry point or a // Java class name externalName = createRoutineNode->getExternalName(); // Verify that current user has authority to create the routine // User must be DB__ROOT or have privileges if (isAuthorizationEnabled() && !ComUser::isRootUserID()) { // For now, go get privileges directly. If we ever cache routines, then // make sure privileges are stored in the cache. NAString privMgrMDLoc; CONCAT_CATSCH(privMgrMDLoc, getSystemCatalog(), SEABASE_PRIVMGR_SCHEMA); PrivMgrCommands privInterface(privMgrMDLoc.data(), CmpCommon::diags()); PrivMgrUserPrivs privs; PrivStatus retcode = privInterface.getPrivileges(libUID, COM_LIBRARY_OBJECT, ComUser::getCurrentUser(), privs); if (retcode != STATUS_GOOD) { if (CmpCommon::diags()->getNumber(DgSqlCode::ERROR_) == 0) SEABASEDDL_INTERNAL_ERROR("checking routine privilege"); processReturn(); return; } // Requester must have USAGE privilege on the library NABoolean hasPriv = TRUE; if ( !privs.hasUsagePriv() ) { *CmpCommon::diags() << DgSqlCode( -4481 ) << DgString0( "USAGE" ) << DgString1( extLibraryName.data()); processReturn(); return; } } ElemDDLParamDefArray &routineParamArray = createRoutineNode->getParamArray(); Lng32 numParams = routineParamArray.entries(); if ((createRoutineNode->getRoutineType() == COM_SCALAR_UDF_TYPE) && (numParams > 32)) { *CmpCommon::diags() << DgSqlCode( -1550 ) << DgString0( extRoutineName ) << DgInt0( numParams ); deallocEHI(ehi); processReturn(); return; } #define MAX_SIGNATURE_LENGTH 8193 // Allocate buffer for generated signature char sigBuf[MAX_SIGNATURE_LENGTH]; sigBuf[0] = '\0'; if (style == COM_STYLE_JAVA_CALL) { // validate routine for Java call based on signature Lng32 numJavaParam = 0; ComFSDataType *paramType = new ComFSDataType[numParams]; ComUInt32 *subType = new ComUInt32 [numParams]; ComColumnDirection *direction = new ComColumnDirection[numParams]; NAType *genericType; // Gather the param attributes for LM from the paramDefArray previously // populated and from the routineparamList generated from paramDefArray. for (CollIndex i = 0; (Int32)i < numParams; i++) { paramType[i] = (ComFSDataType)routineParamArray[i]->getParamDataType()->getFSDatatype(); subType[i] = 0; // default // Set subType for special cases detected by LM switch ( paramType[i] ) { case COM_SIGNED_BIN16_FSDT : case COM_SIGNED_BIN32_FSDT : case COM_SIGNED_BIN64_FSDT : case COM_UNSIGNED_BIN16_FSDT : case COM_UNSIGNED_BIN32_FSDT : case COM_UNSIGNED_BPINT_FSDT : { genericType = routineParamArray[i]->getParamDataType() ; if (genericType->getTypeName() == LiteralNumeric) subType[i] = genericType->getPrecision(); else subType[i] = 0 ; break; } case COM_DATETIME_FSDT : { genericType = routineParamArray[i]->getParamDataType() ; DatetimeType & datetimeType = (DatetimeType &) *genericType; if (datetimeType.getSimpleTypeName() EQU "DATE") subType[i] = 1 ; else if (datetimeType.getSimpleTypeName() EQU "TIME") subType[i] = 2; else if (datetimeType.getSimpleTypeName() EQU "TIMESTAMP") subType[i] = 3; } } // end switch paramType[i] direction[i] = (ComColumnDirection) routineParamArray[i]->getParamDirection(); } // If the syntax specified a signature, pass that to LanguageManager. NAString specifiedSig( createRoutineNode->getJavaSignature() ); char* optionalSig; if ( specifiedSig.length() == 0 ) optionalSig = NULL; else optionalSig = (char *)specifiedSig.data(); ComBoolean isJavaMain = ((str_cmp_ne(createRoutineNode->getJavaMethodName(), "main") == 0) ? TRUE : FALSE); LmResult createSigResult; LmJavaSignature *lmSignature = new (STMTHEAP) LmJavaSignature(NULL, STMTHEAP); createSigResult = lmSignature->createSig(paramType, subType, direction, numParams, COM_UNKNOWN_FSDT, 0, createRoutineNode->getMaxResults(), optionalSig, isJavaMain, sigBuf, MAX_SIGNATURE_LENGTH, CmpCommon::diags()); NADELETE(lmSignature, LmJavaSignature, STMTHEAP); delete [] paramType; delete [] subType; delete [] direction; // Lm returned error. Lm fills diags area, so no need to worry about diags. if (createSigResult == LM_ERR) { *CmpCommon::diags() << DgSqlCode(-1231) << DgString0(extRoutineName); deallocEHI(ehi); processReturn(); return; } numJavaParam = (isJavaMain ? 1 : numParams); if (validateRoutine(&cliInterface, createRoutineNode->getJavaClassName(), createRoutineNode->getJavaMethodName(), externalPath, sigBuf, numJavaParam, createRoutineNode->getMaxResults(), optionalSig)) { *CmpCommon::diags() << DgSqlCode(-1231) << DgString0(extRoutineName); deallocEHI(ehi); processReturn(); return; } } else if (style == COM_STYLE_JAVA_OBJ || style == COM_STYLE_CPP_OBJ) { // validate existence of the C++ or Java class in the library Int32 routineHandle = NullCliRoutineHandle; NAString externalPrefix(externalPath); NAString externalNameForValidation(externalName); NAString containerName; if (language == COM_LANGUAGE_C || language == COM_LANGUAGE_CPP) { // separate the actual DLL name from the prefix char separator = '/'; size_t separatorPos = externalPrefix.last(separator); if (separatorPos != NA_NPOS) { containerName = externalPrefix(separatorPos+1, externalPrefix.length()-separatorPos-1); externalPrefix.remove(separatorPos, externalPrefix.length()-separatorPos); } else { // assume the entire string is a local name containerName = externalPrefix; externalPrefix = "."; } } else { // For Java, the way the language manager works is that the // external path is the fully qualified name of the jar and // the container is the class name (external name). We load // the container (the class) by searching in the path (the // jar). The external name is the method name, which in this // case is the constructor of the class, <init>. // leave externalPrevix unchanged, fully qualified jar file containerName = externalName; externalNameForValidation = "<init>"; } // use a CLI call to validate that the library contains the routine if (cliInterface.getRoutine( NULL, // No InvocationInfo specified in this step 0, NULL, 0, (Int32) language, (Int32) style, externalNameForValidation.data(), containerName.data(), externalPrefix.data(), extLibraryName.data(), &routineHandle, CmpCommon::diags()) != LME_ROUTINE_VALIDATED) { if (routineHandle != NullCliRoutineHandle) cliInterface.putRoutine(routineHandle, CmpCommon::diags()); CMPASSERT(CmpCommon::diags()->mainSQLCODE() < 0); processReturn(); return; } cliInterface.putRoutine(routineHandle, CmpCommon::diags()); } ComTdbVirtTableColumnInfo * colInfoArray = (ComTdbVirtTableColumnInfo*) new(STMTHEAP) ComTdbVirtTableColumnInfo[numParams]; if (buildColInfoArray(&routineParamArray, colInfoArray)) { processReturn(); return; } ComTdbVirtTableTableInfo * tableInfo = new(STMTHEAP) ComTdbVirtTableTableInfo[1]; tableInfo->tableName = NULL, tableInfo->createTime = 0; tableInfo->redefTime = 0; tableInfo->objUID = 0; tableInfo->objOwnerID = objectOwnerID; tableInfo->schemaOwnerID = schemaOwnerID; tableInfo->isAudited = 1; tableInfo->validDef = 1; tableInfo->hbaseCreateOptions = NULL; tableInfo->numSaltPartns = 0; tableInfo->rowFormat = COM_UNKNOWN_FORMAT_TYPE; tableInfo->objectFlags = 0; Int64 objUID = -1; if (updateSeabaseMDTable(&cliInterface, catalogNamePart, schemaNamePart, objectNamePart, COM_USER_DEFINED_ROUTINE_OBJECT, "N", tableInfo, numParams, colInfoArray, 0, NULL, 0, NULL, objUID)) { deallocEHI(ehi); processReturn(); return; } if (objUID == -1) { deallocEHI(ehi); processReturn(); return; } NAString udrType; getRoutineTypeLit(createRoutineNode->getRoutineType(), udrType); NAString languageType; getLanguageTypeLit(language, languageType); NAString sqlAccess; getSqlAccessLit(createRoutineNode->getSqlAccess(), sqlAccess); NAString paramStyle; getParamStyleLit(style, paramStyle); NAString transactionAttributes; getTransAttributesLit(createRoutineNode->getTransactionAttributes(), transactionAttributes); NAString parallelism; getParallelismLit(createRoutineNode->getParallelism(), parallelism); NAString externalSecurity; getExternalSecurityLit(createRoutineNode->getExternalSecurity(), externalSecurity); NAString executionMode; getExecutionModeLit(createRoutineNode->getExecutionMode(), executionMode); char * query = new(STMTHEAP) char[2000+MAX_SIGNATURE_LENGTH]; str_sprintf(query, "insert into %s.\"%s\".%s values (%Ld, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', '%s', '%s', '%s', '%s', %Ld, '%s' )", getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_ROUTINES, objUID, udrType.data(), languageType.data(), createRoutineNode->isDeterministic() ? "Y" : "N" , sqlAccess.data(), createRoutineNode->isCallOnNull() ? "Y" : "N" , createRoutineNode->isIsolate() ? "Y" : "N" , paramStyle.data(), transactionAttributes.data(), createRoutineNode->getMaxResults(), createRoutineNode->getStateAreaSize(), externalName.data(), parallelism.data(), createRoutineNode->getUserVersion().data(), externalSecurity.data(), executionMode.data(), libUID, sigBuf); cliRC = cliInterface.executeImmediate(query); NADELETEBASIC(query, STMTHEAP); if (cliRC < 0) { cliInterface.retrieveSQLDiagnostics(CmpCommon::diags()); processReturn(); return; } char * query1 = new(STMTHEAP) char[1000]; str_sprintf(query1, "insert into %s.\"%s\".%s values (%Ld, %Ld)", getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_LIBRARIES_USAGE, libUID, objUID); cliRC = cliInterface.executeImmediate(query1); NADELETEBASIC(query1, STMTHEAP); if (cliRC < 0) { cliInterface.retrieveSQLDiagnostics(CmpCommon::diags()); processReturn(); return; } // hope to remove this call soon by setting the valid flag to Y sooner if (updateObjectValidDef(&cliInterface, catalogNamePart, schemaNamePart, objectNamePart, COM_USER_DEFINED_ROUTINE_OBJECT_LIT, "Y")) { deallocEHI(ehi); processReturn(); return; } processReturn(); return; }
void CmpSeabaseDDL::createSeabaseLibrary( StmtDDLCreateLibrary * createLibraryNode, NAString &currCatName, NAString &currSchName) { Lng32 retcode = 0; ComObjectName libraryName(createLibraryNode->getLibraryName()); ComAnsiNamePart currCatAnsiName(currCatName); ComAnsiNamePart currSchAnsiName(currSchName); libraryName.applyDefaults(currCatAnsiName, currSchAnsiName); const NAString catalogNamePart = libraryName.getCatalogNamePartAsAnsiString(); const NAString schemaNamePart = libraryName.getSchemaNamePartAsAnsiString(TRUE); const NAString objectNamePart = libraryName.getObjectNamePartAsAnsiString(TRUE); const NAString extLibraryName = libraryName.getExternalName(TRUE); const NAString extNameForHbase = catalogNamePart + "." + schemaNamePart + "." + objectNamePart; // Verify that the requester has MANAGE_LIBRARY privilege. if (isAuthorizationEnabled() && !ComUser::isRootUserID()) { NAString privMgrMDLoc; CONCAT_CATSCH(privMgrMDLoc, getSystemCatalog(), SEABASE_PRIVMGR_SCHEMA); PrivMgrComponentPrivileges componentPrivileges(std::string(privMgrMDLoc.data()),CmpCommon::diags()); if (!componentPrivileges.hasSQLPriv (ComUser::getCurrentUser(),SQLOperation::MANAGE_LIBRARY,true)) { *CmpCommon::diags() << DgSqlCode(-CAT_NOT_AUTHORIZED); processReturn (); return; } } // Check to see if user has the authority to create the library ExeCliInterface cliInterface(STMTHEAP, NULL, NULL, CmpCommon::context()->sqlSession()->getParentQid()); Int32 objectOwnerID = SUPER_USER; Int32 schemaOwnerID = SUPER_USER; ComSchemaClass schemaClass; retcode = verifyDDLCreateOperationAuthorized(&cliInterface, SQLOperation::CREATE_LIBRARY, catalogNamePart, schemaNamePart, schemaClass, objectOwnerID, schemaOwnerID); if (retcode != 0) { handleDDLCreateAuthorizationError(retcode,catalogNamePart,schemaNamePart); return; } ExpHbaseInterface * ehi = NULL; ehi = allocEHI(); if (ehi == NULL) { processReturn(); return; } retcode = existsInSeabaseMDTable(&cliInterface, catalogNamePart, schemaNamePart, objectNamePart, COM_LIBRARY_OBJECT, TRUE, FALSE); if (retcode < 0) { deallocEHI(ehi); processReturn(); return; } if (retcode == 1) // already exists { *CmpCommon::diags() << DgSqlCode(-1390) << DgString0(extLibraryName); deallocEHI(ehi); processReturn(); return; } NAString libFileName = createLibraryNode->getFilename() ; // strip blank spaces libFileName = libFileName.strip(NAString::both, ' '); if (validateLibraryFileExists(libFileName, FALSE)) { deallocEHI(ehi); processReturn(); return; } ComTdbVirtTableTableInfo * tableInfo = new(STMTHEAP) ComTdbVirtTableTableInfo[1]; tableInfo->tableName = NULL, tableInfo->createTime = 0; tableInfo->redefTime = 0; tableInfo->objUID = 0; tableInfo->objOwnerID = objectOwnerID; tableInfo->schemaOwnerID = schemaOwnerID; tableInfo->isAudited = 1; tableInfo->validDef = 1; tableInfo->hbaseCreateOptions = NULL; tableInfo->numSaltPartns = 0; tableInfo->rowFormat = COM_UNKNOWN_FORMAT_TYPE; tableInfo->objectFlags = 0; Int64 objUID = -1; if (updateSeabaseMDTable(&cliInterface, catalogNamePart, schemaNamePart, objectNamePart, COM_LIBRARY_OBJECT, "N", tableInfo, 0, NULL, 0, NULL, 0, NULL, objUID)) { deallocEHI(ehi); processReturn(); return; } if (objUID == -1) { deallocEHI(ehi); processReturn(); return; } char * query = new(STMTHEAP) char[1000]; str_sprintf(query, "insert into %s.\"%s\".%s values (%Ld, '%s', %d)", getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_LIBRARIES, objUID, libFileName.data(), createLibraryNode->getVersion()); Lng32 cliRC = cliInterface.executeImmediate(query); NADELETEBASIC(query, STMTHEAP); if (cliRC < 0) { cliInterface.retrieveSQLDiagnostics(CmpCommon::diags()); processReturn(); return; } // hope to remove this call soon by setting thevalid flag to Y sooner if (updateObjectValidDef(&cliInterface, catalogNamePart, schemaNamePart, objectNamePart, COM_LIBRARY_OBJECT_LIT, "Y")) { deallocEHI(ehi); processReturn(); return; } processReturn(); return; }
short CmpSeabaseDDL::validateRoutine(ExeCliInterface *cliInterface, const char * className, const char * methodName, const char * externalPath, char * signature, Int32 numSqlParam, Int32 maxResultSets, const char * optionalSig) { // // Now proceed with the internal CALL statement... // Lng32 sigLen = 0; if (signature) sigLen = str_len(signature) + 1; char * query = new(STMTHEAP) char[2000+sigLen]; str_sprintf(query, "call %s.\"%s\".%s ('%s', '%s', '%s', '%s', %d, %d, %d, ?x, ?y, ?z)", getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_VALIDATE_SPJ, className, methodName, externalPath, signature, numSqlParam, maxResultSets, optionalSig ? 1 : 0); Lng32 cliRC = cliInterface->fetchRowsPrologue(query, TRUE/*no exec*/); if (cliRC < 0) { cliInterface->retrieveSQLDiagnostics(CmpCommon::diags()); return -1; } cliRC = cliInterface->clearExecFetchClose(NULL, 0); if (cliRC < 0) { cliInterface->retrieveSQLDiagnostics(CmpCommon::diags()); return -1; } NADELETEBASIC(query, STMTHEAP); char * ptr = NULL; Lng32 len = 0; Int32 errCode = 0; cliInterface->getPtrAndLen(1, ptr, len); str_cpy_all(signature, ptr, len); signature[len] = '\0'; cliInterface->getPtrAndLen(2, ptr, len); errCode = *(Int32 *)ptr; // in code below methodName may need to be added to the signature that is printed // out in some error messages. // Check for errors returned from VALIDATEROUTINE switch (errCode) { case 0://Success - Check to see if returned signature is null if (signature[0] NEQ '\0') return 0; else return -1; break; case 11205://Class not found *CmpCommon::diags() << DgSqlCode(-errCode) << DgString0(className) << DgString1(externalPath); break; case 11206://Class definition not found *CmpCommon::diags() << DgSqlCode(-errCode) << DgString0(className); break; case 11230://Overloaded methods were found *CmpCommon::diags() << DgSqlCode(-errCode) << DgString0(methodName) << DgString1(className); break; case 11239://No compatible methods were found *CmpCommon::diags() << DgSqlCode(-errCode) << DgString0(methodName) << DgString1(className); break; case 11231://Method found but not public if(signature[0] NEQ '\0') *CmpCommon::diags() << DgSqlCode(-errCode) << DgString0(signature) << DgString1(className); break; case 11232://Method found but not static if(signature[0] NEQ '\0') *CmpCommon::diags() << DgSqlCode(-errCode) << DgString0(signature) << DgString1(className); break; case 11233://Method found but not void if(signature[0] NEQ '\0') *CmpCommon::diags() << DgSqlCode(-errCode) << DgString0(signature) << DgString1(className); break; case 11234://Method not found if(signature[0] NEQ '\0') *CmpCommon::diags() << DgSqlCode(-errCode) << DgString0(signature) << DgString1(className); break; default://Unknown error code break ; } return -1; } // CmpSeabaseDDL::validateRoutine
void CmpSeabaseDDL::createSeabaseView( StmtDDLCreateView * createViewNode, NAString &currCatName, NAString &currSchName) { Lng32 retcode = 0; Lng32 cliRC = 0; ComObjectName viewName(createViewNode->getViewName()); ComAnsiNamePart currCatAnsiName(currCatName); ComAnsiNamePart currSchAnsiName(currSchName); viewName.applyDefaults(currCatAnsiName, currSchAnsiName); const NAString catalogNamePart = viewName.getCatalogNamePartAsAnsiString(); const NAString schemaNamePart = viewName.getSchemaNamePartAsAnsiString(TRUE); const NAString objectNamePart = viewName.getObjectNamePartAsAnsiString(TRUE); const NAString extViewName = viewName.getExternalName(TRUE); const NAString extNameForHbase = catalogNamePart + "." + schemaNamePart + "." + objectNamePart; ExeCliInterface cliInterface(STMTHEAP, NULL, NULL, CmpCommon::context()->sqlSession()->getParentQid()); Int32 objectOwnerID = SUPER_USER; Int32 schemaOwnerID = SUPER_USER; ComSchemaClass schemaClass; retcode = verifyDDLCreateOperationAuthorized(&cliInterface, SQLOperation::CREATE_VIEW, catalogNamePart, schemaNamePart, schemaClass, objectOwnerID, schemaOwnerID); if (retcode != 0) { handleDDLCreateAuthorizationError(retcode,catalogNamePart,schemaNamePart); return; } ExpHbaseInterface * ehi = NULL; ehi = allocEHI(); if (ehi == NULL) { processReturn(); return; } if ((isSeabaseReservedSchema(viewName)) && (!Get_SqlParser_Flags(INTERNAL_QUERY_FROM_EXEUTIL))) { *CmpCommon::diags() << DgSqlCode(-1118) << DgTableName(extViewName); deallocEHI(ehi); return; } //if metadata views are being created and seabase is uninitialized, then this //indicates that these views are being created during 'initialize trafodion' //and this compiler contains stale version. //Reload version info. // if ((isSeabaseMD(viewName)) && (CmpCommon::context()->isUninitializedSeabase())) { CmpCommon::context()->setIsUninitializedSeabase(FALSE); CmpCommon::context()->uninitializedSeabaseErrNum() = 0; } retcode = existsInSeabaseMDTable(&cliInterface, catalogNamePart, schemaNamePart, objectNamePart, COM_UNKNOWN_OBJECT, FALSE, FALSE); if (retcode < 0) { deallocEHI(ehi); processReturn(); return; } if (retcode == 1) // already exists { if (NOT ((createViewNode->isCreateOrReplaceViewCascade())|| (createViewNode->isCreateOrReplaceView()))) { *CmpCommon::diags() << DgSqlCode(-1390) << DgString0(extViewName); deallocEHI(ehi); processReturn(); return; } } char * query = NULL; int64_t objectUID = -1; std::vector<ObjectPrivsRow> viewPrivsRows; bool replacingView = false; if ((retcode == 1) && // exists ((createViewNode->isCreateOrReplaceViewCascade())|| (createViewNode->isCreateOrReplaceView()))) { // Replace view. Drop this view and recreate it. Int32 objectOwnerID = 0; Int32 schemaOwnerID = 0; Int64 objUID = getObjectUIDandOwners(&cliInterface, catalogNamePart.data(), schemaNamePart.data(), objectNamePart.data(), COM_VIEW_OBJECT, objectOwnerID,schemaOwnerID); if (objUID < 0 || objectOwnerID == 0) { if (CmpCommon::diags()->getNumber(DgSqlCode::ERROR_) == 0) SEABASEDDL_INTERNAL_ERROR("getting object UID and owner for create or replace view"); deallocEHI(ehi); processReturn(); return; } if (isAuthorizationEnabled()) { // Verify user can perform operation if (!isDDLOperationAuthorized(SQLOperation::ALTER_VIEW,objectOwnerID,schemaOwnerID)) { *CmpCommon::diags() << DgSqlCode(-CAT_NOT_AUTHORIZED); deallocEHI(ehi); processReturn (); return; } // Initiate the privilege manager interface class NAString privMgrMDLoc; CONCAT_CATSCH(privMgrMDLoc,getSystemCatalog(),SEABASE_PRIVMGR_SCHEMA); PrivMgrCommands privInterface(std::string(privMgrMDLoc.data()), CmpCommon::diags()); PrivStatus privStatus = privInterface.getPrivRowsForObject(objUID,viewPrivsRows); if (privStatus != PrivStatus::STATUS_GOOD) { SEABASEDDL_INTERNAL_ERROR("Unable to retrieve privileges for replaced view"); deallocEHI(ehi); processReturn(); return; } } if (dropOneTableorView(cliInterface,extViewName.data(),COM_VIEW_OBJECT,false)) { deallocEHI(ehi); processReturn(); return; } replacingView = true; } // Gather the object and grantable privileges that the view creator has. // This code also verifies that the current user has the necessary // privileges to create the view. PrivMgrBitmap privilegesBitmap; PrivMgrBitmap grantableBitmap; privilegesBitmap.set(); grantableBitmap.set(); if (gatherViewPrivileges(createViewNode, &cliInterface, privilegesBitmap, grantableBitmap)) { processReturn(); deallocEHI(ehi); return; } NAString viewText(STMTHEAP); buildViewText(createViewNode, viewText); NAString newViewText(STMTHEAP); for (Lng32 i = 0; i < viewText.length(); i++) { if (viewText.data()[i] == '\'') newViewText += "''"; else newViewText += viewText.data()[i]; } ElemDDLColDefArray colDefArray(STMTHEAP); if (buildViewColInfo(createViewNode, &colDefArray)) { deallocEHI(ehi); processReturn(); return; } Lng32 numCols = colDefArray.entries(); ComTdbVirtTableColumnInfo * colInfoArray = new(STMTHEAP) ComTdbVirtTableColumnInfo[numCols]; if (buildColInfoArray(COM_VIEW_OBJECT, &colDefArray, colInfoArray, FALSE, 0, FALSE)) { deallocEHI(ehi); processReturn(); return; } Int64 objUID = -1; if (updateSeabaseMDTable(&cliInterface, catalogNamePart, schemaNamePart, objectNamePart, COM_VIEW_OBJECT, "N", NULL, numCols, colInfoArray, 0, NULL, 0, NULL, objectOwnerID, schemaOwnerID, objUID)) { deallocEHI(ehi); processReturn(); return; } if (objUID < 0) { deallocEHI(ehi); processReturn(); return; } // grant privileges for view if (isAuthorizationEnabled()) { char authName[MAX_AUTHNAME_LEN+1]; Int32 lActualLen = 0; Int16 status = ComUser::getAuthNameFromAuthID( (Int32) objectOwnerID , (char *)&authName , MAX_AUTHNAME_LEN , lActualLen ); if (status != FEOK) { *CmpCommon::diags() << DgSqlCode(-20235) << DgInt0(status) << DgInt1(objectOwnerID); deallocEHI(ehi); processReturn(); return; } // Initiate the privilege manager interface class NAString privMgrMDLoc; CONCAT_CATSCH(privMgrMDLoc, getSystemCatalog(), SEABASE_PRIVMGR_SCHEMA); PrivMgrCommands privInterface(std::string(privMgrMDLoc.data()), CmpCommon::diags()); retcode = privInterface.grantObjectPrivilege (objUID, std::string(extViewName.data()), COM_VIEW_OBJECT, objectOwnerID, std::string(authName), privilegesBitmap, grantableBitmap); if (retcode != STATUS_GOOD && retcode != STATUS_WARNING) { deallocEHI(ehi); processReturn(); return; } if (replacingView) { PrivStatus privStatus = privInterface.insertPrivRowsForObject(objUID,viewPrivsRows); if (privStatus != PrivStatus::STATUS_GOOD) { SEABASEDDL_INTERNAL_ERROR("Unable to restore privileges for replaced view"); deallocEHI(ehi); processReturn(); return; } } } query = new(STMTHEAP) char[newViewText.length() + 1000]; str_sprintf(query, "upsert into %s.\"%s\".%s values (%Ld, '%s', %d, %d, 0)", getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_VIEWS, objUID, computeCheckOption(createViewNode), (createViewNode->getIsUpdatable() ? 1 : 0), (createViewNode->getIsInsertable() ? 1 : 0)); cliRC = cliInterface.executeImmediate(query); NADELETEBASIC(query, STMTHEAP); if (cliRC < 0) { if (cliRC == -8402) // string overflow, view text does not fit into metadata table *CmpCommon::diags() << DgSqlCode(-1198); else cliInterface.retrieveSQLDiagnostics(CmpCommon::diags()); deallocEHI(ehi); processReturn(); return; } if (updateTextTable(&cliInterface, objUID, COM_VIEW_TEXT, 0, newViewText)) { deallocEHI(ehi); processReturn(); return; } if (updateViewUsage(createViewNode, objUID, &cliInterface)) { deallocEHI(ehi); processReturn(); return; } if (updateObjectValidDef(&cliInterface, catalogNamePart, schemaNamePart, objectNamePart, COM_VIEW_OBJECT_LIT, "Y")) { deallocEHI(ehi); processReturn(); return; } CorrName cn(objectNamePart, STMTHEAP, schemaNamePart, catalogNamePart); ActiveSchemaDB()->getNATableDB()->removeNATable(cn, NATableDB::REMOVE_MINE_ONLY, COM_VIEW_OBJECT); deallocEHI(ehi); processReturn(); return; }
short CmpSeabaseDDL::updateViewUsage(StmtDDLCreateView * createViewParseNode, Int64 viewUID, ExeCliInterface * cliInterface) { const ParViewUsages &vu = createViewParseNode->getViewUsages(); const ParTableUsageList &vtul = vu.getViewTableUsageList(); for (CollIndex i = 0; i < vtul.entries(); i++) { ComObjectName usedObjName(vtul[i].getQualifiedNameObj() .getQualifiedNameAsAnsiString(), vtul[i].getAnsiNameSpace()); const NAString catalogNamePart = usedObjName.getCatalogNamePartAsAnsiString(); const NAString schemaNamePart = usedObjName.getSchemaNamePartAsAnsiString(TRUE); const NAString objectNamePart = usedObjName.getObjectNamePartAsAnsiString(TRUE); const NAString extUsedObjName = usedObjName.getExternalName(TRUE); char objType[10]; Int64 usedObjUID = getObjectUID(cliInterface, catalogNamePart.data(), schemaNamePart.data(), objectNamePart.data(), NULL, NULL, objType); if (usedObjUID < 0) { return -1; } char query[1000]; str_sprintf(query, "upsert into %s.\"%s\".%s values (%Ld, %Ld, '%s', 0 )", getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_VIEWS_USAGE, viewUID, usedObjUID, objType); Lng32 cliRC = cliInterface->executeImmediate(query); if (cliRC < 0) { cliInterface->retrieveSQLDiagnostics(CmpCommon::diags()); return -1; } } // for // Views can also reference functions. Add the list of functions // referenced to the VIEWS_USAGE table. const LIST(OptUDFInfo *) & uul = createViewParseNode->getUDFList(); for (CollIndex u = 0; u < uul.entries(); u++) { char query[1000]; str_sprintf(query, "upsert into %s.\"%s\".%s values (%Ld, %Ld, '%s', 0 )", getSystemCatalog(), SEABASE_MD_SCHEMA, SEABASE_VIEWS_USAGE, viewUID, uul[u]->getUDFUID(), COM_USER_DEFINED_ROUTINE_OBJECT_LIT); Lng32 cliRC = cliInterface->executeImmediate(query); if (cliRC < 0) { cliInterface->retrieveSQLDiagnostics(CmpCommon::diags()); return -1; } } // for return 0; }
short CmpSeabaseDDL::createMetadataViews(ExeCliInterface * cliInterface) { Lng32 cliRC = 0; Lng32 retcode = 0; char queryBuf[5000]; for (Int32 i = 0; i < sizeof(allMDviewsInfo)/sizeof(MDViewInfo); i++) { const MDViewInfo &mdi = allMDviewsInfo[i]; if (! mdi.viewName) continue; for (Int32 j = 0; j < NUM_MAX_PARAMS; j++) { param_[j] = NULL; } const QString * qs = NULL; Int32 sizeOfqs = 0; qs = mdi.viewDefnQuery; sizeOfqs = mdi.sizeOfDefnArr; Int32 qryArraySize = sizeOfqs / sizeof(QString); char * gluedQuery; Lng32 gluedQuerySize; glueQueryFragments(qryArraySize, qs, gluedQuery, gluedQuerySize); if (strcmp(mdi.viewName, TRAF_TABLES_VIEW) == 0) { param_[0] = getSystemCatalog(); param_[1] = SEABASE_MD_SCHEMA; param_[2] = getSystemCatalog(); param_[3] = SEABASE_MD_SCHEMA; param_[4] = SEABASE_OBJECTS; param_[5] = getSystemCatalog(); param_[6] = SEABASE_MD_SCHEMA; param_[7] = SEABASE_TABLES; param_[8] = getSystemCatalog(); param_[9] = SEABASE_MD_SCHEMA; param_[10] = COM_BASE_TABLE_OBJECT_LIT; } else if (strcmp(mdi.viewName, TRAF_COLUMNS_VIEW) == 0) { param_[0] = getSystemCatalog(); param_[1] = SEABASE_MD_SCHEMA; param_[2] = getSystemCatalog(); param_[3] = SEABASE_MD_SCHEMA; param_[4] = SEABASE_OBJECTS; param_[5] = getSystemCatalog(); param_[6] = SEABASE_MD_SCHEMA; param_[7] = SEABASE_COLUMNS; param_[8] = getSystemCatalog(); param_[9] = SEABASE_MD_SCHEMA; param_[10] = COM_BASE_TABLE_OBJECT_LIT; } else if (strcmp(mdi.viewName, TRAF_INDEXES_VIEW) == 0) { param_[0] = getSystemCatalog(); param_[1] = SEABASE_MD_SCHEMA; param_[2] = getSystemCatalog(); param_[3] = SEABASE_MD_SCHEMA; param_[4] = SEABASE_INDEXES; param_[5] = getSystemCatalog(); param_[6] = SEABASE_MD_SCHEMA; param_[7] = SEABASE_OBJECTS; param_[8] = getSystemCatalog(); param_[9] = SEABASE_MD_SCHEMA; param_[10] = SEABASE_OBJECTS; param_[11] = getSystemCatalog(); param_[12] = SEABASE_MD_SCHEMA; } else if (strcmp(mdi.viewName, TRAF_KEYS_VIEW) == 0) { param_[0] = getSystemCatalog(); param_[1] = SEABASE_MD_SCHEMA; param_[2] = getSystemCatalog(); param_[3] = SEABASE_MD_SCHEMA; param_[4] = SEABASE_TABLE_CONSTRAINTS; param_[5] = getSystemCatalog(); param_[6] = SEABASE_MD_SCHEMA; param_[7] = SEABASE_OBJECTS; param_[8] = getSystemCatalog(); param_[9] = SEABASE_MD_SCHEMA; param_[10] = SEABASE_OBJECTS; param_[11] = getSystemCatalog(); param_[12] = SEABASE_MD_SCHEMA; param_[13] = SEABASE_KEYS; param_[14] = getSystemCatalog(); param_[15] = SEABASE_MD_SCHEMA; } else if (strcmp(mdi.viewName, TRAF_REF_CONSTRAINTS_VIEW) == 0) { param_[0] = getSystemCatalog(); param_[1] = SEABASE_MD_SCHEMA; param_[2] = getSystemCatalog(); param_[3] = SEABASE_MD_SCHEMA; param_[4] = SEABASE_REF_CONSTRAINTS; param_[5] = getSystemCatalog(); param_[6] = SEABASE_MD_SCHEMA; param_[7] = SEABASE_OBJECTS; param_[8] = getSystemCatalog(); param_[9] = SEABASE_MD_SCHEMA; param_[10] = SEABASE_OBJECTS; param_[11] = getSystemCatalog(); param_[12] = SEABASE_MD_SCHEMA; param_[13] = SEABASE_OBJECTS; param_[14] = getSystemCatalog(); param_[15] = SEABASE_MD_SCHEMA; param_[16] = SEABASE_TABLE_CONSTRAINTS; param_[17] = getSystemCatalog(); param_[18] = SEABASE_MD_SCHEMA; } else if (strcmp(mdi.viewName, TRAF_SEQUENCES_VIEW) == 0) { param_[0] = getSystemCatalog(); param_[1] = SEABASE_MD_SCHEMA; param_[2] = getSystemCatalog(); param_[3] = SEABASE_MD_SCHEMA; param_[4] = SEABASE_OBJECTS; param_[5] = getSystemCatalog(); param_[6] = SEABASE_MD_SCHEMA; param_[7] = SEABASE_SEQ_GEN; param_[8] = getSystemCatalog(); param_[9] = SEABASE_MD_SCHEMA; param_[10] = COM_SEQUENCE_GENERATOR_OBJECT_LIT; } else if (strcmp(mdi.viewName, TRAF_VIEWS_VIEW) == 0) { param_[0] = getSystemCatalog(); param_[1] = SEABASE_MD_SCHEMA; param_[2] = getSystemCatalog(); param_[3] = SEABASE_MD_SCHEMA; param_[4] = SEABASE_OBJECTS; param_[5] = getSystemCatalog(); param_[6] = SEABASE_MD_SCHEMA; param_[7] = SEABASE_VIEWS; param_[8] = getSystemCatalog(); param_[9] = SEABASE_MD_SCHEMA; param_[10] = COM_VIEW_OBJECT_LIT; } else { NADELETEBASIC(gluedQuery, STMTHEAP); continue; } str_sprintf(queryBuf, gluedQuery, param_[0], param_[1], param_[2], param_[3], param_[4], param_[5], param_[6], param_[7], param_[8], param_[9], param_[10], param_[11], param_[12], param_[13], param_[14], param_[15], param_[16], param_[17], param_[18]); NADELETEBASIC(gluedQuery, STMTHEAP); NABoolean xnWasStartedHere = FALSE; if (beginXnIfNotInProgress(cliInterface, xnWasStartedHere)) return -1; cliRC = cliInterface->executeImmediate(queryBuf); if (cliRC == -1390) // view already exists { // ignore the error. cliRC = 0; } else if (cliRC < 0) { cliInterface->retrieveSQLDiagnostics(CmpCommon::diags()); } if (endXnIfStartedHere(cliInterface, xnWasStartedHere, cliRC) < 0) return -1; } // for return 0; }