text: /**********************************************************************
  // @@@ START COPYRIGHT @@@
  //
  // Licensed to the Apache Software Foundation (ASF) under one
  // or more contributor license agreements.  See the NOTICE file
  // distributed with this work for additional information
  // regarding copyright ownership.  The ASF licenses this file
  // to you under the Apache License, Version 2.0 (the
  // "License"); you may not use this file except in compliance
  // with the License.  You may obtain a copy of the License at
  //
  //   http://www.apache.org/licenses/LICENSE-2.0
  //
  // Unless required by applicable law or agreed to in writing,
  // software distributed under the License is distributed on an
  // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  // KIND, either express or implied.  See the License for the
  // specific language governing permissions and limitations
  // under the License.
  //
  // @@@ END COPYRIGHT @@@
  **********************************************************************/
  /* -*-C++-*-
  ****************************************************************************
  *
  * File:         SqlTableOpenInfo.h
  * Description:  
  *
  * Created:      5/6/98
  * Language:     C++
  *
  *
  *
  *
  ****************************************************************************
  */
  
  #ifndef SQLTABLEOPENINFO_H
  #define SQLTABLEOPENINFO_H
  
  #include "Int64.h"
  #include "NABoolean.h"
  #include "ComPackDefs.h"
  #include "NAVersionedObject.h"
  #include "PrivMgrDefs.h"
  
  // #include "BaseTypes.h"
  // --------------------------------------------------------------------------
  // Class SqlTableOpenInfo
  // --------------------------------------------------------------------------
  #pragma nowarn(1506)   // warning elimination 
  class SqlTableOpenInfo : public NAVersionedObject
  {
  public:
  
    enum AccessMode
    {
      READ_,
      WRITE_,
      READWRITE_
    };
  
    struct AccessFlags
    {
      UInt32 select_: 1;
      UInt32 insert_: 1;
      UInt32 update_: 1;
      UInt32 delete_: 1;
    };
  
    void init()
    {
      openFlags_           = 0;
      otherFlags_          = FILLER_IS_INITED;
  
      // Default settings
      setShareOpens(TRUE);
      setExecutorOpen(TRUE);
      setNoWaited(TRUE);
      setLockWait(TRUE);
      setValidateTimestamp(TRUE);
      setCheckSecurity(FALSE);
      setUtilityOpen(FALSE);
  
      maxNowaitRequests_   = 15;
      accessMode_ 	 = READ_;
      redefTime_ 		 = -1;
      numParts_ 		 = -1;
      numIndexes_          = -1;
  
      fileName_ 		 = (NABasicPtr) NULL ;
      ansiName_ 		 = (NABasicPtr) NULL ;
      corrName_ 		 = (NABasicPtr) NULL ;
      columnListCount_ 	 = 0;
      updateColumnList_ 	 = (Int16Ptr) NULL;
      partNameArray_       = (NABasicPtr) NULL ;
  
      timeoutVal_          = 6000;
  
      utilityOpenId_       = -1;
  
      numPartsInPartNameArray_
                           = 0;
  
      priority_            = 3;
      clearAllAccessFlags();
      clearFiller();
    }
  
    // ---------------------------------------------------------------------
    // Redefine virtual functions required for Versioning.
    //----------------------------------------------------------------------
    virtual unsigned char getClassVersionID()
    {
      return 1;
    }
  
    virtual void populateImageVersionIDArray()
    {
      setImageVersionID(0,getClassVersionID());
    }
  
    virtual short getClassSize()   { return (short)sizeof(SqlTableOpenInfo); }
  
    SqlTableOpenInfo() : NAVersionedObject(-1)                     { init(); }
  
    // No destructor, and no "delete ansiName_;" etc. in setAnsiName() methods,
    // for we will assume that all allocations come from a heap
    
    NABoolean shareOpens()      { return (openFlags_ & SHARE_OPENS)    != 0; }
    NABoolean executorOpen()    { return (openFlags_ & EXECUTOR_OPEN)  != 0; }
    NABoolean openAllParts()    { return (openFlags_ & OPEN_ALL_PARTS) != 0; }
    NABoolean isUtilityOpen()   { return (openFlags_ & UTILITY_OPEN) != 0;   }
    NABoolean distributeOpens() { return (openFlags_ & DISTRIBUTE_OPENS) != 0; }
    NABoolean reuseOpens()      { return (openFlags_ & REUSE_OPENS) != 0; }
    NABoolean reuseOpensForWrite()      { return (openFlags_ & REUSE_OPENS_FOR_WRITE) != 0; }
    NABoolean validateRforkTS() { return (openFlags_ & VALIDATE_RFORK_TS) != 0;}
    NABoolean readProtectedOpen() { return (openFlags_ & READ_PROTECTED_OPEN) != 0;}
    NABoolean insertToNonAudited() { return (openFlags_ & INSERT_TO_NONAUDITED_OPEN) != 0;}
  
    NABoolean randomPartarrayGeneration() { return (openFlags_ & RANDOM_PARTARRAY_GENERATION) != 0;}
  
    NABoolean locationSpecified() { return (otherFlags_ & LOCATION)    != 0; }
    NABoolean isView()            { return (otherFlags_ & IS_MX_VIEW)  != 0; }
    NABoolean validateTimestamp() { return (otherFlags_ & VALIDATE_TS) != 0; }
    NABoolean noWaited()          { return (otherFlags_ & NO_WAIT)     != 0; }
    NABoolean lockWait()          { return (otherFlags_ & LOCK_WAIT)   != 0; }
    NABoolean checkSecurity()     { return (otherFlags_ & SECURITY)    != 0; }
    
    NABoolean subjectTable() const{ return (otherFlags_ & SUBJECT_TABLE) != 0; }
    NABoolean isAudited()         { return (otherFlags_ & AUDITED)     != 0; }
    NABoolean isIndex()           { return (otherFlags_ & IS_MX_INDEX) != 0; }
    NABoolean specialTable() { return (otherFlags_ & SPECIAL_TABLE) != 0; }
    NABoolean isUDRSurrogate()    { return (otherFlags_ & IS_UDR_SURROGATE) != 0; }
    NABoolean isReverseScan()    { return (otherFlags_ & REVERSE_SCAN) != 0; }
    NABoolean isNSAOperation()   { return (otherFlags_ & IS_NSA_OPERATION) != 0; }
    NABoolean isInsertOfUpdateCK() { return (otherFlags_ & INSERT_OF_UPDATE_CK) != 0; }
    NABoolean isMXMetadataTable()
    { return (otherFlags_ & IS_MX_METADATA_TABLE) != 0; }
  
    NABoolean isValidateViewsAtOpenTime()     
    { return (otherFlags_ & VALIDATE_VIEWS_AT_OPEN_TIME)    != 0; }
  
    NABoolean validateNumIndexesAtOpenTime()     
    { return (otherFlags_ & VALIDATE_NUM_INDEXES_AT_OPEN_TIME)    != 0; }
  
    NABoolean isHbase()     
    { return (otherFlags_ & IS_HBASE)    != 0; }
    
    void setShareOpens(NABoolean v)      
             { (v ? openFlags_ |= SHARE_OPENS : openFlags_ &= ~SHARE_OPENS); }
    void setExecutorOpen(NABoolean v)    
         { (v ? openFlags_ |= EXECUTOR_OPEN : openFlags_ &= ~EXECUTOR_OPEN); }
    void setOpenAllParts(NABoolean v)    
       { (v ? openFlags_ |= OPEN_ALL_PARTS : openFlags_ &= ~OPEN_ALL_PARTS); }
    void setUtilityOpen(NABoolean v)            
       { (v ? openFlags_ |= UTILITY_OPEN : openFlags_ &= ~UTILITY_OPEN); }
    void setDistributeOpens(NABoolean v) 	      
                 { (v ? openFlags_ |= DISTRIBUTE_OPENS : openFlags_ &= ~DISTRIBUTE_OPENS); }
    void setReuseOpens(NABoolean v) 	      
                 { (v ? openFlags_ |= REUSE_OPENS : openFlags_ &= ~REUSE_OPENS); }
    void setReuseOpensForWrite(NABoolean v) 	      
                 { (v ? openFlags_ |= REUSE_OPENS_FOR_WRITE : openFlags_ &= ~REUSE_OPENS_FOR_WRITE); }
    void setReadProtectedOpen(NABoolean v) 	      
                 { (v ? openFlags_ |= READ_PROTECTED_OPEN : openFlags_ &= ~READ_PROTECTED_OPEN); }
    void setInsertToNonAuditedOpen(NABoolean v) 	      
                 { (v ? openFlags_ |= INSERT_TO_NONAUDITED_OPEN : openFlags_ &= ~INSERT_TO_NONAUDITED_OPEN); }
  
    void setRandomPartarrayGeneration(NABoolean v) 	      
                 { (v ? openFlags_ |= RANDOM_PARTARRAY_GENERATION : openFlags_ &= ~RANDOM_PARTARRAY_GENERATION); }
  
    void setLocationSpecified(NABoolean v) 
                 { (v ? otherFlags_ |= LOCATION : otherFlags_ &= ~LOCATION); }
    void setIsView(NABoolean v)            
                   { (v ? otherFlags_ |= IS_MX_VIEW : otherFlags_ &= ~IS_MX_VIEW); }
    void setValidateTimestamp(NABoolean v) 
           { (v ? otherFlags_ |= VALIDATE_TS : otherFlags_ &= ~VALIDATE_TS); }
    void setNoWaited(NABoolean v)          
                     { (v ? otherFlags_ |= NO_WAIT : otherFlags_ &= ~NO_WAIT); }
    void setLockWait(NABoolean v)          
               { (v ? otherFlags_ |= LOCK_WAIT : otherFlags_ &= ~LOCK_WAIT); }
    void setCheckSecurity(NABoolean v)     
                 { (v ? otherFlags_ |= SECURITY : otherFlags_ &= ~SECURITY); }
    void setIsAudited(NABoolean v)     
                 { (v ? otherFlags_ |= AUDITED : otherFlags_ &= ~AUDITED); }
    void setIsIndex(NABoolean v)            
                   { (v ? otherFlags_ |= IS_MX_INDEX : otherFlags_ &= ~IS_MX_INDEX); }
    void setSpecialTable(NABoolean v)            
       { (v ? otherFlags_ |= SPECIAL_TABLE : otherFlags_ &= ~SPECIAL_TABLE); }
    void setIsUDRSurrogate(NABoolean v)
       { (v ? otherFlags_ |= IS_UDR_SURROGATE : otherFlags_ &= ~IS_UDR_SURROGATE); }
    void setIsReverseScan(NABoolean v)
       { (v ? otherFlags_ |= REVERSE_SCAN : otherFlags_ &= ~REVERSE_SCAN); }
    void setIsNSAOperation(NABoolean v)
       { (v ? otherFlags_ |= IS_NSA_OPERATION : otherFlags_ &= ~IS_NSA_OPERATION); }
    void setIsMXMetadataTable(NABoolean v)
       { (v ? otherFlags_ |= IS_MX_METADATA_TABLE : otherFlags_ &= ~IS_MX_METADATA_TABLE); }
   void setIsInsertOfUpdateCK(NABoolean v)
       { (v ? otherFlags_ |= INSERT_OF_UPDATE_CK : otherFlags_ &= ~INSERT_OF_UPDATE_CK); }
   void setValidateRforkTS(NABoolean v) 	      
       { (v ? openFlags_ |= VALIDATE_RFORK_TS : openFlags_ &= ~VALIDATE_RFORK_TS); }
  
  
    inline 
    void setSubjectTable(NABoolean v)
  	{ (v ? otherFlags_ |= SUBJECT_TABLE : otherFlags_ &= ~SUBJECT_TABLE); }
    void setValidateViewsAtOpenTime(NABoolean v)     
    { (v ? otherFlags_ |= VALIDATE_VIEWS_AT_OPEN_TIME :
       otherFlags_ &= ~VALIDATE_VIEWS_AT_OPEN_TIME); }
  
    void setValidateNumIndexesAtOpenTime(NABoolean v)     
    { (v ? otherFlags_ |= VALIDATE_NUM_INDEXES_AT_OPEN_TIME :
       otherFlags_ &= ~VALIDATE_NUM_INDEXES_AT_OPEN_TIME); }
  
    void setIsHbase(NABoolean v)     
    { (v ? otherFlags_ |= IS_HBASE : otherFlags_ &= ~IS_HBASE); }
  
    short maxNowaitRequests()                   { return maxNowaitRequests_; }
    void setMaxNowaitRequests(short numreq)   { maxNowaitRequests_ = numreq; }
    short numParts()                                     { return numParts_; }
    void setNumParts(short numparts)                 { numParts_ = numparts; }
  
    AccessMode accessMode()              { return (AccessMode)(accessMode_); }
    void setAccessMode(AccessMode am)                    { accessMode_ = am; }
    
    UInt32 getSelectAccess() const      { return accessFlags_.select_; }
    UInt32 getInsertAccess() const      { return accessFlags_.insert_; }
    UInt32 getUpdateAccess() const      { return accessFlags_.update_; }
    UInt32 getDeleteAccess() const      { return accessFlags_.delete_; }
    UInt32 getPrivAccess(PrivType which)
    {
      if (which == SELECT_PRIV)
        return getSelectAccess();
      else if (which == INSERT_PRIV)
        return getInsertAccess();
      else if (which == UPDATE_PRIV)
        return getUpdateAccess();
      else if (which == DELETE_PRIV)
        return getDeleteAccess();
      else
        return -1;
    }
  
    AccessFlags  getAccessFlags()  const      { return accessFlags_; }
  
    void setSelectAccess(UInt32 flag = 1)
                                      { accessFlags_.select_ = flag ? 1 : 0; }
    void setInsertAccess(UInt32 flag = 1)
                                      { accessFlags_.insert_ = flag ? 1 : 0; }
    void setUpdateAccess(UInt32 flag = 1)
                                      { accessFlags_.update_ = flag ? 1 : 0; }
    void setDeleteAccess(UInt32 flag = 1)
                                      { accessFlags_.delete_ = flag ? 1 : 0; }
    
    void clearAllAccessFlags()
    {
      accessFlags_.select_ = 0;
      accessFlags_.insert_ = 0;
      accessFlags_.update_ = 0;
      accessFlags_.delete_ = 0;
    }
  
    const char *ansiName()                  { return ansiName_.getPointer(); }
    char *nonConstAnsiName()                { return ansiName_.getPointer(); }
    void setAnsiName(char *name)                         { ansiName_ = name; }
    char *fileName()                        { return fileName_.getPointer(); }
    void setFileName(char *name)                         { fileName_ = name; }
    char *corrName()                        { return corrName_.getPointer(); }
    void setCorrName(char *name)                         { corrName_ = name; }
  
    
    char *getPartNameArray()  
             { return partNameArray_.getPointer();  }
    void setPartNameArray (char *buf)    { partNameArray_ = buf; }
  
    void setNumEntriesInPartNameArray (unsigned short numEntries) 
                                    { numPartsInPartNameArray_ = numEntries; }
  
    unsigned short getNumEntriesInPartNameArray (void)
                                          { return numPartsInPartNameArray_; }
    short getColumnListCount() const              { return columnListCount_; } 
    void setColumnListCount(short count)         { columnListCount_ = count; }
    void incColumnListCount()                          { columnListCount_++; }
    void decColumnListCount()                          { columnListCount_--; }
  
    // short *&getRefToColumnList()              { return updateColumnList_; }
    short *getColumnList()          { return updateColumnList_.getPointer(); }
    void setColumnList(short *colList)        { updateColumnList_ = colList; }
  
    // short &updateColumnList(short ix)     { return updateColumnList_[ix]; }
    short getUpdateColumn(short ix)     { return updateColumnList_[(Int32)ix]; }
    void setUpdateColumn(short ix, short col)
                                         { updateColumnList_[(Int32)ix] = col; }
  
    // short &updateColumnList(CollIndex ix) { return updateColumnList_[ix]; }
    short getUpdateColumn(CollIndex ix) { return updateColumnList_[(Int32)ix]; }
    void setUpdateColumn(CollIndex ix, short col)
                                         { updateColumnList_[(Int32)ix] = col; }
  
    // long &timeoutVal()                              { return timeoutVal_; }
    Lng32 getTimeoutVal()                               { return timeoutVal_; }
    void setTimeoutVal(Lng32 timeoutVal)          { timeoutVal_ = timeoutVal; }
  
    // short &priority()                                 { return priority_; }
    short getPriority()                                  { return priority_; }
    void setPriority(short priority)                 { priority_ = priority; }
  
    // timestamp value when table schema was modified 
    Int64 &redefTime()                                  { return redefTime_; }
    Int64 getRedefTime()                                { return redefTime_; }
    void setRedefTime(const Int64 &redefTime)      { redefTime_ = redefTime; }
   
    // security vector to monitor changes   
    Int32 getSecurityVector()                      { return securityVector_; }
    void setSecurityVector(const Int32 &secVec)  { securityVector_ = secVec; }
  
    // owner 
    Int16 getOwner()                                        { return owner_; }
    void setOwner(const Int16 &owner)                      { owner_ = owner; }
  
    Int16 getNumIndexes() {return numIndexes_;}
    void setNumIndexes(const Int16 numIndexes) {numIndexes_ = numIndexes;}
  
    // Utility Open Id
    Int64 getUtilityOpenId()                      { return utilityOpenId_; }
    void setUtilityOpenId(const Int64 &openId)    {utilityOpenId_ = openId;}
  
    void clearFiller()
    {
      memset(fillersSqlTableOpenInfo2_, 0, sizeof fillersSqlTableOpenInfo2_);
      memset(fillersSqlTableOpenInfo_,  0, sizeof fillersSqlTableOpenInfo_ );
    }
  
    Long pack(void *space)
    {
      ansiName_.pack(space);
      fileName_.pack(space);
      corrName_.pack(space);
      updateColumnList_.pack(space);
      partNameArray_.pack(space);
      return NAVersionedObject::pack(space);
    }
  
    Lng32 unpack(void *base, void * reallocator)
    {
      if ((otherFlags_ & FILLER_IS_INITED) == 0)
      {
        // This is a version-compatible way to fix a problem in plans 
        // written by the pre-R2 FCS compiler: the filler fields were not 
        // initialized to zeroes.  We only support plans from the R1.8 compiler,
        // so only offsets that were filler in R1.8 need to be repaired here.
        //
        numPartsInPartNameArray_ = 0;
        utilityOpenId_ = 0;
        partNameArray_ = (NABasicPtr) NULL ;
        clearFiller();
      }   
  
      if(updateColumnList_.unpack(base)) return -1;
      if(fileName_.unpack(base)) return -1;
      if(ansiName_.unpack(base)) return -1;
      if(corrName_.unpack(base)) return -1;
      if(partNameArray_.unpack(base)) return -1;
      return NAVersionedObject::unpack(base, reallocator);
    }
  
  private:
  
    enum OpenFlags 
    {
      SHARE_OPENS = 0x0001, EXECUTOR_OPEN = 0x0002,
      OPEN_ALL_PARTS = 0x0004, SQL_SECURED = 0x0008,
      PRIV_OPEN = 0x0010, LICENSED_PROC = 0x0020,     
      UTILITY_OPEN = 0x0040,
  
      // Normally, first open is always done on the root partition. This
      // could cause heavy traffic on the root datavol and result in it
      // running out of resources(error 35, 30).
      // If this flag is set, then open is done on one of the partitions
      // from the partNameArray, if this array was generated. 
      // This would distribute opens among multiple datavols.
      // See runtime code for the actual algorith used to pick a partition.
      DISTRIBUTE_OPENS = 0x0080,
  
      // if set, tables are not closed at the end of a query. This allows
      // the same open to be reused for the next query which accesses that
      // table.
      // If the table is shared opened by multiple openers from the same
      // process, then the share count is decremented until it reaches 1.
      // At that time, the last open is preserved so it could be reused.
      //
      // Tables are closed if the process is exited, or if user id changes.
      REUSE_OPENS = 0x0100,
  
      // if this flag is set, then we compare the compile TS against the
      // redef TS of the rfork.
      // This is to implement the feature of not blowing away opens of
      // running queries unless it is required. 
      // With this feature, catman changes the redef TS of the rfork for
      // the cases where running queries need not be disrupted. For ex, if
      // permissions are revoked. On the next execution of the query, executor
      // validates the compile timestamp against the TS of rfork and recompiles,
      // if rfork TS is greater.
      VALIDATE_RFORK_TS = 0x0200,
  
      // sets exclusion mode to ARK_DML_PROTECTED. This does a read protected
      // open which prevents any write access to the table.
      READ_PROTECTED_OPEN = 0x0400,
  
      // this flagis set when CQD USTAT_INSERT_TO_NONAUDITED_TABLE is DF_ON.
      // this tells the executor that inserting to a nonaudited table is ok
      // this causes the force open flag to be set for DP2.
      INSERT_TO_NONAUDITED_OPEN = 0x0800,
  
      // this flag is a temporary flag to tell the executor whether to keep 
      // current behavior as far as picking which partition of the table to 
      // open, or not.
      RANDOM_PARTARRAY_GENERATION = 0x1000,
      REUSE_OPENS_FOR_WRITE = 0x2000
    };
  
    /////////////////////////////////////////////////////////////////////
    // OtherFlags:
    //
    // SECURITY: this is set, if security check is to be done before
    //           opening the table to access data. If set, security
    //           check is done with a non-priv open, and if successful,
    //           the table is closed and reopened with priv open.
    /////////////////////////////////////////////////////////////////////
    enum OtherFlags
    {
      LOCATION       = 0x0001,
      IS_MX_VIEW     = 0x0002, 
      VALIDATE_TS    = 0x0004,
      NO_WAIT        = 0x0008,
      LOCK_WAIT      = 0x0010,
      SECURITY       = 0x0020, 
      AUDITED        = 0x0040,
      IS_MX_INDEX    = 0x0080,
      SPECIAL_TABLE =  0x0400, 
      IS_UDR_SURROGATE = 0x0800,
      SUBJECT_TABLE  =   0x01000, // triggers
      FILLER_IS_INITED = 0x2000,
      REVERSE_SCAN   = 0x4000,
      IS_NSA_OPERATION = 0x8000,
      VALIDATE_NUM_INDEXES_AT_OPEN_TIME = 0x10000,
      VALIDATE_VIEWS_AT_OPEN_TIME = 0x20000,
      IS_MX_METADATA_TABLE = 0x40000,
      INSERT_OF_UPDATE_CK = 0x80000,
      IS_HBASE                      = 0x100000
    };
  	
    AccessFlags accessFlags_;                                         // 00-03
    UInt32 openFlags_;                                                // 04-07
    UInt32 otherFlags_;                                               // 08-11
  
    Int16 maxNowaitRequests_;                                         // 12-13
  
    // number of horizontal partitions
    Int16 numParts_;                                                  // 14-15
    
    // physical file name and the ansi name of the table or view
    NABasicPtr ansiName_;                                             // 16-23
    NABasicPtr fileName_;                                             // 24-31
    NABasicPtr corrName_;                                             // 32-39
  
    Int16Ptr updateColumnList_;                                       // 40-47
    Int16 columnListCount_;                                           // 48-49
  
    Int16 accessMode_;                                                // 50-51
    Int16 priority_;                                                  // 52-53
  
    // if this is an sql/mp base table which has secondary indexes, then
    // the next field indicates the number of indexes.
    // This field is used at runtime to validate if a new index with 
    // NO INVALIDATE option was created at runtime. An index created with
    // NO INV option does not change the timestamp of the base table which
    // causes incorrect index maintanence to be done.
    // To validate that, we compare this field with the actual number of
    // indexes at open time, if there is no timestamp mismatch. 
    // If the number at runtime is greater than numIndexes_, then an index
    // was created with NO INV option.
    Int16 numIndexes_;                                                // 54-55
  
    // timestamp value when table schema was modified 
    Int64 redefTime_;                                                 // 56-63
  
    // timeout value used while accessing this table. 
    Int32 timeoutVal_;                                                // 64-67
  
    // securityVector_ and owner_ for use with UDRs
  
    // guardian security vector                          
    Int32 securityVector_;                                            // 68-71
  
    // owner
    Int16 owner_;                                                     // 72-73 
    Int16 numPartsInPartNameArray_;                                   // 74-75
    char fillersSqlTableOpenInfo2_[4];                                // 76-79
    // utility open id, if this open is part of a utility operation.
    Int64 utilityOpenId_;                                             // 80-87
    NABasicPtr partNameArray_;                                        // 88-95
    char fillersSqlTableOpenInfo_[16];                               // 96-111
  
  };
  #pragma warn(1506)   // warning elimination 
  
  // --------------------------------------------------------------------------
  // Template instantiation to produce a 64-bit pointer emulator class
  // for SqlTableOpenInfo
  // --------------------------------------------------------------------------
  typedef NAVersionedObjectPtrTempl<SqlTableOpenInfo> SqlTableOpenInfoPtr;
  
  // --------------------------------------------------------------------------
  // Template instantiation to produce a 64-bit pointer emulator class
  // for SqlTableOpenInfoPtr
  // --------------------------------------------------------------------------
  typedef
    NAVersionedObjectPtrArrayTempl<SqlTableOpenInfoPtr> SqlTableOpenInfoPtrPtr;
  
  
  #endif
  