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 "edStr , "" // 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 "edStr - , "" // 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.
