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::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::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; }