1fb726d48Sopenharmony_ci/* 2fb726d48Sopenharmony_ci * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved. 3fb726d48Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4fb726d48Sopenharmony_ci * you may not use this file except in compliance with the License. 5fb726d48Sopenharmony_ci * You may obtain a copy of the License at 6fb726d48Sopenharmony_ci * 7fb726d48Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8fb726d48Sopenharmony_ci * 9fb726d48Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10fb726d48Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11fb726d48Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fb726d48Sopenharmony_ci * See the License for the specific language governing permissions and 13fb726d48Sopenharmony_ci * limitations under the License. 14fb726d48Sopenharmony_ci */ 15fb726d48Sopenharmony_ci 16fb726d48Sopenharmony_ci#include "table_base.h" 17fb726d48Sopenharmony_ci 18fb726d48Sopenharmony_ci#include <cctype> 19fb726d48Sopenharmony_ci#include <cmath> 20fb726d48Sopenharmony_ci#include <cstring> 21fb726d48Sopenharmony_ci 22fb726d48Sopenharmony_cinamespace SysTuning { 23fb726d48Sopenharmony_cinamespace TraceStreamer { 24fb726d48Sopenharmony_cinamespace { 25fb726d48Sopenharmony_cistruct TableContext { 26fb726d48Sopenharmony_ci TabTemplate tmplate; 27fb726d48Sopenharmony_ci TraceDataCache *dataCache; 28fb726d48Sopenharmony_ci sqlite3_module module; 29fb726d48Sopenharmony_ci std::string tableName; 30fb726d48Sopenharmony_ci}; 31fb726d48Sopenharmony_ci} // namespace 32fb726d48Sopenharmony_ci 33fb726d48Sopenharmony_ciTableBase::~TableBase() 34fb726d48Sopenharmony_ci{ 35fb726d48Sopenharmony_ci dataCache_ = nullptr; 36fb726d48Sopenharmony_ci cursor_ = nullptr; 37fb726d48Sopenharmony_ci} 38fb726d48Sopenharmony_ci 39fb726d48Sopenharmony_civoid TableBase::TableRegister(sqlite3 &db, TraceDataCache *cache, const std::string &tableName, TabTemplate tmplate) 40fb726d48Sopenharmony_ci{ 41fb726d48Sopenharmony_ci std::unique_ptr<TableContext> context(std::make_unique<TableContext>()); 42fb726d48Sopenharmony_ci context->dataCache = cache; 43fb726d48Sopenharmony_ci context->tmplate = tmplate; 44fb726d48Sopenharmony_ci context->tableName = tableName; 45fb726d48Sopenharmony_ci sqlite3_module &module = context->module; 46fb726d48Sopenharmony_ci module = {0}; 47fb726d48Sopenharmony_ci 48fb726d48Sopenharmony_ci auto createFn = [](sqlite3 *xdb, void *pAux, int32_t argc, const char *const *argv, sqlite3_vtab **ppVTab, 49fb726d48Sopenharmony_ci char **pzErr) { 50fb726d48Sopenharmony_ci Unused(argc); 51fb726d48Sopenharmony_ci Unused(argv); 52fb726d48Sopenharmony_ci Unused(pzErr); 53fb726d48Sopenharmony_ci auto xdesc = static_cast<const TableContext *>(pAux); 54fb726d48Sopenharmony_ci auto table = xdesc->tmplate(xdesc->dataCache); 55fb726d48Sopenharmony_ci table->name_ = xdesc->tableName; 56fb726d48Sopenharmony_ci if (table->name_ == "process" || table->name_ == "thread") { 57fb726d48Sopenharmony_ci table->wdataCache_ = xdesc->dataCache; 58fb726d48Sopenharmony_ci } 59fb726d48Sopenharmony_ci 60fb726d48Sopenharmony_ci table->Init(argc, argv); 61fb726d48Sopenharmony_ci std::string createStmt = table->CreateTableSql(); 62fb726d48Sopenharmony_ci TS_LOGD("xCreate table %s, statement: %s", table->name_.c_str(), createStmt.c_str()); 63fb726d48Sopenharmony_ci int32_t ret = sqlite3_declare_vtab(xdb, createStmt.c_str()); 64fb726d48Sopenharmony_ci if (ret != SQLITE_OK) { 65fb726d48Sopenharmony_ci if ((table->name_ == "span_join") || (table->name_ == "_span_join")) { 66fb726d48Sopenharmony_ci return ret; 67fb726d48Sopenharmony_ci } 68fb726d48Sopenharmony_ci TS_LOGE("sqlite3_declare_vtab %s faild: %s", table->name_.c_str(), createStmt.c_str()); 69fb726d48Sopenharmony_ci return ret; 70fb726d48Sopenharmony_ci } 71fb726d48Sopenharmony_ci *ppVTab = table.release(); 72fb726d48Sopenharmony_ci return SQLITE_OK; 73fb726d48Sopenharmony_ci }; 74fb726d48Sopenharmony_ci 75fb726d48Sopenharmony_ci auto destroyFn = [](sqlite3_vtab *t) { 76fb726d48Sopenharmony_ci TS_LOGD("xDestroy table %s", static_cast<TableBase *>(t)->name_.c_str()); 77fb726d48Sopenharmony_ci delete static_cast<TableBase *>(t); 78fb726d48Sopenharmony_ci return SQLITE_OK; 79fb726d48Sopenharmony_ci }; 80fb726d48Sopenharmony_ci module.xCreate = createFn; 81fb726d48Sopenharmony_ci module.xConnect = createFn; 82fb726d48Sopenharmony_ci module.xDisconnect = destroyFn; 83fb726d48Sopenharmony_ci module.xDestroy = destroyFn; 84fb726d48Sopenharmony_ci 85fb726d48Sopenharmony_ci SetModuleCallbacks(module, tableName); 86fb726d48Sopenharmony_ci sqlite3_create_module_v2(&db, tableName.c_str(), &module, context.release(), 87fb726d48Sopenharmony_ci [](void *arg) { delete static_cast<TableContext *>(arg); }); 88fb726d48Sopenharmony_ci} 89fb726d48Sopenharmony_ci 90fb726d48Sopenharmony_civoid TableBase::SetModuleCallbacks(sqlite3_module &module, const std::string &tableName) 91fb726d48Sopenharmony_ci{ 92fb726d48Sopenharmony_ci module.xOpen = [](sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor) { 93fb726d48Sopenharmony_ci TS_LOGD("xOpen: %s", static_cast<TableBase *>(pVTab)->name_.c_str()); 94fb726d48Sopenharmony_ci return static_cast<TableBase *>(pVTab)->Open(ppCursor); 95fb726d48Sopenharmony_ci }; 96fb726d48Sopenharmony_ci 97fb726d48Sopenharmony_ci module.xClose = [](sqlite3_vtab_cursor *vc) { 98fb726d48Sopenharmony_ci TS_LOGD("xClose: %s", static_cast<Cursor *>(vc)->table_->name_.c_str()); 99fb726d48Sopenharmony_ci delete static_cast<Cursor *>(vc); 100fb726d48Sopenharmony_ci return SQLITE_OK; 101fb726d48Sopenharmony_ci }; 102fb726d48Sopenharmony_ci module.xBestIndex = [](sqlite3_vtab *pVTab, sqlite3_index_info *idxInfo) { 103fb726d48Sopenharmony_ci TS_LOGD("xBestIndex: %s %d", static_cast<TableBase *>(pVTab)->name_.c_str(), idxInfo->nConstraint); 104fb726d48Sopenharmony_ci return static_cast<TableBase *>(pVTab)->BestIndex(idxInfo); 105fb726d48Sopenharmony_ci }; 106fb726d48Sopenharmony_ci 107fb726d48Sopenharmony_ci module.xFilter = [](sqlite3_vtab_cursor *vc, int32_t idxNum, const char *idxStr, int32_t argc, 108fb726d48Sopenharmony_ci sqlite3_value **argv) { 109fb726d48Sopenharmony_ci auto *c = static_cast<Cursor *>(vc); 110fb726d48Sopenharmony_ci c->Reset(); 111fb726d48Sopenharmony_ci TS_LOGD("xFilter %s: [%d]%s", static_cast<Cursor *>(vc)->table_->name_.c_str(), idxNum, idxStr); 112fb726d48Sopenharmony_ci if (c->table_->cacheIdxNum_ != idxNum) { 113fb726d48Sopenharmony_ci c->table_->cacheConstraint_.Clear(); 114fb726d48Sopenharmony_ci c->table_->cacheConstraint_.FromString(idxStr); 115fb726d48Sopenharmony_ci c->table_->cacheIdxNum_ = idxNum; 116fb726d48Sopenharmony_ci } 117fb726d48Sopenharmony_ci return c->Filter(c->table_->cacheConstraint_, argv); 118fb726d48Sopenharmony_ci }; 119fb726d48Sopenharmony_ci module.xNext = [](sqlite3_vtab_cursor *vc) { return static_cast<TableBase::Cursor *>(vc)->Next(); }; 120fb726d48Sopenharmony_ci module.xEof = [](sqlite3_vtab_cursor *vc) { return static_cast<TableBase::Cursor *>(vc)->Eof(); }; 121fb726d48Sopenharmony_ci module.xColumn = [](sqlite3_vtab_cursor *vc, sqlite3_context *ctx, int32_t col) { 122fb726d48Sopenharmony_ci static_cast<TableBase::Cursor *>(vc)->context_ = ctx; 123fb726d48Sopenharmony_ci return static_cast<TableBase::Cursor *>(vc)->Column(col); 124fb726d48Sopenharmony_ci }; 125fb726d48Sopenharmony_ci if (tableName == "process" || tableName == "thread") { 126fb726d48Sopenharmony_ci module.xUpdate = [](sqlite3_vtab *pVTab, int32_t argc, sqlite3_value **argv, sqlite3_int64 *pRowid) { 127fb726d48Sopenharmony_ci TS_LOGD("xUpdate: %s", static_cast<TableBase *>(pVTab)->name_.c_str()); 128fb726d48Sopenharmony_ci return static_cast<TableBase *>(pVTab)->Update(argc, argv, pRowid); 129fb726d48Sopenharmony_ci }; 130fb726d48Sopenharmony_ci } 131fb726d48Sopenharmony_ci} 132fb726d48Sopenharmony_ci 133fb726d48Sopenharmony_cistd::string TableBase::CreateTableSql() const 134fb726d48Sopenharmony_ci{ 135fb726d48Sopenharmony_ci std::string stmt = "CREATE TABLE x("; 136fb726d48Sopenharmony_ci for (const auto &col : tableColumn_) { 137fb726d48Sopenharmony_ci stmt += " " + col.name_ + " " + col.type_; 138fb726d48Sopenharmony_ci stmt += ","; 139fb726d48Sopenharmony_ci } 140fb726d48Sopenharmony_ci stmt += " PRIMARY KEY("; 141fb726d48Sopenharmony_ci for (size_t i = 0; i < tablePriKey_.size(); i++) { 142fb726d48Sopenharmony_ci if (i != 0) 143fb726d48Sopenharmony_ci stmt += ", "; 144fb726d48Sopenharmony_ci stmt += tablePriKey_.at(i); 145fb726d48Sopenharmony_ci } 146fb726d48Sopenharmony_ci stmt += ")) WITHOUT ROWID;"; 147fb726d48Sopenharmony_ci return stmt; 148fb726d48Sopenharmony_ci} 149fb726d48Sopenharmony_ciint32_t TableBase::Cursor::Next() 150fb726d48Sopenharmony_ci{ 151fb726d48Sopenharmony_ci indexMap_->Next(); 152fb726d48Sopenharmony_ci return SQLITE_OK; 153fb726d48Sopenharmony_ci} 154fb726d48Sopenharmony_ci 155fb726d48Sopenharmony_ciint32_t TableBase::Cursor::Eof() 156fb726d48Sopenharmony_ci{ 157fb726d48Sopenharmony_ci return dataCache_->Cancel() || indexMap_->Eof(); 158fb726d48Sopenharmony_ci} 159fb726d48Sopenharmony_ciuint32_t TableBase::Cursor::CurrentRow() const 160fb726d48Sopenharmony_ci{ 161fb726d48Sopenharmony_ci return indexMap_->CurrentRow(); 162fb726d48Sopenharmony_ci} 163fb726d48Sopenharmony_civoid TableBase::Cursor::FilterEnd() 164fb726d48Sopenharmony_ci{ 165fb726d48Sopenharmony_ci indexMap_->Sort(); 166fb726d48Sopenharmony_ci} 167fb726d48Sopenharmony_ciint32_t TableBase::BestIndex(sqlite3_index_info *idxInfo) 168fb726d48Sopenharmony_ci{ 169fb726d48Sopenharmony_ci FilterConstraints filterConstraints; 170fb726d48Sopenharmony_ci for (int32_t i = 0; i < idxInfo->nConstraint; i++) { 171fb726d48Sopenharmony_ci const auto &constraint = idxInfo->aConstraint[i]; 172fb726d48Sopenharmony_ci if (constraint.usable) { 173fb726d48Sopenharmony_ci filterConstraints.AddConstraint(i, constraint.iColumn, constraint.op); 174fb726d48Sopenharmony_ci } 175fb726d48Sopenharmony_ci } 176fb726d48Sopenharmony_ci for (int32_t i = 0; i < idxInfo->nOrderBy; i++) { 177fb726d48Sopenharmony_ci filterConstraints.AddOrderBy(idxInfo->aOrderBy[i].iColumn, idxInfo->aOrderBy[i].desc); 178fb726d48Sopenharmony_ci } 179fb726d48Sopenharmony_ci 180fb726d48Sopenharmony_ci EstimatedIndexInfo estimate = {idxInfo->estimatedRows, idxInfo->estimatedCost, false}; 181fb726d48Sopenharmony_ci EstimateFilterCost(filterConstraints, estimate); 182fb726d48Sopenharmony_ci idxInfo->orderByConsumed = estimate.isOrdered; 183fb726d48Sopenharmony_ci idxInfo->estimatedCost = estimate.estimatedCost; 184fb726d48Sopenharmony_ci idxInfo->estimatedRows = estimate.estimatedRows; 185fb726d48Sopenharmony_ci 186fb726d48Sopenharmony_ci auto cs = filterConstraints.GetConstraints(); 187fb726d48Sopenharmony_ci for (size_t i = 0; i < cs.size(); i++) { 188fb726d48Sopenharmony_ci auto &c = cs[i]; 189fb726d48Sopenharmony_ci idxInfo->aConstraintUsage[c.idxInaConstraint].argvIndex = static_cast<int32_t>(i + 1); 190fb726d48Sopenharmony_ci idxInfo->aConstraintUsage[c.idxInaConstraint].omit = c.isSupport; 191fb726d48Sopenharmony_ci } 192fb726d48Sopenharmony_ci 193fb726d48Sopenharmony_ci std::string str; 194fb726d48Sopenharmony_ci filterConstraints.ToString(str); 195fb726d48Sopenharmony_ci char *pIdxStr = static_cast<char *>(sqlite3_malloc(str.size() + 1)); 196fb726d48Sopenharmony_ci std::copy(str.begin(), str.end(), pIdxStr); 197fb726d48Sopenharmony_ci pIdxStr[str.size()] = '\0'; 198fb726d48Sopenharmony_ci idxInfo->idxStr = pIdxStr; 199fb726d48Sopenharmony_ci idxInfo->needToFreeIdxStr = true; 200fb726d48Sopenharmony_ci idxInfo->idxNum = ++bestIndexNum_; 201fb726d48Sopenharmony_ci 202fb726d48Sopenharmony_ci TS_LOGD("%s BestIndex return: %d: %s", name_.c_str(), idxInfo->idxNum, str.c_str()); 203fb726d48Sopenharmony_ci TS_LOGD("%s, aConstraintUsage[%d]", idxInfo->idxStr, idxInfo->nConstraint); 204fb726d48Sopenharmony_ci for (int32_t i = 0; i < idxInfo->nConstraint; i++) { 205fb726d48Sopenharmony_ci TS_LOGD("col: %d op: %d, argvindex: %d omit: %d", idxInfo->aConstraint[i].iColumn, idxInfo->aConstraint[i].op, 206fb726d48Sopenharmony_ci idxInfo->aConstraintUsage[i].argvIndex, idxInfo->aConstraintUsage[i].omit); 207fb726d48Sopenharmony_ci } 208fb726d48Sopenharmony_ci TS_LOGD("estimated: %lld cost:%.3f", idxInfo->estimatedRows, idxInfo->estimatedCost); 209fb726d48Sopenharmony_ci 210fb726d48Sopenharmony_ci return SQLITE_OK; 211fb726d48Sopenharmony_ci} 212fb726d48Sopenharmony_ci 213fb726d48Sopenharmony_ciint32_t TableBase::Open(sqlite3_vtab_cursor **ppCursor) 214fb726d48Sopenharmony_ci{ 215fb726d48Sopenharmony_ci *ppCursor = static_cast<sqlite3_vtab_cursor *>(CreateCursor().release()); 216fb726d48Sopenharmony_ci return SQLITE_OK; 217fb726d48Sopenharmony_ci} 218fb726d48Sopenharmony_ci 219fb726d48Sopenharmony_ciTableBase::Cursor::Cursor(const TraceDataCache *dataCache, TableBase *table, uint32_t rowCount) 220fb726d48Sopenharmony_ci : context_(nullptr), 221fb726d48Sopenharmony_ci table_(table), 222fb726d48Sopenharmony_ci dataCache_(dataCache), 223fb726d48Sopenharmony_ci indexMap_(std::make_unique<IndexMap>(0, rowCount)), 224fb726d48Sopenharmony_ci rowCount_(rowCount) 225fb726d48Sopenharmony_ci{ 226fb726d48Sopenharmony_ci} 227fb726d48Sopenharmony_ci 228fb726d48Sopenharmony_cibool TableBase::CanFilterId(const char op, size_t &rowCount) 229fb726d48Sopenharmony_ci{ 230fb726d48Sopenharmony_ci switch (op) { 231fb726d48Sopenharmony_ci case SQLITE_INDEX_CONSTRAINT_EQ: 232fb726d48Sopenharmony_ci rowCount = 1; 233fb726d48Sopenharmony_ci break; 234fb726d48Sopenharmony_ci case SQLITE_INDEX_CONSTRAINT_GT: 235fb726d48Sopenharmony_ci case SQLITE_INDEX_CONSTRAINT_GE: 236fb726d48Sopenharmony_ci case SQLITE_INDEX_CONSTRAINT_LE: 237fb726d48Sopenharmony_ci case SQLITE_INDEX_CONSTRAINT_LT: 238fb726d48Sopenharmony_ci // assume filter out a half of rows 239fb726d48Sopenharmony_ci rowCount = (rowCount >> 1); 240fb726d48Sopenharmony_ci break; 241fb726d48Sopenharmony_ci default: 242fb726d48Sopenharmony_ci return false; 243fb726d48Sopenharmony_ci } 244fb726d48Sopenharmony_ci return true; 245fb726d48Sopenharmony_ci} 246fb726d48Sopenharmony_ci 247fb726d48Sopenharmony_cibool TableBase::CanFilterSorted(const char op, size_t &rowCount) 248fb726d48Sopenharmony_ci{ 249fb726d48Sopenharmony_ci switch (op) { 250fb726d48Sopenharmony_ci case SQLITE_INDEX_CONSTRAINT_EQ: 251fb726d48Sopenharmony_ci rowCount = log2(rowCount); 252fb726d48Sopenharmony_ci break; 253fb726d48Sopenharmony_ci case SQLITE_INDEX_CONSTRAINT_GT: 254fb726d48Sopenharmony_ci case SQLITE_INDEX_CONSTRAINT_GE: 255fb726d48Sopenharmony_ci case SQLITE_INDEX_CONSTRAINT_LE: 256fb726d48Sopenharmony_ci case SQLITE_INDEX_CONSTRAINT_LT: 257fb726d48Sopenharmony_ci rowCount = (rowCount >> 1); 258fb726d48Sopenharmony_ci break; 259fb726d48Sopenharmony_ci default: 260fb726d48Sopenharmony_ci return false; 261fb726d48Sopenharmony_ci } 262fb726d48Sopenharmony_ci return true; 263fb726d48Sopenharmony_ci} 264fb726d48Sopenharmony_ci 265fb726d48Sopenharmony_ciTableBase::Cursor::~Cursor() 266fb726d48Sopenharmony_ci{ 267fb726d48Sopenharmony_ci context_ = nullptr; 268fb726d48Sopenharmony_ci dataCache_ = nullptr; 269fb726d48Sopenharmony_ci} 270fb726d48Sopenharmony_civoid TableBase::Cursor::FilterTS(unsigned char op, sqlite3_value *argv, const std::deque<InternalTime> ×) 271fb726d48Sopenharmony_ci{ 272fb726d48Sopenharmony_ci auto v = static_cast<uint64_t>(sqlite3_value_int64(argv)); 273fb726d48Sopenharmony_ci auto getValue = [](const uint64_t &row) { return row; }; 274fb726d48Sopenharmony_ci switch (op) { 275fb726d48Sopenharmony_ci case SQLITE_INDEX_CONSTRAINT_EQ: 276fb726d48Sopenharmony_ci indexMap_->IntersectabcEqual(times, v, getValue); 277fb726d48Sopenharmony_ci break; 278fb726d48Sopenharmony_ci case SQLITE_INDEX_CONSTRAINT_GT: 279fb726d48Sopenharmony_ci v++; 280fb726d48Sopenharmony_ci case SQLITE_INDEX_CONSTRAINT_GE: { 281fb726d48Sopenharmony_ci indexMap_->IntersectGreaterEqual(times, v, getValue); 282fb726d48Sopenharmony_ci break; 283fb726d48Sopenharmony_ci } 284fb726d48Sopenharmony_ci case SQLITE_INDEX_CONSTRAINT_LE: 285fb726d48Sopenharmony_ci v++; 286fb726d48Sopenharmony_ci case SQLITE_INDEX_CONSTRAINT_LT: { 287fb726d48Sopenharmony_ci indexMap_->IntersectLessEqual(times, v, getValue); 288fb726d48Sopenharmony_ci break; 289fb726d48Sopenharmony_ci } 290fb726d48Sopenharmony_ci case SQLITE_INDEX_CONSTRAINT_ISNOTNULL: { 291fb726d48Sopenharmony_ci indexMap_->RemoveNullElements(times, v); 292fb726d48Sopenharmony_ci break; 293fb726d48Sopenharmony_ci } 294fb726d48Sopenharmony_ci default: 295fb726d48Sopenharmony_ci break; 296fb726d48Sopenharmony_ci } // end of switch (op) 297fb726d48Sopenharmony_ci} 298fb726d48Sopenharmony_ci 299fb726d48Sopenharmony_ciint32_t TableBase::Cursor::RowId(sqlite3_int64 *id) 300fb726d48Sopenharmony_ci{ 301fb726d48Sopenharmony_ci if (dataCache_->Cancel() || indexMap_->Eof()) { 302fb726d48Sopenharmony_ci return SQLITE_ERROR; 303fb726d48Sopenharmony_ci } 304fb726d48Sopenharmony_ci *id = static_cast<sqlite3_int64>(indexMap_->CurrentRow()); 305fb726d48Sopenharmony_ci return SQLITE_OK; 306fb726d48Sopenharmony_ci} 307fb726d48Sopenharmony_civoid TableBase::Cursor::FilterId(unsigned char op, sqlite3_value *argv) 308fb726d48Sopenharmony_ci{ 309fb726d48Sopenharmony_ci auto type = sqlite3_value_type(argv); 310fb726d48Sopenharmony_ci if (type != SQLITE_INTEGER) { 311fb726d48Sopenharmony_ci // other type consider it NULL 312fb726d48Sopenharmony_ci indexMap_->Intersect(0, 0); 313fb726d48Sopenharmony_ci return; 314fb726d48Sopenharmony_ci } 315fb726d48Sopenharmony_ci if (indexMap_->HasData()) { 316fb726d48Sopenharmony_ci indexMap_->ConvertToIndexMap(); 317fb726d48Sopenharmony_ci } 318fb726d48Sopenharmony_ci 319fb726d48Sopenharmony_ci auto v = static_cast<TableRowId>(sqlite3_value_int64(argv)); 320fb726d48Sopenharmony_ci switch (op) { 321fb726d48Sopenharmony_ci case SQLITE_INDEX_CONSTRAINT_EQ: 322fb726d48Sopenharmony_ci indexMap_->Intersect(v, v + 1); 323fb726d48Sopenharmony_ci break; 324fb726d48Sopenharmony_ci case SQLITE_INDEX_CONSTRAINT_GE: 325fb726d48Sopenharmony_ci indexMap_->Intersect(v, rowCount_); 326fb726d48Sopenharmony_ci break; 327fb726d48Sopenharmony_ci case SQLITE_INDEX_CONSTRAINT_GT: 328fb726d48Sopenharmony_ci v++; 329fb726d48Sopenharmony_ci indexMap_->Intersect(v, rowCount_); 330fb726d48Sopenharmony_ci break; 331fb726d48Sopenharmony_ci case SQLITE_INDEX_CONSTRAINT_LE: 332fb726d48Sopenharmony_ci v++; 333fb726d48Sopenharmony_ci indexMap_->Intersect(0, v); 334fb726d48Sopenharmony_ci break; 335fb726d48Sopenharmony_ci case SQLITE_INDEX_CONSTRAINT_LT: 336fb726d48Sopenharmony_ci indexMap_->Intersect(0, v); 337fb726d48Sopenharmony_ci break; 338fb726d48Sopenharmony_ci default: 339fb726d48Sopenharmony_ci // can't filter, all rows 340fb726d48Sopenharmony_ci break; 341fb726d48Sopenharmony_ci } 342fb726d48Sopenharmony_ci} 343fb726d48Sopenharmony_ci 344fb726d48Sopenharmony_cidouble TableBase::CalculateFilterCost(int64_t rowCount, FilterConstraints &fc) 345fb726d48Sopenharmony_ci{ 346fb726d48Sopenharmony_ci auto constraints = fc.GetConstraints(); 347fb726d48Sopenharmony_ci if (constraints.empty()) { // scan all rows 348fb726d48Sopenharmony_ci return rowCount; 349fb726d48Sopenharmony_ci } 350fb726d48Sopenharmony_ci double filterCost = 0.0; 351fb726d48Sopenharmony_ci for (int32_t i = 0; i < static_cast<int32_t>(constraints.size()); i++) { 352fb726d48Sopenharmony_ci if (rowCount <= 1) { 353fb726d48Sopenharmony_ci // only one row or nothing, needn't filter by constraint 354fb726d48Sopenharmony_ci filterCost += rowCount; 355fb726d48Sopenharmony_ci break; 356fb726d48Sopenharmony_ci } 357fb726d48Sopenharmony_ci FilterByConstraint(fc, filterCost, rowCount, i); 358fb726d48Sopenharmony_ci } 359fb726d48Sopenharmony_ci return filterCost; 360fb726d48Sopenharmony_ci} 361fb726d48Sopenharmony_civoid TableBase::EstimateFilterCost(FilterConstraints &fc, EstimatedIndexInfo &ei) 362fb726d48Sopenharmony_ci{ 363fb726d48Sopenharmony_ci constexpr double filterBaseCost = 1000.0; // set-up and tear-down 364fb726d48Sopenharmony_ci constexpr double indexCost = 2.0; 365fb726d48Sopenharmony_ci ei.estimatedCost = filterBaseCost; 366fb726d48Sopenharmony_ci auto rowCount = GetSize(); 367fb726d48Sopenharmony_ci if (rowCount > -1) { 368fb726d48Sopenharmony_ci if (rowCount == 0 || rowCount == 1) { 369fb726d48Sopenharmony_ci ei.estimatedRows = rowCount; 370fb726d48Sopenharmony_ci ei.estimatedCost += indexCost * rowCount; 371fb726d48Sopenharmony_ci return; 372fb726d48Sopenharmony_ci } 373fb726d48Sopenharmony_ci ei.estimatedCost += CalculateFilterCost(rowCount, fc); 374fb726d48Sopenharmony_ci ei.estimatedRows = rowCount; 375fb726d48Sopenharmony_ci ei.estimatedCost += rowCount * indexCost; 376fb726d48Sopenharmony_ci ei.isOrdered = true; 377fb726d48Sopenharmony_ci 378fb726d48Sopenharmony_ci GetOrbyes(fc, ei); 379fb726d48Sopenharmony_ci } 380fb726d48Sopenharmony_ci} 381fb726d48Sopenharmony_ci 382fb726d48Sopenharmony_ci} // namespace TraceStreamer 383fb726d48Sopenharmony_ci} // namespace SysTuning 384