![]() |
|
|||
WebMoney: WMZ Z294115950220 WMR R409981405661 WME E134003968233 |
Visa 4274 3200 2453 6495 |
Структура sqlite3_index_info и ее подструктуры
используются в качестве части интерфейса
виртуальной таблицы, чтобы передать информацию и
получить ответ от метода xBestIndex
модуля виртуальной таблицы.
Области под **Inputs** это ввод для xBestIndex, они read-only. xBestIndex
вставляет свои результаты в поля **Outputs**. Массив aConstraint[] делает запись ограничений оператора WHERE: здесь OP это =, <, <=, > или >=.
Конкретный оператор сохранен в aConstraint[].op с использованием одного из
значений SQLITE_INDEX_CONSTRAINT_.
Индекс колонки сохранен в aConstraint[].iColumn. aConstraint[].usable = TRUE,
если expr на правой стороне может быть оценен (и таким образом ограничение
применимое) и false, если это не так. Оптимизатор автоматически инвертирует условия формы "expr OP column"
и делает другие упрощения в операторе 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 = true,
то ограничение, как предполагается, полностью обработано виртуальной таблицей
и не могло бы быть проверено снова байт-кодом. Флаг aConstraintUsage[].omit
является намеком оптимизации. Когда флаг omit в его настройке по умолчанию
false, ограничение будет всегда проверяться отдельно в байт-коде.
Если флаг omit = true, то ограничение может или не может быть проверено в
байт-коде. Другими словами, когда omit = true,
нет никакой гарантии, что ограничение не будет проверено снова,
используя байт-код. idxNum и idxStr зарегистрированы и переданы в метод
xFilter.
sqlite3_free() используется, чтобы освободить
idxStr если и только если needToFreeIdxStr = true. orderByConsumed означает, что вывод от
xFilter/xNext
произойдет в правильном порядке, чтобы удовлетворить пункт ORDER BY
так, чтобы никакой отдельный шаг сортировки не требовался. Значение estimatedCost это оценка стоимости конкретной стратегии.
Стоимость N указывает, что стоимость стратегии подобна линейному просмотру
таблицы SQLite с N строками. Стоимость log(N) указывает, что расход операции
подобен двоичному поиску на уникальной индексируемой области
таблицы SQLite с N строками. Значение estimatedRows это оценка количества строк,
которые будут возвращены стратегией. Метод xBestIndex может произвольно наполнить поле idxFlags
маской флагов SQLITE_INDEX_SCAN_*. В настоящее время есть только один такой
флаг SQLITE_INDEX_SCAN_UNIQUE. Если метод xBestIndex его установит, SQLite
предполагает, что стратегия может посетить самое большее одну строку. Кроме того, если xBestIndex устанавливает флаг SQLITE_INDEX_SCAN_UNIQUE,
то SQLite также предполагает, что, если вызов метода xUpdate()
сделан как часть того же самого запроса, чтобы удалить или обновить
виртуальную строку таблицы и внедрение возвращает SQLITE_CONSTRAINT, то нет
никакой потребности к обратной перемотке никаких изменений базы данных.
Другими словами, если xUpdate() вернет SQLITE_CONSTRAINT,
содержание базы данных должно быть точно таким, каким было прежде, чем
вызвали xUpdate. В отличие от этого, если SQLITE_INDEX_SCAN_UNIQUE не
установлен, и xUpdate вернет SQLITE_CONSTRAINT,
любые изменения базы данных, внесенные методом xUpdate,
автоматически отменены SQLite. ВАЖНО: поле estimatedRows было добавлено к структуре sqlite3_index_info
в SQLite version 3.8.2
(2013-12-06). Если виртуальное расширение таблицы
используется с версией SQLite ранее, чем 3.8.2, результаты попытки прочитать
или написать поле estimatedRows не определены (но, вероятно, будут включать
сбой приложения). Поэтому estimatedRows можно использовать
только если sqlite3_libversion_number()
возвращает значение больше или равное 3008002.
Точно так же поле idxFlags добавлено в
version 3.9.0 (2015-10-14).
Это может использоваться только, если sqlite3_libversion_number()
возвращает значение больше или равное 3009000. 3 метода, использующих этот объект:
sqlite3_vtab_collation(),
sqlite3_vtab_distinct(),
sqlite3_vtab_rhs_value()
Choose any three.
SQLite C Interface
Виртуальная таблица информации индекса
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 */
};
column OP expr