Spec-Zone.ru › DuckDB

Совместимость с 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

Spec-Zone.ru

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