aboutsummaryrefslogtreecommitdiffstats
path: root/core/vm/sqlvm/ast
diff options
context:
space:
mode:
Diffstat (limited to 'core/vm/sqlvm/ast')
-rw-r--r--core/vm/sqlvm/ast/ast.go490
-rw-r--r--core/vm/sqlvm/ast/printer.go69
2 files changed, 559 insertions, 0 deletions
diff --git a/core/vm/sqlvm/ast/ast.go b/core/vm/sqlvm/ast/ast.go
new file mode 100644
index 000000000..61a990e20
--- /dev/null
+++ b/core/vm/sqlvm/ast/ast.go
@@ -0,0 +1,490 @@
+package ast
+
+import (
+ "github.com/shopspring/decimal"
+)
+
+// ---------------------------------------------------------------------------
+// Identifiers
+// ---------------------------------------------------------------------------
+
+// IdentifierNode references table, column, or function.
+type IdentifierNode struct {
+ Name []byte
+}
+
+// ---------------------------------------------------------------------------
+// Values
+// ---------------------------------------------------------------------------
+
+// Valuer defines the interface of a constant value.
+type Valuer interface {
+ Value() interface{}
+}
+
+// BoolValueNode is a boolean constant.
+type BoolValueNode struct {
+ V bool
+}
+
+// Value returns the value of BoolValueNode.
+func (n BoolValueNode) Value() interface{} { return n.V }
+
+// IntegerValueNode is an integer constant.
+type IntegerValueNode struct {
+ IsAddress bool
+ V decimal.Decimal
+}
+
+// Value returns the value of IntegerValueNode.
+func (n IntegerValueNode) Value() interface{} { return n.V }
+func (n IntegerValueNode) String() string { return n.V.String() }
+
+// DecimalValueNode is a number constant.
+type DecimalValueNode struct {
+ V decimal.Decimal
+}
+
+// Value returns the value of DecimalValueNode.
+func (n DecimalValueNode) Value() interface{} { return n.V }
+func (n DecimalValueNode) String() string { return n.V.String() }
+
+// BytesValueNode is a dynamic or fixed bytes constant.
+type BytesValueNode struct {
+ V []byte
+}
+
+// Value returns the value of BytesValueNode.
+func (n BytesValueNode) Value() interface{} { return n.V }
+func (n BytesValueNode) String() string { return string(n.V) }
+
+// AnyValueNode is '*' used in SELECT and function call.
+type AnyValueNode struct{}
+
+// Value returns itself.
+func (n AnyValueNode) Value() interface{} { return n }
+
+// DefaultValueNode represents the default value used in INSERT and UPDATE.
+type DefaultValueNode struct{}
+
+// Value returns itself.
+func (n DefaultValueNode) Value() interface{} { return n }
+
+// NullValueNode is NULL.
+type NullValueNode struct{}
+
+// Value returns itself.
+func (n NullValueNode) Value() interface{} { return n }
+
+// ---------------------------------------------------------------------------
+// Types
+// ---------------------------------------------------------------------------
+
+// IntTypeNode represents solidity int{X} and uint{X} types.
+type IntTypeNode struct {
+ Unsigned bool
+ Size uint32
+}
+
+// FixedTypeNode represents solidity fixed{M}x{N} and ufixed{M}x{N} types.
+type FixedTypeNode struct {
+ Unsigned bool
+ Size uint32
+ FractionalDigits uint32
+}
+
+// DynamicBytesTypeNode represents solidity bytes type.
+type DynamicBytesTypeNode struct{}
+
+// FixedBytesTypeNode represents solidity bytes{X} type.
+type FixedBytesTypeNode struct {
+ Size uint32
+}
+
+// AddressTypeNode represents solidity address type.
+type AddressTypeNode struct{}
+
+// BoolTypeNode represents solidity bool type.
+type BoolTypeNode struct{}
+
+// ---------------------------------------------------------------------------
+// Operators
+// ---------------------------------------------------------------------------
+
+// UnaryOperator defines the interface of a unary operator.
+type UnaryOperator interface {
+ GetTarget() interface{}
+ SetTarget(interface{})
+}
+
+// BinaryOperator defines the interface of a binary operator.
+type BinaryOperator interface {
+ GetObject() interface{}
+ GetSubject() interface{}
+ SetObject(interface{})
+ SetSubject(interface{})
+}
+
+// UnaryOperatorNode is a base struct of unary operators.
+type UnaryOperatorNode struct {
+ Target interface{}
+}
+
+// GetTarget gets the target of the operation.
+func (n UnaryOperatorNode) GetTarget() interface{} {
+ return n.Target
+}
+
+// SetTarget sets the target of the operation.
+func (n *UnaryOperatorNode) SetTarget(t interface{}) {
+ n.Target = t
+}
+
+// BinaryOperatorNode is a base struct of binary operators.
+type BinaryOperatorNode struct {
+ Object interface{}
+ Subject interface{}
+}
+
+// GetObject gets the node on which the operation is applied.
+func (n BinaryOperatorNode) GetObject() interface{} {
+ return n.Object
+}
+
+// GetSubject gets the node whose value is applied on the object.
+func (n BinaryOperatorNode) GetSubject() interface{} {
+ return n.Subject
+}
+
+// SetObject sets the object of the operation.
+func (n *BinaryOperatorNode) SetObject(o interface{}) {
+ n.Object = o
+}
+
+// SetSubject sets the subject of the operation.
+func (n *BinaryOperatorNode) SetSubject(s interface{}) {
+ n.Subject = s
+}
+
+// PosOperatorNode is '+'.
+type PosOperatorNode struct{ UnaryOperatorNode }
+
+// NegOperatorNode is '-'.
+type NegOperatorNode struct{ UnaryOperatorNode }
+
+// NotOperatorNode is 'NOT'.
+type NotOperatorNode struct{ UnaryOperatorNode }
+
+// AndOperatorNode is 'AND'.
+type AndOperatorNode struct{ BinaryOperatorNode }
+
+// OrOperatorNode is 'OR'.
+type OrOperatorNode struct{ BinaryOperatorNode }
+
+// GreaterOrEqualOperatorNode is '>='.
+type GreaterOrEqualOperatorNode struct{ BinaryOperatorNode }
+
+// LessOrEqualOperatorNode is '<='.
+type LessOrEqualOperatorNode struct{ BinaryOperatorNode }
+
+// NotEqualOperatorNode is '<>'.
+type NotEqualOperatorNode struct{ BinaryOperatorNode }
+
+// EqualOperatorNode is '=' used in expressions.
+type EqualOperatorNode struct{ BinaryOperatorNode }
+
+// GreaterOperatorNode is '>'.
+type GreaterOperatorNode struct{ BinaryOperatorNode }
+
+// LessOperatorNode is '<'.
+type LessOperatorNode struct{ BinaryOperatorNode }
+
+// ConcatOperatorNode is '||'.
+type ConcatOperatorNode struct{ BinaryOperatorNode }
+
+// AddOperatorNode is '+'.
+type AddOperatorNode struct{ BinaryOperatorNode }
+
+// SubOperatorNode is '-'.
+type SubOperatorNode struct{ BinaryOperatorNode }
+
+// MulOperatorNode is '*'.
+type MulOperatorNode struct{ BinaryOperatorNode }
+
+// DivOperatorNode is '/'.
+type DivOperatorNode struct{ BinaryOperatorNode }
+
+// ModOperatorNode is '%'.
+type ModOperatorNode struct{ BinaryOperatorNode }
+
+// InOperatorNode is 'IN'.
+type InOperatorNode struct{ BinaryOperatorNode }
+
+// IsOperatorNode is 'IS NULL'.
+type IsOperatorNode struct{ BinaryOperatorNode }
+
+// LikeOperatorNode is 'LIKE'.
+type LikeOperatorNode struct{ BinaryOperatorNode }
+
+// CastOperatorNode is 'CAST(expr AS type)'.
+type CastOperatorNode struct{ BinaryOperatorNode }
+
+// AssignOperatorNode is '=' used in UPDATE to set values.
+type AssignOperatorNode struct{ BinaryOperatorNode }
+
+// FunctionOperatorNode is a function call.
+type FunctionOperatorNode struct{ BinaryOperatorNode }
+
+// ---------------------------------------------------------------------------
+// Options
+// ---------------------------------------------------------------------------
+
+// Optional defines the interface for printing AST.
+type Optional interface {
+ GetOption() map[string]interface{}
+}
+
+// NilOptionNode is a base struct implementing Optional interface.
+type NilOptionNode struct{}
+
+// GetOption returns a value for printing AST.
+func (n NilOptionNode) GetOption() map[string]interface{} { return nil }
+
+// WhereOptionNode is 'WHERE' used in SELECT, UPDATE, DELETE.
+type WhereOptionNode struct {
+ Condition interface{}
+}
+
+// GetOption returns a value for printing AST.
+func (n WhereOptionNode) GetOption() map[string]interface{} {
+ return map[string]interface{}{
+ "Condition": n.Condition,
+ }
+}
+
+// OrderOptionNode is an expression in 'ORDER BY' used in SELECT.
+type OrderOptionNode struct {
+ Expr interface{}
+ Desc bool
+ NullsFirst bool
+}
+
+// GetOption returns a value for printing AST.
+func (n OrderOptionNode) GetOption() map[string]interface{} {
+ return map[string]interface{}{
+ "Expr": n.Expr,
+ "Desc": n.Desc,
+ "NullsFirst": n.NullsFirst,
+ }
+}
+
+// GroupOptionNode is 'GROUP BY' used in SELECT.
+type GroupOptionNode struct {
+ Expr interface{}
+}
+
+// GetOption returns a value for printing AST.
+func (n GroupOptionNode) GetOption() map[string]interface{} {
+ return map[string]interface{}{
+ "Expr": n.Expr,
+ }
+}
+
+// OffsetOptionNode is 'OFFSET' used in SELECT.
+type OffsetOptionNode struct {
+ Value IntegerValueNode
+}
+
+// GetOption returns a value for printing AST.
+func (n OffsetOptionNode) GetOption() map[string]interface{} {
+ return map[string]interface{}{
+ "Value": n.Value,
+ }
+}
+
+// LimitOptionNode is 'LIMIT' used in SELECT.
+type LimitOptionNode struct {
+ Value IntegerValueNode
+}
+
+// GetOption returns a value for printing AST.
+func (n LimitOptionNode) GetOption() map[string]interface{} {
+ return map[string]interface{}{
+ "Value": n.Value,
+ }
+}
+
+// InsertWithColumnOptionNode stores columns and values used in INSERT.
+type InsertWithColumnOptionNode struct {
+ Column []interface{}
+ Value []interface{}
+}
+
+// GetOption returns a value for printing AST.
+func (n InsertWithColumnOptionNode) GetOption() map[string]interface{} {
+ return map[string]interface{}{
+ "Column": n.Column,
+ "Value": n.Value,
+ }
+}
+
+// InsertWithDefaultOptionNode is 'DEFAULT VALUES' used in INSERT.
+type InsertWithDefaultOptionNode struct{ NilOptionNode }
+
+// PrimaryOptionNode is 'PRIMARY KEY' used in CREATE TABLE.
+type PrimaryOptionNode struct{ NilOptionNode }
+
+// NotNullOptionNode is 'NOT NULL' used in CREATE TABLE.
+type NotNullOptionNode struct{ NilOptionNode }
+
+// UniqueOptionNode is 'UNIQUE' used in CREATE TABLE and CREATE INDEX.
+type UniqueOptionNode struct{ NilOptionNode }
+
+// AutoIncrementOptionNode is 'AUTOINCREMENT' used in CREATE TABLE.
+type AutoIncrementOptionNode struct{ NilOptionNode }
+
+// DefaultOptionNode is 'DEFAULT' used in CREATE TABLE.
+type DefaultOptionNode struct {
+ Value interface{}
+}
+
+// GetOption returns a value for printing AST.
+func (n DefaultOptionNode) GetOption() map[string]interface{} {
+ return map[string]interface{}{
+ "Value": n.Value,
+ }
+}
+
+// ForeignOptionNode is 'REFERENCES' used in CREATE TABLE.
+type ForeignOptionNode struct {
+ Table IdentifierNode
+ Column IdentifierNode
+}
+
+// GetOption returns a value for printing AST.
+func (n ForeignOptionNode) GetOption() map[string]interface{} {
+ return map[string]interface{}{
+ "Table": n.Table,
+ "Column": n.Column,
+ }
+}
+
+// ---------------------------------------------------------------------------
+// Statements
+// ---------------------------------------------------------------------------
+
+// SelectStmtNode is SELECT.
+type SelectStmtNode struct {
+ Column []interface{}
+ Table *IdentifierNode
+ Where *WhereOptionNode
+ Group []interface{}
+ Order []interface{}
+ Limit *LimitOptionNode
+ Offset *OffsetOptionNode
+}
+
+// GetOption returns a value for printing AST.
+func (n SelectStmtNode) GetOption() map[string]interface{} {
+ return map[string]interface{}{
+ "Column": n.Column,
+ "Table": n.Table,
+ "Where": n.Where,
+ "Group": n.Group,
+ "Order": n.Order,
+ "Limit": n.Limit,
+ "Offset": n.Offset,
+ }
+}
+
+// UpdateStmtNode is UPDATE.
+type UpdateStmtNode struct {
+ Table IdentifierNode
+ Assignment []interface{}
+ Where *WhereOptionNode
+}
+
+// GetOption returns a value for printing AST.
+func (n UpdateStmtNode) GetOption() map[string]interface{} {
+ return map[string]interface{}{
+ "Table": n.Table,
+ "Assignment": n.Assignment,
+ "Where": n.Where,
+ }
+}
+
+// DeleteStmtNode is DELETE.
+type DeleteStmtNode struct {
+ Table IdentifierNode
+ Where *WhereOptionNode
+}
+
+// GetOption returns a value for printing AST.
+func (n DeleteStmtNode) GetOption() map[string]interface{} {
+ return map[string]interface{}{
+ "Table": n.Table,
+ "Where": n.Where,
+ }
+}
+
+// InsertStmtNode is INSERT.
+type InsertStmtNode struct {
+ Table IdentifierNode
+ Insert interface{}
+}
+
+// GetOption returns a value for printing AST.
+func (n InsertStmtNode) GetOption() map[string]interface{} {
+ return map[string]interface{}{
+ "Table": n.Table,
+ "Insert": n.Insert,
+ }
+}
+
+// CreateTableStmtNode is CREATE TABLE.
+type CreateTableStmtNode struct {
+ Table IdentifierNode
+ Column []interface{}
+}
+
+// GetOption returns a value for printing AST.
+func (n CreateTableStmtNode) GetOption() map[string]interface{} {
+ return map[string]interface{}{
+ "Table": n.Table,
+ "Column": n.Column,
+ }
+}
+
+// ColumnSchemaNode specifies a column in CREATE TABLE.
+type ColumnSchemaNode struct {
+ Column IdentifierNode
+ DataType interface{}
+ Constraint []interface{}
+}
+
+// GetOption returns a value for printing AST.
+func (n ColumnSchemaNode) GetOption() map[string]interface{} {
+ return map[string]interface{}{
+ "Column": n.Column,
+ "DataYype": n.DataType,
+ "Constraint": n.Constraint,
+ }
+}
+
+// CreateIndexStmtNode is CREATE INDEX.
+type CreateIndexStmtNode struct {
+ Index IdentifierNode
+ Table IdentifierNode
+ Column []interface{}
+ Unique *UniqueOptionNode
+}
+
+// GetOption returns a value for printing AST.
+func (n CreateIndexStmtNode) GetOption() map[string]interface{} {
+ return map[string]interface{}{
+ "Index": n.Index,
+ "Table": n.Table,
+ "Column": n.Column,
+ "Unique": n.Unique,
+ }
+}
diff --git a/core/vm/sqlvm/ast/printer.go b/core/vm/sqlvm/ast/printer.go
new file mode 100644
index 000000000..25f04e863
--- /dev/null
+++ b/core/vm/sqlvm/ast/printer.go
@@ -0,0 +1,69 @@
+package ast
+
+import (
+ "fmt"
+ "reflect"
+)
+
+// PrintAST prints ast to stdout.
+func PrintAST(n interface{}, indent string) {
+ if n == nil {
+ fmt.Printf("%snil\n", indent)
+ return
+ }
+ typeOf := reflect.TypeOf(n)
+ valueOf := reflect.ValueOf(n)
+ name := ""
+ if typeOf.Kind() == reflect.Ptr {
+ if valueOf.IsNil() {
+ fmt.Printf("%snil\n", indent)
+ return
+ }
+ name = "*"
+ valueOf = valueOf.Elem()
+ typeOf = typeOf.Elem()
+ }
+ name = name + typeOf.Name()
+
+ if op, ok := n.(Optional); ok {
+ fmt.Printf("%s%s", indent, name)
+ m := op.GetOption()
+ if m == nil {
+ fmt.Printf("\n")
+ return
+ }
+ fmt.Printf(":\n")
+ for k := range m {
+ fmt.Printf("%s %s:\n", indent, k)
+ PrintAST(m[k], indent+" ")
+ }
+ return
+ }
+ if op, ok := n.(UnaryOperator); ok {
+ fmt.Printf("%s%s:\n", indent, name)
+ fmt.Printf("%s Target:\n", indent)
+ PrintAST(op.GetTarget(), indent+" ")
+ return
+ }
+ if op, ok := n.(BinaryOperator); ok {
+ fmt.Printf("%s%s:\n", indent, name)
+ fmt.Printf("%s Object:\n", indent)
+ PrintAST(op.GetObject(), indent+" ")
+ fmt.Printf("%s Subject:\n", indent)
+ PrintAST(op.GetSubject(), indent+" ")
+ return
+ }
+ if arr, ok := n.([]interface{}); ok {
+ fmt.Printf("%s[\n", indent)
+ for idx := range arr {
+ PrintAST(arr[idx], indent+" ")
+ }
+ fmt.Printf("%s]\n", indent)
+ return
+ }
+ if stringer, ok := n.(fmt.Stringer); ok {
+ fmt.Printf("%s%s: %s\n", indent, name, stringer.String())
+ return
+ }
+ fmt.Printf("%s%s: %+v\n", indent, name, valueOf.Interface())
+}