aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwmin0 <wmin0@cobinhood.com>2019-01-22 17:43:50 +0800
committerJhih-Ming Huang <jm.huang@cobinhood.com>2019-05-06 10:44:03 +0800
commitd07af9fe6ba1299bec081b77d575d31a23a2f6e1 (patch)
treebb9fc3ae1aa0b3674a65174fe9812b3a97903c06
parentd25ee5f726545b165dba6a45def0e55027b6941b (diff)
downloaddexon-d07af9fe6ba1299bec081b77d575d31a23a2f6e1.tar.gz
dexon-d07af9fe6ba1299bec081b77d575d31a23a2f6e1.tar.zst
dexon-d07af9fe6ba1299bec081b77d575d31a23a2f6e1.zip
core: vm: sqlvm: remove optional interface and add print tag for detail
There are some changes in print ast utility. 1. instead of using optional interface to get detail, use reflect 2. implement a `print` field tag for printer switching detail mode or not
-rw-r--r--core/vm/sqlvm/ast/ast.go81
-rw-r--r--core/vm/sqlvm/ast/printer.go55
-rw-r--r--core/vm/sqlvm/cmd/ast-printer/main.go12
3 files changed, 49 insertions, 99 deletions
diff --git a/core/vm/sqlvm/ast/ast.go b/core/vm/sqlvm/ast/ast.go
index 61a990e20..654e778e4 100644
--- a/core/vm/sqlvm/ast/ast.go
+++ b/core/vm/sqlvm/ast/ast.go
@@ -239,29 +239,11 @@ 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{}
@@ -269,106 +251,53 @@ type OrderOptionNode struct {
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 }
+type InsertWithDefaultOptionNode struct{}
// PrimaryOptionNode is 'PRIMARY KEY' used in CREATE TABLE.
-type PrimaryOptionNode struct{ NilOptionNode }
+type PrimaryOptionNode struct{}
// NotNullOptionNode is 'NOT NULL' used in CREATE TABLE.
-type NotNullOptionNode struct{ NilOptionNode }
+type NotNullOptionNode struct{}
// UniqueOptionNode is 'UNIQUE' used in CREATE TABLE and CREATE INDEX.
-type UniqueOptionNode struct{ NilOptionNode }
+type UniqueOptionNode struct{}
// AutoIncrementOptionNode is 'AUTOINCREMENT' used in CREATE TABLE.
-type AutoIncrementOptionNode struct{ NilOptionNode }
+type AutoIncrementOptionNode struct{}
// 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
// ---------------------------------------------------------------------------
diff --git a/core/vm/sqlvm/ast/printer.go b/core/vm/sqlvm/ast/printer.go
index 25f04e863..e8c612637 100644
--- a/core/vm/sqlvm/ast/printer.go
+++ b/core/vm/sqlvm/ast/printer.go
@@ -3,10 +3,11 @@ package ast
import (
"fmt"
"reflect"
+ "unicode/utf8"
)
// PrintAST prints ast to stdout.
-func PrintAST(n interface{}, indent string) {
+func PrintAST(n interface{}, indent string, detail bool) {
if n == nil {
fmt.Printf("%snil\n", indent)
return
@@ -25,38 +26,28 @@ func PrintAST(n interface{}, indent string) {
}
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+" ")
+ PrintAST(op.GetTarget(), indent+" ", detail)
return
}
if op, ok := n.(BinaryOperator); ok {
fmt.Printf("%s%s:\n", indent, name)
fmt.Printf("%s Object:\n", indent)
- PrintAST(op.GetObject(), indent+" ")
+ PrintAST(op.GetObject(), indent+" ", detail)
fmt.Printf("%s Subject:\n", indent)
- PrintAST(op.GetSubject(), indent+" ")
+ PrintAST(op.GetSubject(), indent+" ", detail)
return
}
if arr, ok := n.([]interface{}); ok {
+ if len(arr) == 0 {
+ fmt.Printf("%s[]\n", indent)
+ return
+ }
fmt.Printf("%s[\n", indent)
for idx := range arr {
- PrintAST(arr[idx], indent+" ")
+ PrintAST(arr[idx], indent+" ", detail)
}
fmt.Printf("%s]\n", indent)
return
@@ -65,5 +56,29 @@ func PrintAST(n interface{}, indent string) {
fmt.Printf("%s%s: %s\n", indent, name, stringer.String())
return
}
- fmt.Printf("%s%s: %+v\n", indent, name, valueOf.Interface())
+ if typeOf.Kind() == reflect.Struct {
+ fmt.Printf("%s%s", indent, name)
+ l := typeOf.NumField()
+ if l == 0 {
+ fmt.Printf(" {}\n")
+ return
+ }
+ fmt.Printf(" {\n")
+ for i := 0; i < l; i++ {
+ if !detail && typeOf.Field(i).Tag.Get("print") == "-" {
+ continue
+ }
+ fmt.Printf("%s %s:\n", indent, typeOf.Field(i).Name)
+ PrintAST(valueOf.Field(i).Interface(), indent+" ", detail)
+ }
+ fmt.Printf("%s}\n", indent)
+ return
+ }
+ if bs, ok := n.([]byte); ok {
+ if utf8.Valid(bs) {
+ fmt.Printf("%s%s\n", indent, bs)
+ return
+ }
+ }
+ fmt.Printf("%s%+v\n", indent, valueOf.Interface())
}
diff --git a/core/vm/sqlvm/cmd/ast-printer/main.go b/core/vm/sqlvm/cmd/ast-printer/main.go
index 4911273c5..200f47173 100644
--- a/core/vm/sqlvm/cmd/ast-printer/main.go
+++ b/core/vm/sqlvm/cmd/ast-printer/main.go
@@ -1,17 +1,23 @@
package main
import (
+ "flag"
"fmt"
- "os"
"github.com/dexon-foundation/dexon/core/vm/sqlvm/ast"
"github.com/dexon-foundation/dexon/core/vm/sqlvm/parser"
)
func main() {
- n, err := parser.ParseString(os.Args[1])
+ var detail bool
+ flag.BoolVar(&detail, "detail", false, "print struct detail")
+
+ flag.Parse()
+
+ n, err := parser.ParseString(flag.Arg(0))
+ fmt.Printf("detail: %t\n", detail)
fmt.Printf("err: %+v\n", err)
if err == nil {
- ast.PrintAST(n, "")
+ ast.PrintAST(n, "", detail)
}
}