Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Spanner Graph(SQL/PGQ) schema statements #101

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
c41fae0
Bump Go version to 1.20, and add util.go
apstndb Sep 19, 2024
b818a86
Implement CREATE PROPERTY GRAPH and DROP PROPERTY GRAPH statements
apstndb Sep 19, 2024
52da535
Improve GQL schema statements
apstndb Sep 19, 2024
81b35e5
Improve tryParsePropertyGraphElementKeys
apstndb Sep 19, 2024
fdf5939
Clean up PropertyGraph*
apstndb Sep 19, 2024
c64b222
Bump Go version in .github/workflows
apstndb Sep 19, 2024
590202b
Merge branch 'main' into support-create-property-graph
apstndb Sep 21, 2024
264c013
Merge remote-tracking branch 'origin/main' into support-create-proper…
apstndb Oct 15, 2024
d294d67
Merge remote-tracking branch 'apstndb/support-create-property-graph' …
apstndb Oct 15, 2024
0d6cd02
Merge remote-tracking branch 'origin/main' into support-create-proper…
apstndb Oct 20, 2024
69f38b2
Update implementation of graph schema statements
apstndb Oct 20, 2024
252b4df
Update ast/ast_test.go
apstndb Oct 20, 2024
04d615b
Merge remote-tracking branch 'origin/main' into support-create-proper…
apstndb Oct 27, 2024
1742216
Merge remote-tracking branch 'origin/main' into support-create-proper…
apstndb Dec 18, 2024
65341ea
Merge remote-tracking branch 'origin/main' into support-create-proper…
apstndb Dec 20, 2024
9764cf8
Merge remote-tracking branch 'origin/main' into support-create-proper…
apstndb Jan 11, 2025
f8e6a56
Update to pass gen-ast-pos
apstndb Jan 11, 2025
88cb3ee
Add whitespace
apstndb Jan 11, 2025
cb051d9
Fix code styles
apstndb Jan 11, 2025
6628a84
Update testdata
apstndb Jan 11, 2025
92ece9e
Update parser.go
apstndb Jan 12, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Update implementation of graph schema statements
  • Loading branch information
apstndb committed Oct 20, 2024
commit 69f38b2f8f73930086147a747e2260e769bb8be6
160 changes: 89 additions & 71 deletions ast/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
}
Expand All @@ -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
}
Expand All @@ -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}}
Expand All @@ -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.
//
Expand All @@ -2576,7 +2608,7 @@ type PropertyGraphNodeElementKey struct {
// pos = PropertyGraphElementKey.pos
// end = PropertyGraphElementKey.end

PropertyGraphElementKey
Key PropertyGraphElementKey
}

// PropertyGraphEdgeElementKeys represents PropertyGraphSourceKey and PropertyGraphDestinationKey with optional PropertyGraphElementKey.
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
29 changes: 20 additions & 9 deletions ast/pos.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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() }
Expand All @@ -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 }
Expand All @@ -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() }
Expand Down
Loading
Loading