18 #include <ndb_global.h> 
   19 #include <AttributeHeader.hpp> 
   20 #include <NdbSqlUtil.hpp> 
   21 #include <NdbIndexStat.hpp> 
   22 #include <NdbTransaction.hpp> 
   23 #include "NdbDictionaryImpl.hpp" 
   24 #include <NdbInterpretedCode.hpp> 
   25 #include <NdbRecord.hpp> 
   26 #include "NdbIndexStatImpl.hpp" 
   28 NdbIndexStat::NdbIndexStat() :
 
   38 NdbIndexStat::~NdbIndexStat()
 
   62                              const char* keyRecordData,
 
   68   char buf[NdbRecord::Attr::SHRINK_VARCHAR_BUFFSIZE];
 
   70   Uint32 key_index= record->key_indexes[ keyPartNum ];
 
   73   bool is_null= column->is_null(keyRecordData);
 
   75   const void *aValue= keyRecordData + column->offset;
 
   81     if (column->flags & NdbRecord::IsMysqldShrinkVarchar)
 
   83       len_ok= column->shrink_varchar(keyRecordData, 
 
   90       len_ok= column->get_var_length(keyRecordData, len);
 
   93       m_impl.setError(4209, __LINE__);
 
   99   Uint32 tIndexAttrId= column->index_attrId;
 
  100   Uint32 sizeInWords= (len + 3) / 4;
 
  102   const Uint32 ahValue= ah.m_value;
 
  104   if (keyLength + (2 + len) > NdbIndexStatImpl::BoundBufWords )
 
  108     m_impl.setError(4207, __LINE__);
 
  113   keyStatData[ keyLength++ ]= boundType;
 
  114   keyStatData[ keyLength++ ]= ahValue;
 
  116   keyStatData[ keyLength + sizeInWords - 1] = 0;
 
  117   memcpy(&keyStatData[ keyLength ], aValue, len);
 
  119   keyLength+= sizeInWords;
 
  134   DBUG_ENTER(
"NdbIndexStat::records_in_range");
 
  136   Uint32 key1[NdbIndexStatImpl::BoundBufWords], keylen1;
 
  137   Uint32 key2[NdbIndexStatImpl::BoundBufWords], keylen2;
 
  143     Uint32 maxBoundParts= (ib->low_key_count > ib->high_key_count) ? 
 
  144       ib->low_key_count : ib->high_key_count;
 
  149     for (Uint32 keyPartNum=0; keyPartNum < maxBoundParts; keyPartNum++)
 
  151       if (ib->low_key_count > keyPartNum)
 
  158         if ((! ib->low_inclusive) && 
 
  159             (keyPartNum == (ib->low_key_count -1 )))
 
  162         if (addKeyPartInfo(key_record,
 
  170       if (ib->high_key_count > keyPartNum)
 
  177         if ((! ib->high_inclusive) && 
 
  178             (keyPartNum == (ib->high_key_count -1)))
 
  181         if (addKeyPartInfo(key_record,
 
  194     Uint32 out[4] = { 0, 0, 0, 0 };  
 
  195     float tot[4] = { 0, 0, 0, 0 };   
 
  197     bool forceSend = 
true;
 
  198     const Uint32 codeWords= 1;
 
  199     Uint32 codeSpace[ codeWords ];
 
  203     if ((
code.interpret_exit_last_row() != 0) ||
 
  204         (
code.finalise() != 0))
 
  206       m_impl.setError(
code.getNdbError().code, __LINE__);
 
  207       DBUG_PRINT(
"error", (
"code: %d", 
code.getNdbError().code));
 
  215     options.optionsPresent= 
 
  216       NdbScanOperation::ScanOptions::SO_GETVALUE | 
 
  217       NdbScanOperation::ScanOptions::SO_INTERPRETED;
 
  220     extraGet.column= NdbDictionary::Column::RECORDS_IN_RANGE;
 
  221     extraGet.appStorage= (
void*) out;
 
  222     extraGet.recAttr= NULL;
 
  224     options.extraGetValues= &extraGet;
 
  225     options.numExtraGetValues= 1;
 
  228     options.interpretedCode= &
code;
 
  230     const Uint32 keyBitmaskWords= (NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY + 31) >> 5;
 
  231     Uint32 emptyMask[keyBitmaskWords];
 
  232     memset(&emptyMask[0], 0, keyBitmaskWords << 2);
 
  238                               (
const unsigned char*) &emptyMask[0],
 
  256     const char* dummy_out_ptr= NULL;
 
  258                                  true, forceSend)) == 0) {
 
  259       DBUG_PRINT(
"info", (
"frag rows=%u in=%u before=%u after=%u [error=%d]",
 
  260                           out[0], out[1], out[2], out[3],
 
  261                           (
int)(out[1] + out[2] + out[3]) - (
int)out[0]));
 
  263       for (i = 0; i < 4; i++)
 
  264         tot[i] += (
float)out[
i];
 
  269       DBUG_PRINT(
"error nextResult ", (
"trans:%d op:%d", trans->
getNdbError().
code,
 
  273     op->
close(forceSend);
 
  274     rows = (Uint64)tot[1];
 
  278   DBUG_PRINT(
"value", (
"rows=%u/%u flags=%x",
 
  279                        (
unsigned)(rows>>32), (
unsigned)(rows), flags));
 
  286 NdbIndexStat::create_systables(
Ndb* ndb)
 
  288   DBUG_ENTER(
"NdbIndexStat::create_systables");
 
  289   if (m_impl.create_systables(ndb) == -1)
 
  295 NdbIndexStat::drop_systables(
Ndb* ndb)
 
  297   DBUG_ENTER(
"NdbIndexStat::drop_systables");
 
  298   if (m_impl.drop_systables(ndb) == -1)
 
  304 NdbIndexStat::check_systables(
Ndb* ndb)
 
  306   DBUG_ENTER(
"NdbIndexStat::check_systables");
 
  307   if (m_impl.check_systables(ndb) == -1)
 
  316   DBUG_ENTER(
"NdbIndexStat::set_index");
 
  317   if (m_impl.set_index(index, table) == -1)
 
  319   m_impl.m_facadeHead.m_indexId = index.
getObjectId();
 
  321   m_impl.m_facadeHead.m_tableId = table.
getObjectId();
 
  326 NdbIndexStat::reset_index()
 
  328   DBUG_ENTER(
"NdbIndexStat::reset_index");
 
  329   m_impl.reset_index();
 
  334 NdbIndexStat::update_stat(
Ndb* ndb)
 
  336   DBUG_ENTER(
"NdbIndexStat::update_stat");
 
  337   if (m_impl.update_stat(ndb, m_impl.m_facadeHead) == -1)
 
  343 NdbIndexStat::delete_stat(
Ndb* ndb)
 
  345   DBUG_ENTER(
"NdbIndexStat::delete_stat");
 
  346   if (m_impl.delete_stat(ndb, m_impl.m_facadeHead) == -1)
 
  354 NdbIndexStat::move_cache()
 
  356   DBUG_ENTER(
"NdbIndexStat::move_cache");
 
  362 NdbIndexStat::clean_cache()
 
  364   DBUG_ENTER(
"NdbIndexStat::clean_cache");
 
  365   m_impl.clean_cache();
 
  370 NdbIndexStat::get_cache_info(CacheInfo& info, CacheType 
type)
 const 
  375     c = m_impl.m_cacheBuild;
 
  378     c = m_impl.m_cacheQuery;
 
  381     c = m_impl.m_cacheClean;
 
  386   info.m_sampleCount = 0;
 
  387   info.m_totalBytes = 0;
 
  388   info.m_save_time = 0;
 
  389   info.m_sort_time = 0;
 
  393     info.m_valid += c->m_valid;
 
  394     info.m_sampleCount += c->m_sampleCount;
 
  395     info.m_totalBytes += c->m_keyBytes + c->m_valueBytes + c->m_addrBytes;
 
  396     info.m_save_time += c->m_save_time;
 
  397     info.m_sort_time += c->m_sort_time;
 
  401   require(type == CacheClean || info.m_count <= 1);
 
  407 NdbIndexStat::get_head(Head& head)
 const 
  409   head = m_impl.m_facadeHead;
 
  413 NdbIndexStat::read_head(
Ndb* ndb)
 
  415   DBUG_ENTER(
"NdbIndexStat::read_head");
 
  416   if (m_impl.read_head(ndb, m_impl.m_facadeHead) == -1)
 
  422 NdbIndexStat::read_stat(
Ndb* ndb)
 
  424   DBUG_ENTER(
"NdbIndexStat::read_stat");
 
  425   if (m_impl.read_stat(ndb, m_impl.m_facadeHead) == -1)
 
  432 NdbIndexStat::Bound::Bound(
const NdbIndexStat* is, 
void* buffer)
 
  434   DBUG_ENTER(
"NdbIndexStat::Bound::Bound");
 
  435   require(is != 0 && is->m_impl.m_indexSet);
 
  436   require(buffer != 0);
 
  437   Uint8* buf = (Uint8*)buffer;
 
  440   UintPtr ubuf1 = (UintPtr)buf1;
 
  442     buf1 += (8 - ubuf1 % 8);
 
  444   m_impl = (
void*)buf1;
 
  448   uint used = (uint)(buf2 - buf);
 
  449   uint bytes = BoundBufferBytes - used;
 
  450   bound.m_data.set_buf(buf2, bytes);
 
  455 NdbIndexStat::add_bound(Bound& bound_f, 
const void* value)
 
  457   DBUG_ENTER(
"NdbIndexStat::add_bound");
 
  463     m_impl.setError(UsageError, __LINE__);
 
  466   if (bound.m_data.add(value, &len_out) == -1)
 
  468     m_impl.setError(UsageError, __LINE__);
 
  475 NdbIndexStat::add_bound_null(Bound& bound_f)
 
  477   DBUG_ENTER(
"NdbIndexStat::add_bound_null");
 
  481   if (bound.m_data.add_null(&len_out) == -1)
 
  483     m_impl.setError(UsageError, __LINE__);
 
  490 NdbIndexStat::set_bound_strict(Bound& bound_f, 
int strict)
 
  492   DBUG_ENTER(
"NdbIndexStat::set_bound_strict");
 
  495   bound.m_strict = strict;
 
  500 NdbIndexStat::reset_bound(Bound& bound_f)
 
  502   DBUG_ENTER(
"NdbIndexStat::reset_bound");
 
  505   bound.m_bound.reset();
 
  513 NdbIndexStat::Range::Range(Bound& bound1, Bound& bound2) :
 
  517   DBUG_ENTER(
"NdbIndexStat::Range::Range");
 
  522 NdbIndexStat::finalize_range(Range& range_f)
 
  524   DBUG_ENTER(
"NdbIndexStat::finalize_range");
 
  525   Bound& bound1_f = range_f.m_bound1;
 
  526   Bound& bound2_f = range_f.m_bound2;
 
  532   if (m_impl.finalize_range(range) == -1)
 
  538 NdbIndexStat::reset_range(Range& range)
 
  540   DBUG_ENTER(
"NdbIndexStat::reset_range");
 
  541   reset_bound(range.m_bound1);
 
  542   reset_bound(range.m_bound2);
 
  547 NdbIndexStat::convert_range(Range& range_f,
 
  551   DBUG_ENTER(
"NdbIndexStat::convert_range");
 
  552   Bound& bound1_f = range_f.m_bound1;
 
  553   Bound& bound2_f = range_f.m_bound2;
 
  559   if (m_impl.convert_range(range, key_record, ib) == -1)
 
  566 NdbIndexStat::Stat::Stat(
void* buffer)
 
  568   DBUG_ENTER(
"NdbIndexStat::Stat::Stat");
 
  569   require(buffer != 0);
 
  570   Uint8* buf = (Uint8*)buffer;
 
  573   UintPtr ubuf1 = (UintPtr)buf1;
 
  575     buf1 += (8 - ubuf1 % 8);
 
  577   m_impl = (
void*)buf1;
 
  582 NdbIndexStat::query_stat(
const Range& range_f, Stat& stat_f)
 
  584   DBUG_ENTER(
"NdbIndexStat::query_stat");
 
  585   Bound& bound1_f = range_f.m_bound1;
 
  586   Bound& bound2_f = range_f.m_bound2;
 
  593   const uint sz = 8000;
 
  595   DBUG_PRINT(
"index_stat", (
"lo: %s", bound1.m_bound.print(buf, sz)));
 
  596   DBUG_PRINT(
"index_stat", (
"hi: %s", bound2.m_bound.print(buf, sz)));
 
  600   if (m_impl.query_stat(range, stat) == -1)
 
  606 NdbIndexStat::get_empty(
const Stat& stat_f, 
bool* empty)
 
  608   DBUG_ENTER(
"NdbIndexStat::get_empty");
 
  612   *empty = stat.m_value.m_empty;
 
  613   DBUG_PRINT(
"index_stat", (
"empty:%d", *empty));
 
  618 NdbIndexStat::get_rir(
const Stat& stat_f, 
double* rir)
 
  620   DBUG_ENTER(
"NdbIndexStat::get_rir");
 
  623   double x = stat.m_value.m_rir;
 
  630   sprintf(buf, 
"%.2f", *rir);
 
  632   DBUG_PRINT(
"index_stat", (
"rir:%s", buf));
 
  637 NdbIndexStat::get_rpk(
const Stat& stat_f, Uint32 k, 
double* rpk)
 
  639   DBUG_ENTER(
"NdbIndexStat::get_rpk");
 
  642   double x = stat.m_value.m_rir / stat.m_value.m_unq[k];
 
  649   sprintf(buf, 
"%.2f", *rpk);
 
  651   DBUG_PRINT(
"index_stat", (
"rpk[%u]:%s", k, buf));
 
  656 NdbIndexStat::get_rule(
const Stat& stat_f, 
char* buffer)
 
  658   DBUG_ENTER(
"NdbIndexStat::get_rule");
 
  661   require(buffer != 0);
 
  663                        stat.m_rule[0], stat.m_rule[1], stat.m_rule[2]);
 
  670 NdbIndexStat::create_sysevents(
Ndb* ndb)
 
  672   DBUG_ENTER(
"NdbIndexStat::create_sysevents");
 
  673   if (m_impl.create_sysevents(ndb) == -1)
 
  679 NdbIndexStat::drop_sysevents(
Ndb* ndb)
 
  681   DBUG_ENTER(
"NdbIndexStat::drop_sysevents");
 
  682   if (m_impl.drop_sysevents(ndb) == -1)
 
  688 NdbIndexStat::check_sysevents(
Ndb* ndb)
 
  690   DBUG_ENTER(
"NdbIndexStat::check_sysevents");
 
  691   if (m_impl.check_sysevents(ndb) == -1)
 
  697 NdbIndexStat::create_listener(
Ndb* ndb)
 
  699   DBUG_ENTER(
"NdbIndexStat::create_listener");
 
  700   if (m_impl.create_listener(ndb) == -1)
 
  706 NdbIndexStat::execute_listener(
Ndb* ndb)
 
  708   DBUG_ENTER(
"NdbIndexStat::execute_listener");
 
  709   if (m_impl.execute_listener(ndb) == -1)
 
  715 NdbIndexStat::poll_listener(
Ndb* ndb, 
int max_wait_ms)
 
  717   DBUG_ENTER(
"NdbIndexStat::poll_listener");
 
  718   int ret = m_impl.poll_listener(ndb, max_wait_ms);
 
  725 NdbIndexStat::next_listener(
Ndb* ndb)
 
  727   DBUG_ENTER(
"NdbIndexStat::next_listener");
 
  728   int ret = m_impl.next_listener(ndb);
 
  735 NdbIndexStat::drop_listener(
Ndb* ndb)
 
  737   DBUG_ENTER(
"NdbIndexStat::drop_listener");
 
  738   if (m_impl.drop_listener(ndb) == -1)
 
  745 NdbIndexStat::Mem::Mem()
 
  749 NdbIndexStat::Mem::~Mem()
 
  754 NdbIndexStat::set_mem_handler(Mem* mem)
 
  756   m_impl.m_mem_handler = mem;
 
  762 NdbIndexStat::getImpl()
 
  769 NdbIndexStat::Error::Error()
 
  776 NdbIndexStat::getNdbError()
 const 
  778   return m_impl.getNdbError();
 
  784   out << static_cast<const NdbError&>(error);
 
  785   out << 
" (line " << error.line << 
", extra " << error.extra << 
")";