Skip to content

Commit e01a84d

Browse files
authored
feat: GQL basic structure (#339)
* feat: Implement basic GQL structure and RETURN clause - Add GQL AST nodes for GRAPH, RETURN, NEXT, and set operators - Implement GQL parser with Lookahead and recursive descent - Implement GQL unparser in ast/sql.go - Add comprehensive test suite for basic GQL queries - Enforce mandatory AS aliases in RETURN clauses in tests * refactor(gql): Refine GQL AST node naming and field structures - Rename GQL operational nodes to match SQL naming patterns (e.g., GQLReturnStatement -> GQLReturn) - Simplify field names in compositional GQL nodes (e.g., Query, Statements, Items) - Add BadGQLLinearQueryStatement and BadGQLPrimitiveQueryStatement for error recovery - Update parser and unparser to reflect the refined AST structure - Update generated files and test expectations * gql: support RETURN * and mandatory AS for aliases in basic structure * gql: rename property graph name to FinGraph in tests * Fix ordering in ast.go * Modify GQLReturnItem.Alias to AsAlias * Refine parseGQLSimpleLinearQueryStatement * Fix testdata * Revert unintended diff * Revert "Revert unintended diff" This reverts commit 93052b4.
1 parent ed2e73d commit e01a84d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+2651
-6
lines changed

ast/ast.go

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ func (BadStatement) isStatement() {}
7676
func (BadDDL) isStatement() {}
7777
func (BadDML) isStatement() {}
7878
func (QueryStatement) isStatement() {}
79+
func (GQLGraphQuery) isStatement() {}
7980
func (CreateSchema) isStatement() {}
8081
func (DropSchema) isStatement() {}
8182
func (CreateDatabase) isStatement() {}
@@ -4324,3 +4325,128 @@ type Call struct {
43244325
Name *Path
43254326
Args []TVFArg // len(Args) > 0
43264327
}
4328+
4329+
// ================================================================================
4330+
//
4331+
// GQL
4332+
//
4333+
// ================================================================================
4334+
4335+
// GQLLinearQueryStatement represents a linear query statement.
4336+
type GQLLinearQueryStatement interface {
4337+
Node
4338+
isGQLLinearQueryStatement()
4339+
}
4340+
4341+
func (GQLSimpleLinearQueryStatement) isGQLLinearQueryStatement() {}
4342+
func (GQLCompoundLinearQueryStatement) isGQLLinearQueryStatement() {}
4343+
func (BadGQLLinearQueryStatement) isGQLLinearQueryStatement() {}
4344+
4345+
// GQLPrimitiveQueryStatement represents a primitive query statement.
4346+
type GQLPrimitiveQueryStatement interface {
4347+
Node
4348+
isGQLPrimitiveQueryStatement()
4349+
}
4350+
4351+
func (GQLReturn) isGQLPrimitiveQueryStatement() {}
4352+
func (BadGQLPrimitiveQueryStatement) isGQLPrimitiveQueryStatement() {}
4353+
4354+
// GQLGraphQuery is a top-level GQL query.
4355+
//
4356+
// {{.Hint | sqlOpt}} {{.GraphClause | sql}} {{.Query | sql}}
4357+
type GQLGraphQuery struct {
4358+
// pos = (Hint ?? GraphClause).pos
4359+
// end = Query.end
4360+
4361+
Hint *Hint
4362+
GraphClause *GQLGraphClause
4363+
4364+
Query *GQLMultiLinearQueryStatement
4365+
}
4366+
4367+
// GQLGraphClause is a GRAPH clause in GQL.
4368+
//
4369+
// GRAPH {{.PropertyGraphName | sql}}
4370+
type GQLGraphClause struct {
4371+
// pos = Graph
4372+
// end = PropertyGraphName.end
4373+
4374+
Graph token.Pos
4375+
PropertyGraphName *Path
4376+
}
4377+
4378+
// GQLMultiLinearQueryStatement is a list of linear query statements chained with NEXT.
4379+
//
4380+
// {{.Statements | sqlJoin " NEXT "}}
4381+
type GQLMultiLinearQueryStatement struct {
4382+
// pos = Statements[0].pos
4383+
// end = Statements[$].end
4384+
4385+
Statements []GQLLinearQueryStatement // len(Statements) > 0
4386+
}
4387+
4388+
// BadGQLLinearQueryStatement is a bad GQLLinearQueryStatement node.
4389+
//
4390+
// {{.BadNode | sql}}
4391+
type BadGQLLinearQueryStatement struct {
4392+
// pos = BadNode.pos
4393+
// end = BadNode.end
4394+
4395+
BadNode *BadNode
4396+
}
4397+
4398+
// GQLSimpleLinearQueryStatement is a list of primitive query statements that ends with RETURN.
4399+
//
4400+
// {{.Statements | sqlJoin " "}}
4401+
type GQLSimpleLinearQueryStatement struct {
4402+
// pos = Statements[0].pos
4403+
// end = Statements[$].end
4404+
4405+
Statements []GQLPrimitiveQueryStatement // len(Statements) > 0
4406+
}
4407+
4408+
// GQLCompoundLinearQueryStatement represents a list of linear query statements composited with the set operators.
4409+
//
4410+
// {{.Statements | sqlJoin (printf " %s %s " .Op .AllOrDistinct)}}
4411+
type GQLCompoundLinearQueryStatement struct {
4412+
// pos = Statements[0].pos
4413+
// end = Statements[$].end
4414+
4415+
Op SetOp
4416+
AllOrDistinct AllOrDistinct
4417+
Statements []GQLLinearQueryStatement // len(Statements) >= 2
4418+
}
4419+
4420+
// BadGQLPrimitiveQueryStatement is a bad GQLPrimitiveQueryStatement node.
4421+
//
4422+
// {{.BadNode | sql}}
4423+
type BadGQLPrimitiveQueryStatement struct {
4424+
// pos = BadNode.pos
4425+
// end = BadNode.end
4426+
4427+
BadNode *BadNode
4428+
}
4429+
4430+
// GQLReturn is a RETURN statement in GQL.
4431+
//
4432+
// RETURN {{.AllOrDistinct | sqlOpt}} {{.Items | sqlJoin ", "}}
4433+
type GQLReturn struct {
4434+
// pos = Return
4435+
// end = Items[$].end
4436+
4437+
Return token.Pos
4438+
AllOrDistinct AllOrDistinct
4439+
Items []*GQLReturnItem
4440+
}
4441+
4442+
// GQLReturnItem is an item in a RETURN statement.
4443+
//
4444+
// {{.Expr | sql}}{{if .Alias}} {{.Alias | sqlOpt}}{{end}}
4445+
type GQLReturnItem struct {
4446+
// pos = Star || Expr.pos
4447+
// end = Star + 1 || (Alias ?? Expr).end
4448+
4449+
Star token.Pos
4450+
Expr Expr
4451+
Alias *AsAlias // optional
4452+
}

ast/pos.go

Lines changed: 72 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ast/sql.go

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -172,12 +172,14 @@ func (b *BadNode) SQL() string {
172172
return sql
173173
}
174174

175-
func (b *BadStatement) SQL() string { return sqlOpt("", b.Hint, " ") + b.BadNode.SQL() }
176-
func (b *BadQueryExpr) SQL() string { return b.BadNode.SQL() }
177-
func (b *BadExpr) SQL() string { return b.BadNode.SQL() }
178-
func (b *BadType) SQL() string { return b.BadNode.SQL() }
179-
func (b *BadDDL) SQL() string { return b.BadNode.SQL() }
180-
func (b *BadDML) SQL() string { return sqlOpt("", b.Hint, " ") + b.BadNode.SQL() }
175+
func (b *BadStatement) SQL() string { return sqlOpt("", b.Hint, " ") + b.BadNode.SQL() }
176+
func (b *BadQueryExpr) SQL() string { return b.BadNode.SQL() }
177+
func (b *BadExpr) SQL() string { return b.BadNode.SQL() }
178+
func (b *BadType) SQL() string { return b.BadNode.SQL() }
179+
func (b *BadDDL) SQL() string { return b.BadNode.SQL() }
180+
func (b *BadDML) SQL() string { return sqlOpt("", b.Hint, " ") + b.BadNode.SQL() }
181+
func (b *BadGQLLinearQueryStatement) SQL() string { return b.BadNode.SQL() }
182+
func (b *BadGQLPrimitiveQueryStatement) SQL() string { return b.BadNode.SQL() }
181183

182184
// ================================================================================
183185
//
@@ -1442,3 +1444,41 @@ func (u *UpdateItem) SQL() string {
14421444
func (c *Call) SQL() string {
14431445
return "CALL " + c.Name.SQL() + "(" + sqlJoin(c.Args, ", ") + ")"
14441446
}
1447+
1448+
// ================================================================================
1449+
//
1450+
// GQL
1451+
//
1452+
// ================================================================================
1453+
1454+
func (q *GQLGraphQuery) SQL() string {
1455+
return sqlOpt("", q.Hint, " ") + q.GraphClause.SQL() + " " + q.Query.SQL()
1456+
}
1457+
1458+
func (c *GQLGraphClause) SQL() string {
1459+
return "GRAPH " + c.PropertyGraphName.SQL()
1460+
}
1461+
1462+
func (s *GQLMultiLinearQueryStatement) SQL() string {
1463+
return sqlJoin(s.Statements, " NEXT ")
1464+
}
1465+
1466+
func (s *GQLSimpleLinearQueryStatement) SQL() string {
1467+
return sqlJoin(s.Statements, " ")
1468+
}
1469+
1470+
func (s *GQLCompoundLinearQueryStatement) SQL() string {
1471+
sep := " " + string(s.Op) + strOpt(s.AllOrDistinct != "", " "+string(s.AllOrDistinct)) + " "
1472+
return sqlJoin(s.Statements, sep)
1473+
}
1474+
1475+
func (s *GQLReturn) SQL() string {
1476+
return "RETURN " + strOpt(s.AllOrDistinct != "", string(s.AllOrDistinct)+" ") + sqlJoin(s.Items, ", ")
1477+
}
1478+
1479+
func (i *GQLReturnItem) SQL() string {
1480+
if !i.Star.Invalid() {
1481+
return "*"
1482+
}
1483+
return i.Expr.SQL() + sqlOpt(" ", i.Alias, "")
1484+
}

ast/walk_internal.go

Lines changed: 30 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)