blob: e438386d023afa715704574ba4f58ff3618a3c92 [file] [log] [blame]
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SRC_TRACE_PROCESSOR_SQLITE_DB_SQLITE_TABLE_H_
#define SRC_TRACE_PROCESSOR_SQLITE_DB_SQLITE_TABLE_H_
#include <sqlite3.h>
#include <cstdint>
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include "perfetto/trace_processor/basic_types.h"
#include "src/trace_processor/db/column/types.h"
#include "src/trace_processor/db/runtime_table.h"
#include "src/trace_processor/db/table.h"
#include "src/trace_processor/perfetto_sql/intrinsics/table_functions/static_table_function.h"
#include "src/trace_processor/sqlite/bindings/sqlite_module.h"
#include "src/trace_processor/sqlite/module_lifecycle_manager.h"
namespace perfetto::trace_processor {
enum class TableComputation {
// Table is statically defined.
kStatic,
// Table is defined as a function.
kTableFunction,
// Table is defined in runtime.
kRuntime
};
// Implements the SQLite table interface for db tables.
struct DbSqliteModule : public sqlite::Module<DbSqliteModule> {
struct State {
State(Table*, Table::Schema);
explicit State(std::unique_ptr<RuntimeTable>);
explicit State(std::unique_ptr<StaticTableFunction>);
TableComputation computation;
Table::Schema schema;
int argument_count = 0;
// Only valid when computation == TableComputation::kStatic.
Table* static_table = nullptr;
// Only valid when computation == TableComputation::kRuntime.
std::unique_ptr<RuntimeTable> runtime_table;
// Only valid when computation == TableComputation::kTableFunction.
std::unique_ptr<StaticTableFunction> static_table_function;
private:
State(TableComputation, Table::Schema);
};
struct Context {
std::unique_ptr<State> temporary_create_state;
sqlite::ModuleStateManager<DbSqliteModule> manager;
};
struct Vtab : public sqlite::Module<DbSqliteModule>::Vtab {
sqlite::ModuleStateManager<DbSqliteModule>::PerVtabState* state;
int best_index_num = 0;
std::string table_name;
};
struct Cursor : public sqlite::Module<DbSqliteModule>::Cursor {
enum class Mode {
kSingleRow,
kTable,
};
const Table* upstream_table = nullptr;
// Only valid for |db_sqlite_table_->computation_| ==
// TableComputation::kDynamic.
std::unique_ptr<Table> dynamic_table;
// Only valid for Mode::kSingleRow.
std::optional<uint32_t> single_row;
// Only valid for Mode::kTable.
std::optional<Table::Iterator> iterator;
bool eof = true;
// Stores a sorted version of |db_table| sorted on a repeated equals
// constraint. This allows speeding up repeated subqueries in joins
// significantly.
std::optional<Table> sorted_cache_table;
// Stores the count of repeated equality queries to decide whether it is
// wortwhile to sort |db_table| to create |sorted_cache_table|.
uint32_t repeated_cache_count = 0;
Mode mode = Mode::kSingleRow;
int last_idx_num = -1;
Query query;
std::vector<SqlValue> table_function_arguments;
};
struct QueryCost {
double cost;
uint32_t rows;
};
static constexpr bool kSupportsWrites = false;
static constexpr bool kDoesOverloadFunctions = false;
static int Create(sqlite3*,
void*,
int,
const char* const*,
sqlite3_vtab**,
char**);
static int Destroy(sqlite3_vtab*);
static int Connect(sqlite3*,
void*,
int,
const char* const*,
sqlite3_vtab**,
char**);
static int Disconnect(sqlite3_vtab*);
static int BestIndex(sqlite3_vtab*, sqlite3_index_info*);
static int Open(sqlite3_vtab*, sqlite3_vtab_cursor**);
static int Close(sqlite3_vtab_cursor*);
static int Filter(sqlite3_vtab_cursor*,
int,
const char*,
int,
sqlite3_value**);
static int Next(sqlite3_vtab_cursor*);
static int Eof(sqlite3_vtab_cursor*);
static int Column(sqlite3_vtab_cursor*, sqlite3_context*, int);
static int Rowid(sqlite3_vtab_cursor*, sqlite_int64*);
// static for testing.
static QueryCost EstimateCost(const Table::Schema&,
uint32_t row_count,
sqlite3_index_info* info,
const std::vector<int>&,
const std::vector<int>&);
// This needs to happen at the end as it depends on the functions
// defined above.
static constexpr sqlite3_module kModule = CreateModule();
};
} // namespace perfetto::trace_processor
#endif // SRC_TRACE_PROCESSOR_SQLITE_DB_SQLITE_TABLE_H_