DuckDB: как мне создать таблицу, содержащую столбец с определенным именем из `CREATE MACRO... AS TABLE...`?

Предположим, у меня есть следующий макрос:

CREATE OR REPLACE MACRO hello_world(col_name, series_start, series_end) AS TABLE (
    SELECT generate_series::VARCHAR AS col_name
    FROM generate_series(series_start, series_end)
  );
CREATE OR REPLACE TABLE tbl AS
FROM hello_world('world', 3, 5);
SHOW TABLES;

Исполнение производит:

┌─────────┐
│  name   │
│ varchar │
├─────────┤
│ tbl     │
└─────────┘

┌──────────┐
│ col_name │
│ varchar  │
├──────────┤
│ 3        │
│ 4        │
│ 5        │
└──────────┘

Но мне нужен столбец с именем «мир», но я получил столбец с именем col_name (имя параметра макроса): так как мне правильно убедиться, что значение параметра макроса используется в качестве имени столбца?

🤔 А знаете ли вы, что...
SQL может выполнять рекурсивные запросы для работы с иерархическими данными.


2
56
2

Ответы:

Решено

В связи с аналогичным вопросом один из авторитетов DuckDB написал:

Мне кажется, здесь есть некоторая путаница в том, как работают параметры макросов. Параметры макроса являются выражениями, поэтому они могут только заменять выражения в запросе.

Далее автор подчеркивает различие между идентификаторами и выражениями.

Как правило, это может означать, что если формальный аргумент игнорируется, то это происходит из-за принципа, изложенного выше. Другими словами, это особенность. Это не означает, что запрос на улучшение не может быть сделан. А пока можно конечно alter table tbl rename 'col_name' to 'world';


Если вы создадите строку запроса, ее можно выполнить с помощью json_execute_serialized_sql()

duckdb.sql("""
create or replace macro hello_world(col_name, series_start, series_end) as table (
   from json_execute_serialized_sql(json_serialize_sql(
      format('
         select generate_series::varchar as {}
         from generate_series({}, {})
      ', col_name, series_start, series_end)
  ))
)
""")
duckdb.sql("""
create or replace table tbl as from hello_world('world', 3, 5);
from tbl
""")
┌─────────┐
│  world  │
│ varchar │
├─────────┤
│ 3       │
│ 4       │
│ 5       │
└─────────┘