http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/021ebd6c/core/sql/regress/seabase/EXPECTED002
----------------------------------------------------------------------
diff --git a/core/sql/regress/seabase/EXPECTED002 
b/core/sql/regress/seabase/EXPECTED002
index 83a8bb5..2888c5b 100644
--- a/core/sql/regress/seabase/EXPECTED002
+++ b/core/sql/regress/seabase/EXPECTED002
@@ -183,8 +183,9 @@ T002SCH.T002T2                                              
                 1
 T002SCH.T002T2                                                               0 
 ReadRequestsCount: 1           WriteRequestsCount: 1         
 T002SCH.SB_HIS                                                               0 
 ReadRequestsCount: 0           WriteRequestsCount: 0         
 T002SCH.T002T1                                                               0 
 ReadRequestsCount: 2           WriteRequestsCount: 1         
+T002SCH.SB_PER                                                               0 
 ReadRequestsCount: 0           WriteRequestsCount: 0         
 
---- 3 row(s) selected.
+--- 4 row(s) selected.
 >>
 >>select left(trim(schema_name) || '.' || trim(object_name), 14),
 +> sum(store_file_size), 
@@ -200,8 +201,9 @@ T002SCH.T002T1                                              
                 0
 T002SCH.T002T2                                                               0 
 ReadRequestsCount: 1           WriteRequestsCount: 1         
 T002SCH.SB_HIS                                                               0 
 ReadRequestsCount: 0           WriteRequestsCount: 0         
 T002SCH.T002T1                                                               0 
 ReadRequestsCount: 2           WriteRequestsCount: 1         
+T002SCH.SB_PER                                                               0 
 ReadRequestsCount: 0           WriteRequestsCount: 0         
 
---- 3 row(s) selected.
+--- 4 row(s) selected.
 >>
 >>get region stats for table t002t1;
 
@@ -446,7 +448,35 @@ Stats Details
 =============
 
   RegionNum:          1
-  RegionName:         
TRAFODION.T002SCH.SB_HISTOGRAM_INTERVALS/94b6ffefc5df9a62180e5a2401e18d9e
+  RegionName:         
TRAFODION.T002SCH.SB_HISTOGRAM_INTERVALS/72bc6242dfa139b77bd15125cf46593f
+  NumStores:          2
+  NumStoreFiles:      0
+  UncompressedSize:   0 (less than 1MB)
+  StoreFileSize:      0 (less than 1MB)
+  MemStoreSize:       0 (less than 1MB)
+  ReadRequestsCount:  0
+  WriteRequestsCount: 0
+
+
+Stats Summary
+=============
+
+  ObjectName:              TRAFODION.T002SCH.SB_PERSISTENT_SAMPLES
+  NumRegions:              1
+  RegionsLocation:         /hbase/data/default
+  TotalNumStores:          2
+  TotalNumStoreFiles:      0
+  TotalUncompressedSize:   0
+  TotalStoreFileSize:      0
+  TotalMemStoreSize:       0
+  TotalReadRequestsCount:  0
+  TotalWriteRequestsCount: 0
+
+Stats Details
+=============
+
+  RegionNum:          1
+  RegionName:         
TRAFODION.T002SCH.SB_PERSISTENT_SAMPLES/121ea772487c23e7f165e29db4647fd4
   NumStores:          2
   NumStoreFiles:      0
   UncompressedSize:   0 (less than 1MB)
@@ -733,6 +763,20 @@ Stats Summary
 Stats Summary
 =============
 
+  ObjectName:              TRAFODION.T002SCH.SB_PERSISTENT_SAMPLES
+  NumRegions:              1
+  RegionsLocation:         /hbase/data/default
+  TotalNumStores:          2
+  TotalNumStoreFiles:      0
+  TotalUncompressedSize:   0
+  TotalStoreFileSize:      0
+  TotalMemStoreSize:       0
+  TotalReadRequestsCount:  0
+  TotalWriteRequestsCount: 0
+
+Stats Summary
+=============
+
   ObjectName:              TRAFODION.T002SCH.T002T1
   NumRegions:              1
   RegionsLocation:         /hbase/data/default

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/021ebd6c/core/sql/regress/seabase/EXPECTED012
----------------------------------------------------------------------
diff --git a/core/sql/regress/seabase/EXPECTED012 
b/core/sql/regress/seabase/EXPECTED012
index 4db69b5..e43f13c 100644
--- a/core/sql/regress/seabase/EXPECTED012
+++ b/core/sql/regress/seabase/EXPECTED012
@@ -284,6 +284,7 @@ Tables in Schema TRAFODION.ZSCHEMA
 
 SB_HISTOGRAMS
 SB_HISTOGRAM_INTERVALS
+SB_PERSISTENT_SAMPLES
 T012T11
 T012T12
 

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/021ebd6c/core/sql/regress/seabase/EXPECTED026
----------------------------------------------------------------------
diff --git a/core/sql/regress/seabase/EXPECTED026 
b/core/sql/regress/seabase/EXPECTED026
index d7b96bc..4151c08 100644
--- a/core/sql/regress/seabase/EXPECTED026
+++ b/core/sql/regress/seabase/EXPECTED026
@@ -221,7 +221,7 @@
 >>delete from "_MD_".objects where catalog_name = 'TRAFODION' and
 +>     schema_name = 'SCH026' and object_type = 'PK';
 
---- 6 row(s) deleted.
+--- 7 row(s) deleted.
 >>cqd hide_indexes reset;
 
 --- SQL operation complete.
@@ -292,7 +292,7 @@ Metadata Cleanup: started, check only
   End:   Cleanup Orphan Hbase Entries (0 entries found)
 
   Start: Cleanup Inconsistent Objects Entries
-  End:   Cleanup Inconsistent Objects Entries (6 entries found)
+  End:   Cleanup Inconsistent Objects Entries (7 entries found)
 
   Start: Cleanup Inconsistent Views Entries
   End:   Cleanup Inconsistent Views Entries (0 entries found)
@@ -327,7 +327,7 @@ Metadata Cleanup: started, check only
   End:   Cleanup Orphan Hbase Entries (1 entry found)
 
   Start: Cleanup Inconsistent Objects Entries
-  End:   Cleanup Inconsistent Objects Entries (8 entries found)
+  End:   Cleanup Inconsistent Objects Entries (9 entries found)
 
   Start: Cleanup Inconsistent Views Entries
   End:   Cleanup Inconsistent Views Entries (0 entries found)
@@ -353,10 +353,11 @@ Metadata Cleanup: started, check only
     Entry #3(OBJECT): TRAFODION.SCH026.T026T2_498588266_9589
     Entry #4(OBJECT): TRAFODION.SCH026.SB_HISTOGRAMS_PK
     Entry #5(OBJECT): TRAFODION.SCH026.SB_HISTOGRAM_INTERVALS_PK
-    Entry #6(OBJECT): TRAFODION.SCH026.LOBMD_00958229992622_255194156_9672
-    Entry #7(OBJECT): TRAFODION.SCH026.LOBDescChunks_009582_898194156_9672
-    Entry #8(UID):    958229992622171473
-  End:   Cleanup Inconsistent Objects Entries (8 entries found)
+    Entry #6(OBJECT): TRAFODION.SCH026.SB_PERSISTENT_SAMPLES_PK
+    Entry #7(OBJECT): TRAFODION.SCH026.LOBMD_03901336551423_331332878_4561
+    Entry #8(OBJECT): TRAFODION.SCH026.LOBDescChunks_039013_645332878_4561
+    Entry #9(UID):    3901336551423203710
+  End:   Cleanup Inconsistent Objects Entries (9 entries found)
 
   Start: Cleanup Inconsistent Views Entries
   End:   Cleanup Inconsistent Views Entries (0 entries found)
@@ -382,10 +383,11 @@ Metadata Cleanup: started
     Entry #3(OBJECT): TRAFODION.SCH026.T026T2_498588266_9589
     Entry #4(OBJECT): TRAFODION.SCH026.SB_HISTOGRAMS_PK
     Entry #5(OBJECT): TRAFODION.SCH026.SB_HISTOGRAM_INTERVALS_PK
-    Entry #6(OBJECT): TRAFODION.SCH026.LOBMD_00958229992622_255194156_9672
-    Entry #7(OBJECT): TRAFODION.SCH026.LOBDescChunks_009582_898194156_9672
-    Entry #8(UID):    958229992622171473
-  End:   Cleanup Inconsistent Objects Entries (8 entries cleaned up)
+    Entry #6(OBJECT): TRAFODION.SCH026.SB_PERSISTENT_SAMPLES_PK
+    Entry #7(OBJECT): TRAFODION.SCH026.LOBMD_03901336551423_331332878_4561
+    Entry #8(OBJECT): TRAFODION.SCH026.LOBDescChunks_039013_645332878_4561
+    Entry #9(UID):    3901336551423203710
+  End:   Cleanup Inconsistent Objects Entries (9 entries cleaned up)
 
   Start: Cleanup Inconsistent Views Entries
   End:   Cleanup Inconsistent Views Entries (0 entries cleaned up)

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/021ebd6c/core/sql/regress/tools/runregr_compGeneral.ksh
----------------------------------------------------------------------
diff --git a/core/sql/regress/tools/runregr_compGeneral.ksh 
b/core/sql/regress/tools/runregr_compGeneral.ksh
index e7e87d7..e100654 100755
--- a/core/sql/regress/tools/runregr_compGeneral.ksh
+++ b/core/sql/regress/tools/runregr_compGeneral.ksh
@@ -226,7 +226,7 @@ fi
 
 # sbtestfiles contains the list of tests to be run in seabase mode
 if [ "$seabase" -ne 0 ]; then
-  sbtestfiles="TEST001 TEST004 TEST005 TEST006 TEST011 TEST012 TEST013 TEST015 
TEST071 TEST042 TESTTOK TESTTOK2 TEST062"
+  sbtestfiles="TEST001 TEST004 TEST005 TEST006 TEST011 TEST012 TEST013 TEST015 
TEST023 TEST071 TEST042 TEST043 TESTTOK TESTTOK2 TEST062"
   sbprettyfiles=
   for i in $prettyfiles; do
     for j in $sbtestfiles; do

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/021ebd6c/core/sql/sqlcomp/CmpSeabaseDDLcleanup.cpp
----------------------------------------------------------------------
diff --git a/core/sql/sqlcomp/CmpSeabaseDDLcleanup.cpp 
b/core/sql/sqlcomp/CmpSeabaseDDLcleanup.cpp
index 6079782..a2afca3 100644
--- a/core/sql/sqlcomp/CmpSeabaseDDLcleanup.cpp
+++ b/core/sql/sqlcomp/CmpSeabaseDDLcleanup.cpp
@@ -234,7 +234,9 @@ short CmpSeabaseMDcleanup::validateInputValues(
                                     inObjType.data(),
                                     outObjType, objectOwner_);
       if ((objUID_ == -1) && // not found
-          (inObjType != COM_UNKNOWN_OBJECT_LIT)) // type explicitly specified
+          (inObjType != COM_UNKNOWN_OBJECT_LIT &&
+           inObjType != COM_PRIVATE_SCHEMA_OBJECT_LIT &&
+           inObjType != COM_SHARED_SCHEMA_OBJECT_LIT)) // type explicitly 
specified
         {
           // check if there is another object type with the same name.
           objUID_ = getCleanupObjectUID(cliInterface,
@@ -941,6 +943,7 @@ void 
CmpSeabaseMDcleanup::cleanupSchemaObjects(ExeCliInterface *cliInterface)
                FALSE, FALSE
            );
       }
+      schObjList->advance();
    }
 
   // Now drop remaining objects

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/021ebd6c/core/sql/sqlcomp/CmpSeabaseDDLcommon.cpp
----------------------------------------------------------------------
diff --git a/core/sql/sqlcomp/CmpSeabaseDDLcommon.cpp 
b/core/sql/sqlcomp/CmpSeabaseDDLcommon.cpp
index a3d834c..1a38b9c 100644
--- a/core/sql/sqlcomp/CmpSeabaseDDLcommon.cpp
+++ b/core/sql/sqlcomp/CmpSeabaseDDLcommon.cpp
@@ -949,7 +949,9 @@ ComBoolean CmpSeabaseDDL::isHbase(const ComObjectName &name)
 bool CmpSeabaseDDL::isHistogramTable(const NAString &name) 
 {
 
-  if (name == HBASE_HIST_NAME || name == HBASE_HISTINT_NAME)
+  if (name == HBASE_HIST_NAME || 
+      name == HBASE_HISTINT_NAME ||
+      name == HBASE_PERS_SAMP_NAME )
     return true;
     
   return false;
@@ -6828,32 +6830,73 @@ short CmpSeabaseDDL::dropSeabaseStats(ExeCliInterface 
*cliInterface,
 {
   Lng32 cliRC = 0;
   char buf[4000];
+
+  // delete any histogram statistics
   
   str_sprintf(buf, "delete from %s.\"%s\".%s where table_uid = %Ld",
               catName, schName, HBASE_HIST_NAME, tableUID);
 
   cliRC = cliInterface->executeImmediate(buf);
-  // if histogram table does not exist, return now without error
-  // (could return on cliRC == 100, but that seems to happen
-  // even when we deleted some histogram rows)
-  if (cliRC == -4082)
-    return 0;
 
-  if (cliRC < 0)
+  // If the histogram table does not exist, don't bother checking
+  // the histogram intervals table. 
+  //
+  // Note: cliRC == 100 happens when we delete some histogram rows
+  // and also when there are no histogram rows to delete, so we
+  // can't decide based on that.
+ 
+  if (cliRC != -4082)
     {
-      cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
-      return -1;
+
+      if (cliRC < 0)
+        {
+          cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
+          return -1;
+        }
+
+      str_sprintf(buf, "delete from %s.\"%s\".%s where table_uid = %Ld",
+                  catName, schName, HBASE_HISTINT_NAME, tableUID);
+      cliRC = cliInterface->executeImmediate(buf);
+
+      if (cliRC < 0)
+        {
+          cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
+          return -1;
+        }
     }
 
-  str_sprintf(buf, "delete from %s.\"%s\".%s where table_uid = %Ld",
-              catName, schName, HBASE_HISTINT_NAME, tableUID);
-  cliRC = cliInterface->executeImmediate(buf);
+  // Drop any persistent sample tables also. (It is possible that these
+  // might exist even if the histograms table does not exist.)
 
-  if (cliRC < 0)
+  // Delete the row in the persistent_samples table if one exists
+
+  str_sprintf(buf, "select translate(sample_name using ucs2toutf8) from "
+                   " (delete from %s.\"%s\".%s where table_uid = %Ld) as t",
+              catName, schName, HBASE_PERS_SAMP_NAME, tableUID);
+    
+  Lng32 len = 0;
+  char sampleTableName[1000];
+
+  cliRC = cliInterface->executeImmediate(buf, (char*)&sampleTableName, &len, 
NULL);
+  if (cliRC == -4082)  // if persistent_samples table does not exist
+    cliRC = 0;         // then there isn't a persistent sample table
+  else if (cliRC < 0)
     {
       cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
       return -1;
     }
+  else if ((len > 0) && (sampleTableName[0])) // if we got a sample table name 
back
+    {
+      // try to drop the sample table
+      sampleTableName[len] = '\0';
+      str_sprintf(buf, "drop table %s", sampleTableName);
+      cliRC = cliInterface->executeImmediate(buf);
+      if (cliRC < 0)
+        {
+          cliInterface->retrieveSQLDiagnostics(CmpCommon::diags());
+          return -1;
+        }
+    }
 
   return 0;
 }

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/021ebd6c/core/sql/sqlcomp/CmpSeabaseDDLmd.h
----------------------------------------------------------------------
diff --git a/core/sql/sqlcomp/CmpSeabaseDDLmd.h 
b/core/sql/sqlcomp/CmpSeabaseDDLmd.h
index e9d6a6f..add89e1 100644
--- a/core/sql/sqlcomp/CmpSeabaseDDLmd.h
+++ b/core/sql/sqlcomp/CmpSeabaseDDLmd.h
@@ -539,6 +539,27 @@ static const QString seabaseHistogramIntervalsDDL[] =
   {" ; "}
 };
 
+static const QString seabasePersistentSamplesDDL[] = 
+{
+  {" create table "HBASE_PERS_SAMP_NAME" "},
+  {" ( "},
+  {"   TABLE_UID LARGEINT NOT NULL NOT SERIALIZED, "},
+  {"   REQUESTED_SAMPLE_ROWS LARGEINT NOT NULL NOT SERIALIZED, "},
+  {"   ACTUAL_SAMPLE_ROWS LARGEINT NOT NULL NOT SERIALIZED, "},
+  {"   SAMPLING_RATIO DOUBLE PRECISION NOT NULL NOT SERIALIZED, "},
+  {"   CREATE_TIME TIMESTAMP(0) NOT NULL NOT SERIALIZED, "},
+  {"   REASON CHAR(1) CHARACTER SET UCS2 NOT NULL NOT SERIALIZED, "},
+  {"   SAMPLE_NAME VARCHAR(250) CHARACTER SET UCS2 NOT NULL NOT SERIALIZED, "},
+  {"   LAST_WHERE_PREDICATE VARCHAR(250) CHARACTER SET UCS2 NOT NULL  NOT 
SERIALIZED, "},
+  {"   UPDATE_START_TIME TIMESTAMP(0) NOT NULL  NOT SERIALIZED, "},
+  {"   UPDATER_INFO VARCHAR(128) CHARACTER SET ISO88591 NOT NULL  NOT 
SERIALIZED, "},
+  {"   V1 VARCHAR(250) CHARACTER SET UCS2 NOT NULL  NOT SERIALIZED, "},
+  {"   V2 VARCHAR(250) CHARACTER SET UCS2 NOT NULL  NOT SERIALIZED, "},
+  {"   constraint "HBASE_PERS_SAMP_PK" primary key (TABLE_UID) "},
+  {" ) "},
+  {" ; "}
+};
+
 struct MDTableInfo
 {
   // name of the new MD table.
@@ -646,6 +667,10 @@ static const MDTableInfo allMDHistInfo[] = {
 
   {HBASE_HISTINT_NAME,
    seabaseHistogramIntervalsDDL, sizeof(seabaseHistogramIntervalsDDL),
+   NULL, 0, FALSE},
+
+  {HBASE_PERS_SAMP_NAME,
+   seabasePersistentSamplesDDL, sizeof(seabasePersistentSamplesDDL),
    NULL, 0, FALSE}
 };
 

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/021ebd6c/core/sql/sqlcomp/CmpSeabaseDDLtable.cpp
----------------------------------------------------------------------
diff --git a/core/sql/sqlcomp/CmpSeabaseDDLtable.cpp 
b/core/sql/sqlcomp/CmpSeabaseDDLtable.cpp
index 988d382..1d825dc 100644
--- a/core/sql/sqlcomp/CmpSeabaseDDLtable.cpp
+++ b/core/sql/sqlcomp/CmpSeabaseDDLtable.cpp
@@ -3661,13 +3661,17 @@ short CmpSeabaseDDL::dropSeabaseTable2(
     }
 
   // drop SB_HISTOGRAMS and SB_HISTOGRAM_INTERVALS entries, if any
-  // if the table that we are dropping itself is not a SB_HISTOGRAMS or 
SB_HISTOGRAM_INTERVALS table
+  // if the table that we are dropping itself is not a SB_HISTOGRAMS 
+  // or SB_HISTOGRAM_INTERVALS table or sampling tables
   // TBD: need to change once we start updating statistics for external
   // tables
   if (! (tableName.isExternalHive() || tableName.isExternalHbase()) )
     {
       if (objectNamePart != "SB_HISTOGRAMS" && 
-          objectNamePart != "SB_HISTOGRAM_INTERVALS")
+          objectNamePart != "SB_HISTOGRAM_INTERVALS" &&
+          objectNamePart != "SB_PERSISTENT_SAMPLES" &&
+          strncmp(objectNamePart.data(),"TRAF_SAMPLE_",sizeof("TRAF_SAMPLE_")) 
!= 0)
+          
       {
         if (dropSeabaseStats(cliInterface,
                              catalogNamePart.data(),

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/021ebd6c/core/sql/ustat/hs_auto.h
----------------------------------------------------------------------
diff --git a/core/sql/ustat/hs_auto.h b/core/sql/ustat/hs_auto.h
index 3214545..5e642f6 100644
--- a/core/sql/ustat/hs_auto.h
+++ b/core/sql/ustat/hs_auto.h
@@ -37,6 +37,8 @@
  *****************************************************************************
  */
 
+#include "hs_log.h"
+
 #define NANewArray        NewArray
 
 // -----------------------------------------------------------------------
@@ -55,7 +57,7 @@ public:
     : ptr_(source)
     {
       source = new(STMTHEAP) T[len];
-      assert(source != NULL);
+      HS_ASSERT(source != NULL);
     }
 
   ~NewArray()

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/021ebd6c/core/sql/ustat/hs_cli.cpp
----------------------------------------------------------------------
diff --git a/core/sql/ustat/hs_cli.cpp b/core/sql/ustat/hs_cli.cpp
index 9e19a63..cc16591 100644
--- a/core/sql/ustat/hs_cli.cpp
+++ b/core/sql/ustat/hs_cli.cpp
@@ -122,28 +122,29 @@ private:
 //          doPrintPlan = if true, the plan for the query will be
 //                printed after the statement is prepared but before
 //                execution; if false we do a single CLI ExecDirect call
+//          checkForMdam = if true, do a query on the Explain virtual table
+//                to see if MDAM was used in the query being executed, and
+//                display the result in the ulog.
 // -----------------------------------------------------------------------
 
 Lng32 HSExecDirect( SQLSTMT_ID * stmt
                   , SQLDESC_ID * srcDesc
                   , NABoolean doPrintPlan
+                  , NABoolean checkForMdam
                   )
 {
   Lng32 retcode = 0;
 
-  if (doPrintPlan)
+  HSLogMan *LM = HSLogMan::Instance();
+  if ((doPrintPlan || checkForMdam) && LM->LogNeeded())
     {
       retcode = SQL_EXEC_Prepare(stmt, srcDesc);
       if (retcode >= 0) // ignore warnings
         {
           if (doPrintPlan)
-            {
-              HSLogMan *LM = HSLogMan::Instance();
-              if (LM->LogNeeded()) 
-                {
-                  printPlan(stmt);
-                }
-            } 
+            printPlan(stmt);
+          if (checkForMdam)
+            checkMdam(stmt);
           retcode = SQL_EXEC_ExecFetch(stmt,0,0);
         }
     }
@@ -173,6 +174,8 @@ Lng32 HSExecDirect( SQLSTMT_ID * stmt
 //                that should not disrupt execution, such as "schema already
 //                exists" when executing a Create Schema statement. 0 indicates
 //                there is no such expected error.
+//          checkMdam = if TRUE, determine whether the query uses MDAM, and
+//                include this information in the ulog.
 // -----------------------------------------------------------------------
 Lng32 HSFuncExecQuery( const char *dml
                     , short sqlcode
@@ -182,6 +185,7 @@ Lng32 HSFuncExecQuery( const char *dml
                     , const HSTableDef *tabDef
                     , NABoolean doRetry
                     , short errorToIgnore
+                    , NABoolean checkMdam
                     )
 {
   HSLogMan *LM = HSLogMan::Instance();
@@ -272,7 +276,7 @@ Lng32 HSFuncExecQuery( const char *dml
   if (!doRetry)
   {
     // execute immediate this statement
-    retcode = HSExecDirect(&stmt, &srcDesc, srcTabRowCount != 0);
+    retcode = HSExecDirect(&stmt, &srcDesc, srcTabRowCount != 0, checkMdam);
     // If retcode is > 0 or sqlcode is HS_WARNING, then set to 0 (no 
error/ignore).
     if (retcode >= 0) retcode = 0;
     // If sqlcode is HS_WARNING, then this means failures should be returned as
@@ -303,7 +307,7 @@ Lng32 HSFuncExecQuery( const char *dml
       }
 
       // execute immediate this statement
-      retcode = HSExecDirect(&stmt, &srcDesc, srcTabRowCount != 0);
+      retcode = HSExecDirect(&stmt, &srcDesc, srcTabRowCount != 0, checkMdam);
 
       // filter retcode for HSHandleError
       HSFilterWarning(retcode);
@@ -431,7 +435,7 @@ Lng32 CreateHistTables (const HSGlobalsClass* hsGlobal)
     // do NOT check volatile tables
     if (hsGlobal->objDef->isVolatile()) return retcode;
 
-    LM->StartTimer("Table creation");
+    LM->StartTimer("Create histogram tables");
     NAString tableNotCreated;
 
     // Call createHistogramTables to create any table that does not yet exist.
@@ -452,6 +456,25 @@ Lng32 CreateHistTables (const HSGlobalsClass* hsGlobal)
     return retcode;
  }
 
+Lng32 CreateSeabasePersSamples(const HSGlobalsClass* hsGlobal)
+  {
+    HSLogMan *LM = HSLogMan::Instance();
+    Lng32 retcode = 0;
+    ComObjectName tableName(hsGlobal->hsperssamp_table->data());
+    HSSqTableDef sampleDef(tableName, ANSI_TABLE);
+    if (!sampleDef.objExists()) //DROP existing sample table
+    {
+      if (LM->LogNeeded())
+        {
+          snprintf(LM->msg, sizeof(LM->msg), "Creating %s table for schema %s 
on demand.",
+                           HBASE_PERS_SAMP_NAME, hsGlobal->catSch->data());
+          LM->Log(LM->msg);
+        }
+
+      retcode = CreateHistTables(hsGlobal);
+    }
+    return retcode;
+}
 
 /***********************************************/
 /* METHOD:  HSSample create() member function  */
@@ -461,27 +484,11 @@ Lng32 CreateHistTables (const HSGlobalsClass* hsGlobal)
 /* RETCODE:  0 - successful                    */
 /*           non-zero otherwise                */
 /***********************************************/
-Lng32 HSSample::create(NABoolean unpartitioned, NABoolean isPersSample,
-                       NABoolean createDandI)
+Lng32 HSSample::create(NABoolean unpartitioned, NABoolean isPersSample)
   {
-      makeTableName(isPersSample); // assigns 'sampleTable' name for MX/MP.
-      Lng32 retcode = 0;
-      retcode = create(sampleTable, unpartitioned, isPersSample);
-
-      if ( !retcode && createDandI ) {
-         NAString tableD(sampleTable);
-         tableD.append("_D");
-
-         //retcode = create(tableD, unpartitioned, isPersSample);
-         //HSHandleError(retcode);
-
-         // The temp. table for sample I is created in ::generateSampleI() on 
demand.
-         // Otherwise, we end up with 8102 error (rows duplicated) and very 
slow
-         // performance.
-         //NAString tableI(sampleTable);
-         //tableI.append("_I");
-         //retcode = create(tableI, unpartitioned, isPersSample);
-      }
+    makeTableName(isPersSample); // assigns 'sampleTable' name for MX/MP.
+    Lng32 retcode = 0;
+    retcode = create(sampleTable, unpartitioned, isPersSample);
 
     return retcode;
   }
@@ -524,12 +531,14 @@ Lng32 HSSample::create(NAString& tblName, NABoolean 
unpartitioned, NABoolean isP
            tableOptions = " WITH PARTITIONS";
         // If a transaction is running, the table needs to be created as 
audited.
         // Otherwise, create table as non-audited.
+        /* TEMPTEMP. Dave need to validate this change.
         if (TM->InTransaction())
           tableOptions += " ATTRIBUTE AUDIT";
         else
           tableOptions += " ATTRIBUTE NO AUDIT";
 
         tableOptions += getTempTablePartitionInfo(unpartitioned, isPersSample);
+        */
 
         ddl  = "CREATE TABLE ";
         ddl += tempTabName;
@@ -795,13 +804,6 @@ Lng32 HSSample::dropSample(NAString& sampTblName, 
HSTableDef *sourceTblDef)
       LM->Log("\tDROP SAMPLE TABLE");
 
       tempTabName = sampTblName;
-      // LCOV_EXCL_START :nsk
-      if (sourceTblDef->getObjectFormat() == SQLMP)
-      {
-        ComMPLoc tempObj(tempTabName, ComMPLoc::FILE);
-        tempTabName = tempObj.getMPName();
-      }
-      // LCOV_EXCL_STOP
 
       // If the table is not volatile, make the sample table 'droppable', 
except
       // in the case of Trafodion, which does not support this Alter statement.
@@ -1100,7 +1102,7 @@ Lng32 HSTranMan::Rollback()
             if (extTrans_)
               LM->Log("ROBACKWORK(external transaction being used)");
             else
-              LM->Log("ROBACKWORK(no running traction)");
+              LM->Log("ROBACKWORK(no running transaction)");
           }
       }
     return retcode_;
@@ -1239,84 +1241,96 @@ Lng32 HSTranController::lockTable(const char* 
tableName, NABoolean exclusive)
 /*           one instance of this class.                                     */
 /*****************************************************************************/
 THREAD_P HSPersSamples* HSPersSamples::instance_ = 0;
-THREAD_P NAList<NAString>* HSPersSamples::persSampleTablesList_ = NULL;
-THREAD_P NAString *HSPersSamples::catalog_ = NULL;
-THREAD_P NAString *HSPersSamples::schema_ = NULL;
 
-HSPersSamples::HSPersSamples()
+
+HSPersSamples::HSPersSamples(const NAString & catalog, const NAString & 
schema) 
+: catalog_(new (CTXTHEAP) NAString(catalog)), 
+  schema_(new (CTXTHEAP) NAString(schema)),
+  triedCreatingSBPersistentSamples_(false)
   {}
-/***********************************************/
-/* METHOD:  Instance()                         */
-/* PURPOSE: Returns the instance of the class  */
-/*          and searches for or creates        */
-/*          PERSISTENT_SAMPLES table (list).   */
-/*          For every catalog for which a      */
-/*          PERSISTENT_SAMPLES table is known  */
-/*          to exist, the catalog name is added*/
-/*          to the 'persSampleTablesList'.     */
-/* RETCODE: 0 if no errors.                    */
-/*          non-zero otherwise.                */
-/* INPUT:   'catalog', the catalog of the table*/
-/*          for which a sample is created.     */
-/*          'createTable', if TRUE, create the */
-/*          PERSISTENT_SAMPLES table for this  */
-/*          catalog if it doesn't exist.       */
-/* NOTES:   We need to instantiate using the   */
-/*          contextHeap because we need this   */
-/*          class to stay around through       */
-/*          multiple statements.               */
-/*                                             */
-/***********************************************/
+
+HSPersSamples::~HSPersSamples()
+  {
+    delete catalog_;
+    delete schema_;
+  }
+
+void HSPersSamples::setCatalogSchema(const NAString &catalog,
+                                     const NAString &schema)
+  {
+    if ((schema != *schema_) || (catalog != *catalog_))
+      {
+        *catalog_ = catalog;
+        *schema_ = schema;
+        triedCreatingSBPersistentSamples_ = false; // will try again on a new 
schema
+      }
+  }
+
+//
+// METHOD:  Instance()
+// PURPOSE: Returns the instance of the class  */
+//          and searches for or creates        */
+//          SB_PERSISTENT_SAMPLES table (list).   */
+//          For every catalog for which a      */
+//          SB_PERSISTENT_SAMPLES table is known  */
+//          to exist, the catalog name is added*/
+//          to the 'persSampleTablesList'.     */
+// RETCODE: 0 if no errors.                    */
+//          non-zero otherwise.                */
+// INPUT:   'catalog', the catalog of the table*/
+//          for which a sample is created.     */
+//          'createTable', if TRUE, create the */
+//          SB_PERSISTENT_SAMPLES table for this  */
+//          catalog if it doesn't exist.       */
+// NOTES:   We need to instantiate using the   */
+//          contextHeap because we need this   */
+//          class to stay around through       */
+//          multiple statements.
+//
 HSPersSamples* HSPersSamples::Instance(const NAString &catalog,
-                                       NABoolean createTable)
+                                       const NAString &schema)
   {
     Lng32 retcode = 0;
-    if (instance_ == 0)
-      instance_ = new (CTXTHEAP) HSPersSamples;
+    HSGlobalsClass *hs_globals = GetHSContext();
 
-    if (persSampleTablesList_ == 0)
-       persSampleTablesList_ = new(CTXTHEAP) NAList<NAString>;
-    if (catalog_ == 0)
-       catalog_ = new (CTXTHEAP) NAString("");
-    if (schema_ == 0)
-       schema_  = new (CTXTHEAP) NAString("");
+    if (instance_ == 0)
+      instance_ = new (CTXTHEAP) HSPersSamples(catalog,schema);
+    else
+      {
+        instance_->setCatalogSchema(catalog,schema);
+      }
 
-    // Search for an instance of catalog in memory resident list.
     if (HSGlobalsClass::isHiveCat(catalog))
       {
-        *catalog_ = HIVE_STATS_CATALOG;
-        *schema_  = HIVE_STATS_SCHEMA;
+        NAString hiveStatsCatalog(HIVE_STATS_CATALOG);
+        NAString hiveStatsSchema(HIVE_STATS_SCHEMA_NO_QUOTES);
+        instance_->setCatalogSchema(hiveStatsCatalog,hiveStatsSchema);
       }
-    else if (HSGlobalsClass::isHbaseCat(catalog))
+    else if (HSGlobalsClass::isNativeHbaseCat(catalog))
       {
-       NAString sbCat = 
ActiveSchemaDB()->getDefaults().getValue(SEABASE_CATALOG);
-
-       //        *catalog_ = SEABASE_SYSTEM_CATALOG;
-        *catalog_ = sbCat;
-        *schema_  = SEABASE_SYSTEM_SCHEMA;
+        NAString hbaseStatsCatalog(HBASE_STATS_CATALOG);
+        NAString hbaseStatsSchema(HBASE_STATS_SCHEMA_NO_QUOTES);
+        instance_->setCatalogSchema(hbaseStatsCatalog,hbaseStatsSchema);
       }
-    else
+
+    // Create the SB_PERSISTENT_SAMPLES table if it does not already exist
+    // Do this at most once
+
+    if ((instance_) && (!instance_->triedCreatingSBPersistentSamples_))
       {
-        *catalog_ = catalog;
-        *schema_  = "PUBLIC_ACCESS_SCHEMA";
+        retcode = CreateSeabasePersSamples(hs_globals);
+        instance_->triedCreatingSBPersistentSamples_ = true;
       }
-    if (!(*persSampleTablesList_).contains(*catalog_))
-    {
-      *(CmpCommon::diags()) << DgSqlCode(-4222)
-                            << DgString0("Persistent Sample Table");
-      return 0;
-    }
 
     if (retcode) return 0;
     else         return instance_;
   }
+
 /***********************************************/
 /* METHOD:  find()                             */
-/* PURPOSE: finds a persistent sample table for*/
-/*          UID and sample size.  If a sample  */
-/*          is found that is 'obsolete', then  */
-/*          it will be removed and another will*/
-/*          be searched for.  If a persistent  */
+/* PURPOSE: finds a manual (i.e., not IUS)     */
+/*          persistent sample table for UID    */
+/*          and sample size. If a persistent   */
 /*          sample is found, the name will be  */
 /*          returned in 'table', or blank if   */
 /*          not.                               */
@@ -1335,63 +1349,69 @@ HSPersSamples* HSPersSamples::Instance(const NAString 
&catalog,
 Lng32 HSPersSamples::find(HSTableDef *objDef, Int64 &actualRows, NABoolean 
isEstimate,
                          Int64 &sampleRows, double allowedDiff, NAString 
&table)
   {
+    // Note: Earlier versions of this code supported multiple sample tables
+    // (with different sample ratios) for the same base table, which seems
+    // like overkill. So, in making this code work for Trafodion, we've made
+    // a simplifying assumption: Assume just one sample table per base table.
+    // (Indeed, we defined SB_PERSISTENT_SAMPLES to be keyed solely on the
+    // base table UID.)
+    //
+    // So, this method now ignores the actualRows, isEstimate, sampleRows and
+    // allowedDiff parameters. We can take them out later if this design
+    // decision becomes permanent.
+
     Lng32 retcode = 0;
     NABoolean removedObsolete=FALSE;
-    table="";
+    table="";  // in case no sample table is found
     NAWchar tempTabNameUCS2[408]; // first double byte is varchar length + a 
few extras NAWchars
     ComObjectName persSampTblObjName(*catalog_,
                                      *schema_,
-                                     "PERSISTENT_SAMPLES",
+                                     "SB_PERSISTENT_SAMPLES",
                                      COM_TABLE_NAME,
                                      ComAnsiNamePart::INTERNAL_FORMAT,
                                      STMTHEAP);
     NAString fromTable = persSampTblObjName.getExternalName();
-    double percent;
-    HSCliStatement::statementIndex del_stmt;
-    HSCliStatement::statementIndex sel_stmt;
-
-    // Create query to search for a matching persistent sample in
-    // PERSISTENT_SAMPLES table.  Persistent samples are matched
-    // by the requested sample rowcount, not the actual that was
-    // created, since the actual can vary due to VARCHARS, ...
-    // A persistent sample is matching if for the same source table
-    // and ABS(RQSTD_NUMROWS - 'sampleRows') <=
-    // ('allowedDiff' * 'sampleRows').  The query will return the
-    // persistent sample table name, sample row count, and sample %.
-    sel_stmt = HSCliStatement::CURSOR_PST;
-    del_stmt = HSCliStatement::DELETE_PST;
     Int64 uid = objDef->getObjectUID();
-    HSCliStatement cursorPST(sel_stmt,
-                             (char *)fromTable.data(),
-                             (char *)&uid,
-                             (char *)&sampleRows,
-                             (char *)&allowedDiff
-                             );
-    retcode = cursorPST.open();
-    HSHandleError(retcode);
+    char uidStr[30];
+    convertInt64ToAscii(uid,uidStr);
 
-    do
-    {
-      // sel_stmt.fetch() will set 'tempTabName' to a persistent table name,
-      // 'sampleRows' to the size, and 'percent' to the % of actual table if
-      // one is found.  Otherwise 'table' is set to "" and 'sampleRows' is not 
set.
-      retcode = cursorPST.fetch (3, (void *)&tempTabNameUCS2[0], (void 
*)&sampleRows,
-                                    (void *)&percent);
-      // Handle errors from fetch. If retcode is 100 (meaning no more data),
-      // then set retcode = 0.
-      if (retcode)
+    HSCursor findSampleTableCursor1(STMTHEAP,"findSampleTable1");
+
+    NAString query = "SELECT SAMPLE_NAME FROM ";
+    query += fromTable;
+    query += " WHERE TABLE_UID = ";
+    query += uidStr;
+    query += " AND REASON = 'M'";
+
+    retcode = findSampleTableCursor1.prepareQuery(query, 0, 4); // no input 
parms, 1 output col
+    HSLogError(retcode);
+
+    retcode = findSampleTableCursor1.open();
+    HSLogError(retcode);
+
+    // expect at most one row will match the condition because of one
+    // IUS sample table only assumption.
+
+    // sel_stmt.fetch() will set 'tempTabName' to a persistent table name,
+    // if one is found. 
+
+    retcode = findSampleTableCursor1.fetch (1, (void *)&tempTabNameUCS2[0]);
+
+    // Handle errors from fetch. If retcode is 100 (meaning no more data),
+    // then set retcode = 0.
+    if (retcode)
       {
         if (retcode != HS_EOF)
-        {
-          HSHandleError(retcode);
-        }
+          {
+            HSHandleError(retcode);
+          }
         else
-        {
-          retcode = 0;
-        }
-        break;
+          {
+            retcode = 0;
+          }
       }
-      else { // fetch() successful.
+    else 
+      { // fetch() successful.
         char tempTabNameUTF8[2*sizeof(tempTabNameUCS2)];
         char *dummyFirstUntranslatedChar;
         unsigned int outputDataLen;
@@ -1408,64 +1428,25 @@ Lng32 HSPersSamples::find(HSTableDef *objDef, Int64 
&actualRows, NABoolean isEst
         HS_ASSERT(rc == 0 && outputDataLen >=0 && outputDataLen < 
sizeof(tempTabNameUTF8));
         tempTabNameUTF8[outputDataLen] = 0;
         table = tempTabNameUTF8;
-
-        //if (/*!forIUS &&*/ table != "" && actualRows != -1  && isEstimate == 
FALSE &&
-        if ( table != "" && actualRows != -1  && isEstimate == FALSE &&
-            ((fabs((sampleRows*100)/percent - actualRows)/actualRows) >
-             (CmpCommon::getDefaultLong(USTAT_OBSOLETE_PERCENT_ROWCOUNT) / 
100.0f)))
-        {
-          // The peristent sample table is 'obsolete' - the base table has 
changed
-          // by more than USTAT_OBSOLETE_PERCENT_ROWCOUNT % rows since sample 
created.
-          HSTranMan *TM = HSTranMan::Instance();
-          TM->Begin("DROP PERSISTENT SAMPLE TABLE AND REMOVE FROM LIST VIA 
FIND.");
-          // Drop persistent sample table and remove from list.
-          NAString ddl  = "DROP TABLE " + table;
-
-          if (!objDef->isVolatile())
-          {
-            // alter the table to droppable before the drop
-            NAString alterdroppableStmt;
-            alterdroppableStmt = "ALTER TABLE ";
-            alterdroppableStmt += table ;
-            alterdroppableStmt += " DROPPABLE ";
-
-            HSFuncExecQuery(alterdroppableStmt, - UERR_INTERNAL_ERROR, NULL,
-                            HS_QUERY_ERROR, NULL, NULL, TRUE/*doRetry*/ );
-          }
-
-          HSFuncExecQuery(ddl, - UERR_INTERNAL_ERROR, NULL,
-                          HS_QUERY_ERROR, NULL, NULL, TRUE/*doRetry*/ );
-
-          // If cannot drop table, attempt to remove from list anyway.
-          HSCliStatement deletePST(del_stmt,
-                                   (char *)fromTable.data(),
-                                   (char *)table.data());
-          retcode = deletePST.execFetch("DELETE " + fromTable );
-          if (retcode) TM->Rollback();
-          else         retcode = TM->Commit();
-          if (!retcode) removedObsolete=TRUE;
-        }
-        else removedObsolete=FALSE;
-      }
-    } while (!retcode && removedObsolete);
+     }
 
     // Don't overwrite the return code if an error has occurred, but attempt to
     // close the cursor anyway (in case it was successfully opened).
     if (retcode < 0)
-      cursorPST.close();
+      findSampleTableCursor1.close();
     else
-      retcode = cursorPST.close();
-   return retcode;
+      retcode = findSampleTableCursor1.close();
+    return retcode;
   }
 
 /***********************************************/
 /* METHOD:  find()                             */
 /* PURPOSE: finds a persistent sample table for*/
-/*          specified reason code.If foundd,   */
+/*          specified reason code.If found,    */
 /*          the name will be returned in       */
 /*          'table', or blank if not.          */
 /* INPUT:   uid - source table UID.            */
-/*          reason - the reason code           */
+/*          reason - I incremental, M manual   */
 /* OUTPUT:  table - the name of a sample table */
 /*            found or "" if none found.       */
 /*            requestedRows: requested rows    */
@@ -1474,9 +1455,9 @@ Lng32 HSPersSamples::find(HSTableDef *objDef, Int64 
&actualRows, NABoolean isEst
 /* RETCODE: 0 if no error during search.       */
 /*          non-zero if error                  */
 /***********************************************/
-Lng32 HSPersSamples::find(HSTableDef *objDef, char reason, NAString &table,
-                          Int64 &requestedRows, Int64 &sampleRows,
-                          double &sampleRate)
+Lng32 HSPersSamples::find(HSTableDef *objDef, char reason,
+                          NAString &table, Int64 &requestedRows,
+                          Int64 &sampleRows, double &sampleRate)
   {
     Lng32 retcode = 0;
     NABoolean removedObsolete=FALSE;
@@ -1484,33 +1465,33 @@ Lng32 HSPersSamples::find(HSTableDef *objDef, char 
reason, NAString &table,
     NAWchar tempTabNameUCS2[408]; // first double byte is varchar length + a 
few extras NAWchars
     ComObjectName persSampTblObjName(*catalog_,
                                      *schema_,
-                                     "PERSISTENT_SAMPLES",
+                                     "SB_PERSISTENT_SAMPLES",
                                      COM_TABLE_NAME,
                                      ComAnsiNamePart::INTERNAL_FORMAT,
                                      STMTHEAP);
     NAString fromTable = persSampTblObjName.getExternalName();
-    //double percent; //@ZXunref
-    //HSCliStatement::statementIndex del_stmt; //@ZXunref
-    HSCliStatement::statementIndex sel_stmt;
+    Int64 uid = objDef->getObjectUID();
+    char uidStr[30];
+    convertInt64ToAscii(uid,uidStr);
 
     // Create query to search for a matching persistent sample in
-    // PERSISTENT_SAMPLES table.  Persistent samples are matched
-    // by the requested sample rowcount, not the actual that was
-    // created, since the actual can vary due to VARCHARS, ...
-    // A persistent sample is matching if for the same source table
-    // and T.REASON = reason_code
-    sel_stmt = HSCliStatement::CURSOR_PST_REASON_CODE;
-    Int64 uid = objDef->getObjectUID();
-    char reason_code = reason;
+    // SB_PERSISTENT_SAMPLES table.
 
-    // sampleRows and allowedDiff are not used
-    HSCliStatement cursorPST_reason_code(sel_stmt,
-                             (char *)fromTable.data(),
-                             (char *)&uid,
-                             (char *)&reason_code
-                   );
-    retcode = cursorPST_reason_code.open();
-    HSHandleError(retcode);
+    HSCursor findSampleTableCursor(STMTHEAP,"findSampleTable");
+
+    NAString query = "SELECT SAMPLE_NAME, REQUESTED_SAMPLE_ROWS, 
ACTUAL_SAMPLE_ROWS, SAMPLING_RATIO FROM ";
+    query += fromTable;
+    query += " WHERE TABLE_UID = ";
+    query += uidStr;
+    query += " AND REASON = '";
+    query += reason;
+    query += "'";
+
+    retcode = findSampleTableCursor.prepareQuery(query, 0, 4); // no input 
parms, 2 output cols
+    HSLogError(retcode);
+
+    retcode = findSampleTableCursor.open();
+    HSLogError(retcode);
 
     // expect at most one row will match the condition because of one
     // IUS sample table only assumption.
@@ -1521,7 +1502,7 @@ Lng32 HSPersSamples::find(HSTableDef *objDef, char 
reason, NAString &table,
       // is set to "" and requestdRows, sampleRows and sampleRate
       // are not set.
 
-      retcode = cursorPST_reason_code.fetch (4, (void *)&tempTabNameUCS2[0],
+      retcode = findSampleTableCursor.fetch (4, (void *)&tempTabNameUCS2[0],
                                                  (void *)&requestedRows,
                                                  (void *)&sampleRows,
                                                  (void *)&sampleRate
@@ -1563,48 +1544,53 @@ Lng32 HSPersSamples::find(HSTableDef *objDef, char 
reason, NAString &table,
     // Don't overwrite the return code if an error has occurred, but attempt to
     // close the cursor anyway (in case it was successfully opened).
     if (retcode < 0)
-      cursorPST_reason_code.close();
+      findSampleTableCursor.close();
     else
-      retcode = cursorPST_reason_code.close();
+      retcode = findSampleTableCursor.close();
    return retcode;
   }
 
 Lng32 HSPersSamples::removeSample(HSTableDef* tabDef, NAString& sampTblName,
-                                  NABoolean useTransaction, const char* 
txnLabel)
+                                  char reason, const char* txnLabel)
 {
   Lng32 retcode = 0;
   HSTranMan *TM = HSTranMan::Instance();
 
   if (sampTblName.length() > 0)
     {
-      if (useTransaction)
-        {
-          TM->Begin(txnLabel);
-        }
-
-      HSSample::dropSample(sampTblName, tabDef);
+      TM->Begin(txnLabel);
 
       // Delete row in persistent samples table regardless of whether sample
       // could be dropped.
       ComObjectName persSampTblObjName(*catalog_,
                                         *schema_,
-                                        "PERSISTENT_SAMPLES",
+                                        "SB_PERSISTENT_SAMPLES",
                                         COM_TABLE_NAME,
                                         ComAnsiNamePart::INTERNAL_FORMAT,
                                         STMTHEAP);
       NAString fromTable = persSampTblObjName.getExternalName();
-      HSCliStatement::statementIndex del_stmt = HSCliStatement::DELETE_PST;
-      HSCliStatement deletePST(del_stmt,
-                                (char*)fromTable.data(),
-                                (char*)sampTblName.data());
-      retcode = deletePST.execFetch("DELETE " + fromTable );
-      if (useTransaction)
-        {
-          if (retcode)
-            TM->Rollback();
-          else
-            TM->Commit();
-        }
+      Int64 objUID = tabDef->getObjectUID();
+
+      NAString dml((size_t)500/*allocate 500 bytes*/, STMTHEAP);
+      dml.append("DELETE FROM ");
+      dml += fromTable; // in UTF8
+      dml += " WHERE TABLE_UID = ";
+      dml += Int64ToNAString(objUID);
+      dml += " AND REASON = '";
+      dml += reason;
+      dml += "'";
+
+      retcode = HSFuncExecQuery(dml, - UERR_INTERNAL_ERROR, NULL,
+                                HS_QUERY_ERROR, NULL, NULL, TRUE/*doRetry*/ );
+      HSHandleError(retcode);
+
+      HSSample::dropSample(sampTblName, tabDef);
+
+      if (retcode)
+        TM->Rollback();
+      else
+        TM->Commit();
+
     }
 
   return retcode;
@@ -1618,7 +1604,7 @@ Lng32 HSPersSamples::removeSample(HSTableDef* tabDef, 
NAString& sampTblName,
 /*          can be determined from statistics.                  */
 /* INPUTS:  tabDef - a pointer to table struct.                 */
 /*          isEstimate - TRUE if 'actualRows' is est. on input. */
-/*          isManual   - sets REASON in PERSISTENT_SAMPLES.     */
+/*          isManual   - sets REASON in SB_PERSISTENT_SAMPLES.     */
 /* IN/OUTS: sampleRows - the desired size of sample on input,   */
 /*            actual sample size on output.                     */
 /*          actualRows - table size (possibly an est.) on input */
@@ -1644,20 +1630,19 @@ Lng32 HSPersSamples::createAndInsert(HSTableDef 
*tabDef, NAString &sampleName,
     if (!tabDef || tabDef->setHasSyskeyFlag() != 0) return -1;
       // Sets flag in tabDef indicating primary key is SYSKEY.
 
-    // Drop the prior IUS persistent sample table if it exists, and remove
-    // the corresponding row from the PERSISTENT_SAMPLES table.
-    if (reason == 'I')
-      {
-        Int64 dummy1, dummy2;
-        double dummy3;
-        NAString oldSampTblName;
-        retcode = find(tabDef, char('I'), oldSampTblName,
-                       dummy1, dummy2, dummy3);
-        removeSample(tabDef, oldSampTblName, TRUE,
-                     "DROP OLD IUS PERSISTENT SAMPLE TABLE AND REMOVE FROM 
LIST");
-      }
+    // Drop the prior persistent sample table if it exists, and remove
+    // the corresponding row from the SB_PERSISTENT_SAMPLES table.
+
+    Int64 dummy1, dummy2;
+    double dummy3;
+    NAString oldSampTblName;
+    retcode = find(tabDef, reason, oldSampTblName,
+                   dummy1, dummy2, dummy3);
+    if (retcode == 0)
+      removeSample(tabDef, oldSampTblName, reason,
+                   "DROP OLD PERSISTENT SAMPLE TABLE AND REMOVE FROM LIST");
 
-    // Save original requested number of sample rows for inserting to 
PERSISTENT_SAMPLES.
+    // Save original requested number of sample rows for inserting to 
SB_PERSISTENT_SAMPLES.
     reqSampleRows = sampleRows;
 
     Lng32 st = (CmpCommon::getDefault(USTAT_IUS_USE_PERIODIC_SAMPLING) == 
DF_ON) ?
@@ -1673,7 +1658,6 @@ Lng32 HSPersSamples::createAndInsert(HSTableDef *tabDef, 
NAString &sampleName,
 
     retcode = sample.make(isEstimate, sampleName, actualRows, sampleRows, TRUE,
                           reason != 'I', /* partitioned for IUS */
-                          createDandI,
                           minRowCtPerPartition
                          );
       // sampleName output & actualRows will get modified if necessary
@@ -1682,72 +1666,22 @@ Lng32 HSPersSamples::createAndInsert(HSTableDef 
*tabDef, NAString &sampleName,
     {
 
       // Sample table successfully created, insert entry into
-      // PERSISTENT_SAMPLES table.  If unable to insert entry,
+      // SB_PERSISTENT_SAMPLES table.  If unable to insert entry,
       // drop sample table.
       stmt = HSCliStatement::INSERT_PST;
       percent = ((float)sampleRows/(float)actualRows)*100;
       ComObjectName persSampTblObjName(*catalog_,
                                        *schema_,
-                                       "PERSISTENT_SAMPLES",
+                                       "SB_PERSISTENT_SAMPLES",
                                        COM_TABLE_NAME,
                                        ComAnsiNamePart::INTERNAL_FORMAT,
                                        STMTHEAP);
       into_table = persSampTblObjName.getExternalName();
       objUID = tabDef->getObjectUID();
-      TM->Begin("INSERT INTO PERSISTENT_SAMPLES TABLE.");
+      TM->Begin("INSERT INTO SB_PERSISTENT_SAMPLES TABLE.");
       char timeStr[HS_TIMESTAMP_SIZE];
       hs_formatTimestamp(timeStr);
-#if 1 // Use the static INSERT_PST query defined in w:/ustat/sqlhist.mdf
-      NAWString *pSampleNameInUTF16 =
-        charToUnicode ( (Lng32) CharInfo::UTF8                 // char set of 
src str
-                      , sampleName/*in_utf8*/.data()           // src str
-                      , (Int32)sampleName/*in_utf8*/.length()  // src str len 
in bytes
-                      , STMTHEAP                               // heap for 
allocated target str
-                      );
-      NAWString sampleNameInUTF16(STMTHEAP);
-      if (pSampleNameInUTF16 != NULL && pSampleNameInUTF16->length() > 0)
-        sampleNameInUTF16.append(*pSampleNameInUTF16);
-      delete pSampleNameInUTF16; pSampleNameInUTF16 = NULL;
-      if (!sampleName.isNull() && sampleNameInUTF16.length() <= 0)
-      {
-        NAString str0((size_t)600/*allocate 600 bytes*/, STMTHEAP);
-        str0.append("INSERT ");
-        str0.append(sampleName);
-        *CmpCommon::diags() << DgSqlCode(-UERR_GENERIC_ERROR)
-                            << DgString0(str0.data())
-                            << DgString1("-2109")
-                            << DgString2("Unable to translate sample name from 
UTF8 to UCS2");
-        // HSHandleError(-UERR_GENERIC_ERROR);
-        return (-UERR_GENERIC_ERROR);
-      }
-
-      HSGlobalsClass *hs_globals = GetHSContext();
-
-      NAWString V1(L"Dummy value for V1 column", STMTHEAP);
-      NAWString V2(L"Dummy value for V2 column", STMTHEAP);
 
-      // Set the UPDATE_DATE to the epoch time '1970-01-01 00:00:00'.
-      // See its usage in HSGlobalsClass::begin_IUS_work() and ::end_IUS_work()
-      HSCliStatement insertPST(stmt,
-                              (char *)into_table.data(),
-                              (char *)&objUID,
-                              (char *)&reqSampleRows,
-                              (char *)&sampleRows,
-                              (char *)&percent,
-                              (char *)&timeStr[0],
-                              (char *)&reason,
-                              (char *)sampleNameInUTF16.data(),
-                              (char *)L"",   // IUS_SEARCH_CONDITION (added 
after IUS stmt)
-                              (char *)"1970-01-01 00:00:00",   // epoch 
UPDATE_DATE
-                              (char *)"",                      // dummy 
IUS_UPDATE_HISTORY
-                              (char *)V1.data(),   // V1
-                              (char *)V2.data());  // V2
-
-      retcode = insertPST.execFetch("INSERT " + sampleName );
-      HSHandleError(retcode);
-
-
-#else // Use dynamic query as a workaround if having problem with the static 
query
       NAString dml((size_t)500/*allocate 500 bytes*/, STMTHEAP);
       dml.append("INSERT INTO ");
       dml += into_table; // in UTF8
@@ -1770,31 +1704,21 @@ Lng32 HSPersSamples::createAndInsert(HSTableDef 
*tabDef, NAString &sampleName,
                      , TRUE             // in  - NABoolean encloseInQuotes = 
TRUE
                      );
       dml += quotedSampleName; // in UTF8
+      HSGlobalsClass *hs_globals = GetHSContext();
       ToQuotedString ( hs_globals->getWherePredicateForIUS()   // out - 
NAString &quotedStr
                      , ""               // in  - const NAString &internalStr
                      , TRUE             // in  - NABoolean encloseInQuotes = 
TRUE
                      );
-      dml += "',_UCS2''";               // IUS_SEARCH_CONDITION (added after 
IUS stmt)
-      dml += ",TIMESTAMP'";
-      dml += timeStr;        // UPDATE_DATE TIMESTAMP
-      dml += ",";
-      dml += ""; // IUS_UPDATE_HISTORY
-      NAWString quotedEmptyWStr(STMTHEAP);
-      ToQuotedString ( quotedEmptyWStr   // out - NAString &quotedStr
-                     , ""               // in  - const NAString &internalStr
-                     , TRUE             // in  - NABoolean encloseInQuotes = 
TRUE
-                     );
-      dml += "',_UCS2";
-      dml += quotedEmptyWStr; // V1
-      dml += "',_UCS2";
-      dml += quotedEmptyWStr; // V2
+      dml += ",_UCS2''";               // IUS_SEARCH_CONDITION (added after 
IUS stmt)
+      dml += ",TIMESTAMP'1970-01-01 00:00:00'"; // UPDATE_START_TIME TIMESTAMP
+      dml += ",''"; // UPDATER_INFO
+      dml += ",_UCS2''";  // V1
+      dml += ",_UCS2''";  // V2
       dml += ");";
 
       retcode = HSFuncExecQuery(dml, - UERR_INTERNAL_ERROR, NULL,
                                 HS_QUERY_ERROR, NULL, NULL, TRUE/*doRetry*/ );
       HSHandleError(retcode);
-#endif
-
 
       if (!retcode) TM->Commit();
       else {
@@ -1818,22 +1742,11 @@ Lng32 HSPersSamples::createAndInsert(HSTableDef 
*tabDef, NAString &sampleName,
     return retcode;
   }
 
-Lng32 HSPersSamples::createAndInsert(HSTableDef *tabDef, NAString &sampleName,
-                                    Int64 &sampleRows, Int64 &actualRows,
-                                    NABoolean isEstimate, NABoolean isManual,
-                                    Int64 minRowCtPerPartition)
-  {
-      char reason = (isManual == TRUE) ? 'M' : 'A';
-      return createAndInsert(tabDef, sampleName, sampleRows, actualRows, 
isEstimate, reason,
-                             FALSE, // do not create DandI
-                             minRowCtPerPartition
-                            );
-  }
-
 /***********************************************/
 /* METHOD:  remove()                           */
-/* PURPOSE: Remove all persistent sample tables*/
-/*          for the table with object uid 'uid'*/
+/* PURPOSE: Remove all manual (i.e., not IUS)  */
+/*          persistent sample tables for       */
+/*          the table with object uid 'uid'    */
 /*          and within 'allowedDiff' fraction  */
 /*          of 'sampleRows' in size.           */
 /* INPUT:   uid - source table UID.            */
@@ -1860,17 +1773,16 @@ Lng32 HSPersSamples::removeMatchingSamples(HSTableDef 
*tabDef,
     HSTranMan *TM = HSTranMan::Instance();
     Lng32 retcode = 0;
     NAString ddl, table, fromTable;
-    HSCliStatement::statementIndex stmt;
+    NABoolean nothingToDrop = TRUE;
 
     TM->Begin("DROP PERSISTENT SAMPLE TABLE AND REMOVE FROM LIST.");
     // Loop until all persistent samples matching criteria have been removed.
     Int64 actualRows = -1; // Obsolete samples will not be removed by find().
     NABoolean isEstimate = TRUE;
     retcode = find(tabDef, actualRows, isEstimate, sampleRows, allowedDiff, 
table);
-    stmt = HSCliStatement::DELETE_PST;
     ComObjectName persSampTblObjName(*catalog_,
                                      *schema_,
-                                     "PERSISTENT_SAMPLES",
+                                     "SB_PERSISTENT_SAMPLES",
                                      COM_TABLE_NAME,
                                      ComAnsiNamePart::INTERNAL_FORMAT,
                                      STMTHEAP);
@@ -1878,19 +1790,27 @@ Lng32 HSPersSamples::removeMatchingSamples(HSTableDef 
*tabDef,
     while (retcode == 0 && table != "")
     {
       // Drop persistent sample table and remove from list.
-      retcode = removeSample(tabDef, table, FALSE, "");
+      nothingToDrop = FALSE;
+      retcode = removeSample(tabDef, table, 'M', "");
       if (!retcode)
         retcode = find(tabDef, actualRows, isEstimate, sampleRows, 
allowedDiff, table);
     }
     if (retcode) TM->Rollback();
     else         retcode = TM->Commit();
+
+    if (nothingToDrop)
+    {
+      // we didn't drop anything; warn the user
+      *CmpCommon::diags() << DgSqlCode(UERR_WARNING_NO_SAMPLE_TABLE);
+    }  
+ 
     return retcode;
   }
 
 
 /*********************************************************************/
 /* METHOD:  readIUSUpdateInfo()                                      */
-/* PURPOSE: Retrieve the UPDATE_DATE and IUS_UPDATE_HISTORY columns  */
+/* PURPOSE: Retrieve the UPDATE_START_TIME and UPDATER_INFO columns  */
 /*          of the persistent samples table for the row identified   */
 /*          by the UID of the passed HSTableDef.                     */
 /* INPUT:   tblDef - Ptr to HSTableDef for table the sample is on.   */
@@ -1907,47 +1827,104 @@ Lng32 HSPersSamples::readIUSUpdateInfo(HSTableDef* 
tblDef,
 
     ComObjectName persSampTblObjName(*catalog_,
                                      *schema_,
-                                     "PERSISTENT_SAMPLES",
+                                     "SB_PERSISTENT_SAMPLES",
                                      COM_TABLE_NAME,
                                      ComAnsiNamePart::INTERNAL_FORMAT,
                                      STMTHEAP);
     NAString fromTable = persSampTblObjName.getExternalName();
-    HSCliStatement::statementIndex sel_stmt;
+    Int64 uid = tblDef->getObjectUID();
+    char uidStr[30];
+    convertInt64ToAscii(uid,uidStr);
 
+    HSCursor readIUSInfoCursor(STMTHEAP,"readIUSUpdateInfo");
 
-    sel_stmt = HSCliStatement::CURSOR_PST_UPDATE_INFO;
+    NAString query = "SELECT UPDATER_INFO, "
+                     "CAST(UPDATE_START_TIME - TIMESTAMP '1970-01-01 00:00:00' 
AS LARGEINT) FROM ";
+    query += fromTable;
+    query += " WHERE TABLE_UID = ";
+    query += uidStr;
+    query += " AND REASON = 'I'";
 
-    Int64 uid = tblDef->getObjectUID();
-    HSCliStatement cursorPSTUpdInfo(sel_stmt,
-                                    (char*)fromTable.data(),
-                                    (char*)&uid);
-    retcode = cursorPSTUpdInfo.open();
-    HSHandleError(retcode);
+    retcode = readIUSInfoCursor.prepareQuery(query, 0, 2); // no input parms, 
2 output cols
+    HSLogError(retcode);
+
+    retcode = readIUSInfoCursor.open();
+    HSLogError(retcode);
 
-    retcode = cursorPSTUpdInfo.fetch(2, (void*)updTimestamp, 
(void*)updHistory);
+    if (retcode == 0)
+      {
+        struct 
+          {
+            short len;
+            char data[129];   // to fetch a varchar; UPDATER_INFO is 
VARCHAR(128)
+          } buffer;
+
+        retcode = readIUSInfoCursor.fetch(2, (void *)&buffer, (void 
*)updTimestamp);
+        HSLogError(retcode);
+        if (retcode == 0)
+          {
+            memmove(updHistory,buffer.data,buffer.len);
+            updHistory[buffer.len] = '\0';  // to insure a null terminator
+          }
+      }
 
     // Don't overwrite a nonzero return code (error, warning, or HS_EOF) from
     // the fetch, but attempt to close the cursor anyway.
     if (retcode != 0)
-      cursorPSTUpdInfo.close();
+      readIUSInfoCursor.close();
     else
-      retcode = cursorPSTUpdInfo.close();
+      retcode = readIUSInfoCursor.close();
     return retcode;
   }
 
+
+// helper function that doubles any single quotes in text, so that
+// we can write SQL text into a SQL table
+void doubleUpSingleQuotes(const char *text, NAString & result)
+  {
+    const char * next = text;
+    char buf[2];  
+    char doubledSingleQuote[3] = "''";
+
+    buf[1] = '\0';
+
+    while (*next)
+      {
+        if (*next == '\'')
+          result += doubledSingleQuote;  // double up any single quote
+        else
+          {
+            // NAString += with a char doesn't work; have to use a char[]
+            buf[0] = *next;
+            result += buf;
+          }
+        next++;
+      }   
+  }
+
+
 /*********************************************************************/
 /* METHOD:  updIUSUpdateInfo()                                       */
-/* PURPOSE: Update the UPDATE_DATE and IUS_UPDATE_HISTORY columns of */
+/* PURPOSE: Update the UPDATE_START_TIME and UPDATER_INFO columns of */
 /*          the persistent samples table for the row identified by   */
 /*          the UID of the passed HSTableDef.                        */
 /* INPUT:   tblDef - Ptr to HSTableDef for table the sample is on.   */
-/*          updHistory - Buffer containing update history value.     */
+/*          updHistory - Buffer containing updater info.             */
 /*          updTimestamp - Char representation of update timestamp.  */
+/*          updWhereCondition - if not null, the where predicate of  */
+/*          the last completed IUS operation. (If null, we don't     */
+/*          update this column.)                                     */
+/*          requestedSampleRows - if non-null, points to expected #  */
+/*          of rows in sample table (based on sampling rate).        */
+/*          actualSampleRows - if non-null, actual # of rows.        */
 /* RETCODE: Status code from the update operation.                   */
 /*********************************************************************/
 Lng32 HSPersSamples::updIUSUpdateInfo(HSTableDef* tblDef,
-                                      char* updHistory,
-                                      char* updTimestampStr)
+                                      const char* updHistory,
+                                      const char* updTimestampStr,
+                                      const char* updWhereCondition,
+                                      const Int64* requestedSampleRows,
+                                      const Int64* actualSampleRows)
 {
   Lng32 retcode = 0;
   HSErrorCatcher errorCatcher(retcode, - UERR_INTERNAL_ERROR, 
"updIUSUpdateInfo", TRUE);
@@ -1961,19 +1938,87 @@ Lng32 HSPersSamples::updIUSUpdateInfo(HSTableDef* 
tblDef,
   // table for the passed table UID.
   ComObjectName persSampTblObjName(*catalog_,
                                    *schema_,
-                                   "PERSISTENT_SAMPLES",
+                                   "SB_PERSISTENT_SAMPLES",
                                    COM_TABLE_NAME,
                                    ComAnsiNamePart::INTERNAL_FORMAT,
                                    STMTHEAP);
   NAString updTable = persSampTblObjName.getExternalName();
-  HSCliStatement::statementIndex updStmt = 
HSCliStatement::UPDATE_PST_UPDATE_INFO;
-  HSCliStatement updPST(updStmt,
-                        (char*)updTable.data(),
-                        updTimestampStr,
-                        updHistory,
-                        (char*)&tblUID);
-  retcode = updPST.execFetch("UPDATE " + updTable );
+  Int64 uid = tblDef->getObjectUID();
+  char buf[30];
+
+  HSCursor writeIUSInfoCursor(STMTHEAP,"writeIUSUpdateInfo");
+
+  // The caller should have checked to see that the row existed first,
+  // but even so it is possible (though unlikely) that someone could
+  // have deleted the row in the meantime.
+
+  NAString query = "UPDATE ";                   
+  query += updTable;
+  query += " SET UPDATE_START_TIME = TIMESTAMP '";
+  query += updTimestampStr;
+  query += "', UPDATER_INFO = '";
+  query += updHistory;
+  query += "'";
+  if (updWhereCondition)
+    {
+      NAString doubledUp;
+      doubleUpSingleQuotes(updWhereCondition,doubledUp /* out*/);
+      query += ", LAST_WHERE_PREDICATE = ";
+      if (strlen(updWhereCondition) > 250)
+        {
+          // let SQL deal with character truncation issues
+          query += "SUBSTRING('";
+          query += doubledUp;
+          query += "' FOR 250)";
+        }    
+      else
+        {
+          query += "'";
+          query += doubledUp;
+          query += "'";
+        }
+    }
+  if (requestedSampleRows)
+    {
+      convertInt64ToAscii(*requestedSampleRows, buf);
+      query += ", REQUESTED_SAMPLE_ROWS = ";
+      query += buf;
+    }
+  if (actualSampleRows)
+    {
+      convertInt64ToAscii(*actualSampleRows, buf);
+      query += ", ACTUAL_SAMPLE_ROWS = ";
+      query += buf;
+    }
+  query += " WHERE TABLE_UID = ";
+  convertInt64ToAscii(uid,buf);
+  query += buf;
+  query += " AND REASON = 'I'";
+
+  retcode = writeIUSInfoCursor.prepareQuery(query, 0, 0);
+  HSLogError(retcode);
 
+  retcode = writeIUSInfoCursor.open();
+  HSLogError(retcode);
+
+  if (retcode == 0)
+    {
+      retcode = writeIUSInfoCursor.fetch(0,0);
+      if (retcode == 100)  // a successful UPDATE returns 100 on fetch
+        retcode = 0;  
+      HSLogError(retcode);
+    }
+
+  // Don't overwrite a nonzero return code (error, warning) from
+  // the fetch, but attempt to close the cursor anyway.
+  if (retcode != 0)
+    writeIUSInfoCursor.close();
+  else
+    {
+      retcode = writeIUSInfoCursor.close();
+      if (retcode == 100) // a successful UPDATE returns 100 on close too
+        retcode = 0;
+    }
 
   if (retcode)
     TM->Rollback();
@@ -2493,7 +2538,8 @@ HSCursor::HSCursor(NAHeap *heap, const char* stmtName)
    colDesc_(NULL), numEntries_(0),
    ptrNAType_(NULL), dataBuf_(NULL), outputDataLen_(0),
    group_(NULL), boundaryRowSet_(NULL), rowset_fields_(NULL),
-   closeStmtNeeded_(FALSE), retcode_(0), heap_(heap)
+   closeStmtNeeded_(FALSE), retcode_(0), heap_(heap),
+   lastFetchReturned100_(FALSE)
 {
   static SQLMODULE_ID module;
   static NABoolean moduleSet = FALSE;
@@ -5817,6 +5863,45 @@ Lng32 printPlan(SQLSTMT_ID *stmt)
 
 #endif // NA_USTAT_USE_STATIC not defined
 
+// Use a query on the Explain virtual table to see if the plan for stmt uses
+// MDAM, and include this information in the ulog. This function is called
+// only if logging is turned on.
+Lng32 checkMdam(SQLSTMT_ID *stmt)
+{
+  Lng32 retcode = 0;
+  HSLogMan *LM = HSLogMan::Instance();
+
+  NAString stmtStr = "select cast(count(*) as int) from table(explain(null,'";
+  stmtStr.append((char*)stmt->identifier)
+         .append("')) where description like '%mdam%'");
+
+  HSCursor cursor(STMTHEAP, "HS_CLI_CHECK_MDAM");
+  retcode = cursor.prepareQuery(stmtStr.data(), 0, 1);
+  HSHandleError(retcode);
+  SQLSTMT_ID* stmtId = cursor.getStmt();
+  SQLDESC_ID* outputDesc = cursor.getOutDesc();
+  retcode = cursor.open();
+  HSHandleError(retcode);
+
+  Int32 rowCount = 0;
+  retcode = SQL_EXEC_Fetch(stmtId, outputDesc, 1, &rowCount, NULL);
+  if (retcode == 0)
+    {
+      if (rowCount > 0)
+        LM->Log("MDAM is used for this query.");
+      else
+        LM->Log("MDAM is NOT used for this query.");
+    }
+  else if (retcode == 100)
+    LM->Log("MDAM check query returned no rows.");
+  else
+    {
+      LM->Log("MDAM check query failed.");
+      HSLogError(retcode);
+    }
+
+  return retcode;
+}
 
 /***********************************************/
 /* METHOD:  getRowCountFromStats(Int64* )      */
@@ -6127,13 +6212,14 @@ Lng32 HSCursor::prepareQuery(const char *cliStr, Lng32 
numParams, Lng32 numResul
 }
 
 //@ZXnew
-Lng32 HSCursor::open(Lng32 numParams)
+Lng32 HSCursor::open(Lng32 numParams, void * in01)
 {
   Lng32 retcode = SQL_EXEC_ClearDiagnostics(stmt_);
   HSHandleError(retcode);
-  retcode = SQL_EXEC_Exec(stmt_, inputDesc_, numParams);
+  retcode = SQL_EXEC_Exec(stmt_, inputDesc_, numParams, in01, NULL);
   HSHandleError(retcode);
   closeStmtNeeded_ = TRUE;
+  lastFetchReturned100_ = FALSE;
   return retcode;
 }
 
@@ -6149,7 +6235,7 @@ Lng32 HSCursor::fetch(Lng32 numResults,
                       void *  out22, void *  out23, void *  out24,
                       void *  out25)
 {
-  HS_ASSERT(numResults > 0 && out01 != NULL);
+  HS_ASSERT((numResults == 0) || (numResults > 0 && out01 != NULL));
   Lng32 retcode = SQL_EXEC_Fetch(stmt_, outputDesc_, numResults,
                                  out01, NULL, out02, NULL, out03, NULL,
                                  out04, NULL, out05, NULL, out06, NULL,
@@ -6160,6 +6246,29 @@ Lng32 HSCursor::fetch(Lng32 numResults,
                                  out19, NULL, out20, NULL, out21, NULL,
                                  out22, NULL, out23, NULL, out24, NULL,
                                  out25, NULL);
+  lastFetchReturned100_ = (retcode == 100);
+  return retcode;
+}
+
+Lng32 HSCursor::close()
+{
+  // This is done by the dtor ordinarily. However, if a cursor needs to
+  // be reused (e.g., different input parameters), we need to be able
+  // to close without destroying the object.
+
+  Lng32 retcode = 0;
+  if (closeStmtNeeded_)
+    {
+      if (lastFetchReturned100_)
+        {
+          // if the last fetch simply ran to the end of the cursor, reset
+          // the diags area so we don't return the 100 again on the close
+          SQL_EXEC_ClearDiagnostics(stmt_);
+        }
+      retcode = SQL_EXEC_CloseStmt(stmt_);
+      closeStmtNeeded_ = FALSE;  // always set to FALSE so we don't try again
+    }
+  lastFetchReturned100_ = FALSE;
   return retcode;
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/021ebd6c/core/sql/ustat/hs_cli.h
----------------------------------------------------------------------
diff --git a/core/sql/ustat/hs_cli.h b/core/sql/ustat/hs_cli.h
index 3c8bb01..3d91ac4 100644
--- a/core/sql/ustat/hs_cli.h
+++ b/core/sql/ustat/hs_cli.h
@@ -75,6 +75,7 @@ Lng32 HSFuncExecQuery( const char *dml
                     , const HSTableDef *tabDef = NULL
                     , NABoolean doRetry = FALSE
                     , short errorToIgnore = 0
+                    , NABoolean checkMdam = FALSE
                     );
 
 Lng32 HSFuncExecDDL( const char *dml
@@ -92,6 +93,7 @@ Lng32 CreateHistView   (const HSGlobalsClass* hsGlobal);
 // Drop the sample table.
 Lng32 DropSampleTable();
 
+Lng32 checkMdam(SQLSTMT_ID *stmt);
 Lng32 printPlan(SQLSTMT_ID *stmt);
 void getRowCountFromStats(Int64 * rowsAffected , const HSTableDef *tabDef = 
NULL);
 
@@ -175,14 +177,11 @@ class HSSample
               NABoolean unpartitioned=FALSE, //input - used to specify if the 
                                             // method is being called to create
                                             // unpartitioned persistent sample 
-              NABoolean createDandI=FALSE,  //input - if table D and I
-                                            // should be created
               Int64 minRowCtPerPartition = -1 // minimal row RC per partition
               );
     // Create sample table (called by make).
     Lng32 create(NABoolean unpartitioned = FALSE,
-                NABoolean isPersSample = FALSE,
-                NABoolean createDandI = FALSE
+                NABoolean isPersSample = FALSE
                 );
     Lng32 create(NAString& tblName,
                 NABoolean unpartitioned = FALSE,
@@ -414,18 +413,22 @@ class HSPersSamples
     public:
          // Creates or returns instance.
          static HSPersSamples* Instance(const NAString &catalog,
-                                        NABoolean createTable = TRUE);
-
-         static Lng32 updIUSUpdateInfo(HSTableDef* tblDef,
-                                       char* updHistory,
-                                       char* updTimestampStr);
-
-         static Lng32 readIUSUpdateInfo(HSTableDef* tblDef,
-                                        char* updHistory,
-                                        Int64* updTimestamp);
-
-         // finds a persistent sample table for UID and reason code and 
returns in 'table'.
-         Lng32 find(HSTableDef *tabDef, char reason_code, NAString &table,
+                                        const NAString &schema);
+
+         Lng32 updIUSUpdateInfo(HSTableDef* tblDef,
+                                const char* updHistory,
+                                const char* updTimestampStr,
+                                const char* updWhereCondition,
+                                const Int64* requestedSampleRows = NULL,
+                                const Int64* actualSampleRows = NULL);
+
+         Lng32 readIUSUpdateInfo(HSTableDef* tblDef,
+                                 char* updHistory,
+                                 Int64* updTimestamp);
+
+         // finds a persistent sample table for UID and reason code and 
returns it in 'table'.
+         // (returns ' ' in table if none is found).
+         Lng32 find(HSTableDef *tabDef, char reason, NAString &table,
                     Int64 &requestedRows, Int64 &sampleRows, double 
&sampleRate);
 
          // finds a persistent sample table for UID and sample size and 
returns in 'table'.
@@ -439,10 +442,6 @@ class HSPersSamples
                               NABoolean isEstimate, char reason,
                               NABoolean createDandI=FALSE,
                               Int64 minRowsCtPerPartition = -1);
-         Lng32 createAndInsert(HSTableDef *tabDef, NAString &sampleName,
-                              Int64 &sampleRows, Int64 &actualRows, 
-                              NABoolean isEstimate, NABoolean isManual,
-                              Int64 minRowsCtPerPartition = -1);
 
           // remove persistent sample table(s) based on uid, sampleRows, and 
the
           // allowed difference between the number of rows and sampleRows.
@@ -451,15 +450,24 @@ class HSPersSamples
          // drop the named sample table and remove its entry from the
          // PERSISTENT_SAMPLES table.
          Lng32 removeSample(HSTableDef* tabDef, NAString& sampTblName,
-                            NABoolean useTransaction, const char* txnLabel);
+                            char reason, const char* txnLabel);
 
-    protected:
-         HSPersSamples();                     /* ensure only 1 instance of 
class */
+         ~HSPersSamples();
+
+    protected:  /* ensure only 1 instance of class */
+
+         HSPersSamples(const NAString &catalog,
+                       const NAString &schema);    
+
+         void setCatalogSchema(const NAString &catalog,
+                               const NAString &schema); 
+      
     private:
+
          static THREAD_P HSPersSamples* instance_;     /* 1 and only 1 
instance           */
-         static THREAD_P NAList<NAString>* persSampleTablesList_;
-         static THREAD_P NAString* catalog_;
-         static THREAD_P NAString* schema_;
+         NAString* catalog_;
+         NAString* schema_;
+         NABoolean triedCreatingSBPersistentSamples_;
   };
 
 /*****************************************************************************/
@@ -492,6 +500,7 @@ class HSPersData
 #define HS_MODULE "HP_SYSTEM_CATALOG.SYSTEM_SCHEMA.SQLHIST_N29_000"
 #define HS_MODULE_LENGTH  50  // more than needed
 #define HS_STMTID "HS_CLI_DYNSTMT"
+#define HS_INTERVAL_STMT_ID "HS_INTERVAL_STMT_ID"
 #define HS_STMTID_LENGTH  50  
 #define HS_FUNC_EXEC_QUERY_STMTID "HS_FUNC_EXEC_QUERY_DYNSTMT"
 
@@ -884,7 +893,7 @@ public:
 
   // Functions below used when the HSCursor is instantiated for a dynamic 
query.
   Lng32 prepareQuery(const char *cliStr, Lng32 numParams, Lng32 numResults);
-  Lng32 open(Lng32 numParams = 0);
+  Lng32 open(Lng32 numParams = 0, void *in01 = NULL);
   Lng32 fetch(Lng32 numResults,
               void* out01,        void* out02 = NULL, void* out03 = NULL,
               void* out04 = NULL, void* out05 = NULL, void* out06 = NULL,
@@ -895,20 +904,8 @@ public:
               void* out19 = NULL, void* out20 = NULL, void* out21 = NULL,
               void* out22 = NULL, void* out23 = NULL, void* out24 = NULL,
               void* out25 = NULL);
-  Lng32 close()
-    {
-      // This is done by the dtor ordinarily. This function exists just to 
avoid
-      // the need for ifdefs around calls to close() on a variable that is 
either
-      // an HSCliStatement or HSCursor depending on the value of 
NA_USTAT_USE_STATIC.
-      Lng32 retcode = 0;
-      if (closeStmtNeeded_)
-        {
-          retcode = SQL_EXEC_CloseStmt(stmt_);
-          if (!retcode)
-            closeStmtNeeded_ = FALSE;
-        }
-      return retcode;
-    }
+  Lng32 close();
+
   SQLSTMT_ID* getStmt() {return stmt_;}
   SQLDESC_ID* getOutDesc() {return outputDesc_;}
   SQLDESC_ID* getInDesc() {return inputDesc_;}
@@ -972,6 +969,8 @@ private:
   
   NAHeap *heap_;
 
+  NABoolean lastFetchReturned100_;
+
   // prepare a dynamic sql statement.
   Lng32 prepare(const char *cliStr, const Lng32 outDescEntries = 500);
 

http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/021ebd6c/core/sql/ustat/hs_const.h
----------------------------------------------------------------------
diff --git a/core/sql/ustat/hs_const.h b/core/sql/ustat/hs_const.h
index 9c0bf7d..5dbbb57 100644
--- a/core/sql/ustat/hs_const.h
+++ b/core/sql/ustat/hs_const.h
@@ -153,7 +153,8 @@ enum USTAT_ERROR_CODES {UERR_SYNTAX_ERROR                   
 = 15001,
                         UERR_WARNING_IUS_TOO_MUCH_UEC_CHANGE_TOTAL = 9225,
                         UERR_WARNING_IUS_ZERO_UEC_INTERVAL   = 9226,
                         UERR_WARNING_IUS_EMPTY_INTERVAL      = 9227,
-                        UERR_IUS_NO_SUFFICIENT_MEMORY        = 9230,
+                        UERR_WARNING_NO_SAMPLE_TABLE         = 9228,
+                        UERR_WARNING_IUS_INSUFFICIENT_MEMORY = 9230,
                         UERR_IUS_WRONG_RANDOM                = 9231,
                         UERR_IUS_IN_PROGRESS                 = 9232,
                         UERR_WARNING_IUS_WHERE_CLAUSE_TOO_LONG = 9233,
@@ -168,10 +169,14 @@ enum USTAT_ERROR_CODES {UERR_SYNTAX_ERROR                 
   = 15001,
                         UERR_CANT_CREATE_HIVE_STATS_SCHEMA   = 9242,
                         UERR_YOU_WILL_LIKELY_BE_SORRY        = 9243,
                         UERR_USER_TRANSACTION                = 9244,
+                        UERR_UNEXPECTED_BACKWARDS_DATA       = 9245,
                         UERR_LOB_STATS_NOT_SUPPORTED         = 9246,
                         UERR_VOLATILE_TABLES_NOT_SUPPORTED   = 9247,
-                        UERR_NO_ERROR                        = 9250,
-                        UERR_LAST_ERROR                      = 9250
+                        UERR_FASTSTATS_MEM_ALLOCATION_ERROR  = 9248,
+                        UERR_IUS_IS_DISABLED                 = 9249,
+                        UERR_WARNING_IUS_NO_LONGER_ALL_NULL  = 9250,
+                        UERR_NO_ERROR                        = 9259,
+                        UERR_LAST_ERROR                      = 9259
                        };
 
 // reason of a histogram entry. it is a char value.

Reply via email to