Приложение D. Специальные типы данных в pgpro_axe
В pgpro_axe представлено несколько специальных типов данных Postgres Pro. Эти типы не нужно создавать в явном виде, но периодически они могут отображаться в сообщениях об ошибках от Postgres Pro.
duckdb.row#Тип
duckdb.rowвозвращается такими функциями, какread_parquet,read_csvиscan_iceberg. В зависимости от аргументов эти функции могут возвращать строки с различными столбцами и типами данных. В настоящее время Postgres Pro не полностью поддерживает эти функции, поэтому они возвращают специальный тип. Чтобы получить столбцы этих строк, необходимо использовать синтаксис «square bracket indexing» (индексация квадратных скобок), как если бы вы хотели получить поле:Пример D.1.
SELECT r['id'], r['name'] FROM read_parquet('file.parquet') r WHERE r['age'] > 21;При использовании
SELECT *столбцы этой строки будут расширены, и результат вашего запроса никогда не будет содержать столбцов с типом данныхduckdb.row:Пример D.2.
SELECT * FROM read_parquet('file.parquet');Существуют ограничения по использованию функции, которая возвращает
duckdb.rowв CTE или подзапросе. Основная проблема заключается в том, что pgpro_axe не может автоматически назначать нужные псевдонимы выбранным столбцам строки.Без CTE или подзапроса такой запрос возвращает столбец
r[company]какcompany:Пример D.3.
SELECT r['company'] FROM duckdb.query($$ SELECT 'DuckDB Labs' company $$) r; -- company -- ───────────── -- DuckDB Labs
Такой же запрос в подзапросе или CTE возвращает столбец как
r:Пример D.4.
WITH mycte AS ( SELECT r['company'] FROM duckdb.query($$ SELECT 'DuckDB Labs' company $$) r ) SELECT * FROM mycte; -- r -- ───────────── -- DuckDB Labs
Это можно легко обойти, добавив явный псевдоним столбцу в CTE или подзапросе:
Пример D.5.
WITH mycte AS ( SELECT r['company'] AS company FROM duckdb.query($$ SELECT 'DuckDB Labs' company $$) r ) SELECT * FROM mycte; -- company -- ───────────── -- DuckDB Labs
Другим ограничением является то, что если при использовании
SELECT *в CTE или подзапросе необходимо указать конкретный столбец вне CTE или подзапроса, вам всё равно потребуется использовать синтаксисr['имя_столбца']вместоимя_столбца.Хотя такой запрос работает нормально:
Пример D.6.
WITH mycte AS ( SELECT * FROM duckdb.query($$ SELECT 'DuckDB Labs' company $$) r ) SELECT * FROM mycte; -- company -- ───────────── -- DuckDB Labs
При выполнении следующего запроса происходит ошибка:
Пример D.7.
WITH mycte AS ( SELECT * FROM duckdb.query($$ SELECT 'DuckDB Labs' company $$) r ) SELECT * FROM mycte WHERE company = 'DuckDB Labs'; -- ERROR: 42703: column "company" does not exist -- LINE 5: SELECT * FROM mycte WHERE company = 'DuckDB Labs'; -- ^ -- Подсказка: При использовании таких функций DuckDB, как read_parquet, для использования столбцов потребуется синтаксис r['colname']. Если этот синтаксис уже используется, возможно вы забыли назначить функции псевдоним r.
Это можно легко обойти с помощью следующего синтаксиса
r['имя_столбца']:Пример D.8.
> WITH mycte AS ( SELECT * FROM duckdb.query($$ SELECT 'DuckDB Labs' company $$) r ) SELECT * FROM mycte WHERE r['company'] = 'DuckDB Labs'; -- company -- ───────────── -- DuckDB Labs
duckdb.unresolved_type#Тип данных
duckdb.unresolved_typeиспользуется, чтобы позволить Postgres Pro понять выражение, содержащее тип данных, который неизвестен в момент разбора запроса. Это может быть тип любого столбца, извлечённого изduckdb.rowс помощью синтаксисаr['имя_столбца']. Многие операторы и агрегатные функции возвращаютduckdb.unresolved_type, если одна из сторон оператора имеет тип данныхduckdb.unresolved_type, напримерr['age'] + 10.При выполнении запроса DuckDB указывается реальный тип данных, поэтому результат запроса никогда не содержит столбцов с типом данных
duckdb.unresolved_type.Вы можете столкнуться с ошибками, в которых сообщается о том, что определённые функции и операции не существуют для типа данных
duckdb.unresolved_type:Пример D.9.
ERROR: function some_func(duckdb.unresolved_type) does not exist LINE 6: some_func(r['somecol']) as somecol
В таких случаях обходное решение — добавить явное преобразование в принимаемый функцией тип данных, например
some_func(r['somecol']::text) as somecol.duckdb.json#Тип данных
duckdb.jsonиспользуется для аргументов JSON-функций DuckDB. Он позволяет этим функциям принимать значенияjson,jsonbиduckdb.unresolved_type.