Repository: incubator-trafodion
Updated Branches:
  refs/heads/master d9e8233c8 -> 47d924b9b


TRAFODION [2137] Improve metadata access time during query compilation

A change was made to return privilege information in the descriptor structure
instead of getting it when the NATable or NARoutine object is instantiated.
For tables, storing privileges in the descriptor structure allows privileges
to be saved with other table attributes in the metadata.  This improves metadata
access time during initial query compilations.

Changes:

--> At create time or when the object's DDL changes (redeftime), the compiler
    gets the list of privs for all users. If stored descriptors is enabled,
    this list is stored as part of the object definition in the TEXT table.
-->    PrivMgr returns a list of bitmaps for all users granted any priv
-->    the list of privs is transformed into a VirtTable
-->    the VirtTable is transformed into TrafDesc
-->    a packed form of the TrafDesc is stored in the TEXT table
--> When an NATable or NARoutine is instantiated, the current user's credentials
    are extracted from the TrafDesc and stored in the class thereby eliminating
    the need to perform I/O to get privs for the user.


Project: http://git-wip-us.apache.org/repos/asf/incubator-trafodion/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-trafodion/commit/c23ad355
Tree: http://git-wip-us.apache.org/repos/asf/incubator-trafodion/tree/c23ad355
Diff: http://git-wip-us.apache.org/repos/asf/incubator-trafodion/diff/c23ad355

Branch: refs/heads/master
Commit: c23ad3559622b9aed0f817db817b5caf7622911d
Parents: 0a31bbb
Author: Roberta Marton <roberta.mar...@apache.org>
Authored: Wed Aug 17 17:52:01 2016 +0000
Committer: Roberta Marton <roberta.mar...@apache.org>
Committed: Wed Aug 17 17:52:01 2016 +0000

----------------------------------------------------------------------
 core/sql/comexe/ComTdb.h                |  29 ++++
 core/sql/common/ComSecurityKey.cpp      |  54 +++++++
 core/sql/common/ComSecurityKey.h        |   8 ++
 core/sql/generator/Generator.cpp        |  95 +++++++++++-
 core/sql/generator/Generator.h          |   7 +-
 core/sql/optimizer/NARoutine.cpp        |  66 +++------
 core/sql/optimizer/NARoutine.h          |   2 +-
 core/sql/optimizer/NATable.cpp          |  93 ++++++++----
 core/sql/optimizer/NATable.h            |   5 +-
 core/sql/regress/privs2/EXPECTED143     | Bin 59506 -> 60014 bytes
 core/sql/regress/privs2/TEST129         |   2 +
 core/sql/regress/privs2/TEST143         |   6 +
 core/sql/sqlcat/TrafDDLdesc.cpp         |  50 +++++++
 core/sql/sqlcat/TrafDDLdesc.h           | 142 +++++++++++++++++-
 core/sql/sqlcomp/CmpSeabaseDDL.h        |   4 +
 core/sql/sqlcomp/CmpSeabaseDDLtable.cpp |  71 ++++++++-
 core/sql/sqlcomp/PrivMgrCommands.cpp    | 127 ++++++++++++++++
 core/sql/sqlcomp/PrivMgrCommands.h      |  14 +-
 core/sql/sqlcomp/PrivMgrDesc.h          |  49 +++++--
 core/sql/sqlcomp/PrivMgrPrivileges.cpp  | 207 ++++++++++++++++++++++++++-
 core/sql/sqlcomp/PrivMgrPrivileges.h    |  15 +-
 core/sql/sqlcomp/PrivMgrRoles.cpp       |  59 ++++++++
 core/sql/sqlcomp/PrivMgrRoles.h         |   4 +
 23 files changed, 1010 insertions(+), 99 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/c23ad355/core/sql/comexe/ComTdb.h
----------------------------------------------------------------------
diff --git a/core/sql/comexe/ComTdb.h b/core/sql/comexe/ComTdb.h
index 03a2f4b..19819f2 100644
--- a/core/sql/comexe/ComTdb.h
+++ b/core/sql/comexe/ComTdb.h
@@ -44,6 +44,8 @@
 #include "exp_expr.h"           // subclasses of TDB contain expressions
 #include "sqlcli.h"
 #include "ComSmallDefs.h"
+#include <vector>               // list of privilege descriptors
+#include "PrivMgrDesc.h"        // Privilege descriptors
 
 // -----------------------------------------------------------------------
 // Classes defined in this file
@@ -1143,6 +1145,33 @@ class ComTdbVirtTableSequenceInfo : public 
ComTdbVirtTableBase
   Int64                  redefTime;
 };
 
+
+// This class describes object and column privileges and if they are grantable 
+// (WGO) for an object. Privileges are stored as a vector of PrivMgrDesc's, one
+// per distinct grantee.  
+//
+//    PrivMgrDesc:
+//      grantee - Int32
+//      objectPrivs - PrivMgrCoreDesc 
+//      columnPrivs - list of PrivMgrCoreDesc 
+//    PrivMgrCoreDesc:
+//      bitmap of granted privileges
+//      bitmap of associated WGO (with grant option)
+//      column ordinal (number) set to -1 for object privs
+class ComTdbVirtTablePrivInfo : public ComTdbVirtTableBase
+{
+ public:
+  ComTdbVirtTablePrivInfo()
+    : ComTdbVirtTableBase()
+    {
+      init();
+    }
+
+  virtual Int32 size() { return sizeof(ComTdbVirtTablePrivInfo);}
+
+  std::vector<PrivMgrDesc>     *privmgr_desc_list;     
+};
+
 class ComTdbVirtTableLibraryInfo : public ComTdbVirtTableBase
 {
  public:

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/c23ad355/core/sql/common/ComSecurityKey.cpp
----------------------------------------------------------------------
diff --git a/core/sql/common/ComSecurityKey.cpp 
b/core/sql/common/ComSecurityKey.cpp
index bd3ce2e..fa3415c 100644
--- a/core/sql/common/ComSecurityKey.cpp
+++ b/core/sql/common/ComSecurityKey.cpp
@@ -33,6 +33,7 @@
 #include <vector>
 #include "exp_function.h"
 #include "ComDistribution.h"
+#include "ComUser.h"
 
 NABoolean qiCheckForInvalidObject (const Int32 numInvalidationKeys,
                                    const SQL_QIKEY* invalidationKeys,
@@ -73,6 +74,59 @@ NABoolean qiCheckForInvalidObject (const Int32 
numInvalidationKeys,
   return found;
 }
 
+// ****************************************************************************
+// Function that builds query invalidation keys for privileges. A separate
+// invalidation key is added for each granted DML privilege. 
+// ****************************************************************************
+bool buildSecurityKeySet(PrivMgrUserPrivs *privInfo,
+                         Int64 objectUID,
+                         ComSecurityKeySet &secKeySet)
+{
+  Int32 granteeID = ComUser::getCurrentUser();
+
+  // Build security keys for object privileges
+  for ( Int32 i = FIRST_DML_PRIV; i <= LAST_DML_PRIV; i++ )
+  {
+    if ( privInfo->hasObjectPriv((PrivType)i) )
+      {
+        ComSecurityKey key(granteeID,
+                           objectUID,
+                           PrivType(i),
+                           ComSecurityKey::OBJECT_IS_OBJECT);
+        if (!key.isValid())
+          return false;
+        secKeySet.insert(key);
+      }
+  }
+  // Build security key for column privileges
+  PrivColumnBitmap privBitmap;
+
+  // Optimizer currently does not support OBJECT_IS_COLUMN, so we "or"
+  // all column-level privileges into one priv bitmap.  We create a key for
+  // each priv type where at least one column has that priv.
+  // The security key set is a list of sets, do duplicates are handled by c++
+  for (PrivColIterator columnIterator = privInfo->getColPrivList().begin();
+       columnIterator != privInfo->getColPrivList().end(); ++columnIterator)
+    privBitmap |= columnIterator->second;
+
+  // Now create a security key on the final bitmap
+  for (Int32 j = FIRST_DML_COL_PRIV; j <= LAST_DML_COL_PRIV; j++ )
+    {
+      if (!privBitmap.test(PrivType((PrivType)j)))
+         continue;
+
+      ComSecurityKey key(granteeID,
+                         objectUID,
+                         PrivType(j),
+                         ComSecurityKey::OBJECT_IS_OBJECT);
+      if (!key.isValid())
+        return false;
+      secKeySet.insert(key);
+   }
+   return true;
+}
+
+
 // 
*****************************************************************************
 //    ComSecurityKey methods
 // 
*****************************************************************************

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/c23ad355/core/sql/common/ComSecurityKey.h
----------------------------------------------------------------------
diff --git a/core/sql/common/ComSecurityKey.h b/core/sql/common/ComSecurityKey.h
index a680d7c..ed1f78e 100644
--- a/core/sql/common/ComSecurityKey.h
+++ b/core/sql/common/ComSecurityKey.h
@@ -28,6 +28,9 @@
 #include "ComSmallDefs.h"
 #include "Collections.h"
 #include "sqlcli.h"
+#include "PrivMgrCommands.h"
+
+class PrivMgrUserPrivs;
 
 class ComSecurityKey;
 
@@ -38,6 +41,11 @@ NABoolean qiCheckForInvalidObject (const Int32 
numInvalidationKeys,
                                    const Int64 objectUID,
                                    const ComSecurityKeySet objectKeys);
 
+bool buildSecurityKeySet(PrivMgrUserPrivs *privInfo,
+                         Int64 objectUID,
+                         ComSecurityKeySet &secKeySet);
+
+
 // ****************************************************************************
 // Class:  ComSecurityKey 
 //   Represents a key describing a change that will effect query and compiler

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/c23ad355/core/sql/generator/Generator.cpp
----------------------------------------------------------------------
diff --git a/core/sql/generator/Generator.cpp b/core/sql/generator/Generator.cpp
index 9f2be03..f419c1f 100644
--- a/core/sql/generator/Generator.cpp
+++ b/core/sql/generator/Generator.cpp
@@ -1737,6 +1737,82 @@ TrafDesc * Generator::createConstrKeyColsDescs(Int32 
numKeys,
   return first_key_desc;
 }
 
+// ****************************************************************************
+// This method creates a set of trafodion descriptors (TrafDesc) based on 
+// ComTdbVirtTablePrivInfo 
+//
+// see ComTdb.h for a description of the ComTdbVirtTablePrivInfo
+// see TrafDDLdesc.h for a description of TrafDesc for the priv_desc
+// ****************************************************************************
+TrafDesc * Generator::createPrivDescs( const ComTdbVirtTablePrivInfo * 
privInfo,
+                                       Space * space)
+{
+  // When authorization is enabled, each object must have at least one grantee
+  // - the system grant to the object owner
+  std::vector<PrivMgrDesc> *privGrantees = privInfo[0].privmgr_desc_list;
+  DCMPASSERT (privGrantees.size() > 0);
+ 
+  TrafDesc * priv_desc = TrafAllocateDDLdesc(DESC_PRIV_TYPE, space);
+  TrafDesc * first_grantee_desc = NULL;
+  TrafDesc * prev_grantee_desc = NULL;
+
+  // generate a TrafPrivGranteeDesc for each grantee and
+  // attach to the privileges descriptor (priv_desc)
+  for (int i = 0; i < privGrantees->size(); i++)
+    {
+      PrivMgrDesc granteeDesc = (*privGrantees)[i];
+      TrafDesc * curr_grantee_desc = 
TrafAllocateDDLdesc(DESC_PRIV_GRANTEE_TYPE, space);
+      if (! first_grantee_desc)
+        first_grantee_desc = curr_grantee_desc;
+
+      curr_grantee_desc->privGranteeDesc()->grantee = granteeDesc.getGrantee();
+
+      // generate a TrafPrivBitmap for the object level privs and
+      // attach it to the privilege grantee descriptor (curr_grantee_desc)
+      TrafDesc * bitmap_desc = TrafAllocateDDLdesc(DESC_PRIV_BITMAP_TYPE, 
space);
+      PrivMgrCoreDesc objDesc = granteeDesc.getTablePrivs();
+      bitmap_desc->privBitmapDesc()->columnOrdinal = -1;
+      bitmap_desc->privBitmapDesc()->privBitmap = 
objDesc.getPrivBitmap().to_ulong();
+      bitmap_desc->privBitmapDesc()->privWGOBitmap = 
objDesc.getWgoBitmap().to_ulong();
+      curr_grantee_desc->privGranteeDesc()->objectBitmap = bitmap_desc;
+
+      // generate a list of TrafPrivBitmapDesc, one for each column and
+      // attach it to the TrafPrivGranteeDesc
+      std::vector<PrivMgrCoreDesc> colDescList = granteeDesc.getColumnPrivs();
+      size_t numCols = colDescList.size();
+      if (numCols > 0)
+        {
+          TrafDesc * first_col_desc = NULL;
+          TrafDesc * prev_col_desc = NULL;
+          for (int j = 0; j < numCols; j++)
+            {
+              const PrivMgrCoreDesc colBitmap = colDescList[j];
+              TrafDesc * curr_col_desc = 
TrafAllocateDDLdesc(DESC_PRIV_BITMAP_TYPE, space);
+              if (! first_col_desc)
+                first_col_desc = curr_col_desc;
+
+              curr_col_desc->privBitmapDesc()->columnOrdinal = 
colBitmap.getColumnOrdinal();
+              curr_col_desc->privBitmapDesc()->privBitmap = 
colBitmap.getPrivBitmap().to_ulong();
+              curr_col_desc->privBitmapDesc()->privWGOBitmap = 
colBitmap.getWgoBitmap().to_ulong();
+
+              if (prev_col_desc)
+                prev_col_desc->next = curr_col_desc;
+              prev_col_desc = curr_col_desc;
+            }
+          curr_grantee_desc->privGranteeDesc()->columnBitmaps = first_col_desc;
+        }
+      else
+        curr_grantee_desc->privGranteeDesc()->columnBitmaps = NULL;
+
+      if (prev_grantee_desc)
+         prev_grantee_desc->next = curr_grantee_desc;
+      prev_grantee_desc = curr_grantee_desc;
+    }
+    priv_desc->privDesc()->privGrantees = first_grantee_desc;
+    return priv_desc;
+}
+
+
 // this method is used to create both referencing and referenced constraint 
structs.
 TrafDesc * Generator::createRefConstrDescStructs(
                                                    Int32 numConstrs,
@@ -1881,7 +1957,8 @@ TrafDesc * Generator::createVirtualTableDesc
      char * snapshotName,
      NABoolean genPackedDesc,
      Int32 * packedDescLen,
-     NABoolean isUserTable
+     NABoolean isUserTable,
+     ComTdbVirtTablePrivInfo * privInfo
  )
 {
   // If genPackedDesc is set, then use Space class to allocate descriptors and
@@ -2187,6 +2264,13 @@ TrafDesc * Generator::createVirtualTableDesc
       seq_desc->sequenceGeneratorDesc()->redefTime = seqInfo->redefTime;
     }
 
+
+  // Setup the privilege descriptors for objects including views, tables, 
+  // libraries, udrs, sequences, and constraints.
+  TrafDesc * priv_desc = NULL;
+  if (privInfo)
+      priv_desc = createPrivDescs(privInfo, space);
+
   // cannot simply point to same files desc as the table one,
   // because then ReadTableDef::deleteTree frees same memory twice (error)
   TrafDesc * i_files_desc = TrafAllocateDDLdesc(DESC_FILES_TYPE, space);
@@ -2200,6 +2284,7 @@ TrafDesc * Generator::createVirtualTableDesc
   table_desc->tableDesc()->constrnts_desc = first_constr_desc;
   table_desc->tableDesc()->constr_count = numConstrs; 
   table_desc->tableDesc()->sequence_generator_desc = seq_desc;
+  table_desc->tableDesc()->priv_desc = priv_desc;
 
   if (endKeyArray)
     {
@@ -2263,6 +2348,7 @@ TrafDesc *Generator::createVirtualRoutineDesc(
      ComTdbVirtTableRoutineInfo *routineInfo,
      Int32 numParams,
      ComTdbVirtTableColumnInfo *paramsArray,
+     ComTdbVirtTablePrivInfo *privInfo,
      Space * space)
 {
   TrafDesc *routine_desc = TrafAllocateDDLdesc(DESC_ROUTINE_TYPE, space);
@@ -2310,6 +2396,13 @@ TrafDesc *Generator::createVirtualRoutineDesc(
                                        space);
    routine_desc->routineDesc()->owner = routineInfo->object_owner_id;
    routine_desc->routineDesc()->schemaOwner = routineInfo->schema_owner_id; 
+
+  // Setup the privilege descriptors for routines.
+  TrafDesc * priv_desc = NULL;
+  if (privInfo)
+      priv_desc = createPrivDescs(privInfo, space);
+  routine_desc->routineDesc()->priv_desc = priv_desc;
+
    return routine_desc;
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/c23ad355/core/sql/generator/Generator.h
----------------------------------------------------------------------
diff --git a/core/sql/generator/Generator.h b/core/sql/generator/Generator.h
index c3093a3..22c465b 100644
--- a/core/sql/generator/Generator.h
+++ b/core/sql/generator/Generator.h
@@ -1390,6 +1390,9 @@ public:
                                                  ComTdbVirtTableRefConstraints 
* refConstrs,
                                                   Space * space);
   
+  static TrafDesc * createPrivDescs( const ComTdbVirtTablePrivInfo * privs,
+                                     Space * space);
+
   static TrafDesc *createVirtualTableDesc(
        const char * tableName, 
        Int32 numCols,
@@ -1408,7 +1411,8 @@ public:
        char * snapshotName = NULL,
        NABoolean genPackedDesc = FALSE,
        Int32 * packedDescLen = NULL,
-       NABoolean isUserTable = FALSE);
+       NABoolean isUserTable = FALSE,
+       ComTdbVirtTablePrivInfo * privInfo = NULL);
 
   static TrafDesc* assembleDescs(
      NAArray<HbaseStr >* keyArray, 
@@ -1420,6 +1424,7 @@ public:
                                   ComTdbVirtTableRoutineInfo *routineInfo,
                                   Int32 numParams,
                                   ComTdbVirtTableColumnInfo *paramsArray,
+                                  ComTdbVirtTablePrivInfo *privInfo,
                                   Space * space);
   static TrafDesc *createVirtualLibraryDesc(
                                   const char *libraryName,

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/c23ad355/core/sql/optimizer/NARoutine.cpp
----------------------------------------------------------------------
diff --git a/core/sql/optimizer/NARoutine.cpp b/core/sql/optimizer/NARoutine.cpp
index e3d8571..e46f6b7 100644
--- a/core/sql/optimizer/NARoutine.cpp
+++ b/core/sql/optimizer/NARoutine.cpp
@@ -604,7 +604,7 @@ NARoutine::NARoutine(const QualifiedName   &name,
     }
     
      
-  setupPrivInfo();
+  getPrivileges(routine_desc->routineDesc()->priv_desc);
 
   heapSize_ = (heap ? heap->getTotalSize() : 0);
 }
@@ -642,64 +642,38 @@ void NARoutine::setSasFormatWidth(NAString &width)
 }
 
 // ----------------------------------------------------------------------------
-// method: setupPrivInfo
+// method: getPrivileges
 //
-// If authorization is enabled, go retrieve privilege information
-// and set up query invalidation (security) keys for the table.
+// If authorization is enabled, set privs based on the passed in priv_desc
+// and set up query invalidation (security) keys for the routine.
 // ----------------------------------------------------------------------------
-void NARoutine::setupPrivInfo(void)
+void NARoutine::getPrivileges(TrafDesc *priv_desc)
 {
-  privInfo_ = new(heap_) PrivMgrUserPrivs;
   if ( !CmpCommon::context()->isAuthorizationEnabled() || 
ComUser::isRootUserID())
   {
+    privInfo_ = new(heap_) PrivMgrUserPrivs;
     privInfo_->setOwnerDefaultPrivs();
     return;
   }
 
-  NAString privMDLoc;
-  
CONCAT_CATSCH(privMDLoc,CmpSeabaseDDL::getSystemCatalogStatic(),SEABASE_PRIVMGR_SCHEMA);
-  PrivMgrCommands privInterface(privMDLoc.data(), 
CmpCommon::diags(),PrivMgr::PRIV_INITIALIZED);
-
-
-  // use embedded compiler.
-  CmpSeabaseDDL cmpSBD(STMTHEAP);
-  if (cmpSBD.switchCompiler(CmpContextInfo::CMPCONTEXT_TYPE_META))
-  {
-    if (CmpCommon::diags()->getNumber(DgSqlCode::ERROR_) == 0)
-      *CmpCommon::diags() << DgSqlCode( -4400 );
-
-    return;
-  }
-
-  // gather privileges
-  std::vector <ComSecurityKey *> secKeyVec;
-  ComObjectType objectType = (UDRType_ == COM_PROCEDURE_TYPE ? 
-                              COM_STORED_PROCEDURE_OBJECT : 
-                              COM_USER_DEFINED_ROUTINE_OBJECT);
-  if (STATUS_GOOD != privInterface.getPrivileges(objectUID_, objectType,
-                                                 ComUser::getCurrentUser(),
-                                                 *privInfo_, &secKeyVec))
+  if (priv_desc == NULL)
   {
-    NADELETE(privInfo_, PrivMgrUserPrivs, heap_);
-    privInfo_ = NULL;
+    *CmpCommon::diags() << DgSqlCode(-1034);
+     return;
   }
 
-  cmpSBD.switchBackCompiler();
-
-  // generate list of query invalidation (security) keys for the
-  // routine and current user
-  // getPrivileges allocates space, this routine should delete it
-  //   (should a heap pointer to set up for this?)
-  for (std::vector<ComSecurityKey*>::iterator iter = secKeyVec.begin();
-       iter != secKeyVec.end();
-       iter++)
-  {
-    // Insertion of the dereferenced pointer results in NASet making
-    // a copy of the object, and then we delete the original.
-    routineSecKeySet_.insert(**iter);
-    delete *iter;
-  }
+  // create privInfo_ from priv_desc
+  privInfo_ = new(heap_) PrivMgrUserPrivs(priv_desc, 
ComUser::getCurrentUser());
 
+  // buildSecurityKeySet uses privInfo_ member to set up the security keys
+  bool rslt = buildSecurityKeySet(privInfo_, objectUID_, routineSecKeySet_);
+  if (!rslt)
+    {
+      NADELETE(privInfo_, PrivMgrUserPrivs, heap_);
+      privInfo_ = NULL;
+      *CmpCommon::diags() << DgSqlCode( -4400 );
+      return;
+    }
 }
 
 ULng32 NARoutineDBKey::hash() const

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/c23ad355/core/sql/optimizer/NARoutine.h
----------------------------------------------------------------------
diff --git a/core/sql/optimizer/NARoutine.h b/core/sql/optimizer/NARoutine.h
index 395955c..6dce421 100644
--- a/core/sql/optimizer/NARoutine.h
+++ b/core/sql/optimizer/NARoutine.h
@@ -206,7 +206,7 @@ public:
   inline NABoolean hasResultSets()        const { return (maxResults_ > 0); }
 
 
-  void setupPrivInfo();
+  void getPrivileges(TrafDesc * priv_desc);
 
   // -------------------------------------------------------------------
   // Standard operators

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/c23ad355/core/sql/optimizer/NATable.cpp
----------------------------------------------------------------------
diff --git a/core/sql/optimizer/NATable.cpp b/core/sql/optimizer/NATable.cpp
index fb3b61c..d8d4b2e 100644
--- a/core/sql/optimizer/NATable.cpp
+++ b/core/sql/optimizer/NATable.cpp
@@ -5293,7 +5293,7 @@ NABoolean createNAFileSets(TrafDesc * table_desc       
/*IN*/,
   // Set up privs
   if ((corrName.getSpecialType() == ExtendedQualName::SG_TABLE) ||
       (!(corrName.isSeabaseMD() || corrName.isSpecialTable())))
-     setupPrivInfo();
+     getPrivileges(table_desc->tableDesc()->priv_desc);
 
   if ((table_desc->tableDesc()->objectFlags & SEABASE_OBJECT_IS_EXTERNAL_HIVE) 
!= 0 ||
       (table_desc->tableDesc()->objectFlags & 
SEABASE_OBJECT_IS_EXTERNAL_HBASE) != 0)
@@ -5939,7 +5939,7 @@ NATable::NATable(BindWA *bindWA,
   }
 
   if (hasExternalTable())
-    setupPrivInfo();
+    getPrivileges(NULL); 
 
   // TBD - if authorization is enabled and there is no external table to store
   // privileges, go get privilege information from HIVE metadata ...
@@ -6028,9 +6028,6 @@ NATable::NATable(BindWA *bindWA,
   if( hiveDefaultStringLenInBytes != 32000 ) 
       hiveDefaultStringLen_ = hiveDefaultStringLenInBytes;
 
-  if (!(corrName.isSeabaseMD() || corrName.isSpecialTable()))
-    setupPrivInfo();
-
 // LCOV_EXCL_STOP
   initialSize_ = heap_->getAllocSize();
   MonitorMemoryUsage_Exit((char*)mmPhase.data(), heap_, NULL, TRUE);
@@ -6880,24 +6877,13 @@ NABoolean 
NATable::getCorrespondingConstraint(NAList<NAString> &inputCols,
   return constrFound;
 }
 
-void NATable::setupPrivInfo()
+// Extracts privilege bitmaps from the priv_desc for the current user
+void NATable::getPrivileges(TrafDesc * priv_desc)
 {
-  Int32 thisUserID = ComUser::getCurrentUser();
-  NAString privMDLoc = CmpSeabaseDDL::getSystemCatalogStatic();
-  privMDLoc += ".\"";
-  privMDLoc += SEABASE_PRIVMGR_SCHEMA;
-  privMDLoc += "\"";
-
-  PrivMgrCommands privInterface(privMDLoc.data(), 
CmpCommon::diags(),PrivMgr::PRIV_INITIALIZED);
-
-  if (privInterface.isPrivMgrTable(
-    qualifiedName_.getQualifiedNameObj().getQualifiedNameAsString().data()))
-    {
-      isSeabasePrivSchemaTable_ = TRUE;
-      return;
-    }
-
-  privInfo_ = new(heap_) PrivMgrUserPrivs;
+  if (CmpSeabaseDDL::isSeabasePrivMgrMD
+       (qualifiedName_.getQualifiedNameObj().getCatalogName(),
+        qualifiedName_.getQualifiedNameObj().getSchemaName()))
+    isSeabasePrivSchemaTable_ = TRUE;
 
   if ((!isSeabaseTable() && !isHiveTable()) ||
       !CmpCommon::context()->isAuthorizationEnabled() ||
@@ -6905,11 +6891,53 @@ void NATable::setupPrivInfo()
       ComUser::isRootUserID()||
       ComUser::getCurrentUser() == owner_)
     {
+      privInfo_ = new(heap_) PrivMgrUserPrivs;
       privInfo_->setOwnerDefaultPrivs();
       return;
     }
+  
+  // priv_desc could be NULL if NATable is being created for an MD or hive
+  // table. 
+  // For hive tables, go ahead and read the privilege manager metadata to 
+  // extract privs
+  // Much of the time, MD is read by the compiler/DDL on behalf of the user so 
+  // privilege checks are skipped.  Instead of performing the I/O to get 
+  // privilege information at this time, set privInfo_ to NULL and rely on 
+  // RelRoot::checkPrivileges to look up privileges. checkPrivileges is 
+  // optimized to lookup privileges only when needed.
+  if (priv_desc == NULL)
+    {
+      if (isHiveTable())
+        readPrivileges();
+      else
+        privInfo_ = NULL;
+      return;
+    }
+  else
+    privInfo_ = new(heap_) PrivMgrUserPrivs(priv_desc, 
ComUser::getCurrentUser());
 
-  std::vector <ComSecurityKey *> secKeyVec;
+  if (privInfo_ == NULL)
+    {
+      *CmpCommon::diags() << DgSqlCode(-1034);
+      return;
+    }
+      
+  // buildSecurityKeySet uses privInfo_ member to set up the security keys
+  bool rslt = buildSecurityKeySet(privInfo_, objectUid().get_value(), 
secKeySet_);
+  if (!rslt)
+    {
+      NADELETE(privInfo_, PrivMgrUserPrivs, heap_);
+      privInfo_ = NULL;
+      *CmpCommon::diags() << DgSqlCode( -4400 );
+      return;
+    }
+}
+
+// Call privilege manager to get privileges and security keys
+// update privInfo_ and secKeySet_ members with values 
+void NATable::readPrivileges ()
+{
+  privInfo_ = new(heap_) PrivMgrUserPrivs;
 
   bool testError = false;
 #ifndef NDEBUG
@@ -6927,9 +6955,18 @@ void NATable::setupPrivInfo()
 
       return;
     }
+
+  NAString privMDLoc = CmpSeabaseDDL::getSystemCatalogStatic();
+  privMDLoc += ".\"";
+  privMDLoc += SEABASE_PRIVMGR_SCHEMA;
+  privMDLoc += "\"";
+
+  PrivMgrCommands privInterface(privMDLoc.data(), 
CmpCommon::diags(),PrivMgr::PRIV_INITIALIZED);
+  std::vector <ComSecurityKey *> secKeyVec;
+
   if (testError || (STATUS_GOOD !=
        privInterface.getPrivileges(objectUid().get_value(), objectType_,
-                                   thisUserID, *privInfo_, &secKeyVec)))
+                                   ComUser::getCurrentUser(), *privInfo_, 
&secKeyVec)))
   {
     if (testError)
 #ifndef NDEBUG
@@ -6941,8 +6978,8 @@ void NATable::setupPrivInfo()
     NADELETE(privInfo_, PrivMgrUserPrivs, heap_);
     privInfo_ = NULL;
 
-  cmpSBD.switchBackCompiler();
-  return;
+    cmpSBD.switchBackCompiler();
+    return;
   }
 
   CMPASSERT (privInfo_);
@@ -7015,6 +7052,7 @@ NATable::~NATable()
     NADELETE(privInfo_, PrivMgrUserPrivs, heap_);
     privInfo_ = NULL;
   }
+
   if (! isHive_) {
      for (int i = 0 ; i < colcount_ ; i++) {
          col = (NAColumn *)colArray_[i];
@@ -7031,6 +7069,9 @@ NATable::~NATable()
      }
      colArray_.clear();
   }
+  
+
+
   if (parentTableName_ != NULL)
   {
      NADELETEBASIC(parentTableName_, heap_);

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/c23ad355/core/sql/optimizer/NATable.h
----------------------------------------------------------------------
diff --git a/core/sql/optimizer/NATable.h b/core/sql/optimizer/NATable.h
index e9dcb51..56556eb 100644
--- a/core/sql/optimizer/NATable.h
+++ b/core/sql/optimizer/NATable.h
@@ -55,6 +55,7 @@ class NATable;
 class NATableDB;
 class HistogramCache;
 class HistogramsCacheEntry;
+
 // -----------------------------------------------------------------------
 // forward references
 // -----------------------------------------------------------------------
@@ -896,7 +897,9 @@ private:
   NATable (const NATable & orig, NAMemory * h=0) ; //not written
 
   void setRecordLength(Int32 recordLength) { recordLength_ = recordLength; }
-  void setupPrivInfo();
+
+  void getPrivileges(TrafDesc * priv_desc);
+  void readPrivileges();
 
   ExpHbaseInterface* getHBaseInterface() const;
   static ExpHbaseInterface* getHBaseInterfaceRaw();

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/c23ad355/core/sql/regress/privs2/EXPECTED143
----------------------------------------------------------------------
diff --git a/core/sql/regress/privs2/EXPECTED143 
b/core/sql/regress/privs2/EXPECTED143
index 141d734..3d22185 100644
Binary files a/core/sql/regress/privs2/EXPECTED143 and 
b/core/sql/regress/privs2/EXPECTED143 differ

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/c23ad355/core/sql/regress/privs2/TEST129
----------------------------------------------------------------------
diff --git a/core/sql/regress/privs2/TEST129 b/core/sql/regress/privs2/TEST129
index 0c28f6e..1cea5c2 100755
--- a/core/sql/regress/privs2/TEST129
+++ b/core/sql/regress/privs2/TEST129
@@ -35,6 +35,8 @@ sh sqlci -i "TEST129(step6)" -u sql_user4;
 sh sqlci -i "TEST129(step7)" -u sql_user4;
 sh sqlci -i "TEST129(invalidate)" -u sql_user1;
 
+obey TEST129(clean_up);
+
 exit;
 
 ?section clean_up

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/c23ad355/core/sql/regress/privs2/TEST143
----------------------------------------------------------------------
diff --git a/core/sql/regress/privs2/TEST143 b/core/sql/regress/privs2/TEST143
index 98a6005..ca36922 100755
--- a/core/sql/regress/privs2/TEST143
+++ b/core/sql/regress/privs2/TEST143
@@ -28,6 +28,8 @@
 -- ============================================================================
 
 cqd SHOWDDL_DISPLAY_PRIVILEGE_GRANTS 'ON';
+cqd traf_store_object_desc 'ON';
+cqd traf_read_object_desc 'ON';
 obey TEST143(clean_up);
 log LOG143 clear ;
 obey TEST143(set_up);
@@ -419,6 +421,8 @@ execute get_col_privs;
 -- executed by sql_user2
 log LOG143;
 cqd SHOWDDL_DISPLAY_PRIVILEGE_GRANTS 'ON';
+cqd traf_store_object_desc 'ON';
+cqd traf_read_object_desc 'ON';
 values (user);
 set schema t143_user2;
 
@@ -431,6 +435,8 @@ create view u2v2 as select * from t143_user1.u1t2;
 -- executed by sql_user3
 log LOG143;
 cqd SHOWDDL_DISPLAY_PRIVILEGE_GRANTS 'ON';
+cqd traf_store_object_desc 'ON';
+cqd traf_read_object_desc 'ON';
 values (user);
 set schema t143_user3;
 

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/c23ad355/core/sql/sqlcat/TrafDDLdesc.cpp
----------------------------------------------------------------------
diff --git a/core/sql/sqlcat/TrafDDLdesc.cpp b/core/sql/sqlcat/TrafDDLdesc.cpp
index b6be69a..a3ad81f 100644
--- a/core/sql/sqlcat/TrafDDLdesc.cpp
+++ b/core/sql/sqlcat/TrafDDLdesc.cpp
@@ -90,6 +90,15 @@ TrafDesc *TrafAllocateDDLdesc(desc_nodetype nodetype, Space 
* space)
     case DESC_USING_MV_TYPE: 
       desc_ptr = new GENHEAP(space) TrafUsingMvDesc();
       break;
+    case DESC_PRIV_TYPE: 
+      desc_ptr = new GENHEAP(space) TrafPrivDesc();
+      break;
+    case DESC_PRIV_GRANTEE_TYPE: 
+      desc_ptr = new GENHEAP(space) TrafPrivGranteeDesc();
+      break;
+    case DESC_PRIV_BITMAP_TYPE: 
+      desc_ptr = new GENHEAP(space) TrafPrivBitmapDesc();
+      break;
     default:
       assert(FALSE);
       break;
@@ -211,6 +220,15 @@ char *TrafDesc::findVTblPtr(short classID)
     case DESC_USING_MV_TYPE: 
       GetVTblPtr(vtblptr, TrafUsingMvDesc);
       break;
+    case DESC_PRIV_TYPE: 
+      GetVTblPtr(vtblptr, TrafPrivDesc);
+      break;
+    case DESC_PRIV_GRANTEE_TYPE: 
+      GetVTblPtr(vtblptr, TrafPrivGranteeDesc);
+      break;
+    case DESC_PRIV_BITMAP_TYPE: 
+      GetVTblPtr(vtblptr, TrafPrivBitmapDesc);
+      break;
     default:
       assert(FALSE);
       break;
@@ -556,6 +574,7 @@ Long TrafTableDesc::pack(void * space)
   files_desc.pack(space);
   hbase_regionkey_desc.pack(space);
   sequence_generator_desc.pack(space);
+  priv_desc.pack(space);
 
   return TrafDesc::pack(space);  
 }
@@ -578,6 +597,7 @@ Lng32 TrafTableDesc::unpack(void * base, void * reallocator)
   if (files_desc.unpack(base, reallocator)) return -1;
   if (hbase_regionkey_desc.unpack(base, reallocator)) return -1;
   if (sequence_generator_desc.unpack(base, reallocator)) return -1;
+  if (priv_desc.unpack(base, reallocator)) return -1;
 
   return TrafDesc::unpack(base, reallocator);
 }
@@ -619,3 +639,33 @@ Lng32 TrafViewDesc::unpack(void * base, void * reallocator)
 
   return TrafDesc::unpack(base, reallocator);
 }
+ 
+Long TrafPrivDesc::pack (void * space)
+{
+   privGrantees.pack(space);
+
+   return TrafDesc::pack(space);
+}
+ 
+Lng32 TrafPrivDesc::unpack(void * base, void * reallocator)
+{
+  if (privGrantees.unpack(base, reallocator)) return -1;
+  return TrafDesc::unpack(base, reallocator);
+}
+
+Long TrafPrivGranteeDesc::pack(void * space)
+{
+  objectBitmap.pack(space);
+  columnBitmaps.pack(space);
+
+  return TrafDesc::pack(space);
+}
+
+Lng32 TrafPrivGranteeDesc::unpack(void * base, void *reallocator)
+{
+  if (objectBitmap.unpack(base, reallocator)) return -1;
+  if (columnBitmaps.unpack(base, reallocator)) return -1;
+
+  return TrafDesc::unpack(base, reallocator);
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/c23ad355/core/sql/sqlcat/TrafDDLdesc.h
----------------------------------------------------------------------
diff --git a/core/sql/sqlcat/TrafDDLdesc.h b/core/sql/sqlcat/TrafDDLdesc.h
index f6fa7da..d9bee94 100644
--- a/core/sql/sqlcat/TrafDDLdesc.h
+++ b/core/sql/sqlcat/TrafDDLdesc.h
@@ -24,6 +24,19 @@
 #ifndef TRAF_DDL_DESC_H
 #define TRAF_DDL_DESC_H
 
+// ****************************************************************************
+// This file contains DDLDesc classes. DDLDesc classes are used to store
+// object definitions that are read from system and privilege manager metadata.
+// The DDLDesc's are referenced by other classes such as NATable and SHOWDDL 
+// that save and display metadata contents.  
+//
+// When DDL operations are performed, the associated DDLDesc structure is 
+// flatten out and stored in the text table related to object.  When the
+// compiler or DDL subsequently require this information, the flattened 
DDLDesc 
+// is read from the metadata and expanded. This information can then be used 
+// by the the different components - such as NATable. 
+// ****************************************************************************
+
 #include "Platform.h"
 #include "NAVersionedObject.h"
 #include "charinfo.h"
@@ -55,7 +68,10 @@ enum desc_nodetype {
   DESC_SCHEMA_LABEL_TYPE,
   DESC_SEQUENCE_GENERATOR_TYPE,
   DESC_ROUTINE_TYPE,
-  DESC_LIBRARY_TYPE
+  DESC_LIBRARY_TYPE,
+  DESC_PRIV_TYPE,
+  DESC_PRIV_GRANTEE_TYPE,
+  DESC_PRIV_BITMAP_TYPE
 };
 
 class TrafDesc;
@@ -79,6 +95,9 @@ class TrafSequenceGeneratorDesc;
 class TrafTableDesc;
 class TrafUsingMvDesc;
 class TrafViewDesc;
+class TrafPrivDesc;
+class TrafPrivGranteeDesc;
+class TrafPrivBitmapDesc;
 
 class TrafDesc : public NAVersionedObject {
 public:
@@ -136,6 +155,9 @@ public:
   virtual TrafTableDesc *tableDesc() const { return NULL; }
   virtual TrafUsingMvDesc *usingMvDesc() const { return NULL; }
   virtual TrafViewDesc *viewDesc() const { return NULL; }
+  virtual TrafPrivDesc *privDesc() const { return NULL; }
+  virtual TrafPrivGranteeDesc *privGranteeDesc() const { return NULL; }
+  virtual TrafPrivBitmapDesc *privBitmapDesc() const { return NULL; }
 
 };
 
@@ -820,6 +842,7 @@ public:
   ComRoutineParallelism parallelism;
   Int32 owner;
   Int32 schemaOwner;
+  DescStructPtr priv_desc;
 
   Int64 routineDescFlags; // my flags
 
@@ -1008,6 +1031,7 @@ public:
   DescStructPtr referencing_tables_desc;
   DescStructPtr histograms_desc;
   DescStructPtr files_desc;
+  DescStructPtr priv_desc;
 
   // for hbase's region keys
   DescStructPtr hbase_regionkey_desc;
@@ -1072,23 +1096,23 @@ public:
   }
 
   virtual short getClassSize()      { return (short)sizeof(TrafViewDesc); }
- 
+
   virtual Long pack(void *space);
   virtual Lng32 unpack(void * base, void * reallocator);
 
   virtual TrafViewDesc *viewDesc() const { return (TrafViewDesc*)this; }
 
   enum ViewDescFlags
-    { 
+    {
       UPDATABLE           = 0x0001,
       INSERTABLE          = 0x0002
     };
 
-  void setUpdatable(NABoolean v) 
+  void setUpdatable(NABoolean v)
   {(v ? viewDescFlags |= UPDATABLE : viewDescFlags &= ~UPDATABLE); };
   NABoolean isUpdatable() { return (viewDescFlags & UPDATABLE) != 0; };
 
-  void setInsertable(NABoolean v) 
+  void setInsertable(NABoolean v)
   {(v ? viewDescFlags |= INSERTABLE : viewDescFlags &= ~INSERTABLE); };
   NABoolean isInsertable() { return (viewDescFlags & INSERTABLE) != 0; };
 
@@ -1105,6 +1129,114 @@ public:
   char filler[22];
 };
 
+// --------------------------- privilege descriptors 
---------------------------
+// The privilege descriptors are organized as follows:
+//   privDesc - a TrafPrivDesc containing the privGrantees
+//   privGrantees - a TrafPrivGranteeDesc descriptor containing:
+//     grantee - int32 value for each user granted a privilege directly or
+//               through a role granted to the user
+//     objectBitmap  - a TrafPrivBitmapDesc containing granted object privs
+//                     summarized across all grantors
+//     columnBitmaps - list of TrafPrivBitmapDesc, one per colummn, containing 
+//                     granted column privs, summarized across all grantors
+//   priv_bits desc - a TrafPrivBitmapDesc descriptor containing:
+//     privBitmap - bitmap containing granted privs such as SELECT
+//     privWGO - bitmap containing WGO for associated grant (privBitmap)
+//     columnOrdinal - column number for bitmap, for objects, column
+//                     number is not relavent so it is set to -1.
+//   column bits - list of TrafPrivBitmapDesc
+class TrafPrivDesc : public TrafDesc {
+public:
+  TrafPrivDesc() : TrafDesc(DESC_PRIV_TYPE)
+  {}
+
+  // ---------------------------------------------------------------------
+  // Redefine virtual functions required for Versioning.
+  //----------------------------------------------------------------------
+  virtual unsigned char getClassVersionID()
+  {
+    return 1;
+  }
+
+  virtual void populateImageVersionIDArray()
+  {
+    setImageVersionID(0,getClassVersionID());
+  }
+
+  virtual short getClassSize()      { return (short)sizeof(TrafPrivDesc); }
+
+  virtual Long pack(void *space);
+  virtual Lng32 unpack(void * base, void * reallocator);
+
+  virtual TrafPrivDesc *privDesc() const { return (TrafPrivDesc*)this; }
+
+  DescStructPtr privGrantees;
+  char filler[16];
+};
+
+class TrafPrivGranteeDesc : public TrafDesc {
+public:
+  TrafPrivGranteeDesc() : TrafDesc(DESC_PRIV_GRANTEE_TYPE)
+  {}
+
+  // ---------------------------------------------------------------------
+  // Redefine virtual functions required for Versioning.
+  //----------------------------------------------------------------------
+  virtual unsigned char getClassVersionID()
+  {
+    return 1;
+  }
+
+  virtual void populateImageVersionIDArray()
+  {
+    setImageVersionID(0,getClassVersionID());
+  }
+
+  virtual short getClassSize()      { return 
(short)sizeof(TrafPrivGranteeDesc); }
+
+  virtual Long pack(void *space);
+  virtual Lng32 unpack(void * base, void * reallocator);
+
+  virtual TrafPrivGranteeDesc *privGranteeDesc() const { return 
(TrafPrivGranteeDesc*)this; }
+
+  Int32 grantee;
+  DescStructPtr objectBitmap;
+  DescStructPtr columnBitmaps;
+  char filler[20];
+};
+
+class TrafPrivBitmapDesc : public TrafDesc {
+public:
+  TrafPrivBitmapDesc() : TrafDesc(DESC_PRIV_BITMAP_TYPE)
+  {}
+
+  // ---------------------------------------------------------------------
+  // Redefine virtual functions required for Versioning.
+  //----------------------------------------------------------------------
+  virtual unsigned char getClassVersionID()
+  {
+    return 1;
+  }
+
+  virtual void populateImageVersionIDArray()
+  {
+    setImageVersionID(0,getClassVersionID());
+  }
+
+  virtual short getClassSize()      { return 
(short)sizeof(TrafPrivBitmapDesc); }
+
+  //virtual Long pack(void *space);
+  //virtual Lng32 unpack(void * base, void * reallocator);
+
+  virtual TrafPrivBitmapDesc *privBitmapDesc() const { return 
(TrafPrivBitmapDesc*)this; }
+
+  Int32  columnOrdinal;
+  Int64  privBitmap;
+  Int64  privWGOBitmap;
+  char filler[20];
+};
+// ------------------------- end privilege descriptors 
-------------------------
+
 // if space is passed in, use it. Otherwise use HEAP of CmpCommon
 TrafDesc *TrafAllocateDDLdesc(desc_nodetype nodetype, 
                                  Space *space);

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/c23ad355/core/sql/sqlcomp/CmpSeabaseDDL.h
----------------------------------------------------------------------
diff --git a/core/sql/sqlcomp/CmpSeabaseDDL.h b/core/sql/sqlcomp/CmpSeabaseDDL.h
index 64ca868..edc554f 100644
--- a/core/sql/sqlcomp/CmpSeabaseDDL.h
+++ b/core/sql/sqlcomp/CmpSeabaseDDL.h
@@ -1385,6 +1385,10 @@ protected:
                                       const NAString &schName, 
                                       const NAString &seqName);
     
+  ComTdbVirtTablePrivInfo * getSeabasePrivInfo
+    (const Int64 objUID,
+     const ComObjectType objType);
+
   Lng32 getSeabaseColumnInfo(ExeCliInterface *cliInterface,
                              Int64 objUID,
                              const NAString &catName,

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/c23ad355/core/sql/sqlcomp/CmpSeabaseDDLtable.cpp
----------------------------------------------------------------------
diff --git a/core/sql/sqlcomp/CmpSeabaseDDLtable.cpp 
b/core/sql/sqlcomp/CmpSeabaseDDLtable.cpp
index 1e90ece..59a4817 100644
--- a/core/sql/sqlcomp/CmpSeabaseDDLtable.cpp
+++ b/core/sql/sqlcomp/CmpSeabaseDDLtable.cpp
@@ -4292,7 +4292,7 @@ void CmpSeabaseDDL::alterSeabaseTableStoredDesc(
       return;
     }
  
-  // Make sure user has the privilege to perform the rename
+  // Make sure user has the privilege to perform the alter
  if (alterStoredDesc->getType() != StmtDDLAlterTableStoredDesc::CHECK)
    {
      if (!isDDLOperationAuthorized(SQLOperation::ALTER_TABLE,
@@ -9483,6 +9483,17 @@ void CmpSeabaseDDL::seabaseGrantRevoke(
  
       }
   }
+
+  if (result == STATUS_ERROR)
+    return;
+
+  // Adjust the stored descriptor
+  char objectTypeLit[3] = {0};
+  strncpy(objectTypeLit,PrivMgr::ObjectEnumToLit(objectType),2);
+
+  updateObjectRedefTime(&cliInterface,
+                        catalogNamePart, schemaNamePart, objectNamePart,
+                        objectTypeLit, -1, objectUID);
   return;
 }
 
@@ -10322,6 +10333,48 @@ ComTdbVirtTableSequenceInfo * 
CmpSeabaseDDL::getSeabaseSequenceInfo(
   return seqInfo;
 }
 
+// ****************************************************************************
+// Method: getSeabasePrivInfo
+//
+// This method retrieves the list of privilege descriptors for each user that
+// has been granted an object or column level privilege on the object.
+// ****************************************************************************
+ComTdbVirtTablePrivInfo * CmpSeabaseDDL::getSeabasePrivInfo(
+  const Int64 objUID,
+  const ComObjectType objType)
+{
+  if (!isAuthorizationEnabled())
+    return NULL;
+
+  // Prepare to call privilege manager
+  NAString MDLoc;
+  CONCAT_CATSCH(MDLoc, getSystemCatalog(), SEABASE_MD_SCHEMA);
+  NAString privMgrMDLoc;
+  CONCAT_CATSCH(privMgrMDLoc, getSystemCatalog(), SEABASE_PRIVMGR_SCHEMA);
+
+  // Summarize privileges for object
+  PrivStatus privStatus = STATUS_GOOD;
+  std::vector<PrivMgrDesc> privDescs;
+  PrivMgrCommands command(std::string(MDLoc.data()),
+                          std::string(privMgrMDLoc.data()),
+                          CmpCommon::diags());
+  if (command.getPrivileges(objUID, objType, privDescs) != STATUS_GOOD)
+    {
+      *CmpCommon::diags() << DgSqlCode(-CAT_UNABLE_TO_RETRIEVE_PRIVS);
+      return NULL;
+    }
+
+  ComTdbVirtTablePrivInfo *privInfo = new (STMTHEAP) ComTdbVirtTablePrivInfo();
+
+  // PrivMgrDesc operator= is a deep copy
+  privInfo->privmgr_desc_list = new (STMTHEAP) std::vector<PrivMgrDesc>;
+  for (size_t i = 0; i < privDescs.size(); i++)
+    privInfo->privmgr_desc_list->push_back(privDescs[i]);
+
+  return privInfo;
+}
+
+
 TrafDesc * CmpSeabaseDDL::getSeabaseLibraryDesc(
    const NAString &catName, 
    const NAString &schName, 
@@ -10434,6 +10487,9 @@ TrafDesc * CmpSeabaseDDL::getSeabaseSequenceDesc(const 
NAString &catName,
     {
       return NULL;
     }
+  
+  ComTdbVirtTablePrivInfo * privInfo = 
+    getSeabasePrivInfo(seqUID, COM_SEQUENCE_GENERATOR_OBJECT);
 
   ComTdbVirtTableTableInfo * tableInfo =
     new(STMTHEAP) ComTdbVirtTableTableInfo[1];
@@ -10458,7 +10514,10 @@ TrafDesc * CmpSeabaseDDL::getSeabaseSequenceDesc(const 
NAString &catName,
      0, NULL, //indexInfo
      0, NULL, // viewInfo
      tableInfo,
-     seqInfo);
+     seqInfo,
+     NULL, NULL, // endKeyArray, snapshotName
+     FALSE, NULL, FALSE, // genPackedDesc, packedDescLen, isUserTable
+     privInfo);
   
   return tableDesc;
 }
@@ -11230,6 +11289,8 @@ TrafDesc * CmpSeabaseDDL::getSeabaseUserTableDesc(const 
NAString &catName,
                                        extSeqName, objectOwner, schemaOwner, 
seqUID);
     }
 
+  ComTdbVirtTablePrivInfo * privInfo = getSeabasePrivInfo(objUID, objType);
+
   ComTdbVirtTableTableInfo * tableInfo = new(STMTHEAP) 
ComTdbVirtTableTableInfo[1];
   tableInfo->tableName = extTableName->data();
   tableInfo->createTime = 0;
@@ -11309,7 +11370,8 @@ TrafDesc * CmpSeabaseDDL::getSeabaseUserTableDesc(const 
NAString &catName,
      snapshotName,
      ((ctlFlags & GEN_PACKED_DESC) != 0),
      &packedDescLen,
-     TRUE /*user table*/);
+     TRUE /*user table*/,
+     privInfo);
   
   deleteNAArray(heap_, endKeyArray);
   
@@ -11638,12 +11700,15 @@ TrafDesc 
*CmpSeabaseDDL::getSeabaseRoutineDescInternal(const NAString &catName,
       return NULL;
     } 
   
+  ComTdbVirtTablePrivInfo * privInfo = getSeabasePrivInfo(objectUID, 
objectType);
+
   TrafDesc *routine_desc = NULL;
   routine_desc = Generator::createVirtualRoutineDesc(
        objName.data(),
        routineInfo,
        numParams,
        paramsArray,
+       privInfo,
        NULL);
 
   if (routine_desc == NULL)

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/c23ad355/core/sql/sqlcomp/PrivMgrCommands.cpp
----------------------------------------------------------------------
diff --git a/core/sql/sqlcomp/PrivMgrCommands.cpp 
b/core/sql/sqlcomp/PrivMgrCommands.cpp
index 35b7146..550ac64 100644
--- a/core/sql/sqlcomp/PrivMgrCommands.cpp
+++ b/core/sql/sqlcomp/PrivMgrCommands.cpp
@@ -40,6 +40,7 @@
 #include "PrivMgrComponentPrivileges.h"
 #include "PrivMgrRoles.h"
 #include "ComSecurityKey.h"
+#include "ComUser.h"
 #include <cstdio>
 #include <algorithm>
 
@@ -64,6 +65,100 @@ PrivMgrObjectInfo::PrivMgrObjectInfo(
 }
  
 // ****************************************************************************
+// Class: PrivMgrUserPrivs
+// ****************************************************************************
+PrivMgrUserPrivs::PrivMgrUserPrivs(
+  const TrafDesc *priv_desc,
+  const int32_t userID)
+{
+  assert (priv_desc);
+
+  // generate PrivMgrUserPrivs from the priv_desc structure
+  TrafDesc *priv_grantees_desc = priv_desc->privDesc()->privGrantees;
+  TrafDesc *priv_grantee_desc = NULL;
+  TrafDesc *priv_public_desc = NULL;
+
+  // Find relevant desc for the user
+  while (priv_grantees_desc)
+  {
+    Int32 grantee = priv_grantees_desc->privGranteeDesc()->grantee;
+    if (grantee == userID)
+      priv_grantee_desc = priv_grantees_desc->privGranteeDesc();
+
+    if (ComUser::isPublicUserID(grantee))
+      priv_public_desc = priv_grantees_desc->privGranteeDesc();
+
+    priv_grantees_desc = priv_grantees_desc->next;
+  }
+
+  // If the user has a privilege in the priv_grantees_desc list, use it to
+  // create the PrivMgrUserPrivs class.
+  if (priv_grantee_desc)
+  {
+
+    // Set up object level privileges
+    TrafDesc *objectPrivs = priv_grantee_desc->privGranteeDesc()->objectBitmap;
+    objectBitmap_ = objectPrivs->privBitmapDesc()->privBitmap;
+    grantableBitmap_ = objectPrivs->privBitmapDesc()->privWGOBitmap;
+
+    // Set up column level privileges
+    // The PrivColList is a key <=> value pair structure, the key is the
+    // column ordinal (number) and the value is the associated bitmap.
+    TrafDesc *columnPrivs = 
priv_grantee_desc->privGranteeDesc()->columnBitmaps;
+    PrivColList colPrivsList;
+    PrivColList colGrantableList;
+    while (columnPrivs)
+    {
+      Int32 columnOrdinal = columnPrivs->privBitmapDesc()->columnOrdinal;
+      colPrivsList[columnOrdinal] = columnPrivs->privBitmapDesc()->privBitmap;
+      colGrantableList[columnOrdinal] = 
columnPrivs->privBitmapDesc()->privWGOBitmap;
+      columnPrivs = columnPrivs->next;
+    }
+    colPrivsList_= colPrivsList;
+    colGrantableList_ = colGrantableList;
+  }
+
+  // See if there are privileges assigned to public.  If so, "or" the public
+  // list to the user to the current bitmaps. Initially all the bitmap are
+  // set to 0.
+  if (priv_public_desc)
+  {
+    // Set up object level privileges
+    TrafDesc *objectPrivs = priv_public_desc->privGranteeDesc()->objectBitmap;
+    objectBitmap_ |= objectPrivs->privBitmapDesc()->privBitmap;
+    grantableBitmap_ |= objectPrivs->privBitmapDesc()->privWGOBitmap;
+
+    // Set up column level privileges
+    // The PrivColList is a key <=> value pair structure, the key is the
+    // column ordinal (number) and the value is the associated bitmap.
+    TrafDesc *columnPrivs = priv_public_desc->privGranteeDesc()->columnBitmaps;
+    PrivColList colPrivsList;
+    PrivColList colGrantableList;
+    std::map<size_t,PrivColumnBitmap>::iterator it; 
+    while (columnPrivs)
+    {
+      Int32 columnOrdinal = columnPrivs->privBitmapDesc()->columnOrdinal;
+      it = colPrivsList_.find(columnOrdinal);
+      if (it == colPrivsList_.end())
+      {
+        colPrivsList_[columnOrdinal] = 
columnPrivs->privBitmapDesc()->privBitmap;
+        colGrantableList[columnOrdinal] = 
columnPrivs->privBitmapDesc()->privWGOBitmap;
+      }
+      else
+      {
+        colPrivsList_[columnOrdinal] |= 
columnPrivs->privBitmapDesc()->privBitmap;
+        colGrantableList[columnOrdinal] |= 
columnPrivs->privBitmapDesc()->privWGOBitmap;
+      }
+
+      columnPrivs = columnPrivs->next;
+    }
+  }
+
+  // TBD - add schema privilege bitmaps
+}
+
+
+// ****************************************************************************
 // Class: PrivMgrCommands
 // ****************************************************************************
 
@@ -399,6 +494,38 @@ PrivStatus PrivMgrCommands::getGrantorDetailsForObject(
 // ----------------------------------------------------------------------------
 // method: getPrivileges
 //
+// Creates a set of priv descriptors for all user grantees on an object
+// Used by Trafodion compiler to store as part of the table descriptor.
+//                                                       
+//  Parameters:    
+//                                                                       
+//  <objectUID> is the unique identifier of the object
+//  <objectType> is the type of object
+//  <privDescs> is the returned list of privileges the on the object
+//                                                                  
+// Returns: PrivStatus                                               
+//                                                                  
+//   STATUS_GOOD: privilege descriptors were built
+//             *: unexpected error occurred, see diags.     
+// ----------------------------------------------------------------------------
+PrivStatus PrivMgrCommands::getPrivileges(
+  const int64_t objectUID,
+  ComObjectType objectType,
+  std::vector <PrivMgrDesc > &privDescs)
+{
+  // If authorization is enabled, go get privilege bitmaps from metadata
+  if (authorizationEnabled())
+  {
+    PrivMgrPrivileges privInfo (objectUID, metadataLocation_, pDiags_);
+    return privInfo.getPrivsOnObject(objectType, privDescs);
+  }
+  return STATUS_GOOD;
+}
+
+
+// ----------------------------------------------------------------------------
+// method: getPrivileges
+//
 // returns GRANT statements for privileges associated with the 
 // specified objectUID
 //

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/c23ad355/core/sql/sqlcomp/PrivMgrCommands.h
----------------------------------------------------------------------
diff --git a/core/sql/sqlcomp/PrivMgrCommands.h 
b/core/sql/sqlcomp/PrivMgrCommands.h
index 8ca2a07..cf281e8 100644
--- a/core/sql/sqlcomp/PrivMgrCommands.h
+++ b/core/sql/sqlcomp/PrivMgrCommands.h
@@ -30,9 +30,11 @@
 #include <iterator>
 #include "PrivMgrMD.h"
 #include "PrivMgrDefs.h"
+#include "TrafDDLdesc.h"
 
 class ComDiagsArea;
 class ComSecurityKey;
+struct TrafDesc;
 
 // 
*****************************************************************************
 // This file contains classes used by callers of privilege manager
@@ -129,6 +131,9 @@ class PrivMgrUserPrivs
   public:
 
   PrivMgrUserPrivs(const int32_t nbrCols = 0){};
+  PrivMgrUserPrivs(
+    const TrafDesc *priv_desc,
+    const int32_t userID);
 
   static std::string convertPrivTypeToLiteral(PrivType which)
   {
@@ -389,8 +394,8 @@ class PrivMgrUserPrivs
 
 
  private:
-   std::bitset<NBR_OF_PRIVS> objectBitmap_;
-   std::bitset<NBR_OF_PRIVS> grantableBitmap_;
+   PrivObjectBitmap objectBitmap_;
+   PrivObjectBitmap grantableBitmap_;
    PrivColList colPrivsList_;
    PrivColList colGrantableList_;
    PrivSchemaBitmap schemaPrivBitmap_;
@@ -461,6 +466,11 @@ public:
    PrivStatus getPrivileges(
       const int64_t objectUID,
       ComObjectType objectType,
+      std::vector<PrivMgrDesc> &userPrivileges);
+     
+   PrivStatus getPrivileges(
+      const int64_t objectUID,
+      ComObjectType objectType,
       const int32_t granteeUID,
       PrivMgrUserPrivs &userPrivileges,
       std::vector <ComSecurityKey *>* secKeySet = NULL);

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/c23ad355/core/sql/sqlcomp/PrivMgrDesc.h
----------------------------------------------------------------------
diff --git a/core/sql/sqlcomp/PrivMgrDesc.h b/core/sql/sqlcomp/PrivMgrDesc.h
index ce325e1..e8173c8 100644
--- a/core/sql/sqlcomp/PrivMgrDesc.h
+++ b/core/sql/sqlcomp/PrivMgrDesc.h
@@ -175,6 +175,21 @@ class PrivMgrCoreDesc
     virtual ~PrivMgrCoreDesc()              // destructor
     {}
 
+  // assignment operator
+  PrivMgrCoreDesc& operator=(const PrivMgrCoreDesc& other) 
+  {
+     //  Check for pathological case of X == X.
+      if ( this == &other )
+         return *this;
+
+      priv_ = other.priv_;
+      wgo_ = other.wgo_;
+      columnOrdinal_ = other.columnOrdinal_;
+
+      return *this;
+  }
+
+
   // comparison operator 
   bool operator==(const PrivMgrCoreDesc& other) const;
    
@@ -366,23 +381,31 @@ class PrivMgrDesc
 
 public:
    PrivMgrDesc(const PrivMgrDesc&other)           // copy constructor
-   : tableLevel_(other.tableLevel_)
+   : tableLevel_(other.tableLevel_),
+     columnLevel_(other.columnLevel_),
+     grantee_(other.grantee_)
    {}
 
    PrivMgrDesc(const int32_t grantee,
                const int32_t nbrCols = 0    // preset constructor
               )
-   : tableLevel_()
+   : tableLevel_(),
+     columnLevel_(),
+     grantee_(grantee)
   {}
 
    //PrivMgrDesc(const int32_t nbrCols);    // preset constructor
    PrivMgrDesc(const PrivMgrDesc &privs,            // preset constructor
                const int32_t grantee)
-   : tableLevel_(privs.tableLevel_)
+   : tableLevel_(privs.tableLevel_),
+     columnLevel_(privs.columnLevel_),
+     grantee_(privs.grantee_)
    {}
 
    PrivMgrDesc(void)
-   : tableLevel_()
+   : tableLevel_(),
+     columnLevel_(),
+     grantee_(0)
    {}
 
    virtual ~PrivMgrDesc()                 // destructor
@@ -396,7 +419,8 @@ public:
          return *this;
 
       tableLevel_  = other.tableLevel_;
-      //columnLevel_ = other.columnLevel_;
+      columnLevel_ = other.columnLevel_;
+      grantee_ = other.grantee_;
 
       return *this;
    }
@@ -410,8 +434,9 @@ public:
          return TRUE;
 
       return ( 
-//             ( columnLevel_ == other.columnLevel_ ) &&
-               ( tableLevel_  == other.tableLevel_  ) );
+               ( columnLevel_ == other.columnLevel_ ) &&
+               ( tableLevel_  == other.tableLevel_  ) &&
+               ( grantee_ == other.grantee_));
    }
 
 
@@ -457,7 +482,9 @@ public:
 
    // Accessors
 
-   PrivMgrCoreDesc getTablePrivs() const { return tableLevel_;}
+   PrivMgrCoreDesc getTablePrivs()  const { return tableLevel_; }
+   std::vector<PrivMgrCoreDesc> getColumnPrivs() const { return columnLevel_; }
+   int32_t getGrantee() const { return grantee_; }
    PrivMgrCoreDesc &       fetchTablePrivs();
    bool       getOneTablePriv(const PrivType which) const;
    bool       getOneTableWgo(const PrivType which) const;
@@ -472,11 +499,10 @@ public:
 
    // Mutators
 
-   void setGrantee(const int32_t&);
+   void setGrantee(const int32_t&grantee) { grantee_ = grantee; }
    void setTablePrivs(const PrivMgrCoreDesc &privs) { tableLevel_ = privs; }
    void resetTablePrivs() { tableLevel_.setAllPrivAndWgo(0); }
-
-   //void setColumnPrivs(const CatColPrivsList& privs);
+   void setColumnPrivs(const std::vector<PrivMgrCoreDesc> &privs) { 
columnLevel_ = privs; }
 
 #if 0
    void setColumnPriv(const PrivType which,
@@ -602,6 +628,7 @@ private:
 
    PrivMgrCoreDesc                 tableLevel_;
    std::vector<PrivMgrCoreDesc>    columnLevel_;
+   int32_t                         grantee_;
 };
 
 

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/c23ad355/core/sql/sqlcomp/PrivMgrPrivileges.cpp
----------------------------------------------------------------------
diff --git a/core/sql/sqlcomp/PrivMgrPrivileges.cpp 
b/core/sql/sqlcomp/PrivMgrPrivileges.cpp
index a1af7cb..dcdb328 100644
--- a/core/sql/sqlcomp/PrivMgrPrivileges.cpp
+++ b/core/sql/sqlcomp/PrivMgrPrivileges.cpp
@@ -555,6 +555,90 @@ PrivStatus PrivMgrPrivileges::buildSecurityKeys(
 }
 
 // 
*****************************************************************************
+// * Method: getPrivsOnObject                                
+// *                                                       
+// * Creates a set of priv descriptors for all user grantees on an object
+// * Used by Trafodion compiler to store as part of the table descriptor.
+// *                                                       
+// *  Parameters:    
+// *                                                                       
+// *  <objectType> is the type of object
+// *  <priv>Descs> is the list of privileges the on the object
+// *                                                                  
+// * Returns: PrivStatus                                               
+// *                                                                  
+// * STATUS_GOOD: privilege descriptors were built
+// *           *: unexpected error occurred, see diags.     
+// *  
+// 
*****************************************************************************
+PrivStatus PrivMgrPrivileges::getPrivsOnObject (
+  const ComObjectType objectType,
+  std::vector<PrivMgrDesc> & privDescs )
+{
+  PrivStatus retcode = STATUS_GOOD;
+
+  if (objectUID_ == 0)
+  {
+    PRIVMGR_INTERNAL_ERROR("objectUID is 0 for getPrivRowsForObject()");
+    return STATUS_ERROR;
+  }
+
+  // generate the list of privileges granted to the object and store in class
+  if (generateObjectRowList() == STATUS_ERROR)
+    return STATUS_ERROR;
+  
+  // generate the list of privileges granted to the object and store in class
+  if (generateColumnRowList() == STATUS_ERROR)
+    return STATUS_ERROR;
+  
+  // Gets all the grantees from the object and column lists
+  // This list is affected userIDs.  The public auth ID is also included if any
+  // privs were granted. 
+  std::vector<int32_t> userIDs;
+  if (getDistinctUserIDs(objectRowList_, columnRowList_, userIDs) == 
STATUS_ERROR)
+    return STATUS_ERROR;
+
+  for (size_t i = 0; i < userIDs.size(); i++)
+  {
+    int32_t userID = userIDs[i];
+
+    PrivMgrDesc privsOfTheUser(userID);
+    bool hasManagePrivileges = false;
+    std::vector <int32_t> roleIDs;
+ 
+    // Public is not granted roles, skip to avoid extra I/O
+    if (!ComUser::isPublicUserID(userID))
+    {
+      if (getRoleIDsForUserID(userID,roleIDs) == STATUS_ERROR)
+        return STATUS_ERROR;
+    }
+
+    if (getUserPrivs(objectType, userID, roleIDs, privsOfTheUser,
+                     hasManagePrivileges, NULL ) != STATUS_GOOD)
+      return STATUS_ERROR;
+
+    PrivColList colPrivsList;
+    PrivColList colGrantableList;
+    if (getColPrivsForUser(userID,roleIDs,colPrivsList,colGrantableList,NULL) 
!= STATUS_GOOD)
+      return STATUS_ERROR;
+
+    // the returned list are in column ordinal order, if no privileges have
+    // been granted on the column, then the bitmap is all zeroes
+    std::vector<PrivMgrCoreDesc> colPrivs;
+    for (size_t j = 0; j < colPrivsList.size(); j++)
+    {
+      PrivMgrCoreDesc colPriv(colPrivsList[j], colGrantableList[j], j);
+      colPrivs.push_back(colPriv);
+    }
+    privsOfTheUser.setColumnPrivs(colPrivs);
+
+    privDescs.push_back(privsOfTheUser);  
+  }
+  return STATUS_GOOD;
+}
+
+
+// 
*****************************************************************************
 // * Method: getColPrivsForUser                                
 // *                                                       
 // *    Returns the column privileges a user has been granted on the object.
@@ -650,6 +734,92 @@ void PrivMgrPrivileges::getColRowsForGranteeOrdinal(
 }
 
 // 
*****************************************************************************
+// * Method: getDistinctUserIDs                                
+// *
+// * Finds all the usersIDs that have been granted at least one privilege on
+// * object.  These userIDs include direct grants: 
+// *   grant <privilege> on <object> to <user>  <== user added to list
+// * Or indirect grants through role:
+// *   grant <privilege> on <object> to <role>
+// *   grant <role> to <user>  <== user added to list
+// * Includes public in the returned list
+// 
*****************************************************************************
+PrivStatus PrivMgrPrivileges::getDistinctUserIDs(
+  const std::vector <PrivMgrMDRow *> &objectRowList,
+  const std::vector <PrivMgrMDRow *> &columnRowList,
+  std::vector<int32_t> &userIDs)
+{
+  std::vector<int32_t> roleIDs;
+  int32_t authID;
+
+  // DB__ROOTROLE is a special role.  If the current user has been granted 
+  // this role, then they have privileges.  Add it to the roleIDs list for
+  // processing.
+  roleIDs.push_back(ROOT_ROLE_ID);
+
+  // The direct object grants are stored in memory (objectRowList) so no I/O
+  // Save grants to roles for further processing
+  for (size_t i = 0; i < objectRowList.size(); i++)
+  {
+    ObjectPrivsMDRow &row = static_cast<ObjectPrivsMDRow &> 
(*objectRowList[i]);
+    authID = row.granteeID_;
+
+    // insert authID into correct list, if not already present
+    if (ComUser::isPublicUserID(authID) || 
+        CmpSeabaseDDLauth::isUserID(authID)) 
+    {
+       if (std::find(userIDs.begin(), userIDs.end(), authID) == userIDs.end())
+         userIDs.insert( std::upper_bound( userIDs.begin(), userIDs.end(), 
authID ), authID);
+    }
+    else
+    {
+       if (std::find(roleIDs.begin(), roleIDs.end(), authID) == roleIDs.end())
+         roleIDs.insert( std::upper_bound( roleIDs.begin(), roleIDs.end(), 
authID ), authID);
+    }
+  }
+
+  // The direct column grants are stored in memory (columnRowList) so no I/O
+  // Save grants to roles for further processing
+  for (size_t i = 0; i < columnRowList.size(); i++)
+  {
+    ColumnPrivsMDRow &row = static_cast<ColumnPrivsMDRow &> 
(*columnRowList[i]);
+    authID = row.granteeID_;
+
+    // insert authID into correct list, if not already present
+    if (ComUser::isPublicUserID(authID) ||
+        CmpSeabaseDDLauth::isUserID(authID)) 
+    {
+      if (std::find(userIDs.begin(), userIDs.end(), authID) == userIDs.end())
+        userIDs.insert( std::upper_bound( userIDs.begin(), userIDs.end(), 
authID ), authID);
+    }
+    else
+    {
+       if (std::find(roleIDs.begin(), roleIDs.end(), authID) == roleIDs.end())
+         roleIDs.insert( std::upper_bound( roleIDs.begin(), roleIDs.end(), 
authID ), authID);
+    }
+  }
+
+  // Get the list of users that have been granted one or more of the roles in
+  // the role list.  A query that retrieves all userIDs granted to the list of
+  // roles (roleIDs) is performed. 
+  if (roleIDs.size() > 0)
+  {
+    std::vector<int32_t> userIDsForRoleIDs;
+    if (getUserIDsForRoleIDs(roleIDs, userIDsForRoleIDs) == STATUS_ERROR)
+      return STATUS_ERROR;
+
+    for (size_t i = 0; i < userIDsForRoleIDs.size(); i++)
+    {
+      authID = userIDsForRoleIDs[i];
+      if (std::find(userIDs.begin(), userIDs.end(), authID) == userIDs.end())
+         userIDs.insert( std::upper_bound( userIDs.begin(), userIDs.end(), 
authID ), authID);
+    }
+  }
+  return STATUS_GOOD;
+}
+  
+   
+// 
*****************************************************************************
 // * Method: getPrivRowsForObject                                
 // *                                                       
 // *    returns rows describing all the privileges that have been
@@ -4248,6 +4418,41 @@ std::vector<int32_t> roleDepths;
 //*************** End of PrivMgrPrivileges::getRoleIDsForUserID 
****************
 
 // 
*****************************************************************************
+// * Method: getUserIDsForRoleIDs                              
+// *                                                       
+// *    Returns the userIDs granted to the role passed in role list
+// *                                                       
+// *  Parameters:    
+// *                                                                       
+// *  <roleIDs> list of roles to check
+// *  <userIDs> passed back the list (potentially empty) of users granted to 
+// *            the roleIDs
+// *                                                                     
+// * Returns: PrivStatus                                               
+// *                                                                  
+// * STATUS_GOOD: Role list returned
+// *           *: Unable to fetch granted roles, see diags.     
+// *                                                               
+// 
*****************************************************************************
+PrivStatus PrivMgrPrivileges::getUserIDsForRoleIDs(
+  const std::vector<int32_t>  & roleIDs,
+  std::vector<int32_t> & userIDs)
+{
+  std::vector<int32_t> userIDsForRoleIDs;
+  PrivMgrRoles roles(" ",metadataLocation_,pDiags_);
+  if (roles.fetchUsersForRoles(roleIDs, userIDsForRoleIDs) == STATUS_ERROR)
+    return STATUS_ERROR;
+
+  for (size_t i = 0; i < userIDsForRoleIDs.size(); i++)
+  {
+     int32_t authID = userIDsForRoleIDs[i];
+     if (std::find(userIDs.begin(), userIDs.end(), authID) == userIDs.end())
+       userIDs.insert( std::upper_bound( userIDs.begin(), userIDs.end(), 
authID ), authID);
+  }
+  return STATUS_GOOD;
+}
+
+// 
*****************************************************************************
 // * Method: getUserPrivs                                
 // *                                                       
 // *    Accumulates privileges for a user summarized over all grantors
@@ -4274,7 +4479,7 @@ PrivStatus PrivMgrPrivileges::getUserPrivs(
   const std::vector<int32_t> & roleIDs,
   PrivMgrDesc &summarizedPrivs,
   bool & hasManagePrivileges,
-  std::vector <ComSecurityKey *>* secKeySet 
+  std::vector<ComSecurityKey *>* secKeySet 
   )
 {
    PrivStatus retcode = STATUS_GOOD;

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/c23ad355/core/sql/sqlcomp/PrivMgrPrivileges.h
----------------------------------------------------------------------
diff --git a/core/sql/sqlcomp/PrivMgrPrivileges.h 
b/core/sql/sqlcomp/PrivMgrPrivileges.h
index 1239c7a..10d2809 100644
--- a/core/sql/sqlcomp/PrivMgrPrivileges.h
+++ b/core/sql/sqlcomp/PrivMgrPrivileges.h
@@ -158,6 +158,10 @@ public:
       const PrivMgrCoreDesc &privs,
       std::vector <ComSecurityKey *> & secKeySet);
       
+   PrivStatus getPrivsOnObject (
+      const ComObjectType objectType,
+      std::vector<PrivMgrDesc> & privDescs );
+ 
    PrivStatus getColPrivsForUser(
       const int32_t granteeID,
       const std::vector<int32_t> & roleIDs,
@@ -370,7 +374,12 @@ private:
 
   PrivStatus getColumnRowList(
     const int64_t objectUID,
-   std::vector<PrivMgrMDRow *> &columnRows);
+    std::vector<PrivMgrMDRow *> &columnRows);
+
+  PrivStatus getDistinctUserIDs(
+    const std::vector <PrivMgrMDRow *> &objectRowList,
+    const std::vector <PrivMgrMDRow *> &columnRowList,
+    std::vector<int32_t> &userIDs);
 
   PrivStatus getGrantedPrivs(
     const int32_t granteeID,
@@ -400,6 +409,10 @@ private:
     const int32_t granteeID,
     std::set<int32_t> &listOfGrantors);
 
+  PrivStatus getUserIDsForRoleIDs(
+    const std::vector<int32_t> & roleIDs,
+    std::vector<int32_t> & userIDs);
+
   PrivStatus givePriv(
      const int32_t currentOwnerID,
      const int32_t newOwnerID,

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/c23ad355/core/sql/sqlcomp/PrivMgrRoles.cpp
----------------------------------------------------------------------
diff --git a/core/sql/sqlcomp/PrivMgrRoles.cpp 
b/core/sql/sqlcomp/PrivMgrRoles.cpp
index 08489a1..12861fd 100644
--- a/core/sql/sqlcomp/PrivMgrRoles.cpp
+++ b/core/sql/sqlcomp/PrivMgrRoles.cpp
@@ -722,6 +722,65 @@ PrivStatus privStatus = 
myTable.selectAllWhere(whereClause,orderByClause,rows);
 }
 //****************** End of PrivMgrRoles::fetchUsersForRole 
********************
 
+// 
*****************************************************************************
+// *                                                                           
*
+// * Function: PrivMgrRoles::fetchUsersForRoles                                
*
+// *                                                                           
*
+// *    Returns all users granted the list of roles                            
*
+// *                                                                           
*
+// 
*****************************************************************************
+// *                                                                           
*
+// *  Parameters:                                                              
*
+// *                                                                           
*
+// *  <roleIDs>                       const std::vector<int32_t> &    In       
*
+// *    is a list of roles.                                                    
*
+// *                                                                           
*
+// *  <userIDs>                       std::vector<std::int32_t> &     Out      
*
+// *    passes back a list of user grantees for the roles.                     
*
+// *                                                                           
*
+// 
*****************************************************************************
+// *                                                                           
*
+// * Returns: PrivStatus                                                       
*
+// *                                                                           
*
+// *   STATUS_GOOD: Zero or more userIDs were returned                         
*
+// *             *: Grants for roles were not returned due to SQL error.       
*
+// *                A CLI error is put into the diags area.                    
*
+// *                                                                           
*
+// 
*****************************************************************************
+PrivStatus PrivMgrRoles::fetchUsersForRoles(
+   const std::vector<int32_t> & userIDs,
+   std::vector<std::int32_t> & granteeIDs)
+{
+   std::string whereClause(" WHERE ROLE_ID IN( ");
+   for (size_t i = 0; i < userIDs.size(); i++)
+   {
+      if (i > 0)
+        whereClause += ", ";
+      whereClause += authIDToString(userIDs[i]);
+   }
+   whereClause += ")";
+   std::string orderByClause(" ORDER BY GRANTEE_ID");
+
+   std::vector<MyRow> rows;
+   MyTable &myTable = static_cast<MyTable &>(myTable_);
+   if (myTable.selectAllWhere(whereClause,orderByClause,rows) == STATUS_ERROR)
+      return STATUS_ERROR;
+
+   // When we support hierarchical roles, then we need to save all grants to
+   // roles and recursively check for user grantees.
+   for (size_t r = 0; r < rows.size(); r++)
+   {
+      MyRow &row = rows[r];
+
+      if (CmpSeabaseDDLauth::isUserID(row.granteeID_))
+         granteeIDs.push_back(row.granteeID_);
+   }
+
+   return STATUS_GOOD;
+}
+//****************** End of PrivMgrRoles::fetchUsersForRole 
********************
+
+
 
 // 
*****************************************************************************
 // *                                                                           
*

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/c23ad355/core/sql/sqlcomp/PrivMgrRoles.h
----------------------------------------------------------------------
diff --git a/core/sql/sqlcomp/PrivMgrRoles.h b/core/sql/sqlcomp/PrivMgrRoles.h
index 052ce6e..83a9120 100644
--- a/core/sql/sqlcomp/PrivMgrRoles.h
+++ b/core/sql/sqlcomp/PrivMgrRoles.h
@@ -66,6 +66,10 @@ public:
       std::vector<int32_t> & grantorIDs,
       std::vector<int32_t> & grantDepths);
    
+   PrivStatus fetchUsersForRoles(
+      const std::vector<int32_t> & roleIDs,
+      std::vector<int32_t> & userIDs);
+   
    PrivStatus grantRole(
       const std::vector<int32_t> & roleIDs,
       const std::vector<std::string> & roleNames,

Reply via email to