Spec-Zone.ru › SQLite

Определение, является ли запрос виртуальной таблицы DISTINCT

int sqlite3_vtab_distinct(sqlite3_index_info*);

Этот API может быть использован только изнутри метода xBestIndex реализации виртуальной таблицы. Результат вызова этого интерфейса вне xBestIndex() не определён и, вероятно, вреден.

Интерфейс sqlite3_vtab_distinct() возвращает целое число от 0 до 3. Возвращаемое целое число sqlite3_vtab_distinct() предоставляет виртуальной таблице дополнительную информацию о том, как планировщик запросов хочет, чтобы вывод был упорядочен. Пока виртуальная таблица может удовлетворить требованиям упорядочения планировщика запросов, она может установить флаг «orderByConsumed».

  1. Если интерфейс sqlite3_vtab_distinct() возвращает 0, это означает, что планировщик запросов требует от виртуальной таблицы возвращения всех строк в порядке сортировки, определённом полями «nOrderBy» и «aOrderBy» объекта sqlite3_index_info. Это ожидаемое значение по умолчанию. Если виртуальная таблица выводит все строки в отсортированном порядке, то для метода xBestIndex всегда безопасно установить флаг «orderByConsumed», независимо от значения, возвращаемого sqlite3_vtab_distinct().

  2. Если интерфейс sqlite3_vtab_distinct() возвращает 1, это означает, что планировщик запросов не требует возвращения строк в отсортированном порядке, при условии, что все строки с одинаковыми значениями во всех столбцах, определённых полем «aOrderBy», являются смежными. Этот режим используется, когда планировщик запросов выполняет GROUP BY.

  3. Если интерфейс sqlite3_vtab_distinct() возвращает 2, это означает, что планировщик запросов не требует возвращения строк в определённом порядке, при условии, что строки с одинаковыми значениями во всех столбцах, определённых полем «aOrderBy», являются смежными. Кроме того, когда две или более строки содержат одинаковые значения для всех столбцов, определённых полем «colUsed», все, кроме одной такой строки, могут быть необязательно опущены из результата. Виртуальная таблица не обязана опускать строки, являющиеся дубликатами по столбцам «colUsed», но если виртуальная таблица может сделать это без лишних усилий, это может потенциально ускорить выполнение запроса. Этот режим используется для запроса DISTINCT.

  4. Если интерфейс sqlite3_vtab_distinct() возвращает 3, это означает, что виртуальная таблица должна возвращать строки в порядке, определённом полем «aOrderBy», как если бы интерфейс sqlite3_vtab_distinct() возвращал 0. Однако, если две или более строки в результате имеют одинаковые значения для всех столбцов, определённых полем «colUsed», все, кроме одной такой строки, могут быть необязательно опущены. Как и в случае с возвращаемым значением 2, виртуальная таблица не обязана опускать строки, являющиеся дубликатами по столбцам «colUsed», но если виртуальная таблица может сделать это без лишних усилий, это может потенциально ускорить выполнение запроса. Этот режим используется для запросов, имеющих как DISTINCT, так и ORDER BY.

В следующей таблице подытожены условия, при которых виртуальная таблица может установить флаг «orderByConsumed», в зависимости от значения, возвращаемого sqlite3_vtab_distinct(). Эта таблица — перефразировка предыдущих четырёх абзацев:

Возвращаемое значение sqlite3_vtab_distinct() Строки возвращаются в порядке aOrderBy Строки с одинаковым значением во всех столбцах aOrderBy смежны Дубликаты по всем столбцам colUsed могут быть опущены
0 да да нет
1 нет да нет
2 нет да да
3 да да да

Для сравнения значений вывода виртуальной таблицы с целью определения, являются ли значения одинаковыми для целей сортировки, два значения NULL считаются одинаковыми. Другими словами, оператор сравнения — «IS» (или «IS NOT DISTINCT FROM»), а не «==».

Если реализация виртуальной таблицы не может выполнить указанные выше требования, она не должна устанавливать флаг «orderByConsumed» в объекте sqlite3_index_info, иначе может получиться неверный ответ.

Реализация виртуальной таблицы всегда может возвращать строки в любом порядке, при условии, что флаг «orderByConsumed» не установлен. Когда флаг «orderByConsumed» не установлен, планировщик запросов добавит дополнительные байткоды для обеспечения правильного упорядочения конечных результатов SQL-запроса. Использование флага «orderByConsumed» и интерфейса sqlite3_vtab_distinct() — просто оптимизация. Осторожное использование интерфейса sqlite3_vtab_distinct() и флага «orderByConsumed» может ускорить запросы к виртуальной таблице. С другой стороны, излишняя агрессивность и установка флага «orderByConsumed», когда это неправомерно, может привести к неправильным результатам в SQLite.

См. также списки объектов, констант и функций.

SQLite is in the Public Domain.
https://sqlite.org/c3ref/vtab_distinct.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API