Совместимость с PostgreSQL
Диалект SQL в DuckDB тесно следует соглашениям диалекта PostgreSQL. Несколько исключений из этого перечислены на этой странице.
Арифметика с плавающей точкой
DuckDB и PostgreSQL обрабатывают арифметику с плавающей точкой при делении на ноль по-разному. DuckDB соответствует стандарту IEEE 754 для арифметики с плавающей точкой как для деления на ноль, так и для операций с бесконечными значениями. PostgreSQL возвращает ошибку при делении на ноль, но соответствует стандарту IEEE 754 для обработки бесконечных значений. Для демонстрации различий выполните следующие запросы SQL:
SELECT 1.0 / 0.0 AS x; SELECT 0.0 / 0.0 AS x; SELECT -1.0 / 0.0 AS x; SELECT 'Infinity'::FLOAT / 'Infinity'::FLOAT AS x; SELECT 1.0 / 'Infinity'::FLOAT AS x; SELECT 'Infinity'::FLOAT - 'Infinity'::FLOAT AS x; SELECT 'Infinity'::FLOAT - 1.0 AS x;
| Выражение | PostgreSQL | DuckDB | IEEE 754 |
|---|---|---|---|
| 1.0 / 0.0 | ошибка | Бесконечность | Бесконечность |
| 0.0 / 0.0 | ошибка | NaN | NaN |
| -1.0 / 0.0 | ошибка | -Бесконечность | -Бесконечность |
| 'Бесконечность' / 'Бесконечность' | NaN | NaN | NaN |
| 1.0 / 'Бесконечность' | 0.0 | 0.0 | 0.0 |
| 'Бесконечность' - 'Бесконечность' | NaN | NaN | NaN |
| 'Бесконечность' - 1.0 | Бесконечность | Бесконечность | Бесконечность |
Деление целых чисел
При вычислении деления целых чисел PostgreSQL выполняет целочисленное деление, а DuckDB выполняет деление с плавающей точкой:
SELECT 1 / 2 AS x;
PostgreSQL возвращает:
x --- 0 (1 row)
DuckDB возвращает:
| x |
|---|
| 0.5 |
Для выполнения целочисленного деления в DuckDB используйте оператор //:
SELECT 1 // 2 AS x;
| x |
|---|
| 0 |
Объединение значений булевых и целых типов
Следующий запрос не выполняется в PostgreSQL, но успешно выполняется в DuckDB:
SELECT true AS x UNION SELECT 2;
PostgreSQL возвращает ошибку:
ERROR: UNION types boolean and integer cannot be matched
DuckDB выполняет принудительное преобразование, поэтому запрос выполняется и возвращает следующее:
| x |
|---|
| 1 |
| 2 |
Чувствительность к регистру для цитируемых идентификаторов
PostgreSQL нечувствителен к регистру. Способ PostgreSQL добиться нечувствительности к регистру заключается в приведении к нижнему регистру нецитируемых идентификаторов в SQL, в то время как цитирование сохраняет регистр, например, следующая команда создает таблицу с именем mytable , но пытается запросить MyTaBLe , так как цитирование сохраняет регистр.
CREATE TABLE MyTaBLe(x INT); SELECT * FROM "MyTaBLe";
ERROR: relation "MyTaBLe" does not exist
PostgreSQL не только рассматривает цитируемые идентификаторы как чувствительные к регистру, PostgreSQL рассматривает все идентификаторы как чувствительные к регистру, например, это тоже не работает:
CREATE TABLE "PreservedCase"(x INT); SELECT * FROM PreservedCase;
ERROR: relation "preservedcase" does not exist
Следовательно, нечувствительность к регистру в PostgreSQL работает только в том случае, если вы никогда не используете цитируемые идентификаторы с разными регистрами.
Для DuckDB это поведение создавало проблемы при взаимодействии с другими инструментами (например, Parquet, Pandas), которые по умолчанию чувствительны к регистру, — поскольку все идентификаторы всегда приводились к нижнему регистру. Поэтому DuckDB добивается нечувствительности к регистру, делая идентификаторы полностью нечувствительными к регистру во всей системе, но сохраняя их регистр.
В DuckDB указанные выше скрипты выполняются успешно:
CREATE TABLE MyTaBLe(x INT); SELECT * FROM "MyTaBLe"; CREATE TABLE "PreservedCase"(x INT); SELECT * FROM PreservedCase; SELECT table_name FROM duckdb_tables();
| table_name |
|---|
| MyTaBLe |
| PreservedCase |
Поведение PostgreSQL, сводящее идентификаторы к нижнему регистру, доступно с помощью опции preserve_identifier_case:
SET preserve_identifier_case = false; CREATE TABLE MyTaBLe(x INT); SELECT table_name FROM duckdb_tables();
| table_name |
|---|
| mytable |
Однако, нечувствительность к регистру в системе для идентификаторов отключить нельзя.
Использование двойного знака равенства для сравнения
DuckDB поддерживает как = , так и == для сравнения качества, в то время как Postgres поддерживает только =.
SELECT 1 == 1 AS t;
DuckDB возвращает:
┌─────────┐ │ t │ │ boolean │ ├─────────┤ │ true │ └─────────┘
Postgres возвращает:
postgres=# SELECT 1 == 1 AS t; ERROR: operator does not exist: integer == integer LINE 1: SELECT 1 == 1 AS t;
Обратите внимание, что использование == не рекомендуется из-за его ограниченной переносимости.
Удаление таблиц
В PostgreSQL оператор VACUUM выполняет сборку мусора таблиц и анализирует таблицы. В DuckDB оператор VACUUM используется только для перестроения статистики. Для получения инструкций по освобождению места обратитесь к странице “Освобождение места”.
Функции
to_date Функция
DuckDB не поддерживает функцию форматирования дат PostgreSQL to_date. Вместо этого, пожалуйста, используйте функцию strptime.
Разрешение имён типов в схеме
Для операторов CREATE TABLE, DuckDB пытается разрешить имена типов в схеме, где создаётся таблица. Например:
CREATE SCHEMA myschema;
CREATE TYPE myschema.mytype AS ENUM ('as', 'df');
CREATE TABLE myschema.mytable (v mytype); PostgreSQL возвращает ошибку в последнем операторе:
ERROR: type "mytype" does not exist
LINE 1: CREATE TABLE myschema.mytable (v mytype);
^ DuckDB выполняет оператор и успешно создаёт таблицу, подтверждённую следующей запросом:
DESCRIBE myschema.mytable;
┌─────────────┬──────────────────┬─────────┬─────────┬─────────┬─────────┐
│ column_name │ column_type │ null │ key │ default │ extra │
│ varchar │ varchar │ varchar │ varchar │ varchar │ varchar │
├─────────────┼──────────────────┼─────────┼─────────┼─────────┼─────────┤
│ v │ ENUM('as', 'df') │ YES │ NULL │ NULL │ NULL │
└─────────────┴──────────────────┴─────────┴─────────┴─────────┴─────────┘
© Copyright 2018–2024 Stichting DuckDB Foundation
Licensed under the MIT License.
https://duckdb.org/docs/sql/dialect/postgresql_compatibility.html