2

Suppose I have the following macro:

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;

Execution produces:

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

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

But I wanted a column named 'world', yet I got a column named col_name (the macro parameter's name): so how do I correctly make sure that the macro parameter's value is used as a column name?

0

2 Answers 2

2

You can build a query string and execute it with query()

duckdb.sql("""
create or replace macro hello_world(col_name, series_start, series_end) as table (
   from query(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       │
└─────────┘
Sign up to request clarification or add additional context in comments.

Comments

1

In connection with a similar question, one of the DuckDB powers-that-be wrote:

I think there is some confusion here in how macro parameters work. Macro parameters are expressions, as such they can only replace expressions in a query.

The author goes on to emphasize the distinction between identifiers and expressions.

As a rule of thumb, this can be taken to mean that if a formal argument is being ignored, that's because of the principle enunciated above. In other words, it's a feature. Which is not to say an enhancement request couldn't be made. In the meantime, you could of course alter table tbl rename 'col_name' to 'world';

2 Comments

Thank you. I think it's very weird that I cannot use a variable as a variable. I could do alter table tbl rename 'col_name' to 'world'; but that ignores the fact that I do not know that col_name is 'world' for the use case I was thinking of --- col_name is truly a variable. Overall, the answer that one seems to be lead by this issue together with others is that DuckDB SQL is that it's meant to be generated by some other language (e.g. using Python).
Yes, "macro" is very misleading. An alternative to a programming language approach would be "dynamic sql" based on the DuckDB CLI (e.g. using .once and .read). But an enhancement request might make a difference.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.