-
Notifications
You must be signed in to change notification settings - Fork 19
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
Refactor SQL() methods #173
Refactor SQL() methods #173
Conversation
ast/sql.go
Outdated
} | ||
sql += ")" | ||
return sql | ||
// TODO: len(s.Fields) > 0 is better than s.Fields != nil, but it need to update current testdata. |
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 intentionally distinct STRUCT
and STRUCT<>
because the first means a struct having any fields, and the second is the struct with no fields. For instance, select CAST(struct(1) AS STRUCT<x INT64>).x
is valid, but select CAST(struct<>(1) AS STRUCT<x INT64>).x
is invalid.
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.
Thank you for your explanation.
I understood your intention.
We intentionally distinct STRUCT and STRUCT<> because the first means a struct having any fields, and the second is the struct with no fields. For instance, select
CAST(struct(1) AS STRUCT<x INT64>).x
is valid, but selectCAST(struct<>(1) AS STRUCT<x INT64>).x
is invalid.
My thought is that:
- It is
StructLiteral
, notStructType
, so there is no semantic difference betweenSTRUCT<>()
andSTRUCT()
. It can be normalized without ambiguity. STRUCT<>()
is valid, but it can feel unfamiliar because it has no fields to name or type.- The official docs describe only
STRUCT()
.
It might be a good idea to comment that both STRUCT()
and STRUCT<>()
are lexically preserved.
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.
Perhaps, we need to split the current StructLiteral
into a new two s.t. TypedStructLiteral
and TypelessStructLiteral
for clarity.
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.
LGTM for splitting.
In ZetaSQL, both of them are treated in ASTStructConstructorWithKeyword
, but they can't be mixed.
- In typed struct syntax
AS alias
is not allowed on the input expressions.STRUCT<x int64>(5 AS x)
Error - Typed syntax does not allow AS
Note:
- Splitting will be a part of Support typeless STRUCT syntax with field name #143
Thought: The existing |
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.
Good. Thank you.
This PR refactors
SQL()
methods.ast/sql.go
testdata
.Empty struct is better to be unparse asdiscussed Refactor SQL() methods #173 (review)STRUCT()
, but currentlySTRUCT<>()
.ast.ChangeStreamForTable
doesn't implementast.Node
Note:
There is a idea to introduce
text/template
style conditions.https://pkg.go.dev/text/template#hdr-Actions
It can simplify more, but empty slice, map handling may require to use
reflect
because empty slice/map are not the same with zero values, and their types doesn't satisfycomparable
.Added: I have implement only zero value as false, but it seems not useful than expected: 1606256