-
Notifications
You must be signed in to change notification settings - Fork 207
Feat: Add condition in the union macro for conditional union of tables #4337
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
sqlmesh/core/macros.py
Outdated
@macro() | ||
def union_if( | ||
evaluator: MacroEvaluator, | ||
condition: exp.Expression, | ||
type_: exp.Literal = exp.Literal.string("ALL"), | ||
*tables: exp.Table, | ||
) -> exp.Query: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't we extend the existing @UNION
macro somehow to make this work? Having a separate _if
variant is not great.
Perhaps you could extend the argument list to make the condition
argument keyword-only. Alternatively, you could make it the first argument in the list, which is consistent with other macros, and try to migrate existing models or make it backwards-compatible by checking if the first argument is 'all'
or 'distinct'
to preserve the old behavior.
cc @tobymao
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was initially thinking of simply extending the existing @union macro as well, but ended up leaning against it because you'd either need to compromise a bit on the parameter structure, as you mentioned, or require migration of existing models and for people to learn the new way.
Also, looking back at the original issue, it seems there was a need to support both tables and select statements as inputs. That adds complexity, and having a dedicated variant might make that clearer and easier to manage in practice, even if it's not ideal from a naming standpoint. Though for the tables the union logic for tables could still be reused with a helper. But yes happy to go down whatever route sounds more sound.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what does extending union look like?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are two ways I was thinking it could be extended:
1. @UNION(<condition>, 'distinct', table1, table2, ...)
2. @UNION('distinct', table1, table2, ..., condition := <condition>)
The first one is backwards-incompatible and would require a migration. Perhaps one way to make it backwards-compatible and avoid that is to always evaluate the first argument and if it produces TRUE
or FALSE
, we treat it as a condition, otherwise we treat it as the existing type_
argument.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we could do the first one, in a backwards compatible way, and make it check if it's a string literal right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it only accepts all or distinct right now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok thanks I will alter it this way
a8eb123
to
178d59d
Compare
178d59d
to
8b30347
Compare
This update extends the
@UNION
macro with a condition that is statically evaluatable and if it is false it short-circuits and it only keeps the first table, otherwise unions all tables, fixes: #4202Example:
the previous behaviour when the first argument can't be interpreted as a conditional True or False remains with the first argument being the union type and then the table names.