From c41fae00ff6083008f1ebc9e18414e725dd43f87 Mon Sep 17 00:00:00 2001 From: apstndb <803393+apstndb@users.noreply.github.com> Date: Thu, 19 Sep 2024 19:14:46 +0900 Subject: [PATCH 01/13] Bump Go version to 1.20, and add util.go --- ast/util.go | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++ go.mod | 2 +- 2 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 ast/util.go diff --git a/ast/util.go b/ast/util.go new file mode 100644 index 00000000..8a631ee5 --- /dev/null +++ b/ast/util.go @@ -0,0 +1,59 @@ +package ast + +import ( + "github.com/cloudspannerecosystem/memefish/token" + "strings" +) + +// sqlOpt outputs: +// +// when node != nil: left + node.SQL() + right +// else : empty string +func sqlOpt[T interface { + Node + comparable +}](left string, node T, right string) string { + var zero T + if node == zero { + return "" + } + return left + node.SQL() + right +} + +func lastElem[T any](s []T) T { + return s[len(s)-1] +} + +func firstValidEnd(ns ...Node) token.Pos { + for _, n := range ns { + if n != nil && n.End() != token.InvalidPos { + return n.End() + } + } + return token.InvalidPos +} + +func firstPos[T Node](s []T) token.Pos { + if len(s) == 0 { + return token.InvalidPos + } + return s[0].Pos() +} + +func lastEnd[T Node](s []T) token.Pos { + if len(s) == 0 { + return token.InvalidPos + } + return lastElem(s).End() +} + +func sqlJoin[T Node](elems []T, sep string) string { + var b strings.Builder + for i, r := range elems { + if i > 0 { + b.WriteString(sep) + } + b.WriteString(r.SQL()) + } + return b.String() +} diff --git a/go.mod b/go.mod index cfc62164..3ae33182 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/cloudspannerecosystem/memefish -go 1.19 +go 1.20 require ( github.com/MakeNowJust/heredoc/v2 v2.0.1 From b818a86551263d7bdd3271657d99ee92de4808f1 Mon Sep 17 00:00:00 2001 From: apstndb <803393+apstndb@users.noreply.github.com> Date: Thu, 19 Sep 2024 12:10:48 +0900 Subject: [PATCH 02/13] Implement CREATE PROPERTY GRAPH and DROP PROPERTY GRAPH statements --- ast/ast.go | 612 ++++++++++++++++-- parser.go | 318 ++++++++- ...ate_or_replace_property_graph_fingraph.sql | 15 + ...y_graph_if_not_exists_fingraph_verbose.sql | 19 + testdata/input/ddl/drop_property_graph.sql | 1 + .../ddl/drop_property_graph_if_exists.sql | 1 + ...or_replace_property_graph_fingraph.sql.txt | 237 +++++++ ...aph_if_not_exists_fingraph_verbose.sql.txt | 326 ++++++++++ .../result/ddl/drop_property_graph.sql.txt | 16 + .../ddl/drop_property_graph_if_exists.sql.txt | 16 + ...or_replace_property_graph_fingraph.sql.txt | 237 +++++++ ...aph_if_not_exists_fingraph_verbose.sql.txt | 326 ++++++++++ .../statement/drop_property_graph.sql.txt | 16 + .../drop_property_graph_if_exists.sql.txt | 16 + 14 files changed, 2103 insertions(+), 53 deletions(-) create mode 100644 testdata/input/ddl/create_or_replace_property_graph_fingraph.sql create mode 100644 testdata/input/ddl/create_property_graph_if_not_exists_fingraph_verbose.sql create mode 100644 testdata/input/ddl/drop_property_graph.sql create mode 100644 testdata/input/ddl/drop_property_graph_if_exists.sql create mode 100644 testdata/result/ddl/create_or_replace_property_graph_fingraph.sql.txt create mode 100644 testdata/result/ddl/create_property_graph_if_not_exists_fingraph_verbose.sql.txt create mode 100644 testdata/result/ddl/drop_property_graph.sql.txt create mode 100644 testdata/result/ddl/drop_property_graph_if_exists.sql.txt create mode 100644 testdata/result/statement/create_or_replace_property_graph_fingraph.sql.txt create mode 100644 testdata/result/statement/create_property_graph_if_not_exists_fingraph_verbose.sql.txt create mode 100644 testdata/result/statement/drop_property_graph.sql.txt create mode 100644 testdata/result/statement/drop_property_graph_if_exists.sql.txt diff --git a/ast/ast.go b/ast/ast.go index a58895cf..32c21fa4 100644 --- a/ast/ast.go +++ b/ast/ast.go @@ -50,30 +50,32 @@ type Statement interface { isStatement() } -func (QueryStatement) isStatement() {} -func (CreateDatabase) isStatement() {} -func (CreateTable) isStatement() {} -func (CreateSequence) isStatement() {} -func (CreateView) isStatement() {} -func (CreateIndex) isStatement() {} -func (CreateVectorIndex) isStatement() {} -func (CreateRole) isStatement() {} -func (AlterTable) isStatement() {} -func (AlterIndex) isStatement() {} -func (AlterSequence) isStatement() {} -func (DropTable) isStatement() {} -func (DropIndex) isStatement() {} -func (DropVectorIndex) isStatement() {} -func (DropSequence) isStatement() {} -func (DropRole) isStatement() {} -func (Insert) isStatement() {} -func (Delete) isStatement() {} -func (Update) isStatement() {} -func (Grant) isStatement() {} -func (Revoke) isStatement() {} -func (CreateChangeStream) isStatement() {} -func (AlterChangeStream) isStatement() {} -func (DropChangeStream) isStatement() {} +func (QueryStatement) isStatement() {} +func (CreateDatabase) isStatement() {} +func (CreateTable) isStatement() {} +func (CreateSequence) isStatement() {} +func (CreateView) isStatement() {} +func (CreateIndex) isStatement() {} +func (CreateVectorIndex) isStatement() {} +func (CreateRole) isStatement() {} +func (AlterTable) isStatement() {} +func (AlterIndex) isStatement() {} +func (AlterSequence) isStatement() {} +func (DropTable) isStatement() {} +func (DropIndex) isStatement() {} +func (DropVectorIndex) isStatement() {} +func (DropSequence) isStatement() {} +func (DropRole) isStatement() {} +func (Insert) isStatement() {} +func (Delete) isStatement() {} +func (Update) isStatement() {} +func (Grant) isStatement() {} +func (Revoke) isStatement() {} +func (CreateChangeStream) isStatement() {} +func (AlterChangeStream) isStatement() {} +func (DropChangeStream) isStatement() {} +func (CreatePropertyGraph) isStatement() {} +func (DropPropertyGraph) isStatement() {} // QueryExpr represents set operator operands. type QueryExpr interface { @@ -223,26 +225,28 @@ type DDL interface { isDDL() } -func (CreateDatabase) isDDL() {} -func (CreateTable) isDDL() {} -func (CreateView) isDDL() {} -func (CreateSequence) isDDL() {} -func (AlterTable) isDDL() {} -func (DropTable) isDDL() {} -func (CreateIndex) isDDL() {} -func (CreateVectorIndex) isDDL() {} -func (AlterIndex) isDDL() {} -func (AlterSequence) isDDL() {} -func (DropIndex) isDDL() {} -func (DropVectorIndex) isDDL() {} -func (DropSequence) isDDL() {} -func (CreateRole) isDDL() {} -func (DropRole) isDDL() {} -func (Grant) isDDL() {} -func (Revoke) isDDL() {} -func (CreateChangeStream) isDDL() {} -func (AlterChangeStream) isDDL() {} -func (DropChangeStream) isDDL() {} +func (CreateDatabase) isDDL() {} +func (CreateTable) isDDL() {} +func (CreateView) isDDL() {} +func (CreateSequence) isDDL() {} +func (AlterTable) isDDL() {} +func (DropTable) isDDL() {} +func (CreateIndex) isDDL() {} +func (CreateVectorIndex) isDDL() {} +func (AlterIndex) isDDL() {} +func (AlterSequence) isDDL() {} +func (DropIndex) isDDL() {} +func (DropVectorIndex) isDDL() {} +func (DropSequence) isDDL() {} +func (CreateRole) isDDL() {} +func (DropRole) isDDL() {} +func (Grant) isDDL() {} +func (Revoke) isDDL() {} +func (CreateChangeStream) isDDL() {} +func (AlterChangeStream) isDDL() {} +func (DropChangeStream) isDDL() {} +func (CreatePropertyGraph) isDDL() {} +func (DropPropertyGraph) isDDL() {} // Constraint represents table constraint of CONSTARINT clause. type Constraint interface { @@ -2297,6 +2301,526 @@ type ArraySchemaType struct { Item SchemaType // ScalarSchemaType or SizedSchemaType } +// ================================================================================ +// +// GQL schema statements +// +// ================================================================================ + +// CreatePropertyGraph is CREATE PROPERTY GRAPH statement node. +// +// CREATE {{if.OrReplace }}OR REPLACE{{end}} PROPERTY GRAPH {{if .IfNotExists}}IF NOT EXISTS{{end}} {{.Name | sql}} +// {{.Content | sql}} +type CreatePropertyGraph struct { + // pos = Create + // end = Content.end + + Create token.Pos // position of "CREATE" keyword + OrReplace bool + IfNotExists bool + Name *Ident + Content *PropertyGraphContent +} + +func (c *CreatePropertyGraph) Pos() token.Pos { + return c.Create +} + +func (c *CreatePropertyGraph) End() token.Pos { + return c.Content.End() +} + +func (c *CreatePropertyGraph) SQL() string { + sql := "CREATE " + if c.OrReplace { + sql += "OR REPLACE " + } + sql += "PROPERTY GRAPH " + if c.IfNotExists { + sql += "IF NOT EXISTS " + } + sql += c.Name.SQL() + " " + c.Content.SQL() + return sql +} + +// PropertyGraphContent +// +// NODE TABLES {{.NodeTables | sql}} {{if not(.EdgeTables | isnil)}}NODE TABLES {{.EdgeTables | sqlOpt}}{{end}} +type PropertyGraphContent struct { + // pos = Node + // end = (EdgeTables ?? NodeTables).end + + Node token.Pos // position of "NODE" + NodeTables *PropertyGraphElementList + EdgeTables *PropertyGraphElementList //optional +} + +func (p *PropertyGraphContent) Pos() token.Pos { + return p.Node +} + +func (p *PropertyGraphContent) End() token.Pos { + return firstValidEnd(p.EdgeTables, p.NodeTables) +} + +func (p *PropertyGraphContent) SQL() string { + return "NODE TABLES" + p.NodeTables.SQL() + sqlOpt(" EDGE TABLES ", p.EdgeTables, "") +} + +// PropertyGraphElementList +// +// ({{.Elements | sqlJoin ", "}}) +type PropertyGraphElementList struct { + // pos = LParen + // end = RParen + 1 + + LParen, RParen token.Pos + Elements []*PropertyGraphElement +} + +func (p *PropertyGraphElementList) Pos() token.Pos { + return p.LParen +} + +func (p *PropertyGraphElementList) End() token.Pos { + return p.RParen + 1 +} + +func (p *PropertyGraphElementList) SQL() string { + return "(" + sqlJoin(p.Elements, ", ") + ")" +} + +// PropertyGraphElement +// +// {{.Ident | sql}} {{.AsAlias | sqlOpt}} {{.Keys | sqlOpt}} {{.Properties | sqlOpt}} +type PropertyGraphElement struct { + // pos = Name.pos + // end = (Properties ?? Keys ?? Alias ?? Name).end + + Name *Ident + Alias *AsAlias // optional + Keys PropertyGraphElementKeys // optional + Properties PropertyGraphProperties // optional +} + +func (p *PropertyGraphElement) Pos() token.Pos { + return p.Name.Pos() +} + +func (p *PropertyGraphElement) End() token.Pos { + return firstValidEnd(p.Properties, p.Keys, p.Alias, p.Name) +} + +func (p *PropertyGraphElement) SQL() string { + return p.Name.SQL() + + sqlOpt(" ", p.Alias, "") + + sqlOpt(" ", p.Keys, "") + + sqlOpt(" ", p.Properties, "") +} + +type PropertyGraphProperties interface { + Node + isPropertyGraphProperties() +} + +// PropertyGraphLabelAndPropertiesList +// +// {{.LabelAndProperties | sqlJoin " "}} +type PropertyGraphLabelAndPropertiesList struct { + // pos = LabelAndProperties.pos + // end = LabelAndProperties.end + + LabelAndProperties []*PropertyGraphLabelAndProperties +} + +func (p *PropertyGraphLabelAndPropertiesList) Pos() token.Pos { + return firstPos(p.LabelAndProperties) +} + +func (p *PropertyGraphLabelAndPropertiesList) End() token.Pos { + return lastEnd(p.LabelAndProperties) +} + +func (p *PropertyGraphLabelAndPropertiesList) SQL() string { + return sqlJoin(p.LabelAndProperties, " ") +} + +// PropertyGraphLabelAndProperties +type PropertyGraphLabelAndProperties struct { + // pos = Label.pos + // end = (Properties ?? Label).end + + Label PropertyGraphElementLabel + Properties PropertyGraphElementProperties // optional +} + +func (p *PropertyGraphLabelAndProperties) Pos() token.Pos { + return p.Label.Pos() +} + +func (p *PropertyGraphLabelAndProperties) End() token.Pos { + return firstValidEnd(p.Properties, p.Label) +} + +func (p *PropertyGraphLabelAndProperties) SQL() string { + return p.Label.SQL() + sqlOpt(" ", p.Properties, "") +} + +type PropertyGraphElementLabel interface { + Node + isPropertyGraphElementLabel() +} + +func (*PropertyGraphElementLabelLabelName) isPropertyGraphElementLabel() {} +func (*PropertyGraphElementLabelDefaultLabel) isPropertyGraphElementLabel() {} + +// PropertyGraphElementLabelLabelName +// +// LABEL {{.Name | sql}} +type PropertyGraphElementLabelLabelName struct { + // pos = Label + // end = Name.end + + Label token.Pos + Name *Ident +} + +func (*PropertyGraphElementLabelLabelName) isPropertyGraphProperties() {} + +func (p *PropertyGraphElementLabelLabelName) Pos() token.Pos { + return p.Label +} + +func (p *PropertyGraphElementLabelLabelName) End() token.Pos { + return p.Name.End() +} + +func (p *PropertyGraphElementLabelLabelName) SQL() string { + return "LABEL " + p.Name.SQL() +} + +// PropertyGraphElementLabelDefaultLabel +// +// DEFAULT LABEL +type PropertyGraphElementLabelDefaultLabel struct { + // pos = Default + // end = Label + 5 # len("LABEL") + Default token.Pos + Label token.Pos +} + +func (*PropertyGraphElementLabelDefaultLabel) isPropertyGraphProperties() {} + +func (p *PropertyGraphElementLabelDefaultLabel) Pos() token.Pos { + return p.Default +} + +func (p *PropertyGraphElementLabelDefaultLabel) End() token.Pos { + return p.Label + 5 +} + +func (p *PropertyGraphElementLabelDefaultLabel) SQL() string { + return "DEFAULT LABEL" +} + +func (*PropertyGraphLabelAndPropertiesList) isPropertyGraphProperties() {} + +type PropertyGraphElementKeys interface { + Node + isPropertyGraphElementKeys() +} + +func (*PropertyGraphNodeElementKey) isPropertyGraphElementKeys() {} +func (*PropertyGraphEdgeElementKeys) isPropertyGraphElementKeys() {} + +// PropertyGraphNodeElementKey is a wrapper of PropertyGraphElementKey +type PropertyGraphNodeElementKey struct { + PropertyGraphElementKey +} + +func (p *PropertyGraphNodeElementKey) Pos() token.Pos { + return p.PropertyGraphElementKey.Pos() +} + +func (p *PropertyGraphNodeElementKey) End() token.Pos { + return p.PropertyGraphElementKey.End() +} + +func (p *PropertyGraphNodeElementKey) SQL() string { + return p.PropertyGraphElementKey.SQL() +} + +// PropertyGraphEdgeElementKeys +// +// {{.Element | sql}} {{.Source | sql}} {{.Destination | sql}} +type PropertyGraphEdgeElementKeys struct { + // pos = Element.pos + // end = Destination.end + Element *PropertyGraphElementKey + Source *PropertyGraphSourceKey + Destination *PropertyGraphDestinationKey +} + +func (p *PropertyGraphEdgeElementKeys) Pos() token.Pos { + return p.Element.Pos() +} + +func (p *PropertyGraphEdgeElementKeys) End() token.Pos { + return p.Destination.End() +} + +func (p *PropertyGraphEdgeElementKeys) SQL() string { + return sqlOpt("", p.Element, " ") + p.Source.SQL() + " " + p.Destination.SQL() +} + +// PropertyGraphElementKey +// +// KEY {{.Keys | sql}} +type PropertyGraphElementKey struct { + // pos = Key + // end = Keys.end + + Key token.Pos + Keys *PropertyGraphColumnNameList +} + +func (p *PropertyGraphElementKey) Pos() token.Pos { + return p.Key +} + +func (p *PropertyGraphElementKey) End() token.Pos { + return p.Keys.End() +} + +func (p *PropertyGraphElementKey) SQL() string { + return "KEY " + p.Keys.SQL() +} + +// PropertyGraphSourceKey +// +// SOURCE KEY {{.Keys | sql}} +// REFERENCES {{.ElementReference | sql}} {{.ReferenceColumns | sqlOpt}} +type PropertyGraphSourceKey struct { + // pos = Source + // end = (ReferenceColumns[$] ?? ElementReference).end + + Source token.Pos + Keys *PropertyGraphColumnNameList + ElementReference *Ident + ReferenceColumns *PropertyGraphColumnNameList // optional +} + +func (p *PropertyGraphSourceKey) Pos() token.Pos { + return p.Source +} + +func (p *PropertyGraphSourceKey) End() token.Pos { + return firstValidEnd(p.ReferenceColumns, p.ElementReference) +} + +func (p *PropertyGraphSourceKey) SQL() string { + return "SOURCE KEY " + p.Keys.SQL() + + " REFERENCES " + p.ElementReference.SQL() + + sqlOpt(" ", p.ReferenceColumns, "") +} + +// PropertyGraphDestinationKey +// +// DESTINATION KEY {{.Keys | sql}} +// REFERENCES {{.ElementReference | sql}} {{.ReferenceColumns | sqlOpt}} +type PropertyGraphDestinationKey struct { + // pos = Destination + // end = (ReferenceColumns[$] ?? ElementReference).end + + Destination token.Pos + Keys *PropertyGraphColumnNameList + ElementReference *Ident + ReferenceColumns *PropertyGraphColumnNameList // optional +} + +func (p *PropertyGraphDestinationKey) Pos() token.Pos { + return p.Destination +} + +func (p *PropertyGraphDestinationKey) End() token.Pos { + return firstValidEnd(p.ElementReference, p.ElementReference) +} + +func (p *PropertyGraphDestinationKey) SQL() string { + return "DESTINATION KEY " + p.Keys.SQL() + + " REFERENCES " + p.ElementReference.SQL() + + sqlOpt(" ", p.ReferenceColumns, "") +} + +// PropertyGraphColumnNameList +// +// ({{.ColumnNameList | sqlJoin ", "}}) +type PropertyGraphColumnNameList struct { + // pos = LParen + // end = RParen + 1 + LParen, RParen token.Pos + ColumnNameList []*Ident +} + +func (p *PropertyGraphColumnNameList) Pos() token.Pos { + return p.LParen +} + +func (p *PropertyGraphColumnNameList) End() token.Pos { + return p.RParen + 1 +} + +func (p *PropertyGraphColumnNameList) SQL() string { + return "(" + sqlJoin(p.ColumnNameList, ", ") + ")" +} + +// Element properties definition +// https://cloud.google.com/spanner/docs/reference/standard-sql/graph-schema-statements#element_table_property_definition + +type PropertyGraphElementProperties interface { + PropertyGraphProperties + isPropertyGraphElementProperties() +} + +func (p *PropertyGraphNoProperties) isPropertyGraphElementProperties() {} + +// PropertyGraphNoProperties +// +// NO PROPERTIES +type PropertyGraphNoProperties struct { + // pos = No + // end = Properties + 10 # len("PROPERTIES") + + No, Properties token.Pos // position of "NO" and "PROPERTIES" +} + +func (p *PropertyGraphNoProperties) isPropertyGraphProperties() {} + +func (p *PropertyGraphNoProperties) Pos() token.Pos { + return p.No +} + +func (p PropertyGraphNoProperties) End() token.Pos { + return p.Properties + 10 +} + +func (p PropertyGraphNoProperties) SQL() string { + return "NO PROPERTIES" +} + +// PropertyGraphPropertiesAre +// +// PROPERTIES ARE ALL COLUMNS{{if not(.ExceptColumns | isnil)}} EXCEPT {{.ExceptColumns}}{{end}} +type PropertyGraphPropertiesAre struct { + // pos = Properties + // end = ExceptColumns.end + + Properties token.Pos // position of "PROPERTIES" + Columns token.Pos // position of "COLUMNS" + + ExceptColumns *PropertyGraphColumnNameList // optional + +} + +func (*PropertyGraphPropertiesAre) isPropertyGraphProperties() {} + +func (p *PropertyGraphPropertiesAre) Pos() token.Pos { + return p.Properties +} + +func (p *PropertyGraphPropertiesAre) End() token.Pos { + return p.ExceptColumns.End() +} + +func (p *PropertyGraphPropertiesAre) SQL() string { + return "PROPERTIES ARE ALL COLUMNS" + sqlOpt(" EXCEPT ", p.ExceptColumns, "") +} + +func (*PropertyGraphPropertiesAre) isPropertyGraphElementProperties() {} + +// PropertyGraphDerivedPropertyList +// +// PROPERTIES ({{.DerivedProperties | sqlJoin ", "}}) +// +// NOTE: In current official syntax, "(" and ")" are missing. +type PropertyGraphDerivedPropertyList struct { + // pos = Properties + // end = RParen.end + + Properties token.Pos // position of "PROPERTIES" + RParen token.Pos // position of ")" + DerivedProperties []*PropertyGraphDerivedProperty // len > 0 +} + +func (*PropertyGraphDerivedPropertyList) isPropertyGraphProperties() {} + +func (*PropertyGraphDerivedPropertyList) isPropertyGraphElementProperties() {} + +func (p *PropertyGraphDerivedPropertyList) Pos() token.Pos { + return p.Properties +} + +func (p *PropertyGraphDerivedPropertyList) End() token.Pos { + return p.RParen + 1 +} + +func (p *PropertyGraphDerivedPropertyList) SQL() string { + return "PROPERTIES (" + sqlJoin(p.DerivedProperties, ", ") + ")" +} + +// PropertyGraphDerivedProperty +// +// {{.Expr | sql}}{{if not(.PropertyName | isnil)}} AS {{.PropertyName | sql}}{{end}} +type PropertyGraphDerivedProperty struct { + // pos = Expr.pos + // end = (PropertyName ?? Expr).end + + Expr Expr + PropertyName *Ident //optional +} + +func (p *PropertyGraphDerivedProperty) Pos() token.Pos { + return p.Expr.Pos() +} + +func (p *PropertyGraphDerivedProperty) End() token.Pos { + return firstValidEnd(p.PropertyName, p.Expr) + +} + +func (p *PropertyGraphDerivedProperty) SQL() string { + return p.Expr.SQL() + sqlOpt(" AS ", p.PropertyName, "") +} + +// DropPropertyGraph +// +// DROP PROPERTY GRAPH {{if .IfExists}}IF EXISTS{{end}} {{.PropertyGraphName | sql}} +type DropPropertyGraph struct { + // pos = Drop + // end = Name.end + + Drop token.Pos + IfExists bool + Name *Ident +} + +func (g *DropPropertyGraph) Pos() token.Pos { + return g.Drop +} + +func (g *DropPropertyGraph) End() token.Pos { + return g.Name.End() +} + +func (g *DropPropertyGraph) SQL() string { + sql := "DROP PROPERTY GRAPH " + if g.IfExists { + sql += "IF EXISTS " + } + sql += g.Name.SQL() + return sql +} + // ================================================================================ // // DML diff --git a/parser.go b/parser.go index fb5473c3..1bf76ba7 100644 --- a/parser.go +++ b/parser.go @@ -1983,8 +1983,8 @@ func (p *Parser) parseDDL() ast.DDL { return p.parseCreateTable(pos) case p.Token.IsKeywordLike("SEQUENCE"): return p.parseCreateSequence(pos) - case p.Token.IsKeywordLike("VIEW") || p.Token.Kind == "OR": - return p.parseCreateView(pos) + case p.Token.IsKeywordLike("VIEW"): + return p.parseCreateView(pos, false) case p.Token.IsKeywordLike("INDEX") || p.Token.IsKeywordLike("UNIQUE") || p.Token.IsKeywordLike("NULL_FILTERED"): return p.parseCreateIndex(pos) case p.Token.IsKeywordLike("VECTOR"): @@ -1993,6 +1993,17 @@ func (p *Parser) parseDDL() ast.DDL { return p.parseCreateRole(pos) case p.Token.IsKeywordLike("CHANGE"): return p.parseCreateChangeStream(pos) + case p.Token.IsKeywordLike("PROPERTY"): + return p.parseCreatePropertyGraph(pos, false) + case p.Token.Kind == "OR": + p.expect("OR") + p.expectKeywordLike("REPLACE") + switch { + case p.Token.IsKeywordLike("VIEW"): + return p.parseCreateView(pos, true) + case p.Token.IsKeywordLike("PROPERTY"): + return p.parseCreatePropertyGraph(pos, true) + } } p.panicfAtToken(&p.Token, "expected pseudo keyword: DATABASE, TABLE, INDEX, UNIQUE, NULL_FILTERED, ROLE, CHANGE but: %s", p.Token.AsString) case p.Token.IsKeywordLike("ALTER"): @@ -2023,6 +2034,8 @@ func (p *Parser) parseDDL() ast.DDL { return p.parseDropRole(pos) case p.Token.IsKeywordLike("CHANGE"): return p.parseDropChangeStream(pos) + case p.Token.IsKeywordLike("PROPERTY"): + return p.parseDropPropertyGraph(pos) } p.panicfAtToken(&p.Token, "expected pseudo keyword: TABLE, INDEX, ROLE, CHANGE, but: %s", p.Token.AsString) case p.Token.IsKeywordLike("GRANT"): @@ -2169,13 +2182,7 @@ func (p *Parser) parseCreateSequence(pos token.Pos) *ast.CreateSequence { } } -func (p *Parser) parseCreateView(pos token.Pos) *ast.CreateView { - var orReplace bool - if p.Token.Kind == "OR" { - p.nextToken() - p.expectKeywordLike("REPLACE") - orReplace = true - } +func (p *Parser) parseCreateView(pos token.Pos, orReplace bool) *ast.CreateView { p.expectKeywordLike("VIEW") name := p.parseIdent() @@ -3223,6 +3230,299 @@ func (p *Parser) tryParseTablePrivilegeColumns() ([]*ast.Ident, token.Pos) { return columns, rparen } +// CREATE PROPERTY GRAPH + +func (p *Parser) parseCreatePropertyGraph(pos token.Pos, orReplace bool) *ast.CreatePropertyGraph { + p.expectKeywordLike("PROPERTY") + p.expectKeywordLike("GRAPH") + + ifNotExists := p.parseIfNotExists() + name := p.parseIdent() + content := p.parsePropertyGraphContent() + + return &ast.CreatePropertyGraph{ + Create: pos, + OrReplace: orReplace, + IfNotExists: ifNotExists, + Name: name, + Content: content, + } +} + +func (p *Parser) parsePropertyGraphContent() *ast.PropertyGraphContent { + node := p.expectKeywordLike("NODE").Pos + p.expectKeywordLike("TABLES") + + nodeTables := p.parsePropertyGraphElementList() + + var edgeTables *ast.PropertyGraphElementList + if p.Token.IsKeywordLike("EDGE") { + p.expectKeywordLike("EDGE") + p.expectKeywordLike("TABLES") + edgeTables = p.parsePropertyGraphElementList() + } + + return &ast.PropertyGraphContent{ + Node: node, + NodeTables: nodeTables, + EdgeTables: edgeTables, + } +} + +func (p *Parser) parsePropertyGraphElementList() *ast.PropertyGraphElementList { + lparen := p.expect("(").Pos + elements := parseList(p, ",", p.parsePropertyGraphElement) + rparen := p.expect(")").Pos + + return &ast.PropertyGraphElementList{ + LParen: lparen, + RParen: rparen, + Elements: elements, + } + +} +func (p *Parser) parsePropertyGraphElement() *ast.PropertyGraphElement { + name := p.parseIdent() + + var alias *ast.AsAlias + if p.Token.Kind == "AS" { + alias = p.tryParseAsAlias() + } + + keys := p.tryParsePropertyGraphElementKeys() + properties := p.tryParsePropertyGraphProperties() + + return &ast.PropertyGraphElement{ + Name: name, + Alias: alias, + Keys: keys, + Properties: properties, + } +} + +func (p *Parser) parsePropertyGraphLabelAndPropertiesList() *ast.PropertyGraphLabelAndPropertiesList { + var list []*ast.PropertyGraphLabelAndProperties + for { + var label ast.PropertyGraphElementLabel + if p.Token.Kind == "DEFAULT" { + defaultPos := p.expect("DEFAULT").Pos + labelPos := p.expectKeywordLike("LABEL").Pos + label = &ast.PropertyGraphElementLabelDefaultLabel{ + Default: defaultPos, + Label: labelPos, + } + } else if p.Token.IsKeywordLike("LABEL") { + labelPos := p.expectKeywordLike("LABEL").Pos + name := p.parseIdent() + + label = &ast.PropertyGraphElementLabelLabelName{ + Label: labelPos, + Name: name, + } + } else { + break + } + + properties := p.tryParsePropertyGraphElementProperties() + list = append(list, &ast.PropertyGraphLabelAndProperties{ + Label: label, + Properties: properties, + }) + } + return &ast.PropertyGraphLabelAndPropertiesList{ + LabelAndProperties: list, + } +} + +func (p *Parser) tryParsePropertyGraphElementProperties() ast.PropertyGraphElementProperties { + if p.Token.Kind != "NO" && !p.Token.IsKeywordLike("PROPERTIES") { + return nil + } + return p.parsePropertyGraphElementProperties() +} + +func (p *Parser) tryExpect(s token.TokenKind) *token.Token { + if p.Token.Kind != s { + return nil + } + return p.expect(s) +} + +func (p *Parser) tryExpectKeywordLike(s string) *token.Token { + if !p.Token.IsKeywordLike(s) { + return nil + } + return p.expectKeywordLike(s) +} + +func (p *Parser) parsePropertyGraphElementProperties() ast.PropertyGraphElementProperties { + switch { + case p.Token.Kind == "NO": + no := p.expect("NO").Pos + properties := p.expectKeywordLike("PROPERTIES").Pos + return &ast.PropertyGraphNoProperties{ + No: no, + Properties: properties, + } + case p.Token.IsKeywordLike("PROPERTIES"): + properties := p.expectKeywordLike("PROPERTIES").Pos + if p.Token.IsKeywordLike("ARE") || p.Token.Kind == "ALL" { + p.tryExpectKeywordLike("ARE") + p.expect("ALL") + columns := p.expectKeywordLike("COLUMNS").Pos + var exceptColumns *ast.PropertyGraphColumnNameList + if p.Token.Kind == "EXCEPT" { + p.expect("EXCEPT") + exceptColumns = p.parsePropertyGraphColumnNameList() + } + return &ast.PropertyGraphPropertiesAre{ + Properties: properties, + Columns: columns, + ExceptColumns: exceptColumns, + } + } + + p.expect("(") + list := parseList(p, ",", func() *ast.PropertyGraphDerivedProperty { + expr := p.parseExpr() + + var name *ast.Ident + if p.Token.Kind == "AS" { + p.expect("AS") + name = p.parseIdent() + } + return &ast.PropertyGraphDerivedProperty{ + Expr: expr, + PropertyName: name, + } + }) + rparen := p.expect(")").Pos + return &ast.PropertyGraphDerivedPropertyList{ + RParen: rparen, + Properties: properties, + DerivedProperties: list, + } + default: + } + p.panicfAtToken(&p.Token, `expect "NO" or "PROPERTIES", but %v`, p.Token.Kind) + return nil +} + +func (p *Parser) tryParsePropertyGraphProperties() ast.PropertyGraphProperties { + if p.Token.IsKeywordLike("LABEL") || p.Token.Kind == "DEFAULT" { + return p.parsePropertyGraphLabelAndPropertiesList() + } + return p.tryParsePropertyGraphElementProperties() +} + +func (p *Parser) tryParsePropertyGraphElementKeys() ast.PropertyGraphElementKeys { + if !p.Token.IsKeywordLike("KEY") && !p.Token.IsKeywordLike("SOURCE") { + return nil + } + + if p.Token.IsKeywordLike("KEY") { + key := p.expectKeywordLike("KEY").Pos + keyColumns := p.parsePropertyGraphColumnNameList() + elementKey := &ast.PropertyGraphElementKey{ + Key: key, + Keys: keyColumns, + } + return &ast.PropertyGraphNodeElementKey{ + PropertyGraphElementKey: *elementKey, + } + + } + + source := p.expectKeywordLike("SOURCE").Pos + p.expectKeywordLike("KEY") + sourceColumns := p.parsePropertyGraphColumnNameList() + p.expectKeywordLike("REFERENCES") + sourceReference := p.parseIdent() + + var sourceReferenceColumns *ast.PropertyGraphColumnNameList + if p.Token.Kind == "(" { + sourceReferenceColumns = p.parsePropertyGraphColumnNameList() + } + + destination := p.expectKeywordLike("DESTINATION").Pos + p.expectKeywordLike("KEY") + destinationColumns := p.parsePropertyGraphColumnNameList() + p.expectKeywordLike("REFERENCES") + destinationReference := p.parseIdent() + var destinationReferenceColumns *ast.PropertyGraphColumnNameList + if p.Token.Kind == "(" { + destinationReferenceColumns = p.parsePropertyGraphColumnNameList() + } + + return &ast.PropertyGraphEdgeElementKeys{ + // Element: elementKey, + Source: &ast.PropertyGraphSourceKey{ + Source: source, + Keys: sourceColumns, + ElementReference: sourceReference, + ReferenceColumns: sourceReferenceColumns, + }, + Destination: &ast.PropertyGraphDestinationKey{ + Destination: destination, + Keys: destinationColumns, + ElementReference: destinationReference, + ReferenceColumns: destinationReferenceColumns, + }, + } +} + +func (p *Parser) parsePropertyGraphColumnNameList() *ast.PropertyGraphColumnNameList { + lparen := p.expect("(").Pos + list := parseList(p, ",", p.parseIdent) + rparen := p.expect(")").Pos + return &ast.PropertyGraphColumnNameList{ + LParen: lparen, + RParen: rparen, + ColumnNameList: list, + } +} + +// This function can't be a method because Go haven't yet supported gemeric methods. +func parseList[T interface { + ast.Node + comparable +}](p *Parser, sep token.TokenKind, doParse func() T) []T { + first := doParse() + var zero T + if first == zero { + return nil + } + list := []T{first} + + for { + if p.Token.Kind != sep { + break + } + p.nextToken() + + elem := doParse() + if elem == zero { + return list + } + list = append(list, elem) + } + return list +} + +// DROP PROPERTY GRAPH + +func (p *Parser) parseDropPropertyGraph(pos token.Pos) *ast.DropPropertyGraph { + p.expectKeywordLike("PROPERTY") + p.expectKeywordLike("GRAPH") + ifExists := p.parseIfExists() + name := p.parseIdent() + return &ast.DropPropertyGraph{ + Drop: pos, + IfExists: ifExists, + Name: name, + } +} + func (p *Parser) parseSchemaType() ast.SchemaType { switch p.Token.Kind { case token.TokenIdent: diff --git a/testdata/input/ddl/create_or_replace_property_graph_fingraph.sql b/testdata/input/ddl/create_or_replace_property_graph_fingraph.sql new file mode 100644 index 00000000..e432bf76 --- /dev/null +++ b/testdata/input/ddl/create_or_replace_property_graph_fingraph.sql @@ -0,0 +1,15 @@ +CREATE OR REPLACE PROPERTY GRAPH FinGraph + NODE TABLES ( + Account, + Person + ) + EDGE TABLES ( + PersonOwnAccount + SOURCE KEY (id) REFERENCES Person (id) + DESTINATION KEY (account_id) REFERENCES Account (id) + LABEL Owns, + AccountTransferAccount + SOURCE KEY (id) REFERENCES Account (id) + DESTINATION KEY (to_id) REFERENCES Account (id) + LABEL Transfers + ) \ No newline at end of file diff --git a/testdata/input/ddl/create_property_graph_if_not_exists_fingraph_verbose.sql b/testdata/input/ddl/create_property_graph_if_not_exists_fingraph_verbose.sql new file mode 100644 index 00000000..67d6190c --- /dev/null +++ b/testdata/input/ddl/create_property_graph_if_not_exists_fingraph_verbose.sql @@ -0,0 +1,19 @@ +CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph + NODE TABLES ( + Account AS Account + DEFAULT LABEL + PROPERTIES (create_time, is_blocked, nick_name AS name), + Person + LABEL Person + PROPERTIES ALL COLUMNS + ) + EDGE TABLES ( + PersonOwnAccount + SOURCE KEY (id) REFERENCES Person (id) + DESTINATION KEY (account_id) REFERENCES Account (id) + LABEL Owns PROPERTIES ALL COLUMNS EXCEPT (a), + AccountTransferAccount + SOURCE KEY (id) REFERENCES Account (id) + DESTINATION KEY (to_id) REFERENCES Account (id) + LABEL Transfers NO PROPERTIES + ) \ No newline at end of file diff --git a/testdata/input/ddl/drop_property_graph.sql b/testdata/input/ddl/drop_property_graph.sql new file mode 100644 index 00000000..403d3298 --- /dev/null +++ b/testdata/input/ddl/drop_property_graph.sql @@ -0,0 +1 @@ +DROP PROPERTY GRAPH FinGraph diff --git a/testdata/input/ddl/drop_property_graph_if_exists.sql b/testdata/input/ddl/drop_property_graph_if_exists.sql new file mode 100644 index 00000000..ecb5196e --- /dev/null +++ b/testdata/input/ddl/drop_property_graph_if_exists.sql @@ -0,0 +1 @@ +DROP PROPERTY GRAPH IF EXISTS FinGraph diff --git a/testdata/result/ddl/create_or_replace_property_graph_fingraph.sql.txt b/testdata/result/ddl/create_or_replace_property_graph_fingraph.sql.txt new file mode 100644 index 00000000..d328544c --- /dev/null +++ b/testdata/result/ddl/create_or_replace_property_graph_fingraph.sql.txt @@ -0,0 +1,237 @@ +--- create_or_replace_property_graph_fingraph.sql +CREATE OR REPLACE PROPERTY GRAPH FinGraph + NODE TABLES ( + Account, + Person + ) + EDGE TABLES ( + PersonOwnAccount + SOURCE KEY (id) REFERENCES Person (id) + DESTINATION KEY (account_id) REFERENCES Account (id) + LABEL Owns, + AccountTransferAccount + SOURCE KEY (id) REFERENCES Account (id) + DESTINATION KEY (to_id) REFERENCES Account (id) + LABEL Transfers + ) +--- AST +&ast.CreatePropertyGraph{ + Create: 0, + OrReplace: true, + IfNotExists: false, + Name: &ast.Ident{ + NamePos: 33, + NameEnd: 41, + Name: "FinGraph", + }, + Content: &ast.PropertyGraphContent{ + Node: 44, + NodeTables: &ast.PropertyGraphElementList{ + LParen: 56, + RParen: 84, + Elements: []*ast.PropertyGraphElement{ + &ast.PropertyGraphElement{ + Name: &ast.Ident{ + NamePos: 62, + NameEnd: 69, + Name: "Account", + }, + Alias: (*ast.AsAlias)(nil), + Keys: nil, + Properties: nil, + }, + &ast.PropertyGraphElement{ + Name: &ast.Ident{ + NamePos: 75, + NameEnd: 81, + Name: "Person", + }, + Alias: (*ast.AsAlias)(nil), + Keys: nil, + Properties: nil, + }, + }, + }, + EdgeTables: &ast.PropertyGraphElementList{ + LParen: 100, + RParen: 396, + Elements: []*ast.PropertyGraphElement{ + &ast.PropertyGraphElement{ + Name: &ast.Ident{ + NamePos: 106, + NameEnd: 122, + Name: "PersonOwnAccount", + }, + Alias: (*ast.AsAlias)(nil), + Keys: &ast.PropertyGraphEdgeElementKeys{ + Element: (*ast.PropertyGraphElementKey)(nil), + Source: &ast.PropertyGraphSourceKey{ + Source: 129, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 140, + RParen: 143, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 141, + NameEnd: 143, + Name: "id", + }, + }, + }, + ElementReference: &ast.Ident{ + NamePos: 156, + NameEnd: 162, + Name: "Person", + }, + ReferenceColumns: &ast.PropertyGraphColumnNameList{ + LParen: 163, + RParen: 166, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 164, + NameEnd: 166, + Name: "id", + }, + }, + }, + }, + Destination: &ast.PropertyGraphDestinationKey{ + Destination: 174, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 190, + RParen: 201, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 191, + NameEnd: 201, + Name: "account_id", + }, + }, + }, + ElementReference: &ast.Ident{ + NamePos: 214, + NameEnd: 221, + Name: "Account", + }, + ReferenceColumns: &ast.PropertyGraphColumnNameList{ + LParen: 222, + RParen: 225, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 223, + NameEnd: 225, + Name: "id", + }, + }, + }, + }, + }, + Properties: &ast.PropertyGraphLabelAndPropertiesList{ + LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ + &ast.PropertyGraphLabelAndProperties{ + Label: &ast.PropertyGraphElementLabelLabelName{ + Label: 233, + Name: &ast.Ident{ + NamePos: 239, + NameEnd: 243, + Name: "Owns", + }, + }, + Properties: nil, + }, + }, + }, + }, + &ast.PropertyGraphElement{ + Name: &ast.Ident{ + NamePos: 249, + NameEnd: 271, + Name: "AccountTransferAccount", + }, + Alias: (*ast.AsAlias)(nil), + Keys: &ast.PropertyGraphEdgeElementKeys{ + Element: (*ast.PropertyGraphElementKey)(nil), + Source: &ast.PropertyGraphSourceKey{ + Source: 278, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 289, + RParen: 292, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 290, + NameEnd: 292, + Name: "id", + }, + }, + }, + ElementReference: &ast.Ident{ + NamePos: 305, + NameEnd: 312, + Name: "Account", + }, + ReferenceColumns: &ast.PropertyGraphColumnNameList{ + LParen: 313, + RParen: 316, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 314, + NameEnd: 316, + Name: "id", + }, + }, + }, + }, + Destination: &ast.PropertyGraphDestinationKey{ + Destination: 324, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 340, + RParen: 346, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 341, + NameEnd: 346, + Name: "to_id", + }, + }, + }, + ElementReference: &ast.Ident{ + NamePos: 359, + NameEnd: 366, + Name: "Account", + }, + ReferenceColumns: &ast.PropertyGraphColumnNameList{ + LParen: 367, + RParen: 370, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 368, + NameEnd: 370, + Name: "id", + }, + }, + }, + }, + }, + Properties: &ast.PropertyGraphLabelAndPropertiesList{ + LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ + &ast.PropertyGraphLabelAndProperties{ + Label: &ast.PropertyGraphElementLabelLabelName{ + Label: 378, + Name: &ast.Ident{ + NamePos: 384, + NameEnd: 393, + Name: "Transfers", + }, + }, + Properties: nil, + }, + }, + }, + }, + }, + }, + }, +} + +--- SQL +CREATE OR REPLACE PROPERTY GRAPH FinGraph NODE TABLES(Account, Person) EDGE TABLES (PersonOwnAccount SOURCE KEY (id) REFERENCES Person (id) DESTINATION KEY (account_id) REFERENCES Account (id) LABEL Owns, AccountTransferAccount SOURCE KEY (id) REFERENCES Account (id) DESTINATION KEY (to_id) REFERENCES Account (id) LABEL Transfers) diff --git a/testdata/result/ddl/create_property_graph_if_not_exists_fingraph_verbose.sql.txt b/testdata/result/ddl/create_property_graph_if_not_exists_fingraph_verbose.sql.txt new file mode 100644 index 00000000..02a55722 --- /dev/null +++ b/testdata/result/ddl/create_property_graph_if_not_exists_fingraph_verbose.sql.txt @@ -0,0 +1,326 @@ +--- create_property_graph_if_not_exists_fingraph_verbose.sql +CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph + NODE TABLES ( + Account AS Account + DEFAULT LABEL + PROPERTIES (create_time, is_blocked, nick_name AS name), + Person + LABEL Person + PROPERTIES ALL COLUMNS + ) + EDGE TABLES ( + PersonOwnAccount + SOURCE KEY (id) REFERENCES Person (id) + DESTINATION KEY (account_id) REFERENCES Account (id) + LABEL Owns PROPERTIES ALL COLUMNS EXCEPT (a), + AccountTransferAccount + SOURCE KEY (id) REFERENCES Account (id) + DESTINATION KEY (to_id) REFERENCES Account (id) + LABEL Transfers NO PROPERTIES + ) +--- AST +&ast.CreatePropertyGraph{ + Create: 0, + OrReplace: false, + IfNotExists: true, + Name: &ast.Ident{ + NamePos: 36, + NameEnd: 44, + Name: "FinGraph", + }, + Content: &ast.PropertyGraphContent{ + Node: 47, + NodeTables: &ast.PropertyGraphElementList{ + LParen: 59, + RParen: 232, + Elements: []*ast.PropertyGraphElement{ + &ast.PropertyGraphElement{ + Name: &ast.Ident{ + NamePos: 65, + NameEnd: 72, + Name: "Account", + }, + Alias: &ast.AsAlias{ + As: -1, + Alias: &ast.Ident{ + NamePos: 76, + NameEnd: 83, + Name: "Account", + }, + }, + Keys: nil, + Properties: &ast.PropertyGraphLabelAndPropertiesList{ + LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ + &ast.PropertyGraphLabelAndProperties{ + Label: &ast.PropertyGraphElementLabelDefaultLabel{ + Default: 91, + Label: 99, + }, + Properties: &ast.PropertyGraphDerivedPropertyList{ + Properties: 112, + RParen: 166, + DerivedProperties: []*ast.PropertyGraphDerivedProperty{ + &ast.PropertyGraphDerivedProperty{ + Expr: &ast.Ident{ + NamePos: 124, + NameEnd: 135, + Name: "create_time", + }, + PropertyName: (*ast.Ident)(nil), + }, + &ast.PropertyGraphDerivedProperty{ + Expr: &ast.Ident{ + NamePos: 137, + NameEnd: 147, + Name: "is_blocked", + }, + PropertyName: (*ast.Ident)(nil), + }, + &ast.PropertyGraphDerivedProperty{ + Expr: &ast.Ident{ + NamePos: 149, + NameEnd: 158, + Name: "nick_name", + }, + PropertyName: &ast.Ident{ + NamePos: 162, + NameEnd: 166, + Name: "name", + }, + }, + }, + }, + }, + }, + }, + }, + &ast.PropertyGraphElement{ + Name: &ast.Ident{ + NamePos: 173, + NameEnd: 179, + Name: "Person", + }, + Alias: (*ast.AsAlias)(nil), + Keys: nil, + Properties: &ast.PropertyGraphLabelAndPropertiesList{ + LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ + &ast.PropertyGraphLabelAndProperties{ + Label: &ast.PropertyGraphElementLabelLabelName{ + Label: 187, + Name: &ast.Ident{ + NamePos: 193, + NameEnd: 199, + Name: "Person", + }, + }, + Properties: &ast.PropertyGraphPropertiesAre{ + Properties: 207, + Columns: 222, + ExceptColumns: (*ast.PropertyGraphColumnNameList)(nil), + }, + }, + }, + }, + }, + }, + }, + EdgeTables: &ast.PropertyGraphElementList{ + LParen: 248, + RParen: 592, + Elements: []*ast.PropertyGraphElement{ + &ast.PropertyGraphElement{ + Name: &ast.Ident{ + NamePos: 254, + NameEnd: 270, + Name: "PersonOwnAccount", + }, + Alias: (*ast.AsAlias)(nil), + Keys: &ast.PropertyGraphEdgeElementKeys{ + Element: (*ast.PropertyGraphElementKey)(nil), + Source: &ast.PropertyGraphSourceKey{ + Source: 277, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 288, + RParen: 291, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 289, + NameEnd: 291, + Name: "id", + }, + }, + }, + ElementReference: &ast.Ident{ + NamePos: 304, + NameEnd: 310, + Name: "Person", + }, + ReferenceColumns: &ast.PropertyGraphColumnNameList{ + LParen: 311, + RParen: 314, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 312, + NameEnd: 314, + Name: "id", + }, + }, + }, + }, + Destination: &ast.PropertyGraphDestinationKey{ + Destination: 322, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 338, + RParen: 349, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 339, + NameEnd: 349, + Name: "account_id", + }, + }, + }, + ElementReference: &ast.Ident{ + NamePos: 362, + NameEnd: 369, + Name: "Account", + }, + ReferenceColumns: &ast.PropertyGraphColumnNameList{ + LParen: 370, + RParen: 373, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 371, + NameEnd: 373, + Name: "id", + }, + }, + }, + }, + }, + Properties: &ast.PropertyGraphLabelAndPropertiesList{ + LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ + &ast.PropertyGraphLabelAndProperties{ + Label: &ast.PropertyGraphElementLabelLabelName{ + Label: 381, + Name: &ast.Ident{ + NamePos: 387, + NameEnd: 391, + Name: "Owns", + }, + }, + Properties: &ast.PropertyGraphPropertiesAre{ + Properties: 392, + Columns: 407, + ExceptColumns: &ast.PropertyGraphColumnNameList{ + LParen: 422, + RParen: 424, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 423, + NameEnd: 424, + Name: "a", + }, + }, + }, + }, + }, + }, + }, + }, + &ast.PropertyGraphElement{ + Name: &ast.Ident{ + NamePos: 431, + NameEnd: 453, + Name: "AccountTransferAccount", + }, + Alias: (*ast.AsAlias)(nil), + Keys: &ast.PropertyGraphEdgeElementKeys{ + Element: (*ast.PropertyGraphElementKey)(nil), + Source: &ast.PropertyGraphSourceKey{ + Source: 460, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 471, + RParen: 474, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 472, + NameEnd: 474, + Name: "id", + }, + }, + }, + ElementReference: &ast.Ident{ + NamePos: 487, + NameEnd: 494, + Name: "Account", + }, + ReferenceColumns: &ast.PropertyGraphColumnNameList{ + LParen: 495, + RParen: 498, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 496, + NameEnd: 498, + Name: "id", + }, + }, + }, + }, + Destination: &ast.PropertyGraphDestinationKey{ + Destination: 506, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 522, + RParen: 528, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 523, + NameEnd: 528, + Name: "to_id", + }, + }, + }, + ElementReference: &ast.Ident{ + NamePos: 541, + NameEnd: 548, + Name: "Account", + }, + ReferenceColumns: &ast.PropertyGraphColumnNameList{ + LParen: 549, + RParen: 552, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 550, + NameEnd: 552, + Name: "id", + }, + }, + }, + }, + }, + Properties: &ast.PropertyGraphLabelAndPropertiesList{ + LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ + &ast.PropertyGraphLabelAndProperties{ + Label: &ast.PropertyGraphElementLabelLabelName{ + Label: 560, + Name: &ast.Ident{ + NamePos: 566, + NameEnd: 575, + Name: "Transfers", + }, + }, + Properties: &ast.PropertyGraphNoProperties{ + No: 576, + Properties: 579, + }, + }, + }, + }, + }, + }, + }, + }, +} + +--- SQL +CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph NODE TABLES(Account AS Account DEFAULT LABEL PROPERTIES (create_time, is_blocked, nick_name AS name), Person LABEL Person PROPERTIES ARE ALL COLUMNS) EDGE TABLES (PersonOwnAccount SOURCE KEY (id) REFERENCES Person (id) DESTINATION KEY (account_id) REFERENCES Account (id) LABEL Owns PROPERTIES ARE ALL COLUMNS EXCEPT (a), AccountTransferAccount SOURCE KEY (id) REFERENCES Account (id) DESTINATION KEY (to_id) REFERENCES Account (id) LABEL Transfers NO PROPERTIES) diff --git a/testdata/result/ddl/drop_property_graph.sql.txt b/testdata/result/ddl/drop_property_graph.sql.txt new file mode 100644 index 00000000..d229e02f --- /dev/null +++ b/testdata/result/ddl/drop_property_graph.sql.txt @@ -0,0 +1,16 @@ +--- drop_property_graph.sql +DROP PROPERTY GRAPH FinGraph + +--- AST +&ast.DropPropertyGraph{ + Drop: 0, + IfExists: false, + Name: &ast.Ident{ + NamePos: 20, + NameEnd: 28, + Name: "FinGraph", + }, +} + +--- SQL +DROP PROPERTY GRAPH FinGraph diff --git a/testdata/result/ddl/drop_property_graph_if_exists.sql.txt b/testdata/result/ddl/drop_property_graph_if_exists.sql.txt new file mode 100644 index 00000000..2ec607fc --- /dev/null +++ b/testdata/result/ddl/drop_property_graph_if_exists.sql.txt @@ -0,0 +1,16 @@ +--- drop_property_graph_if_exists.sql +DROP PROPERTY GRAPH IF EXISTS FinGraph + +--- AST +&ast.DropPropertyGraph{ + Drop: 0, + IfExists: true, + Name: &ast.Ident{ + NamePos: 30, + NameEnd: 38, + Name: "FinGraph", + }, +} + +--- SQL +DROP PROPERTY GRAPH IF EXISTS FinGraph diff --git a/testdata/result/statement/create_or_replace_property_graph_fingraph.sql.txt b/testdata/result/statement/create_or_replace_property_graph_fingraph.sql.txt new file mode 100644 index 00000000..d328544c --- /dev/null +++ b/testdata/result/statement/create_or_replace_property_graph_fingraph.sql.txt @@ -0,0 +1,237 @@ +--- create_or_replace_property_graph_fingraph.sql +CREATE OR REPLACE PROPERTY GRAPH FinGraph + NODE TABLES ( + Account, + Person + ) + EDGE TABLES ( + PersonOwnAccount + SOURCE KEY (id) REFERENCES Person (id) + DESTINATION KEY (account_id) REFERENCES Account (id) + LABEL Owns, + AccountTransferAccount + SOURCE KEY (id) REFERENCES Account (id) + DESTINATION KEY (to_id) REFERENCES Account (id) + LABEL Transfers + ) +--- AST +&ast.CreatePropertyGraph{ + Create: 0, + OrReplace: true, + IfNotExists: false, + Name: &ast.Ident{ + NamePos: 33, + NameEnd: 41, + Name: "FinGraph", + }, + Content: &ast.PropertyGraphContent{ + Node: 44, + NodeTables: &ast.PropertyGraphElementList{ + LParen: 56, + RParen: 84, + Elements: []*ast.PropertyGraphElement{ + &ast.PropertyGraphElement{ + Name: &ast.Ident{ + NamePos: 62, + NameEnd: 69, + Name: "Account", + }, + Alias: (*ast.AsAlias)(nil), + Keys: nil, + Properties: nil, + }, + &ast.PropertyGraphElement{ + Name: &ast.Ident{ + NamePos: 75, + NameEnd: 81, + Name: "Person", + }, + Alias: (*ast.AsAlias)(nil), + Keys: nil, + Properties: nil, + }, + }, + }, + EdgeTables: &ast.PropertyGraphElementList{ + LParen: 100, + RParen: 396, + Elements: []*ast.PropertyGraphElement{ + &ast.PropertyGraphElement{ + Name: &ast.Ident{ + NamePos: 106, + NameEnd: 122, + Name: "PersonOwnAccount", + }, + Alias: (*ast.AsAlias)(nil), + Keys: &ast.PropertyGraphEdgeElementKeys{ + Element: (*ast.PropertyGraphElementKey)(nil), + Source: &ast.PropertyGraphSourceKey{ + Source: 129, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 140, + RParen: 143, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 141, + NameEnd: 143, + Name: "id", + }, + }, + }, + ElementReference: &ast.Ident{ + NamePos: 156, + NameEnd: 162, + Name: "Person", + }, + ReferenceColumns: &ast.PropertyGraphColumnNameList{ + LParen: 163, + RParen: 166, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 164, + NameEnd: 166, + Name: "id", + }, + }, + }, + }, + Destination: &ast.PropertyGraphDestinationKey{ + Destination: 174, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 190, + RParen: 201, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 191, + NameEnd: 201, + Name: "account_id", + }, + }, + }, + ElementReference: &ast.Ident{ + NamePos: 214, + NameEnd: 221, + Name: "Account", + }, + ReferenceColumns: &ast.PropertyGraphColumnNameList{ + LParen: 222, + RParen: 225, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 223, + NameEnd: 225, + Name: "id", + }, + }, + }, + }, + }, + Properties: &ast.PropertyGraphLabelAndPropertiesList{ + LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ + &ast.PropertyGraphLabelAndProperties{ + Label: &ast.PropertyGraphElementLabelLabelName{ + Label: 233, + Name: &ast.Ident{ + NamePos: 239, + NameEnd: 243, + Name: "Owns", + }, + }, + Properties: nil, + }, + }, + }, + }, + &ast.PropertyGraphElement{ + Name: &ast.Ident{ + NamePos: 249, + NameEnd: 271, + Name: "AccountTransferAccount", + }, + Alias: (*ast.AsAlias)(nil), + Keys: &ast.PropertyGraphEdgeElementKeys{ + Element: (*ast.PropertyGraphElementKey)(nil), + Source: &ast.PropertyGraphSourceKey{ + Source: 278, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 289, + RParen: 292, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 290, + NameEnd: 292, + Name: "id", + }, + }, + }, + ElementReference: &ast.Ident{ + NamePos: 305, + NameEnd: 312, + Name: "Account", + }, + ReferenceColumns: &ast.PropertyGraphColumnNameList{ + LParen: 313, + RParen: 316, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 314, + NameEnd: 316, + Name: "id", + }, + }, + }, + }, + Destination: &ast.PropertyGraphDestinationKey{ + Destination: 324, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 340, + RParen: 346, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 341, + NameEnd: 346, + Name: "to_id", + }, + }, + }, + ElementReference: &ast.Ident{ + NamePos: 359, + NameEnd: 366, + Name: "Account", + }, + ReferenceColumns: &ast.PropertyGraphColumnNameList{ + LParen: 367, + RParen: 370, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 368, + NameEnd: 370, + Name: "id", + }, + }, + }, + }, + }, + Properties: &ast.PropertyGraphLabelAndPropertiesList{ + LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ + &ast.PropertyGraphLabelAndProperties{ + Label: &ast.PropertyGraphElementLabelLabelName{ + Label: 378, + Name: &ast.Ident{ + NamePos: 384, + NameEnd: 393, + Name: "Transfers", + }, + }, + Properties: nil, + }, + }, + }, + }, + }, + }, + }, +} + +--- SQL +CREATE OR REPLACE PROPERTY GRAPH FinGraph NODE TABLES(Account, Person) EDGE TABLES (PersonOwnAccount SOURCE KEY (id) REFERENCES Person (id) DESTINATION KEY (account_id) REFERENCES Account (id) LABEL Owns, AccountTransferAccount SOURCE KEY (id) REFERENCES Account (id) DESTINATION KEY (to_id) REFERENCES Account (id) LABEL Transfers) diff --git a/testdata/result/statement/create_property_graph_if_not_exists_fingraph_verbose.sql.txt b/testdata/result/statement/create_property_graph_if_not_exists_fingraph_verbose.sql.txt new file mode 100644 index 00000000..02a55722 --- /dev/null +++ b/testdata/result/statement/create_property_graph_if_not_exists_fingraph_verbose.sql.txt @@ -0,0 +1,326 @@ +--- create_property_graph_if_not_exists_fingraph_verbose.sql +CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph + NODE TABLES ( + Account AS Account + DEFAULT LABEL + PROPERTIES (create_time, is_blocked, nick_name AS name), + Person + LABEL Person + PROPERTIES ALL COLUMNS + ) + EDGE TABLES ( + PersonOwnAccount + SOURCE KEY (id) REFERENCES Person (id) + DESTINATION KEY (account_id) REFERENCES Account (id) + LABEL Owns PROPERTIES ALL COLUMNS EXCEPT (a), + AccountTransferAccount + SOURCE KEY (id) REFERENCES Account (id) + DESTINATION KEY (to_id) REFERENCES Account (id) + LABEL Transfers NO PROPERTIES + ) +--- AST +&ast.CreatePropertyGraph{ + Create: 0, + OrReplace: false, + IfNotExists: true, + Name: &ast.Ident{ + NamePos: 36, + NameEnd: 44, + Name: "FinGraph", + }, + Content: &ast.PropertyGraphContent{ + Node: 47, + NodeTables: &ast.PropertyGraphElementList{ + LParen: 59, + RParen: 232, + Elements: []*ast.PropertyGraphElement{ + &ast.PropertyGraphElement{ + Name: &ast.Ident{ + NamePos: 65, + NameEnd: 72, + Name: "Account", + }, + Alias: &ast.AsAlias{ + As: -1, + Alias: &ast.Ident{ + NamePos: 76, + NameEnd: 83, + Name: "Account", + }, + }, + Keys: nil, + Properties: &ast.PropertyGraphLabelAndPropertiesList{ + LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ + &ast.PropertyGraphLabelAndProperties{ + Label: &ast.PropertyGraphElementLabelDefaultLabel{ + Default: 91, + Label: 99, + }, + Properties: &ast.PropertyGraphDerivedPropertyList{ + Properties: 112, + RParen: 166, + DerivedProperties: []*ast.PropertyGraphDerivedProperty{ + &ast.PropertyGraphDerivedProperty{ + Expr: &ast.Ident{ + NamePos: 124, + NameEnd: 135, + Name: "create_time", + }, + PropertyName: (*ast.Ident)(nil), + }, + &ast.PropertyGraphDerivedProperty{ + Expr: &ast.Ident{ + NamePos: 137, + NameEnd: 147, + Name: "is_blocked", + }, + PropertyName: (*ast.Ident)(nil), + }, + &ast.PropertyGraphDerivedProperty{ + Expr: &ast.Ident{ + NamePos: 149, + NameEnd: 158, + Name: "nick_name", + }, + PropertyName: &ast.Ident{ + NamePos: 162, + NameEnd: 166, + Name: "name", + }, + }, + }, + }, + }, + }, + }, + }, + &ast.PropertyGraphElement{ + Name: &ast.Ident{ + NamePos: 173, + NameEnd: 179, + Name: "Person", + }, + Alias: (*ast.AsAlias)(nil), + Keys: nil, + Properties: &ast.PropertyGraphLabelAndPropertiesList{ + LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ + &ast.PropertyGraphLabelAndProperties{ + Label: &ast.PropertyGraphElementLabelLabelName{ + Label: 187, + Name: &ast.Ident{ + NamePos: 193, + NameEnd: 199, + Name: "Person", + }, + }, + Properties: &ast.PropertyGraphPropertiesAre{ + Properties: 207, + Columns: 222, + ExceptColumns: (*ast.PropertyGraphColumnNameList)(nil), + }, + }, + }, + }, + }, + }, + }, + EdgeTables: &ast.PropertyGraphElementList{ + LParen: 248, + RParen: 592, + Elements: []*ast.PropertyGraphElement{ + &ast.PropertyGraphElement{ + Name: &ast.Ident{ + NamePos: 254, + NameEnd: 270, + Name: "PersonOwnAccount", + }, + Alias: (*ast.AsAlias)(nil), + Keys: &ast.PropertyGraphEdgeElementKeys{ + Element: (*ast.PropertyGraphElementKey)(nil), + Source: &ast.PropertyGraphSourceKey{ + Source: 277, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 288, + RParen: 291, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 289, + NameEnd: 291, + Name: "id", + }, + }, + }, + ElementReference: &ast.Ident{ + NamePos: 304, + NameEnd: 310, + Name: "Person", + }, + ReferenceColumns: &ast.PropertyGraphColumnNameList{ + LParen: 311, + RParen: 314, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 312, + NameEnd: 314, + Name: "id", + }, + }, + }, + }, + Destination: &ast.PropertyGraphDestinationKey{ + Destination: 322, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 338, + RParen: 349, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 339, + NameEnd: 349, + Name: "account_id", + }, + }, + }, + ElementReference: &ast.Ident{ + NamePos: 362, + NameEnd: 369, + Name: "Account", + }, + ReferenceColumns: &ast.PropertyGraphColumnNameList{ + LParen: 370, + RParen: 373, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 371, + NameEnd: 373, + Name: "id", + }, + }, + }, + }, + }, + Properties: &ast.PropertyGraphLabelAndPropertiesList{ + LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ + &ast.PropertyGraphLabelAndProperties{ + Label: &ast.PropertyGraphElementLabelLabelName{ + Label: 381, + Name: &ast.Ident{ + NamePos: 387, + NameEnd: 391, + Name: "Owns", + }, + }, + Properties: &ast.PropertyGraphPropertiesAre{ + Properties: 392, + Columns: 407, + ExceptColumns: &ast.PropertyGraphColumnNameList{ + LParen: 422, + RParen: 424, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 423, + NameEnd: 424, + Name: "a", + }, + }, + }, + }, + }, + }, + }, + }, + &ast.PropertyGraphElement{ + Name: &ast.Ident{ + NamePos: 431, + NameEnd: 453, + Name: "AccountTransferAccount", + }, + Alias: (*ast.AsAlias)(nil), + Keys: &ast.PropertyGraphEdgeElementKeys{ + Element: (*ast.PropertyGraphElementKey)(nil), + Source: &ast.PropertyGraphSourceKey{ + Source: 460, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 471, + RParen: 474, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 472, + NameEnd: 474, + Name: "id", + }, + }, + }, + ElementReference: &ast.Ident{ + NamePos: 487, + NameEnd: 494, + Name: "Account", + }, + ReferenceColumns: &ast.PropertyGraphColumnNameList{ + LParen: 495, + RParen: 498, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 496, + NameEnd: 498, + Name: "id", + }, + }, + }, + }, + Destination: &ast.PropertyGraphDestinationKey{ + Destination: 506, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 522, + RParen: 528, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 523, + NameEnd: 528, + Name: "to_id", + }, + }, + }, + ElementReference: &ast.Ident{ + NamePos: 541, + NameEnd: 548, + Name: "Account", + }, + ReferenceColumns: &ast.PropertyGraphColumnNameList{ + LParen: 549, + RParen: 552, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 550, + NameEnd: 552, + Name: "id", + }, + }, + }, + }, + }, + Properties: &ast.PropertyGraphLabelAndPropertiesList{ + LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ + &ast.PropertyGraphLabelAndProperties{ + Label: &ast.PropertyGraphElementLabelLabelName{ + Label: 560, + Name: &ast.Ident{ + NamePos: 566, + NameEnd: 575, + Name: "Transfers", + }, + }, + Properties: &ast.PropertyGraphNoProperties{ + No: 576, + Properties: 579, + }, + }, + }, + }, + }, + }, + }, + }, +} + +--- SQL +CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph NODE TABLES(Account AS Account DEFAULT LABEL PROPERTIES (create_time, is_blocked, nick_name AS name), Person LABEL Person PROPERTIES ARE ALL COLUMNS) EDGE TABLES (PersonOwnAccount SOURCE KEY (id) REFERENCES Person (id) DESTINATION KEY (account_id) REFERENCES Account (id) LABEL Owns PROPERTIES ARE ALL COLUMNS EXCEPT (a), AccountTransferAccount SOURCE KEY (id) REFERENCES Account (id) DESTINATION KEY (to_id) REFERENCES Account (id) LABEL Transfers NO PROPERTIES) diff --git a/testdata/result/statement/drop_property_graph.sql.txt b/testdata/result/statement/drop_property_graph.sql.txt new file mode 100644 index 00000000..d229e02f --- /dev/null +++ b/testdata/result/statement/drop_property_graph.sql.txt @@ -0,0 +1,16 @@ +--- drop_property_graph.sql +DROP PROPERTY GRAPH FinGraph + +--- AST +&ast.DropPropertyGraph{ + Drop: 0, + IfExists: false, + Name: &ast.Ident{ + NamePos: 20, + NameEnd: 28, + Name: "FinGraph", + }, +} + +--- SQL +DROP PROPERTY GRAPH FinGraph diff --git a/testdata/result/statement/drop_property_graph_if_exists.sql.txt b/testdata/result/statement/drop_property_graph_if_exists.sql.txt new file mode 100644 index 00000000..2ec607fc --- /dev/null +++ b/testdata/result/statement/drop_property_graph_if_exists.sql.txt @@ -0,0 +1,16 @@ +--- drop_property_graph_if_exists.sql +DROP PROPERTY GRAPH IF EXISTS FinGraph + +--- AST +&ast.DropPropertyGraph{ + Drop: 0, + IfExists: true, + Name: &ast.Ident{ + NamePos: 30, + NameEnd: 38, + Name: "FinGraph", + }, +} + +--- SQL +DROP PROPERTY GRAPH IF EXISTS FinGraph From 52da53508cac00a29b1b69292848f8f601018873 Mon Sep 17 00:00:00 2001 From: apstndb <803393+apstndb@users.noreply.github.com> Date: Thu, 19 Sep 2024 16:14:57 +0900 Subject: [PATCH 03/13] Improve GQL schema statements --- ast/ast.go | 294 ++---------------- ast/pos.go | 71 +++++ ast/sql.go | 95 ++++++ parser.go | 224 ++++++------- ...or_replace_property_graph_fingraph.sql.txt | 8 +- ...aph_if_not_exists_fingraph_verbose.sql.txt | 17 +- ...or_replace_property_graph_fingraph.sql.txt | 8 +- ...aph_if_not_exists_fingraph_verbose.sql.txt | 17 +- 8 files changed, 326 insertions(+), 408 deletions(-) diff --git a/ast/ast.go b/ast/ast.go index 32c21fa4..a75dc5c5 100644 --- a/ast/ast.go +++ b/ast/ast.go @@ -2309,8 +2309,8 @@ type ArraySchemaType struct { // CreatePropertyGraph is CREATE PROPERTY GRAPH statement node. // -// CREATE {{if.OrReplace }}OR REPLACE{{end}} PROPERTY GRAPH {{if .IfNotExists}}IF NOT EXISTS{{end}} {{.Name | sql}} -// {{.Content | sql}} +// CREATE {{if .OrReplace}}OR REPLACE{{end}} PROPERTY GRAPH {{if .IfNotExists}}IF NOT EXISTS{{end}} {{.Name | sql}} +// {{.Content | sql}} type CreatePropertyGraph struct { // pos = Create // end = Content.end @@ -2322,27 +2322,6 @@ type CreatePropertyGraph struct { Content *PropertyGraphContent } -func (c *CreatePropertyGraph) Pos() token.Pos { - return c.Create -} - -func (c *CreatePropertyGraph) End() token.Pos { - return c.Content.End() -} - -func (c *CreatePropertyGraph) SQL() string { - sql := "CREATE " - if c.OrReplace { - sql += "OR REPLACE " - } - sql += "PROPERTY GRAPH " - if c.IfNotExists { - sql += "IF NOT EXISTS " - } - sql += c.Name.SQL() + " " + c.Content.SQL() - return sql -} - // PropertyGraphContent // // NODE TABLES {{.NodeTables | sql}} {{if not(.EdgeTables | isnil)}}NODE TABLES {{.EdgeTables | sqlOpt}}{{end}} @@ -2355,18 +2334,6 @@ type PropertyGraphContent struct { EdgeTables *PropertyGraphElementList //optional } -func (p *PropertyGraphContent) Pos() token.Pos { - return p.Node -} - -func (p *PropertyGraphContent) End() token.Pos { - return firstValidEnd(p.EdgeTables, p.NodeTables) -} - -func (p *PropertyGraphContent) SQL() string { - return "NODE TABLES" + p.NodeTables.SQL() + sqlOpt(" EDGE TABLES ", p.EdgeTables, "") -} - // PropertyGraphElementList // // ({{.Elements | sqlJoin ", "}}) @@ -2378,52 +2345,32 @@ type PropertyGraphElementList struct { Elements []*PropertyGraphElement } -func (p *PropertyGraphElementList) Pos() token.Pos { - return p.LParen -} - -func (p *PropertyGraphElementList) End() token.Pos { - return p.RParen + 1 -} - -func (p *PropertyGraphElementList) SQL() string { - return "(" + sqlJoin(p.Elements, ", ") + ")" -} - // PropertyGraphElement // -// {{.Ident | sql}} {{.AsAlias | sqlOpt}} {{.Keys | sqlOpt}} {{.Properties | sqlOpt}} +// {{.Ident | sql}} {{if not(.Alias | isnil)}} AS {{.Alias | sql}}{{end}} {{.Keys | sqlOpt}} {{.Properties | sqlOpt}} type PropertyGraphElement struct { // pos = Name.pos // end = (Properties ?? Keys ?? Alias ?? Name).end Name *Ident - Alias *AsAlias // optional + Alias *Ident // optional Keys PropertyGraphElementKeys // optional Properties PropertyGraphProperties // optional } -func (p *PropertyGraphElement) Pos() token.Pos { - return p.Name.Pos() -} - -func (p *PropertyGraphElement) End() token.Pos { - return firstValidEnd(p.Properties, p.Keys, p.Alias, p.Name) -} - -func (p *PropertyGraphElement) SQL() string { - return p.Name.SQL() + - sqlOpt(" ", p.Alias, "") + - sqlOpt(" ", p.Keys, "") + - sqlOpt(" ", p.Properties, "") -} - type PropertyGraphProperties interface { Node isPropertyGraphProperties() } -// PropertyGraphLabelAndPropertiesList +func (*PropertyGraphNoProperties) isPropertyGraphProperties() {} +func (*PropertyGraphPropertiesAre) isPropertyGraphProperties() {} +func (*PropertyGraphElementLabelLabelName) isPropertyGraphProperties() {} +func (*PropertyGraphLabelAndPropertiesList) isPropertyGraphProperties() {} +func (*PropertyGraphElementLabelDefaultLabel) isPropertyGraphProperties() {} + +// PropertyGraphLabelAndPropertiesList represents whitespace-separated list of PropertyGraphLabelAndProperties. +// It implements PropertyGraphProperties. // // {{.LabelAndProperties | sqlJoin " "}} type PropertyGraphLabelAndPropertiesList struct { @@ -2433,19 +2380,9 @@ type PropertyGraphLabelAndPropertiesList struct { LabelAndProperties []*PropertyGraphLabelAndProperties } -func (p *PropertyGraphLabelAndPropertiesList) Pos() token.Pos { - return firstPos(p.LabelAndProperties) -} - -func (p *PropertyGraphLabelAndPropertiesList) End() token.Pos { - return lastEnd(p.LabelAndProperties) -} - -func (p *PropertyGraphLabelAndPropertiesList) SQL() string { - return sqlJoin(p.LabelAndProperties, " ") -} - // PropertyGraphLabelAndProperties +// +// {{.Label | sql}} {{.Properties | sqlOpt}} type PropertyGraphLabelAndProperties struct { // pos = Label.pos // end = (Properties ?? Label).end @@ -2454,18 +2391,6 @@ type PropertyGraphLabelAndProperties struct { Properties PropertyGraphElementProperties // optional } -func (p *PropertyGraphLabelAndProperties) Pos() token.Pos { - return p.Label.Pos() -} - -func (p *PropertyGraphLabelAndProperties) End() token.Pos { - return firstValidEnd(p.Properties, p.Label) -} - -func (p *PropertyGraphLabelAndProperties) SQL() string { - return p.Label.SQL() + sqlOpt(" ", p.Properties, "") -} - type PropertyGraphElementLabel interface { Node isPropertyGraphElementLabel() @@ -2485,20 +2410,6 @@ type PropertyGraphElementLabelLabelName struct { Name *Ident } -func (*PropertyGraphElementLabelLabelName) isPropertyGraphProperties() {} - -func (p *PropertyGraphElementLabelLabelName) Pos() token.Pos { - return p.Label -} - -func (p *PropertyGraphElementLabelLabelName) End() token.Pos { - return p.Name.End() -} - -func (p *PropertyGraphElementLabelLabelName) SQL() string { - return "LABEL " + p.Name.SQL() -} - // PropertyGraphElementLabelDefaultLabel // // DEFAULT LABEL @@ -2509,22 +2420,6 @@ type PropertyGraphElementLabelDefaultLabel struct { Label token.Pos } -func (*PropertyGraphElementLabelDefaultLabel) isPropertyGraphProperties() {} - -func (p *PropertyGraphElementLabelDefaultLabel) Pos() token.Pos { - return p.Default -} - -func (p *PropertyGraphElementLabelDefaultLabel) End() token.Pos { - return p.Label + 5 -} - -func (p *PropertyGraphElementLabelDefaultLabel) SQL() string { - return "DEFAULT LABEL" -} - -func (*PropertyGraphLabelAndPropertiesList) isPropertyGraphProperties() {} - type PropertyGraphElementKeys interface { Node isPropertyGraphElementKeys() @@ -2533,42 +2428,28 @@ type PropertyGraphElementKeys interface { func (*PropertyGraphNodeElementKey) isPropertyGraphElementKeys() {} func (*PropertyGraphEdgeElementKeys) isPropertyGraphElementKeys() {} -// PropertyGraphNodeElementKey is a wrapper of PropertyGraphElementKey +// PropertyGraphNodeElementKey is a wrapper of PropertyGraphElementKey to implement PropertyGraphElementKeys +// without deeper AST hierarchy. +// +// {{.PropertyGraphElementKey | sql}} type PropertyGraphNodeElementKey struct { - PropertyGraphElementKey -} - -func (p *PropertyGraphNodeElementKey) Pos() token.Pos { - return p.PropertyGraphElementKey.Pos() -} + // pos = PropertyGraphElementKey.pos + // end = PropertyGraphElementKey.end -func (p *PropertyGraphNodeElementKey) End() token.Pos { - return p.PropertyGraphElementKey.End() -} - -func (p *PropertyGraphNodeElementKey) SQL() string { - return p.PropertyGraphElementKey.SQL() + PropertyGraphElementKey } // PropertyGraphEdgeElementKeys // -// {{.Element | sql}} {{.Source | sql}} {{.Destination | sql}} +// {{.Element | sqlOpt}} {{.Source | sql}} {{.Destination | sql}} type PropertyGraphEdgeElementKeys struct { // pos = Element.pos // end = Destination.end - Element *PropertyGraphElementKey + Element *PropertyGraphElementKey // optional Source *PropertyGraphSourceKey Destination *PropertyGraphDestinationKey } -func (p *PropertyGraphEdgeElementKeys) Pos() token.Pos { - return p.Element.Pos() -} - -func (p *PropertyGraphEdgeElementKeys) End() token.Pos { - return p.Destination.End() -} - func (p *PropertyGraphEdgeElementKeys) SQL() string { return sqlOpt("", p.Element, " ") + p.Source.SQL() + " " + p.Destination.SQL() } @@ -2584,18 +2465,6 @@ type PropertyGraphElementKey struct { Keys *PropertyGraphColumnNameList } -func (p *PropertyGraphElementKey) Pos() token.Pos { - return p.Key -} - -func (p *PropertyGraphElementKey) End() token.Pos { - return p.Keys.End() -} - -func (p *PropertyGraphElementKey) SQL() string { - return "KEY " + p.Keys.SQL() -} - // PropertyGraphSourceKey // // SOURCE KEY {{.Keys | sql}} @@ -2610,20 +2479,6 @@ type PropertyGraphSourceKey struct { ReferenceColumns *PropertyGraphColumnNameList // optional } -func (p *PropertyGraphSourceKey) Pos() token.Pos { - return p.Source -} - -func (p *PropertyGraphSourceKey) End() token.Pos { - return firstValidEnd(p.ReferenceColumns, p.ElementReference) -} - -func (p *PropertyGraphSourceKey) SQL() string { - return "SOURCE KEY " + p.Keys.SQL() + - " REFERENCES " + p.ElementReference.SQL() + - sqlOpt(" ", p.ReferenceColumns, "") -} - // PropertyGraphDestinationKey // // DESTINATION KEY {{.Keys | sql}} @@ -2638,20 +2493,6 @@ type PropertyGraphDestinationKey struct { ReferenceColumns *PropertyGraphColumnNameList // optional } -func (p *PropertyGraphDestinationKey) Pos() token.Pos { - return p.Destination -} - -func (p *PropertyGraphDestinationKey) End() token.Pos { - return firstValidEnd(p.ElementReference, p.ElementReference) -} - -func (p *PropertyGraphDestinationKey) SQL() string { - return "DESTINATION KEY " + p.Keys.SQL() + - " REFERENCES " + p.ElementReference.SQL() + - sqlOpt(" ", p.ReferenceColumns, "") -} - // PropertyGraphColumnNameList // // ({{.ColumnNameList | sqlJoin ", "}}) @@ -2662,18 +2503,6 @@ type PropertyGraphColumnNameList struct { ColumnNameList []*Ident } -func (p *PropertyGraphColumnNameList) Pos() token.Pos { - return p.LParen -} - -func (p *PropertyGraphColumnNameList) End() token.Pos { - return p.RParen + 1 -} - -func (p *PropertyGraphColumnNameList) SQL() string { - return "(" + sqlJoin(p.ColumnNameList, ", ") + ")" -} - // Element properties definition // https://cloud.google.com/spanner/docs/reference/standard-sql/graph-schema-statements#element_table_property_definition @@ -2682,8 +2511,6 @@ type PropertyGraphElementProperties interface { isPropertyGraphElementProperties() } -func (p *PropertyGraphNoProperties) isPropertyGraphElementProperties() {} - // PropertyGraphNoProperties // // NO PROPERTIES @@ -2694,20 +2521,6 @@ type PropertyGraphNoProperties struct { No, Properties token.Pos // position of "NO" and "PROPERTIES" } -func (p *PropertyGraphNoProperties) isPropertyGraphProperties() {} - -func (p *PropertyGraphNoProperties) Pos() token.Pos { - return p.No -} - -func (p PropertyGraphNoProperties) End() token.Pos { - return p.Properties + 10 -} - -func (p PropertyGraphNoProperties) SQL() string { - return "NO PROPERTIES" -} - // PropertyGraphPropertiesAre // // PROPERTIES ARE ALL COLUMNS{{if not(.ExceptColumns | isnil)}} EXCEPT {{.ExceptColumns}}{{end}} @@ -2722,21 +2535,8 @@ type PropertyGraphPropertiesAre struct { } -func (*PropertyGraphPropertiesAre) isPropertyGraphProperties() {} - -func (p *PropertyGraphPropertiesAre) Pos() token.Pos { - return p.Properties -} - -func (p *PropertyGraphPropertiesAre) End() token.Pos { - return p.ExceptColumns.End() -} - -func (p *PropertyGraphPropertiesAre) SQL() string { - return "PROPERTIES ARE ALL COLUMNS" + sqlOpt(" EXCEPT ", p.ExceptColumns, "") -} - -func (*PropertyGraphPropertiesAre) isPropertyGraphElementProperties() {} +func (*PropertyGraphPropertiesAre) isPropertyGraphElementProperties() {} +func (*PropertyGraphDerivedPropertyList) isPropertyGraphElementProperties() {} // PropertyGraphDerivedPropertyList // @@ -2754,20 +2554,6 @@ type PropertyGraphDerivedPropertyList struct { func (*PropertyGraphDerivedPropertyList) isPropertyGraphProperties() {} -func (*PropertyGraphDerivedPropertyList) isPropertyGraphElementProperties() {} - -func (p *PropertyGraphDerivedPropertyList) Pos() token.Pos { - return p.Properties -} - -func (p *PropertyGraphDerivedPropertyList) End() token.Pos { - return p.RParen + 1 -} - -func (p *PropertyGraphDerivedPropertyList) SQL() string { - return "PROPERTIES (" + sqlJoin(p.DerivedProperties, ", ") + ")" -} - // PropertyGraphDerivedProperty // // {{.Expr | sql}}{{if not(.PropertyName | isnil)}} AS {{.PropertyName | sql}}{{end}} @@ -2779,19 +2565,6 @@ type PropertyGraphDerivedProperty struct { PropertyName *Ident //optional } -func (p *PropertyGraphDerivedProperty) Pos() token.Pos { - return p.Expr.Pos() -} - -func (p *PropertyGraphDerivedProperty) End() token.Pos { - return firstValidEnd(p.PropertyName, p.Expr) - -} - -func (p *PropertyGraphDerivedProperty) SQL() string { - return p.Expr.SQL() + sqlOpt(" AS ", p.PropertyName, "") -} - // DropPropertyGraph // // DROP PROPERTY GRAPH {{if .IfExists}}IF EXISTS{{end}} {{.PropertyGraphName | sql}} @@ -2804,23 +2577,6 @@ type DropPropertyGraph struct { Name *Ident } -func (g *DropPropertyGraph) Pos() token.Pos { - return g.Drop -} - -func (g *DropPropertyGraph) End() token.Pos { - return g.Name.End() -} - -func (g *DropPropertyGraph) SQL() string { - sql := "DROP PROPERTY GRAPH " - if g.IfExists { - sql += "IF EXISTS " - } - sql += g.Name.SQL() - return sql -} - // ================================================================================ // // DML diff --git a/ast/pos.go b/ast/pos.go index ad28dcae..985f1693 100644 --- a/ast/pos.go +++ b/ast/pos.go @@ -796,6 +796,77 @@ func (e *ExecutePrivilegeOnTableFunction) End() token.Pos { return e.Names[len(e func (r *RolePrivilege) Pos() token.Pos { return r.Role } func (r *RolePrivilege) End() token.Pos { return r.Names[len(r.Names)-1].End() } +// ================================================================================ +// +// GQL schema statements +// +// ================================================================================ + +func (c *CreatePropertyGraph) Pos() token.Pos { return c.Create } +func (c *CreatePropertyGraph) End() token.Pos { return c.Content.End() } + +func (p *PropertyGraphContent) Pos() token.Pos { return p.Node } +func (p *PropertyGraphContent) End() token.Pos { return firstValidEnd(p.EdgeTables, p.NodeTables) } + +func (p *PropertyGraphElementList) Pos() token.Pos { return p.LParen } +func (p *PropertyGraphElementList) End() token.Pos { return p.RParen + 1 } + +func (p *PropertyGraphElement) Pos() token.Pos { return p.Name.Pos() } +func (p *PropertyGraphElement) End() token.Pos { + return firstValidEnd(p.Properties, p.Keys, p.Alias, p.Name) +} + +func (p *PropertyGraphLabelAndPropertiesList) Pos() token.Pos { return firstPos(p.LabelAndProperties) } +func (p *PropertyGraphLabelAndPropertiesList) End() token.Pos { return lastEnd(p.LabelAndProperties) } + +func (p *PropertyGraphLabelAndProperties) Pos() token.Pos { return p.Label.Pos() } +func (p *PropertyGraphLabelAndProperties) End() token.Pos { + return firstValidEnd(p.Properties, p.Label) +} + +func (p *PropertyGraphElementLabelLabelName) Pos() token.Pos { return p.Label } +func (p *PropertyGraphElementLabelLabelName) End() token.Pos { return p.Name.End() } + +func (p *PropertyGraphElementLabelDefaultLabel) Pos() token.Pos { return p.Default } +func (p *PropertyGraphElementLabelDefaultLabel) End() token.Pos { return p.Label + 5 } + +func (p *PropertyGraphNodeElementKey) Pos() token.Pos { return p.PropertyGraphElementKey.Pos() } +func (p *PropertyGraphNodeElementKey) End() token.Pos { return p.PropertyGraphElementKey.End() } + +func (p *PropertyGraphEdgeElementKeys) Pos() token.Pos { return p.Element.Pos() } +func (p *PropertyGraphEdgeElementKeys) End() token.Pos { return p.Destination.End() } + +func (p *PropertyGraphElementKey) Pos() token.Pos { return p.Key } +func (p *PropertyGraphElementKey) End() token.Pos { return p.Keys.End() } + +func (p *PropertyGraphSourceKey) Pos() token.Pos { return p.Source } +func (p *PropertyGraphSourceKey) End() token.Pos { + return firstValidEnd(p.ReferenceColumns, p.ElementReference) +} + +func (p *PropertyGraphDestinationKey) Pos() token.Pos { return p.Destination } +func (p *PropertyGraphDestinationKey) End() token.Pos { + return firstValidEnd(p.ElementReference, p.ElementReference) +} + +func (p *PropertyGraphColumnNameList) Pos() token.Pos { return p.LParen } +func (p *PropertyGraphColumnNameList) End() token.Pos { return p.RParen + 1 } + +func (p *PropertyGraphNoProperties) Pos() token.Pos { return p.No } +func (p *PropertyGraphNoProperties) End() token.Pos { return p.Properties + 10 } + +func (p *PropertyGraphPropertiesAre) Pos() token.Pos { return p.Properties } +func (p *PropertyGraphPropertiesAre) End() token.Pos { return p.ExceptColumns.End() } + +func (p *PropertyGraphDerivedPropertyList) Pos() token.Pos { return p.Properties } +func (p *PropertyGraphDerivedPropertyList) End() token.Pos { return p.RParen + 1 } + +func (p *PropertyGraphDerivedProperty) Pos() token.Pos { return p.Expr.Pos() } +func (p *PropertyGraphDerivedProperty) End() token.Pos { return firstValidEnd(p.PropertyName, p.Expr) } + +func (g *DropPropertyGraph) Pos() token.Pos { return g.Drop } +func (g *DropPropertyGraph) End() token.Pos { return g.Name.End() } + // ================================================================================ // // Types for Schema diff --git a/ast/sql.go b/ast/sql.go index 8c3fdad5..86a4309a 100644 --- a/ast/sql.go +++ b/ast/sql.go @@ -1246,6 +1246,101 @@ func (r *RolePrivilege) SQL() string { return sql } +// ================================================================================ +// +// GQL schema statements +// +// ================================================================================ + +func (c *CreatePropertyGraph) SQL() string { + sql := "CREATE " + if c.OrReplace { + sql += "OR REPLACE " + } + sql += "PROPERTY GRAPH " + if c.IfNotExists { + sql += "IF NOT EXISTS " + } + sql += c.Name.SQL() + " " + c.Content.SQL() + return sql +} + +func (p *PropertyGraphContent) SQL() string { + return "NODE TABLES" + p.NodeTables.SQL() + sqlOpt(" EDGE TABLES ", p.EdgeTables, "") +} + +func (p *PropertyGraphElementList) SQL() string { + return "(" + sqlJoin(p.Elements, ", ") + ")" +} + +func (p *PropertyGraphElement) SQL() string { + return p.Name.SQL() + + sqlOpt(" AS ", p.Alias, "") + + sqlOpt(" ", p.Keys, "") + + sqlOpt(" ", p.Properties, "") +} + +func (p *PropertyGraphLabelAndPropertiesList) SQL() string { + return sqlJoin(p.LabelAndProperties, " ") +} + +func (p *PropertyGraphLabelAndProperties) SQL() string { + return p.Label.SQL() + sqlOpt(" ", p.Properties, "") +} + +func (p *PropertyGraphElementLabelLabelName) SQL() string { return "LABEL " + p.Name.SQL() } + +func (p *PropertyGraphElementLabelDefaultLabel) SQL() string { return "DEFAULT LABEL" } + +func (p *PropertyGraphNodeElementKey) SQL() string { return p.PropertyGraphElementKey.SQL() } + +func (p *PropertyGraphElementKey) SQL() string { + return "KEY " + p.Keys.SQL() +} + +func (p *PropertyGraphSourceKey) SQL() string { + return "SOURCE KEY " + p.Keys.SQL() + + " REFERENCES " + p.ElementReference.SQL() + + sqlOpt(" ", p.ReferenceColumns, "") +} + +func (p *PropertyGraphDestinationKey) SQL() string { + return "DESTINATION KEY " + p.Keys.SQL() + + " REFERENCES " + p.ElementReference.SQL() + + sqlOpt(" ", p.ReferenceColumns, "") +} + +func (p *PropertyGraphColumnNameList) SQL() string { + return "(" + sqlJoin(p.ColumnNameList, ", ") + ")" +} + +func (*PropertyGraphNoProperties) isPropertyGraphElementProperties() {} + +func (p *PropertyGraphNoProperties) SQL() string { + return "NO PROPERTIES" +} + +func (p *PropertyGraphPropertiesAre) SQL() string { + return "PROPERTIES ARE ALL COLUMNS" + sqlOpt(" EXCEPT ", p.ExceptColumns, "") +} + +func (p *PropertyGraphDerivedPropertyList) SQL() string { + return "PROPERTIES (" + sqlJoin(p.DerivedProperties, ", ") + ")" +} + +func (p *PropertyGraphDerivedProperty) SQL() string { + return p.Expr.SQL() + sqlOpt(" AS ", p.PropertyName, "") +} + +func (g *DropPropertyGraph) SQL() string { + sql := "DROP PROPERTY GRAPH " + if g.IfExists { + sql += "IF EXISTS " + } + sql += g.Name.SQL() + return sql +} + // ================================================================================ // // Types for Schema diff --git a/parser.go b/parser.go index 1bf76ba7..3e64bf69 100644 --- a/parser.go +++ b/parser.go @@ -3230,7 +3230,7 @@ func (p *Parser) tryParseTablePrivilegeColumns() ([]*ast.Ident, token.Pos) { return columns, rparen } -// CREATE PROPERTY GRAPH +// begin CREATE PROPERTY GRAPH func (p *Parser) parseCreatePropertyGraph(pos token.Pos, orReplace bool) *ast.CreatePropertyGraph { p.expectKeywordLike("PROPERTY") @@ -3256,8 +3256,7 @@ func (p *Parser) parsePropertyGraphContent() *ast.PropertyGraphContent { nodeTables := p.parsePropertyGraphElementList() var edgeTables *ast.PropertyGraphElementList - if p.Token.IsKeywordLike("EDGE") { - p.expectKeywordLike("EDGE") + if p.tryExpectKeywordLike("EDGE") != nil { p.expectKeywordLike("TABLES") edgeTables = p.parsePropertyGraphElementList() } @@ -3271,7 +3270,7 @@ func (p *Parser) parsePropertyGraphContent() *ast.PropertyGraphContent { func (p *Parser) parsePropertyGraphElementList() *ast.PropertyGraphElementList { lparen := p.expect("(").Pos - elements := parseList(p, ",", p.parsePropertyGraphElement) + elements := parseSeparatedList(p, ",", p.parsePropertyGraphElement) rparen := p.expect(")").Pos return &ast.PropertyGraphElementList{ @@ -3284,9 +3283,9 @@ func (p *Parser) parsePropertyGraphElementList() *ast.PropertyGraphElementList { func (p *Parser) parsePropertyGraphElement() *ast.PropertyGraphElement { name := p.parseIdent() - var alias *ast.AsAlias - if p.Token.Kind == "AS" { - alias = p.tryParseAsAlias() + var alias *ast.Ident + if p.tryExpect("AS") != nil { + alias = p.parseIdent() } keys := p.tryParsePropertyGraphElementKeys() @@ -3300,32 +3299,34 @@ func (p *Parser) parsePropertyGraphElement() *ast.PropertyGraphElement { } } +// parsePropertyGraphLabelAndPropertiesList parses consecutive ast.PropertyGraphLabelAndProperties, +// and returns *ast.PropertyGraphLabelAndPropertiesList. func (p *Parser) parsePropertyGraphLabelAndPropertiesList() *ast.PropertyGraphLabelAndPropertiesList { var list []*ast.PropertyGraphLabelAndProperties for { - var label ast.PropertyGraphElementLabel - if p.Token.Kind == "DEFAULT" { - defaultPos := p.expect("DEFAULT").Pos + if p.Token.Kind != "DEFAULT" && !p.Token.IsKeywordLike("LABEL") { + break + } + + var elemLabel ast.PropertyGraphElementLabel + if def := p.tryExpect("DEFAULT"); def != nil { labelPos := p.expectKeywordLike("LABEL").Pos - label = &ast.PropertyGraphElementLabelDefaultLabel{ - Default: defaultPos, + elemLabel = &ast.PropertyGraphElementLabelDefaultLabel{ + Default: def.Pos, Label: labelPos, } - } else if p.Token.IsKeywordLike("LABEL") { - labelPos := p.expectKeywordLike("LABEL").Pos + } else { + label := p.expectKeywordLike("LABEL") name := p.parseIdent() - - label = &ast.PropertyGraphElementLabelLabelName{ - Label: labelPos, + elemLabel = &ast.PropertyGraphElementLabelLabelName{ + Label: label.Pos, Name: name, } - } else { - break } properties := p.tryParsePropertyGraphElementProperties() list = append(list, &ast.PropertyGraphLabelAndProperties{ - Label: label, + Label: elemLabel, Properties: properties, }) } @@ -3341,71 +3342,58 @@ func (p *Parser) tryParsePropertyGraphElementProperties() ast.PropertyGraphEleme return p.parsePropertyGraphElementProperties() } -func (p *Parser) tryExpect(s token.TokenKind) *token.Token { - if p.Token.Kind != s { - return nil - } - return p.expect(s) -} - -func (p *Parser) tryExpectKeywordLike(s string) *token.Token { - if !p.Token.IsKeywordLike(s) { - return nil +func (p *Parser) parsePropertyGraphElementProperties() ast.PropertyGraphElementProperties { + if p.Token.Kind != "NO" && !p.Token.IsKeywordLike("PROPERTIES") { + p.panicfAtToken(&p.Token, `expect "NO" or "PROPERTIES", but %v`, p.Token.Kind) } - return p.expectKeywordLike(s) -} -func (p *Parser) parsePropertyGraphElementProperties() ast.PropertyGraphElementProperties { - switch { - case p.Token.Kind == "NO": - no := p.expect("NO").Pos + if no := p.tryExpect("NO"); no != nil { properties := p.expectKeywordLike("PROPERTIES").Pos return &ast.PropertyGraphNoProperties{ - No: no, + No: no.Pos, Properties: properties, } - case p.Token.IsKeywordLike("PROPERTIES"): - properties := p.expectKeywordLike("PROPERTIES").Pos - if p.Token.IsKeywordLike("ARE") || p.Token.Kind == "ALL" { - p.tryExpectKeywordLike("ARE") - p.expect("ALL") - columns := p.expectKeywordLike("COLUMNS").Pos - var exceptColumns *ast.PropertyGraphColumnNameList - if p.Token.Kind == "EXCEPT" { - p.expect("EXCEPT") - exceptColumns = p.parsePropertyGraphColumnNameList() - } - return &ast.PropertyGraphPropertiesAre{ - Properties: properties, - Columns: columns, - ExceptColumns: exceptColumns, - } + } + + properties := p.expectKeywordLike("PROPERTIES") + if p.Token.IsKeywordLike("ARE") || p.Token.Kind == "ALL" { + p.tryExpectKeywordLike("ARE") + p.expect("ALL") + columns := p.expectKeywordLike("COLUMNS").Pos + + var exceptColumns *ast.PropertyGraphColumnNameList + if p.tryExpect("EXCEPT") != nil { + exceptColumns = p.parsePropertyGraphColumnNameList() } - p.expect("(") - list := parseList(p, ",", func() *ast.PropertyGraphDerivedProperty { - expr := p.parseExpr() + return &ast.PropertyGraphPropertiesAre{ + Properties: properties.Pos, + Columns: columns, + ExceptColumns: exceptColumns, + } + } - var name *ast.Ident - if p.Token.Kind == "AS" { - p.expect("AS") - name = p.parseIdent() - } - return &ast.PropertyGraphDerivedProperty{ - Expr: expr, - PropertyName: name, - } - }) - rparen := p.expect(")").Pos - return &ast.PropertyGraphDerivedPropertyList{ - RParen: rparen, - Properties: properties, - DerivedProperties: list, + p.expect("(") + list := parseSeparatedList(p, ",", func() *ast.PropertyGraphDerivedProperty { + expr := p.parseExpr() + + var name *ast.Ident + if p.tryExpect("AS") != nil { + name = p.parseIdent() } - default: + + return &ast.PropertyGraphDerivedProperty{ + Expr: expr, + PropertyName: name, + } + }) + rparen := p.expect(")").Pos + + return &ast.PropertyGraphDerivedPropertyList{ + RParen: rparen, + Properties: properties.Pos, + DerivedProperties: list, } - p.panicfAtToken(&p.Token, `expect "NO" or "PROPERTIES", but %v`, p.Token.Kind) - return nil } func (p *Parser) tryParsePropertyGraphProperties() ast.PropertyGraphProperties { @@ -3420,11 +3408,10 @@ func (p *Parser) tryParsePropertyGraphElementKeys() ast.PropertyGraphElementKeys return nil } - if p.Token.IsKeywordLike("KEY") { - key := p.expectKeywordLike("KEY").Pos + if key := p.tryExpectKeywordLike("KEY"); key != nil { keyColumns := p.parsePropertyGraphColumnNameList() elementKey := &ast.PropertyGraphElementKey{ - Key: key, + Key: key.Pos, Keys: keyColumns, } return &ast.PropertyGraphNodeElementKey{ @@ -3438,21 +3425,14 @@ func (p *Parser) tryParsePropertyGraphElementKeys() ast.PropertyGraphElementKeys sourceColumns := p.parsePropertyGraphColumnNameList() p.expectKeywordLike("REFERENCES") sourceReference := p.parseIdent() - - var sourceReferenceColumns *ast.PropertyGraphColumnNameList - if p.Token.Kind == "(" { - sourceReferenceColumns = p.parsePropertyGraphColumnNameList() - } + sourceReferenceColumns := p.tryParsePropertyGraphColumnNameList() destination := p.expectKeywordLike("DESTINATION").Pos p.expectKeywordLike("KEY") destinationColumns := p.parsePropertyGraphColumnNameList() p.expectKeywordLike("REFERENCES") destinationReference := p.parseIdent() - var destinationReferenceColumns *ast.PropertyGraphColumnNameList - if p.Token.Kind == "(" { - destinationReferenceColumns = p.parsePropertyGraphColumnNameList() - } + destinationReferenceColumns := p.tryParsePropertyGraphColumnNameList() return &ast.PropertyGraphEdgeElementKeys{ // Element: elementKey, @@ -3473,7 +3453,7 @@ func (p *Parser) tryParsePropertyGraphElementKeys() ast.PropertyGraphElementKeys func (p *Parser) parsePropertyGraphColumnNameList() *ast.PropertyGraphColumnNameList { lparen := p.expect("(").Pos - list := parseList(p, ",", p.parseIdent) + list := parseSeparatedList(p, ",", p.parseIdent) rparen := p.expect(")").Pos return &ast.PropertyGraphColumnNameList{ LParen: lparen, @@ -3482,34 +3462,14 @@ func (p *Parser) parsePropertyGraphColumnNameList() *ast.PropertyGraphColumnName } } -// This function can't be a method because Go haven't yet supported gemeric methods. -func parseList[T interface { - ast.Node - comparable -}](p *Parser, sep token.TokenKind, doParse func() T) []T { - first := doParse() - var zero T - if first == zero { +func (p *Parser) tryParsePropertyGraphColumnNameList() *ast.PropertyGraphColumnNameList { + if p.Token.Kind != "(" { return nil } - list := []T{first} - - for { - if p.Token.Kind != sep { - break - } - p.nextToken() - - elem := doParse() - if elem == zero { - return list - } - list = append(list, elem) - } - return list + return p.parsePropertyGraphColumnNameList() } -// DROP PROPERTY GRAPH +// end CREATE PROPERTY GRAPH func (p *Parser) parseDropPropertyGraph(pos token.Pos) *ast.DropPropertyGraph { p.expectKeywordLike("PROPERTY") @@ -4006,6 +3966,48 @@ func (p *Parser) expectKeywordLike(s string) *token.Token { return id } +func (p *Parser) tryExpect(s token.TokenKind) *token.Token { + if p.Token.Kind != s { + return nil + } + return p.expect(s) +} + +func (p *Parser) tryExpectKeywordLike(s string) *token.Token { + if !p.Token.IsKeywordLike(s) { + return nil + } + return p.expectKeywordLike(s) +} + +// This function can't be a method because Go haven't yet supported generic methods. +func parseSeparatedList[T interface { + ast.Node + comparable +}](p *Parser, sep token.TokenKind, doParse func() T) []T { + var zero T + + first := doParse() + if first == zero { + return nil + } + + list := []T{first} + for { + if p.Token.Kind != sep { + break + } + p.nextToken() + + elem := doParse() + if elem == zero { + return list + } + list = append(list, elem) + } + return list +} + func (p *Parser) errorfAtToken(tok *token.Token, msg string, params ...interface{}) *Error { return &Error{ Message: fmt.Sprintf(msg, params...), diff --git a/testdata/result/ddl/create_or_replace_property_graph_fingraph.sql.txt b/testdata/result/ddl/create_or_replace_property_graph_fingraph.sql.txt index d328544c..7dd6b1c1 100644 --- a/testdata/result/ddl/create_or_replace_property_graph_fingraph.sql.txt +++ b/testdata/result/ddl/create_or_replace_property_graph_fingraph.sql.txt @@ -36,7 +36,7 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph NameEnd: 69, Name: "Account", }, - Alias: (*ast.AsAlias)(nil), + Alias: (*ast.Ident)(nil), Keys: nil, Properties: nil, }, @@ -46,7 +46,7 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph NameEnd: 81, Name: "Person", }, - Alias: (*ast.AsAlias)(nil), + Alias: (*ast.Ident)(nil), Keys: nil, Properties: nil, }, @@ -62,7 +62,7 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph NameEnd: 122, Name: "PersonOwnAccount", }, - Alias: (*ast.AsAlias)(nil), + Alias: (*ast.Ident)(nil), Keys: &ast.PropertyGraphEdgeElementKeys{ Element: (*ast.PropertyGraphElementKey)(nil), Source: &ast.PropertyGraphSourceKey{ @@ -148,7 +148,7 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph NameEnd: 271, Name: "AccountTransferAccount", }, - Alias: (*ast.AsAlias)(nil), + Alias: (*ast.Ident)(nil), Keys: &ast.PropertyGraphEdgeElementKeys{ Element: (*ast.PropertyGraphElementKey)(nil), Source: &ast.PropertyGraphSourceKey{ diff --git a/testdata/result/ddl/create_property_graph_if_not_exists_fingraph_verbose.sql.txt b/testdata/result/ddl/create_property_graph_if_not_exists_fingraph_verbose.sql.txt index 02a55722..27ed080d 100644 --- a/testdata/result/ddl/create_property_graph_if_not_exists_fingraph_verbose.sql.txt +++ b/testdata/result/ddl/create_property_graph_if_not_exists_fingraph_verbose.sql.txt @@ -40,13 +40,10 @@ CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph NameEnd: 72, Name: "Account", }, - Alias: &ast.AsAlias{ - As: -1, - Alias: &ast.Ident{ - NamePos: 76, - NameEnd: 83, - Name: "Account", - }, + Alias: &ast.Ident{ + NamePos: 76, + NameEnd: 83, + Name: "Account", }, Keys: nil, Properties: &ast.PropertyGraphLabelAndPropertiesList{ @@ -100,7 +97,7 @@ CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph NameEnd: 179, Name: "Person", }, - Alias: (*ast.AsAlias)(nil), + Alias: (*ast.Ident)(nil), Keys: nil, Properties: &ast.PropertyGraphLabelAndPropertiesList{ LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ @@ -134,7 +131,7 @@ CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph NameEnd: 270, Name: "PersonOwnAccount", }, - Alias: (*ast.AsAlias)(nil), + Alias: (*ast.Ident)(nil), Keys: &ast.PropertyGraphEdgeElementKeys{ Element: (*ast.PropertyGraphElementKey)(nil), Source: &ast.PropertyGraphSourceKey{ @@ -234,7 +231,7 @@ CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph NameEnd: 453, Name: "AccountTransferAccount", }, - Alias: (*ast.AsAlias)(nil), + Alias: (*ast.Ident)(nil), Keys: &ast.PropertyGraphEdgeElementKeys{ Element: (*ast.PropertyGraphElementKey)(nil), Source: &ast.PropertyGraphSourceKey{ diff --git a/testdata/result/statement/create_or_replace_property_graph_fingraph.sql.txt b/testdata/result/statement/create_or_replace_property_graph_fingraph.sql.txt index d328544c..7dd6b1c1 100644 --- a/testdata/result/statement/create_or_replace_property_graph_fingraph.sql.txt +++ b/testdata/result/statement/create_or_replace_property_graph_fingraph.sql.txt @@ -36,7 +36,7 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph NameEnd: 69, Name: "Account", }, - Alias: (*ast.AsAlias)(nil), + Alias: (*ast.Ident)(nil), Keys: nil, Properties: nil, }, @@ -46,7 +46,7 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph NameEnd: 81, Name: "Person", }, - Alias: (*ast.AsAlias)(nil), + Alias: (*ast.Ident)(nil), Keys: nil, Properties: nil, }, @@ -62,7 +62,7 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph NameEnd: 122, Name: "PersonOwnAccount", }, - Alias: (*ast.AsAlias)(nil), + Alias: (*ast.Ident)(nil), Keys: &ast.PropertyGraphEdgeElementKeys{ Element: (*ast.PropertyGraphElementKey)(nil), Source: &ast.PropertyGraphSourceKey{ @@ -148,7 +148,7 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph NameEnd: 271, Name: "AccountTransferAccount", }, - Alias: (*ast.AsAlias)(nil), + Alias: (*ast.Ident)(nil), Keys: &ast.PropertyGraphEdgeElementKeys{ Element: (*ast.PropertyGraphElementKey)(nil), Source: &ast.PropertyGraphSourceKey{ diff --git a/testdata/result/statement/create_property_graph_if_not_exists_fingraph_verbose.sql.txt b/testdata/result/statement/create_property_graph_if_not_exists_fingraph_verbose.sql.txt index 02a55722..27ed080d 100644 --- a/testdata/result/statement/create_property_graph_if_not_exists_fingraph_verbose.sql.txt +++ b/testdata/result/statement/create_property_graph_if_not_exists_fingraph_verbose.sql.txt @@ -40,13 +40,10 @@ CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph NameEnd: 72, Name: "Account", }, - Alias: &ast.AsAlias{ - As: -1, - Alias: &ast.Ident{ - NamePos: 76, - NameEnd: 83, - Name: "Account", - }, + Alias: &ast.Ident{ + NamePos: 76, + NameEnd: 83, + Name: "Account", }, Keys: nil, Properties: &ast.PropertyGraphLabelAndPropertiesList{ @@ -100,7 +97,7 @@ CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph NameEnd: 179, Name: "Person", }, - Alias: (*ast.AsAlias)(nil), + Alias: (*ast.Ident)(nil), Keys: nil, Properties: &ast.PropertyGraphLabelAndPropertiesList{ LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ @@ -134,7 +131,7 @@ CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph NameEnd: 270, Name: "PersonOwnAccount", }, - Alias: (*ast.AsAlias)(nil), + Alias: (*ast.Ident)(nil), Keys: &ast.PropertyGraphEdgeElementKeys{ Element: (*ast.PropertyGraphElementKey)(nil), Source: &ast.PropertyGraphSourceKey{ @@ -234,7 +231,7 @@ CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph NameEnd: 453, Name: "AccountTransferAccount", }, - Alias: (*ast.AsAlias)(nil), + Alias: (*ast.Ident)(nil), Keys: &ast.PropertyGraphEdgeElementKeys{ Element: (*ast.PropertyGraphElementKey)(nil), Source: &ast.PropertyGraphSourceKey{ From 81b35e538bfdfaed6a9945a6fe330c23149575dd Mon Sep 17 00:00:00 2001 From: apstndb <803393+apstndb@users.noreply.github.com> Date: Thu, 19 Sep 2024 17:23:36 +0900 Subject: [PATCH 04/13] Improve tryParsePropertyGraphElementKeys --- parser.go | 18 +- ...eplace_property_graph_fingraph_verbose.sql | 28 ++ ...property_graph_if_not_exists_fingraph.sql} | 2 +- ...y_graph_if_not_exists_fingraph_verbose.sql | 19 -- ...e_property_graph_fingraph_verbose.sql.txt} | 315 ++++++++++-------- ...erty_graph_if_not_exists_fingraph.sql.txt} | 140 ++++---- ...e_property_graph_fingraph_verbose.sql.txt} | 315 ++++++++++-------- ...erty_graph_if_not_exists_fingraph.sql.txt} | 140 ++++---- 8 files changed, 521 insertions(+), 456 deletions(-) create mode 100644 testdata/input/ddl/create_or_replace_property_graph_fingraph_verbose.sql rename testdata/input/ddl/{create_or_replace_property_graph_fingraph.sql => create_property_graph_if_not_exists_fingraph.sql} (88%) delete mode 100644 testdata/input/ddl/create_property_graph_if_not_exists_fingraph_verbose.sql rename testdata/result/{statement/create_property_graph_if_not_exists_fingraph_verbose.sql.txt => ddl/create_or_replace_property_graph_fingraph_verbose.sql.txt} (50%) rename testdata/result/{statement/create_or_replace_property_graph_fingraph.sql.txt => ddl/create_property_graph_if_not_exists_fingraph.sql.txt} (67%) rename testdata/result/{ddl/create_property_graph_if_not_exists_fingraph_verbose.sql.txt => statement/create_or_replace_property_graph_fingraph_verbose.sql.txt} (50%) rename testdata/result/{ddl/create_or_replace_property_graph_fingraph.sql.txt => statement/create_property_graph_if_not_exists_fingraph.sql.txt} (67%) diff --git a/parser.go b/parser.go index 3e64bf69..16edad38 100644 --- a/parser.go +++ b/parser.go @@ -3408,18 +3408,27 @@ func (p *Parser) tryParsePropertyGraphElementKeys() ast.PropertyGraphElementKeys return nil } + // element_key + var elementKey *ast.PropertyGraphElementKey if key := p.tryExpectKeywordLike("KEY"); key != nil { keyColumns := p.parsePropertyGraphColumnNameList() - elementKey := &ast.PropertyGraphElementKey{ + elementKey = &ast.PropertyGraphElementKey{ Key: key.Pos, Keys: keyColumns, } - return &ast.PropertyGraphNodeElementKey{ - PropertyGraphElementKey: *elementKey, + + // if SOURCE KEY doesn't follow, it is node_element_key. + if !p.Token.IsKeywordLike("SOURCE") { + return &ast.PropertyGraphNodeElementKey{ + PropertyGraphElementKey: *elementKey, + } } } + // the rest of edge_element_keys + + // source_key source := p.expectKeywordLike("SOURCE").Pos p.expectKeywordLike("KEY") sourceColumns := p.parsePropertyGraphColumnNameList() @@ -3427,6 +3436,7 @@ func (p *Parser) tryParsePropertyGraphElementKeys() ast.PropertyGraphElementKeys sourceReference := p.parseIdent() sourceReferenceColumns := p.tryParsePropertyGraphColumnNameList() + // destination_key destination := p.expectKeywordLike("DESTINATION").Pos p.expectKeywordLike("KEY") destinationColumns := p.parsePropertyGraphColumnNameList() @@ -3435,7 +3445,7 @@ func (p *Parser) tryParsePropertyGraphElementKeys() ast.PropertyGraphElementKeys destinationReferenceColumns := p.tryParsePropertyGraphColumnNameList() return &ast.PropertyGraphEdgeElementKeys{ - // Element: elementKey, + Element: elementKey, Source: &ast.PropertyGraphSourceKey{ Source: source, Keys: sourceColumns, diff --git a/testdata/input/ddl/create_or_replace_property_graph_fingraph_verbose.sql b/testdata/input/ddl/create_or_replace_property_graph_fingraph_verbose.sql new file mode 100644 index 00000000..2e97e23c --- /dev/null +++ b/testdata/input/ddl/create_or_replace_property_graph_fingraph_verbose.sql @@ -0,0 +1,28 @@ +CREATE OR REPLACE PROPERTY GRAPH FinGraph + NODE TABLES ( + Account AS Account -- element_alias + KEY (id) -- element_key in node_element_key in element_keys + -- label_and_property_list + LABEL DetailedAccount -- LABEL label_name in element_label + PROPERTIES (create_time, is_blocked, nick_name AS name) -- derived_property_list + DEFAULT LABEL -- DEFAULT LABEL in element_label + NO PROPERTIES -- NO PROPERTIES in element_properties + , + Person + -- no element_keys + -- no element_label because of direct element_properties + PROPERTIES ARE ALL COLUMNS EXCEPT (city) -- properties_are + ) + EDGE TABLES ( + PersonOwnAccount AS PersonOwnAccount + KEY (id, account_id) + SOURCE KEY (id) REFERENCES Person -- source_key without column_name_list + DESTINATION KEY (account_id) REFERENCES Account -- destination_key without column_name_list + LABEL Owns + PROPERTIES ALL COLUMNS, + AccountTransferAccount + SOURCE KEY (id) REFERENCES Account (id) -- source_key + DESTINATION KEY (to_id) REFERENCES Account (id) -- destination_key + LABEL Transfers -- LABEL label_name in element_label + -- without element_properties + ) \ No newline at end of file diff --git a/testdata/input/ddl/create_or_replace_property_graph_fingraph.sql b/testdata/input/ddl/create_property_graph_if_not_exists_fingraph.sql similarity index 88% rename from testdata/input/ddl/create_or_replace_property_graph_fingraph.sql rename to testdata/input/ddl/create_property_graph_if_not_exists_fingraph.sql index e432bf76..632af155 100644 --- a/testdata/input/ddl/create_or_replace_property_graph_fingraph.sql +++ b/testdata/input/ddl/create_property_graph_if_not_exists_fingraph.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE PROPERTY GRAPH FinGraph +CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph NODE TABLES ( Account, Person diff --git a/testdata/input/ddl/create_property_graph_if_not_exists_fingraph_verbose.sql b/testdata/input/ddl/create_property_graph_if_not_exists_fingraph_verbose.sql deleted file mode 100644 index 67d6190c..00000000 --- a/testdata/input/ddl/create_property_graph_if_not_exists_fingraph_verbose.sql +++ /dev/null @@ -1,19 +0,0 @@ -CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph - NODE TABLES ( - Account AS Account - DEFAULT LABEL - PROPERTIES (create_time, is_blocked, nick_name AS name), - Person - LABEL Person - PROPERTIES ALL COLUMNS - ) - EDGE TABLES ( - PersonOwnAccount - SOURCE KEY (id) REFERENCES Person (id) - DESTINATION KEY (account_id) REFERENCES Account (id) - LABEL Owns PROPERTIES ALL COLUMNS EXCEPT (a), - AccountTransferAccount - SOURCE KEY (id) REFERENCES Account (id) - DESTINATION KEY (to_id) REFERENCES Account (id) - LABEL Transfers NO PROPERTIES - ) \ No newline at end of file diff --git a/testdata/result/statement/create_property_graph_if_not_exists_fingraph_verbose.sql.txt b/testdata/result/ddl/create_or_replace_property_graph_fingraph_verbose.sql.txt similarity index 50% rename from testdata/result/statement/create_property_graph_if_not_exists_fingraph_verbose.sql.txt rename to testdata/result/ddl/create_or_replace_property_graph_fingraph_verbose.sql.txt index 27ed080d..b4cad616 100644 --- a/testdata/result/statement/create_property_graph_if_not_exists_fingraph_verbose.sql.txt +++ b/testdata/result/ddl/create_or_replace_property_graph_fingraph_verbose.sql.txt @@ -1,119 +1,153 @@ ---- create_property_graph_if_not_exists_fingraph_verbose.sql -CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph +--- create_or_replace_property_graph_fingraph_verbose.sql +CREATE OR REPLACE PROPERTY GRAPH FinGraph NODE TABLES ( - Account AS Account - DEFAULT LABEL - PROPERTIES (create_time, is_blocked, nick_name AS name), + Account AS Account -- element_alias + KEY (id) -- element_key in node_element_key in element_keys + -- label_and_property_list + LABEL DetailedAccount -- LABEL label_name in element_label + PROPERTIES (create_time, is_blocked, nick_name AS name) -- derived_property_list + DEFAULT LABEL -- DEFAULT LABEL in element_label + NO PROPERTIES -- NO PROPERTIES in element_properties + , Person - LABEL Person - PROPERTIES ALL COLUMNS + -- no element_keys + -- no element_label because of direct element_properties + PROPERTIES ARE ALL COLUMNS EXCEPT (city) -- properties_are ) EDGE TABLES ( - PersonOwnAccount - SOURCE KEY (id) REFERENCES Person (id) - DESTINATION KEY (account_id) REFERENCES Account (id) - LABEL Owns PROPERTIES ALL COLUMNS EXCEPT (a), + PersonOwnAccount AS PersonOwnAccount + KEY (id, account_id) + SOURCE KEY (id) REFERENCES Person -- source_key without column_name_list + DESTINATION KEY (account_id) REFERENCES Account -- destination_key without column_name_list + LABEL Owns + PROPERTIES ALL COLUMNS, AccountTransferAccount - SOURCE KEY (id) REFERENCES Account (id) - DESTINATION KEY (to_id) REFERENCES Account (id) - LABEL Transfers NO PROPERTIES + SOURCE KEY (id) REFERENCES Account (id) -- source_key + DESTINATION KEY (to_id) REFERENCES Account (id) -- destination_key + LABEL Transfers -- LABEL label_name in element_label + -- without element_properties ) --- AST &ast.CreatePropertyGraph{ Create: 0, - OrReplace: false, - IfNotExists: true, + OrReplace: true, + IfNotExists: false, Name: &ast.Ident{ - NamePos: 36, - NameEnd: 44, + NamePos: 33, + NameEnd: 41, Name: "FinGraph", }, Content: &ast.PropertyGraphContent{ - Node: 47, + Node: 44, NodeTables: &ast.PropertyGraphElementList{ - LParen: 59, - RParen: 232, + LParen: 56, + RParen: 638, Elements: []*ast.PropertyGraphElement{ &ast.PropertyGraphElement{ Name: &ast.Ident{ - NamePos: 65, - NameEnd: 72, + NamePos: 62, + NameEnd: 69, Name: "Account", }, Alias: &ast.Ident{ - NamePos: 76, - NameEnd: 83, + NamePos: 73, + NameEnd: 80, Name: "Account", }, - Keys: nil, + Keys: &ast.PropertyGraphNodeElementKey{ + PropertyGraphElementKey: ast.PropertyGraphElementKey{ + Key: 104, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 108, + RParen: 111, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 109, + NameEnd: 111, + Name: "id", + }, + }, + }, + }, + }, Properties: &ast.PropertyGraphLabelAndPropertiesList{ LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ &ast.PropertyGraphLabelAndProperties{ - Label: &ast.PropertyGraphElementLabelDefaultLabel{ - Default: 91, - Label: 99, + Label: &ast.PropertyGraphElementLabelLabelName{ + Label: 203, + Name: &ast.Ident{ + NamePos: 209, + NameEnd: 224, + Name: "DetailedAccount", + }, }, Properties: &ast.PropertyGraphDerivedPropertyList{ - Properties: 112, - RParen: 166, + Properties: 270, + RParen: 324, DerivedProperties: []*ast.PropertyGraphDerivedProperty{ &ast.PropertyGraphDerivedProperty{ Expr: &ast.Ident{ - NamePos: 124, - NameEnd: 135, + NamePos: 282, + NameEnd: 293, Name: "create_time", }, PropertyName: (*ast.Ident)(nil), }, &ast.PropertyGraphDerivedProperty{ Expr: &ast.Ident{ - NamePos: 137, - NameEnd: 147, + NamePos: 295, + NameEnd: 305, Name: "is_blocked", }, PropertyName: (*ast.Ident)(nil), }, &ast.PropertyGraphDerivedProperty{ Expr: &ast.Ident{ - NamePos: 149, - NameEnd: 158, + NamePos: 307, + NameEnd: 316, Name: "nick_name", }, PropertyName: &ast.Ident{ - NamePos: 162, - NameEnd: 166, + NamePos: 320, + NameEnd: 324, Name: "name", }, }, }, }, }, + &ast.PropertyGraphLabelAndProperties{ + Label: &ast.PropertyGraphElementLabelDefaultLabel{ + Default: 357, + Label: 365, + }, + Properties: &ast.PropertyGraphNoProperties{ + No: 413, + Properties: 416, + }, + }, }, }, }, &ast.PropertyGraphElement{ Name: &ast.Ident{ - NamePos: 173, - NameEnd: 179, + NamePos: 476, + NameEnd: 482, Name: "Person", }, Alias: (*ast.Ident)(nil), Keys: nil, - Properties: &ast.PropertyGraphLabelAndPropertiesList{ - LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ - &ast.PropertyGraphLabelAndProperties{ - Label: &ast.PropertyGraphElementLabelLabelName{ - Label: 187, - Name: &ast.Ident{ - NamePos: 193, - NameEnd: 199, - Name: "Person", - }, - }, - Properties: &ast.PropertyGraphPropertiesAre{ - Properties: 207, - Columns: 222, - ExceptColumns: (*ast.PropertyGraphColumnNameList)(nil), + Properties: &ast.PropertyGraphPropertiesAre{ + Properties: 577, + Columns: 596, + ExceptColumns: &ast.PropertyGraphColumnNameList{ + LParen: 611, + RParen: 616, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 612, + NameEnd: 616, + Name: "city", }, }, }, @@ -122,104 +156,96 @@ CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph }, }, EdgeTables: &ast.PropertyGraphElementList{ - LParen: 248, - RParen: 592, + LParen: 654, + RParen: 1207, Elements: []*ast.PropertyGraphElement{ &ast.PropertyGraphElement{ Name: &ast.Ident{ - NamePos: 254, - NameEnd: 270, + NamePos: 660, + NameEnd: 676, Name: "PersonOwnAccount", }, - Alias: (*ast.Ident)(nil), - Keys: &ast.PropertyGraphEdgeElementKeys{ - Element: (*ast.PropertyGraphElementKey)(nil), - Source: &ast.PropertyGraphSourceKey{ - Source: 277, - Keys: &ast.PropertyGraphColumnNameList{ - LParen: 288, - RParen: 291, + Alias: &ast.Ident{ + NamePos: 680, + NameEnd: 696, + Name: "PersonOwnAccount", + }, + Keys: &ast.PropertyGraphEdgeElementKeys{ + Element: &ast.PropertyGraphElementKey{ + Key: 703, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 707, + RParen: 722, ColumnNameList: []*ast.Ident{ &ast.Ident{ - NamePos: 289, - NameEnd: 291, + NamePos: 708, + NameEnd: 710, Name: "id", }, + &ast.Ident{ + NamePos: 712, + NameEnd: 722, + Name: "account_id", + }, }, }, - ElementReference: &ast.Ident{ - NamePos: 304, - NameEnd: 310, - Name: "Person", - }, - ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 311, - RParen: 314, + }, + Source: &ast.PropertyGraphSourceKey{ + Source: 730, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 741, + RParen: 744, ColumnNameList: []*ast.Ident{ &ast.Ident{ - NamePos: 312, - NameEnd: 314, + NamePos: 742, + NameEnd: 744, Name: "id", }, }, }, + ElementReference: &ast.Ident{ + NamePos: 757, + NameEnd: 763, + Name: "Person", + }, + ReferenceColumns: (*ast.PropertyGraphColumnNameList)(nil), }, Destination: &ast.PropertyGraphDestinationKey{ - Destination: 322, + Destination: 809, Keys: &ast.PropertyGraphColumnNameList{ - LParen: 338, - RParen: 349, + LParen: 825, + RParen: 836, ColumnNameList: []*ast.Ident{ &ast.Ident{ - NamePos: 339, - NameEnd: 349, + NamePos: 826, + NameEnd: 836, Name: "account_id", }, }, }, ElementReference: &ast.Ident{ - NamePos: 362, - NameEnd: 369, + NamePos: 849, + NameEnd: 856, Name: "Account", }, - ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 370, - RParen: 373, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 371, - NameEnd: 373, - Name: "id", - }, - }, - }, + ReferenceColumns: (*ast.PropertyGraphColumnNameList)(nil), }, }, Properties: &ast.PropertyGraphLabelAndPropertiesList{ LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ &ast.PropertyGraphLabelAndProperties{ Label: &ast.PropertyGraphElementLabelLabelName{ - Label: 381, + Label: 907, Name: &ast.Ident{ - NamePos: 387, - NameEnd: 391, + NamePos: 913, + NameEnd: 917, Name: "Owns", }, }, Properties: &ast.PropertyGraphPropertiesAre{ - Properties: 392, - Columns: 407, - ExceptColumns: &ast.PropertyGraphColumnNameList{ - LParen: 422, - RParen: 424, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 423, - NameEnd: 424, - Name: "a", - }, - }, - }, + Properties: 926, + Columns: 941, + ExceptColumns: (*ast.PropertyGraphColumnNameList)(nil), }, }, }, @@ -227,68 +253,68 @@ CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph }, &ast.PropertyGraphElement{ Name: &ast.Ident{ - NamePos: 431, - NameEnd: 453, + NamePos: 954, + NameEnd: 976, Name: "AccountTransferAccount", }, Alias: (*ast.Ident)(nil), Keys: &ast.PropertyGraphEdgeElementKeys{ Element: (*ast.PropertyGraphElementKey)(nil), Source: &ast.PropertyGraphSourceKey{ - Source: 460, + Source: 983, Keys: &ast.PropertyGraphColumnNameList{ - LParen: 471, - RParen: 474, + LParen: 994, + RParen: 997, ColumnNameList: []*ast.Ident{ &ast.Ident{ - NamePos: 472, - NameEnd: 474, + NamePos: 995, + NameEnd: 997, Name: "id", }, }, }, ElementReference: &ast.Ident{ - NamePos: 487, - NameEnd: 494, + NamePos: 1010, + NameEnd: 1017, Name: "Account", }, ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 495, - RParen: 498, + LParen: 1018, + RParen: 1021, ColumnNameList: []*ast.Ident{ &ast.Ident{ - NamePos: 496, - NameEnd: 498, + NamePos: 1019, + NameEnd: 1021, Name: "id", }, }, }, }, Destination: &ast.PropertyGraphDestinationKey{ - Destination: 506, + Destination: 1043, Keys: &ast.PropertyGraphColumnNameList{ - LParen: 522, - RParen: 528, + LParen: 1059, + RParen: 1065, ColumnNameList: []*ast.Ident{ &ast.Ident{ - NamePos: 523, - NameEnd: 528, + NamePos: 1060, + NameEnd: 1065, Name: "to_id", }, }, }, ElementReference: &ast.Ident{ - NamePos: 541, - NameEnd: 548, + NamePos: 1078, + NameEnd: 1085, Name: "Account", }, ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 549, - RParen: 552, + LParen: 1086, + RParen: 1089, ColumnNameList: []*ast.Ident{ &ast.Ident{ - NamePos: 550, - NameEnd: 552, + NamePos: 1087, + NameEnd: 1089, Name: "id", }, }, @@ -299,17 +325,14 @@ CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ &ast.PropertyGraphLabelAndProperties{ Label: &ast.PropertyGraphElementLabelLabelName{ - Label: 560, + Label: 1116, Name: &ast.Ident{ - NamePos: 566, - NameEnd: 575, + NamePos: 1122, + NameEnd: 1131, Name: "Transfers", }, }, - Properties: &ast.PropertyGraphNoProperties{ - No: 576, - Properties: 579, - }, + Properties: nil, }, }, }, @@ -320,4 +343,4 @@ CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph } --- SQL -CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph NODE TABLES(Account AS Account DEFAULT LABEL PROPERTIES (create_time, is_blocked, nick_name AS name), Person LABEL Person PROPERTIES ARE ALL COLUMNS) EDGE TABLES (PersonOwnAccount SOURCE KEY (id) REFERENCES Person (id) DESTINATION KEY (account_id) REFERENCES Account (id) LABEL Owns PROPERTIES ARE ALL COLUMNS EXCEPT (a), AccountTransferAccount SOURCE KEY (id) REFERENCES Account (id) DESTINATION KEY (to_id) REFERENCES Account (id) LABEL Transfers NO PROPERTIES) +CREATE OR REPLACE PROPERTY GRAPH FinGraph NODE TABLES(Account AS Account KEY (id) LABEL DetailedAccount PROPERTIES (create_time, is_blocked, nick_name AS name) DEFAULT LABEL NO PROPERTIES, Person PROPERTIES ARE ALL COLUMNS EXCEPT (city)) EDGE TABLES (PersonOwnAccount AS PersonOwnAccount KEY (id, account_id) SOURCE KEY (id) REFERENCES Person DESTINATION KEY (account_id) REFERENCES Account LABEL Owns PROPERTIES ARE ALL COLUMNS, AccountTransferAccount SOURCE KEY (id) REFERENCES Account (id) DESTINATION KEY (to_id) REFERENCES Account (id) LABEL Transfers) diff --git a/testdata/result/statement/create_or_replace_property_graph_fingraph.sql.txt b/testdata/result/ddl/create_property_graph_if_not_exists_fingraph.sql.txt similarity index 67% rename from testdata/result/statement/create_or_replace_property_graph_fingraph.sql.txt rename to testdata/result/ddl/create_property_graph_if_not_exists_fingraph.sql.txt index 7dd6b1c1..06ceb355 100644 --- a/testdata/result/statement/create_or_replace_property_graph_fingraph.sql.txt +++ b/testdata/result/ddl/create_property_graph_if_not_exists_fingraph.sql.txt @@ -1,5 +1,5 @@ ---- create_or_replace_property_graph_fingraph.sql -CREATE OR REPLACE PROPERTY GRAPH FinGraph +--- create_property_graph_if_not_exists_fingraph.sql +CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph NODE TABLES ( Account, Person @@ -17,23 +17,23 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph --- AST &ast.CreatePropertyGraph{ Create: 0, - OrReplace: true, - IfNotExists: false, + OrReplace: false, + IfNotExists: true, Name: &ast.Ident{ - NamePos: 33, - NameEnd: 41, + NamePos: 36, + NameEnd: 44, Name: "FinGraph", }, Content: &ast.PropertyGraphContent{ - Node: 44, + Node: 47, NodeTables: &ast.PropertyGraphElementList{ - LParen: 56, - RParen: 84, + LParen: 59, + RParen: 87, Elements: []*ast.PropertyGraphElement{ &ast.PropertyGraphElement{ Name: &ast.Ident{ - NamePos: 62, - NameEnd: 69, + NamePos: 65, + NameEnd: 72, Name: "Account", }, Alias: (*ast.Ident)(nil), @@ -42,8 +42,8 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph }, &ast.PropertyGraphElement{ Name: &ast.Ident{ - NamePos: 75, - NameEnd: 81, + NamePos: 78, + NameEnd: 84, Name: "Person", }, Alias: (*ast.Ident)(nil), @@ -53,73 +53,73 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph }, }, EdgeTables: &ast.PropertyGraphElementList{ - LParen: 100, - RParen: 396, + LParen: 103, + RParen: 399, Elements: []*ast.PropertyGraphElement{ &ast.PropertyGraphElement{ Name: &ast.Ident{ - NamePos: 106, - NameEnd: 122, + NamePos: 109, + NameEnd: 125, Name: "PersonOwnAccount", }, Alias: (*ast.Ident)(nil), Keys: &ast.PropertyGraphEdgeElementKeys{ Element: (*ast.PropertyGraphElementKey)(nil), Source: &ast.PropertyGraphSourceKey{ - Source: 129, + Source: 132, Keys: &ast.PropertyGraphColumnNameList{ - LParen: 140, - RParen: 143, + LParen: 143, + RParen: 146, ColumnNameList: []*ast.Ident{ &ast.Ident{ - NamePos: 141, - NameEnd: 143, + NamePos: 144, + NameEnd: 146, Name: "id", }, }, }, ElementReference: &ast.Ident{ - NamePos: 156, - NameEnd: 162, + NamePos: 159, + NameEnd: 165, Name: "Person", }, ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 163, - RParen: 166, + LParen: 166, + RParen: 169, ColumnNameList: []*ast.Ident{ &ast.Ident{ - NamePos: 164, - NameEnd: 166, + NamePos: 167, + NameEnd: 169, Name: "id", }, }, }, }, Destination: &ast.PropertyGraphDestinationKey{ - Destination: 174, + Destination: 177, Keys: &ast.PropertyGraphColumnNameList{ - LParen: 190, - RParen: 201, + LParen: 193, + RParen: 204, ColumnNameList: []*ast.Ident{ &ast.Ident{ - NamePos: 191, - NameEnd: 201, + NamePos: 194, + NameEnd: 204, Name: "account_id", }, }, }, ElementReference: &ast.Ident{ - NamePos: 214, - NameEnd: 221, + NamePos: 217, + NameEnd: 224, Name: "Account", }, ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 222, - RParen: 225, + LParen: 225, + RParen: 228, ColumnNameList: []*ast.Ident{ &ast.Ident{ - NamePos: 223, - NameEnd: 225, + NamePos: 226, + NameEnd: 228, Name: "id", }, }, @@ -130,10 +130,10 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ &ast.PropertyGraphLabelAndProperties{ Label: &ast.PropertyGraphElementLabelLabelName{ - Label: 233, + Label: 236, Name: &ast.Ident{ - NamePos: 239, - NameEnd: 243, + NamePos: 242, + NameEnd: 246, Name: "Owns", }, }, @@ -144,68 +144,68 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph }, &ast.PropertyGraphElement{ Name: &ast.Ident{ - NamePos: 249, - NameEnd: 271, + NamePos: 252, + NameEnd: 274, Name: "AccountTransferAccount", }, Alias: (*ast.Ident)(nil), Keys: &ast.PropertyGraphEdgeElementKeys{ Element: (*ast.PropertyGraphElementKey)(nil), Source: &ast.PropertyGraphSourceKey{ - Source: 278, + Source: 281, Keys: &ast.PropertyGraphColumnNameList{ - LParen: 289, - RParen: 292, + LParen: 292, + RParen: 295, ColumnNameList: []*ast.Ident{ &ast.Ident{ - NamePos: 290, - NameEnd: 292, + NamePos: 293, + NameEnd: 295, Name: "id", }, }, }, ElementReference: &ast.Ident{ - NamePos: 305, - NameEnd: 312, + NamePos: 308, + NameEnd: 315, Name: "Account", }, ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 313, - RParen: 316, + LParen: 316, + RParen: 319, ColumnNameList: []*ast.Ident{ &ast.Ident{ - NamePos: 314, - NameEnd: 316, + NamePos: 317, + NameEnd: 319, Name: "id", }, }, }, }, Destination: &ast.PropertyGraphDestinationKey{ - Destination: 324, + Destination: 327, Keys: &ast.PropertyGraphColumnNameList{ - LParen: 340, - RParen: 346, + LParen: 343, + RParen: 349, ColumnNameList: []*ast.Ident{ &ast.Ident{ - NamePos: 341, - NameEnd: 346, + NamePos: 344, + NameEnd: 349, Name: "to_id", }, }, }, ElementReference: &ast.Ident{ - NamePos: 359, - NameEnd: 366, + NamePos: 362, + NameEnd: 369, Name: "Account", }, ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 367, - RParen: 370, + LParen: 370, + RParen: 373, ColumnNameList: []*ast.Ident{ &ast.Ident{ - NamePos: 368, - NameEnd: 370, + NamePos: 371, + NameEnd: 373, Name: "id", }, }, @@ -216,10 +216,10 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ &ast.PropertyGraphLabelAndProperties{ Label: &ast.PropertyGraphElementLabelLabelName{ - Label: 378, + Label: 381, Name: &ast.Ident{ - NamePos: 384, - NameEnd: 393, + NamePos: 387, + NameEnd: 396, Name: "Transfers", }, }, @@ -234,4 +234,4 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph } --- SQL -CREATE OR REPLACE PROPERTY GRAPH FinGraph NODE TABLES(Account, Person) EDGE TABLES (PersonOwnAccount SOURCE KEY (id) REFERENCES Person (id) DESTINATION KEY (account_id) REFERENCES Account (id) LABEL Owns, AccountTransferAccount SOURCE KEY (id) REFERENCES Account (id) DESTINATION KEY (to_id) REFERENCES Account (id) LABEL Transfers) +CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph NODE TABLES(Account, Person) EDGE TABLES (PersonOwnAccount SOURCE KEY (id) REFERENCES Person (id) DESTINATION KEY (account_id) REFERENCES Account (id) LABEL Owns, AccountTransferAccount SOURCE KEY (id) REFERENCES Account (id) DESTINATION KEY (to_id) REFERENCES Account (id) LABEL Transfers) diff --git a/testdata/result/ddl/create_property_graph_if_not_exists_fingraph_verbose.sql.txt b/testdata/result/statement/create_or_replace_property_graph_fingraph_verbose.sql.txt similarity index 50% rename from testdata/result/ddl/create_property_graph_if_not_exists_fingraph_verbose.sql.txt rename to testdata/result/statement/create_or_replace_property_graph_fingraph_verbose.sql.txt index 27ed080d..b4cad616 100644 --- a/testdata/result/ddl/create_property_graph_if_not_exists_fingraph_verbose.sql.txt +++ b/testdata/result/statement/create_or_replace_property_graph_fingraph_verbose.sql.txt @@ -1,119 +1,153 @@ ---- create_property_graph_if_not_exists_fingraph_verbose.sql -CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph +--- create_or_replace_property_graph_fingraph_verbose.sql +CREATE OR REPLACE PROPERTY GRAPH FinGraph NODE TABLES ( - Account AS Account - DEFAULT LABEL - PROPERTIES (create_time, is_blocked, nick_name AS name), + Account AS Account -- element_alias + KEY (id) -- element_key in node_element_key in element_keys + -- label_and_property_list + LABEL DetailedAccount -- LABEL label_name in element_label + PROPERTIES (create_time, is_blocked, nick_name AS name) -- derived_property_list + DEFAULT LABEL -- DEFAULT LABEL in element_label + NO PROPERTIES -- NO PROPERTIES in element_properties + , Person - LABEL Person - PROPERTIES ALL COLUMNS + -- no element_keys + -- no element_label because of direct element_properties + PROPERTIES ARE ALL COLUMNS EXCEPT (city) -- properties_are ) EDGE TABLES ( - PersonOwnAccount - SOURCE KEY (id) REFERENCES Person (id) - DESTINATION KEY (account_id) REFERENCES Account (id) - LABEL Owns PROPERTIES ALL COLUMNS EXCEPT (a), + PersonOwnAccount AS PersonOwnAccount + KEY (id, account_id) + SOURCE KEY (id) REFERENCES Person -- source_key without column_name_list + DESTINATION KEY (account_id) REFERENCES Account -- destination_key without column_name_list + LABEL Owns + PROPERTIES ALL COLUMNS, AccountTransferAccount - SOURCE KEY (id) REFERENCES Account (id) - DESTINATION KEY (to_id) REFERENCES Account (id) - LABEL Transfers NO PROPERTIES + SOURCE KEY (id) REFERENCES Account (id) -- source_key + DESTINATION KEY (to_id) REFERENCES Account (id) -- destination_key + LABEL Transfers -- LABEL label_name in element_label + -- without element_properties ) --- AST &ast.CreatePropertyGraph{ Create: 0, - OrReplace: false, - IfNotExists: true, + OrReplace: true, + IfNotExists: false, Name: &ast.Ident{ - NamePos: 36, - NameEnd: 44, + NamePos: 33, + NameEnd: 41, Name: "FinGraph", }, Content: &ast.PropertyGraphContent{ - Node: 47, + Node: 44, NodeTables: &ast.PropertyGraphElementList{ - LParen: 59, - RParen: 232, + LParen: 56, + RParen: 638, Elements: []*ast.PropertyGraphElement{ &ast.PropertyGraphElement{ Name: &ast.Ident{ - NamePos: 65, - NameEnd: 72, + NamePos: 62, + NameEnd: 69, Name: "Account", }, Alias: &ast.Ident{ - NamePos: 76, - NameEnd: 83, + NamePos: 73, + NameEnd: 80, Name: "Account", }, - Keys: nil, + Keys: &ast.PropertyGraphNodeElementKey{ + PropertyGraphElementKey: ast.PropertyGraphElementKey{ + Key: 104, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 108, + RParen: 111, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 109, + NameEnd: 111, + Name: "id", + }, + }, + }, + }, + }, Properties: &ast.PropertyGraphLabelAndPropertiesList{ LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ &ast.PropertyGraphLabelAndProperties{ - Label: &ast.PropertyGraphElementLabelDefaultLabel{ - Default: 91, - Label: 99, + Label: &ast.PropertyGraphElementLabelLabelName{ + Label: 203, + Name: &ast.Ident{ + NamePos: 209, + NameEnd: 224, + Name: "DetailedAccount", + }, }, Properties: &ast.PropertyGraphDerivedPropertyList{ - Properties: 112, - RParen: 166, + Properties: 270, + RParen: 324, DerivedProperties: []*ast.PropertyGraphDerivedProperty{ &ast.PropertyGraphDerivedProperty{ Expr: &ast.Ident{ - NamePos: 124, - NameEnd: 135, + NamePos: 282, + NameEnd: 293, Name: "create_time", }, PropertyName: (*ast.Ident)(nil), }, &ast.PropertyGraphDerivedProperty{ Expr: &ast.Ident{ - NamePos: 137, - NameEnd: 147, + NamePos: 295, + NameEnd: 305, Name: "is_blocked", }, PropertyName: (*ast.Ident)(nil), }, &ast.PropertyGraphDerivedProperty{ Expr: &ast.Ident{ - NamePos: 149, - NameEnd: 158, + NamePos: 307, + NameEnd: 316, Name: "nick_name", }, PropertyName: &ast.Ident{ - NamePos: 162, - NameEnd: 166, + NamePos: 320, + NameEnd: 324, Name: "name", }, }, }, }, }, + &ast.PropertyGraphLabelAndProperties{ + Label: &ast.PropertyGraphElementLabelDefaultLabel{ + Default: 357, + Label: 365, + }, + Properties: &ast.PropertyGraphNoProperties{ + No: 413, + Properties: 416, + }, + }, }, }, }, &ast.PropertyGraphElement{ Name: &ast.Ident{ - NamePos: 173, - NameEnd: 179, + NamePos: 476, + NameEnd: 482, Name: "Person", }, Alias: (*ast.Ident)(nil), Keys: nil, - Properties: &ast.PropertyGraphLabelAndPropertiesList{ - LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ - &ast.PropertyGraphLabelAndProperties{ - Label: &ast.PropertyGraphElementLabelLabelName{ - Label: 187, - Name: &ast.Ident{ - NamePos: 193, - NameEnd: 199, - Name: "Person", - }, - }, - Properties: &ast.PropertyGraphPropertiesAre{ - Properties: 207, - Columns: 222, - ExceptColumns: (*ast.PropertyGraphColumnNameList)(nil), + Properties: &ast.PropertyGraphPropertiesAre{ + Properties: 577, + Columns: 596, + ExceptColumns: &ast.PropertyGraphColumnNameList{ + LParen: 611, + RParen: 616, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 612, + NameEnd: 616, + Name: "city", }, }, }, @@ -122,104 +156,96 @@ CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph }, }, EdgeTables: &ast.PropertyGraphElementList{ - LParen: 248, - RParen: 592, + LParen: 654, + RParen: 1207, Elements: []*ast.PropertyGraphElement{ &ast.PropertyGraphElement{ Name: &ast.Ident{ - NamePos: 254, - NameEnd: 270, + NamePos: 660, + NameEnd: 676, Name: "PersonOwnAccount", }, - Alias: (*ast.Ident)(nil), - Keys: &ast.PropertyGraphEdgeElementKeys{ - Element: (*ast.PropertyGraphElementKey)(nil), - Source: &ast.PropertyGraphSourceKey{ - Source: 277, - Keys: &ast.PropertyGraphColumnNameList{ - LParen: 288, - RParen: 291, + Alias: &ast.Ident{ + NamePos: 680, + NameEnd: 696, + Name: "PersonOwnAccount", + }, + Keys: &ast.PropertyGraphEdgeElementKeys{ + Element: &ast.PropertyGraphElementKey{ + Key: 703, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 707, + RParen: 722, ColumnNameList: []*ast.Ident{ &ast.Ident{ - NamePos: 289, - NameEnd: 291, + NamePos: 708, + NameEnd: 710, Name: "id", }, + &ast.Ident{ + NamePos: 712, + NameEnd: 722, + Name: "account_id", + }, }, }, - ElementReference: &ast.Ident{ - NamePos: 304, - NameEnd: 310, - Name: "Person", - }, - ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 311, - RParen: 314, + }, + Source: &ast.PropertyGraphSourceKey{ + Source: 730, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 741, + RParen: 744, ColumnNameList: []*ast.Ident{ &ast.Ident{ - NamePos: 312, - NameEnd: 314, + NamePos: 742, + NameEnd: 744, Name: "id", }, }, }, + ElementReference: &ast.Ident{ + NamePos: 757, + NameEnd: 763, + Name: "Person", + }, + ReferenceColumns: (*ast.PropertyGraphColumnNameList)(nil), }, Destination: &ast.PropertyGraphDestinationKey{ - Destination: 322, + Destination: 809, Keys: &ast.PropertyGraphColumnNameList{ - LParen: 338, - RParen: 349, + LParen: 825, + RParen: 836, ColumnNameList: []*ast.Ident{ &ast.Ident{ - NamePos: 339, - NameEnd: 349, + NamePos: 826, + NameEnd: 836, Name: "account_id", }, }, }, ElementReference: &ast.Ident{ - NamePos: 362, - NameEnd: 369, + NamePos: 849, + NameEnd: 856, Name: "Account", }, - ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 370, - RParen: 373, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 371, - NameEnd: 373, - Name: "id", - }, - }, - }, + ReferenceColumns: (*ast.PropertyGraphColumnNameList)(nil), }, }, Properties: &ast.PropertyGraphLabelAndPropertiesList{ LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ &ast.PropertyGraphLabelAndProperties{ Label: &ast.PropertyGraphElementLabelLabelName{ - Label: 381, + Label: 907, Name: &ast.Ident{ - NamePos: 387, - NameEnd: 391, + NamePos: 913, + NameEnd: 917, Name: "Owns", }, }, Properties: &ast.PropertyGraphPropertiesAre{ - Properties: 392, - Columns: 407, - ExceptColumns: &ast.PropertyGraphColumnNameList{ - LParen: 422, - RParen: 424, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 423, - NameEnd: 424, - Name: "a", - }, - }, - }, + Properties: 926, + Columns: 941, + ExceptColumns: (*ast.PropertyGraphColumnNameList)(nil), }, }, }, @@ -227,68 +253,68 @@ CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph }, &ast.PropertyGraphElement{ Name: &ast.Ident{ - NamePos: 431, - NameEnd: 453, + NamePos: 954, + NameEnd: 976, Name: "AccountTransferAccount", }, Alias: (*ast.Ident)(nil), Keys: &ast.PropertyGraphEdgeElementKeys{ Element: (*ast.PropertyGraphElementKey)(nil), Source: &ast.PropertyGraphSourceKey{ - Source: 460, + Source: 983, Keys: &ast.PropertyGraphColumnNameList{ - LParen: 471, - RParen: 474, + LParen: 994, + RParen: 997, ColumnNameList: []*ast.Ident{ &ast.Ident{ - NamePos: 472, - NameEnd: 474, + NamePos: 995, + NameEnd: 997, Name: "id", }, }, }, ElementReference: &ast.Ident{ - NamePos: 487, - NameEnd: 494, + NamePos: 1010, + NameEnd: 1017, Name: "Account", }, ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 495, - RParen: 498, + LParen: 1018, + RParen: 1021, ColumnNameList: []*ast.Ident{ &ast.Ident{ - NamePos: 496, - NameEnd: 498, + NamePos: 1019, + NameEnd: 1021, Name: "id", }, }, }, }, Destination: &ast.PropertyGraphDestinationKey{ - Destination: 506, + Destination: 1043, Keys: &ast.PropertyGraphColumnNameList{ - LParen: 522, - RParen: 528, + LParen: 1059, + RParen: 1065, ColumnNameList: []*ast.Ident{ &ast.Ident{ - NamePos: 523, - NameEnd: 528, + NamePos: 1060, + NameEnd: 1065, Name: "to_id", }, }, }, ElementReference: &ast.Ident{ - NamePos: 541, - NameEnd: 548, + NamePos: 1078, + NameEnd: 1085, Name: "Account", }, ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 549, - RParen: 552, + LParen: 1086, + RParen: 1089, ColumnNameList: []*ast.Ident{ &ast.Ident{ - NamePos: 550, - NameEnd: 552, + NamePos: 1087, + NameEnd: 1089, Name: "id", }, }, @@ -299,17 +325,14 @@ CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ &ast.PropertyGraphLabelAndProperties{ Label: &ast.PropertyGraphElementLabelLabelName{ - Label: 560, + Label: 1116, Name: &ast.Ident{ - NamePos: 566, - NameEnd: 575, + NamePos: 1122, + NameEnd: 1131, Name: "Transfers", }, }, - Properties: &ast.PropertyGraphNoProperties{ - No: 576, - Properties: 579, - }, + Properties: nil, }, }, }, @@ -320,4 +343,4 @@ CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph } --- SQL -CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph NODE TABLES(Account AS Account DEFAULT LABEL PROPERTIES (create_time, is_blocked, nick_name AS name), Person LABEL Person PROPERTIES ARE ALL COLUMNS) EDGE TABLES (PersonOwnAccount SOURCE KEY (id) REFERENCES Person (id) DESTINATION KEY (account_id) REFERENCES Account (id) LABEL Owns PROPERTIES ARE ALL COLUMNS EXCEPT (a), AccountTransferAccount SOURCE KEY (id) REFERENCES Account (id) DESTINATION KEY (to_id) REFERENCES Account (id) LABEL Transfers NO PROPERTIES) +CREATE OR REPLACE PROPERTY GRAPH FinGraph NODE TABLES(Account AS Account KEY (id) LABEL DetailedAccount PROPERTIES (create_time, is_blocked, nick_name AS name) DEFAULT LABEL NO PROPERTIES, Person PROPERTIES ARE ALL COLUMNS EXCEPT (city)) EDGE TABLES (PersonOwnAccount AS PersonOwnAccount KEY (id, account_id) SOURCE KEY (id) REFERENCES Person DESTINATION KEY (account_id) REFERENCES Account LABEL Owns PROPERTIES ARE ALL COLUMNS, AccountTransferAccount SOURCE KEY (id) REFERENCES Account (id) DESTINATION KEY (to_id) REFERENCES Account (id) LABEL Transfers) diff --git a/testdata/result/ddl/create_or_replace_property_graph_fingraph.sql.txt b/testdata/result/statement/create_property_graph_if_not_exists_fingraph.sql.txt similarity index 67% rename from testdata/result/ddl/create_or_replace_property_graph_fingraph.sql.txt rename to testdata/result/statement/create_property_graph_if_not_exists_fingraph.sql.txt index 7dd6b1c1..06ceb355 100644 --- a/testdata/result/ddl/create_or_replace_property_graph_fingraph.sql.txt +++ b/testdata/result/statement/create_property_graph_if_not_exists_fingraph.sql.txt @@ -1,5 +1,5 @@ ---- create_or_replace_property_graph_fingraph.sql -CREATE OR REPLACE PROPERTY GRAPH FinGraph +--- create_property_graph_if_not_exists_fingraph.sql +CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph NODE TABLES ( Account, Person @@ -17,23 +17,23 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph --- AST &ast.CreatePropertyGraph{ Create: 0, - OrReplace: true, - IfNotExists: false, + OrReplace: false, + IfNotExists: true, Name: &ast.Ident{ - NamePos: 33, - NameEnd: 41, + NamePos: 36, + NameEnd: 44, Name: "FinGraph", }, Content: &ast.PropertyGraphContent{ - Node: 44, + Node: 47, NodeTables: &ast.PropertyGraphElementList{ - LParen: 56, - RParen: 84, + LParen: 59, + RParen: 87, Elements: []*ast.PropertyGraphElement{ &ast.PropertyGraphElement{ Name: &ast.Ident{ - NamePos: 62, - NameEnd: 69, + NamePos: 65, + NameEnd: 72, Name: "Account", }, Alias: (*ast.Ident)(nil), @@ -42,8 +42,8 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph }, &ast.PropertyGraphElement{ Name: &ast.Ident{ - NamePos: 75, - NameEnd: 81, + NamePos: 78, + NameEnd: 84, Name: "Person", }, Alias: (*ast.Ident)(nil), @@ -53,73 +53,73 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph }, }, EdgeTables: &ast.PropertyGraphElementList{ - LParen: 100, - RParen: 396, + LParen: 103, + RParen: 399, Elements: []*ast.PropertyGraphElement{ &ast.PropertyGraphElement{ Name: &ast.Ident{ - NamePos: 106, - NameEnd: 122, + NamePos: 109, + NameEnd: 125, Name: "PersonOwnAccount", }, Alias: (*ast.Ident)(nil), Keys: &ast.PropertyGraphEdgeElementKeys{ Element: (*ast.PropertyGraphElementKey)(nil), Source: &ast.PropertyGraphSourceKey{ - Source: 129, + Source: 132, Keys: &ast.PropertyGraphColumnNameList{ - LParen: 140, - RParen: 143, + LParen: 143, + RParen: 146, ColumnNameList: []*ast.Ident{ &ast.Ident{ - NamePos: 141, - NameEnd: 143, + NamePos: 144, + NameEnd: 146, Name: "id", }, }, }, ElementReference: &ast.Ident{ - NamePos: 156, - NameEnd: 162, + NamePos: 159, + NameEnd: 165, Name: "Person", }, ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 163, - RParen: 166, + LParen: 166, + RParen: 169, ColumnNameList: []*ast.Ident{ &ast.Ident{ - NamePos: 164, - NameEnd: 166, + NamePos: 167, + NameEnd: 169, Name: "id", }, }, }, }, Destination: &ast.PropertyGraphDestinationKey{ - Destination: 174, + Destination: 177, Keys: &ast.PropertyGraphColumnNameList{ - LParen: 190, - RParen: 201, + LParen: 193, + RParen: 204, ColumnNameList: []*ast.Ident{ &ast.Ident{ - NamePos: 191, - NameEnd: 201, + NamePos: 194, + NameEnd: 204, Name: "account_id", }, }, }, ElementReference: &ast.Ident{ - NamePos: 214, - NameEnd: 221, + NamePos: 217, + NameEnd: 224, Name: "Account", }, ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 222, - RParen: 225, + LParen: 225, + RParen: 228, ColumnNameList: []*ast.Ident{ &ast.Ident{ - NamePos: 223, - NameEnd: 225, + NamePos: 226, + NameEnd: 228, Name: "id", }, }, @@ -130,10 +130,10 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ &ast.PropertyGraphLabelAndProperties{ Label: &ast.PropertyGraphElementLabelLabelName{ - Label: 233, + Label: 236, Name: &ast.Ident{ - NamePos: 239, - NameEnd: 243, + NamePos: 242, + NameEnd: 246, Name: "Owns", }, }, @@ -144,68 +144,68 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph }, &ast.PropertyGraphElement{ Name: &ast.Ident{ - NamePos: 249, - NameEnd: 271, + NamePos: 252, + NameEnd: 274, Name: "AccountTransferAccount", }, Alias: (*ast.Ident)(nil), Keys: &ast.PropertyGraphEdgeElementKeys{ Element: (*ast.PropertyGraphElementKey)(nil), Source: &ast.PropertyGraphSourceKey{ - Source: 278, + Source: 281, Keys: &ast.PropertyGraphColumnNameList{ - LParen: 289, - RParen: 292, + LParen: 292, + RParen: 295, ColumnNameList: []*ast.Ident{ &ast.Ident{ - NamePos: 290, - NameEnd: 292, + NamePos: 293, + NameEnd: 295, Name: "id", }, }, }, ElementReference: &ast.Ident{ - NamePos: 305, - NameEnd: 312, + NamePos: 308, + NameEnd: 315, Name: "Account", }, ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 313, - RParen: 316, + LParen: 316, + RParen: 319, ColumnNameList: []*ast.Ident{ &ast.Ident{ - NamePos: 314, - NameEnd: 316, + NamePos: 317, + NameEnd: 319, Name: "id", }, }, }, }, Destination: &ast.PropertyGraphDestinationKey{ - Destination: 324, + Destination: 327, Keys: &ast.PropertyGraphColumnNameList{ - LParen: 340, - RParen: 346, + LParen: 343, + RParen: 349, ColumnNameList: []*ast.Ident{ &ast.Ident{ - NamePos: 341, - NameEnd: 346, + NamePos: 344, + NameEnd: 349, Name: "to_id", }, }, }, ElementReference: &ast.Ident{ - NamePos: 359, - NameEnd: 366, + NamePos: 362, + NameEnd: 369, Name: "Account", }, ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 367, - RParen: 370, + LParen: 370, + RParen: 373, ColumnNameList: []*ast.Ident{ &ast.Ident{ - NamePos: 368, - NameEnd: 370, + NamePos: 371, + NameEnd: 373, Name: "id", }, }, @@ -216,10 +216,10 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ &ast.PropertyGraphLabelAndProperties{ Label: &ast.PropertyGraphElementLabelLabelName{ - Label: 378, + Label: 381, Name: &ast.Ident{ - NamePos: 384, - NameEnd: 393, + NamePos: 387, + NameEnd: 396, Name: "Transfers", }, }, @@ -234,4 +234,4 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph } --- SQL -CREATE OR REPLACE PROPERTY GRAPH FinGraph NODE TABLES(Account, Person) EDGE TABLES (PersonOwnAccount SOURCE KEY (id) REFERENCES Person (id) DESTINATION KEY (account_id) REFERENCES Account (id) LABEL Owns, AccountTransferAccount SOURCE KEY (id) REFERENCES Account (id) DESTINATION KEY (to_id) REFERENCES Account (id) LABEL Transfers) +CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph NODE TABLES(Account, Person) EDGE TABLES (PersonOwnAccount SOURCE KEY (id) REFERENCES Person (id) DESTINATION KEY (account_id) REFERENCES Account (id) LABEL Owns, AccountTransferAccount SOURCE KEY (id) REFERENCES Account (id) DESTINATION KEY (to_id) REFERENCES Account (id) LABEL Transfers) From fdf5939fb5c326b1617167daac52636a1e118cc9 Mon Sep 17 00:00:00 2001 From: apstndb <803393+apstndb@users.noreply.github.com> Date: Thu, 19 Sep 2024 22:45:03 +0900 Subject: [PATCH 05/13] Clean up PropertyGraph* --- ast/ast.go | 85 ++++++++++--------- ast/pos.go | 3 + ast/sql.go | 8 +- parser.go | 11 ++- ...ce_property_graph_fingraph_verbose.sql.txt | 24 +++--- ...ce_property_graph_fingraph_verbose.sql.txt | 24 +++--- 6 files changed, 88 insertions(+), 67 deletions(-) diff --git a/ast/ast.go b/ast/ast.go index a75dc5c5..e5733f4b 100644 --- a/ast/ast.go +++ b/ast/ast.go @@ -2322,7 +2322,7 @@ type CreatePropertyGraph struct { Content *PropertyGraphContent } -// PropertyGraphContent +// PropertyGraphContent represents body of CREATE PROPERTY GRAPH statement. // // NODE TABLES {{.NodeTables | sql}} {{if not(.EdgeTables | isnil)}}NODE TABLES {{.EdgeTables | sqlOpt}}{{end}} type PropertyGraphContent struct { @@ -2334,7 +2334,7 @@ type PropertyGraphContent struct { EdgeTables *PropertyGraphElementList //optional } -// PropertyGraphElementList +// PropertyGraphElementList represents element list in NODE TABLES or EDGE TABLES. // // ({{.Elements | sqlJoin ", "}}) type PropertyGraphElementList struct { @@ -2345,7 +2345,7 @@ type PropertyGraphElementList struct { Elements []*PropertyGraphElement } -// PropertyGraphElement +// PropertyGraphElement represents a single element in NODE TABLES or EDGE TABLES. // // {{.Ident | sql}} {{if not(.Alias | isnil)}} AS {{.Alias | sql}}{{end}} {{.Keys | sqlOpt}} {{.Properties | sqlOpt}} type PropertyGraphElement struct { @@ -2353,24 +2353,33 @@ type PropertyGraphElement struct { // end = (Properties ?? Keys ?? Alias ?? Name).end Name *Ident - Alias *Ident // optional - Keys PropertyGraphElementKeys // optional - Properties PropertyGraphProperties // optional + Alias *Ident // optional + Keys PropertyGraphElementKeys // optional + Properties PropertyGraphLabelsOrProperties // optional } -type PropertyGraphProperties interface { +// PropertyGraphLabelsOrProperties represents labels with properties or a single properties of node or edge. +type PropertyGraphLabelsOrProperties interface { Node - isPropertyGraphProperties() + isPropertyGraphLabelsOrProperties() } -func (*PropertyGraphNoProperties) isPropertyGraphProperties() {} -func (*PropertyGraphPropertiesAre) isPropertyGraphProperties() {} -func (*PropertyGraphElementLabelLabelName) isPropertyGraphProperties() {} -func (*PropertyGraphLabelAndPropertiesList) isPropertyGraphProperties() {} -func (*PropertyGraphElementLabelDefaultLabel) isPropertyGraphProperties() {} +func (*PropertyGraphSingleProperties) isPropertyGraphLabelsOrProperties() {} +func (*PropertyGraphLabelAndPropertiesList) isPropertyGraphLabelsOrProperties() {} + +// PropertyGraphSingleProperties is wrapper node for PropertyGraphElementProperties in PropertyGraphElement. +// It implements PropertyGraphLabelsOrProperties. +// +// {{.Properties | sql}} +type PropertyGraphSingleProperties struct { + // pos = Properties.pos + // end = Properties.pos + + Properties PropertyGraphElementProperties +} // PropertyGraphLabelAndPropertiesList represents whitespace-separated list of PropertyGraphLabelAndProperties. -// It implements PropertyGraphProperties. +// It implements PropertyGraphLabelsOrProperties. // // {{.LabelAndProperties | sqlJoin " "}} type PropertyGraphLabelAndPropertiesList struct { @@ -2380,7 +2389,7 @@ type PropertyGraphLabelAndPropertiesList struct { LabelAndProperties []*PropertyGraphLabelAndProperties } -// PropertyGraphLabelAndProperties +// PropertyGraphLabelAndProperties represents label and properties definition for a single label. // // {{.Label | sql}} {{.Properties | sqlOpt}} type PropertyGraphLabelAndProperties struct { @@ -2391,6 +2400,7 @@ type PropertyGraphLabelAndProperties struct { Properties PropertyGraphElementProperties // optional } +// PropertyGraphElementLabel represents a element label definition. type PropertyGraphElementLabel interface { Node isPropertyGraphElementLabel() @@ -2399,7 +2409,7 @@ type PropertyGraphElementLabel interface { func (*PropertyGraphElementLabelLabelName) isPropertyGraphElementLabel() {} func (*PropertyGraphElementLabelDefaultLabel) isPropertyGraphElementLabel() {} -// PropertyGraphElementLabelLabelName +// PropertyGraphElementLabelLabelName represents LABEL label_name node. // // LABEL {{.Name | sql}} type PropertyGraphElementLabelLabelName struct { @@ -2410,7 +2420,7 @@ type PropertyGraphElementLabelLabelName struct { Name *Ident } -// PropertyGraphElementLabelDefaultLabel +// PropertyGraphElementLabelDefaultLabel represents DEFAULT LABEL node. // // DEFAULT LABEL type PropertyGraphElementLabelDefaultLabel struct { @@ -2420,6 +2430,7 @@ type PropertyGraphElementLabelDefaultLabel struct { Label token.Pos } +// PropertyGraphElementKeys represents PropertyGraphNodeElementKey or PropertyGraphEdgeElementKeys. type PropertyGraphElementKeys interface { Node isPropertyGraphElementKeys() @@ -2439,7 +2450,7 @@ type PropertyGraphNodeElementKey struct { PropertyGraphElementKey } -// PropertyGraphEdgeElementKeys +// PropertyGraphEdgeElementKeys represents PropertyGraphSourceKey and PropertyGraphDestinationKey with optional PropertyGraphElementKey. // // {{.Element | sqlOpt}} {{.Source | sql}} {{.Destination | sql}} type PropertyGraphEdgeElementKeys struct { @@ -2450,11 +2461,7 @@ type PropertyGraphEdgeElementKeys struct { Destination *PropertyGraphDestinationKey } -func (p *PropertyGraphEdgeElementKeys) SQL() string { - return sqlOpt("", p.Element, " ") + p.Source.SQL() + " " + p.Destination.SQL() -} - -// PropertyGraphElementKey +// PropertyGraphElementKey represents the key that identifies the node or edge element. // // KEY {{.Keys | sql}} type PropertyGraphElementKey struct { @@ -2465,7 +2472,7 @@ type PropertyGraphElementKey struct { Keys *PropertyGraphColumnNameList } -// PropertyGraphSourceKey +// PropertyGraphSourceKey represents the key for the source node of the edge. // // SOURCE KEY {{.Keys | sql}} // REFERENCES {{.ElementReference | sql}} {{.ReferenceColumns | sqlOpt}} @@ -2479,7 +2486,7 @@ type PropertyGraphSourceKey struct { ReferenceColumns *PropertyGraphColumnNameList // optional } -// PropertyGraphDestinationKey +// PropertyGraphDestinationKey represents the key for the destination node of the edge. // // DESTINATION KEY {{.Keys | sql}} // REFERENCES {{.ElementReference | sql}} {{.ReferenceColumns | sqlOpt}} @@ -2493,7 +2500,7 @@ type PropertyGraphDestinationKey struct { ReferenceColumns *PropertyGraphColumnNameList // optional } -// PropertyGraphColumnNameList +// PropertyGraphColumnNameList represents one or more columns to assign to a key. // // ({{.ColumnNameList | sqlJoin ", "}}) type PropertyGraphColumnNameList struct { @@ -2503,15 +2510,18 @@ type PropertyGraphColumnNameList struct { ColumnNameList []*Ident } -// Element properties definition -// https://cloud.google.com/spanner/docs/reference/standard-sql/graph-schema-statements#element_table_property_definition - +// PropertyGraphElementProperties represents a definition of properties. +// See https://cloud.google.com/spanner/docs/reference/standard-sql/graph-schema-statements#element_table_property_definition. type PropertyGraphElementProperties interface { - PropertyGraphProperties + Node isPropertyGraphElementProperties() } -// PropertyGraphNoProperties +func (*PropertyGraphNoProperties) isPropertyGraphElementProperties() {} +func (*PropertyGraphPropertiesAre) isPropertyGraphElementProperties() {} +func (*PropertyGraphDerivedPropertyList) isPropertyGraphElementProperties() {} + +// PropertyGraphNoProperties represents the element doesn't have properties. // // NO PROPERTIES type PropertyGraphNoProperties struct { @@ -2521,7 +2531,7 @@ type PropertyGraphNoProperties struct { No, Properties token.Pos // position of "NO" and "PROPERTIES" } -// PropertyGraphPropertiesAre +// PropertyGraphPropertiesAre defines which columns to include as element properties. // // PROPERTIES ARE ALL COLUMNS{{if not(.ExceptColumns | isnil)}} EXCEPT {{.ExceptColumns}}{{end}} type PropertyGraphPropertiesAre struct { @@ -2535,10 +2545,7 @@ type PropertyGraphPropertiesAre struct { } -func (*PropertyGraphPropertiesAre) isPropertyGraphElementProperties() {} -func (*PropertyGraphDerivedPropertyList) isPropertyGraphElementProperties() {} - -// PropertyGraphDerivedPropertyList +// PropertyGraphDerivedPropertyList represents a list of PropertyGraphDerivedProperty. // // PROPERTIES ({{.DerivedProperties | sqlJoin ", "}}) // @@ -2552,9 +2559,7 @@ type PropertyGraphDerivedPropertyList struct { DerivedProperties []*PropertyGraphDerivedProperty // len > 0 } -func (*PropertyGraphDerivedPropertyList) isPropertyGraphProperties() {} - -// PropertyGraphDerivedProperty +// PropertyGraphDerivedProperty represents an expression that defines a property and can optionally reference the input table columns. // // {{.Expr | sql}}{{if not(.PropertyName | isnil)}} AS {{.PropertyName | sql}}{{end}} type PropertyGraphDerivedProperty struct { @@ -2565,7 +2570,7 @@ type PropertyGraphDerivedProperty struct { PropertyName *Ident //optional } -// DropPropertyGraph +// DropPropertyGraph is DROP PROPERTY GRAPH statement node. // // DROP PROPERTY GRAPH {{if .IfExists}}IF EXISTS{{end}} {{.PropertyGraphName | sql}} type DropPropertyGraph struct { diff --git a/ast/pos.go b/ast/pos.go index 985f1693..a8e80081 100644 --- a/ast/pos.go +++ b/ast/pos.go @@ -816,6 +816,9 @@ func (p *PropertyGraphElement) End() token.Pos { return firstValidEnd(p.Properties, p.Keys, p.Alias, p.Name) } +func (p *PropertyGraphSingleProperties) Pos() token.Pos { return p.Properties.Pos() } +func (p *PropertyGraphSingleProperties) End() token.Pos { return p.Properties.End() } + func (p *PropertyGraphLabelAndPropertiesList) Pos() token.Pos { return firstPos(p.LabelAndProperties) } func (p *PropertyGraphLabelAndPropertiesList) End() token.Pos { return lastEnd(p.LabelAndProperties) } diff --git a/ast/sql.go b/ast/sql.go index 86a4309a..26a89b92 100644 --- a/ast/sql.go +++ b/ast/sql.go @@ -1280,6 +1280,8 @@ func (p *PropertyGraphElement) SQL() string { sqlOpt(" ", p.Properties, "") } +func (p *PropertyGraphSingleProperties) SQL() string { return p.Properties.SQL() } + func (p *PropertyGraphLabelAndPropertiesList) SQL() string { return sqlJoin(p.LabelAndProperties, " ") } @@ -1298,6 +1300,10 @@ func (p *PropertyGraphElementKey) SQL() string { return "KEY " + p.Keys.SQL() } +func (p *PropertyGraphEdgeElementKeys) SQL() string { + return sqlOpt("", p.Element, " ") + p.Source.SQL() + " " + p.Destination.SQL() +} + func (p *PropertyGraphSourceKey) SQL() string { return "SOURCE KEY " + p.Keys.SQL() + " REFERENCES " + p.ElementReference.SQL() + @@ -1314,8 +1320,6 @@ func (p *PropertyGraphColumnNameList) SQL() string { return "(" + sqlJoin(p.ColumnNameList, ", ") + ")" } -func (*PropertyGraphNoProperties) isPropertyGraphElementProperties() {} - func (p *PropertyGraphNoProperties) SQL() string { return "NO PROPERTIES" } diff --git a/parser.go b/parser.go index 16edad38..99b20679 100644 --- a/parser.go +++ b/parser.go @@ -3289,7 +3289,7 @@ func (p *Parser) parsePropertyGraphElement() *ast.PropertyGraphElement { } keys := p.tryParsePropertyGraphElementKeys() - properties := p.tryParsePropertyGraphProperties() + properties := p.tryParsePropertyGraphLabelsOrProperties() return &ast.PropertyGraphElement{ Name: name, @@ -3396,11 +3396,16 @@ func (p *Parser) parsePropertyGraphElementProperties() ast.PropertyGraphElementP } } -func (p *Parser) tryParsePropertyGraphProperties() ast.PropertyGraphProperties { +func (p *Parser) tryParsePropertyGraphLabelsOrProperties() ast.PropertyGraphLabelsOrProperties { if p.Token.IsKeywordLike("LABEL") || p.Token.Kind == "DEFAULT" { return p.parsePropertyGraphLabelAndPropertiesList() } - return p.tryParsePropertyGraphElementProperties() + if properties := p.tryParsePropertyGraphElementProperties(); properties != nil { + return &ast.PropertyGraphSingleProperties{ + Properties: properties, + } + } + return nil } func (p *Parser) tryParsePropertyGraphElementKeys() ast.PropertyGraphElementKeys { diff --git a/testdata/result/ddl/create_or_replace_property_graph_fingraph_verbose.sql.txt b/testdata/result/ddl/create_or_replace_property_graph_fingraph_verbose.sql.txt index b4cad616..8d10330f 100644 --- a/testdata/result/ddl/create_or_replace_property_graph_fingraph_verbose.sql.txt +++ b/testdata/result/ddl/create_or_replace_property_graph_fingraph_verbose.sql.txt @@ -137,17 +137,19 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph }, Alias: (*ast.Ident)(nil), Keys: nil, - Properties: &ast.PropertyGraphPropertiesAre{ - Properties: 577, - Columns: 596, - ExceptColumns: &ast.PropertyGraphColumnNameList{ - LParen: 611, - RParen: 616, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 612, - NameEnd: 616, - Name: "city", + Properties: &ast.PropertyGraphSingleProperties{ + Properties: &ast.PropertyGraphPropertiesAre{ + Properties: 577, + Columns: 596, + ExceptColumns: &ast.PropertyGraphColumnNameList{ + LParen: 611, + RParen: 616, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 612, + NameEnd: 616, + Name: "city", + }, }, }, }, diff --git a/testdata/result/statement/create_or_replace_property_graph_fingraph_verbose.sql.txt b/testdata/result/statement/create_or_replace_property_graph_fingraph_verbose.sql.txt index b4cad616..8d10330f 100644 --- a/testdata/result/statement/create_or_replace_property_graph_fingraph_verbose.sql.txt +++ b/testdata/result/statement/create_or_replace_property_graph_fingraph_verbose.sql.txt @@ -137,17 +137,19 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph }, Alias: (*ast.Ident)(nil), Keys: nil, - Properties: &ast.PropertyGraphPropertiesAre{ - Properties: 577, - Columns: 596, - ExceptColumns: &ast.PropertyGraphColumnNameList{ - LParen: 611, - RParen: 616, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 612, - NameEnd: 616, - Name: "city", + Properties: &ast.PropertyGraphSingleProperties{ + Properties: &ast.PropertyGraphPropertiesAre{ + Properties: 577, + Columns: 596, + ExceptColumns: &ast.PropertyGraphColumnNameList{ + LParen: 611, + RParen: 616, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 612, + NameEnd: 616, + Name: "city", + }, }, }, }, From c64b2228e8b2226b15859bd64eb8316f386f59bc Mon Sep 17 00:00:00 2001 From: apstndb <803393+apstndb@users.noreply.github.com> Date: Thu, 19 Sep 2024 22:48:23 +0900 Subject: [PATCH 06/13] Bump Go version in .github/workflows --- .github/workflows/go.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index c253430b..c826e202 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -11,10 +11,10 @@ jobs: runs-on: ubuntu-latest steps: - - name: Set up Go 1.19 + - name: Set up Go 1.20 uses: actions/setup-go@v4 with: - go-version: 1.19 + go-version: "1.20" id: go - name: Check out code into the Go module directory From 69f38b2f8f73930086147a747e2260e769bb8be6 Mon Sep 17 00:00:00 2001 From: apstndb <803393+apstndb@users.noreply.github.com> Date: Mon, 21 Oct 2024 01:46:15 +0900 Subject: [PATCH 07/13] Update implementation of graph schema statements --- ast/ast.go | 160 +++--- ast/pos.go | 29 +- ast/sql.go | 47 +- parser.go | 168 +++--- ...ce_property_graph_fingraph_verbose.sql.txt | 499 +++++++++--------- ...perty_graph_if_not_exists_fingraph.sql.txt | 337 ++++++------ ...ce_property_graph_fingraph_verbose.sql.txt | 499 +++++++++--------- ...perty_graph_if_not_exists_fingraph.sql.txt | 337 ++++++------ 8 files changed, 1057 insertions(+), 1019 deletions(-) diff --git a/ast/ast.go b/ast/ast.go index d3fdadcb..6e13dd34 100644 --- a/ast/ast.go +++ b/ast/ast.go @@ -2436,9 +2436,49 @@ type ArraySchemaType struct { // // ================================================================================ +// PropertyGraphLabelsOrProperties represents labels with properties or a single properties of node or edge. +type PropertyGraphLabelsOrProperties interface { + Node + isPropertyGraphLabelsOrProperties() +} + +func (*PropertyGraphSingleProperties) isPropertyGraphLabelsOrProperties() {} +func (*PropertyGraphLabelAndPropertiesList) isPropertyGraphLabelsOrProperties() {} + +// PropertyGraphElementLabel represents a element label definition. +type PropertyGraphElementLabel interface { + Node + isPropertyGraphElementLabel() +} + +func (*PropertyGraphElementLabelLabelName) isPropertyGraphElementLabel() {} +func (*PropertyGraphElementLabelDefaultLabel) isPropertyGraphElementLabel() {} + +// PropertyGraphElementKeys represents PropertyGraphNodeElementKey or PropertyGraphEdgeElementKeys. +type PropertyGraphElementKeys interface { + Node + isPropertyGraphElementKeys() +} + +func (*PropertyGraphNodeElementKey) isPropertyGraphElementKeys() {} +func (*PropertyGraphEdgeElementKeys) isPropertyGraphElementKeys() {} + +// PropertyGraphElementProperties represents a definition of properties. +// See https://cloud.google.com/spanner/docs/reference/standard-sql/graph-schema-statements#element_table_property_definition. +type PropertyGraphElementProperties interface { + Node + isPropertyGraphElementProperties() +} + +func (*PropertyGraphNoProperties) isPropertyGraphElementProperties() {} +func (*PropertyGraphPropertiesAre) isPropertyGraphElementProperties() {} +func (*PropertyGraphDerivedPropertyList) isPropertyGraphElementProperties() {} + // CreatePropertyGraph is CREATE PROPERTY GRAPH statement node. // -// CREATE {{if .OrReplace}}OR REPLACE{{end}} PROPERTY GRAPH {{if .IfNotExists}}IF NOT EXISTS{{end}} {{.Name | sql}} +// CREATE {{if .OrReplace}}OR REPLACE{{end}} PROPERTY GRAPH +// {{if .IfNotExists}}IF NOT EXISTS{{end}} +// {{.Name | sql}} // {{.Content | sql}} type CreatePropertyGraph struct { // pos = Create @@ -2453,30 +2493,48 @@ type CreatePropertyGraph struct { // PropertyGraphContent represents body of CREATE PROPERTY GRAPH statement. // -// NODE TABLES {{.NodeTables | sql}} {{if not(.EdgeTables | isnil)}}NODE TABLES {{.EdgeTables | sqlOpt}}{{end}} +// NODE TABLES {{.NodeTables | sql}} {{.EdgeTables | sqlOpt}} type PropertyGraphContent struct { - // pos = Node + // pos = NodeTables.pos // end = (EdgeTables ?? NodeTables).end - Node token.Pos // position of "NODE" - NodeTables *PropertyGraphElementList - EdgeTables *PropertyGraphElementList //optional + NodeTables *PropertyGraphNodeTables + EdgeTables *PropertyGraphEdgeTables //optional +} + +// PropertyGraphNodeTables is NODE TABLES node in CREATE PROPERTY GRAPH statement. +type PropertyGraphNodeTables struct { + // pos = Node + // end = Tables.end + + Node token.Pos + Tables *PropertyGraphElementList +} + +// PropertyGraphEdgeTables is EDGE TABLES node in CREATE PROPERTY GRAPH statement. +type PropertyGraphEdgeTables struct { + // pos = Edge + // end = Tables.end + + Edge token.Pos + Tables *PropertyGraphElementList } // PropertyGraphElementList represents element list in NODE TABLES or EDGE TABLES. // // ({{.Elements | sqlJoin ", "}}) type PropertyGraphElementList struct { - // pos = LParen - // end = RParen + 1 + // pos = Lparen + // end = Rparen + 1 - LParen, RParen token.Pos + Lparen, Rparen token.Pos Elements []*PropertyGraphElement } // PropertyGraphElement represents a single element in NODE TABLES or EDGE TABLES. // -// {{.Ident | sql}} {{if not(.Alias | isnil)}} AS {{.Alias | sql}}{{end}} {{.Keys | sqlOpt}} {{.Properties | sqlOpt}} +// {{.Name | sql}} {{if .Alias | isnil | not)}}AS {{.Alias | sql}}{{end}} +// {{.Keys | sqlOpt}} {{.Properties | sqlOpt}} type PropertyGraphElement struct { // pos = Name.pos // end = (Properties ?? Keys ?? Alias ?? Name).end @@ -2487,22 +2545,13 @@ type PropertyGraphElement struct { Properties PropertyGraphLabelsOrProperties // optional } -// PropertyGraphLabelsOrProperties represents labels with properties or a single properties of node or edge. -type PropertyGraphLabelsOrProperties interface { - Node - isPropertyGraphLabelsOrProperties() -} - -func (*PropertyGraphSingleProperties) isPropertyGraphLabelsOrProperties() {} -func (*PropertyGraphLabelAndPropertiesList) isPropertyGraphLabelsOrProperties() {} - // PropertyGraphSingleProperties is wrapper node for PropertyGraphElementProperties in PropertyGraphElement. // It implements PropertyGraphLabelsOrProperties. // // {{.Properties | sql}} type PropertyGraphSingleProperties struct { // pos = Properties.pos - // end = Properties.pos + // end = Properties.end Properties PropertyGraphElementProperties } @@ -2512,8 +2561,8 @@ type PropertyGraphSingleProperties struct { // // {{.LabelAndProperties | sqlJoin " "}} type PropertyGraphLabelAndPropertiesList struct { - // pos = LabelAndProperties.pos - // end = LabelAndProperties.end + // pos = LabelAndProperties[0].pos + // end = LabelAndProperties[$].end LabelAndProperties []*PropertyGraphLabelAndProperties } @@ -2529,15 +2578,6 @@ type PropertyGraphLabelAndProperties struct { Properties PropertyGraphElementProperties // optional } -// PropertyGraphElementLabel represents a element label definition. -type PropertyGraphElementLabel interface { - Node - isPropertyGraphElementLabel() -} - -func (*PropertyGraphElementLabelLabelName) isPropertyGraphElementLabel() {} -func (*PropertyGraphElementLabelDefaultLabel) isPropertyGraphElementLabel() {} - // PropertyGraphElementLabelLabelName represents LABEL label_name node. // // LABEL {{.Name | sql}} @@ -2554,20 +2594,12 @@ type PropertyGraphElementLabelLabelName struct { // DEFAULT LABEL type PropertyGraphElementLabelDefaultLabel struct { // pos = Default - // end = Label + 5 # len("LABEL") + // end = Label + 5 + Default token.Pos Label token.Pos } -// PropertyGraphElementKeys represents PropertyGraphNodeElementKey or PropertyGraphEdgeElementKeys. -type PropertyGraphElementKeys interface { - Node - isPropertyGraphElementKeys() -} - -func (*PropertyGraphNodeElementKey) isPropertyGraphElementKeys() {} -func (*PropertyGraphEdgeElementKeys) isPropertyGraphElementKeys() {} - // PropertyGraphNodeElementKey is a wrapper of PropertyGraphElementKey to implement PropertyGraphElementKeys // without deeper AST hierarchy. // @@ -2576,7 +2608,7 @@ type PropertyGraphNodeElementKey struct { // pos = PropertyGraphElementKey.pos // end = PropertyGraphElementKey.end - PropertyGraphElementKey + Key PropertyGraphElementKey } // PropertyGraphEdgeElementKeys represents PropertyGraphSourceKey and PropertyGraphDestinationKey with optional PropertyGraphElementKey. @@ -2607,7 +2639,7 @@ type PropertyGraphElementKey struct { // REFERENCES {{.ElementReference | sql}} {{.ReferenceColumns | sqlOpt}} type PropertyGraphSourceKey struct { // pos = Source - // end = (ReferenceColumns[$] ?? ElementReference).end + // end = (ReferenceColumns ?? ElementReference).end Source token.Pos Keys *PropertyGraphColumnNameList @@ -2621,7 +2653,7 @@ type PropertyGraphSourceKey struct { // REFERENCES {{.ElementReference | sql}} {{.ReferenceColumns | sqlOpt}} type PropertyGraphDestinationKey struct { // pos = Destination - // end = (ReferenceColumns[$] ?? ElementReference).end + // end = (ReferenceColumns ?? ElementReference).end Destination token.Pos Keys *PropertyGraphColumnNameList @@ -2639,69 +2671,55 @@ type PropertyGraphColumnNameList struct { ColumnNameList []*Ident } -// PropertyGraphElementProperties represents a definition of properties. -// See https://cloud.google.com/spanner/docs/reference/standard-sql/graph-schema-statements#element_table_property_definition. -type PropertyGraphElementProperties interface { - Node - isPropertyGraphElementProperties() -} - -func (*PropertyGraphNoProperties) isPropertyGraphElementProperties() {} -func (*PropertyGraphPropertiesAre) isPropertyGraphElementProperties() {} -func (*PropertyGraphDerivedPropertyList) isPropertyGraphElementProperties() {} - // PropertyGraphNoProperties represents the element doesn't have properties. // // NO PROPERTIES type PropertyGraphNoProperties struct { // pos = No - // end = Properties + 10 # len("PROPERTIES") + // end = Properties + 10 No, Properties token.Pos // position of "NO" and "PROPERTIES" } // PropertyGraphPropertiesAre defines which columns to include as element properties. // -// PROPERTIES ARE ALL COLUMNS{{if not(.ExceptColumns | isnil)}} EXCEPT {{.ExceptColumns}}{{end}} +// PROPERTIES ARE ALL COLUMNS{{if .ExceptColumns | isnil | not}} EXCEPT {{.ExceptColumns | sql}}{{end}} type PropertyGraphPropertiesAre struct { // pos = Properties - // end = ExceptColumns.end - - Properties token.Pos // position of "PROPERTIES" - Columns token.Pos // position of "COLUMNS" + // end = ExceptColumns.end || Columns + 7 + Properties token.Pos // position of "PROPERTIES" + Columns token.Pos // position of "COLUMNS" ExceptColumns *PropertyGraphColumnNameList // optional - } // PropertyGraphDerivedPropertyList represents a list of PropertyGraphDerivedProperty. +// NOTE: In current syntax reference, "(" and ")" are missing. // // PROPERTIES ({{.DerivedProperties | sqlJoin ", "}}) -// -// NOTE: In current official syntax, "(" and ")" are missing. type PropertyGraphDerivedPropertyList struct { // pos = Properties - // end = RParen.end + // end = Rparen.end Properties token.Pos // position of "PROPERTIES" - RParen token.Pos // position of ")" - DerivedProperties []*PropertyGraphDerivedProperty // len > 0 + Rparen token.Pos // position of ")" + DerivedProperties []*PropertyGraphDerivedProperty // len(DerivedProperties) > 0 } // PropertyGraphDerivedProperty represents an expression that defines a property and can optionally reference the input table columns. // -// {{.Expr | sql}}{{if not(.PropertyName | isnil)}} AS {{.PropertyName | sql}}{{end}} +// {{.Expr | sql}} {{if .PropertyName | isnil | not}}AS {{.Alias | sql}}{{end}} type PropertyGraphDerivedProperty struct { // pos = Expr.pos // end = (PropertyName ?? Expr).end - Expr Expr - PropertyName *Ident //optional + Expr Expr + Alias *Ident //optional } // DropPropertyGraph is DROP PROPERTY GRAPH statement node. // -// DROP PROPERTY GRAPH {{if .IfExists}}IF EXISTS{{end}} {{.PropertyGraphName | sql}} +// DROP PROPERTY GRAPH {{if .IfExists}}IF EXISTS{{end}} {{.Name | sql}} type DropPropertyGraph struct { // pos = Drop // end = Name.end diff --git a/ast/pos.go b/ast/pos.go index 75b93421..4f45f76e 100644 --- a/ast/pos.go +++ b/ast/pos.go @@ -862,11 +862,17 @@ func (r *RolePrivilege) End() token.Pos { return r.Names[len(r.Names)-1].End() } func (c *CreatePropertyGraph) Pos() token.Pos { return c.Create } func (c *CreatePropertyGraph) End() token.Pos { return c.Content.End() } -func (p *PropertyGraphContent) Pos() token.Pos { return p.Node } +func (p *PropertyGraphContent) Pos() token.Pos { return p.NodeTables.Pos() } func (p *PropertyGraphContent) End() token.Pos { return firstValidEnd(p.EdgeTables, p.NodeTables) } -func (p *PropertyGraphElementList) Pos() token.Pos { return p.LParen } -func (p *PropertyGraphElementList) End() token.Pos { return p.RParen + 1 } +func (p *PropertyGraphNodeTables) Pos() token.Pos { return p.Node } +func (p *PropertyGraphNodeTables) End() token.Pos { return p.Tables.End() } + +func (p *PropertyGraphEdgeTables) Pos() token.Pos { return p.Edge } +func (p *PropertyGraphEdgeTables) End() token.Pos { return p.Tables.End() } + +func (p *PropertyGraphElementList) Pos() token.Pos { return p.Lparen } +func (p *PropertyGraphElementList) End() token.Pos { return p.Rparen + 1 } func (p *PropertyGraphElement) Pos() token.Pos { return p.Name.Pos() } func (p *PropertyGraphElement) End() token.Pos { @@ -890,8 +896,8 @@ func (p *PropertyGraphElementLabelLabelName) End() token.Pos { return p.Name.End func (p *PropertyGraphElementLabelDefaultLabel) Pos() token.Pos { return p.Default } func (p *PropertyGraphElementLabelDefaultLabel) End() token.Pos { return p.Label + 5 } -func (p *PropertyGraphNodeElementKey) Pos() token.Pos { return p.PropertyGraphElementKey.Pos() } -func (p *PropertyGraphNodeElementKey) End() token.Pos { return p.PropertyGraphElementKey.End() } +func (p *PropertyGraphNodeElementKey) Pos() token.Pos { return p.Key.Pos() } +func (p *PropertyGraphNodeElementKey) End() token.Pos { return p.Key.End() } func (p *PropertyGraphEdgeElementKeys) Pos() token.Pos { return p.Element.Pos() } func (p *PropertyGraphEdgeElementKeys) End() token.Pos { return p.Destination.End() } @@ -906,7 +912,7 @@ func (p *PropertyGraphSourceKey) End() token.Pos { func (p *PropertyGraphDestinationKey) Pos() token.Pos { return p.Destination } func (p *PropertyGraphDestinationKey) End() token.Pos { - return firstValidEnd(p.ElementReference, p.ElementReference) + return firstValidEnd(p.ReferenceColumns, p.ElementReference) } func (p *PropertyGraphColumnNameList) Pos() token.Pos { return p.LParen } @@ -916,13 +922,18 @@ func (p *PropertyGraphNoProperties) Pos() token.Pos { return p.No } func (p *PropertyGraphNoProperties) End() token.Pos { return p.Properties + 10 } func (p *PropertyGraphPropertiesAre) Pos() token.Pos { return p.Properties } -func (p *PropertyGraphPropertiesAre) End() token.Pos { return p.ExceptColumns.End() } +func (p *PropertyGraphPropertiesAre) End() token.Pos { + if p.ExceptColumns != nil { + return p.ExceptColumns.End() + } + return p.Columns + 7 +} func (p *PropertyGraphDerivedPropertyList) Pos() token.Pos { return p.Properties } -func (p *PropertyGraphDerivedPropertyList) End() token.Pos { return p.RParen + 1 } +func (p *PropertyGraphDerivedPropertyList) End() token.Pos { return p.Rparen + 1 } func (p *PropertyGraphDerivedProperty) Pos() token.Pos { return p.Expr.Pos() } -func (p *PropertyGraphDerivedProperty) End() token.Pos { return firstValidEnd(p.PropertyName, p.Expr) } +func (p *PropertyGraphDerivedProperty) End() token.Pos { return firstValidEnd(p.Alias, p.Expr) } func (g *DropPropertyGraph) Pos() token.Pos { return g.Drop } func (g *DropPropertyGraph) End() token.Pos { return g.Name.End() } diff --git a/ast/sql.go b/ast/sql.go index 5a509002..7ce02c66 100644 --- a/ast/sql.go +++ b/ast/sql.go @@ -1254,20 +1254,23 @@ func (r *RolePrivilege) SQL() string { // ================================================================================ func (c *CreatePropertyGraph) SQL() string { - sql := "CREATE " - if c.OrReplace { - sql += "OR REPLACE " - } - sql += "PROPERTY GRAPH " - if c.IfNotExists { - sql += "IF NOT EXISTS " - } - sql += c.Name.SQL() + " " + c.Content.SQL() - return sql + return "CREATE " + + strOpt(c.OrReplace, "OR REPLACE ") + + "PROPERTY GRAPH " + + strOpt(c.IfNotExists, "IF NOT EXISTS ") + + c.Name.SQL() + " " + c.Content.SQL() } func (p *PropertyGraphContent) SQL() string { - return "NODE TABLES" + p.NodeTables.SQL() + sqlOpt(" EDGE TABLES ", p.EdgeTables, "") + return p.NodeTables.SQL() + sqlOpt(" ", p.EdgeTables, "") +} + +func (p *PropertyGraphNodeTables) SQL() string { + return "NODE TABLES " + p.Tables.SQL() +} + +func (p *PropertyGraphEdgeTables) SQL() string { + return "EDGE TABLES " + p.Tables.SQL() } func (p *PropertyGraphElementList) SQL() string { @@ -1295,16 +1298,15 @@ func (p *PropertyGraphElementLabelLabelName) SQL() string { return "LABEL " + p. func (p *PropertyGraphElementLabelDefaultLabel) SQL() string { return "DEFAULT LABEL" } -func (p *PropertyGraphNodeElementKey) SQL() string { return p.PropertyGraphElementKey.SQL() } - -func (p *PropertyGraphElementKey) SQL() string { - return "KEY " + p.Keys.SQL() -} +func (p *PropertyGraphNodeElementKey) SQL() string { return p.Key.SQL() } func (p *PropertyGraphEdgeElementKeys) SQL() string { - return sqlOpt("", p.Element, " ") + p.Source.SQL() + " " + p.Destination.SQL() + return sqlOpt("", p.Element, " ") + + p.Source.SQL() + " " + p.Destination.SQL() } +func (p *PropertyGraphElementKey) SQL() string { return "KEY " + p.Keys.SQL() } + func (p *PropertyGraphSourceKey) SQL() string { return "SOURCE KEY " + p.Keys.SQL() + " REFERENCES " + p.ElementReference.SQL() + @@ -1334,16 +1336,13 @@ func (p *PropertyGraphDerivedPropertyList) SQL() string { } func (p *PropertyGraphDerivedProperty) SQL() string { - return p.Expr.SQL() + sqlOpt(" AS ", p.PropertyName, "") + return p.Expr.SQL() + sqlOpt(" AS ", p.Alias, "") } func (g *DropPropertyGraph) SQL() string { - sql := "DROP PROPERTY GRAPH " - if g.IfExists { - sql += "IF EXISTS " - } - sql += g.Name.SQL() - return sql + return "DROP PROPERTY GRAPH " + + strOpt(g.IfExists, "IF EXISTS ") + + g.Name.SQL() } // ================================================================================ diff --git a/parser.go b/parser.go index e1f98585..ef7c1347 100644 --- a/parser.go +++ b/parser.go @@ -3256,16 +3256,23 @@ func (p *Parser) parsePropertyGraphContent() *ast.PropertyGraphContent { node := p.expectKeywordLike("NODE").Pos p.expectKeywordLike("TABLES") - nodeTables := p.parsePropertyGraphElementList() + nodeTables := &ast.PropertyGraphNodeTables{ + Node: node, + Tables: p.parsePropertyGraphElementList(), + } - var edgeTables *ast.PropertyGraphElementList - if p.tryExpectKeywordLike("EDGE") != nil { + var edgeTables *ast.PropertyGraphEdgeTables + if p.Token.IsKeywordLike("EDGE") { + edge := p.expectKeywordLike("EDGE").Pos p.expectKeywordLike("TABLES") - edgeTables = p.parsePropertyGraphElementList() + tables := p.parsePropertyGraphElementList() + edgeTables = &ast.PropertyGraphEdgeTables{ + Edge: edge, + Tables: tables, + } } return &ast.PropertyGraphContent{ - Node: node, NodeTables: nodeTables, EdgeTables: edgeTables, } @@ -3273,12 +3280,12 @@ func (p *Parser) parsePropertyGraphContent() *ast.PropertyGraphContent { func (p *Parser) parsePropertyGraphElementList() *ast.PropertyGraphElementList { lparen := p.expect("(").Pos - elements := parseSeparatedList(p, ",", p.parsePropertyGraphElement) + elements := parseCommaSeparatedList(p, p.parsePropertyGraphElement) rparen := p.expect(")").Pos return &ast.PropertyGraphElementList{ - LParen: lparen, - RParen: rparen, + Lparen: lparen, + Rparen: rparen, Elements: elements, } @@ -3287,7 +3294,8 @@ func (p *Parser) parsePropertyGraphElement() *ast.PropertyGraphElement { name := p.parseIdent() var alias *ast.Ident - if p.tryExpect("AS") != nil { + if p.Token.Kind == "AS" { + p.nextToken() alias = p.parseIdent() } @@ -3305,43 +3313,52 @@ func (p *Parser) parsePropertyGraphElement() *ast.PropertyGraphElement { // parsePropertyGraphLabelAndPropertiesList parses consecutive ast.PropertyGraphLabelAndProperties, // and returns *ast.PropertyGraphLabelAndPropertiesList. func (p *Parser) parsePropertyGraphLabelAndPropertiesList() *ast.PropertyGraphLabelAndPropertiesList { + // list can be empty var list []*ast.PropertyGraphLabelAndProperties for { if p.Token.Kind != "DEFAULT" && !p.Token.IsKeywordLike("LABEL") { break } - var elemLabel ast.PropertyGraphElementLabel - if def := p.tryExpect("DEFAULT"); def != nil { - labelPos := p.expectKeywordLike("LABEL").Pos - elemLabel = &ast.PropertyGraphElementLabelDefaultLabel{ - Default: def.Pos, - Label: labelPos, - } - } else { - label := p.expectKeywordLike("LABEL") - name := p.parseIdent() - elemLabel = &ast.PropertyGraphElementLabelLabelName{ - Label: label.Pos, - Name: name, - } - } - + elemLabel := p.parsePropertyGraphElementLabel() properties := p.tryParsePropertyGraphElementProperties() + list = append(list, &ast.PropertyGraphLabelAndProperties{ Label: elemLabel, Properties: properties, }) } + return &ast.PropertyGraphLabelAndPropertiesList{ LabelAndProperties: list, } } +func (p *Parser) parsePropertyGraphElementLabel() ast.PropertyGraphElementLabel { + if p.Token.Kind == "DEFAULT" { + def := p.expect("DEFAULT").Pos + label := p.expectKeywordLike("LABEL").Pos + + return &ast.PropertyGraphElementLabelDefaultLabel{ + Default: def, + Label: label, + } + } + + label := p.expectKeywordLike("LABEL").Pos + name := p.parseIdent() + + return &ast.PropertyGraphElementLabelLabelName{ + Label: label, + Name: name, + } +} + func (p *Parser) tryParsePropertyGraphElementProperties() ast.PropertyGraphElementProperties { if p.Token.Kind != "NO" && !p.Token.IsKeywordLike("PROPERTIES") { return nil } + return p.parsePropertyGraphElementProperties() } @@ -3350,22 +3367,29 @@ func (p *Parser) parsePropertyGraphElementProperties() ast.PropertyGraphElementP p.panicfAtToken(&p.Token, `expect "NO" or "PROPERTIES", but %v`, p.Token.Kind) } - if no := p.tryExpect("NO"); no != nil { + if p.Token.Kind == "NO" { + no := p.expect("NO").Pos properties := p.expectKeywordLike("PROPERTIES").Pos + return &ast.PropertyGraphNoProperties{ - No: no.Pos, + No: no, Properties: properties, } } properties := p.expectKeywordLike("PROPERTIES") if p.Token.IsKeywordLike("ARE") || p.Token.Kind == "ALL" { - p.tryExpectKeywordLike("ARE") + // "ARE" is optional + if p.Token.IsKeywordLike("ARE") { + p.nextToken() + } + p.expect("ALL") columns := p.expectKeywordLike("COLUMNS").Pos var exceptColumns *ast.PropertyGraphColumnNameList - if p.tryExpect("EXCEPT") != nil { + if p.Token.Kind == "EXCEPT" { + p.nextToken() exceptColumns = p.parsePropertyGraphColumnNameList() } @@ -3377,32 +3401,36 @@ func (p *Parser) parsePropertyGraphElementProperties() ast.PropertyGraphElementP } p.expect("(") - list := parseSeparatedList(p, ",", func() *ast.PropertyGraphDerivedProperty { - expr := p.parseExpr() - - var name *ast.Ident - if p.tryExpect("AS") != nil { - name = p.parseIdent() - } - - return &ast.PropertyGraphDerivedProperty{ - Expr: expr, - PropertyName: name, - } - }) + list := parseCommaSeparatedList(p, p.parsePropertyGraphDerivedProperty) rparen := p.expect(")").Pos return &ast.PropertyGraphDerivedPropertyList{ - RParen: rparen, + Rparen: rparen, Properties: properties.Pos, DerivedProperties: list, } } +func (p *Parser) parsePropertyGraphDerivedProperty() *ast.PropertyGraphDerivedProperty { + expr := p.parseExpr() + + var name *ast.Ident + if p.Token.Kind == "AS" { + p.nextToken() + name = p.parseIdent() + } + + return &ast.PropertyGraphDerivedProperty{ + Expr: expr, + Alias: name, + } +} + func (p *Parser) tryParsePropertyGraphLabelsOrProperties() ast.PropertyGraphLabelsOrProperties { if p.Token.IsKeywordLike("LABEL") || p.Token.Kind == "DEFAULT" { return p.parsePropertyGraphLabelAndPropertiesList() } + if properties := p.tryParsePropertyGraphElementProperties(); properties != nil { return &ast.PropertyGraphSingleProperties{ Properties: properties, @@ -3418,17 +3446,19 @@ func (p *Parser) tryParsePropertyGraphElementKeys() ast.PropertyGraphElementKeys // element_key var elementKey *ast.PropertyGraphElementKey - if key := p.tryExpectKeywordLike("KEY"); key != nil { + if p.Token.IsKeywordLike("KEY") { + key := p.expectKeywordLike("KEY").Pos keyColumns := p.parsePropertyGraphColumnNameList() + elementKey = &ast.PropertyGraphElementKey{ - Key: key.Pos, + Key: key, Keys: keyColumns, } // if SOURCE KEY doesn't follow, it is node_element_key. if !p.Token.IsKeywordLike("SOURCE") { return &ast.PropertyGraphNodeElementKey{ - PropertyGraphElementKey: *elementKey, + Key: *elementKey, } } @@ -3471,8 +3501,9 @@ func (p *Parser) tryParsePropertyGraphElementKeys() ast.PropertyGraphElementKeys func (p *Parser) parsePropertyGraphColumnNameList() *ast.PropertyGraphColumnNameList { lparen := p.expect("(").Pos - list := parseSeparatedList(p, ",", p.parseIdent) + list := parseCommaSeparatedList(p, p.parseIdent) rparen := p.expect(")").Pos + return &ast.PropertyGraphColumnNameList{ LParen: lparen, RParen: rparen, @@ -3494,6 +3525,7 @@ func (p *Parser) parseDropPropertyGraph(pos token.Pos) *ast.DropPropertyGraph { p.expectKeywordLike("GRAPH") ifExists := p.parseIfExists() name := p.parseIdent() + return &ast.DropPropertyGraph{ Drop: pos, IfExists: ifExists, @@ -3995,48 +4027,6 @@ func (p *Parser) expectKeywordLike(s string) *token.Token { return id } -func (p *Parser) tryExpect(s token.TokenKind) *token.Token { - if p.Token.Kind != s { - return nil - } - return p.expect(s) -} - -func (p *Parser) tryExpectKeywordLike(s string) *token.Token { - if !p.Token.IsKeywordLike(s) { - return nil - } - return p.expectKeywordLike(s) -} - -// This function can't be a method because Go haven't yet supported generic methods. -func parseSeparatedList[T interface { - ast.Node - comparable -}](p *Parser, sep token.TokenKind, doParse func() T) []T { - var zero T - - first := doParse() - if first == zero { - return nil - } - - list := []T{first} - for { - if p.Token.Kind != sep { - break - } - p.nextToken() - - elem := doParse() - if elem == zero { - return list - } - list = append(list, elem) - } - return list -} - func (p *Parser) errorfAtToken(tok *token.Token, msg string, params ...interface{}) *Error { return &Error{ Message: fmt.Sprintf(msg, params...), diff --git a/testdata/result/ddl/create_or_replace_property_graph_fingraph_verbose.sql.txt b/testdata/result/ddl/create_or_replace_property_graph_fingraph_verbose.sql.txt index 8d10330f..e208f041 100644 --- a/testdata/result/ddl/create_or_replace_property_graph_fingraph_verbose.sql.txt +++ b/testdata/result/ddl/create_or_replace_property_graph_fingraph_verbose.sql.txt @@ -38,117 +38,119 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph Name: "FinGraph", }, Content: &ast.PropertyGraphContent{ - Node: 44, - NodeTables: &ast.PropertyGraphElementList{ - LParen: 56, - RParen: 638, - Elements: []*ast.PropertyGraphElement{ - &ast.PropertyGraphElement{ - Name: &ast.Ident{ - NamePos: 62, - NameEnd: 69, - Name: "Account", - }, - Alias: &ast.Ident{ - NamePos: 73, - NameEnd: 80, - Name: "Account", - }, - Keys: &ast.PropertyGraphNodeElementKey{ - PropertyGraphElementKey: ast.PropertyGraphElementKey{ - Key: 104, - Keys: &ast.PropertyGraphColumnNameList{ - LParen: 108, - RParen: 111, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 109, - NameEnd: 111, - Name: "id", + NodeTables: &ast.PropertyGraphNodeTables{ + Node: 44, + Tables: &ast.PropertyGraphElementList{ + Lparen: 56, + Rparen: 638, + Elements: []*ast.PropertyGraphElement{ + &ast.PropertyGraphElement{ + Name: &ast.Ident{ + NamePos: 62, + NameEnd: 69, + Name: "Account", + }, + Alias: &ast.Ident{ + NamePos: 73, + NameEnd: 80, + Name: "Account", + }, + Keys: &ast.PropertyGraphNodeElementKey{ + Key: ast.PropertyGraphElementKey{ + Key: 104, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 108, + RParen: 111, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 109, + NameEnd: 111, + Name: "id", + }, }, }, }, }, - }, - Properties: &ast.PropertyGraphLabelAndPropertiesList{ - LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ - &ast.PropertyGraphLabelAndProperties{ - Label: &ast.PropertyGraphElementLabelLabelName{ - Label: 203, - Name: &ast.Ident{ - NamePos: 209, - NameEnd: 224, - Name: "DetailedAccount", - }, - }, - Properties: &ast.PropertyGraphDerivedPropertyList{ - Properties: 270, - RParen: 324, - DerivedProperties: []*ast.PropertyGraphDerivedProperty{ - &ast.PropertyGraphDerivedProperty{ - Expr: &ast.Ident{ - NamePos: 282, - NameEnd: 293, - Name: "create_time", - }, - PropertyName: (*ast.Ident)(nil), + Properties: &ast.PropertyGraphLabelAndPropertiesList{ + LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ + &ast.PropertyGraphLabelAndProperties{ + Label: &ast.PropertyGraphElementLabelLabelName{ + Label: 203, + Name: &ast.Ident{ + NamePos: 209, + NameEnd: 224, + Name: "DetailedAccount", }, - &ast.PropertyGraphDerivedProperty{ - Expr: &ast.Ident{ - NamePos: 295, - NameEnd: 305, - Name: "is_blocked", + }, + Properties: &ast.PropertyGraphDerivedPropertyList{ + Properties: 270, + Rparen: 324, + DerivedProperties: []*ast.PropertyGraphDerivedProperty{ + &ast.PropertyGraphDerivedProperty{ + Expr: &ast.Ident{ + NamePos: 282, + NameEnd: 293, + Name: "create_time", + }, + Alias: (*ast.Ident)(nil), }, - PropertyName: (*ast.Ident)(nil), - }, - &ast.PropertyGraphDerivedProperty{ - Expr: &ast.Ident{ - NamePos: 307, - NameEnd: 316, - Name: "nick_name", + &ast.PropertyGraphDerivedProperty{ + Expr: &ast.Ident{ + NamePos: 295, + NameEnd: 305, + Name: "is_blocked", + }, + Alias: (*ast.Ident)(nil), }, - PropertyName: &ast.Ident{ - NamePos: 320, - NameEnd: 324, - Name: "name", + &ast.PropertyGraphDerivedProperty{ + Expr: &ast.Ident{ + NamePos: 307, + NameEnd: 316, + Name: "nick_name", + }, + Alias: &ast.Ident{ + NamePos: 320, + NameEnd: 324, + Name: "name", + }, }, }, }, }, - }, - &ast.PropertyGraphLabelAndProperties{ - Label: &ast.PropertyGraphElementLabelDefaultLabel{ - Default: 357, - Label: 365, - }, - Properties: &ast.PropertyGraphNoProperties{ - No: 413, - Properties: 416, + &ast.PropertyGraphLabelAndProperties{ + Label: &ast.PropertyGraphElementLabelDefaultLabel{ + Default: 357, + Label: 365, + }, + Properties: &ast.PropertyGraphNoProperties{ + No: 413, + Properties: 416, + }, }, }, }, }, - }, - &ast.PropertyGraphElement{ - Name: &ast.Ident{ - NamePos: 476, - NameEnd: 482, - Name: "Person", - }, - Alias: (*ast.Ident)(nil), - Keys: nil, - Properties: &ast.PropertyGraphSingleProperties{ - Properties: &ast.PropertyGraphPropertiesAre{ - Properties: 577, - Columns: 596, - ExceptColumns: &ast.PropertyGraphColumnNameList{ - LParen: 611, - RParen: 616, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 612, - NameEnd: 616, - Name: "city", + &ast.PropertyGraphElement{ + Name: &ast.Ident{ + NamePos: 476, + NameEnd: 482, + Name: "Person", + }, + Alias: (*ast.Ident)(nil), + Keys: nil, + Properties: &ast.PropertyGraphSingleProperties{ + Properties: &ast.PropertyGraphPropertiesAre{ + Properties: 577, + Columns: 596, + ExceptColumns: &ast.PropertyGraphColumnNameList{ + LParen: 611, + RParen: 616, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 612, + NameEnd: 616, + Name: "city", + }, }, }, }, @@ -157,184 +159,187 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph }, }, }, - EdgeTables: &ast.PropertyGraphElementList{ - LParen: 654, - RParen: 1207, - Elements: []*ast.PropertyGraphElement{ - &ast.PropertyGraphElement{ - Name: &ast.Ident{ - NamePos: 660, - NameEnd: 676, - Name: "PersonOwnAccount", - }, - Alias: &ast.Ident{ - NamePos: 680, - NameEnd: 696, - Name: "PersonOwnAccount", - }, - Keys: &ast.PropertyGraphEdgeElementKeys{ - Element: &ast.PropertyGraphElementKey{ - Key: 703, - Keys: &ast.PropertyGraphColumnNameList{ - LParen: 707, - RParen: 722, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 708, - NameEnd: 710, - Name: "id", - }, - &ast.Ident{ - NamePos: 712, - NameEnd: 722, - Name: "account_id", + EdgeTables: &ast.PropertyGraphEdgeTables{ + Edge: 642, + Tables: &ast.PropertyGraphElementList{ + Lparen: 654, + Rparen: 1207, + Elements: []*ast.PropertyGraphElement{ + &ast.PropertyGraphElement{ + Name: &ast.Ident{ + NamePos: 660, + NameEnd: 676, + Name: "PersonOwnAccount", + }, + Alias: &ast.Ident{ + NamePos: 680, + NameEnd: 696, + Name: "PersonOwnAccount", + }, + Keys: &ast.PropertyGraphEdgeElementKeys{ + Element: &ast.PropertyGraphElementKey{ + Key: 703, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 707, + RParen: 722, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 708, + NameEnd: 710, + Name: "id", + }, + &ast.Ident{ + NamePos: 712, + NameEnd: 722, + Name: "account_id", + }, }, }, }, - }, - Source: &ast.PropertyGraphSourceKey{ - Source: 730, - Keys: &ast.PropertyGraphColumnNameList{ - LParen: 741, - RParen: 744, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 742, - NameEnd: 744, - Name: "id", + Source: &ast.PropertyGraphSourceKey{ + Source: 730, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 741, + RParen: 744, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 742, + NameEnd: 744, + Name: "id", + }, }, }, + ElementReference: &ast.Ident{ + NamePos: 757, + NameEnd: 763, + Name: "Person", + }, + ReferenceColumns: (*ast.PropertyGraphColumnNameList)(nil), }, - ElementReference: &ast.Ident{ - NamePos: 757, - NameEnd: 763, - Name: "Person", - }, - ReferenceColumns: (*ast.PropertyGraphColumnNameList)(nil), - }, - Destination: &ast.PropertyGraphDestinationKey{ - Destination: 809, - Keys: &ast.PropertyGraphColumnNameList{ - LParen: 825, - RParen: 836, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 826, - NameEnd: 836, - Name: "account_id", + Destination: &ast.PropertyGraphDestinationKey{ + Destination: 809, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 825, + RParen: 836, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 826, + NameEnd: 836, + Name: "account_id", + }, }, }, + ElementReference: &ast.Ident{ + NamePos: 849, + NameEnd: 856, + Name: "Account", + }, + ReferenceColumns: (*ast.PropertyGraphColumnNameList)(nil), }, - ElementReference: &ast.Ident{ - NamePos: 849, - NameEnd: 856, - Name: "Account", - }, - ReferenceColumns: (*ast.PropertyGraphColumnNameList)(nil), }, - }, - Properties: &ast.PropertyGraphLabelAndPropertiesList{ - LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ - &ast.PropertyGraphLabelAndProperties{ - Label: &ast.PropertyGraphElementLabelLabelName{ - Label: 907, - Name: &ast.Ident{ - NamePos: 913, - NameEnd: 917, - Name: "Owns", + Properties: &ast.PropertyGraphLabelAndPropertiesList{ + LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ + &ast.PropertyGraphLabelAndProperties{ + Label: &ast.PropertyGraphElementLabelLabelName{ + Label: 907, + Name: &ast.Ident{ + NamePos: 913, + NameEnd: 917, + Name: "Owns", + }, + }, + Properties: &ast.PropertyGraphPropertiesAre{ + Properties: 926, + Columns: 941, + ExceptColumns: (*ast.PropertyGraphColumnNameList)(nil), }, - }, - Properties: &ast.PropertyGraphPropertiesAre{ - Properties: 926, - Columns: 941, - ExceptColumns: (*ast.PropertyGraphColumnNameList)(nil), }, }, }, }, - }, - &ast.PropertyGraphElement{ - Name: &ast.Ident{ - NamePos: 954, - NameEnd: 976, - Name: "AccountTransferAccount", - }, - Alias: (*ast.Ident)(nil), - Keys: &ast.PropertyGraphEdgeElementKeys{ - Element: (*ast.PropertyGraphElementKey)(nil), - Source: &ast.PropertyGraphSourceKey{ - Source: 983, - Keys: &ast.PropertyGraphColumnNameList{ - LParen: 994, - RParen: 997, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 995, - NameEnd: 997, - Name: "id", + &ast.PropertyGraphElement{ + Name: &ast.Ident{ + NamePos: 954, + NameEnd: 976, + Name: "AccountTransferAccount", + }, + Alias: (*ast.Ident)(nil), + Keys: &ast.PropertyGraphEdgeElementKeys{ + Element: (*ast.PropertyGraphElementKey)(nil), + Source: &ast.PropertyGraphSourceKey{ + Source: 983, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 994, + RParen: 997, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 995, + NameEnd: 997, + Name: "id", + }, }, }, - }, - ElementReference: &ast.Ident{ - NamePos: 1010, - NameEnd: 1017, - Name: "Account", - }, - ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 1018, - RParen: 1021, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 1019, - NameEnd: 1021, - Name: "id", + ElementReference: &ast.Ident{ + NamePos: 1010, + NameEnd: 1017, + Name: "Account", + }, + ReferenceColumns: &ast.PropertyGraphColumnNameList{ + LParen: 1018, + RParen: 1021, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 1019, + NameEnd: 1021, + Name: "id", + }, }, }, }, - }, - Destination: &ast.PropertyGraphDestinationKey{ - Destination: 1043, - Keys: &ast.PropertyGraphColumnNameList{ - LParen: 1059, - RParen: 1065, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 1060, - NameEnd: 1065, - Name: "to_id", + Destination: &ast.PropertyGraphDestinationKey{ + Destination: 1043, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 1059, + RParen: 1065, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 1060, + NameEnd: 1065, + Name: "to_id", + }, }, }, - }, - ElementReference: &ast.Ident{ - NamePos: 1078, - NameEnd: 1085, - Name: "Account", - }, - ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 1086, - RParen: 1089, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 1087, - NameEnd: 1089, - Name: "id", + ElementReference: &ast.Ident{ + NamePos: 1078, + NameEnd: 1085, + Name: "Account", + }, + ReferenceColumns: &ast.PropertyGraphColumnNameList{ + LParen: 1086, + RParen: 1089, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 1087, + NameEnd: 1089, + Name: "id", + }, }, }, }, }, - }, - Properties: &ast.PropertyGraphLabelAndPropertiesList{ - LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ - &ast.PropertyGraphLabelAndProperties{ - Label: &ast.PropertyGraphElementLabelLabelName{ - Label: 1116, - Name: &ast.Ident{ - NamePos: 1122, - NameEnd: 1131, - Name: "Transfers", + Properties: &ast.PropertyGraphLabelAndPropertiesList{ + LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ + &ast.PropertyGraphLabelAndProperties{ + Label: &ast.PropertyGraphElementLabelLabelName{ + Label: 1116, + Name: &ast.Ident{ + NamePos: 1122, + NameEnd: 1131, + Name: "Transfers", + }, }, + Properties: nil, }, - Properties: nil, }, }, }, @@ -345,4 +350,4 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph } --- SQL -CREATE OR REPLACE PROPERTY GRAPH FinGraph NODE TABLES(Account AS Account KEY (id) LABEL DetailedAccount PROPERTIES (create_time, is_blocked, nick_name AS name) DEFAULT LABEL NO PROPERTIES, Person PROPERTIES ARE ALL COLUMNS EXCEPT (city)) EDGE TABLES (PersonOwnAccount AS PersonOwnAccount KEY (id, account_id) SOURCE KEY (id) REFERENCES Person DESTINATION KEY (account_id) REFERENCES Account LABEL Owns PROPERTIES ARE ALL COLUMNS, AccountTransferAccount SOURCE KEY (id) REFERENCES Account (id) DESTINATION KEY (to_id) REFERENCES Account (id) LABEL Transfers) +CREATE OR REPLACE PROPERTY GRAPH FinGraph NODE TABLES (Account AS Account KEY (id) LABEL DetailedAccount PROPERTIES (create_time, is_blocked, nick_name AS name) DEFAULT LABEL NO PROPERTIES, Person PROPERTIES ARE ALL COLUMNS EXCEPT (city)) EDGE TABLES (PersonOwnAccount AS PersonOwnAccount KEY (id, account_id) SOURCE KEY (id) REFERENCES Person DESTINATION KEY (account_id) REFERENCES Account LABEL Owns PROPERTIES ARE ALL COLUMNS, AccountTransferAccount SOURCE KEY (id) REFERENCES Account (id) DESTINATION KEY (to_id) REFERENCES Account (id) LABEL Transfers) diff --git a/testdata/result/ddl/create_property_graph_if_not_exists_fingraph.sql.txt b/testdata/result/ddl/create_property_graph_if_not_exists_fingraph.sql.txt index 06ceb355..982125b4 100644 --- a/testdata/result/ddl/create_property_graph_if_not_exists_fingraph.sql.txt +++ b/testdata/result/ddl/create_property_graph_if_not_exists_fingraph.sql.txt @@ -25,205 +25,210 @@ CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph Name: "FinGraph", }, Content: &ast.PropertyGraphContent{ - Node: 47, - NodeTables: &ast.PropertyGraphElementList{ - LParen: 59, - RParen: 87, - Elements: []*ast.PropertyGraphElement{ - &ast.PropertyGraphElement{ - Name: &ast.Ident{ - NamePos: 65, - NameEnd: 72, - Name: "Account", + NodeTables: &ast.PropertyGraphNodeTables{ + Node: 47, + Tables: &ast.PropertyGraphElementList{ + Lparen: 59, + Rparen: 87, + Elements: []*ast.PropertyGraphElement{ + &ast.PropertyGraphElement{ + Name: &ast.Ident{ + NamePos: 65, + NameEnd: 72, + Name: "Account", + }, + Alias: (*ast.Ident)(nil), + Keys: nil, + Properties: nil, }, - Alias: (*ast.Ident)(nil), - Keys: nil, - Properties: nil, - }, - &ast.PropertyGraphElement{ - Name: &ast.Ident{ - NamePos: 78, - NameEnd: 84, - Name: "Person", + &ast.PropertyGraphElement{ + Name: &ast.Ident{ + NamePos: 78, + NameEnd: 84, + Name: "Person", + }, + Alias: (*ast.Ident)(nil), + Keys: nil, + Properties: nil, }, - Alias: (*ast.Ident)(nil), - Keys: nil, - Properties: nil, }, }, }, - EdgeTables: &ast.PropertyGraphElementList{ - LParen: 103, - RParen: 399, - Elements: []*ast.PropertyGraphElement{ - &ast.PropertyGraphElement{ - Name: &ast.Ident{ - NamePos: 109, - NameEnd: 125, - Name: "PersonOwnAccount", - }, - Alias: (*ast.Ident)(nil), - Keys: &ast.PropertyGraphEdgeElementKeys{ - Element: (*ast.PropertyGraphElementKey)(nil), - Source: &ast.PropertyGraphSourceKey{ - Source: 132, - Keys: &ast.PropertyGraphColumnNameList{ - LParen: 143, - RParen: 146, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 144, - NameEnd: 146, - Name: "id", + EdgeTables: &ast.PropertyGraphEdgeTables{ + Edge: 91, + Tables: &ast.PropertyGraphElementList{ + Lparen: 103, + Rparen: 399, + Elements: []*ast.PropertyGraphElement{ + &ast.PropertyGraphElement{ + Name: &ast.Ident{ + NamePos: 109, + NameEnd: 125, + Name: "PersonOwnAccount", + }, + Alias: (*ast.Ident)(nil), + Keys: &ast.PropertyGraphEdgeElementKeys{ + Element: (*ast.PropertyGraphElementKey)(nil), + Source: &ast.PropertyGraphSourceKey{ + Source: 132, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 143, + RParen: 146, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 144, + NameEnd: 146, + Name: "id", + }, }, }, - }, - ElementReference: &ast.Ident{ - NamePos: 159, - NameEnd: 165, - Name: "Person", - }, - ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 166, - RParen: 169, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 167, - NameEnd: 169, - Name: "id", + ElementReference: &ast.Ident{ + NamePos: 159, + NameEnd: 165, + Name: "Person", + }, + ReferenceColumns: &ast.PropertyGraphColumnNameList{ + LParen: 166, + RParen: 169, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 167, + NameEnd: 169, + Name: "id", + }, }, }, }, - }, - Destination: &ast.PropertyGraphDestinationKey{ - Destination: 177, - Keys: &ast.PropertyGraphColumnNameList{ - LParen: 193, - RParen: 204, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 194, - NameEnd: 204, - Name: "account_id", + Destination: &ast.PropertyGraphDestinationKey{ + Destination: 177, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 193, + RParen: 204, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 194, + NameEnd: 204, + Name: "account_id", + }, }, }, - }, - ElementReference: &ast.Ident{ - NamePos: 217, - NameEnd: 224, - Name: "Account", - }, - ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 225, - RParen: 228, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 226, - NameEnd: 228, - Name: "id", + ElementReference: &ast.Ident{ + NamePos: 217, + NameEnd: 224, + Name: "Account", + }, + ReferenceColumns: &ast.PropertyGraphColumnNameList{ + LParen: 225, + RParen: 228, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 226, + NameEnd: 228, + Name: "id", + }, }, }, }, }, - }, - Properties: &ast.PropertyGraphLabelAndPropertiesList{ - LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ - &ast.PropertyGraphLabelAndProperties{ - Label: &ast.PropertyGraphElementLabelLabelName{ - Label: 236, - Name: &ast.Ident{ - NamePos: 242, - NameEnd: 246, - Name: "Owns", + Properties: &ast.PropertyGraphLabelAndPropertiesList{ + LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ + &ast.PropertyGraphLabelAndProperties{ + Label: &ast.PropertyGraphElementLabelLabelName{ + Label: 236, + Name: &ast.Ident{ + NamePos: 242, + NameEnd: 246, + Name: "Owns", + }, }, + Properties: nil, }, - Properties: nil, }, }, }, - }, - &ast.PropertyGraphElement{ - Name: &ast.Ident{ - NamePos: 252, - NameEnd: 274, - Name: "AccountTransferAccount", - }, - Alias: (*ast.Ident)(nil), - Keys: &ast.PropertyGraphEdgeElementKeys{ - Element: (*ast.PropertyGraphElementKey)(nil), - Source: &ast.PropertyGraphSourceKey{ - Source: 281, - Keys: &ast.PropertyGraphColumnNameList{ - LParen: 292, - RParen: 295, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 293, - NameEnd: 295, - Name: "id", + &ast.PropertyGraphElement{ + Name: &ast.Ident{ + NamePos: 252, + NameEnd: 274, + Name: "AccountTransferAccount", + }, + Alias: (*ast.Ident)(nil), + Keys: &ast.PropertyGraphEdgeElementKeys{ + Element: (*ast.PropertyGraphElementKey)(nil), + Source: &ast.PropertyGraphSourceKey{ + Source: 281, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 292, + RParen: 295, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 293, + NameEnd: 295, + Name: "id", + }, }, }, - }, - ElementReference: &ast.Ident{ - NamePos: 308, - NameEnd: 315, - Name: "Account", - }, - ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 316, - RParen: 319, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 317, - NameEnd: 319, - Name: "id", + ElementReference: &ast.Ident{ + NamePos: 308, + NameEnd: 315, + Name: "Account", + }, + ReferenceColumns: &ast.PropertyGraphColumnNameList{ + LParen: 316, + RParen: 319, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 317, + NameEnd: 319, + Name: "id", + }, }, }, }, - }, - Destination: &ast.PropertyGraphDestinationKey{ - Destination: 327, - Keys: &ast.PropertyGraphColumnNameList{ - LParen: 343, - RParen: 349, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 344, - NameEnd: 349, - Name: "to_id", + Destination: &ast.PropertyGraphDestinationKey{ + Destination: 327, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 343, + RParen: 349, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 344, + NameEnd: 349, + Name: "to_id", + }, }, }, - }, - ElementReference: &ast.Ident{ - NamePos: 362, - NameEnd: 369, - Name: "Account", - }, - ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 370, - RParen: 373, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 371, - NameEnd: 373, - Name: "id", + ElementReference: &ast.Ident{ + NamePos: 362, + NameEnd: 369, + Name: "Account", + }, + ReferenceColumns: &ast.PropertyGraphColumnNameList{ + LParen: 370, + RParen: 373, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 371, + NameEnd: 373, + Name: "id", + }, }, }, }, }, - }, - Properties: &ast.PropertyGraphLabelAndPropertiesList{ - LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ - &ast.PropertyGraphLabelAndProperties{ - Label: &ast.PropertyGraphElementLabelLabelName{ - Label: 381, - Name: &ast.Ident{ - NamePos: 387, - NameEnd: 396, - Name: "Transfers", + Properties: &ast.PropertyGraphLabelAndPropertiesList{ + LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ + &ast.PropertyGraphLabelAndProperties{ + Label: &ast.PropertyGraphElementLabelLabelName{ + Label: 381, + Name: &ast.Ident{ + NamePos: 387, + NameEnd: 396, + Name: "Transfers", + }, }, + Properties: nil, }, - Properties: nil, }, }, }, @@ -234,4 +239,4 @@ CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph } --- SQL -CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph NODE TABLES(Account, Person) EDGE TABLES (PersonOwnAccount SOURCE KEY (id) REFERENCES Person (id) DESTINATION KEY (account_id) REFERENCES Account (id) LABEL Owns, AccountTransferAccount SOURCE KEY (id) REFERENCES Account (id) DESTINATION KEY (to_id) REFERENCES Account (id) LABEL Transfers) +CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph NODE TABLES (Account, Person) EDGE TABLES (PersonOwnAccount SOURCE KEY (id) REFERENCES Person (id) DESTINATION KEY (account_id) REFERENCES Account (id) LABEL Owns, AccountTransferAccount SOURCE KEY (id) REFERENCES Account (id) DESTINATION KEY (to_id) REFERENCES Account (id) LABEL Transfers) diff --git a/testdata/result/statement/create_or_replace_property_graph_fingraph_verbose.sql.txt b/testdata/result/statement/create_or_replace_property_graph_fingraph_verbose.sql.txt index 8d10330f..e208f041 100644 --- a/testdata/result/statement/create_or_replace_property_graph_fingraph_verbose.sql.txt +++ b/testdata/result/statement/create_or_replace_property_graph_fingraph_verbose.sql.txt @@ -38,117 +38,119 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph Name: "FinGraph", }, Content: &ast.PropertyGraphContent{ - Node: 44, - NodeTables: &ast.PropertyGraphElementList{ - LParen: 56, - RParen: 638, - Elements: []*ast.PropertyGraphElement{ - &ast.PropertyGraphElement{ - Name: &ast.Ident{ - NamePos: 62, - NameEnd: 69, - Name: "Account", - }, - Alias: &ast.Ident{ - NamePos: 73, - NameEnd: 80, - Name: "Account", - }, - Keys: &ast.PropertyGraphNodeElementKey{ - PropertyGraphElementKey: ast.PropertyGraphElementKey{ - Key: 104, - Keys: &ast.PropertyGraphColumnNameList{ - LParen: 108, - RParen: 111, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 109, - NameEnd: 111, - Name: "id", + NodeTables: &ast.PropertyGraphNodeTables{ + Node: 44, + Tables: &ast.PropertyGraphElementList{ + Lparen: 56, + Rparen: 638, + Elements: []*ast.PropertyGraphElement{ + &ast.PropertyGraphElement{ + Name: &ast.Ident{ + NamePos: 62, + NameEnd: 69, + Name: "Account", + }, + Alias: &ast.Ident{ + NamePos: 73, + NameEnd: 80, + Name: "Account", + }, + Keys: &ast.PropertyGraphNodeElementKey{ + Key: ast.PropertyGraphElementKey{ + Key: 104, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 108, + RParen: 111, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 109, + NameEnd: 111, + Name: "id", + }, }, }, }, }, - }, - Properties: &ast.PropertyGraphLabelAndPropertiesList{ - LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ - &ast.PropertyGraphLabelAndProperties{ - Label: &ast.PropertyGraphElementLabelLabelName{ - Label: 203, - Name: &ast.Ident{ - NamePos: 209, - NameEnd: 224, - Name: "DetailedAccount", - }, - }, - Properties: &ast.PropertyGraphDerivedPropertyList{ - Properties: 270, - RParen: 324, - DerivedProperties: []*ast.PropertyGraphDerivedProperty{ - &ast.PropertyGraphDerivedProperty{ - Expr: &ast.Ident{ - NamePos: 282, - NameEnd: 293, - Name: "create_time", - }, - PropertyName: (*ast.Ident)(nil), + Properties: &ast.PropertyGraphLabelAndPropertiesList{ + LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ + &ast.PropertyGraphLabelAndProperties{ + Label: &ast.PropertyGraphElementLabelLabelName{ + Label: 203, + Name: &ast.Ident{ + NamePos: 209, + NameEnd: 224, + Name: "DetailedAccount", }, - &ast.PropertyGraphDerivedProperty{ - Expr: &ast.Ident{ - NamePos: 295, - NameEnd: 305, - Name: "is_blocked", + }, + Properties: &ast.PropertyGraphDerivedPropertyList{ + Properties: 270, + Rparen: 324, + DerivedProperties: []*ast.PropertyGraphDerivedProperty{ + &ast.PropertyGraphDerivedProperty{ + Expr: &ast.Ident{ + NamePos: 282, + NameEnd: 293, + Name: "create_time", + }, + Alias: (*ast.Ident)(nil), }, - PropertyName: (*ast.Ident)(nil), - }, - &ast.PropertyGraphDerivedProperty{ - Expr: &ast.Ident{ - NamePos: 307, - NameEnd: 316, - Name: "nick_name", + &ast.PropertyGraphDerivedProperty{ + Expr: &ast.Ident{ + NamePos: 295, + NameEnd: 305, + Name: "is_blocked", + }, + Alias: (*ast.Ident)(nil), }, - PropertyName: &ast.Ident{ - NamePos: 320, - NameEnd: 324, - Name: "name", + &ast.PropertyGraphDerivedProperty{ + Expr: &ast.Ident{ + NamePos: 307, + NameEnd: 316, + Name: "nick_name", + }, + Alias: &ast.Ident{ + NamePos: 320, + NameEnd: 324, + Name: "name", + }, }, }, }, }, - }, - &ast.PropertyGraphLabelAndProperties{ - Label: &ast.PropertyGraphElementLabelDefaultLabel{ - Default: 357, - Label: 365, - }, - Properties: &ast.PropertyGraphNoProperties{ - No: 413, - Properties: 416, + &ast.PropertyGraphLabelAndProperties{ + Label: &ast.PropertyGraphElementLabelDefaultLabel{ + Default: 357, + Label: 365, + }, + Properties: &ast.PropertyGraphNoProperties{ + No: 413, + Properties: 416, + }, }, }, }, }, - }, - &ast.PropertyGraphElement{ - Name: &ast.Ident{ - NamePos: 476, - NameEnd: 482, - Name: "Person", - }, - Alias: (*ast.Ident)(nil), - Keys: nil, - Properties: &ast.PropertyGraphSingleProperties{ - Properties: &ast.PropertyGraphPropertiesAre{ - Properties: 577, - Columns: 596, - ExceptColumns: &ast.PropertyGraphColumnNameList{ - LParen: 611, - RParen: 616, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 612, - NameEnd: 616, - Name: "city", + &ast.PropertyGraphElement{ + Name: &ast.Ident{ + NamePos: 476, + NameEnd: 482, + Name: "Person", + }, + Alias: (*ast.Ident)(nil), + Keys: nil, + Properties: &ast.PropertyGraphSingleProperties{ + Properties: &ast.PropertyGraphPropertiesAre{ + Properties: 577, + Columns: 596, + ExceptColumns: &ast.PropertyGraphColumnNameList{ + LParen: 611, + RParen: 616, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 612, + NameEnd: 616, + Name: "city", + }, }, }, }, @@ -157,184 +159,187 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph }, }, }, - EdgeTables: &ast.PropertyGraphElementList{ - LParen: 654, - RParen: 1207, - Elements: []*ast.PropertyGraphElement{ - &ast.PropertyGraphElement{ - Name: &ast.Ident{ - NamePos: 660, - NameEnd: 676, - Name: "PersonOwnAccount", - }, - Alias: &ast.Ident{ - NamePos: 680, - NameEnd: 696, - Name: "PersonOwnAccount", - }, - Keys: &ast.PropertyGraphEdgeElementKeys{ - Element: &ast.PropertyGraphElementKey{ - Key: 703, - Keys: &ast.PropertyGraphColumnNameList{ - LParen: 707, - RParen: 722, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 708, - NameEnd: 710, - Name: "id", - }, - &ast.Ident{ - NamePos: 712, - NameEnd: 722, - Name: "account_id", + EdgeTables: &ast.PropertyGraphEdgeTables{ + Edge: 642, + Tables: &ast.PropertyGraphElementList{ + Lparen: 654, + Rparen: 1207, + Elements: []*ast.PropertyGraphElement{ + &ast.PropertyGraphElement{ + Name: &ast.Ident{ + NamePos: 660, + NameEnd: 676, + Name: "PersonOwnAccount", + }, + Alias: &ast.Ident{ + NamePos: 680, + NameEnd: 696, + Name: "PersonOwnAccount", + }, + Keys: &ast.PropertyGraphEdgeElementKeys{ + Element: &ast.PropertyGraphElementKey{ + Key: 703, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 707, + RParen: 722, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 708, + NameEnd: 710, + Name: "id", + }, + &ast.Ident{ + NamePos: 712, + NameEnd: 722, + Name: "account_id", + }, }, }, }, - }, - Source: &ast.PropertyGraphSourceKey{ - Source: 730, - Keys: &ast.PropertyGraphColumnNameList{ - LParen: 741, - RParen: 744, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 742, - NameEnd: 744, - Name: "id", + Source: &ast.PropertyGraphSourceKey{ + Source: 730, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 741, + RParen: 744, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 742, + NameEnd: 744, + Name: "id", + }, }, }, + ElementReference: &ast.Ident{ + NamePos: 757, + NameEnd: 763, + Name: "Person", + }, + ReferenceColumns: (*ast.PropertyGraphColumnNameList)(nil), }, - ElementReference: &ast.Ident{ - NamePos: 757, - NameEnd: 763, - Name: "Person", - }, - ReferenceColumns: (*ast.PropertyGraphColumnNameList)(nil), - }, - Destination: &ast.PropertyGraphDestinationKey{ - Destination: 809, - Keys: &ast.PropertyGraphColumnNameList{ - LParen: 825, - RParen: 836, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 826, - NameEnd: 836, - Name: "account_id", + Destination: &ast.PropertyGraphDestinationKey{ + Destination: 809, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 825, + RParen: 836, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 826, + NameEnd: 836, + Name: "account_id", + }, }, }, + ElementReference: &ast.Ident{ + NamePos: 849, + NameEnd: 856, + Name: "Account", + }, + ReferenceColumns: (*ast.PropertyGraphColumnNameList)(nil), }, - ElementReference: &ast.Ident{ - NamePos: 849, - NameEnd: 856, - Name: "Account", - }, - ReferenceColumns: (*ast.PropertyGraphColumnNameList)(nil), }, - }, - Properties: &ast.PropertyGraphLabelAndPropertiesList{ - LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ - &ast.PropertyGraphLabelAndProperties{ - Label: &ast.PropertyGraphElementLabelLabelName{ - Label: 907, - Name: &ast.Ident{ - NamePos: 913, - NameEnd: 917, - Name: "Owns", + Properties: &ast.PropertyGraphLabelAndPropertiesList{ + LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ + &ast.PropertyGraphLabelAndProperties{ + Label: &ast.PropertyGraphElementLabelLabelName{ + Label: 907, + Name: &ast.Ident{ + NamePos: 913, + NameEnd: 917, + Name: "Owns", + }, + }, + Properties: &ast.PropertyGraphPropertiesAre{ + Properties: 926, + Columns: 941, + ExceptColumns: (*ast.PropertyGraphColumnNameList)(nil), }, - }, - Properties: &ast.PropertyGraphPropertiesAre{ - Properties: 926, - Columns: 941, - ExceptColumns: (*ast.PropertyGraphColumnNameList)(nil), }, }, }, }, - }, - &ast.PropertyGraphElement{ - Name: &ast.Ident{ - NamePos: 954, - NameEnd: 976, - Name: "AccountTransferAccount", - }, - Alias: (*ast.Ident)(nil), - Keys: &ast.PropertyGraphEdgeElementKeys{ - Element: (*ast.PropertyGraphElementKey)(nil), - Source: &ast.PropertyGraphSourceKey{ - Source: 983, - Keys: &ast.PropertyGraphColumnNameList{ - LParen: 994, - RParen: 997, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 995, - NameEnd: 997, - Name: "id", + &ast.PropertyGraphElement{ + Name: &ast.Ident{ + NamePos: 954, + NameEnd: 976, + Name: "AccountTransferAccount", + }, + Alias: (*ast.Ident)(nil), + Keys: &ast.PropertyGraphEdgeElementKeys{ + Element: (*ast.PropertyGraphElementKey)(nil), + Source: &ast.PropertyGraphSourceKey{ + Source: 983, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 994, + RParen: 997, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 995, + NameEnd: 997, + Name: "id", + }, }, }, - }, - ElementReference: &ast.Ident{ - NamePos: 1010, - NameEnd: 1017, - Name: "Account", - }, - ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 1018, - RParen: 1021, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 1019, - NameEnd: 1021, - Name: "id", + ElementReference: &ast.Ident{ + NamePos: 1010, + NameEnd: 1017, + Name: "Account", + }, + ReferenceColumns: &ast.PropertyGraphColumnNameList{ + LParen: 1018, + RParen: 1021, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 1019, + NameEnd: 1021, + Name: "id", + }, }, }, }, - }, - Destination: &ast.PropertyGraphDestinationKey{ - Destination: 1043, - Keys: &ast.PropertyGraphColumnNameList{ - LParen: 1059, - RParen: 1065, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 1060, - NameEnd: 1065, - Name: "to_id", + Destination: &ast.PropertyGraphDestinationKey{ + Destination: 1043, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 1059, + RParen: 1065, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 1060, + NameEnd: 1065, + Name: "to_id", + }, }, }, - }, - ElementReference: &ast.Ident{ - NamePos: 1078, - NameEnd: 1085, - Name: "Account", - }, - ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 1086, - RParen: 1089, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 1087, - NameEnd: 1089, - Name: "id", + ElementReference: &ast.Ident{ + NamePos: 1078, + NameEnd: 1085, + Name: "Account", + }, + ReferenceColumns: &ast.PropertyGraphColumnNameList{ + LParen: 1086, + RParen: 1089, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 1087, + NameEnd: 1089, + Name: "id", + }, }, }, }, }, - }, - Properties: &ast.PropertyGraphLabelAndPropertiesList{ - LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ - &ast.PropertyGraphLabelAndProperties{ - Label: &ast.PropertyGraphElementLabelLabelName{ - Label: 1116, - Name: &ast.Ident{ - NamePos: 1122, - NameEnd: 1131, - Name: "Transfers", + Properties: &ast.PropertyGraphLabelAndPropertiesList{ + LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ + &ast.PropertyGraphLabelAndProperties{ + Label: &ast.PropertyGraphElementLabelLabelName{ + Label: 1116, + Name: &ast.Ident{ + NamePos: 1122, + NameEnd: 1131, + Name: "Transfers", + }, }, + Properties: nil, }, - Properties: nil, }, }, }, @@ -345,4 +350,4 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph } --- SQL -CREATE OR REPLACE PROPERTY GRAPH FinGraph NODE TABLES(Account AS Account KEY (id) LABEL DetailedAccount PROPERTIES (create_time, is_blocked, nick_name AS name) DEFAULT LABEL NO PROPERTIES, Person PROPERTIES ARE ALL COLUMNS EXCEPT (city)) EDGE TABLES (PersonOwnAccount AS PersonOwnAccount KEY (id, account_id) SOURCE KEY (id) REFERENCES Person DESTINATION KEY (account_id) REFERENCES Account LABEL Owns PROPERTIES ARE ALL COLUMNS, AccountTransferAccount SOURCE KEY (id) REFERENCES Account (id) DESTINATION KEY (to_id) REFERENCES Account (id) LABEL Transfers) +CREATE OR REPLACE PROPERTY GRAPH FinGraph NODE TABLES (Account AS Account KEY (id) LABEL DetailedAccount PROPERTIES (create_time, is_blocked, nick_name AS name) DEFAULT LABEL NO PROPERTIES, Person PROPERTIES ARE ALL COLUMNS EXCEPT (city)) EDGE TABLES (PersonOwnAccount AS PersonOwnAccount KEY (id, account_id) SOURCE KEY (id) REFERENCES Person DESTINATION KEY (account_id) REFERENCES Account LABEL Owns PROPERTIES ARE ALL COLUMNS, AccountTransferAccount SOURCE KEY (id) REFERENCES Account (id) DESTINATION KEY (to_id) REFERENCES Account (id) LABEL Transfers) diff --git a/testdata/result/statement/create_property_graph_if_not_exists_fingraph.sql.txt b/testdata/result/statement/create_property_graph_if_not_exists_fingraph.sql.txt index 06ceb355..982125b4 100644 --- a/testdata/result/statement/create_property_graph_if_not_exists_fingraph.sql.txt +++ b/testdata/result/statement/create_property_graph_if_not_exists_fingraph.sql.txt @@ -25,205 +25,210 @@ CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph Name: "FinGraph", }, Content: &ast.PropertyGraphContent{ - Node: 47, - NodeTables: &ast.PropertyGraphElementList{ - LParen: 59, - RParen: 87, - Elements: []*ast.PropertyGraphElement{ - &ast.PropertyGraphElement{ - Name: &ast.Ident{ - NamePos: 65, - NameEnd: 72, - Name: "Account", + NodeTables: &ast.PropertyGraphNodeTables{ + Node: 47, + Tables: &ast.PropertyGraphElementList{ + Lparen: 59, + Rparen: 87, + Elements: []*ast.PropertyGraphElement{ + &ast.PropertyGraphElement{ + Name: &ast.Ident{ + NamePos: 65, + NameEnd: 72, + Name: "Account", + }, + Alias: (*ast.Ident)(nil), + Keys: nil, + Properties: nil, }, - Alias: (*ast.Ident)(nil), - Keys: nil, - Properties: nil, - }, - &ast.PropertyGraphElement{ - Name: &ast.Ident{ - NamePos: 78, - NameEnd: 84, - Name: "Person", + &ast.PropertyGraphElement{ + Name: &ast.Ident{ + NamePos: 78, + NameEnd: 84, + Name: "Person", + }, + Alias: (*ast.Ident)(nil), + Keys: nil, + Properties: nil, }, - Alias: (*ast.Ident)(nil), - Keys: nil, - Properties: nil, }, }, }, - EdgeTables: &ast.PropertyGraphElementList{ - LParen: 103, - RParen: 399, - Elements: []*ast.PropertyGraphElement{ - &ast.PropertyGraphElement{ - Name: &ast.Ident{ - NamePos: 109, - NameEnd: 125, - Name: "PersonOwnAccount", - }, - Alias: (*ast.Ident)(nil), - Keys: &ast.PropertyGraphEdgeElementKeys{ - Element: (*ast.PropertyGraphElementKey)(nil), - Source: &ast.PropertyGraphSourceKey{ - Source: 132, - Keys: &ast.PropertyGraphColumnNameList{ - LParen: 143, - RParen: 146, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 144, - NameEnd: 146, - Name: "id", + EdgeTables: &ast.PropertyGraphEdgeTables{ + Edge: 91, + Tables: &ast.PropertyGraphElementList{ + Lparen: 103, + Rparen: 399, + Elements: []*ast.PropertyGraphElement{ + &ast.PropertyGraphElement{ + Name: &ast.Ident{ + NamePos: 109, + NameEnd: 125, + Name: "PersonOwnAccount", + }, + Alias: (*ast.Ident)(nil), + Keys: &ast.PropertyGraphEdgeElementKeys{ + Element: (*ast.PropertyGraphElementKey)(nil), + Source: &ast.PropertyGraphSourceKey{ + Source: 132, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 143, + RParen: 146, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 144, + NameEnd: 146, + Name: "id", + }, }, }, - }, - ElementReference: &ast.Ident{ - NamePos: 159, - NameEnd: 165, - Name: "Person", - }, - ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 166, - RParen: 169, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 167, - NameEnd: 169, - Name: "id", + ElementReference: &ast.Ident{ + NamePos: 159, + NameEnd: 165, + Name: "Person", + }, + ReferenceColumns: &ast.PropertyGraphColumnNameList{ + LParen: 166, + RParen: 169, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 167, + NameEnd: 169, + Name: "id", + }, }, }, }, - }, - Destination: &ast.PropertyGraphDestinationKey{ - Destination: 177, - Keys: &ast.PropertyGraphColumnNameList{ - LParen: 193, - RParen: 204, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 194, - NameEnd: 204, - Name: "account_id", + Destination: &ast.PropertyGraphDestinationKey{ + Destination: 177, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 193, + RParen: 204, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 194, + NameEnd: 204, + Name: "account_id", + }, }, }, - }, - ElementReference: &ast.Ident{ - NamePos: 217, - NameEnd: 224, - Name: "Account", - }, - ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 225, - RParen: 228, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 226, - NameEnd: 228, - Name: "id", + ElementReference: &ast.Ident{ + NamePos: 217, + NameEnd: 224, + Name: "Account", + }, + ReferenceColumns: &ast.PropertyGraphColumnNameList{ + LParen: 225, + RParen: 228, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 226, + NameEnd: 228, + Name: "id", + }, }, }, }, }, - }, - Properties: &ast.PropertyGraphLabelAndPropertiesList{ - LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ - &ast.PropertyGraphLabelAndProperties{ - Label: &ast.PropertyGraphElementLabelLabelName{ - Label: 236, - Name: &ast.Ident{ - NamePos: 242, - NameEnd: 246, - Name: "Owns", + Properties: &ast.PropertyGraphLabelAndPropertiesList{ + LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ + &ast.PropertyGraphLabelAndProperties{ + Label: &ast.PropertyGraphElementLabelLabelName{ + Label: 236, + Name: &ast.Ident{ + NamePos: 242, + NameEnd: 246, + Name: "Owns", + }, }, + Properties: nil, }, - Properties: nil, }, }, }, - }, - &ast.PropertyGraphElement{ - Name: &ast.Ident{ - NamePos: 252, - NameEnd: 274, - Name: "AccountTransferAccount", - }, - Alias: (*ast.Ident)(nil), - Keys: &ast.PropertyGraphEdgeElementKeys{ - Element: (*ast.PropertyGraphElementKey)(nil), - Source: &ast.PropertyGraphSourceKey{ - Source: 281, - Keys: &ast.PropertyGraphColumnNameList{ - LParen: 292, - RParen: 295, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 293, - NameEnd: 295, - Name: "id", + &ast.PropertyGraphElement{ + Name: &ast.Ident{ + NamePos: 252, + NameEnd: 274, + Name: "AccountTransferAccount", + }, + Alias: (*ast.Ident)(nil), + Keys: &ast.PropertyGraphEdgeElementKeys{ + Element: (*ast.PropertyGraphElementKey)(nil), + Source: &ast.PropertyGraphSourceKey{ + Source: 281, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 292, + RParen: 295, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 293, + NameEnd: 295, + Name: "id", + }, }, }, - }, - ElementReference: &ast.Ident{ - NamePos: 308, - NameEnd: 315, - Name: "Account", - }, - ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 316, - RParen: 319, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 317, - NameEnd: 319, - Name: "id", + ElementReference: &ast.Ident{ + NamePos: 308, + NameEnd: 315, + Name: "Account", + }, + ReferenceColumns: &ast.PropertyGraphColumnNameList{ + LParen: 316, + RParen: 319, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 317, + NameEnd: 319, + Name: "id", + }, }, }, }, - }, - Destination: &ast.PropertyGraphDestinationKey{ - Destination: 327, - Keys: &ast.PropertyGraphColumnNameList{ - LParen: 343, - RParen: 349, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 344, - NameEnd: 349, - Name: "to_id", + Destination: &ast.PropertyGraphDestinationKey{ + Destination: 327, + Keys: &ast.PropertyGraphColumnNameList{ + LParen: 343, + RParen: 349, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 344, + NameEnd: 349, + Name: "to_id", + }, }, }, - }, - ElementReference: &ast.Ident{ - NamePos: 362, - NameEnd: 369, - Name: "Account", - }, - ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 370, - RParen: 373, - ColumnNameList: []*ast.Ident{ - &ast.Ident{ - NamePos: 371, - NameEnd: 373, - Name: "id", + ElementReference: &ast.Ident{ + NamePos: 362, + NameEnd: 369, + Name: "Account", + }, + ReferenceColumns: &ast.PropertyGraphColumnNameList{ + LParen: 370, + RParen: 373, + ColumnNameList: []*ast.Ident{ + &ast.Ident{ + NamePos: 371, + NameEnd: 373, + Name: "id", + }, }, }, }, }, - }, - Properties: &ast.PropertyGraphLabelAndPropertiesList{ - LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ - &ast.PropertyGraphLabelAndProperties{ - Label: &ast.PropertyGraphElementLabelLabelName{ - Label: 381, - Name: &ast.Ident{ - NamePos: 387, - NameEnd: 396, - Name: "Transfers", + Properties: &ast.PropertyGraphLabelAndPropertiesList{ + LabelAndProperties: []*ast.PropertyGraphLabelAndProperties{ + &ast.PropertyGraphLabelAndProperties{ + Label: &ast.PropertyGraphElementLabelLabelName{ + Label: 381, + Name: &ast.Ident{ + NamePos: 387, + NameEnd: 396, + Name: "Transfers", + }, }, + Properties: nil, }, - Properties: nil, }, }, }, @@ -234,4 +239,4 @@ CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph } --- SQL -CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph NODE TABLES(Account, Person) EDGE TABLES (PersonOwnAccount SOURCE KEY (id) REFERENCES Person (id) DESTINATION KEY (account_id) REFERENCES Account (id) LABEL Owns, AccountTransferAccount SOURCE KEY (id) REFERENCES Account (id) DESTINATION KEY (to_id) REFERENCES Account (id) LABEL Transfers) +CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph NODE TABLES (Account, Person) EDGE TABLES (PersonOwnAccount SOURCE KEY (id) REFERENCES Person (id) DESTINATION KEY (account_id) REFERENCES Account (id) LABEL Owns, AccountTransferAccount SOURCE KEY (id) REFERENCES Account (id) DESTINATION KEY (to_id) REFERENCES Account (id) LABEL Transfers) From 252b4dfd9a9976a297a62fe4c2291702ce9545c0 Mon Sep 17 00:00:00 2001 From: apstndb <803393+apstndb@users.noreply.github.com> Date: Mon, 21 Oct 2024 01:55:16 +0900 Subject: [PATCH 08/13] Update ast/ast_test.go --- ast/ast_test.go | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/ast/ast_test.go b/ast/ast_test.go index dbf09542..0e1ea644 100644 --- a/ast/ast_test.go +++ b/ast/ast_test.go @@ -146,6 +146,8 @@ func TestDDL(t *testing.T) { DDL(&DropRole{}).isDDL() DDL(&Grant{}).isDDL() DDL(&Revoke{}).isDDL() + DDL(&CreatePropertyGraph{}).isDDL() + DDL(&DropPropertyGraph{}).isDDL() } func TestConstraint(t *testing.T) { @@ -198,3 +200,24 @@ func TestInsertInput(t *testing.T) { InsertInput(&ValuesInput{}).isInsertInput() InsertInput(&SubQueryInput{}).isInsertInput() } + +func TestPropertyGraphLabelsOrProperties(t *testing.T) { + PropertyGraphLabelsOrProperties(&PropertyGraphSingleProperties{}).isPropertyGraphLabelsOrProperties() + PropertyGraphLabelsOrProperties(&PropertyGraphLabelAndPropertiesList{}).isPropertyGraphLabelsOrProperties() +} + +func TestPropertyGraphElementLabel(t *testing.T) { + PropertyGraphElementLabel(&PropertyGraphElementLabelLabelName{}).isPropertyGraphElementLabel() + PropertyGraphElementLabel(&PropertyGraphElementLabelDefaultLabel{}).isPropertyGraphElementLabel() +} + +func TestPropertyGraphElementKeys(t *testing.T) { + PropertyGraphElementKeys(&PropertyGraphNodeElementKey{}).isPropertyGraphElementKeys() + PropertyGraphElementKeys(&PropertyGraphEdgeElementKeys{}).isPropertyGraphElementKeys() +} + +func TestPropertyGraphElementProperties(t *testing.T) { + PropertyGraphElementProperties(&PropertyGraphNoProperties{}).isPropertyGraphElementProperties() + PropertyGraphElementProperties(&PropertyGraphPropertiesAre{}).isPropertyGraphElementProperties() + PropertyGraphElementProperties(&PropertyGraphDerivedPropertyList{}).isPropertyGraphElementProperties() +} From f8e6a56b1658cbe3b4d3f6df97a28081f38a541b Mon Sep 17 00:00:00 2001 From: apstndb <803393+apstndb@users.noreply.github.com> Date: Sun, 12 Jan 2025 00:38:37 +0900 Subject: [PATCH 09/13] Update to pass gen-ast-pos --- ast/ast.go | 188 +++++++++++++++++++++++++++-------------------------- 1 file changed, 96 insertions(+), 92 deletions(-) diff --git a/ast/ast.go b/ast/ast.go index 382f323d..552feb9c 100644 --- a/ast/ast.go +++ b/ast/ast.go @@ -71,53 +71,53 @@ type Statement interface { // - https://cloud.google.com/spanner/docs/reference/standard-sql/data-definition-language // - https://cloud.google.com/spanner/docs/reference/standard-sql/dml-syntax -func (BadStatement) isStatement() {} -func (BadDDL) isStatement() {} -func (BadDML) isStatement() {} -func (QueryStatement) isStatement() {} -func (CreateSchema) isStatement() {} -func (DropSchema) isStatement() {} -func (CreateDatabase) isStatement() {} -func (AlterDatabase) isStatement() {} -func (CreatePlacement) isStatement() {} -func (CreateProtoBundle) isStatement() {} -func (AlterProtoBundle) isStatement() {} -func (DropProtoBundle) isStatement() {} -func (CreateTable) isStatement() {} -func (AlterTable) isStatement() {} -func (DropTable) isStatement() {} -func (RenameTable) isStatement() {} -func (CreateIndex) isStatement() {} -func (AlterIndex) isStatement() {} -func (DropIndex) isStatement() {} -func (CreateSearchIndex) isStatement() {} -func (DropSearchIndex) isStatement() {} -func (AlterSearchIndex) isStatement() {} -func (CreateView) isStatement() {} -func (DropView) isStatement() {} -func (CreateChangeStream) isStatement() {} -func (AlterChangeStream) isStatement() {} -func (DropChangeStream) isStatement() {} -func (CreateRole) isStatement() {} -func (DropRole) isStatement() {} -func (Grant) isStatement() {} -func (Revoke) isStatement() {} -func (CreateSequence) isStatement() {} -func (AlterSequence) isStatement() {} -func (DropSequence) isStatement() {} -func (AlterStatistics) isStatement() {} -func (CreateModel) isStatement() {} -func (AlterModel) isStatement() {} -func (DropModel) isStatement() {} -func (Analyze) isStatement() {} -func (CreateVectorIndex) isStatement() {} -func (DropVectorIndex) isStatement() {} +func (BadStatement) isStatement() {} +func (BadDDL) isStatement() {} +func (BadDML) isStatement() {} +func (QueryStatement) isStatement() {} +func (CreateSchema) isStatement() {} +func (DropSchema) isStatement() {} +func (CreateDatabase) isStatement() {} +func (AlterDatabase) isStatement() {} +func (CreatePlacement) isStatement() {} +func (CreateProtoBundle) isStatement() {} +func (AlterProtoBundle) isStatement() {} +func (DropProtoBundle) isStatement() {} +func (CreateTable) isStatement() {} +func (AlterTable) isStatement() {} +func (DropTable) isStatement() {} +func (RenameTable) isStatement() {} +func (CreateIndex) isStatement() {} +func (AlterIndex) isStatement() {} +func (DropIndex) isStatement() {} +func (CreateSearchIndex) isStatement() {} +func (DropSearchIndex) isStatement() {} +func (AlterSearchIndex) isStatement() {} +func (CreateView) isStatement() {} +func (DropView) isStatement() {} +func (CreateChangeStream) isStatement() {} +func (AlterChangeStream) isStatement() {} +func (DropChangeStream) isStatement() {} +func (CreateRole) isStatement() {} +func (DropRole) isStatement() {} +func (Grant) isStatement() {} +func (Revoke) isStatement() {} +func (CreateSequence) isStatement() {} +func (AlterSequence) isStatement() {} +func (DropSequence) isStatement() {} +func (AlterStatistics) isStatement() {} +func (CreateModel) isStatement() {} +func (AlterModel) isStatement() {} +func (DropModel) isStatement() {} +func (Analyze) isStatement() {} +func (CreateVectorIndex) isStatement() {} +func (DropVectorIndex) isStatement() {} func (CreatePropertyGraph) isStatement() {} func (DropPropertyGraph) isStatement() {} -func (Insert) isStatement() {} -func (Delete) isStatement() {} -func (Update) isStatement() {} -func (Call) isStatement() {} +func (Insert) isStatement() {} +func (Delete) isStatement() {} +func (Update) isStatement() {} +func (Call) isStatement() {} // QueryExpr represents query expression, which can be body of QueryStatement or subqueries. // Select and FromQuery are leaf QueryExpr and others wrap other QueryExpr. @@ -363,44 +363,44 @@ type DDL interface { // // - https://cloud.google.com/spanner/docs/reference/standard-sql/data-definition-language -func (BadDDL) isDDL() {} -func (CreateSchema) isDDL() {} -func (DropSchema) isDDL() {} -func (CreateDatabase) isDDL() {} -func (AlterDatabase) isDDL() {} -func (CreatePlacement) isDDL() {} -func (CreateProtoBundle) isDDL() {} -func (AlterProtoBundle) isDDL() {} -func (DropProtoBundle) isDDL() {} -func (CreateTable) isDDL() {} -func (AlterTable) isDDL() {} -func (DropTable) isDDL() {} -func (RenameTable) isDDL() {} -func (CreateIndex) isDDL() {} -func (AlterIndex) isDDL() {} -func (DropIndex) isDDL() {} -func (CreateView) isDDL() {} -func (CreateSearchIndex) isDDL() {} -func (DropSearchIndex) isDDL() {} -func (AlterSearchIndex) isDDL() {} -func (DropView) isDDL() {} -func (CreateChangeStream) isDDL() {} -func (AlterChangeStream) isDDL() {} -func (DropChangeStream) isDDL() {} -func (CreateRole) isDDL() {} -func (DropRole) isDDL() {} -func (Grant) isDDL() {} -func (Revoke) isDDL() {} -func (CreateSequence) isDDL() {} -func (AlterSequence) isDDL() {} -func (DropSequence) isDDL() {} -func (AlterStatistics) isDDL() {} -func (CreateModel) isDDL() {} -func (AlterModel) isDDL() {} -func (DropModel) isDDL() {} -func (Analyze) isDDL() {} -func (CreateVectorIndex) isDDL() {} -func (DropVectorIndex) isDDL() {} +func (BadDDL) isDDL() {} +func (CreateSchema) isDDL() {} +func (DropSchema) isDDL() {} +func (CreateDatabase) isDDL() {} +func (AlterDatabase) isDDL() {} +func (CreatePlacement) isDDL() {} +func (CreateProtoBundle) isDDL() {} +func (AlterProtoBundle) isDDL() {} +func (DropProtoBundle) isDDL() {} +func (CreateTable) isDDL() {} +func (AlterTable) isDDL() {} +func (DropTable) isDDL() {} +func (RenameTable) isDDL() {} +func (CreateIndex) isDDL() {} +func (AlterIndex) isDDL() {} +func (DropIndex) isDDL() {} +func (CreateView) isDDL() {} +func (CreateSearchIndex) isDDL() {} +func (DropSearchIndex) isDDL() {} +func (AlterSearchIndex) isDDL() {} +func (DropView) isDDL() {} +func (CreateChangeStream) isDDL() {} +func (AlterChangeStream) isDDL() {} +func (DropChangeStream) isDDL() {} +func (CreateRole) isDDL() {} +func (DropRole) isDDL() {} +func (Grant) isDDL() {} +func (Revoke) isDDL() {} +func (CreateSequence) isDDL() {} +func (AlterSequence) isDDL() {} +func (DropSequence) isDDL() {} +func (AlterStatistics) isDDL() {} +func (CreateModel) isDDL() {} +func (AlterModel) isDDL() {} +func (DropModel) isDDL() {} +func (Analyze) isDDL() {} +func (CreateVectorIndex) isDDL() {} +func (DropVectorIndex) isDDL() {} func (CreatePropertyGraph) isDDL() {} func (DropPropertyGraph) isDDL() {} @@ -3628,8 +3628,8 @@ type PropertyGraphLabelsOrProperties interface { isPropertyGraphLabelsOrProperties() } -func (*PropertyGraphSingleProperties) isPropertyGraphLabelsOrProperties() {} -func (*PropertyGraphLabelAndPropertiesList) isPropertyGraphLabelsOrProperties() {} +func (PropertyGraphSingleProperties) isPropertyGraphLabelsOrProperties() {} +func (PropertyGraphLabelAndPropertiesList) isPropertyGraphLabelsOrProperties() {} // PropertyGraphElementLabel represents a element label definition. type PropertyGraphElementLabel interface { @@ -3637,8 +3637,8 @@ type PropertyGraphElementLabel interface { isPropertyGraphElementLabel() } -func (*PropertyGraphElementLabelLabelName) isPropertyGraphElementLabel() {} -func (*PropertyGraphElementLabelDefaultLabel) isPropertyGraphElementLabel() {} +func (PropertyGraphElementLabelLabelName) isPropertyGraphElementLabel() {} +func (PropertyGraphElementLabelDefaultLabel) isPropertyGraphElementLabel() {} // PropertyGraphElementKeys represents PropertyGraphNodeElementKey or PropertyGraphEdgeElementKeys. type PropertyGraphElementKeys interface { @@ -3646,8 +3646,8 @@ type PropertyGraphElementKeys interface { isPropertyGraphElementKeys() } -func (*PropertyGraphNodeElementKey) isPropertyGraphElementKeys() {} -func (*PropertyGraphEdgeElementKeys) isPropertyGraphElementKeys() {} +func (PropertyGraphNodeElementKey) isPropertyGraphElementKeys() {} +func (PropertyGraphEdgeElementKeys) isPropertyGraphElementKeys() {} // PropertyGraphElementProperties represents a definition of properties. // See https://cloud.google.com/spanner/docs/reference/standard-sql/graph-schema-statements#element_table_property_definition. @@ -3656,9 +3656,9 @@ type PropertyGraphElementProperties interface { isPropertyGraphElementProperties() } -func (*PropertyGraphNoProperties) isPropertyGraphElementProperties() {} -func (*PropertyGraphPropertiesAre) isPropertyGraphElementProperties() {} -func (*PropertyGraphDerivedPropertyList) isPropertyGraphElementProperties() {} +func (PropertyGraphNoProperties) isPropertyGraphElementProperties() {} +func (PropertyGraphPropertiesAre) isPropertyGraphElementProperties() {} +func (PropertyGraphDerivedPropertyList) isPropertyGraphElementProperties() {} // CreatePropertyGraph is CREATE PROPERTY GRAPH statement node. // @@ -3689,6 +3689,8 @@ type PropertyGraphContent struct { } // PropertyGraphNodeTables is NODE TABLES node in CREATE PROPERTY GRAPH statement. +// +// NODE TABLES {{.Tables | sql}} type PropertyGraphNodeTables struct { // pos = Node // end = Tables.end @@ -3698,6 +3700,8 @@ type PropertyGraphNodeTables struct { } // PropertyGraphEdgeTables is EDGE TABLES node in CREATE PROPERTY GRAPH statement. +// +// EDGE TABLES {{.Tables | sql}} type PropertyGraphEdgeTables struct { // pos = Edge // end = Tables.end From 88cb3ee936b53e97eaa470e77f3f18260e65aa74 Mon Sep 17 00:00:00 2001 From: apstndb <803393+apstndb@users.noreply.github.com> Date: Sun, 12 Jan 2025 00:40:24 +0900 Subject: [PATCH 10/13] Add whitespace --- ast/ast.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ast/ast.go b/ast/ast.go index 552feb9c..342dc3b2 100644 --- a/ast/ast.go +++ b/ast/ast.go @@ -3904,7 +3904,7 @@ type PropertyGraphDerivedProperty struct { // end = (Alias ?? Expr).end Expr Expr - Alias *Ident //optional + Alias *Ident // optional } // DropPropertyGraph is DROP PROPERTY GRAPH statement node. From cb051d992a5a4d84b284d86a858c0a849f0b3476 Mon Sep 17 00:00:00 2001 From: apstndb <803393+apstndb@users.noreply.github.com> Date: Sun, 12 Jan 2025 00:44:16 +0900 Subject: [PATCH 11/13] Fix code styles --- ast/ast.go | 18 +++++++++++------- ast/pos.go | 4 ++-- parser.go | 4 ++-- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/ast/ast.go b/ast/ast.go index 342dc3b2..2bac23cd 100644 --- a/ast/ast.go +++ b/ast/ast.go @@ -3754,7 +3754,7 @@ type PropertyGraphLabelAndPropertiesList struct { // pos = LabelAndProperties[0].pos // end = LabelAndProperties[$].end - LabelAndProperties []*PropertyGraphLabelAndProperties + LabelAndProperties []*PropertyGraphLabelAndProperties // len(LabelAndProperties) > 0 } // PropertyGraphLabelAndProperties represents label and properties definition for a single label. @@ -3855,9 +3855,11 @@ type PropertyGraphDestinationKey struct { // // ({{.ColumnNameList | sqlJoin ", "}}) type PropertyGraphColumnNameList struct { - // pos = LParen - // end = RParen + 1 - LParen, RParen token.Pos + // pos = Lparen + // end = Rparen + 1 + + Lparen, Rparen token.Pos + ColumnNameList []*Ident } @@ -3878,8 +3880,9 @@ type PropertyGraphPropertiesAre struct { // pos = Properties // end = ExceptColumns.end || Columns + 7 - Properties token.Pos // position of "PROPERTIES" - Columns token.Pos // position of "COLUMNS" + Properties token.Pos // position of "PROPERTIES" + Columns token.Pos // position of "COLUMNS" + ExceptColumns *PropertyGraphColumnNameList // optional } @@ -3914,7 +3917,8 @@ type DropPropertyGraph struct { // pos = Drop // end = Name.end - Drop token.Pos + Drop token.Pos + IfExists bool Name *Ident } diff --git a/ast/pos.go b/ast/pos.go index 3d6941de..d370cc48 100644 --- a/ast/pos.go +++ b/ast/pos.go @@ -1943,11 +1943,11 @@ func (p *PropertyGraphDestinationKey) End() token.Pos { } func (p *PropertyGraphColumnNameList) Pos() token.Pos { - return p.LParen + return p.Lparen } func (p *PropertyGraphColumnNameList) End() token.Pos { - return posAdd(p.RParen, 1) + return posAdd(p.Rparen, 1) } func (p *PropertyGraphNoProperties) Pos() token.Pos { diff --git a/parser.go b/parser.go index b1355296..4f2c0a87 100644 --- a/parser.go +++ b/parser.go @@ -4740,8 +4740,8 @@ func (p *Parser) parsePropertyGraphColumnNameList() *ast.PropertyGraphColumnName rparen := p.expect(")").Pos return &ast.PropertyGraphColumnNameList{ - LParen: lparen, - RParen: rparen, + Lparen: lparen, + Rparen: rparen, ColumnNameList: list, } } From 6628a845da8cc548838a1472267105ff3b3d6db4 Mon Sep 17 00:00:00 2001 From: apstndb <803393+apstndb@users.noreply.github.com> Date: Sun, 12 Jan 2025 00:44:32 +0900 Subject: [PATCH 12/13] Update testdata --- ...ce_property_graph_fingraph_verbose.sql.txt | 36 +++++++++---------- ...perty_graph_if_not_exists_fingraph.sql.txt | 32 ++++++++--------- ...ce_property_graph_fingraph_verbose.sql.txt | 36 +++++++++---------- ...perty_graph_if_not_exists_fingraph.sql.txt | 32 ++++++++--------- 4 files changed, 68 insertions(+), 68 deletions(-) diff --git a/testdata/result/ddl/create_or_replace_property_graph_fingraph_verbose.sql.txt b/testdata/result/ddl/create_or_replace_property_graph_fingraph_verbose.sql.txt index 8e579cfa..4094102f 100644 --- a/testdata/result/ddl/create_or_replace_property_graph_fingraph_verbose.sql.txt +++ b/testdata/result/ddl/create_or_replace_property_graph_fingraph_verbose.sql.txt @@ -57,8 +57,8 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph Key: &ast.PropertyGraphElementKey{ Key: 104, Keys: &ast.PropertyGraphColumnNameList{ - LParen: 108, - RParen: 111, + Lparen: 108, + Rparen: 111, ColumnNameList: []*ast.Ident{ &ast.Ident{ NamePos: 109, @@ -137,8 +137,8 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph Properties: 577, Columns: 596, ExceptColumns: &ast.PropertyGraphColumnNameList{ - LParen: 611, - RParen: 616, + Lparen: 611, + Rparen: 616, ColumnNameList: []*ast.Ident{ &ast.Ident{ NamePos: 612, @@ -174,8 +174,8 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph Element: &ast.PropertyGraphElementKey{ Key: 703, Keys: &ast.PropertyGraphColumnNameList{ - LParen: 707, - RParen: 722, + Lparen: 707, + Rparen: 722, ColumnNameList: []*ast.Ident{ &ast.Ident{ NamePos: 708, @@ -193,8 +193,8 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph Source: &ast.PropertyGraphSourceKey{ Source: 730, Keys: &ast.PropertyGraphColumnNameList{ - LParen: 741, - RParen: 744, + Lparen: 741, + Rparen: 744, ColumnNameList: []*ast.Ident{ &ast.Ident{ NamePos: 742, @@ -212,8 +212,8 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph Destination: &ast.PropertyGraphDestinationKey{ Destination: 809, Keys: &ast.PropertyGraphColumnNameList{ - LParen: 825, - RParen: 836, + Lparen: 825, + Rparen: 836, ColumnNameList: []*ast.Ident{ &ast.Ident{ NamePos: 826, @@ -258,8 +258,8 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph Source: &ast.PropertyGraphSourceKey{ Source: 983, Keys: &ast.PropertyGraphColumnNameList{ - LParen: 994, - RParen: 997, + Lparen: 994, + Rparen: 997, ColumnNameList: []*ast.Ident{ &ast.Ident{ NamePos: 995, @@ -274,8 +274,8 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph Name: "Account", }, ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 1018, - RParen: 1021, + Lparen: 1018, + Rparen: 1021, ColumnNameList: []*ast.Ident{ &ast.Ident{ NamePos: 1019, @@ -288,8 +288,8 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph Destination: &ast.PropertyGraphDestinationKey{ Destination: 1043, Keys: &ast.PropertyGraphColumnNameList{ - LParen: 1059, - RParen: 1065, + Lparen: 1059, + Rparen: 1065, ColumnNameList: []*ast.Ident{ &ast.Ident{ NamePos: 1060, @@ -304,8 +304,8 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph Name: "Account", }, ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 1086, - RParen: 1089, + Lparen: 1086, + Rparen: 1089, ColumnNameList: []*ast.Ident{ &ast.Ident{ NamePos: 1087, diff --git a/testdata/result/ddl/create_property_graph_if_not_exists_fingraph.sql.txt b/testdata/result/ddl/create_property_graph_if_not_exists_fingraph.sql.txt index def1bf74..a0869e1f 100644 --- a/testdata/result/ddl/create_property_graph_if_not_exists_fingraph.sql.txt +++ b/testdata/result/ddl/create_property_graph_if_not_exists_fingraph.sql.txt @@ -62,8 +62,8 @@ CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph Source: &ast.PropertyGraphSourceKey{ Source: 132, Keys: &ast.PropertyGraphColumnNameList{ - LParen: 143, - RParen: 146, + Lparen: 143, + Rparen: 146, ColumnNameList: []*ast.Ident{ &ast.Ident{ NamePos: 144, @@ -78,8 +78,8 @@ CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph Name: "Person", }, ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 166, - RParen: 169, + Lparen: 166, + Rparen: 169, ColumnNameList: []*ast.Ident{ &ast.Ident{ NamePos: 167, @@ -92,8 +92,8 @@ CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph Destination: &ast.PropertyGraphDestinationKey{ Destination: 177, Keys: &ast.PropertyGraphColumnNameList{ - LParen: 193, - RParen: 204, + Lparen: 193, + Rparen: 204, ColumnNameList: []*ast.Ident{ &ast.Ident{ NamePos: 194, @@ -108,8 +108,8 @@ CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph Name: "Account", }, ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 225, - RParen: 228, + Lparen: 225, + Rparen: 228, ColumnNameList: []*ast.Ident{ &ast.Ident{ NamePos: 226, @@ -145,8 +145,8 @@ CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph Source: &ast.PropertyGraphSourceKey{ Source: 281, Keys: &ast.PropertyGraphColumnNameList{ - LParen: 292, - RParen: 295, + Lparen: 292, + Rparen: 295, ColumnNameList: []*ast.Ident{ &ast.Ident{ NamePos: 293, @@ -161,8 +161,8 @@ CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph Name: "Account", }, ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 316, - RParen: 319, + Lparen: 316, + Rparen: 319, ColumnNameList: []*ast.Ident{ &ast.Ident{ NamePos: 317, @@ -175,8 +175,8 @@ CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph Destination: &ast.PropertyGraphDestinationKey{ Destination: 327, Keys: &ast.PropertyGraphColumnNameList{ - LParen: 343, - RParen: 349, + Lparen: 343, + Rparen: 349, ColumnNameList: []*ast.Ident{ &ast.Ident{ NamePos: 344, @@ -191,8 +191,8 @@ CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph Name: "Account", }, ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 370, - RParen: 373, + Lparen: 370, + Rparen: 373, ColumnNameList: []*ast.Ident{ &ast.Ident{ NamePos: 371, diff --git a/testdata/result/statement/create_or_replace_property_graph_fingraph_verbose.sql.txt b/testdata/result/statement/create_or_replace_property_graph_fingraph_verbose.sql.txt index 8e579cfa..4094102f 100644 --- a/testdata/result/statement/create_or_replace_property_graph_fingraph_verbose.sql.txt +++ b/testdata/result/statement/create_or_replace_property_graph_fingraph_verbose.sql.txt @@ -57,8 +57,8 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph Key: &ast.PropertyGraphElementKey{ Key: 104, Keys: &ast.PropertyGraphColumnNameList{ - LParen: 108, - RParen: 111, + Lparen: 108, + Rparen: 111, ColumnNameList: []*ast.Ident{ &ast.Ident{ NamePos: 109, @@ -137,8 +137,8 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph Properties: 577, Columns: 596, ExceptColumns: &ast.PropertyGraphColumnNameList{ - LParen: 611, - RParen: 616, + Lparen: 611, + Rparen: 616, ColumnNameList: []*ast.Ident{ &ast.Ident{ NamePos: 612, @@ -174,8 +174,8 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph Element: &ast.PropertyGraphElementKey{ Key: 703, Keys: &ast.PropertyGraphColumnNameList{ - LParen: 707, - RParen: 722, + Lparen: 707, + Rparen: 722, ColumnNameList: []*ast.Ident{ &ast.Ident{ NamePos: 708, @@ -193,8 +193,8 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph Source: &ast.PropertyGraphSourceKey{ Source: 730, Keys: &ast.PropertyGraphColumnNameList{ - LParen: 741, - RParen: 744, + Lparen: 741, + Rparen: 744, ColumnNameList: []*ast.Ident{ &ast.Ident{ NamePos: 742, @@ -212,8 +212,8 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph Destination: &ast.PropertyGraphDestinationKey{ Destination: 809, Keys: &ast.PropertyGraphColumnNameList{ - LParen: 825, - RParen: 836, + Lparen: 825, + Rparen: 836, ColumnNameList: []*ast.Ident{ &ast.Ident{ NamePos: 826, @@ -258,8 +258,8 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph Source: &ast.PropertyGraphSourceKey{ Source: 983, Keys: &ast.PropertyGraphColumnNameList{ - LParen: 994, - RParen: 997, + Lparen: 994, + Rparen: 997, ColumnNameList: []*ast.Ident{ &ast.Ident{ NamePos: 995, @@ -274,8 +274,8 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph Name: "Account", }, ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 1018, - RParen: 1021, + Lparen: 1018, + Rparen: 1021, ColumnNameList: []*ast.Ident{ &ast.Ident{ NamePos: 1019, @@ -288,8 +288,8 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph Destination: &ast.PropertyGraphDestinationKey{ Destination: 1043, Keys: &ast.PropertyGraphColumnNameList{ - LParen: 1059, - RParen: 1065, + Lparen: 1059, + Rparen: 1065, ColumnNameList: []*ast.Ident{ &ast.Ident{ NamePos: 1060, @@ -304,8 +304,8 @@ CREATE OR REPLACE PROPERTY GRAPH FinGraph Name: "Account", }, ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 1086, - RParen: 1089, + Lparen: 1086, + Rparen: 1089, ColumnNameList: []*ast.Ident{ &ast.Ident{ NamePos: 1087, diff --git a/testdata/result/statement/create_property_graph_if_not_exists_fingraph.sql.txt b/testdata/result/statement/create_property_graph_if_not_exists_fingraph.sql.txt index def1bf74..a0869e1f 100644 --- a/testdata/result/statement/create_property_graph_if_not_exists_fingraph.sql.txt +++ b/testdata/result/statement/create_property_graph_if_not_exists_fingraph.sql.txt @@ -62,8 +62,8 @@ CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph Source: &ast.PropertyGraphSourceKey{ Source: 132, Keys: &ast.PropertyGraphColumnNameList{ - LParen: 143, - RParen: 146, + Lparen: 143, + Rparen: 146, ColumnNameList: []*ast.Ident{ &ast.Ident{ NamePos: 144, @@ -78,8 +78,8 @@ CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph Name: "Person", }, ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 166, - RParen: 169, + Lparen: 166, + Rparen: 169, ColumnNameList: []*ast.Ident{ &ast.Ident{ NamePos: 167, @@ -92,8 +92,8 @@ CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph Destination: &ast.PropertyGraphDestinationKey{ Destination: 177, Keys: &ast.PropertyGraphColumnNameList{ - LParen: 193, - RParen: 204, + Lparen: 193, + Rparen: 204, ColumnNameList: []*ast.Ident{ &ast.Ident{ NamePos: 194, @@ -108,8 +108,8 @@ CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph Name: "Account", }, ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 225, - RParen: 228, + Lparen: 225, + Rparen: 228, ColumnNameList: []*ast.Ident{ &ast.Ident{ NamePos: 226, @@ -145,8 +145,8 @@ CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph Source: &ast.PropertyGraphSourceKey{ Source: 281, Keys: &ast.PropertyGraphColumnNameList{ - LParen: 292, - RParen: 295, + Lparen: 292, + Rparen: 295, ColumnNameList: []*ast.Ident{ &ast.Ident{ NamePos: 293, @@ -161,8 +161,8 @@ CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph Name: "Account", }, ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 316, - RParen: 319, + Lparen: 316, + Rparen: 319, ColumnNameList: []*ast.Ident{ &ast.Ident{ NamePos: 317, @@ -175,8 +175,8 @@ CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph Destination: &ast.PropertyGraphDestinationKey{ Destination: 327, Keys: &ast.PropertyGraphColumnNameList{ - LParen: 343, - RParen: 349, + Lparen: 343, + Rparen: 349, ColumnNameList: []*ast.Ident{ &ast.Ident{ NamePos: 344, @@ -191,8 +191,8 @@ CREATE PROPERTY GRAPH IF NOT EXISTS FinGraph Name: "Account", }, ReferenceColumns: &ast.PropertyGraphColumnNameList{ - LParen: 370, - RParen: 373, + Lparen: 370, + Rparen: 373, ColumnNameList: []*ast.Ident{ &ast.Ident{ NamePos: 371, From 92ece9ebafbdf604888a4c23c2f626a0a99a6434 Mon Sep 17 00:00:00 2001 From: apstndb <803393+apstndb@users.noreply.github.com> Date: Sun, 12 Jan 2025 13:17:46 +0900 Subject: [PATCH 13/13] Update parser.go Co-authored-by: Hiroya Fujinami --- parser.go | 1 + 1 file changed, 1 insertion(+) diff --git a/parser.go b/parser.go index 4f2c0a87..821371af 100644 --- a/parser.go +++ b/parser.go @@ -4525,6 +4525,7 @@ func (p *Parser) parsePropertyGraphElementList() *ast.PropertyGraphElementList { } } + func (p *Parser) parsePropertyGraphElement() *ast.PropertyGraphElement { name := p.parseIdent()