Esempio n. 1
0
// ----------------------------------------------------------------------------
// method: removeNARoutine
//
// The method is called when DDL is performed against a routine making its 
// definition incorrect.
// It has a side affect of generating query invalidation keys that are 
// propagate to all the other processes that could have the routine stored 
// in cache.
// ----------------------------------------------------------------------------
void NARoutineDB::removeNARoutine2(QualifiedName &routineName, 
                                   ComQiScope qiScope, 
                                   Int64 objUID)
{

  NAHashDictionaryIterator<NARoutineDBKey,NARoutine> iter (*this); 
  NARoutineDBKey *key = NULL;
  NARoutine *cachedNARoutine = NULL;

  NASet<Int64> objectUIDs(CmpCommon::statementHeap(), 1);

  // If there are no items in cache, skip
  if (entries() > 0)
  {
    NASet<Int64> objectUIDs(CmpCommon::statementHeap(), 1);

    // iterate over all entries and remove the ones that match the name
    iter.reset();
    iter.getNext(key,cachedNARoutine);

    while(key && cachedNARoutine)
    {
      if (cachedNARoutine->getSqlName() == routineName)
      {
        objectUIDs.insert(cachedNARoutine->getRoutineID());
        moveRoutineToDeleteList(cachedNARoutine,key);
      }
      iter.getNext(key,cachedNARoutine);
    }
  }

  // clear out the other users' caches too.
  if (qiScope == REMOVE_FROM_ALL_USERS) 
  {
    // There are some scenarios where the affected object does not have an 
    // NARoutine cache entry.  However, other processes may have this routine
    // in their caches.  Go ahead and create an invalidation key 
    if (0 == objectUIDs.entries())
        objectUIDs.insert(objUID);

    Int32 numKeys = objectUIDs.entries();
    SQL_QIKEY qiKeys[numKeys];
    for (CollIndex i = 0; i < numKeys; i++)
    {
      qiKeys[i].ddlObjectUID = objectUIDs[i];
      qiKeys[i].operation[0] = 'O';
      qiKeys[i].operation[1] = 'R';
    }
    long retcode = SQL_EXEC_SetSecInvalidKeys(numKeys, qiKeys);
  }
}
Esempio n. 2
0
// ----------------------------------------------------------------------------
// method: free_entries_with_QI_key
//
// This method is sent a list of query invalidation keys.
// It looks through the list of routines to see if any of them need to be
// removed from cache because their definitions are no longer valid.
//
// numKeys - number of existing invalidation keys
// qiKeyArray - actual keys
// ----------------------------------------------------------------------------
void NARoutineDB::free_entries_with_QI_key(Int32 numKeys, SQL_QIKEY* qiKeyArray)
{
  NAHashDictionaryIterator<NARoutineDBKey,NARoutine> iter (*this);
  NARoutineDBKey *key;
  NARoutine *routine;
  iter.getNext(key,routine);
  while(key && routine)
  {
    // See if item should be removed
    if (qiCheckForInvalidObject(numKeys, qiKeyArray,
                                routine->getRoutineID(),
                                routine->getSecKeySet()))
      moveRoutineToDeleteList(routine, key);
    iter.getNext(key,routine);
  }
}
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;
}