Контекст
Я пытаюсь воспроизвести представления INFORMATION_SCHEMA
из MySQL в SQLite (у меня есть инструменты, которые ожидают эти представления).
Для представления INFORMATION_SCHEMA.COLUMNS
у меня есть следующий запрос
WITH RECURSIVE table_list AS
(
SELECT name, schema
FROM pragma_table_list()
UNION
SELECT name, 'main'
FROM pragma_module_list()
WHERE name NOT LIKE 'fts%'
AND name NOT LIKE 'rtree%'
),
table_info AS
(
SELECT
'def' AS TABLE_CATALOG,
tl.schema AS TABLE_SCHEMA,
tl.name AS TABLE_NAME,
ti.name AS COLUMN_NAME,
ti.cid AS ORDINAL_POSITION,
ti.dflt_value AS COLUMN_DEFAULT,
IIF(ti."notnull" AND ti.pk, 'YES', 'NO') AS IS_NULLABLE,
CASE UPPER(ti.type)
WHEN 'TEXT' THEN 'varchar'
WHEN 'INT' THEN 'bigint'
WHEN 'REAL' THEN 'float'
WHEN 'BLOB' THEN 'blob'
WHEN 'INTEGER' THEN 'bigint'
WHEN 'TINYINT' THEN 'bigint'
WHEN 'SMALLINT' THEN 'bigint'
WHEN 'MEDIUMINT' THEN 'bigint'
WHEN 'BIGINT' THEN 'bigint'
WHEN 'UNSIGNED BIG INT' THEN 'bigint'
WHEN 'INT2' THEN 'bigint'
WHEN 'INT8' THEN 'bigint'
WHEN 'VARCHAR' THEN 'varchar'
WHEN 'VARCHAR(255)' THEN 'varchar'
ELSE 'varchar'
END AS DATA_TYPE,
65535 AS CHARACTER_MAXIMUM_LENGTH,
65535 AS CHARACTER_OCTET_LENGTH,
NULL AS NUMERIC_PRECISION,
NULL AS NUMERIC_SCALE,
NULL AS DATETIME_PRECISION,
'utf8mb3' AS CHARACTER_SET_NAME,
'BINARY' AS COLLATION_NAME,
CASE UPPER(ti.type)
WHEN 'TEXT' THEN 'varchar(65535)'
WHEN 'INT' THEN 'int'
WHEN 'REAL' THEN 'double'
WHEN 'BLOB' THEN 'blob'
WHEN 'INTEGER' THEN 'int'
WHEN 'TINYINT' THEN 'int'
WHEN 'SMALLINT' THEN 'int'
WHEN 'MEDIUMINT' THEN 'int'
WHEN 'BIGINT' THEN 'int'
WHEN 'UNSIGNED BIG INT' THEN 'int'
WHEN 'INT2' THEN 'int'
WHEN 'INT8' THEN 'int'
WHEN 'VARCHAR' THEN 'varchar(65535)'
WHEN 'VARCHAR(255)' THEN 'varchar(65535)'
ELSE 'varchar(65535)'
END AS COLUMN_TYPE,
IIF(ti.pk, 'PRI', '') AS COLUMN_KEY,
IIF(tl.schema='information_schema', 'select', 'select,insert,update,references') AS PRIVILEGES,
'' AS COLUMN_COMMENT,
'' AS GENERATION_EXPRESSION,
NULL AS SRS_ID,
'' AS EXTRA
FROM
table_list tl,
pragma_table_info(tl.name) ti
)
SELECT *
FROM table_info;
который возвращает все столбцы всех таблиц.
Проблема
К этому запросу я могу добавить предложение WHERE
:
...
SELECT *
FROM table_info
WHERE TABLE_SCHEMA = 'main';
и это работает.
Я также могу добавить пункт ORDER BY
:
...
SELECT *
FROM table_info
ORDER BY TABLE_NAME, ORDINAL_POSITION;
и это тоже работает.
Однако когда я объединяю предложение WHERE
с предложением ORDER BY
, запрос не возвращает ни одной строки:
...
SELECT *
FROM table_info
WHERE TABLE_SCHEMA = 'main'
ORDER BY TABLE_NAME, ORDINAL_POSITION;
Я запускал каждый подзапрос отдельно, и они возвращали строки. Я также пытался запустить запрос только с предложением WHERE
или только с предложением ORDER BY
, и он возвращает строки.
Поэтому я ожидал, что объединение предложения WHERE
и предложения ORDER BY
сработает, но этого не произошло.
Версия SQLite: 3.45.1
@Догберт, я тоже. Я пытался поискать в документации, но нет упоминания об этой проблеме. Я начинаю думать, что это может быть ошибка. Скрипка
Также в моей скрипке, если вы измените x.name = 'posts'
на x.name <> 'posts'
, все будет работать нормально. Для меня это похоже на ошибку.
Обновление SQLite до 3.46.0 решило проблему с моей стороны.
Я использовал mattn/go-sqlite3, версия которого на данный момент составляет 3.45.1.
Не смог выяснить причину, но в итоге получил небольшой тестовый пример на случай, если кто-нибудь захочет попробовать: sqlime.org/#deta:e2jqd8sbbksb или db-fiddle.com/f/uNBgYC7emG1Rn7VdrB6ZCP/0. Комментирование одного из
where
илиorder by
возвращает результат, но оба вместе ничего не возвращают.