Информация об индексировании виртуальных таблиц
struct sqlite3_index_info {
/* Inputs */
int nConstraint; /* Number of entries in aConstraint */
struct sqlite3_index_constraint {
int iColumn; /* Column constrained. -1 for ROWID */
unsigned char op; /* Constraint operator */
unsigned char usable; /* True if this constraint is usable */
int iTermOffset; /* Used internally - xBestIndex should ignore */
} *aConstraint; /* Table of WHERE clause constraints */
int nOrderBy; /* Number of terms in the ORDER BY clause */
struct sqlite3_index_orderby {
int iColumn; /* Column number */
unsigned char desc; /* True for DESC. False for ASC. */
} *aOrderBy; /* The ORDER BY clause */
/* Outputs */
struct sqlite3_index_constraint_usage {
int argvIndex; /* if >0, constraint is part of argv to xFilter */
unsigned char omit; /* Do not code a test for this constraint */
} *aConstraintUsage;
int idxNum; /* Number used to identify the index */
char *idxStr; /* String, possibly obtained from sqlite3_malloc */
int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */
int orderByConsumed; /* True if output is already ordered */
double estimatedCost; /* Estimated cost of using this index */
/* Fields below are only available in SQLite 3.8.2 and later */
sqlite3_int64 estimatedRows; /* Estimated number of rows returned */
/* Fields below are only available in SQLite 3.9.0 and later */
int idxFlags; /* Mask of SQLITE_INDEX_SCAN_* flags */
/* Fields below are only available in SQLite 3.10.0 and later */
sqlite3_uint64 colUsed; /* Input: Mask of columns used by statement */
};
Структура sqlite3_index_info и её подструктуры используются как часть интерфейса виртуальных таблиц для передачи информации и получения ответа от метода xBestIndex модуля виртуальной таблицы. Поля в разделе **Вводные данные** являются входными данными для xBestIndex и являются только для чтения. xBestIndex вставляет свои результаты в поля **Выходные данные**.
Массив aConstraint[] записывает ограничения условия WHERE в формате:
столбец ОП выражение
где ОП — это =, <, <=, > или >=. Конкретный оператор хранится в aConstraint[].op с использованием одного из значений SQLITE_INDEX_CONSTRAINT. Индекс столбца хранится в aConstraint[].iColumn. aConstraint[].usable имеет значение ИСТИНА, если выражение в правой части может быть вычислено (и, следовательно, ограничение применимо), и ЛОЖЬ, если нет.
Оптимизатор автоматически инвертирует члены вида «выражение ОП столбец» и выполняет другие упрощения условия WHERE, пытаясь получить как можно больше членов условия WHERE в указанном выше формате. Массив aConstraint[] сообщает только о членах условия WHERE, относящихся к конкретной виртуальной таблице, к которой обращаются.
Информация об операторе ORDER BY хранится в aOrderBy[]. Каждый член aOrderBy записывает столбец из оператора ORDER BY.
Поле colUsed указывает, какие столбцы виртуальной таблицы могут потребоваться для текущего сканирования. Столбцы виртуальной таблицы нумеруются с нуля в порядке, в котором они появляются в операторе CREATE TABLE, переданном в sqlite3_declare_vtab(). Для первых 63 столбцов (столбцы 0-62) соответствующий бит устанавливается в маске colUsed, если столбец может потребоваться SQLite. Если таблица имеет не менее 64 столбцов и какой-либо столбец справа от первых 63 столбцов требуется, то также устанавливается бит 63 colUsed. Другими словами, столбец iCol может потребоваться, если выражение (colUsed & ((sqlite3_uint64)1 << (iCol>=63 ? 63 : iCol))) оценивается как ненулевое.
Метод xBestIndex должен заполнить aConstraintUsage[] информацией о том, какие параметры передать в xFilter. Если argvIndex>0, правая часть соответствующего aConstraint[] вычисляется и становится argvIndex-м элементом в argv. Если aConstraintUsage[].omit имеет значение ИСТИНА, то предполагается, что ограничение полностью обрабатывается виртуальной таблицей и, возможно, не будет проверяться кодом байт-кода повторно. Флаг aConstraintUsage[].omit — это подсказка по оптимизации. Когда флаг omit оставлен в своём значении по умолчанию — ЛОЖЬ, ограничение всегда будет проверяться отдельно в коде байт-кода. Если флаг omit изменён на ИСТИНА, то ограничение может или не может проверяться в коде байт-кода. Другими словами, когда флаг omit имеет значение ИСТИНА, нет гарантии, что ограничение не будет проверяться повторно с использованием байт-кода.
Значения idxNum и idxStr записываются и передаются в метод xFilter. sqlite3_free() используется для освобождения idxStr только в том случае, если needToFreeIdxStr имеет значение ИСТИНА.
orderByConsumed означает, что вывод от xFilter/xNext будет происходить в правильном порядке для удовлетворения условия ORDER BY, так что дополнительный шаг сортировки не требуется.
Значение estimatedCost — это оценка стоимости конкретной стратегии. Стоимость N указывает, что стоимость стратегии аналогична линейному сканированию таблицы SQLite с N строками. Стоимость log(N) указывает, что стоимость операции аналогична двоичному поиску по уникальному индексированному полю таблицы SQLite с N строками.
Значение estimatedRows — это оценка количества строк, которые будут возвращены стратегией.
Метод xBestIndex может дополнительно заполнить поле idxFlags маской флагов SQLITE_INDEX_SCAN_*. Одним из таких флагов является SQLITE_INDEX_SCAN_HEX, который, если установлен, заставляет вывод EXPLAIN QUERY PLAN отображать idxNum в шестнадцатеричном формате вместо десятичного. Другим флагом является SQLITE_INDEX_SCAN_UNIQUE, который, если установлен, указывает, что план запроса вернёт не более одной строки.
Кроме того, если xBestIndex установит флаг SQLITE_INDEX_SCAN_UNIQUE, то SQLite также предположит, что если вызов метода xUpdate() выполняется в рамках одного оператора для удаления или обновления строки виртуальной таблицы, и реализация возвращает SQLITE_CONSTRAINT, то нет необходимости отменять любые изменения в базе данных. Другими словами, если xUpdate() возвращает SQLITE_CONSTRAINT, содержимое базы данных должно быть точно таким же, как и до вызова xUpdate(). Напротив, если SQLITE_INDEX_SCAN_UNIQUE не установлен, а xUpdate возвращает SQLITE_CONSTRAINT, SQLite автоматически отменяет все изменения в базе данных, внесённые методом xUpdate.
ВАЖНО: Поле estimatedRows было добавлено в структуру sqlite3_index_info для SQLite версии 3.8.2 (2013-12-06). Если расширение виртуальной таблицы используется с версией SQLite, предшествующей 3.8.2, результаты попытки чтения или записи поля estimatedRows не определены (но, вероятно, включают сбой приложения). Поэтому поле estimatedRows следует использовать только в том случае, если sqlite3_libversion_number() возвращает значение, большее или равное 3008002. Аналогично, поле idxFlags было добавлено для версии 3.9.0 (2015-10-14). Поэтому оно может использоваться только в том случае, если sqlite3_libversion_number() возвращает значение, большее или равное 3009000.
3 метода, использующие этот объект: sqlite3_vtab_collation(), sqlite3_vtab_distinct(), sqlite3_vtab_rhs_value()
См. также списки Объектов, Констант и Функций.
SQLite is in the Public Domain.
https://sqlite.org/c3ref/index_info.html