// ***************************************************************************** // * * // * Function: MyTable::setRow * // * * // * Sets the fields of a row. * // * * // ***************************************************************************** // * * // * Parameters: * // * * // * <cliInterface> OutputInfo & In * // * is a reference to CLI interface to the row data that was read. * // * * // * <rowOut> PrivMgrMDRow & Out * // * passes back a MyRow. * // * * // ***************************************************************************** void MyTable::setRow( OutputInfo & cliInterface, PrivMgrMDRow & rowOut) { MyRow & row = static_cast<MyRow &>(rowOut); char * ptr = NULL; int32_t length = 0; char value[500]; // column 1: CATALOG_NAME cliInterface.get(0,ptr,length); strncpy(value,ptr,length); value[length] = 0; row.catalogName_ = value; // column 2: SCHEMA_NAME cliInterface.get(1,ptr,length); strncpy(value,ptr,length); value[length] = 0; row.schemaName_ = value; // column 3: OBJECT_NAME cliInterface.get(2,ptr,length); strncpy(value,ptr,length); value[length] = 0; row.objectName_ = value; // column 4: OBJECT_TYPE cliInterface.get(3,ptr,length); strncpy(value,ptr,length); value[length] = 0; row.objectType_ = PrivMgr::ObjectLitToEnum(value); // column 5: OBJECT_UID cliInterface.get(4,ptr,length); row.objectUID_ = *(reinterpret_cast<int64_t*>(ptr)); // column 6: CREATE_TIME cliInterface.get(5,ptr,length); row.createTime_ = *(reinterpret_cast<int64_t*>(ptr)); // column 7: REDEF_TIME cliInterface.get(6,ptr,length); row.redefTime_ = *(reinterpret_cast<int64_t*>(ptr)); // column 8: VALID_DEF cliInterface.get(7,ptr,length); strncpy(value,ptr,length); value[length] = 0; row.isValid_ = (value[0] == 'Y' ? true : false); // column 9: OBJECT_OWNER cliInterface.get(8,ptr,length); row.objectOwner_ = *(reinterpret_cast<int32_t*>(ptr)); lastRowRead_ = row; }
// **************************************************************************** // 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; }
// ---------------------------------------------------------------------------- // method: authorizationEnabled // // Input: pointer to the error structure // // Returns: // PRIV_INITIALIZED means all metadata tables exist // PRIV_UNINITIALIZED means no metadata tables exist // PRIV_PARTIALLY_INITIALIZED means only part of the metadata tables exist // PRIV_INITIALIZE_UNKNOWN means unable to retrieve metadata table info // // A cli error is put into the diags area if there is an error // ---------------------------------------------------------------------------- PrivMgr::PrivMDStatus PrivMgr::authorizationEnabled( std::set<std::string> &existingObjectList) { // Will require QI to reset on INITIALIZE AUTHORIZATION [,DROP] // get the list of tables from the schema // if the catalog name ever allows an embedded '.', this code will need // to change. std::string metadataLocation = getMetadataLocation(); size_t period = metadataLocation.find("."); std::string catName = metadataLocation.substr(0, period); std::string schName = metadataLocation.substr(period+1); char buf[1000]; sprintf(buf, "get tables in schema %s.%s, no header", catName.c_str(), schName.c_str()); ExeCliInterface cliInterface(STMTHEAP, NULL, NULL, CmpCommon::context()->sqlSession()->getParentQid()); Queue * schemaQueue = NULL; // set pointer in diags area int32_t diagsMark = pDiags_->mark(); int32_t cliRC = cliInterface.fetchAllRows(schemaQueue, buf, 0, FALSE, FALSE, TRUE); if (cliRC < 0) { cliInterface.retrieveSQLDiagnostics(pDiags_); return PRIV_INITIALIZE_UNKNOWN; } if (cliRC == 100) // did not find the row { pDiags_->rewind(diagsMark); return PRIV_UNINITIALIZED; } // Not sure how this can happen but code I cloned had the check if (schemaQueue->numEntries() == 0) return PRIV_UNINITIALIZED; // Gather the returned list of tables in existingObjectList schemaQueue->position(); for (int idx = 0; idx < schemaQueue->numEntries(); idx++) { OutputInfo * row = (OutputInfo*)schemaQueue->getNext(); std::string theName = row->get(0); existingObjectList.insert(theName); } // Gather the list of expected tables in expectedObjectList std::set<string> expectedObjectList; size_t numTables = sizeof(privMgrTables)/sizeof(PrivMgrTableStruct); for (int ndx_tl = 0; ndx_tl < numTables; ndx_tl++) { const PrivMgrTableStruct &tableDefinition = privMgrTables[ndx_tl]; expectedObjectList.insert(tableDefinition.tableName); } // Compare the existing with the expected std::set<string> diffsObjectList; std::set_difference (expectedObjectList.begin(), expectedObjectList.end(), existingObjectList.begin(), existingObjectList.end(), std::inserter(diffsObjectList, diffsObjectList.end())); // If the number of existing tables match the expected, diffsObjectList // is empty -> return initialized if (diffsObjectList.empty()) return PRIV_INITIALIZED; // If the number of existing tables does not match the expected, // initialization is required -> return not initialized if (existingObjectList.size() == diffsObjectList.size()) return PRIV_UNINITIALIZED; // Otherwise, mismatch is found, return partially initialized return PRIV_PARTIALLY_INITIALIZED; }
// ***************************************************************************** // * * // * 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); }
void CmpSeabaseDDL::dropSeabaseLibrary(StmtDDLDropLibrary * dropLibraryNode, NAString &currCatName, NAString &currSchName) { Lng32 cliRC = 0; Lng32 retcode = 0; const NAString &objName = dropLibraryNode->getLibraryName(); ComObjectName libraryName(objName); 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); ExeCliInterface cliInterface(STMTHEAP, NULL, NULL, CmpCommon::context()->sqlSession()->getParentQid()); ExpHbaseInterface * ehi = allocEHI(); if (ehi == NULL) return; retcode = existsInSeabaseMDTable(&cliInterface, catalogNamePart, schemaNamePart, objectNamePart, COM_LIBRARY_OBJECT, TRUE, FALSE); if (retcode < 0) { deallocEHI(ehi); processReturn(); return; } if (retcode == 0) // does not exist { *CmpCommon::diags() << DgSqlCode(-1389) << DgString0(extLibraryName); deallocEHI(ehi); processReturn(); return; } Int32 objectOwnerID = 0; Int32 schemaOwnerID = 0; Int64 objectFlags = 0; Int64 objUID = getObjectInfo(&cliInterface, catalogNamePart.data(), schemaNamePart.data(), objectNamePart.data(), COM_LIBRARY_OBJECT, objectOwnerID,schemaOwnerID,objectFlags); if (objUID < 0 || objectOwnerID == 0 || schemaOwnerID == 0) { deallocEHI(ehi); processReturn(); return; } if (!isDDLOperationAuthorized(SQLOperation::DROP_LIBRARY, objectOwnerID, schemaOwnerID)) { *CmpCommon::diags() << DgSqlCode(-CAT_NOT_AUTHORIZED); processReturn (); return; } Queue * usingRoutinesQueue = NULL; cliRC = getUsingRoutines(&cliInterface, objUID, usingRoutinesQueue); if (cliRC < 0) { deallocEHI(ehi); processReturn(); return; } // If RESTRICT and the library is being used, return an error if (cliRC != 100 && dropLibraryNode->getDropBehavior() == COM_RESTRICT_DROP_BEHAVIOR) { *CmpCommon::diags() << DgSqlCode(-CAT_DEPENDENT_ROUTINES_EXIST); deallocEHI(ehi); processReturn(); return; } for (size_t i = 0; i < usingRoutinesQueue->numEntries(); i++) { usingRoutinesQueue->position(); OutputInfo * rou = (OutputInfo*)usingRoutinesQueue->getNext(); char * routineName = rou->get(0); ComObjectType objectType = PrivMgr::ObjectLitToEnum(rou->get(1)); if (dropSeabaseObject(ehi, routineName, currCatName, currSchName, objectType, TRUE, FALSE)) { deallocEHI(ehi); processReturn(); return; } } // can get a slight perf. gain if we pass in objUID if (dropSeabaseObject(ehi, objName, currCatName, currSchName, COM_LIBRARY_OBJECT, TRUE, FALSE)) { deallocEHI(ehi); processReturn(); return; } deallocEHI(ehi); processReturn(); return; }
void CmpSeabaseDDL::dropSeabaseRoutine(StmtDDLDropRoutine * dropRoutineNode, NAString &currCatName, NAString &currSchName) { Lng32 retcode = 0; ComObjectName routineName(dropRoutineNode->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); ExpHbaseInterface * ehi = NULL; ExeCliInterface cliInterface(STMTHEAP, NULL, NULL, CmpCommon::context()->sqlSession()->getParentQid()); 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 == 0) // does not exist { *CmpCommon::diags() << DgSqlCode(-1389) << DgString0(extRoutineName); deallocEHI(ehi); processReturn(); return; } // get objectOwner Int64 objUID = 0; Int32 objectOwnerID = 0; Int32 schemaOwnerID = 0; Int64 objectFlags = 0; // see if routine is cached BindWA bindWA(ActiveSchemaDB(), CmpCommon::context(), FALSE/*inDDL*/); NARoutineDB *pRoutineDBCache = ActiveSchemaDB()->getNARoutineDB(); QualifiedName qualRoutineName(routineName, STMTHEAP); NARoutineDBKey key(qualRoutineName, STMTHEAP); NARoutine *cachedNARoutine = pRoutineDBCache->get(&bindWA, &key); if (cachedNARoutine) { objUID = cachedNARoutine->getRoutineID(); objectOwnerID = cachedNARoutine->getObjectOwner(); schemaOwnerID = cachedNARoutine->getSchemaOwner(); } else { objUID = getObjectInfo(&cliInterface, catalogNamePart.data(), schemaNamePart.data(), objectNamePart.data(), COM_USER_DEFINED_ROUTINE_OBJECT, objectOwnerID,schemaOwnerID,objectFlags); if (objUID < 0 || objectOwnerID == 0 || schemaOwnerID == 0) { deallocEHI(ehi); processReturn(); return; } } // Verify user has privilege to drop routine if (!isDDLOperationAuthorized(SQLOperation::DROP_ROUTINE,objectOwnerID,schemaOwnerID)) { *CmpCommon::diags() << DgSqlCode(-CAT_NOT_AUTHORIZED); deallocEHI(ehi); processReturn (); return; } // Determine if this function is referenced by any other objects. Lng32 cliRC = 0; Queue * usingViewsQueue = NULL; if (dropRoutineNode->getDropBehavior() == COM_RESTRICT_DROP_BEHAVIOR) { NAString usingObjName; cliRC = getUsingObject(&cliInterface, objUID, usingObjName); if (cliRC < 0) { deallocEHI(ehi); processReturn(); return; } if (cliRC != 100) // found an object { *CmpCommon::diags() << DgSqlCode(-CAT_DEPENDENT_VIEW_EXISTS) << DgTableName(usingObjName); deallocEHI(ehi); processReturn(); return; } } else if (dropRoutineNode->getDropBehavior() == COM_CASCADE_DROP_BEHAVIOR) { cliRC = getUsingViews(&cliInterface, objUID, usingViewsQueue); if (cliRC < 0) { deallocEHI(ehi); processReturn(); return; } } if (usingViewsQueue) { usingViewsQueue->position(); for (int idx = 0; idx < usingViewsQueue->numEntries(); idx++) { OutputInfo * vi = (OutputInfo*)usingViewsQueue->getNext(); char * viewName = vi->get(0); if (dropOneTableorView(cliInterface,viewName,COM_VIEW_OBJECT,false)) { deallocEHI(ehi); processReturn(); return; } } } // Removed routine from metadata if (dropSeabaseObject(ehi, dropRoutineNode->getRoutineName(), currCatName, currSchName, COM_USER_DEFINED_ROUTINE_OBJECT, TRUE, FALSE)) { deallocEHI(ehi); processReturn(); return; } // Remove cached entries in other processes pRoutineDBCache->removeNARoutine(qualRoutineName, NARoutineDB::REMOVE_FROM_ALL_USERS, objUID); deallocEHI(ehi); processReturn(); return; }
void CmpSeabaseDDL::dropSeabaseView( StmtDDLDropView * dropViewNode, NAString &currCatName, NAString &currSchName) { Lng32 cliRC = 0; Lng32 retcode = 0; const NAString &tabName = dropViewNode->getViewName(); ComObjectName viewName(tabName); 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); ExeCliInterface cliInterface(STMTHEAP, NULL, NULL, CmpCommon::context()->sqlSession()->getParentQid()); ExpHbaseInterface * ehi = allocEHI(); if (ehi == NULL) return; if ((isSeabaseReservedSchema(viewName)) && (!Get_SqlParser_Flags(INTERNAL_QUERY_FROM_EXEUTIL))) { *CmpCommon::diags() << DgSqlCode(-1119) << DgTableName(extViewName); deallocEHI(ehi); processReturn(); return; } retcode = existsInSeabaseMDTable(&cliInterface, catalogNamePart, schemaNamePart, objectNamePart, COM_VIEW_OBJECT, TRUE, FALSE); if (retcode < 0) { deallocEHI(ehi); processReturn(); return; } if (retcode == 0) // does not exist { *CmpCommon::diags() << DgSqlCode(-1389) << DgString0(extViewName); deallocEHI(ehi); processReturn(); return; } 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 drop view"); deallocEHI(ehi); processReturn(); return; } // Verify user can perform operation if (!isDDLOperationAuthorized(SQLOperation::DROP_VIEW,objectOwnerID,schemaOwnerID)) { *CmpCommon::diags() << DgSqlCode(-CAT_NOT_AUTHORIZED); deallocEHI(ehi); processReturn (); return; } Queue * usingViewsQueue = NULL; if (dropViewNode->getDropBehavior() == COM_RESTRICT_DROP_BEHAVIOR) { NAString usingObjName; cliRC = getUsingObject(&cliInterface, objUID, usingObjName); if (cliRC < 0) { deallocEHI(ehi); processReturn(); return; } if (cliRC != 100) // found an object { *CmpCommon::diags() << DgSqlCode(-1047) << DgTableName(usingObjName); deallocEHI(ehi); processReturn(); return; } } else if (dropViewNode->getDropBehavior() == COM_CASCADE_DROP_BEHAVIOR) { cliRC = getUsingViews(&cliInterface, objUID, usingViewsQueue); if (cliRC < 0) { deallocEHI(ehi); processReturn(); return; } } // get the list of all tables referenced by the view. Save this list so // referenced tables can be removed from cache later NAList<objectRefdByMe> tablesRefdList; short status = getListOfReferencedTables(&cliInterface, objUID, tablesRefdList); if (usingViewsQueue) { usingViewsQueue->position(); for (int idx = 0; idx < usingViewsQueue->numEntries(); idx++) { OutputInfo * vi = (OutputInfo*)usingViewsQueue->getNext(); char * viewName = vi->get(0); if (dropSeabaseObject(ehi, viewName, currCatName, currSchName, COM_VIEW_OBJECT)) { deallocEHI(ehi); processReturn(); return; } } } if (dropSeabaseObject(ehi, tabName, currCatName, currSchName, COM_VIEW_OBJECT)) { deallocEHI(ehi); processReturn(); return; } // clear view definition from my cache only. CorrName cn(objectNamePart, STMTHEAP, schemaNamePart, catalogNamePart); ActiveSchemaDB()->getNATableDB()->removeNATable(cn, NATableDB::REMOVE_MINE_ONLY, COM_VIEW_OBJECT); // clear view from all other caches here. This compensates for a // scenario where the object UID is not available in removeNATable, // and the look up failed too. Solution is just to use the objectUID // here. SQL_QIKEY qiKey; qiKey.operation[0] = 'O'; qiKey.operation[1] = 'R'; qiKey.ddlObjectUID = objUID; SQL_EXEC_SetSecInvalidKeys(1, &qiKey); // Now remove referenced tables from cache. // When a query that references a view is compiled, all views are converted // to the underlying base tables. Query plans are generated to access the // tables, and the views are no longer relevant. // When dropping a view, query plans that reference the dropped view will // continue to work if the plans are cached. This code removes the // referenced tables from caches to force recompilations so dropped views // are noticed. for (CollIndex i = 0; i < tablesRefdList.entries(); i++) { CorrName cn(tablesRefdList[i].objectName, STMTHEAP, tablesRefdList[i].schemaName, tablesRefdList[i].catalogName); ActiveSchemaDB()->getNATableDB()->removeNATable(cn, NATableDB::REMOVE_FROM_ALL_USERS, COM_BASE_TABLE_OBJECT); } deallocEHI(ehi); processReturn(); return; }