Skip to content
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

How to normalize list nodes? #56

Open
benchub opened this issue Mar 17, 2022 · 1 comment
Open

How to normalize list nodes? #56

benchub opened this issue Mar 17, 2022 · 1 comment
Labels

Comments

@benchub
Copy link

benchub commented Mar 17, 2022

I would like to modify the parse tree so that in (1) and in (1,2,3) end up looking the same. I can find the list node well enough, but it's not clear how to replace it - not only do I not know what function to use to make a new list node with a single item, it's not clear to me how that would affect the locations of all the other parse tree tokens.

If you could give an example of this, that would be amazing.

@lfittl
Copy link
Member

lfittl commented Jun 28, 2022

@benchub Not sure if you are still looking for this - but the quick TLDR is that you would construct the appropriate Protobuf structure. See here for a similar example than the one you are asking for:

pg_query_go/parse_test.go

Lines 152 to 203 in ee7bb71

"SELECT * FROM x WHERE y IN (?)",
`{"version":130003,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget":{"val":{"ColumnRef":{"fields":[{"A_Star":{}}],"location":7}},"location":7}}],"fromClause":[{"RangeVar":{"relname":"x","inh":true,"relpersistence":"p","location":14}}],"whereClause":{"A_Expr":{"kind":"AEXPR_IN","name":[{"String":{"str":"="}}],"lexpr":{"ColumnRef":{"fields":[{"String":{"str":"y"}}],"location":22}},"rexpr":{"List":{"items":[{"ParamRef":{"location":28}}]}},"location":24}},"limitOption":"LIMIT_OPTION_DEFAULT","op":"SETOP_NONE"}}}]}`,
&pg_query.ParseResult{
Version: int32(130003),
Stmts: []*pg_query.RawStmt{
{
Stmt: &pg_query.Node{
Node: &pg_query.Node_SelectStmt{
SelectStmt: &pg_query.SelectStmt{
LimitOption: pg_query.LimitOption_LIMIT_OPTION_DEFAULT,
Op: pg_query.SetOperation_SETOP_NONE,
TargetList: []*pg_query.Node{
pg_query.MakeResTargetNodeWithVal(
pg_query.MakeColumnRefNode(
[]*pg_query.Node{
pg_query.MakeAStarNode(),
},
7,
),
7,
),
},
FromClause: []*pg_query.Node{
pg_query.MakeSimpleRangeVarNode("x", 14),
},
WhereClause: &pg_query.Node{
Node: &pg_query.Node_AExpr{
AExpr: &pg_query.A_Expr{
Kind: pg_query.A_Expr_Kind_AEXPR_IN,
Name: []*pg_query.Node{
pg_query.MakeStrNode("="),
},
Lexpr: pg_query.MakeColumnRefNode(
[]*pg_query.Node{
pg_query.MakeStrNode("y"),
},
22,
),
Rexpr: pg_query.MakeListNode([]*pg_query.Node{
pg_query.MakeParamRefNode(0, 28),
}),
Location: 24,
},
},
},
},
},
},
},
},
},
},

And then pass it to the Deparse function:

https://github.com/pganalyze/pg_query_go#deparsing-a-parse-tree-back-into-a-sql-statement-experimental

Just in case you were worried about the Location fields - you don't need to do anything about those, they are only added for debugging by the parser, and are not used during deparsing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants