diff --git a/cmd/db-server/main.go b/cmd/db-server/main.go
index 0bd06cdec8501fc780590c003c46f8e9ae706e48..6c00a34731eff07bc17d82e5cca76a4cf86187bc 100644
--- a/cmd/db-server/main.go
+++ b/cmd/db-server/main.go
@@ -59,14 +59,14 @@ func cleanup() {
 }
 
 func main() {
-	if len(os.Args) < 2{
-		fmt.Printf("Usage: %s configFile")
+	if len(os.Args) < 2 {
+		fmt.Printf("Usage: %s configFile", os.Args[0])
 		os.Exit(-1)
 	}
 	flag.Parse()
 	config.InitializeConfig(*configPath, *configCheck, *configStrict, reloadConfig, overrideConfig)
 	config.GlobalSystemVariables.LoadInitialValues()
-	config.LoadvarsConfigFromFile(os.Args[1],&config.GlobalSystemVariables)
+	config.LoadvarsConfigFromFile(os.Args[1], &config.GlobalSystemVariables)
 	createServer()
 	registerSignalHandlers()
 	runServer()
diff --git a/go.mod b/go.mod
index 4b4f27ba9999b347795207bbe3546bac5adbd443..c996275758c1da7dbb1afc74f57db20d0debf1d0 100644
--- a/go.mod
+++ b/go.mod
@@ -5,16 +5,10 @@ go 1.15
 require (
 	github.com/BurntSushi/toml v0.3.1
 	github.com/aws/aws-sdk-go v1.37.14
-	github.com/blacktear23/go-proxyprotocol v0.0.0-20180807104634-af7a81e8dd0d
+	github.com/cockroachdb/pebble v0.0.0-20210526183633-dd2a545f5d75 // indirect
 	github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548
-	github.com/fagongzi/goetty v2.0.2+incompatible
-	github.com/fagongzi/util v0.0.0-20201116094402-221cc40c4593
 	github.com/frankban/quicktest v1.11.3 // indirect
-	github.com/go-sql-driver/mysql v1.5.0 // indirect
-	github.com/gogo/protobuf v1.3.2
-	github.com/golang/protobuf v1.5.2 // indirect
-	github.com/google/uuid v1.2.0 // indirect
-	github.com/klauspost/compress v1.11.7 // indirect
+	github.com/google/uuid v1.2.0
 	github.com/pierrec/lz4 v2.6.0+incompatible
 	github.com/pilosa/pilosa v1.4.0
 	github.com/pingcap/check v0.0.0-20190102082844-67f458068fc8
@@ -25,5 +19,5 @@ require (
 	github.com/traetox/goaio v0.0.0-20171005222435-46641abceb17
 	go.uber.org/zap v1.15.0
 	golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f
-	golang.org/x/text v0.3.3 // indirect
+	golang.org/x/tools v0.0.0-20201105001634-bc3cf281b174 // indirect
 )
diff --git a/pkg/config/config.toml b/pkg/config/config.toml
new file mode 100644
index 0000000000000000000000000000000000000000..e79411e031253506282f7a448e310beca5ae5e59
--- /dev/null
+++ b/pkg/config/config.toml
@@ -0,0 +1,139 @@
+
+# Code generated by tool; DO NOT EDIT.
+
+
+	
+#	Name:	boolSet1
+#	Scope:	[global]
+#	Access:	[file]
+#	DataType:	bool
+#	DomainType:	set
+#	Values:	[true]
+#	Comment:	boolSet1
+#	UpdateMode:	dynamic
+	boolSet1=true
+
+
+	
+#	Name:	boolSet2
+#	Scope:	[global]
+#	Access:	[file]
+#	DataType:	bool
+#	DomainType:	set
+#	Values:	[false]
+#	Comment:	boolSet2
+#	UpdateMode:	hotload
+	boolSet2=false
+
+
+	
+#	Name:	boolSet3
+#	Scope:	[global]
+#	Access:	[file]
+#	DataType:	bool
+#	DomainType:	set
+#	Values:	[]
+#	Comment:	boolSet3
+#	UpdateMode:	dynamic
+	boolSet3= false
+
+
+	
+#	Name:	stringSet1
+#	Scope:	[global]
+#	Access:	[file]
+#	DataType:	string
+#	DomainType:	set
+#	Values:	[ss1 ss2 ss3]
+#	Comment:	stringSet1
+#	UpdateMode:	dynamic
+	stringSet1= "ss1"
+
+
+	
+#	Name:	stringSet2
+#	Scope:	[global]
+#	Access:	[file]
+#	DataType:	string
+#	DomainType:	set
+#	Values:	[]
+#	Comment:	stringSet2
+#	UpdateMode:	dynamic
+	stringSet2= ""
+
+
+	
+#	Name:	int64set1
+#	Scope:	[global]
+#	Access:	[file]
+#	DataType:	int64
+#	DomainType:	set
+#	Values:	[1 2 3 4 5 6]
+#	Comment:	int64Set1
+#	UpdateMode:	dynamic
+	int64set1=1
+
+
+
+
+	
+#	Name:	int64set3
+#	Scope:	[global]
+#	Access:	[file]
+#	DataType:	int64
+#	DomainType:	set
+#	Values:	[]
+#	Comment:	int64Set3
+#	UpdateMode:	dynamic
+	int64set3= 0
+
+
+	
+#	Name:	int64Range1
+#	Scope:	[global]
+#	Access:	[file]
+#	DataType:	int64
+#	DomainType:	range
+#	Values:	[1000 0 10000]
+#	Comment:	int64Range1
+#	UpdateMode:	dynamic
+	int64Range1=1000
+
+
+	
+#	Name:	float64set1
+#	Scope:	[global]
+#	Access:	[file]
+#	DataType:	float64
+#	DomainType:	set
+#	Values:	[1.0 2.0 3.0 4.00 5.0 6.0]
+#	Comment:	float64Set1
+#	UpdateMode:	dynamic
+	float64set1=1.0
+
+
+
+
+	
+#	Name:	float64set3
+#	Scope:	[global]
+#	Access:	[file]
+#	DataType:	float64
+#	DomainType:	set
+#	Values:	[]
+#	Comment:	float64Set3
+#	UpdateMode:	dynamic
+	float64set3= 0.0
+
+
+	
+#	Name:	float64Range1
+#	Scope:	[global]
+#	Access:	[file]
+#	DataType:	float64
+#	DomainType:	range
+#	Values:	[1000.01 0.02 10000.03]
+#	Comment:	float64Range1
+#	UpdateMode:	dynamic
+	float64Range1=1000.01
+
diff --git a/pkg/config/config_template.go b/pkg/config/config_template.go
index 492305ea30de28b03fdd327cdd2b9b089d0701c1..a690502358bf030016b787a89a6d4ba86d3d1a15 100644
--- a/pkg/config/config_template.go
+++ b/pkg/config/config_template.go
@@ -1338,6 +1338,25 @@ func (cfgi *ConfigurationFileGeneratorImpl) Generate() error {
 	return nil
 }
 
+/**
+load items from configuration file periodly.
+ */
+type ConfigurationFileHotLoader interface {
+	/**
+	register a configuration file into the loader.
+	path : the path of the configuration file
+	period: load the configration every period
+	configObject: the target that will be updated
+	 */
+	Register(path string,period int64,configObject interface{})
+
+	/**
+	unregister a configuration file from the loader.
+	the configuration file will be loaded again.
+	 */
+	Unregister(path string)
+}
+
 func NewConfigurationFileGenerator(defFileName string)ConfigurationFileGenerator{
 	return &ConfigurationFileGeneratorImpl{
 		parameterDefinitionFileName: defFileName,
diff --git a/pkg/config/config_template_test.go b/pkg/config/config_template_test.go
index 8d05b1e3bf87be76e9652c89f7599f3d0b1f0500..3f08f7b775f5769d71abfbd0fa11e643cceaf36d 100644
--- a/pkg/config/config_template_test.go
+++ b/pkg/config/config_template_test.go
@@ -12,14 +12,14 @@ import (
 )
 
 type par struct {
-	Name     string 	`toml:"Name"`
+	Name string `toml:"Name"`
 }
 type Pars struct {
 	Par []par
 }
 
 func TestToml(t *testing.T) {
-	blob :=`
+	blob := `
 		[[par]]
 		Name = "Thunder Road"
 		
@@ -37,14 +37,14 @@ func TestToml(t *testing.T) {
 	}
 }
 
-func compareArray(A,B []string)bool{
-	if len(A) != len(B){
+func compareArray(A, B []string) bool {
+	if len(A) != len(B) {
 		return false
 	}
 
 	sort.Strings(A)
 	sort.Strings(B)
-	for i:=0; i < len(A);i++{
+	for i := 0; i < len(A); i++ {
 		if A[i] != B[i] {
 			return false
 		}
@@ -75,67 +75,67 @@ func TestParameter(t *testing.T) {
 		update-mode = "fix"
 		`
 	var results = map[string]parameter{
-		"autocommit":parameter{
-				Name : "autocommit",
-				Scope : []string{"global", "session"},
-				Access : []string{"file"},
-				DataType: "bool",
-				DomainType : "set",
-				Values: []string{"true"},
-				Comment : "autocommit",
-				UpdateMode:"dynamic",
-			},
-		"back-log":parameter{
-			Name : "back-log",
-			Scope : []string{"global"},
-			Access : []string{"file"},
-			DataType: "int64",
-			DomainType : "range",
-			Values : []string{"-1","1","65535"},
-			Comment : "back-log",
-			UpdateMode:"fix",
+		"autocommit": parameter{
+			Name:       "autocommit",
+			Scope:      []string{"global", "session"},
+			Access:     []string{"file"},
+			DataType:   "bool",
+			DomainType: "set",
+			Values:     []string{"true"},
+			Comment:    "autocommit",
+			UpdateMode: "dynamic",
+		},
+		"back-log": parameter{
+			Name:       "back-log",
+			Scope:      []string{"global"},
+			Access:     []string{"file"},
+			DataType:   "int64",
+			DomainType: "range",
+			Values:     []string{"-1", "1", "65535"},
+			Comment:    "back-log",
+			UpdateMode: "fix",
 		},
 	}
 	var paras parameters
 	if metadata, err := toml.Decode(blob, &paras); err != nil {
 		t.Errorf("error:%v \n", err)
-	}else if undecoded := metadata.Undecoded() ; len(undecoded) > 0 && err == nil{
+	} else if undecoded := metadata.Undecoded(); len(undecoded) > 0 && err == nil {
 		for _, item := range undecoded {
-			t.Errorf("undecoded %s\n",item.String())
+			t.Errorf("undecoded %s\n", item.String())
 		}
 	}
 
 	for _, p := range paras.Parameter {
 		par := results[p.Name]
 		if p.Name != par.Name ||
-			!compareArray(p.Scope , par.Scope) ||
-			!compareArray(p.Access , par.Access) ||
+			!compareArray(p.Scope, par.Scope) ||
+			!compareArray(p.Access, par.Access) ||
 			p.DataType != par.DataType ||
 			p.DomainType != par.DomainType ||
-			!compareArray(p.Values,par.Values) ||
+			!compareArray(p.Values, par.Values) ||
 			p.Comment != par.Comment ||
-			p.UpdateMode != par.UpdateMode{
-				t.Errorf("toml decode parameter failed.")
-			}
+			p.UpdateMode != par.UpdateMode {
+			t.Errorf("toml decode parameter failed.")
+		}
 	}
 }
 
 func Test_isAsciiChar(t *testing.T) {
 	cases := [][]byte{
-		{'a', 'j','z', 'A','J', 'Z','_'},
-		{'<','=','>','+','{','[','@',0,' ','~'},
+		{'a', 'j', 'z', 'A', 'J', 'Z', '_'},
+		{'<', '=', '>', '+', '{', '[', '@', 0, ' ', '~'},
 	}
 
-	results :=[]bool{
+	results := []bool{
 		true,
 		false,
 	}
 
-	for i:=0; i < len(results);i++{
-		for _, x := range cases[i]{
+	for i := 0; i < len(results); i++ {
+		for _, x := range cases[i] {
 			r := isAsciiChar(x)
-			if r != results[i]{
-				t.Errorf("isAsciiChar failed. %d %c %v %v",i,x,r,results[i])
+			if r != results[i] {
+				t.Errorf("isAsciiChar failed. %d %c %v %v", i, x, r, results[i])
 				return
 			}
 		}
@@ -144,20 +144,20 @@ func Test_isAsciiChar(t *testing.T) {
 
 func Test_isAsciiDigit(t *testing.T) {
 	cases := [][]byte{
-		{'0', '1','7', '8','9'},
-		{'<','=','>','+','{','[','@',0,' ','~','/',':'},
+		{'0', '1', '7', '8', '9'},
+		{'<', '=', '>', '+', '{', '[', '@', 0, ' ', '~', '/', ':'},
 	}
 
-	results :=[]bool{
+	results := []bool{
 		true,
 		false,
 	}
 
-	for i:=0; i < len(results);i++{
-		for _, x := range cases[i]{
+	for i := 0; i < len(results); i++ {
+		for _, x := range cases[i] {
 			r := isAsciiDigit(x)
-			if r != results[i]{
-				t.Errorf("isAsciiDigit failed. %d %c %v %v",i,x,r,results[i])
+			if r != results[i] {
+				t.Errorf("isAsciiDigit failed. %d %c %v %v", i, x, r, results[i])
 				return
 			}
 		}
@@ -166,19 +166,19 @@ func Test_isAsciiDigit(t *testing.T) {
 
 func Test_isGoIdentifier(t *testing.T) {
 	cases := [][]string{
-		{"a", "j","z", "_"},
-		{"A","J", "Z"},
-		{"<","=",">","+","{","[","@","0"," ","~",""},
-		{"a0", "j0","z0", "_0"},
-		{"A0","J0", "Z0"},
-		{"a<", "j<","z<", "_<"},
-		{"A<","J<", "Z<"},
-		{"ap", "jp","zp", "_p"},
-		{"Ap","Jp", "Zp"},
-		{"pA","pJ", "pZ"},
-	}
-
-	results :=[]bool{
+		{"a", "j", "z", "_"},
+		{"A", "J", "Z"},
+		{"<", "=", ">", "+", "{", "[", "@", "0", " ", "~", ""},
+		{"a0", "j0", "z0", "_0"},
+		{"A0", "J0", "Z0"},
+		{"a<", "j<", "z<", "_<"},
+		{"A<", "J<", "Z<"},
+		{"ap", "jp", "zp", "_p"},
+		{"Ap", "Jp", "Zp"},
+		{"pA", "pJ", "pZ"},
+	}
+
+	results := []bool{
 		true,
 		false,
 		false,
@@ -191,11 +191,11 @@ func Test_isGoIdentifier(t *testing.T) {
 		true,
 	}
 
-	for i:=0; i < len(results);i++{
-		for _, x := range cases[i]{
+	for i := 0; i < len(results); i++ {
+		for _, x := range cases[i] {
 			r := isGoIdentifier(x)
-			if r != results[i]{
-				t.Errorf("isGoIdentifier failed. %d %s %v %v",i,x,r,results[i])
+			if r != results[i] {
+				t.Errorf("isGoIdentifier failed. %d %s %v %v", i, x, r, results[i])
 				return
 			}
 		}
@@ -204,19 +204,19 @@ func Test_isGoIdentifier(t *testing.T) {
 
 func Test_isGoStructAndInterfaceIdentifier(t *testing.T) {
 	cases := [][]string{
-		{"a", "j","z", "_"},
-		{"A","J", "Z"},
-		{"<","=",">","+","{","[","@","0"," ","~",""},
-		{"a0", "j0","z0", "_0"},
-		{"A0","J0", "Z0"},
-		{"a<", "j<","z<", "_<"},
-		{"A<","J<", "Z<"},
-		{"ap", "jp","zp", "_p"},
-		{"Ap","Jp", "Zp"},
-		{"pA","pJ", "pZ"},
-	}
-
-	results :=[]bool{
+		{"a", "j", "z", "_"},
+		{"A", "J", "Z"},
+		{"<", "=", ">", "+", "{", "[", "@", "0", " ", "~", ""},
+		{"a0", "j0", "z0", "_0"},
+		{"A0", "J0", "Z0"},
+		{"a<", "j<", "z<", "_<"},
+		{"A<", "J<", "Z<"},
+		{"ap", "jp", "zp", "_p"},
+		{"Ap", "Jp", "Zp"},
+		{"pA", "pJ", "pZ"},
+	}
+
+	results := []bool{
 		true,
 		true,
 		false,
@@ -229,44 +229,44 @@ func Test_isGoStructAndInterfaceIdentifier(t *testing.T) {
 		true,
 	}
 
-	for i:=0; i < len(results);i++{
-		for _, x := range cases[i]{
+	for i := 0; i < len(results); i++ {
+		for _, x := range cases[i] {
 			r := isGoStructAndInterfaceIdentifier(x)
-			if r != results[i]{
-				t.Errorf("isGoIdentifier failed. %d %s %v %v",i,x,r,results[i])
+			if r != results[i] {
+				t.Errorf("isGoIdentifier failed. %d %s %v %v", i, x, r, results[i])
 				return
 			}
 		}
 	}
 }
 
-func Test_isSubset(t *testing.T){
+func Test_isSubset(t *testing.T) {
 	A := [][]string{
-		{"a","b","c"},
+		{"a", "b", "c"},
 		{},
-		{"a","a"},
-		{"a","e"},
-		{"a","b","c","e"},
-		{"a","b"},
-		{"b","c"},
-		{"a","c"},
+		{"a", "a"},
+		{"a", "e"},
+		{"a", "b", "c", "e"},
+		{"a", "b"},
+		{"b", "c"},
+		{"a", "c"},
 		{"a"},
 		{"b"},
 		{"c"},
 	}
 
 	B := [][]string{
-		{"a","b","c"},
-		{"a","b","c"},
-		{"a","b","c"},
-		{"a","b","c"},
-		{"a","b","c"},
-		{"a","b","c"},
-		{"a","b","c"},
-		{"a","b","c"},
-		{"a","b","c"},
-		{"a","b","c"},
-		{"a","b","c"},
+		{"a", "b", "c"},
+		{"a", "b", "c"},
+		{"a", "b", "c"},
+		{"a", "b", "c"},
+		{"a", "b", "c"},
+		{"a", "b", "c"},
+		{"a", "b", "c"},
+		{"a", "b", "c"},
+		{"a", "b", "c"},
+		{"a", "b", "c"},
+		{"a", "b", "c"},
 	}
 
 	results := []bool{
@@ -283,25 +283,25 @@ func Test_isSubset(t *testing.T){
 		true,
 	}
 
-	for i:=0; i < len(results);i++{
-		r := isSubset(A[i],B[i])
-		if r != results[i]{
-			t.Errorf("isSubset failed. %d %s %s %v %v",i,A[i],B[i],r,results[i])
+	for i := 0; i < len(results); i++ {
+		r := isSubset(A[i], B[i])
+		if r != results[i] {
+			t.Errorf("isSubset failed. %d %s %s %v %v", i, A[i], B[i], r, results[i])
 			return
 		}
 	}
 }
 
-func Test_isScope(t *testing.T){
+func Test_isScope(t *testing.T) {
 	A := [][]string{
-		{"session","global","c"},
+		{"session", "global", "c"},
 		{},
-		{"session","session"},
-		{"session","e"},
-		{"session","global","c","e"},
-		{"session","global"},
-		{"global","c"},
-		{"session","c"},
+		{"session", "session"},
+		{"session", "e"},
+		{"session", "global", "c", "e"},
+		{"session", "global"},
+		{"global", "c"},
+		{"session", "c"},
 		{"session"},
 		{"global"},
 		{"c"},
@@ -321,25 +321,25 @@ func Test_isScope(t *testing.T){
 		false,
 	}
 
-	for i:=0; i < len(results);i++{
+	for i := 0; i < len(results); i++ {
 		r := isScope(A[i])
-		if r != results[i]{
-			t.Errorf("isScope failed. %d %s %v %v",i,A[i],r,results[i])
+		if r != results[i] {
+			t.Errorf("isScope failed. %d %s %v %v", i, A[i], r, results[i])
 			return
 		}
 	}
 }
 
-func Test_isAccess(t *testing.T){
+func Test_isAccess(t *testing.T) {
 	A := [][]string{
-		{"cmd","file","c"},
+		{"cmd", "file", "c"},
 		{},
-		{"cmd","cmd"},
-		{"cmd","e"},
-		{"cmd","file","c","e"},
-		{"cmd","file"},
-		{"file","c"},
-		{"cmd","c"},
+		{"cmd", "cmd"},
+		{"cmd", "e"},
+		{"cmd", "file", "c", "e"},
+		{"cmd", "file"},
+		{"file", "c"},
+		{"cmd", "c"},
 		{"cmd"},
 		{"file"},
 		{"c"},
@@ -359,19 +359,19 @@ func Test_isAccess(t *testing.T){
 		false,
 	}
 
-	for i:=0; i < len(results);i++{
+	for i := 0; i < len(results); i++ {
 		r := isAccess(A[i])
-		if r != results[i]{
-			t.Errorf("isAccess failed. %d %s %v %v",i,A[i],r,results[i])
+		if r != results[i] {
+			t.Errorf("isAccess failed. %d %s %v %v", i, A[i], r, results[i])
 			return
 		}
 	}
 }
 
-func Test_isDataType(t *testing.T){
+func Test_isDataType(t *testing.T) {
 	A := []string{
 		"string", "int64", "float64", "bool",
-		"A","B","C","D",
+		"A", "B", "C", "D",
 	}
 
 	results := []bool{
@@ -385,20 +385,20 @@ func Test_isDataType(t *testing.T){
 		false,
 	}
 
-	for i:=0; i < len(results);i++{
+	for i := 0; i < len(results); i++ {
 		r := isDataType(A[i])
-		if r != results[i]{
-			t.Errorf("isDataType failed. %d %s %v %v",i,A[i],r,results[i])
+		if r != results[i] {
+			t.Errorf("isDataType failed. %d %s %v %v", i, A[i], r, results[i])
 			return
 		}
 	}
 }
 
-func Test_isDomainType(t *testing.T){
+func Test_isDomainType(t *testing.T) {
 	A := []string{
-		"set","range",
+		"set", "range",
 		"string", "int64", "float64", "bool",
-		"A","B","C","D",
+		"A", "B", "C", "D",
 	}
 
 	results := []bool{
@@ -414,97 +414,97 @@ func Test_isDomainType(t *testing.T){
 		false,
 	}
 
-	for i:=0; i < len(results);i++{
+	for i := 0; i < len(results); i++ {
 		r := isDomainType(A[i])
-		if r != results[i]{
-			t.Errorf("isDataType failed. %d %s %v %v",i,A[i],r,results[i])
+		if r != results[i] {
+			t.Errorf("isDataType failed. %d %s %v %v", i, A[i], r, results[i])
 			return
 		}
 	}
 }
 
 type valueCase struct {
-	dataType string
+	dataType   string
 	domainType string
-	values []string
+	values     []string
 }
 
-func Test_checkValues(t *testing.T){
+func Test_checkValues(t *testing.T) {
 	A := []valueCase{
 		//string
-		{"string","set",[]string{}},
-		{"string","set",[]string{"A"}},
-		{"string","set",[]string{"A","A"}},
-		{"string","set",[]string{"A","A","B","C"}},
-		{"string","set",[]string{"A","B","C"}},
-
-		{"string","range",[]string{}},
-		{"string","range",[]string{"A"}},
-		{"string","range",[]string{"A","A"}},
-		{"string","range",[]string{"A","A","B","C"}},
-		{"string","range",[]string{"A","B","C"}},
+		{"string", "set", []string{}},
+		{"string", "set", []string{"A"}},
+		{"string", "set", []string{"A", "A"}},
+		{"string", "set", []string{"A", "A", "B", "C"}},
+		{"string", "set", []string{"A", "B", "C"}},
+
+		{"string", "range", []string{}},
+		{"string", "range", []string{"A"}},
+		{"string", "range", []string{"A", "A"}},
+		{"string", "range", []string{"A", "A", "B", "C"}},
+		{"string", "range", []string{"A", "B", "C"}},
 
 		//int64
-		{"int64","set",[]string{}},
-		{"int64","set",[]string{"A"}},
-		{"int64","set",[]string{"A","A"}},
-		{"int64","set",[]string{"A","A","B","C"}},
-		{"int64","set",[]string{"A","B","C"}},
-
-		{"int64","set",[]string{"0"}},
-		{"int64","set",[]string{"0","0"}},
-		{"int64","set",[]string{"0","0","1","C"}},
-		{"int64","set",[]string{"0","1","2"}},
-		{"int64","set",[]string{"0","1","2","0"}},
-
-		{"int64","range",[]string{"0"}},
-		{"int64","range",[]string{"0","1"}},
-		{"int64","range",[]string{"0","1","2"}},
-		{"int64","range",[]string{"1","0","2"}},
-		{"int64","range",[]string{"3","1","2"}},
-		{"int64","range",[]string{"5","1","9"}},
+		{"int64", "set", []string{}},
+		{"int64", "set", []string{"A"}},
+		{"int64", "set", []string{"A", "A"}},
+		{"int64", "set", []string{"A", "A", "B", "C"}},
+		{"int64", "set", []string{"A", "B", "C"}},
+
+		{"int64", "set", []string{"0"}},
+		{"int64", "set", []string{"0", "0"}},
+		{"int64", "set", []string{"0", "0", "1", "C"}},
+		{"int64", "set", []string{"0", "1", "2"}},
+		{"int64", "set", []string{"0", "1", "2", "0"}},
+
+		{"int64", "range", []string{"0"}},
+		{"int64", "range", []string{"0", "1"}},
+		{"int64", "range", []string{"0", "1", "2"}},
+		{"int64", "range", []string{"1", "0", "2"}},
+		{"int64", "range", []string{"3", "1", "2"}},
+		{"int64", "range", []string{"5", "1", "9"}},
 
 		//float64
-		{"float64","set",[]string{}},
-		{"float64","set",[]string{"A"}},
-		{"float64","set",[]string{"A","A"}},
-		{"float64","set",[]string{"A","A","B","C"}},
-		{"float64","set",[]string{"A","B","C"}},
-
-		{"float64","set",[]string{"0.1"}},
-		{"float64","set",[]string{"0.1","0.1"}},
-		{"float64","set",[]string{"0","0","1","C"}},
-		{"float64","set",[]string{"0","1","2"}},
-		{"float64","set",[]string{"0","1","2","0"}},
-
-		{"float64","range",[]string{"0"}},
-		{"float64","range",[]string{"0","1"}},
-		{"float64","range",[]string{"0","1","2"}},
-		{"float64","range",[]string{"1","0","2"}},
-		{"float64","range",[]string{"3","1","2"}},
-		{"float64","range",[]string{"5","1","9"}},
+		{"float64", "set", []string{}},
+		{"float64", "set", []string{"A"}},
+		{"float64", "set", []string{"A", "A"}},
+		{"float64", "set", []string{"A", "A", "B", "C"}},
+		{"float64", "set", []string{"A", "B", "C"}},
+
+		{"float64", "set", []string{"0.1"}},
+		{"float64", "set", []string{"0.1", "0.1"}},
+		{"float64", "set", []string{"0", "0", "1", "C"}},
+		{"float64", "set", []string{"0", "1", "2"}},
+		{"float64", "set", []string{"0", "1", "2", "0"}},
+
+		{"float64", "range", []string{"0"}},
+		{"float64", "range", []string{"0", "1"}},
+		{"float64", "range", []string{"0", "1", "2"}},
+		{"float64", "range", []string{"1", "0", "2"}},
+		{"float64", "range", []string{"3", "1", "2"}},
+		{"float64", "range", []string{"5", "1", "9"}},
 
 		//bool
-		{"bool","set",[]string{}},
-		{"bool","set",[]string{"A"}},
-		{"bool","set",[]string{"A","A"}},
-		{"bool","set",[]string{"A","A","B","C"}},
-		{"bool","set",[]string{"A","B","C"}},
-
-		{"bool","set",[]string{"0.1"}},
-		{"bool","set",[]string{"false"}},
-		{"bool","set",[]string{"off"}},
-		{"bool","set",[]string{"true"}},
-		{"bool","set",[]string{"on"}},
-
-		{"bool","range",[]string{"0","1","2","0"}},
-		{"bool","set",[]string{"FALSE"}},
-		{"bool","set",[]string{"OFF"}},
-		{"bool","set",[]string{"TRUE"}},
-		{"bool","set",[]string{"ON"}},
+		{"bool", "set", []string{}},
+		{"bool", "set", []string{"A"}},
+		{"bool", "set", []string{"A", "A"}},
+		{"bool", "set", []string{"A", "A", "B", "C"}},
+		{"bool", "set", []string{"A", "B", "C"}},
+
+		{"bool", "set", []string{"0.1"}},
+		{"bool", "set", []string{"false"}},
+		{"bool", "set", []string{"off"}},
+		{"bool", "set", []string{"true"}},
+		{"bool", "set", []string{"on"}},
+
+		{"bool", "range", []string{"0", "1", "2", "0"}},
+		{"bool", "set", []string{"FALSE"}},
+		{"bool", "set", []string{"OFF"}},
+		{"bool", "set", []string{"TRUE"}},
+		{"bool", "set", []string{"ON"}},
 
 		//x
-		{"x","set",[]string{"FALSE"}},
+		{"x", "set", []string{"FALSE"}},
 	}
 
 	results := []bool{
@@ -584,10 +584,10 @@ func Test_checkValues(t *testing.T){
 		false,
 	}
 
-	for i:=0; i < len(results);i++{
-		r := checkValues(A[i].dataType,A[i].domainType,A[i].values)
-		if r != results[i]{
-			t.Errorf("checkValues failed. %d %s %v %v",i,A[i],r,results[i])
+	for i := 0; i < len(results); i++ {
+		r := checkValues(A[i].dataType, A[i].domainType, A[i].values)
+		if r != results[i] {
+			t.Errorf("checkValues failed. %d %s %v %v", i, A[i], r, results[i])
 			return
 		}
 	}
@@ -602,11 +602,11 @@ func Test_hasDuplicateValue(t *testing.T) {
 		args args
 		want bool
 	}{
-		{"t1",args{[]string{"A","B","A"}},true},
-		{"t2",args{[]string{"A","B","C"}},false},
-		{"t3",args{[]string{"A"}},false},
-		{"t4",args{[]string{"A","A"}},true},
-		{"t5",args{[]string{}},false},
+		{"t1", args{[]string{"A", "B", "A"}}, true},
+		{"t2", args{[]string{"A", "B", "C"}}, false},
+		{"t3", args{[]string{"A"}}, false},
+		{"t4", args{[]string{"A", "A"}}, true},
+		{"t5", args{[]string{}}, false},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
@@ -626,11 +626,11 @@ func Test_hasDuplicateValueInt64(t *testing.T) {
 		args args
 		want bool
 	}{
-		{"t1",args{[]int64{0,1,0}},true},
-		{"t2",args{[]int64{0,1,2}},false},
-		{"t3",args{[]int64{0}},false},
-		{"t4",args{[]int64{0,0}},true},
-		{"t5",args{[]int64{}},false},
+		{"t1", args{[]int64{0, 1, 0}}, true},
+		{"t2", args{[]int64{0, 1, 2}}, false},
+		{"t3", args{[]int64{0}}, false},
+		{"t4", args{[]int64{0, 0}}, true},
+		{"t5", args{[]int64{}}, false},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
@@ -650,11 +650,11 @@ func Test_hasDuplicateValueFloat64(t *testing.T) {
 		args args
 		want bool
 	}{
-		{"t1",args{[]float64{0,1,0}},true},
-		{"t2",args{[]float64{0,1,2}},false},
-		{"t3",args{[]float64{0}},false},
-		{"t4",args{[]float64{0,0}},true},
-		{"t5",args{[]float64{}},false},
+		{"t1", args{[]float64{0, 1, 0}}, true},
+		{"t2", args{[]float64{0, 1, 2}}, false},
+		{"t3", args{[]float64{0}}, false},
+		{"t4", args{[]float64{0, 0}}, true},
+		{"t5", args{[]float64{}}, false},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
@@ -674,8 +674,8 @@ func Test_parameters_LoadParametersDefinition(t *testing.T) {
 		args    args
 		wantErr bool
 	}{
-		{"t1",args{"test/t1.toml"},false},
-		{"t2",args{"test/t2.toml"},true},
+		{"t1", args{"test/t1.toml"}, false},
+		{"t2", args{"test/t2.toml"}, true},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
@@ -691,6 +691,8 @@ func Test_parameters_LoadParametersDefinitionFromString(t *testing.T) {
 	t1 := `
 		parameter-struct-name = "AllParameters"
 		config-struct-name = "configuration"
+		operation-file-name = "parameters"
+		config-file-name = "config"
 
 		[[parameter]]
 		name = "autocommit"
@@ -705,6 +707,8 @@ func Test_parameters_LoadParametersDefinitionFromString(t *testing.T) {
 	t2 := `
 parameter-struct-name = "AllParameters"
 config-struct-name = "configuration"
+operation-file-name = "parameters"
+config-file-name = "config"
 
 		[[parameter]]
 		name = "autocommit@"
@@ -719,6 +723,8 @@ config-struct-name = "configuration"
 	t3 := `
 parameter-struct-name = "AllParameters"
 config-struct-name = "configuration"
+operation-file-name = "parameters"
+config-file-name = "config"
 
 		[[parameter]]
 		name = "autocommit"
@@ -733,6 +739,8 @@ config-struct-name = "configuration"
 	t4 := `
 parameter-struct-name = "AllParameters"
 config-struct-name = "configuration"
+operation-file-name = "parameters"
+config-file-name = "config"
 
 		[[parameter]]
 		name = "autocommit"
@@ -747,6 +755,8 @@ config-struct-name = "configuration"
 	t5 := `
 parameter-struct-name = "AllParameters"
 config-struct-name = "configuration"
+operation-file-name = "parameters"
+config-file-name = "config"
 
 		[[parameter]]
 		name = "autocommit"
@@ -761,6 +771,8 @@ config-struct-name = "configuration"
 	t6 := `
 parameter-struct-name = "AllParameters"
 config-struct-name = "configuration"
+operation-file-name = "parameters"
+config-file-name = "config"
 
 		[[parameter]]
 		name = "autocommit"
@@ -775,6 +787,8 @@ config-struct-name = "configuration"
 	t7 := `
 parameter-struct-name = "AllParameters"
 config-struct-name = "configuration"
+operation-file-name = "parameters"
+config-file-name = "config"
 
 		[[parameter]]
 		name = "count"
@@ -789,6 +803,8 @@ config-struct-name = "configuration"
 	t8 := `
 parameter-struct-name = "AllParameters"
 config-struct-name = "configuration"
+operation-file-name = "parameters"
+config-file-name = "config"
 
 		[[parameter]]
 		name = "count"
@@ -811,9 +827,11 @@ config-struct-name = "configuration"
 		update-mode = "fix"
 `
 
-	t9 :=`
+	t9 := `
 parameter-struct-name = "AllParameters"
 config-struct-name = "configuration"
+operation-file-name = "parameters"
+config-file-name = "config"
 
 		[[parameter]]
 		name = "boolset1"
@@ -826,9 +844,11 @@ config-struct-name = "configuration"
 		update-mode = "dynamic"
 `
 
-	t10 :=`
+	t10 := `
 parameter-struct-name = "AllParameters"
 config-struct-name = "configuration"
+operation-file-name = "parameters"
+config-file-name = "config"
 
 		[[parameter]]
 		name = "int64set1"
@@ -841,9 +861,11 @@ config-struct-name = "configuration"
 		update-mode = "dynamic"
 `
 
-	t11 :=`
+	t11 := `
 parameter-struct-name = "AllParameters"
 config-struct-name = "configuration"
+operation-file-name = "parameters"
+config-file-name = "config"
 
 		[[parameter]]
 		name = "float64set1"
@@ -856,9 +878,11 @@ config-struct-name = "configuration"
 		update-mode = "dynamic"
 `
 
-	t12 :=`
+	t12 := `
 parameter-struct-name = "AllParameters"
 config-struct-name = "configuration"
+operation-file-name = "parameters"
+config-file-name = "config"
 
 		[[parameter]]
 		name = "stringset1"
@@ -878,18 +902,18 @@ config-struct-name = "configuration"
 		args    args
 		wantErr bool
 	}{
-		{"t1",args{t1},false},
-		{"t2",args{t2},true},
-		{"t3",args{t3},true},
-		{"t4",args{t4},true},
-		{"t5",args{t5},true},
-		{"t6",args{t6},false},
-		{"t7",args{t7},false},
-		{"t8",args{t8},true},
-		{"t9",args{t9},false},
-		{"t10",args{t10},false},
-		{"t11",args{t11},false},
-		{"t12",args{t12},false},
+		{"t1", args{t1}, false},
+		{"t2", args{t2}, true},
+		{"t3", args{t3}, true},
+		{"t4", args{t4}, true},
+		{"t5", args{t5}, true},
+		{"t6", args{t6}, false},
+		{"t7", args{t7}, false},
+		{"t8", args{t8}, true},
+		{"t9", args{t9}, false},
+		{"t10", args{t10}, false},
+		{"t11", args{t11}, false},
+		{"t12", args{t12}, false},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
@@ -906,7 +930,7 @@ type Inventory struct {
 	Count    uint
 }
 
-var tmplStr =  `
+var tmplStr = `
 // Code generated by tool; DO NOT EDIT.
 package config
 
@@ -941,7 +965,7 @@ type {{.ConfigurationStructName}} struct{
 	{{ printf "/**\n\tName:\t%s\n\tScope:\t%s\n\tAccess:\t%s\n\tDataType:\t%s\n\tDomainType:\t%s\n\tValues:\t%s\n\tComment:\t%s\n\tUpdateMode:\t%s\n\t*/"  
 			.Name .Scope .Access .DataType .DomainType .Values .Comment .UpdateMode
 	}}
-	{{ printf "%s    %s  `+"`toml:"+`\"%s\"`+"`"+`" .CapitalName .DataType .Name }}
+	{{ printf "%s    %s  ` + "`toml:" + `\"%s\"` + "`" + `" .CapitalName .DataType .Name }}
 
 	{{end}}
 {{end}}
@@ -1296,13 +1320,13 @@ func (ap * {{.ParameterStructName}} ) UpdateParametersWithConfiguration(config *
 }
 `
 
-func Test_template(t *testing.T){
+func Test_template(t *testing.T) {
 	var paras = parameters{
-		ParameterStructName: "AllParameters",
+		ParameterStructName:     "AllParameters",
 		ConfigurationStructName: "configuration",
 		Parameter: []parameter{
 			{
-				Name: "boolSet1",
+				Name:       "boolSet1",
 				Scope:      []string{"global", "session"},
 				Access:     []string{"file"},
 				DataType:   "bool",
@@ -1312,7 +1336,7 @@ func Test_template(t *testing.T){
 				UpdateMode: "dynamic",
 			},
 			{
-				Name: "boolRange1",
+				Name:       "boolRange1",
 				Scope:      []string{"global", "session"},
 				Access:     []string{"file"},
 				DataType:   "bool",
@@ -1322,97 +1346,97 @@ func Test_template(t *testing.T){
 				UpdateMode: "dynamic",
 			},
 			{
-				Name: "stringSet1",
+				Name:       "stringSet1",
 				Scope:      []string{"global"},
 				Access:     []string{"file"},
 				DataType:   "string",
 				DomainType: "set",
-				Values:     []string{"localhost","127.0.0.1",},
+				Values:     []string{"localhost", "127.0.0.1"},
 				Comment:    "stringSet1",
 				UpdateMode: "dynamic",
 			},
 			{
-				Name: "stringRange1",
+				Name:       "stringRange1",
 				Scope:      []string{"global"},
 				Access:     []string{"file"},
 				DataType:   "string",
 				DomainType: "range",
-				Values:     []string{"localhost","127.0.0.1",},
+				Values:     []string{"localhost", "127.0.0.1"},
 				Comment:    "stringRange1",
 				UpdateMode: "dynamic",
 			},
 			{
-				Name: "int64set1",
+				Name:       "int64set1",
 				Scope:      []string{"global"},
 				Access:     []string{"file"},
 				DataType:   "int64",
 				DomainType: "set",
-				Values:     []string{"-1","2","65535"},
+				Values:     []string{"-1", "2", "65535"},
 				Comment:    "int64set1",
 				UpdateMode: "dynamic",
 			},
 			{
-				Name: "int64range1",
+				Name:       "int64range1",
 				Scope:      []string{"global"},
 				Access:     []string{"file"},
 				DataType:   "int64",
 				DomainType: "range",
-				Values:     []string{"-1","-1","65535"},
+				Values:     []string{"-1", "-1", "65535"},
 				Comment:    "int64range1",
 				UpdateMode: "dynamic",
 			},
 			{
-				Name: "int64X1",
+				Name:       "int64X1",
 				Scope:      []string{"global"},
 				Access:     []string{"file"},
 				DataType:   "int64",
 				DomainType: "X",
-				Values:     []string{"-1","-1","65535"},
+				Values:     []string{"-1", "-1", "65535"},
 				Comment:    "int64X1",
 				UpdateMode: "dynamic",
 			},
 			{
-				Name: "float64set1",
+				Name:       "float64set1",
 				Scope:      []string{"global"},
 				Access:     []string{"file"},
 				DataType:   "float64",
 				DomainType: "set",
-				Values:     []string{"-1.01","2.02","65535.03"},
+				Values:     []string{"-1.01", "2.02", "65535.03"},
 				Comment:    "float64set1",
 				UpdateMode: "dynamic",
 			},
 			{
-				Name: "float64range1",
+				Name:       "float64range1",
 				Scope:      []string{"global"},
 				Access:     []string{"file"},
 				DataType:   "float64",
 				DomainType: "range",
-				Values:     []string{"-2.02","-1.01","65535.03"},
+				Values:     []string{"-2.02", "-1.01", "65535.03"},
 				Comment:    "float64range1",
 				UpdateMode: "dynamic",
 			},
 			{
-				Name: "float64X1",
+				Name:       "float64X1",
 				Scope:      []string{"global"},
 				Access:     []string{"file"},
 				DataType:   "float64",
 				DomainType: "X",
-				Values:     []string{"-1","-1","65535"},
+				Values:     []string{"-1", "-1", "65535"},
 				Comment:    "float64X1",
 				UpdateMode: "dynamic",
 			},
 			{
-				Name: "float64set2",
+				Name:       "float64set2",
 				Scope:      []string{"global"},
 				Access:     []string{"file"},
 				DataType:   "float64",
 				DomainType: "set",
-				Values:     []string{"-1","-1","65535"},
+				Values:     []string{"-1", "-1", "65535"},
 				Comment:    "float64set2",
 				UpdateMode: "fix",
 			},
 			{
-				Name: "boolSet2",
+				Name:       "boolSet2",
 				Scope:      []string{"global", "session"},
 				Access:     []string{"file"},
 				DataType:   "bool",
@@ -1422,7 +1446,7 @@ func Test_template(t *testing.T){
 				UpdateMode: "dynamic",
 			},
 			{
-				Name: "boolSet3",
+				Name:       "boolSet3",
 				Scope:      []string{"global", "session"},
 				Access:     []string{"file"},
 				DataType:   "bool",
@@ -1434,7 +1458,7 @@ func Test_template(t *testing.T){
 		},
 	}
 
-	for i :=0; i<len(paras.Parameter);i++{
+	for i := 0; i < len(paras.Parameter); i++ {
 		p := paras.Parameter[i].Name
 		capName := p
 		capName = string(unicode.ToUpper(rune(p[0]))) + p[1:]
@@ -1442,19 +1466,23 @@ func Test_template(t *testing.T){
 	}
 
 	tmpl, err := template.New("test").Parse(tmplStr)
-	if err != nil { panic(err) }
+	if err != nil {
+		panic(err)
+	}
 
 	f, err := os.Create("parameters.go")
-	if err != nil{
+	if err != nil {
 		panic(err)
 	}
 	defer f.Close()
 
 	err = tmpl.Execute(f, paras)
-	if err != nil { panic(err) }
+	if err != nil {
+		panic(err)
+	}
 }
 
-var tomlTmplString=`
+var tomlTmplString = `
 # Code generated by tool; DO NOT EDIT.
 {{range $index,$param := .Parameter}}
 {{ if ne .UpdateMode "fix"}}
@@ -1485,7 +1513,7 @@ var tomlTmplString=`
 {{end}}
 `
 
-var testOperationTmpl=`
+var testOperationTmpl = `
 // Code generated by tool; DO NOT EDIT.
 package config
 
@@ -1515,7 +1543,7 @@ func is{{.ConfigurationStructName}}Equal(c1,c2 {{.ConfigurationStructName}}) boo
 }
 
 func Test_{{.ConfigurationStructName}}_LoadConfigurationFromString(t *testing.T) {
-	t1 := `+"`"+`
+	t1 := ` + "`" + `
 {{range $index,$param := .Parameter}}
 {{ if ne .UpdateMode "fix"}}
 	{{- with $count := len .Values -}}
@@ -1539,7 +1567,7 @@ func Test_{{.ConfigurationStructName}}_LoadConfigurationFromString(t *testing.T)
 	{{- end -}}
 {{end}}
 {{end}}		
-`+"`"+`
+` + "`" + `
 	t1_config:={{.ConfigurationStructName}}{
 		rwlock:            sync.RWMutex{},
 
@@ -1609,7 +1637,7 @@ func Test_{{.ConfigurationStructName}}_LoadConfigurationFromString(t *testing.T)
 }
 `
 
-func Test_ParameterDefinitionAndTemplate2(t *testing.T){
+func Test_ParameterDefinitionAndTemplate2(t *testing.T) {
 	t1 := `
 		parameter-struct-name = "AllParameters"
 		config-struct-name = "configuration"
@@ -1798,7 +1826,7 @@ func Test_ParameterDefinitionAndTemplate2(t *testing.T){
 		update-mode = "fix"
 `
 
-	t5 :=`
+	t5 := `
 		parameter-struct-name = "AllParameters"
 		config-struct-name = "configuration"
 		operation-file-name = "parameters"
@@ -1832,7 +1860,7 @@ func Test_ParameterDefinitionAndTemplate2(t *testing.T){
 		update-mode = "fix"
 `
 
-	t7 :=`
+	t7 := `
 		parameter-struct-name = "AllParameters"
 		config-struct-name = "configuration"
 		operation-file-name = "parameters"
@@ -1849,7 +1877,7 @@ func Test_ParameterDefinitionAndTemplate2(t *testing.T){
 		update-mode = "dynamic"
 `
 
-	t8 :=`
+	t8 := `
 		parameter-struct-name = "AllParameters"
 		config-struct-name = "configuration"
 		operation-file-name = "parameters"
@@ -1873,14 +1901,14 @@ func Test_ParameterDefinitionAndTemplate2(t *testing.T){
 		args    args
 		wantErr bool
 	}{
-		{"t1",args{t1},false},
-		{"t2",args{t2},true},
-		{"t3",args{t3},true},
-		{"t4",args{t4},true},
-		{"t5",args{t5},true},
-		{"t6",args{t6},true},
-		{"t7",args{t7},true},
-		{"t8",args{t8},true},
+		{"t1", args{t1}, false},
+		{"t2", args{t2}, true},
+		{"t3", args{t3}, true},
+		{"t4", args{t4}, true},
+		{"t5", args{t5}, true},
+		{"t6", args{t6}, true},
+		{"t7", args{t7}, true},
+		{"t8", args{t8}, true},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
@@ -1888,54 +1916,65 @@ func Test_ParameterDefinitionAndTemplate2(t *testing.T){
 			if err := params.LoadParametersDefinitionFromString(tt.args.input); (err != nil) != tt.wantErr {
 				t.Errorf("LoadParametersDefinitionFromString() error = %v, wantErr %v", err, tt.wantErr)
 				return
-			}else if err!=nil{
+			} else if err != nil {
 				return
 			}
 
 			tmpl, err := template.New("test").Parse(tmplStr)
-			if err != nil { panic(err) }
+			if err != nil {
+				panic(err)
+			}
 
 			f, err := os.Create("parameters.go")
-			if err != nil{
+			if err != nil {
 				panic(err)
 			}
 			defer f.Close()
 
 			err = tmpl.Execute(f, params)
-			if err != nil { panic(err) }
+			if err != nil {
+				panic(err)
+			}
 
-			tomlTmpl,err := template.New("toml").Parse(tomlTmplString)
-			if err != nil { panic(err)}
+			tomlTmpl, err := template.New("toml").Parse(tomlTmplString)
+			if err != nil {
+				panic(err)
+			}
 
-			tomlf,err := os.Create("config.toml")
-			if err!= nil{
+			tomlf, err := os.Create("config.toml")
+			if err != nil {
 				panic(err)
 			}
 			defer tomlf.Close()
 
-			err = tomlTmpl.Execute(tomlf,params)
-			if err != nil { panic(err) }
+			err = tomlTmpl.Execute(tomlf, params)
+			if err != nil {
+				panic(err)
+			}
 
-			testTmpl,err := template.New("genTest").Parse(testOperationTmpl)
-			if err != nil { panic(err)}
+			testTmpl, err := template.New("genTest").Parse(testOperationTmpl)
+			if err != nil {
+				panic(err)
+			}
 
-			testf,err := os.Create("parameters_test.go")
-			if err!= nil{
+			testf, err := os.Create("parameters_test.go")
+			if err != nil {
 				panic(err)
 			}
 			defer testf.Close()
 
-			err = testTmpl.Execute(testf,params)
-			if err != nil { panic(err) }
+			err = testTmpl.Execute(testf, params)
+			if err != nil {
+				panic(err)
+			}
 
 		})
 	}
 
-
 }
 
 func Test_String(t *testing.T) {
-	fmt.Printf("%s \n","`toml:\"name\"`")
+	fmt.Printf("%s \n", "`toml:\"name\"`")
 }
 
 func TestNewConfigurationFileGenerator(t *testing.T) {
@@ -1943,20 +1982,20 @@ func TestNewConfigurationFileGenerator(t *testing.T) {
 		defFileName string
 	}
 	tests := []struct {
-		name string
-		args args
+		name    string
+		args    args
 		wantErr bool
 	}{
-		{"t1",args{"test/def1.toml"},false},
-		{"t2",args{"test/def2.toml"},false},
-		{"t3",args{"system_vars_def.toml"},false},
+		{"t1", args{"test/def1.toml"}, false},
+		{"t2", args{"test/def2.toml"}, false},
+		{"t3", args{"system_vars_def.toml"}, false},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			gen := NewConfigurationFileGenerator(tt.args.defFileName)
-			if err := gen.Generate(); (err!=nil) != tt.wantErr {
+			if err := gen.Generate(); (err != nil) != tt.wantErr {
 				t.Errorf("Generator() = %v, want %v", err, tt.wantErr)
 			}
 		})
 	}
-}
\ No newline at end of file
+}
diff --git a/pkg/config/parameters.go b/pkg/config/parameters.go
new file mode 100644
index 0000000000000000000000000000000000000000..83c45a4b4c946c5620b4963d3f9bfd0041236556
--- /dev/null
+++ b/pkg/config/parameters.go
@@ -0,0 +1,1317 @@
+// Code generated by tool; DO NOT EDIT.
+package config
+
+import (
+	"fmt"
+	"github.com/BurntSushi/toml"
+	"sync"
+)
+
+//all parameters in the system
+type AllParameters struct {
+	//read and write lock
+	rwlock sync.RWMutex
+
+	/**
+	Name:	boolSet1
+	Scope:	[global]
+	Access:	[file]
+	DataType:	bool
+	DomainType:	set
+	Values:	[true]
+	Comment:	boolSet1
+	UpdateMode:	dynamic
+	*/
+	boolSet1 bool
+
+	/**
+	Name:	boolSet2
+	Scope:	[global]
+	Access:	[file]
+	DataType:	bool
+	DomainType:	set
+	Values:	[false]
+	Comment:	boolSet2
+	UpdateMode:	hotload
+	*/
+	boolSet2 bool
+
+	/**
+	Name:	boolSet3
+	Scope:	[global]
+	Access:	[file]
+	DataType:	bool
+	DomainType:	set
+	Values:	[]
+	Comment:	boolSet3
+	UpdateMode:	dynamic
+	*/
+	boolSet3 bool
+
+	/**
+	Name:	stringSet1
+	Scope:	[global]
+	Access:	[file]
+	DataType:	string
+	DomainType:	set
+	Values:	[ss1 ss2 ss3]
+	Comment:	stringSet1
+	UpdateMode:	dynamic
+	*/
+	stringSet1 string
+
+	/**
+	Name:	stringSet2
+	Scope:	[global]
+	Access:	[file]
+	DataType:	string
+	DomainType:	set
+	Values:	[]
+	Comment:	stringSet2
+	UpdateMode:	dynamic
+	*/
+	stringSet2 string
+
+	/**
+	Name:	int64set1
+	Scope:	[global]
+	Access:	[file]
+	DataType:	int64
+	DomainType:	set
+	Values:	[1 2 3 4 5 6]
+	Comment:	int64Set1
+	UpdateMode:	dynamic
+	*/
+	int64set1 int64
+
+	/**
+	Name:	int64set2
+	Scope:	[global]
+	Access:	[file]
+	DataType:	int64
+	DomainType:	set
+	Values:	[1 3 5 7]
+	Comment:	int64Set2
+	UpdateMode:	fix
+	*/
+	int64set2 int64
+
+	/**
+	Name:	int64set3
+	Scope:	[global]
+	Access:	[file]
+	DataType:	int64
+	DomainType:	set
+	Values:	[]
+	Comment:	int64Set3
+	UpdateMode:	dynamic
+	*/
+	int64set3 int64
+
+	/**
+	Name:	int64Range1
+	Scope:	[global]
+	Access:	[file]
+	DataType:	int64
+	DomainType:	range
+	Values:	[1000 0 10000]
+	Comment:	int64Range1
+	UpdateMode:	dynamic
+	*/
+	int64Range1 int64
+
+	/**
+	Name:	float64set1
+	Scope:	[global]
+	Access:	[file]
+	DataType:	float64
+	DomainType:	set
+	Values:	[1.0 2.0 3.0 4.00 5.0 6.0]
+	Comment:	float64Set1
+	UpdateMode:	dynamic
+	*/
+	float64set1 float64
+
+	/**
+	Name:	float64set2
+	Scope:	[global]
+	Access:	[file]
+	DataType:	float64
+	DomainType:	set
+	Values:	[1.001 3.003 5.005 7.007]
+	Comment:	float64Set2
+	UpdateMode:	fix
+	*/
+	float64set2 float64
+
+	/**
+	Name:	float64set3
+	Scope:	[global]
+	Access:	[file]
+	DataType:	float64
+	DomainType:	set
+	Values:	[]
+	Comment:	float64Set3
+	UpdateMode:	dynamic
+	*/
+	float64set3 float64
+
+	/**
+	Name:	float64Range1
+	Scope:	[global]
+	Access:	[file]
+	DataType:	float64
+	DomainType:	range
+	Values:	[1000.01 0.02 10000.03]
+	Comment:	float64Range1
+	UpdateMode:	dynamic
+	*/
+	float64Range1 float64
+
+	//parameter name -> parameter definition string
+	name2definition map[string]string
+} //end AllParameters
+
+//all parameters can be set in the configuration file.
+type configuration struct {
+	//read and write lock
+	rwlock sync.RWMutex
+
+	/**
+	Name:	boolSet1
+	Scope:	[global]
+	Access:	[file]
+	DataType:	bool
+	DomainType:	set
+	Values:	[true]
+	Comment:	boolSet1
+	UpdateMode:	dynamic
+	*/
+	BoolSet1 bool `toml:"boolSet1"`
+
+	/**
+	Name:	boolSet2
+	Scope:	[global]
+	Access:	[file]
+	DataType:	bool
+	DomainType:	set
+	Values:	[false]
+	Comment:	boolSet2
+	UpdateMode:	hotload
+	*/
+	BoolSet2 bool `toml:"boolSet2"`
+
+	/**
+	Name:	boolSet3
+	Scope:	[global]
+	Access:	[file]
+	DataType:	bool
+	DomainType:	set
+	Values:	[]
+	Comment:	boolSet3
+	UpdateMode:	dynamic
+	*/
+	BoolSet3 bool `toml:"boolSet3"`
+
+	/**
+	Name:	stringSet1
+	Scope:	[global]
+	Access:	[file]
+	DataType:	string
+	DomainType:	set
+	Values:	[ss1 ss2 ss3]
+	Comment:	stringSet1
+	UpdateMode:	dynamic
+	*/
+	StringSet1 string `toml:"stringSet1"`
+
+	/**
+	Name:	stringSet2
+	Scope:	[global]
+	Access:	[file]
+	DataType:	string
+	DomainType:	set
+	Values:	[]
+	Comment:	stringSet2
+	UpdateMode:	dynamic
+	*/
+	StringSet2 string `toml:"stringSet2"`
+
+	/**
+	Name:	int64set1
+	Scope:	[global]
+	Access:	[file]
+	DataType:	int64
+	DomainType:	set
+	Values:	[1 2 3 4 5 6]
+	Comment:	int64Set1
+	UpdateMode:	dynamic
+	*/
+	Int64set1 int64 `toml:"int64set1"`
+
+	/**
+	Name:	int64set3
+	Scope:	[global]
+	Access:	[file]
+	DataType:	int64
+	DomainType:	set
+	Values:	[]
+	Comment:	int64Set3
+	UpdateMode:	dynamic
+	*/
+	Int64set3 int64 `toml:"int64set3"`
+
+	/**
+	Name:	int64Range1
+	Scope:	[global]
+	Access:	[file]
+	DataType:	int64
+	DomainType:	range
+	Values:	[1000 0 10000]
+	Comment:	int64Range1
+	UpdateMode:	dynamic
+	*/
+	Int64Range1 int64 `toml:"int64Range1"`
+
+	/**
+	Name:	float64set1
+	Scope:	[global]
+	Access:	[file]
+	DataType:	float64
+	DomainType:	set
+	Values:	[1.0 2.0 3.0 4.00 5.0 6.0]
+	Comment:	float64Set1
+	UpdateMode:	dynamic
+	*/
+	Float64set1 float64 `toml:"float64set1"`
+
+	/**
+	Name:	float64set3
+	Scope:	[global]
+	Access:	[file]
+	DataType:	float64
+	DomainType:	set
+	Values:	[]
+	Comment:	float64Set3
+	UpdateMode:	dynamic
+	*/
+	Float64set3 float64 `toml:"float64set3"`
+
+	/**
+	Name:	float64Range1
+	Scope:	[global]
+	Access:	[file]
+	DataType:	float64
+	DomainType:	range
+	Values:	[1000.01 0.02 10000.03]
+	Comment:	float64Range1
+	UpdateMode:	dynamic
+	*/
+	Float64Range1 float64 `toml:"float64Range1"`
+
+	//parameter name -> updated flag
+	name2updatedFlags map[string]bool
+} //end configuration
+
+/**
+prepare something before anything else.
+it is unsafe in multi-thread environment.
+*/
+func (ap *AllParameters) prepareAnything() {
+	if ap.name2definition == nil {
+		ap.name2definition = make(map[string]string)
+	}
+}
+
+/**
+set parameter and its string of the definition.
+*/
+func (ap *AllParameters) PrepareDefinition() {
+	ap.rwlock.Lock()
+	defer ap.rwlock.Unlock()
+
+	ap.prepareAnything()
+
+	ap.name2definition["boolSet1"] = "	Name:	boolSet1	Scope:	[global]	Access:	[file]	DataType:	bool	DomainType:	set	Values:	[true]	Comment:	boolSet1	UpdateMode:	dynamic	"
+
+	ap.name2definition["boolSet2"] = "	Name:	boolSet2	Scope:	[global]	Access:	[file]	DataType:	bool	DomainType:	set	Values:	[false]	Comment:	boolSet2	UpdateMode:	hotload	"
+
+	ap.name2definition["boolSet3"] = "	Name:	boolSet3	Scope:	[global]	Access:	[file]	DataType:	bool	DomainType:	set	Values:	[]	Comment:	boolSet3	UpdateMode:	dynamic	"
+
+	ap.name2definition["stringSet1"] = "	Name:	stringSet1	Scope:	[global]	Access:	[file]	DataType:	string	DomainType:	set	Values:	[ss1 ss2 ss3]	Comment:	stringSet1	UpdateMode:	dynamic	"
+
+	ap.name2definition["stringSet2"] = "	Name:	stringSet2	Scope:	[global]	Access:	[file]	DataType:	string	DomainType:	set	Values:	[]	Comment:	stringSet2	UpdateMode:	dynamic	"
+
+	ap.name2definition["int64set1"] = "	Name:	int64set1	Scope:	[global]	Access:	[file]	DataType:	int64	DomainType:	set	Values:	[1 2 3 4 5 6]	Comment:	int64Set1	UpdateMode:	dynamic	"
+
+	ap.name2definition["int64set2"] = "	Name:	int64set2	Scope:	[global]	Access:	[file]	DataType:	int64	DomainType:	set	Values:	[1 3 5 7]	Comment:	int64Set2	UpdateMode:	fix	"
+
+	ap.name2definition["int64set3"] = "	Name:	int64set3	Scope:	[global]	Access:	[file]	DataType:	int64	DomainType:	set	Values:	[]	Comment:	int64Set3	UpdateMode:	dynamic	"
+
+	ap.name2definition["int64Range1"] = "	Name:	int64Range1	Scope:	[global]	Access:	[file]	DataType:	int64	DomainType:	range	Values:	[1000 0 10000]	Comment:	int64Range1	UpdateMode:	dynamic	"
+
+	ap.name2definition["float64set1"] = "	Name:	float64set1	Scope:	[global]	Access:	[file]	DataType:	float64	DomainType:	set	Values:	[1.0 2.0 3.0 4.00 5.0 6.0]	Comment:	float64Set1	UpdateMode:	dynamic	"
+
+	ap.name2definition["float64set2"] = "	Name:	float64set2	Scope:	[global]	Access:	[file]	DataType:	float64	DomainType:	set	Values:	[1.001 3.003 5.005 7.007]	Comment:	float64Set2	UpdateMode:	fix	"
+
+	ap.name2definition["float64set3"] = "	Name:	float64set3	Scope:	[global]	Access:	[file]	DataType:	float64	DomainType:	set	Values:	[]	Comment:	float64Set3	UpdateMode:	dynamic	"
+
+	ap.name2definition["float64Range1"] = "	Name:	float64Range1	Scope:	[global]	Access:	[file]	DataType:	float64	DomainType:	range	Values:	[1000.01 0.02 10000.03]	Comment:	float64Range1	UpdateMode:	dynamic	"
+
+}
+
+/**
+get the definition of the parameter.
+*/
+func (ap *AllParameters) GetDefinition(name string) (string, error) {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	ap.prepareAnything()
+	if p, ok := ap.name2definition[name]; !ok {
+		return "", fmt.Errorf("there is no parameter %s", name)
+	} else {
+		return p, nil
+	}
+}
+
+/**
+check if there is the parameter
+*/
+func (ap *AllParameters) HasParameter(name string) bool {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	ap.prepareAnything()
+	if _, ok := ap.name2definition[name]; !ok {
+		return false
+	} else {
+		return true
+	}
+}
+
+/**
+Load the initial values of all parameters.
+*/
+func (ap *AllParameters) LoadInitialValues() error {
+	ap.PrepareDefinition()
+	var err error
+
+	boolSet1choices := []bool{
+
+		true,
+	}
+	if len(boolSet1choices) != 0 {
+		if err = ap.setBoolSet1(boolSet1choices[0]); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "BoolSet1", err)
+		}
+	} else {
+
+		if err = ap.setBoolSet1(false); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "BoolSet1", err)
+		}
+
+	}
+
+	boolSet2choices := []bool{
+
+		false,
+	}
+	if len(boolSet2choices) != 0 {
+		if err = ap.setBoolSet2(boolSet2choices[0]); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "BoolSet2", err)
+		}
+	} else {
+
+		if err = ap.setBoolSet2(false); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "BoolSet2", err)
+		}
+
+	}
+
+	boolSet3choices := []bool{}
+	if len(boolSet3choices) != 0 {
+		if err = ap.setBoolSet3(boolSet3choices[0]); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "BoolSet3", err)
+		}
+	} else {
+
+		if err = ap.setBoolSet3(false); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "BoolSet3", err)
+		}
+
+	}
+
+	stringSet1choices := []string{
+
+		"ss1",
+
+		"ss2",
+
+		"ss3",
+	}
+	if len(stringSet1choices) != 0 {
+		if err = ap.setStringSet1(stringSet1choices[0]); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "StringSet1", err)
+		}
+	} else {
+		//empty string
+		if err = ap.setStringSet1(""); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "StringSet1", err)
+		}
+	}
+
+	stringSet2choices := []string{}
+	if len(stringSet2choices) != 0 {
+		if err = ap.setStringSet2(stringSet2choices[0]); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "StringSet2", err)
+		}
+	} else {
+		//empty string
+		if err = ap.setStringSet2(""); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "StringSet2", err)
+		}
+	}
+
+	int64set1choices := []int64{
+
+		1,
+
+		2,
+
+		3,
+
+		4,
+
+		5,
+
+		6,
+	}
+	if len(int64set1choices) != 0 {
+		if err = ap.setInt64set1(int64set1choices[0]); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Int64set1", err)
+		}
+	} else {
+
+		if err = ap.setInt64set1(0); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Int64set1", err)
+		}
+
+	}
+
+	int64set2choices := []int64{
+
+		1,
+
+		3,
+
+		5,
+
+		7,
+	}
+	if len(int64set2choices) != 0 {
+		if err = ap.setInt64set2(int64set2choices[0]); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Int64set2", err)
+		}
+	} else {
+
+		if err = ap.setInt64set2(0); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Int64set2", err)
+		}
+
+	}
+
+	int64set3choices := []int64{}
+	if len(int64set3choices) != 0 {
+		if err = ap.setInt64set3(int64set3choices[0]); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Int64set3", err)
+		}
+	} else {
+
+		if err = ap.setInt64set3(0); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Int64set3", err)
+		}
+
+	}
+
+	int64Range1choices := []int64{
+
+		1000,
+
+		0,
+
+		10000,
+	}
+	if len(int64Range1choices) != 0 {
+		if err = ap.setInt64Range1(int64Range1choices[0]); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Int64Range1", err)
+		}
+	} else {
+
+		if err = ap.setInt64Range1(0); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Int64Range1", err)
+		}
+
+	}
+
+	float64set1choices := []float64{
+
+		1.0,
+
+		2.0,
+
+		3.0,
+
+		4.00,
+
+		5.0,
+
+		6.0,
+	}
+	if len(float64set1choices) != 0 {
+		if err = ap.setFloat64set1(float64set1choices[0]); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Float64set1", err)
+		}
+	} else {
+
+		if err = ap.setFloat64set1(0.0); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Float64set1", err)
+		}
+
+	}
+
+	float64set2choices := []float64{
+
+		1.001,
+
+		3.003,
+
+		5.005,
+
+		7.007,
+	}
+	if len(float64set2choices) != 0 {
+		if err = ap.setFloat64set2(float64set2choices[0]); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Float64set2", err)
+		}
+	} else {
+
+		if err = ap.setFloat64set2(0.0); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Float64set2", err)
+		}
+
+	}
+
+	float64set3choices := []float64{}
+	if len(float64set3choices) != 0 {
+		if err = ap.setFloat64set3(float64set3choices[0]); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Float64set3", err)
+		}
+	} else {
+
+		if err = ap.setFloat64set3(0.0); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Float64set3", err)
+		}
+
+	}
+
+	float64Range1choices := []float64{
+
+		1000.01,
+
+		0.02,
+
+		10000.03,
+	}
+	if len(float64Range1choices) != 0 {
+		if err = ap.setFloat64Range1(float64Range1choices[0]); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Float64Range1", err)
+		}
+	} else {
+
+		if err = ap.setFloat64Range1(0.0); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Float64Range1", err)
+		}
+
+	}
+
+	return nil
+}
+
+/**
+Get the value of the parameter boolSet1
+*/
+func (ap *AllParameters) GetBoolSet1() bool {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	return ap.boolSet1
+}
+
+/**
+Get the value of the parameter boolSet2
+*/
+func (ap *AllParameters) GetBoolSet2() bool {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	return ap.boolSet2
+}
+
+/**
+Get the value of the parameter boolSet3
+*/
+func (ap *AllParameters) GetBoolSet3() bool {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	return ap.boolSet3
+}
+
+/**
+Get the value of the parameter stringSet1
+*/
+func (ap *AllParameters) GetStringSet1() string {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	return ap.stringSet1
+}
+
+/**
+Get the value of the parameter stringSet2
+*/
+func (ap *AllParameters) GetStringSet2() string {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	return ap.stringSet2
+}
+
+/**
+Get the value of the parameter int64set1
+*/
+func (ap *AllParameters) GetInt64set1() int64 {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	return ap.int64set1
+}
+
+/**
+Get the value of the parameter int64set2
+*/
+func (ap *AllParameters) GetInt64set2() int64 {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	return ap.int64set2
+}
+
+/**
+Get the value of the parameter int64set3
+*/
+func (ap *AllParameters) GetInt64set3() int64 {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	return ap.int64set3
+}
+
+/**
+Get the value of the parameter int64Range1
+*/
+func (ap *AllParameters) GetInt64Range1() int64 {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	return ap.int64Range1
+}
+
+/**
+Get the value of the parameter float64set1
+*/
+func (ap *AllParameters) GetFloat64set1() float64 {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	return ap.float64set1
+}
+
+/**
+Get the value of the parameter float64set2
+*/
+func (ap *AllParameters) GetFloat64set2() float64 {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	return ap.float64set2
+}
+
+/**
+Get the value of the parameter float64set3
+*/
+func (ap *AllParameters) GetFloat64set3() float64 {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	return ap.float64set3
+}
+
+/**
+Get the value of the parameter float64Range1
+*/
+func (ap *AllParameters) GetFloat64Range1() float64 {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	return ap.float64Range1
+}
+
+/**
+Set the value of the parameter boolSet1
+*/
+func (ap *AllParameters) SetBoolSet1(value bool) error {
+	return ap.setBoolSet1(value)
+}
+
+/**
+Set the value of the parameter boolSet2
+*/
+func (ap *AllParameters) SetBoolSet2(value bool) error {
+	return ap.setBoolSet2(value)
+}
+
+/**
+Set the value of the parameter boolSet3
+*/
+func (ap *AllParameters) SetBoolSet3(value bool) error {
+	return ap.setBoolSet3(value)
+}
+
+/**
+Set the value of the parameter stringSet1
+*/
+func (ap *AllParameters) SetStringSet1(value string) error {
+	return ap.setStringSet1(value)
+}
+
+/**
+Set the value of the parameter stringSet2
+*/
+func (ap *AllParameters) SetStringSet2(value string) error {
+	return ap.setStringSet2(value)
+}
+
+/**
+Set the value of the parameter int64set1
+*/
+func (ap *AllParameters) SetInt64set1(value int64) error {
+	return ap.setInt64set1(value)
+}
+
+/**
+Set the value of the parameter int64set3
+*/
+func (ap *AllParameters) SetInt64set3(value int64) error {
+	return ap.setInt64set3(value)
+}
+
+/**
+Set the value of the parameter int64Range1
+*/
+func (ap *AllParameters) SetInt64Range1(value int64) error {
+	return ap.setInt64Range1(value)
+}
+
+/**
+Set the value of the parameter float64set1
+*/
+func (ap *AllParameters) SetFloat64set1(value float64) error {
+	return ap.setFloat64set1(value)
+}
+
+/**
+Set the value of the parameter float64set3
+*/
+func (ap *AllParameters) SetFloat64set3(value float64) error {
+	return ap.setFloat64set3(value)
+}
+
+/**
+Set the value of the parameter float64Range1
+*/
+func (ap *AllParameters) SetFloat64Range1(value float64) error {
+	return ap.setFloat64Range1(value)
+}
+
+/**
+Set the value of the parameter boolSet1
+*/
+func (ap *AllParameters) setBoolSet1(value bool) error {
+	ap.rwlock.Lock()
+	defer ap.rwlock.Unlock()
+
+	choices := []bool{
+
+		true,
+	}
+	if len(choices) != 0 {
+		if !isInSliceBool(value, choices) {
+			return fmt.Errorf("setBoolSet1,the value %t is not in set %v", value, choices)
+		}
+	} //else means any bool value: true or false
+
+	ap.boolSet1 = value
+	return nil
+}
+
+/**
+Set the value of the parameter boolSet2
+*/
+func (ap *AllParameters) setBoolSet2(value bool) error {
+	ap.rwlock.Lock()
+	defer ap.rwlock.Unlock()
+
+	choices := []bool{
+
+		false,
+	}
+	if len(choices) != 0 {
+		if !isInSliceBool(value, choices) {
+			return fmt.Errorf("setBoolSet2,the value %t is not in set %v", value, choices)
+		}
+	} //else means any bool value: true or false
+
+	ap.boolSet2 = value
+	return nil
+}
+
+/**
+Set the value of the parameter boolSet3
+*/
+func (ap *AllParameters) setBoolSet3(value bool) error {
+	ap.rwlock.Lock()
+	defer ap.rwlock.Unlock()
+
+	choices := []bool{}
+	if len(choices) != 0 {
+		if !isInSliceBool(value, choices) {
+			return fmt.Errorf("setBoolSet3,the value %t is not in set %v", value, choices)
+		}
+	} //else means any bool value: true or false
+
+	ap.boolSet3 = value
+	return nil
+}
+
+/**
+Set the value of the parameter stringSet1
+*/
+func (ap *AllParameters) setStringSet1(value string) error {
+	ap.rwlock.Lock()
+	defer ap.rwlock.Unlock()
+
+	choices := []string{
+
+		"ss1",
+
+		"ss2",
+
+		"ss3",
+	}
+	if len(choices) != 0 {
+		if !isInSlice(value, choices) {
+			return fmt.Errorf("setStringSet1,the value %s is not in set %v", value, choices)
+		}
+	} //else means any string
+
+	ap.stringSet1 = value
+	return nil
+}
+
+/**
+Set the value of the parameter stringSet2
+*/
+func (ap *AllParameters) setStringSet2(value string) error {
+	ap.rwlock.Lock()
+	defer ap.rwlock.Unlock()
+
+	choices := []string{}
+	if len(choices) != 0 {
+		if !isInSlice(value, choices) {
+			return fmt.Errorf("setStringSet2,the value %s is not in set %v", value, choices)
+		}
+	} //else means any string
+
+	ap.stringSet2 = value
+	return nil
+}
+
+/**
+Set the value of the parameter int64set1
+*/
+func (ap *AllParameters) setInt64set1(value int64) error {
+	ap.rwlock.Lock()
+	defer ap.rwlock.Unlock()
+
+	choices := []int64{
+
+		1,
+
+		2,
+
+		3,
+
+		4,
+
+		5,
+
+		6,
+	}
+	if len(choices) != 0 {
+		if !isInSliceInt64(value, choices) {
+			return fmt.Errorf("setInt64set1,the value %d is not in set %v", value, choices)
+		}
+	} //else means any int64
+
+	ap.int64set1 = value
+	return nil
+}
+
+/**
+Set the value of the parameter int64set2
+*/
+func (ap *AllParameters) setInt64set2(value int64) error {
+	ap.rwlock.Lock()
+	defer ap.rwlock.Unlock()
+
+	choices := []int64{
+
+		1,
+
+		3,
+
+		5,
+
+		7,
+	}
+	if len(choices) != 0 {
+		if !isInSliceInt64(value, choices) {
+			return fmt.Errorf("setInt64set2,the value %d is not in set %v", value, choices)
+		}
+	} //else means any int64
+
+	ap.int64set2 = value
+	return nil
+}
+
+/**
+Set the value of the parameter int64set3
+*/
+func (ap *AllParameters) setInt64set3(value int64) error {
+	ap.rwlock.Lock()
+	defer ap.rwlock.Unlock()
+
+	choices := []int64{}
+	if len(choices) != 0 {
+		if !isInSliceInt64(value, choices) {
+			return fmt.Errorf("setInt64set3,the value %d is not in set %v", value, choices)
+		}
+	} //else means any int64
+
+	ap.int64set3 = value
+	return nil
+}
+
+/**
+Set the value of the parameter int64Range1
+*/
+func (ap *AllParameters) setInt64Range1(value int64) error {
+	ap.rwlock.Lock()
+	defer ap.rwlock.Unlock()
+
+	choices := []int64{
+
+		1000,
+
+		0,
+
+		10000,
+	}
+	if !(value >= choices[1] && value <= choices[2]) {
+		return fmt.Errorf("setInt64Range1,the value %d is not in the range [%d,%d]", value, choices[1], choices[2])
+	}
+
+	ap.int64Range1 = value
+	return nil
+}
+
+/**
+Set the value of the parameter float64set1
+*/
+func (ap *AllParameters) setFloat64set1(value float64) error {
+	ap.rwlock.Lock()
+	defer ap.rwlock.Unlock()
+
+	choices := []float64{
+
+		1.0,
+
+		2.0,
+
+		3.0,
+
+		4.00,
+
+		5.0,
+
+		6.0,
+	}
+	if len(choices) != 0 {
+		if !isInSliceFloat64(value, choices) {
+			return fmt.Errorf("setFloat64set1,the value %f is not in set %v", value, choices)
+		}
+	} //else means any float64
+
+	ap.float64set1 = value
+	return nil
+}
+
+/**
+Set the value of the parameter float64set2
+*/
+func (ap *AllParameters) setFloat64set2(value float64) error {
+	ap.rwlock.Lock()
+	defer ap.rwlock.Unlock()
+
+	choices := []float64{
+
+		1.001,
+
+		3.003,
+
+		5.005,
+
+		7.007,
+	}
+	if len(choices) != 0 {
+		if !isInSliceFloat64(value, choices) {
+			return fmt.Errorf("setFloat64set2,the value %f is not in set %v", value, choices)
+		}
+	} //else means any float64
+
+	ap.float64set2 = value
+	return nil
+}
+
+/**
+Set the value of the parameter float64set3
+*/
+func (ap *AllParameters) setFloat64set3(value float64) error {
+	ap.rwlock.Lock()
+	defer ap.rwlock.Unlock()
+
+	choices := []float64{}
+	if len(choices) != 0 {
+		if !isInSliceFloat64(value, choices) {
+			return fmt.Errorf("setFloat64set3,the value %f is not in set %v", value, choices)
+		}
+	} //else means any float64
+
+	ap.float64set3 = value
+	return nil
+}
+
+/**
+Set the value of the parameter float64Range1
+*/
+func (ap *AllParameters) setFloat64Range1(value float64) error {
+	ap.rwlock.Lock()
+	defer ap.rwlock.Unlock()
+
+	choices := []float64{
+
+		1000.01,
+
+		0.02,
+
+		10000.03,
+	}
+	if !(value >= choices[1] && value <= choices[2]) {
+		return fmt.Errorf("setFloat64Range1,the value %f is not in the range [%f,%f]", value, choices[1], choices[2])
+	}
+
+	ap.float64Range1 = value
+	return nil
+}
+
+/**
+prepare something before anything else.
+it is unsafe in multi-thread environment.
+*/
+func (config *configuration) prepareAnything() {
+	if config.name2updatedFlags == nil {
+		config.name2updatedFlags = make(map[string]bool)
+	}
+}
+
+/**
+reset update flags of configuration items
+*/
+func (config *configuration) resetUpdatedFlags() {
+	config.rwlock.Lock()
+	defer config.rwlock.Unlock()
+	config.prepareAnything()
+
+	config.name2updatedFlags["boolSet1"] = false
+
+	config.name2updatedFlags["boolSet2"] = false
+
+	config.name2updatedFlags["boolSet3"] = false
+
+	config.name2updatedFlags["stringSet1"] = false
+
+	config.name2updatedFlags["stringSet2"] = false
+
+	config.name2updatedFlags["int64set1"] = false
+
+	config.name2updatedFlags["int64set3"] = false
+
+	config.name2updatedFlags["int64Range1"] = false
+
+	config.name2updatedFlags["float64set1"] = false
+
+	config.name2updatedFlags["float64set3"] = false
+
+	config.name2updatedFlags["float64Range1"] = false
+
+}
+
+/**
+set update flag of configuration item
+*/
+func (config *configuration) setUpdatedFlag(name string, updated bool) {
+	config.rwlock.Lock()
+	defer config.rwlock.Unlock()
+	config.prepareAnything()
+	config.name2updatedFlags[name] = updated
+}
+
+/**
+get update flag of configuration item
+*/
+func (config *configuration) getUpdatedFlag(name string) bool {
+	config.rwlock.RLock()
+	defer config.rwlock.RUnlock()
+	config.prepareAnything()
+	return config.name2updatedFlags[name]
+}
+
+/**
+Load parameters' values in the configuration string.
+*/
+func (config *configuration) LoadConfigurationFromString(input string) error {
+	config.resetUpdatedFlags()
+
+	metadata, err := toml.Decode(input, config)
+	if err != nil {
+		return err
+	} else if failed := metadata.Undecoded(); len(failed) > 0 {
+		var failedItems []string
+		for _, item := range failed {
+			failedItems = append(failedItems, item.String())
+		}
+		return fmt.Errorf("decode failed %s. error:%v", failedItems, err)
+	}
+
+	for _, k := range metadata.Keys() {
+		config.setUpdatedFlag(k[0], true)
+	}
+
+	return nil
+}
+
+/**
+Load parameters' values in the configuration file.
+*/
+func (config *configuration) LoadConfigurationFromFile(fname string) error {
+	config.resetUpdatedFlags()
+
+	metadata, err := toml.DecodeFile(fname, config)
+	if err != nil {
+		return err
+	} else if failed := metadata.Undecoded(); len(failed) > 0 {
+		var failedItems []string
+		for _, item := range failed {
+			failedItems = append(failedItems, item.String())
+		}
+		return fmt.Errorf("decode failed %s. error:%v", failedItems, err)
+	}
+
+	for _, k := range metadata.Keys() {
+		config.setUpdatedFlag(k[0], true)
+	}
+
+	return nil
+}
+
+/**
+Update parameters' values with configuration.
+*/
+func (ap *AllParameters) UpdateParametersWithConfiguration(config *configuration) error {
+	var err error
+
+	if config.getUpdatedFlag("boolSet1") {
+		if err = ap.setBoolSet1(config.BoolSet1); err != nil {
+			return fmt.Errorf("update parameter boolSet1 failed.error:%v", err)
+		}
+	}
+
+	if config.getUpdatedFlag("boolSet2") {
+		if err = ap.setBoolSet2(config.BoolSet2); err != nil {
+			return fmt.Errorf("update parameter boolSet2 failed.error:%v", err)
+		}
+	}
+
+	if config.getUpdatedFlag("boolSet3") {
+		if err = ap.setBoolSet3(config.BoolSet3); err != nil {
+			return fmt.Errorf("update parameter boolSet3 failed.error:%v", err)
+		}
+	}
+
+	if config.getUpdatedFlag("stringSet1") {
+		if err = ap.setStringSet1(config.StringSet1); err != nil {
+			return fmt.Errorf("update parameter stringSet1 failed.error:%v", err)
+		}
+	}
+
+	if config.getUpdatedFlag("stringSet2") {
+		if err = ap.setStringSet2(config.StringSet2); err != nil {
+			return fmt.Errorf("update parameter stringSet2 failed.error:%v", err)
+		}
+	}
+
+	if config.getUpdatedFlag("int64set1") {
+		if err = ap.setInt64set1(config.Int64set1); err != nil {
+			return fmt.Errorf("update parameter int64set1 failed.error:%v", err)
+		}
+	}
+
+	if config.getUpdatedFlag("int64set3") {
+		if err = ap.setInt64set3(config.Int64set3); err != nil {
+			return fmt.Errorf("update parameter int64set3 failed.error:%v", err)
+		}
+	}
+
+	if config.getUpdatedFlag("int64Range1") {
+		if err = ap.setInt64Range1(config.Int64Range1); err != nil {
+			return fmt.Errorf("update parameter int64Range1 failed.error:%v", err)
+		}
+	}
+
+	if config.getUpdatedFlag("float64set1") {
+		if err = ap.setFloat64set1(config.Float64set1); err != nil {
+			return fmt.Errorf("update parameter float64set1 failed.error:%v", err)
+		}
+	}
+
+	if config.getUpdatedFlag("float64set3") {
+		if err = ap.setFloat64set3(config.Float64set3); err != nil {
+			return fmt.Errorf("update parameter float64set3 failed.error:%v", err)
+		}
+	}
+
+	if config.getUpdatedFlag("float64Range1") {
+		if err = ap.setFloat64Range1(config.Float64Range1); err != nil {
+			return fmt.Errorf("update parameter float64Range1 failed.error:%v", err)
+		}
+	}
+
+	return nil
+}
diff --git a/pkg/config/parameters_test.go b/pkg/config/parameters_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..090c2599ddc5c3406ec288247dca84ee99f0ae08
--- /dev/null
+++ b/pkg/config/parameters_test.go
@@ -0,0 +1,159 @@
+// Code generated by tool; DO NOT EDIT.
+package config
+
+import (
+	"sync"
+	"testing"
+)
+
+func TestAllParameters_LoadInitialValues(t *testing.T) {
+	ap := &AllParameters{}
+	if err := ap.LoadInitialValues(); err != nil {
+		t.Errorf("LoadInitialValues failed. error:%v", err)
+	}
+}
+
+func isconfigurationEqual(c1, c2 configuration) bool {
+
+	if c1.BoolSet1 != c2.BoolSet1 {
+		return false
+	}
+
+	if c1.BoolSet2 != c2.BoolSet2 {
+		return false
+	}
+
+	if c1.BoolSet3 != c2.BoolSet3 {
+		return false
+	}
+
+	if c1.StringSet1 != c2.StringSet1 {
+		return false
+	}
+
+	if c1.StringSet2 != c2.StringSet2 {
+		return false
+	}
+
+	if c1.Int64set1 != c2.Int64set1 {
+		return false
+	}
+
+	if c1.Int64set3 != c2.Int64set3 {
+		return false
+	}
+
+	if c1.Int64Range1 != c2.Int64Range1 {
+		return false
+	}
+
+	if c1.Float64set1 != c2.Float64set1 {
+		return false
+	}
+
+	if c1.Float64set3 != c2.Float64set3 {
+		return false
+	}
+
+	if c1.Float64Range1 != c2.Float64Range1 {
+		return false
+	}
+
+	return true
+}
+
+func Test_configuration_LoadConfigurationFromString(t *testing.T) {
+	t1 := `
+
+boolSet1=true
+
+boolSet2=false
+
+boolSet3= false
+
+stringSet1= "ss1"
+
+stringSet2= ""
+
+int64set1=1
+
+
+
+int64set3= 0
+
+int64Range1=1000
+
+float64set1=1.0
+
+
+
+float64set3= 0.0
+
+float64Range1=1000.01
+		
+`
+	t1_config := configuration{
+		rwlock: sync.RWMutex{},
+
+		BoolSet1: true,
+
+		BoolSet2: false,
+
+		BoolSet3: false,
+
+		StringSet1: "ss1",
+
+		StringSet2: "",
+
+		Int64set1: 1,
+
+		Int64set3: 0,
+
+		Int64Range1: 1000,
+
+		Float64set1: 1.0,
+
+		Float64set3: 0.0,
+
+		Float64Range1: 1000.01,
+
+		name2updatedFlags: nil,
+	}
+
+	type args struct {
+		input  string
+		config configuration
+	}
+	tests := []struct {
+		name     string
+		args     args
+		wantErr  bool
+		wantErr2 bool
+		wantErr3 bool
+	}{
+		{"t1", args{t1, t1_config}, false, false, false},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			ap := &AllParameters{}
+			if err := ap.LoadInitialValues(); err != nil {
+				t.Errorf("LoadInitialValues failed.error %v", err)
+			}
+			config := &configuration{}
+			if err := config.LoadConfigurationFromString(tt.args.input); (err != nil) != tt.wantErr {
+				t.Errorf("LoadConfigurationFromString() error = %v, wantErr %v", err, tt.wantErr)
+			} else if err != nil {
+				return
+			}
+
+			if err := ap.UpdateParametersWithConfiguration(config); (err != nil) != tt.wantErr2 {
+				t.Errorf("UpdateParametersWithConfiguration failed. error:%v", err)
+			}
+
+			if (isconfigurationEqual(*config, tt.args.config) != true) != tt.wantErr3 {
+				t.Errorf("Configuration are not equal. %v vs %v ", *config, tt.args.config)
+				return
+			}
+		})
+	}
+}
diff --git a/pkg/config/test/config.toml b/pkg/config/test/config.toml
new file mode 100644
index 0000000000000000000000000000000000000000..e79411e031253506282f7a448e310beca5ae5e59
--- /dev/null
+++ b/pkg/config/test/config.toml
@@ -0,0 +1,139 @@
+
+# Code generated by tool; DO NOT EDIT.
+
+
+	
+#	Name:	boolSet1
+#	Scope:	[global]
+#	Access:	[file]
+#	DataType:	bool
+#	DomainType:	set
+#	Values:	[true]
+#	Comment:	boolSet1
+#	UpdateMode:	dynamic
+	boolSet1=true
+
+
+	
+#	Name:	boolSet2
+#	Scope:	[global]
+#	Access:	[file]
+#	DataType:	bool
+#	DomainType:	set
+#	Values:	[false]
+#	Comment:	boolSet2
+#	UpdateMode:	hotload
+	boolSet2=false
+
+
+	
+#	Name:	boolSet3
+#	Scope:	[global]
+#	Access:	[file]
+#	DataType:	bool
+#	DomainType:	set
+#	Values:	[]
+#	Comment:	boolSet3
+#	UpdateMode:	dynamic
+	boolSet3= false
+
+
+	
+#	Name:	stringSet1
+#	Scope:	[global]
+#	Access:	[file]
+#	DataType:	string
+#	DomainType:	set
+#	Values:	[ss1 ss2 ss3]
+#	Comment:	stringSet1
+#	UpdateMode:	dynamic
+	stringSet1= "ss1"
+
+
+	
+#	Name:	stringSet2
+#	Scope:	[global]
+#	Access:	[file]
+#	DataType:	string
+#	DomainType:	set
+#	Values:	[]
+#	Comment:	stringSet2
+#	UpdateMode:	dynamic
+	stringSet2= ""
+
+
+	
+#	Name:	int64set1
+#	Scope:	[global]
+#	Access:	[file]
+#	DataType:	int64
+#	DomainType:	set
+#	Values:	[1 2 3 4 5 6]
+#	Comment:	int64Set1
+#	UpdateMode:	dynamic
+	int64set1=1
+
+
+
+
+	
+#	Name:	int64set3
+#	Scope:	[global]
+#	Access:	[file]
+#	DataType:	int64
+#	DomainType:	set
+#	Values:	[]
+#	Comment:	int64Set3
+#	UpdateMode:	dynamic
+	int64set3= 0
+
+
+	
+#	Name:	int64Range1
+#	Scope:	[global]
+#	Access:	[file]
+#	DataType:	int64
+#	DomainType:	range
+#	Values:	[1000 0 10000]
+#	Comment:	int64Range1
+#	UpdateMode:	dynamic
+	int64Range1=1000
+
+
+	
+#	Name:	float64set1
+#	Scope:	[global]
+#	Access:	[file]
+#	DataType:	float64
+#	DomainType:	set
+#	Values:	[1.0 2.0 3.0 4.00 5.0 6.0]
+#	Comment:	float64Set1
+#	UpdateMode:	dynamic
+	float64set1=1.0
+
+
+
+
+	
+#	Name:	float64set3
+#	Scope:	[global]
+#	Access:	[file]
+#	DataType:	float64
+#	DomainType:	set
+#	Values:	[]
+#	Comment:	float64Set3
+#	UpdateMode:	dynamic
+	float64set3= 0.0
+
+
+	
+#	Name:	float64Range1
+#	Scope:	[global]
+#	Access:	[file]
+#	DataType:	float64
+#	DomainType:	range
+#	Values:	[1000.01 0.02 10000.03]
+#	Comment:	float64Range1
+#	UpdateMode:	dynamic
+	float64Range1=1000.01
+
diff --git a/pkg/config/test/config_template.go b/pkg/config/test/config_template.go
new file mode 100644
index 0000000000000000000000000000000000000000..3f1d76d6adeb34785bca9ce6e38bacf0ea098504
--- /dev/null
+++ b/pkg/config/test/config_template.go
@@ -0,0 +1,1366 @@
+package config
+
+import (
+	"fmt"
+	"github.com/BurntSushi/toml"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"sort"
+	"strconv"
+	"strings"
+	"text/template"
+	"unicode"
+)
+
+/*
+	scope options:
+
+	session:
+
+	If you change a session parameter,
+		the value remains in effect within your session until you change the variable to a different value
+			or the session ends.
+		The change has no effect on other sessions.
+
+	global:
+
+	If you change a global parameter, the value is remembered and used to initialize the session value
+		for new sessions until you change the parameter to a different value or the server exits.
+	The change is visible to any client that accesses the global value.
+		However, the change affects the corresponding session value only for clients that connect after the change.
+		The global parameter change does not affect the session value for any current client sessions (
+		not even the session within which the global value change occurs).
+*/
+var scopeOptions = []string{"session", "global"}
+
+//the access
+var accessOptions = []string{"cmd", "file", "env"}
+
+//the data type
+var dataTypeOptions = []string{"string", "int64", "float64", "bool"}
+
+var boolFalseOptions = []string{"false", "off"}
+var boolTrueOptions = []string{"true", "on"}
+
+//the domain
+var domainTyoeOptions = []string{"set", "range"}
+
+//the updateMode
+var updateModeOptions = []string{"dynamic", "fix", "hotload"}
+
+//a unit in configuration template for a configuration item
+type parameter struct {
+	//the Name
+	Name string `toml:"name"`
+
+	//also the Name whose initial character is capital
+	CapitalName string
+
+	//the scope (also visibility)
+	//where can the others see the value
+	Scope []string `toml:"scope"`
+
+	//the access: command line; configure file; environment variable in the shell
+	//where the value can be changed
+	Access []string `toml:"access"`
+
+	//the data type of the value like int, string ,bool,float,...
+	DataType string `toml:"type"`
+
+	//the domain of the value for validity: set; range;
+	//set: select one among discrete values.
+	//range: select a point in a real range
+	DomainType string `toml:"domain-type"`
+
+	/**
+	The first one is the initial-value.
+	for range domain-type
+	[initial-value,minimum,maximum]
+
+	for set domain-type
+		normal situation
+			[initial-value,value2,value3,value4,...,]
+
+		special situation
+			[] is empty, you can set any value in the domain of the data type
+	*/
+	Values []string `toml:"values"`
+
+	//the comment
+	Comment string `toml:"comment"`
+
+	//the update mode in running
+	//dynamic: can be updated in running
+	//fix: can not be updated in running
+	//hotLoad: can be loaded from the config file and updated in running
+	UpdateMode string `toml:"update-mode"`
+}
+
+type parameters struct {
+	//the name of parameter data structure
+	//the parameter structure can be exported.
+	//the first character must be capital.
+	ParameterStructName string `toml:"parameter-struct-name"`
+
+	//the name of configuration data structure
+	//the configuration structure is an internal structure that will not be exported.
+	//the first character should not be capital.
+	ConfigurationStructName string `toml:"config-struct-name"`
+
+	//the name of operation file which contains all interface code for operating parameters
+	//without ".go"
+	OperationFileName string `toml:"operation-file-name"`
+
+	//the name of configuration file which contains all auto generated parameters.
+	//without ".toml"
+	ConfigurationFileName string `toml:"config-file-name"`
+
+	//the array of parameters
+	Parameter []parameter
+}
+
+/**
+load and analyse parameters definition from the template file
+*/
+func (params *parameters) LoadParametersDefinitionFromFile(filename string) error {
+	pfile, err := os.Open(filename)
+	if err != nil {
+		return err
+	}
+	defer pfile.Close()
+
+	fbytes, err := ioutil.ReadAll(pfile)
+	if err != nil {
+		return err
+	}
+	return params.LoadParametersDefinitionFromString(string(fbytes))
+}
+
+func (params *parameters) LoadParametersDefinitionFromString(input string) error {
+	metadata, err := toml.Decode(input, params)
+	if err != nil {
+		return err
+	} else if failed := metadata.Undecoded(); len(failed) > 0 {
+		var failedItems []string
+		for _, item := range failed {
+			failedItems = append(failedItems, item.String())
+		}
+		return fmt.Errorf("decode failed %s. error:%v", failedItems, err)
+	}
+
+	//check parameter-struct-name
+	if !isExportedGoIdentifier(params.ParameterStructName) {
+		return fmt.Errorf("ParameterStructName [%s] is not a valid identifier name within ascii characters", params.ParameterStructName)
+	}
+
+	//check config-struct-name
+	if !isGoIdentifier(params.ConfigurationStructName) {
+		return fmt.Errorf("ConfigurationStructName [%s] is not a valid identifier name within ascii characters", params.ConfigurationStructName)
+	}
+
+	//check parameter operation file name
+	if !isGoStructAndInterfaceIdentifier(params.OperationFileName) {
+		return fmt.Errorf("OperationFileName [%s] is not a valid identifier name within ascii characters", params.OperationFileName)
+	}
+
+	//check parameter configuration file name
+	if !isGoStructAndInterfaceIdentifier(params.ConfigurationFileName) {
+		return fmt.Errorf("ConfigurationFileName [%s] is not a valid identifier name within ascii characters", params.ConfigurationFileName)
+	}
+
+	//check parameter
+	for _, p := range params.Parameter {
+		if !isGoIdentifier(p.Name) {
+			return fmt.Errorf("Name [%s] is not a valid identifier name within ascii characters", p.Name)
+		}
+
+		if !isScope(p.Scope) {
+			return fmt.Errorf("Scope [%s] is not a valid scope", p.Scope)
+		}
+
+		if !isAccess(p.Access) {
+			return fmt.Errorf("Access [%s] is not a valid access", p.Access)
+		}
+
+		if !isDataType(p.DataType) {
+			return fmt.Errorf("DataType [%s] is not a valid data type", p.DataType)
+		}
+
+		if !isDomainType(p.DomainType) {
+			return fmt.Errorf("DomainType [%s] is not a valid domain type", p.DomainType)
+		}
+
+		if !checkValues(p.DataType, p.DomainType, p.Values) {
+			return fmt.Errorf("Values [%s] is not compatible with data type %s and domain type %s", p.Values, p.DataType, p.DomainType)
+		}
+
+		if !isUpdateMode(p.UpdateMode) {
+			return fmt.Errorf("UpdateMode [%s] is not a valid update mode", p.UpdateMode)
+		}
+	}
+
+	//parameter name dedup
+	var dedup = make(map[string]bool)
+
+	if _, ok := dedup[params.ParameterStructName]; !ok {
+		dedup[params.ParameterStructName] = true
+	} else {
+		return fmt.Errorf("has duplicate parameter struct name %s.", params.ParameterStructName)
+	}
+
+	if _, ok := dedup[params.ConfigurationStructName]; !ok {
+		dedup[params.ConfigurationStructName] = true
+	} else {
+		return fmt.Errorf("has duplicate configuration struct name %s.", params.ConfigurationStructName)
+	}
+
+	if _, ok := dedup[params.OperationFileName]; !ok {
+		dedup[params.OperationFileName] = true
+	} else {
+		return fmt.Errorf("has duplicate operation file name %s.", params.OperationFileName)
+	}
+
+	if _, ok := dedup[params.ConfigurationFileName]; !ok {
+		dedup[params.ConfigurationFileName] = true
+	} else {
+		return fmt.Errorf("has duplicate configuration file name %s.", params.ConfigurationFileName)
+	}
+
+	for _, p := range params.Parameter {
+		if _, ok := dedup[p.Name]; !ok {
+			dedup[p.Name] = true
+		} else {
+			return fmt.Errorf("has duplicate parameter name %s.", p.Name)
+		}
+	}
+
+	//make capital name for the name
+	for i := 0; i < len(params.Parameter); i++ {
+		p := params.Parameter[i].Name
+		capName := p
+		capName = string(unicode.ToUpper(rune(p[0]))) + p[1:]
+		params.Parameter[i].CapitalName = capName
+	}
+
+	return err
+}
+
+/**
+check the x is a valid low case ascii character
+*/
+func isLowCaseAsciiChar(x byte) bool {
+	return x >= 'a' && x <= 'z' || x == '_'
+}
+
+/**
+check the x is a valid low case ascii character
+*/
+func isUpCaseAsciiChar(x byte) bool {
+	return x >= 'A' && x <= 'Z'
+}
+
+/**
+check the x is a valid ascii character
+*/
+func isAsciiChar(x byte) bool {
+	return x >= 'a' && x <= 'z' || x >= 'A' && x <= 'Z' || x == '_'
+}
+
+/**
+check the x is a valid ascii digit
+*/
+func isAsciiDigit(x byte) bool {
+	return x >= '0' && x <= '9'
+}
+
+/**
+check if the string can be a valid identifier in Golang.
+
+In our context, the identifier can be defined as follow:
+identifier = low-case-letter { letter | digit }
+low-case-letter = "a" ... "z" | "_"
+letter     = "a" ... "z" | "A" ... "Z" | "_"
+digit      = "0" ... "9"
+
+here,the letter just has the ascii characters.
+So,it's the subset of the identifier in Golang.
+*/
+func isGoIdentifier(s string) bool {
+	if len(s) == 0 {
+		return false
+	}
+
+	//the first character is a low case ascii character.
+	if !isLowCaseAsciiChar(s[0]) {
+		return false
+	}
+
+	//the rest should ascii character | ascii digit | _
+	for i := 1; i < len(s); i++ {
+		if !(isAsciiChar(s[i]) || isAsciiDigit(s[i])) {
+			return false
+		}
+	}
+
+	return true
+}
+
+/**
+check if the string can be a valid identifier in Golang.
+
+In our context, the identifier can be defined as follow:
+identifier = up-case-letter { letter | digit }
+up-case-letter = "A" ... "Z"
+letter     = "a" ... "z" | "A" ... "Z" | "_"
+digit      = "0" ... "9"
+
+here,the letter just has the ascii characters.
+So,it's the subset of the identifier in Golang.
+*/
+func isExportedGoIdentifier(s string) bool {
+	if len(s) == 0 {
+		return false
+	}
+
+	//the first character is a low case ascii character.
+	if !isUpCaseAsciiChar(s[0]) {
+		return false
+	}
+
+	//the rest should ascii character | ascii digit | _
+	for i := 1; i < len(s); i++ {
+		if !(isAsciiChar(s[i]) || isAsciiDigit(s[i])) {
+			return false
+		}
+	}
+
+	return true
+}
+
+/**
+check if the string can be a valid struct and interface identifier in Golang.
+
+In our context, the identifier can be defined as follow:
+identifier = letter { letter | digit }
+letter     = "a" ... "z" | "A" ... "Z" | "_"
+digit      = "0" ... "9"
+
+here,the letter just has the ascii characters.
+So,it's the subset of the identifier in Golang.
+*/
+func isGoStructAndInterfaceIdentifier(s string) bool {
+	if len(s) == 0 {
+		return false
+	}
+
+	//the first character is a low case ascii character.
+	if !isAsciiChar(s[0]) {
+		return false
+	}
+
+	//the rest should ascii character | ascii digit | _
+	for i := 1; i < len(s); i++ {
+		if !(isAsciiChar(s[i]) || isAsciiDigit(s[i])) {
+			return false
+		}
+	}
+
+	return true
+}
+
+/**
+check if the scope is valid.
+*/
+func isScope(sc []string) bool {
+	return isSubset(sc, scopeOptions)
+}
+
+/**
+check if the access is valid.
+*/
+func isAccess(sc []string) bool {
+	return isSubset(sc, accessOptions)
+}
+
+/**
+check if the data type is valid
+*/
+func isDataType(x string) bool {
+	return isInSlice(x, dataTypeOptions)
+}
+
+/**
+check if the domain type is valid
+*/
+func isDomainType(x string) bool {
+	return isInSlice(x, domainTyoeOptions)
+}
+
+/**
+make a float string look like a float64 string.
+*/
+func looklikeFloat64String(s string) string {
+	if i := strings.Index(s, "."); i != -1 {
+		if i == len(s)-1 { //. is the last one, append a zero
+			return s + "0"
+		}
+		return s
+	} else {
+		return s + ".0"
+	}
+}
+
+/**
+check if the values are valid based on dataType, domainType.
+*/
+func checkValues(dataType string, domainType string, values []string) bool {
+	switch dataType {
+	case "string":
+		switch domainType {
+		case "set":
+			if len(values) < 1 {
+				return true
+			} else if len(values) == 1 {
+				return true
+			} else {
+				if hasDuplicateValueString(values) {
+					return false
+				}
+			}
+			return true
+		case "range":
+			return false
+		default:
+			return false
+		}
+	case "int64":
+		switch domainType {
+		case "set":
+			if len(values) < 1 {
+				return true
+			}
+
+			var intArr []int64
+			for i := 0; i < len(values); i++ {
+				if v, err := strconv.ParseInt(values[i], 10, 64); err != nil {
+					return false
+				} else {
+					intArr = append(intArr, v)
+				}
+			}
+
+			if len(intArr) == 1 {
+				return true
+			}
+
+			//first one is the default value.
+			//there are no duplicate values in the set.
+			if hasDuplicateValueInt64(intArr) {
+				return false
+			}
+			return true
+		case "range":
+			if len(values) != 3 {
+				return false
+			}
+
+			var intArr []int64
+			for i := 0; i < len(values); i++ {
+				if v, err := strconv.ParseInt(values[i], 10, 64); err != nil {
+					return false
+				} else {
+					intArr = append(intArr, v)
+				}
+			}
+
+			if !(intArr[0] >= intArr[1] && intArr[0] <= intArr[2]) {
+				return false
+			}
+			return true
+		}
+	case "float64":
+		switch domainType {
+		case "set":
+			if len(values) < 1 {
+				return true
+			}
+
+			var fArr []float64
+			for i := 0; i < len(values); i++ {
+				if v, err := strconv.ParseFloat(values[i], 64); err != nil {
+					return false
+				} else {
+					fArr = append(fArr, v)
+				}
+			}
+
+			if len(fArr) == 1 {
+				return true
+			}
+
+			if hasDuplicateValueFloat64(fArr) {
+				return false
+			}
+
+			//for configuration file generation
+			for i := 0; i < len(values); i++ {
+				values[i] = looklikeFloat64String(values[i])
+			}
+
+			return true
+		case "range":
+			if len(values) != 3 {
+				return false
+			}
+
+			var fArr []float64
+			for i := 0; i < len(values); i++ {
+				if v, err := strconv.ParseFloat(values[i], 64); err != nil {
+					return false
+				} else {
+					fArr = append(fArr, v)
+				}
+			}
+
+			if !(fArr[0] >= fArr[1] && fArr[0] <= fArr[2]) {
+				return false
+			}
+			return true
+		}
+	case "bool":
+		switch domainType {
+		case "set":
+			if len(values) < 1 {
+				return true
+			}
+
+			if len(values) != 1 {
+				return false
+			}
+
+			low := strings.ToLower(values[0])
+			if !isInSlice(low, boolFalseOptions) && !isInSlice(low, boolTrueOptions) {
+				return false
+			}
+			return true
+		case "range":
+			return false
+		default:
+
+		}
+	}
+
+	return false
+}
+
+/**
+check if the update mode is valid
+*/
+func isUpdateMode(um string) bool {
+	return isInSlice(um, updateModeOptions)
+}
+
+/**
+check if A is a valid subset of B.
+if A has something that is not in B,then return false.
+if A has duplicate elements,then return false.
+if A has nothing,then return false.
+*/
+func isSubset(A []string, B []string) bool {
+	if len(A) > len(B) {
+		return false
+	}
+
+	sort.Strings(B)
+
+	//check the element of A is in B or not
+	for _, x := range A {
+		if !isInSlice(x, B) {
+			return false
+		}
+	}
+
+	//check the A has duplicate elements
+	dedup := map[string]bool{}
+	for _, x := range A {
+		if _, ok := dedup[x]; ok { //duplicate scope
+			return false
+		}
+		dedup[x] = true
+	}
+
+	return len(A) > 0
+}
+
+/**
+check if x in a slice
+*/
+func isInSlice(x string, arr []string) bool {
+	for _, y := range arr {
+		if x == y {
+			return true
+		}
+	}
+	return false
+}
+
+/**
+check if x in a slice
+*/
+func isInSliceBool(x bool, arr []bool) bool {
+	for _, y := range arr {
+		if x == y {
+			return true
+		}
+	}
+	return false
+}
+
+/**
+check if x in a slice
+*/
+func isInSliceInt64(x int64, arr []int64) bool {
+	for _, y := range arr {
+		if x == y {
+			return true
+		}
+	}
+	return false
+}
+
+/**
+check if x in a slice
+*/
+func isInSliceFloat64(x float64, arr []float64) bool {
+	for _, y := range arr {
+		if x == y {
+			return true
+		}
+	}
+	return false
+}
+
+/**
+check if x has duplicate values.
+*/
+func hasDuplicateValueString(x []string) bool {
+	var dedup = make(map[string]bool)
+	for _, v := range x {
+		if _, ok := dedup[v]; !ok {
+			dedup[v] = true
+		} else {
+			return true
+		}
+	}
+	return false
+}
+
+/**
+check if x has duplicate values.
+*/
+func hasDuplicateValueInt64(x []int64) bool {
+	var dedup = make(map[int64]bool)
+	for _, v := range x {
+		if _, ok := dedup[v]; !ok {
+			dedup[v] = true
+		} else {
+			return true
+		}
+	}
+	return false
+}
+
+/**
+check if x has duplicate values.
+*/
+func hasDuplicateValueFloat64(x []float64) bool {
+	var dedup = make(map[float64]bool)
+	for _, v := range x {
+		if _, ok := dedup[v]; !ok {
+			dedup[v] = true
+		} else {
+			return true
+		}
+	}
+	return false
+}
+
+var defaultParameterTempate = `
+// Code generated by tool; DO NOT EDIT.
+package config
+
+import (
+	"fmt"
+	"sync"
+	"github.com/BurntSushi/toml"
+)
+
+//all parameters in the system
+type {{.ParameterStructName}} struct{
+	//read and write lock
+	rwlock	sync.RWMutex
+{{range .Parameter}}
+	{{ printf "/**\n\tName:\t%s\n\tScope:\t%s\n\tAccess:\t%s\n\tDataType:\t%s\n\tDomainType:\t%s\n\tValues:\t%s\n\tComment:\t%s\n\tUpdateMode:\t%s\n\t*/"  
+			.Name .Scope .Access .DataType .DomainType .Values .Comment .UpdateMode
+	}}
+	{{ printf "%s    %s" .Name .DataType }}
+{{end}}
+
+	//parameter name -> parameter definition string
+	name2definition map[string]string
+}//end {{.ParameterStructName}}
+
+//all parameters can be set in the configuration file.
+type {{.ConfigurationStructName}} struct{
+	//read and write lock
+	rwlock	sync.RWMutex
+
+{{range .Parameter}}
+	{{ if ne .UpdateMode "fix"}}
+	{{ printf "/**\n\tName:\t%s\n\tScope:\t%s\n\tAccess:\t%s\n\tDataType:\t%s\n\tDomainType:\t%s\n\tValues:\t%s\n\tComment:\t%s\n\tUpdateMode:\t%s\n\t*/"  
+			.Name .Scope .Access .DataType .DomainType .Values .Comment .UpdateMode
+	}}
+	{{ printf "%s    %s  ` + "`toml:" + `\"%s\"` + "`" + `" .CapitalName .DataType .Name }}
+
+	{{end}}
+{{end}}
+
+	//parameter name -> updated flag
+	name2updatedFlags map[string]bool
+}//end {{.ConfigurationStructName}}
+
+/**
+prepare something before anything else.
+it is unsafe in multi-thread environment.
+*/
+func (ap *{{.ParameterStructName}}) prepareAnything(){
+	if ap.name2definition == nil {
+		ap.name2definition = make(map[string]string)
+	}
+}
+
+/**
+set parameter and its string of the definition.
+*/
+func (ap *{{.ParameterStructName}}) PrepareDefinition(){
+	ap.rwlock.Lock()
+	defer ap.rwlock.Unlock()
+
+	ap.prepareAnything()
+	{{range .Parameter}}
+	{{ printf "ap.name2definition[\"%s\"] = \"\tName:\t%s\tScope:\t%s\tAccess:\t%s\tDataType:\t%s\tDomainType:\t%s\tValues:\t%s\tComment:\t%s\tUpdateMode:\t%s\t\"" 
+			.Name .Name .Scope .Access .DataType .DomainType .Values .Comment .UpdateMode
+	}}
+	{{end}}
+}
+
+/**
+get the definition of the parameter.
+*/
+func (ap *{{.ParameterStructName}}) GetDefinition(name string)(string,error){
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	ap.prepareAnything()
+	if p,ok := ap.name2definition[name];!ok{
+		return "",fmt.Errorf("there is no parameter %s",name)
+	}else{
+		return p,nil
+	}
+}
+
+/**
+check if there is the parameter
+*/
+func (ap *{{.ParameterStructName}}) HasParameter(name string)bool{
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	ap.prepareAnything()
+	if _,ok := ap.name2definition[name];!ok{
+		return false
+	}else{
+		return true
+	}
+}
+
+/**
+Load the initial values of all parameters.
+*/
+func (ap *{{.ParameterStructName}}) LoadInitialValues()error{
+	ap.PrepareDefinition()
+	var err error
+	{{range .Parameter}}
+		
+		{{if eq .DataType "string"}}
+			{{.Name}}choices :=[]{{.DataType}} {
+				{{range .Values}}
+				{{printf "\"%s\"" .}},
+				{{end}}	
+			}
+			if len({{.Name}}choices) != 0{
+				if err = ap.set{{.CapitalName}}( {{.Name}}choices[0] ) ; err != nil{
+					return fmt.Errorf("set%s failed.error:%v",{{printf "\"%s\"" .CapitalName}},err)
+				}
+			}else{
+				//empty string
+				if err = ap.set{{.CapitalName}}( "" ) ; err != nil{
+					return fmt.Errorf("set%s failed.error:%v",{{printf "\"%s\"" .CapitalName}},err)
+				}
+			}
+		{{else}}
+			{{.Name}}choices :=[]{{.DataType}} {
+				{{range .Values}}
+				{{printf "%s" .}},
+				{{end}}	
+			}
+			if len({{.Name}}choices) != 0{
+				if err = ap.set{{.CapitalName}}( {{.Name}}choices[0] ) ; err != nil{
+					return fmt.Errorf("set%s failed.error:%v",{{printf "\"%s\"" .CapitalName}},err)
+				}
+			}else{
+				{{if eq .DataType "bool"}}
+					if err = ap.set{{.CapitalName}}( false ) ; err != nil{
+						return fmt.Errorf("set%s failed.error:%v",{{printf "\"%s\"" .CapitalName}},err)
+					}	
+				{{else if  eq .DataType "int64"}}
+					if err = ap.set{{.CapitalName}}( 0 ) ; err != nil{
+						return fmt.Errorf("set%s failed.error:%v",{{printf "\"%s\"" .CapitalName}},err)
+					}
+				{{else if eq .DataType "float64"}}
+					if err = ap.set{{.CapitalName}}( 0.0 ) ; err != nil{
+						return fmt.Errorf("set%s failed.error:%v",{{printf "\"%s\"" .CapitalName}},err)
+					}
+				{{end}}
+			}
+		{{end}}
+	{{end}}
+	return nil
+}
+
+{{with $Params := .}}
+{{range $Params.Parameter}}
+/**
+Get the value of the parameter {{.Name}}
+*/
+func (ap * {{$Params.ParameterStructName}} ) Get{{.CapitalName}}() {{.DataType}} {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	return ap.{{.Name}}
+}
+{{end}}
+{{end}}
+
+
+{{with $Params := .}}
+{{range $Params.Parameter}}
+{{ if ne .UpdateMode "fix"}}
+/**
+Set the value of the parameter {{.Name}}
+*/
+func (ap * {{$Params.ParameterStructName}} ) Set{{.CapitalName}}(value {{.DataType}})error {
+	return  ap.set{{.CapitalName}}(value)
+}
+{{end}}
+{{end}}
+{{end}}
+
+{{with $Params := .}}
+{{range $Params.Parameter}}
+/**
+Set the value of the parameter {{.Name}}
+*/
+func (ap * {{$Params.ParameterStructName}} ) set{{.CapitalName}}(value {{.DataType}})error {
+	ap.rwlock.Lock()
+	defer ap.rwlock.Unlock()
+
+	{{if eq .DataType "bool"}}
+		
+		{{if eq .DomainType "set"}}
+			choices :=[]{{.DataType}} {
+				{{range .Values}}
+				{{printf "%s" .}},
+				{{end}}	
+			}
+			if len( choices ) != 0{
+				if !isInSliceBool(value, choices){
+					return fmt.Errorf("set{{.CapitalName}},the value %t is not in set %v",value,choices)
+				}
+			}//else means any bool value: true or false
+		{{else}}
+			return fmt.Errorf("the bool type does not support domainType %s",{{printf "\"%s\"" .DomainType}})
+		{{end}}
+
+	{{else if eq .DataType "string"}}
+
+		{{if eq .DomainType "set"}}
+			choices :=[]{{.DataType}} {
+				{{range .Values}}
+				{{printf "\"%s\"" .}},
+				{{end}}	
+			}
+			if len( choices ) != 0{
+				if !isInSlice(value, choices){
+					return fmt.Errorf("set{{.CapitalName}},the value %s is not in set %v",value,choices)
+				}
+			}//else means any string
+		{{else}}
+			return fmt.Errorf("the string type does not support domainType %s",{{printf "\"%s\"" .DomainType}})
+		{{end}}
+
+	{{else if eq .DataType "int64"}}
+
+		{{if eq .DomainType "set"}}
+			choices :=[]{{.DataType}} {
+				{{range .Values}}
+				{{printf "%s" .}},
+				{{end}}	
+			}
+			if len( choices ) != 0{
+				if !isInSliceInt64(value, choices){
+					return fmt.Errorf("set{{.CapitalName}},the value %d is not in set %v",value,choices)
+				}
+			}//else means any int64
+		{{else if eq .DomainType "range"}}
+			choices :=[]{{.DataType}} {
+				{{range .Values}}
+				{{printf "%s" .}},
+				{{end}}	
+			}
+			if !(value >= choices[1] && value <= choices[2]){
+				return fmt.Errorf("set{{.CapitalName}},the value %d is not in the range [%d,%d]",value,choices[1],choices[2])
+			}
+		{{else}}
+			return fmt.Errorf("the int64 type does not support domainType %s",{{printf "\"%s\"" .DomainType}})
+		{{end}}
+
+	{{else if eq .DataType "float64"}}
+
+		{{if eq .DomainType "set"}}
+			choices :=[]{{.DataType}} {
+				{{range .Values}}
+				{{printf "%s" .}},
+				{{end}}	
+			}
+			if len( choices ) != 0{
+				if !isInSliceFloat64(value, choices){
+					return fmt.Errorf("set{{.CapitalName}},the value %f is not in set %v",value,choices)
+				}
+			}//else means any float64
+		{{else if eq .DomainType "range"}}
+			choices :=[]{{.DataType}} {
+				{{range .Values}}
+				{{printf "%s" .}},
+				{{end}}	
+			}
+			if !(value >= choices[1] && value <= choices[2]){
+				return fmt.Errorf("set{{.CapitalName}},the value %f is not in the range [%f,%f]",value,choices[1],choices[2])
+			}
+		{{else}}
+			return fmt.Errorf("the float64 type does not support domainType %s",{{printf "\"%s\"" .DomainType}})
+		{{end}}
+	{{end}}
+
+	ap.{{.Name}} = value
+	return nil
+}
+{{end}}
+{{end}}
+
+/**
+prepare something before anything else.
+it is unsafe in multi-thread environment.
+*/
+func (config *{{.ConfigurationStructName}}) prepareAnything(){
+	if config.name2updatedFlags == nil {
+		config.name2updatedFlags = make(map[string]bool)
+	}
+}
+
+/**
+reset update flags of configuration items
+*/
+func (config *{{.ConfigurationStructName}}) resetUpdatedFlags(){
+	config.rwlock.Lock()
+	defer config.rwlock.Unlock()
+	config.prepareAnything()
+	{{range .Parameter}}
+	{{ if ne .UpdateMode "fix"}}
+		{{ printf "config.name2updatedFlags[\"%s\"] = false" .Name}}
+	{{end}}
+	{{end}}
+}
+
+/**
+set update flag of configuration item
+*/
+func (config *{{.ConfigurationStructName}}) setUpdatedFlag(name string,updated bool){
+	config.rwlock.Lock()
+	defer config.rwlock.Unlock()
+	config.prepareAnything()
+	config.name2updatedFlags[name] = updated
+}
+
+/**
+get update flag of configuration item
+*/
+func (config *{{.ConfigurationStructName}}) getUpdatedFlag(name string)bool{
+	config.rwlock.RLock()
+	defer config.rwlock.RUnlock()
+	config.prepareAnything()
+	return config.name2updatedFlags[name]
+}
+
+/**
+Load parameters' values in the configuration string.
+*/
+func (config *{{.ConfigurationStructName}}) LoadConfigurationFromString(input string) error {
+	config.resetUpdatedFlags()
+
+	metadata, err := toml.Decode(input, config);
+	if err != nil {
+		return err
+	}else if failed := metadata.Undecoded() ; len(failed) > 0 {
+		var failedItems []string
+		for _, item := range failed {
+			failedItems = append(failedItems, item.String())
+		}
+		return fmt.Errorf("decode failed %s. error:%v",failedItems,err)
+	}
+
+	for _,k := range metadata.Keys(){
+		config.setUpdatedFlag(k[0],true)
+	}
+
+	return nil
+}
+
+/**
+Load parameters' values in the configuration file.
+*/
+func (config *{{.ConfigurationStructName}}) LoadConfigurationFromFile(fname string) error {
+	config.resetUpdatedFlags()
+
+	metadata, err := toml.DecodeFile(fname, config);
+	if err != nil {
+		return err
+	}else if failed := metadata.Undecoded() ; len(failed) > 0 {
+		var failedItems []string
+		for _, item := range failed {
+			failedItems = append(failedItems, item.String())
+		}
+		return fmt.Errorf("decode failed %s. error:%v",failedItems,err)
+	}
+
+	for _,k := range metadata.Keys(){
+		config.setUpdatedFlag(k[0],true)
+	}
+
+	return nil
+}
+
+/**
+Update parameters' values with configuration.
+*/
+func (ap * {{.ParameterStructName}} ) UpdateParametersWithConfiguration(config *{{.ConfigurationStructName}})error{
+	var err error
+	{{range .Parameter}}
+	{{ if ne .UpdateMode "fix"}}
+	if config.getUpdatedFlag("{{.Name}}"){
+		if err = ap.set{{.CapitalName}}(config.{{.CapitalName}}); err != nil{
+			return fmt.Errorf("update parameter {{.Name}} failed.error:%v",err)
+		}
+	}
+	{{end}}
+	{{end}}
+	return nil
+}
+
+/**
+Load configuration from file into {{.ConfigurationStructName}}.
+Then update items into {{.ParameterStructName}}
+*/
+func Load{{.ConfigurationStructName}}FromFile(filename string,params *{{.ParameterStructName}}) error{
+	config := &{{.ConfigurationStructName}}{}
+	if err := config.LoadConfigurationFromFile(filename); err != nil{
+		return err
+	}
+
+	if err := params.UpdateParametersWithConfiguration(config); err != nil{
+		return err
+	}
+	return nil
+}
+`
+
+var defaultConfigurationTemplate = `
+# Code generated by tool; DO NOT EDIT.
+{{range $index,$param := .Parameter}}
+{{ if ne .UpdateMode "fix"}}
+	{{ printf "\n#\tName:\t%s\n#\tScope:\t%s\n#\tAccess:\t%s\n#\tDataType:\t%s\n#\tDomainType:\t%s\n#\tValues:\t%s\n#\tComment:\t%s\n#\tUpdateMode:\t%s\n\t"  
+			.Name .Scope .Access .DataType .DomainType .Values .Comment .UpdateMode
+	}}
+
+	{{- with $count := len .Values -}}
+		{{- if ne 0 $count -}}
+			{{- if eq $param.DataType "string" -}}
+				{{- $param.Name -}} = "{{- index $param.Values 0 -}}"
+			{{- else -}}
+				{{- $param.Name -}} = {{- index $param.Values 0 -}}
+			{{- end -}}
+		{{- end -}}
+	{{- else -}}
+		{{- if eq $param.DataType "string" -}}
+			{{- $param.Name -}} = ""
+		{{- else if eq $param.DataType "bool" -}}
+			{{- $param.Name -}} = false
+		{{- else if eq $param.DataType "int64" -}}
+			{{- $param.Name -}} = 0
+		{{- else if eq $param.DataType "float64" -}}
+			{{- $param.Name -}} = 0.0
+		{{- end -}}
+	{{- end -}}
+{{end}}
+{{end}}
+`
+
+var defaultOperationTestTemplate = `
+// Code generated by tool; DO NOT EDIT.
+package config
+
+import (
+	"sync"
+	"testing"
+)
+
+func Test{{.ParameterStructName}}_LoadInitialValues(t *testing.T) {
+	ap := &{{.ParameterStructName}}{}
+	if err :=ap.LoadInitialValues(); err!=nil{
+		t.Errorf("LoadInitialValues failed. error:%v",err)
+	}
+}
+
+func is{{.ConfigurationStructName}}Equal(c1,c2 {{.ConfigurationStructName}}) bool {
+
+{{range .Parameter}}
+{{ if ne .UpdateMode "fix"}}
+	if c1.{{.CapitalName}} != c2.{{.CapitalName}} {
+		return false
+	}
+{{end}}
+{{end}}
+
+	return true
+}
+
+func Test_{{.ConfigurationStructName}}_LoadConfigurationFromString(t *testing.T) {
+	t1 := ` + "`" + `
+{{range $index,$param := .Parameter}}
+{{ if ne .UpdateMode "fix"}}
+	{{- with $count := len .Values -}}
+		{{- if ne 0 $count -}}
+			{{- if eq $param.DataType "string" -}}
+				{{- $param.Name -}} = "{{- index $param.Values 0 -}}"
+			{{- else -}}
+				{{- $param.Name -}} = {{- index $param.Values 0 -}}
+			{{- end -}}
+		{{- end -}}
+	{{- else -}}
+		{{- if eq $param.DataType "string" -}}
+			{{- $param.Name -}} = ""
+		{{- else if eq $param.DataType "bool" -}}
+			{{- $param.Name -}} = false
+		{{- else if eq $param.DataType "int64" -}}
+			{{- $param.Name -}} = 0
+		{{- else if eq $param.DataType "float64" -}}
+			{{- $param.Name -}} = 0.0
+		{{- end -}}
+	{{- end -}}
+{{end}}
+{{end}}		
+` + "`" + `
+	t1_config:={{.ConfigurationStructName}}{
+		rwlock:            sync.RWMutex{},
+
+{{range $index,$param := .Parameter}}
+{{ if ne .UpdateMode "fix"}}
+	{{- with $count := len .Values -}}
+		{{- if ne 0 $count -}}
+			{{- if eq $param.DataType "string" -}}
+				{{- $param.CapitalName -}} : "{{- index $param.Values 0 -}}" ,
+			{{- else -}}
+				{{- $param.CapitalName -}} : {{- index $param.Values 0 -}} ,
+			{{- end -}}
+		{{- end -}}
+	{{- else -}}
+		{{- if eq $param.DataType "string" -}}
+			{{- $param.CapitalName -}} : "" ,
+		{{- else if eq $param.DataType "bool" -}}
+			{{- $param.CapitalName -}} : false ,
+		{{- else if eq $param.DataType "int64" -}}
+			{{- $param.CapitalName -}} : 0 ,
+		{{- else if eq $param.DataType "float64" -}}
+			{{- $param.CapitalName -}} : 0.0 ,
+		{{- end -}}
+	{{- end -}}
+{{end}}
+{{end}}	
+
+		name2updatedFlags: nil,
+	}
+
+	type args struct {
+		input string
+		config {{.ConfigurationStructName}}
+	}
+	tests := []struct {
+		name    string
+		args    args
+		wantErr bool
+		wantErr2 bool
+		wantErr3 bool
+	}{
+		{"t1",args{t1,t1_config},false,false,false},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			ap := &{{.ParameterStructName}}{}
+			if err := ap.LoadInitialValues(); err != nil{
+				t.Errorf("LoadInitialValues failed.error %v",err)
+			}
+			config := &{{.ConfigurationStructName}}{}
+			if err := config.LoadConfigurationFromString(tt.args.input); (err != nil) != tt.wantErr {
+				t.Errorf("LoadConfigurationFromString() error = %v, wantErr %v", err, tt.wantErr)
+			}else if err != nil{
+				return
+			}
+
+			if err := ap.UpdateParametersWithConfiguration(config); (err != nil) != tt.wantErr2{
+				t.Errorf("UpdateParametersWithConfiguration failed. error:%v",err)
+			}
+
+			if ( is{{.ConfigurationStructName}}Equal(*config,tt.args.config) != true ) != tt.wantErr3{
+				t.Errorf("Configuration are not equal. %v vs %v ",*config,tt.args.config)
+				return
+			}
+		})
+	}
+}
+`
+
+/**
+Analyse the template files.
+Generate configuration file, operation interfaces.
+*/
+type ConfigurationFileGenerator interface {
+	/**
+	Input: parameter definition file name
+	Output:
+		1. operation interface and code for parameters
+		2. configuraion file for parameters
+	*/
+	Generate() error
+}
+
+type ConfigurationFileGeneratorImpl struct {
+	//the name of the parameter definition
+	parameterDefinitionFileName string
+
+	//the template string for the auto generated parameter operation interfaces and classes.
+	parameterTemplate string
+
+	//the template string for the auto generated initial configuration file.
+	configurationTemplate string
+
+	//the template string for the auto generated parameter operation interfaces test cases.
+	parameterTestCasesTemplate string
+}
+
+func (cfgi *ConfigurationFileGeneratorImpl) Generate() error {
+	defDir, err := filepath.Abs(filepath.Dir(cfgi.parameterDefinitionFileName))
+	if err != nil {
+		return fmt.Errorf("Get the directory of parameter defintion file failed.error:%v", err)
+	}
+
+	params := &parameters{}
+	if err := params.LoadParametersDefinitionFromFile(cfgi.parameterDefinitionFileName); err != nil {
+		return fmt.Errorf("LoadParametersDefinitionFromFile failed.error:%v", err)
+	}
+
+	parameterTmpl, err := template.New("MakeParameterTemplate").Parse(cfgi.parameterTemplate)
+	if err != nil {
+		return fmt.Errorf("Make parameter template failed. error:%v", err)
+	}
+
+	f, err := os.Create(defDir + "/" + params.OperationFileName + ".go")
+	if err != nil {
+		return err
+	}
+	defer f.Close()
+
+	err = parameterTmpl.Execute(f, params)
+	if err != nil {
+		return err
+	}
+
+	tomlTmpl, err := template.New("MakeConfigurationTemplate").Parse(cfgi.configurationTemplate)
+	if err != nil {
+		return err
+	}
+
+	tomlf, err := os.Create(defDir + "/" + params.ConfigurationFileName + ".toml")
+	if err != nil {
+		return err
+	}
+	defer tomlf.Close()
+
+	err = tomlTmpl.Execute(tomlf, params)
+	if err != nil {
+		return err
+	}
+
+	testCasesTmpl, err := template.New("MakeTestCasesTemplate").Parse(cfgi.parameterTestCasesTemplate)
+	if err != nil {
+		return err
+	}
+
+	testCasesf, err := os.Create(defDir + "/" + params.OperationFileName + "_test.go")
+	if err != nil {
+		return err
+	}
+	defer testCasesf.Close()
+
+	err = testCasesTmpl.Execute(testCasesf, params)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+/**
+load items from configuration file periodly.
+*/
+type ConfigurationFileHotLoader interface {
+	/**
+	register a configuration file into the loader.
+	path : the path of the configuration file
+	period: load the configration every period
+	configObject: the target that will be updated
+	*/
+	Register(path string, period int64, configObject interface{})
+
+	/**
+	unregister a configuration file from the loader.
+	the configuration file will be loaded again.
+	*/
+	Unregister(path string)
+}
+
+func NewConfigurationFileGenerator(defFileName string) ConfigurationFileGenerator {
+	return &ConfigurationFileGeneratorImpl{
+		parameterDefinitionFileName: defFileName,
+		parameterTemplate:           defaultParameterTempate,
+		configurationTemplate:       defaultConfigurationTemplate,
+		parameterTestCasesTemplate:  defaultOperationTestTemplate,
+	}
+}
diff --git a/pkg/config/test/parameters.go b/pkg/config/test/parameters.go
new file mode 100644
index 0000000000000000000000000000000000000000..bb821bfbc2311b12738c5a27e0cc6314ebc806b0
--- /dev/null
+++ b/pkg/config/test/parameters.go
@@ -0,0 +1,1333 @@
+// Code generated by tool; DO NOT EDIT.
+package config
+
+import (
+	"fmt"
+	"github.com/BurntSushi/toml"
+	"sync"
+)
+
+//all parameters in the system
+type AllParameters struct {
+	//read and write lock
+	rwlock sync.RWMutex
+
+	/**
+	Name:	boolSet1
+	Scope:	[global]
+	Access:	[file]
+	DataType:	bool
+	DomainType:	set
+	Values:	[true]
+	Comment:	boolSet1
+	UpdateMode:	dynamic
+	*/
+	boolSet1 bool
+
+	/**
+	Name:	boolSet2
+	Scope:	[global]
+	Access:	[file]
+	DataType:	bool
+	DomainType:	set
+	Values:	[false]
+	Comment:	boolSet2
+	UpdateMode:	hotload
+	*/
+	boolSet2 bool
+
+	/**
+	Name:	boolSet3
+	Scope:	[global]
+	Access:	[file]
+	DataType:	bool
+	DomainType:	set
+	Values:	[]
+	Comment:	boolSet3
+	UpdateMode:	dynamic
+	*/
+	boolSet3 bool
+
+	/**
+	Name:	stringSet1
+	Scope:	[global]
+	Access:	[file]
+	DataType:	string
+	DomainType:	set
+	Values:	[ss1 ss2 ss3]
+	Comment:	stringSet1
+	UpdateMode:	dynamic
+	*/
+	stringSet1 string
+
+	/**
+	Name:	stringSet2
+	Scope:	[global]
+	Access:	[file]
+	DataType:	string
+	DomainType:	set
+	Values:	[]
+	Comment:	stringSet2
+	UpdateMode:	dynamic
+	*/
+	stringSet2 string
+
+	/**
+	Name:	int64set1
+	Scope:	[global]
+	Access:	[file]
+	DataType:	int64
+	DomainType:	set
+	Values:	[1 2 3 4 5 6]
+	Comment:	int64Set1
+	UpdateMode:	dynamic
+	*/
+	int64set1 int64
+
+	/**
+	Name:	int64set2
+	Scope:	[global]
+	Access:	[file]
+	DataType:	int64
+	DomainType:	set
+	Values:	[1 3 5 7]
+	Comment:	int64Set2
+	UpdateMode:	fix
+	*/
+	int64set2 int64
+
+	/**
+	Name:	int64set3
+	Scope:	[global]
+	Access:	[file]
+	DataType:	int64
+	DomainType:	set
+	Values:	[]
+	Comment:	int64Set3
+	UpdateMode:	dynamic
+	*/
+	int64set3 int64
+
+	/**
+	Name:	int64Range1
+	Scope:	[global]
+	Access:	[file]
+	DataType:	int64
+	DomainType:	range
+	Values:	[1000 0 10000]
+	Comment:	int64Range1
+	UpdateMode:	dynamic
+	*/
+	int64Range1 int64
+
+	/**
+	Name:	float64set1
+	Scope:	[global]
+	Access:	[file]
+	DataType:	float64
+	DomainType:	set
+	Values:	[1.0 2.0 3.0 4.00 5.0 6.0]
+	Comment:	float64Set1
+	UpdateMode:	dynamic
+	*/
+	float64set1 float64
+
+	/**
+	Name:	float64set2
+	Scope:	[global]
+	Access:	[file]
+	DataType:	float64
+	DomainType:	set
+	Values:	[1.001 3.003 5.005 7.007]
+	Comment:	float64Set2
+	UpdateMode:	fix
+	*/
+	float64set2 float64
+
+	/**
+	Name:	float64set3
+	Scope:	[global]
+	Access:	[file]
+	DataType:	float64
+	DomainType:	set
+	Values:	[]
+	Comment:	float64Set3
+	UpdateMode:	dynamic
+	*/
+	float64set3 float64
+
+	/**
+	Name:	float64Range1
+	Scope:	[global]
+	Access:	[file]
+	DataType:	float64
+	DomainType:	range
+	Values:	[1000.01 0.02 10000.03]
+	Comment:	float64Range1
+	UpdateMode:	dynamic
+	*/
+	float64Range1 float64
+
+	//parameter name -> parameter definition string
+	name2definition map[string]string
+} //end AllParameters
+
+//all parameters can be set in the configuration file.
+type configuration struct {
+	//read and write lock
+	rwlock sync.RWMutex
+
+	/**
+	Name:	boolSet1
+	Scope:	[global]
+	Access:	[file]
+	DataType:	bool
+	DomainType:	set
+	Values:	[true]
+	Comment:	boolSet1
+	UpdateMode:	dynamic
+	*/
+	BoolSet1 bool `toml:"boolSet1"`
+
+	/**
+	Name:	boolSet2
+	Scope:	[global]
+	Access:	[file]
+	DataType:	bool
+	DomainType:	set
+	Values:	[false]
+	Comment:	boolSet2
+	UpdateMode:	hotload
+	*/
+	BoolSet2 bool `toml:"boolSet2"`
+
+	/**
+	Name:	boolSet3
+	Scope:	[global]
+	Access:	[file]
+	DataType:	bool
+	DomainType:	set
+	Values:	[]
+	Comment:	boolSet3
+	UpdateMode:	dynamic
+	*/
+	BoolSet3 bool `toml:"boolSet3"`
+
+	/**
+	Name:	stringSet1
+	Scope:	[global]
+	Access:	[file]
+	DataType:	string
+	DomainType:	set
+	Values:	[ss1 ss2 ss3]
+	Comment:	stringSet1
+	UpdateMode:	dynamic
+	*/
+	StringSet1 string `toml:"stringSet1"`
+
+	/**
+	Name:	stringSet2
+	Scope:	[global]
+	Access:	[file]
+	DataType:	string
+	DomainType:	set
+	Values:	[]
+	Comment:	stringSet2
+	UpdateMode:	dynamic
+	*/
+	StringSet2 string `toml:"stringSet2"`
+
+	/**
+	Name:	int64set1
+	Scope:	[global]
+	Access:	[file]
+	DataType:	int64
+	DomainType:	set
+	Values:	[1 2 3 4 5 6]
+	Comment:	int64Set1
+	UpdateMode:	dynamic
+	*/
+	Int64set1 int64 `toml:"int64set1"`
+
+	/**
+	Name:	int64set3
+	Scope:	[global]
+	Access:	[file]
+	DataType:	int64
+	DomainType:	set
+	Values:	[]
+	Comment:	int64Set3
+	UpdateMode:	dynamic
+	*/
+	Int64set3 int64 `toml:"int64set3"`
+
+	/**
+	Name:	int64Range1
+	Scope:	[global]
+	Access:	[file]
+	DataType:	int64
+	DomainType:	range
+	Values:	[1000 0 10000]
+	Comment:	int64Range1
+	UpdateMode:	dynamic
+	*/
+	Int64Range1 int64 `toml:"int64Range1"`
+
+	/**
+	Name:	float64set1
+	Scope:	[global]
+	Access:	[file]
+	DataType:	float64
+	DomainType:	set
+	Values:	[1.0 2.0 3.0 4.00 5.0 6.0]
+	Comment:	float64Set1
+	UpdateMode:	dynamic
+	*/
+	Float64set1 float64 `toml:"float64set1"`
+
+	/**
+	Name:	float64set3
+	Scope:	[global]
+	Access:	[file]
+	DataType:	float64
+	DomainType:	set
+	Values:	[]
+	Comment:	float64Set3
+	UpdateMode:	dynamic
+	*/
+	Float64set3 float64 `toml:"float64set3"`
+
+	/**
+	Name:	float64Range1
+	Scope:	[global]
+	Access:	[file]
+	DataType:	float64
+	DomainType:	range
+	Values:	[1000.01 0.02 10000.03]
+	Comment:	float64Range1
+	UpdateMode:	dynamic
+	*/
+	Float64Range1 float64 `toml:"float64Range1"`
+
+	//parameter name -> updated flag
+	name2updatedFlags map[string]bool
+} //end configuration
+
+/**
+prepare something before anything else.
+it is unsafe in multi-thread environment.
+*/
+func (ap *AllParameters) prepareAnything() {
+	if ap.name2definition == nil {
+		ap.name2definition = make(map[string]string)
+	}
+}
+
+/**
+set parameter and its string of the definition.
+*/
+func (ap *AllParameters) PrepareDefinition() {
+	ap.rwlock.Lock()
+	defer ap.rwlock.Unlock()
+
+	ap.prepareAnything()
+
+	ap.name2definition["boolSet1"] = "	Name:	boolSet1	Scope:	[global]	Access:	[file]	DataType:	bool	DomainType:	set	Values:	[true]	Comment:	boolSet1	UpdateMode:	dynamic	"
+
+	ap.name2definition["boolSet2"] = "	Name:	boolSet2	Scope:	[global]	Access:	[file]	DataType:	bool	DomainType:	set	Values:	[false]	Comment:	boolSet2	UpdateMode:	hotload	"
+
+	ap.name2definition["boolSet3"] = "	Name:	boolSet3	Scope:	[global]	Access:	[file]	DataType:	bool	DomainType:	set	Values:	[]	Comment:	boolSet3	UpdateMode:	dynamic	"
+
+	ap.name2definition["stringSet1"] = "	Name:	stringSet1	Scope:	[global]	Access:	[file]	DataType:	string	DomainType:	set	Values:	[ss1 ss2 ss3]	Comment:	stringSet1	UpdateMode:	dynamic	"
+
+	ap.name2definition["stringSet2"] = "	Name:	stringSet2	Scope:	[global]	Access:	[file]	DataType:	string	DomainType:	set	Values:	[]	Comment:	stringSet2	UpdateMode:	dynamic	"
+
+	ap.name2definition["int64set1"] = "	Name:	int64set1	Scope:	[global]	Access:	[file]	DataType:	int64	DomainType:	set	Values:	[1 2 3 4 5 6]	Comment:	int64Set1	UpdateMode:	dynamic	"
+
+	ap.name2definition["int64set2"] = "	Name:	int64set2	Scope:	[global]	Access:	[file]	DataType:	int64	DomainType:	set	Values:	[1 3 5 7]	Comment:	int64Set2	UpdateMode:	fix	"
+
+	ap.name2definition["int64set3"] = "	Name:	int64set3	Scope:	[global]	Access:	[file]	DataType:	int64	DomainType:	set	Values:	[]	Comment:	int64Set3	UpdateMode:	dynamic	"
+
+	ap.name2definition["int64Range1"] = "	Name:	int64Range1	Scope:	[global]	Access:	[file]	DataType:	int64	DomainType:	range	Values:	[1000 0 10000]	Comment:	int64Range1	UpdateMode:	dynamic	"
+
+	ap.name2definition["float64set1"] = "	Name:	float64set1	Scope:	[global]	Access:	[file]	DataType:	float64	DomainType:	set	Values:	[1.0 2.0 3.0 4.00 5.0 6.0]	Comment:	float64Set1	UpdateMode:	dynamic	"
+
+	ap.name2definition["float64set2"] = "	Name:	float64set2	Scope:	[global]	Access:	[file]	DataType:	float64	DomainType:	set	Values:	[1.001 3.003 5.005 7.007]	Comment:	float64Set2	UpdateMode:	fix	"
+
+	ap.name2definition["float64set3"] = "	Name:	float64set3	Scope:	[global]	Access:	[file]	DataType:	float64	DomainType:	set	Values:	[]	Comment:	float64Set3	UpdateMode:	dynamic	"
+
+	ap.name2definition["float64Range1"] = "	Name:	float64Range1	Scope:	[global]	Access:	[file]	DataType:	float64	DomainType:	range	Values:	[1000.01 0.02 10000.03]	Comment:	float64Range1	UpdateMode:	dynamic	"
+
+}
+
+/**
+get the definition of the parameter.
+*/
+func (ap *AllParameters) GetDefinition(name string) (string, error) {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	ap.prepareAnything()
+	if p, ok := ap.name2definition[name]; !ok {
+		return "", fmt.Errorf("there is no parameter %s", name)
+	} else {
+		return p, nil
+	}
+}
+
+/**
+check if there is the parameter
+*/
+func (ap *AllParameters) HasParameter(name string) bool {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	ap.prepareAnything()
+	if _, ok := ap.name2definition[name]; !ok {
+		return false
+	} else {
+		return true
+	}
+}
+
+/**
+Load the initial values of all parameters.
+*/
+func (ap *AllParameters) LoadInitialValues() error {
+	ap.PrepareDefinition()
+	var err error
+
+	boolSet1choices := []bool{
+
+		true,
+	}
+	if len(boolSet1choices) != 0 {
+		if err = ap.setBoolSet1(boolSet1choices[0]); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "BoolSet1", err)
+		}
+	} else {
+
+		if err = ap.setBoolSet1(false); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "BoolSet1", err)
+		}
+
+	}
+
+	boolSet2choices := []bool{
+
+		false,
+	}
+	if len(boolSet2choices) != 0 {
+		if err = ap.setBoolSet2(boolSet2choices[0]); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "BoolSet2", err)
+		}
+	} else {
+
+		if err = ap.setBoolSet2(false); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "BoolSet2", err)
+		}
+
+	}
+
+	boolSet3choices := []bool{}
+	if len(boolSet3choices) != 0 {
+		if err = ap.setBoolSet3(boolSet3choices[0]); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "BoolSet3", err)
+		}
+	} else {
+
+		if err = ap.setBoolSet3(false); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "BoolSet3", err)
+		}
+
+	}
+
+	stringSet1choices := []string{
+
+		"ss1",
+
+		"ss2",
+
+		"ss3",
+	}
+	if len(stringSet1choices) != 0 {
+		if err = ap.setStringSet1(stringSet1choices[0]); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "StringSet1", err)
+		}
+	} else {
+		//empty string
+		if err = ap.setStringSet1(""); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "StringSet1", err)
+		}
+	}
+
+	stringSet2choices := []string{}
+	if len(stringSet2choices) != 0 {
+		if err = ap.setStringSet2(stringSet2choices[0]); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "StringSet2", err)
+		}
+	} else {
+		//empty string
+		if err = ap.setStringSet2(""); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "StringSet2", err)
+		}
+	}
+
+	int64set1choices := []int64{
+
+		1,
+
+		2,
+
+		3,
+
+		4,
+
+		5,
+
+		6,
+	}
+	if len(int64set1choices) != 0 {
+		if err = ap.setInt64set1(int64set1choices[0]); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Int64set1", err)
+		}
+	} else {
+
+		if err = ap.setInt64set1(0); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Int64set1", err)
+		}
+
+	}
+
+	int64set2choices := []int64{
+
+		1,
+
+		3,
+
+		5,
+
+		7,
+	}
+	if len(int64set2choices) != 0 {
+		if err = ap.setInt64set2(int64set2choices[0]); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Int64set2", err)
+		}
+	} else {
+
+		if err = ap.setInt64set2(0); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Int64set2", err)
+		}
+
+	}
+
+	int64set3choices := []int64{}
+	if len(int64set3choices) != 0 {
+		if err = ap.setInt64set3(int64set3choices[0]); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Int64set3", err)
+		}
+	} else {
+
+		if err = ap.setInt64set3(0); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Int64set3", err)
+		}
+
+	}
+
+	int64Range1choices := []int64{
+
+		1000,
+
+		0,
+
+		10000,
+	}
+	if len(int64Range1choices) != 0 {
+		if err = ap.setInt64Range1(int64Range1choices[0]); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Int64Range1", err)
+		}
+	} else {
+
+		if err = ap.setInt64Range1(0); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Int64Range1", err)
+		}
+
+	}
+
+	float64set1choices := []float64{
+
+		1.0,
+
+		2.0,
+
+		3.0,
+
+		4.00,
+
+		5.0,
+
+		6.0,
+	}
+	if len(float64set1choices) != 0 {
+		if err = ap.setFloat64set1(float64set1choices[0]); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Float64set1", err)
+		}
+	} else {
+
+		if err = ap.setFloat64set1(0.0); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Float64set1", err)
+		}
+
+	}
+
+	float64set2choices := []float64{
+
+		1.001,
+
+		3.003,
+
+		5.005,
+
+		7.007,
+	}
+	if len(float64set2choices) != 0 {
+		if err = ap.setFloat64set2(float64set2choices[0]); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Float64set2", err)
+		}
+	} else {
+
+		if err = ap.setFloat64set2(0.0); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Float64set2", err)
+		}
+
+	}
+
+	float64set3choices := []float64{}
+	if len(float64set3choices) != 0 {
+		if err = ap.setFloat64set3(float64set3choices[0]); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Float64set3", err)
+		}
+	} else {
+
+		if err = ap.setFloat64set3(0.0); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Float64set3", err)
+		}
+
+	}
+
+	float64Range1choices := []float64{
+
+		1000.01,
+
+		0.02,
+
+		10000.03,
+	}
+	if len(float64Range1choices) != 0 {
+		if err = ap.setFloat64Range1(float64Range1choices[0]); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Float64Range1", err)
+		}
+	} else {
+
+		if err = ap.setFloat64Range1(0.0); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Float64Range1", err)
+		}
+
+	}
+
+	return nil
+}
+
+/**
+Get the value of the parameter boolSet1
+*/
+func (ap *AllParameters) GetBoolSet1() bool {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	return ap.boolSet1
+}
+
+/**
+Get the value of the parameter boolSet2
+*/
+func (ap *AllParameters) GetBoolSet2() bool {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	return ap.boolSet2
+}
+
+/**
+Get the value of the parameter boolSet3
+*/
+func (ap *AllParameters) GetBoolSet3() bool {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	return ap.boolSet3
+}
+
+/**
+Get the value of the parameter stringSet1
+*/
+func (ap *AllParameters) GetStringSet1() string {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	return ap.stringSet1
+}
+
+/**
+Get the value of the parameter stringSet2
+*/
+func (ap *AllParameters) GetStringSet2() string {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	return ap.stringSet2
+}
+
+/**
+Get the value of the parameter int64set1
+*/
+func (ap *AllParameters) GetInt64set1() int64 {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	return ap.int64set1
+}
+
+/**
+Get the value of the parameter int64set2
+*/
+func (ap *AllParameters) GetInt64set2() int64 {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	return ap.int64set2
+}
+
+/**
+Get the value of the parameter int64set3
+*/
+func (ap *AllParameters) GetInt64set3() int64 {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	return ap.int64set3
+}
+
+/**
+Get the value of the parameter int64Range1
+*/
+func (ap *AllParameters) GetInt64Range1() int64 {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	return ap.int64Range1
+}
+
+/**
+Get the value of the parameter float64set1
+*/
+func (ap *AllParameters) GetFloat64set1() float64 {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	return ap.float64set1
+}
+
+/**
+Get the value of the parameter float64set2
+*/
+func (ap *AllParameters) GetFloat64set2() float64 {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	return ap.float64set2
+}
+
+/**
+Get the value of the parameter float64set3
+*/
+func (ap *AllParameters) GetFloat64set3() float64 {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	return ap.float64set3
+}
+
+/**
+Get the value of the parameter float64Range1
+*/
+func (ap *AllParameters) GetFloat64Range1() float64 {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	return ap.float64Range1
+}
+
+/**
+Set the value of the parameter boolSet1
+*/
+func (ap *AllParameters) SetBoolSet1(value bool) error {
+	return ap.setBoolSet1(value)
+}
+
+/**
+Set the value of the parameter boolSet2
+*/
+func (ap *AllParameters) SetBoolSet2(value bool) error {
+	return ap.setBoolSet2(value)
+}
+
+/**
+Set the value of the parameter boolSet3
+*/
+func (ap *AllParameters) SetBoolSet3(value bool) error {
+	return ap.setBoolSet3(value)
+}
+
+/**
+Set the value of the parameter stringSet1
+*/
+func (ap *AllParameters) SetStringSet1(value string) error {
+	return ap.setStringSet1(value)
+}
+
+/**
+Set the value of the parameter stringSet2
+*/
+func (ap *AllParameters) SetStringSet2(value string) error {
+	return ap.setStringSet2(value)
+}
+
+/**
+Set the value of the parameter int64set1
+*/
+func (ap *AllParameters) SetInt64set1(value int64) error {
+	return ap.setInt64set1(value)
+}
+
+/**
+Set the value of the parameter int64set3
+*/
+func (ap *AllParameters) SetInt64set3(value int64) error {
+	return ap.setInt64set3(value)
+}
+
+/**
+Set the value of the parameter int64Range1
+*/
+func (ap *AllParameters) SetInt64Range1(value int64) error {
+	return ap.setInt64Range1(value)
+}
+
+/**
+Set the value of the parameter float64set1
+*/
+func (ap *AllParameters) SetFloat64set1(value float64) error {
+	return ap.setFloat64set1(value)
+}
+
+/**
+Set the value of the parameter float64set3
+*/
+func (ap *AllParameters) SetFloat64set3(value float64) error {
+	return ap.setFloat64set3(value)
+}
+
+/**
+Set the value of the parameter float64Range1
+*/
+func (ap *AllParameters) SetFloat64Range1(value float64) error {
+	return ap.setFloat64Range1(value)
+}
+
+/**
+Set the value of the parameter boolSet1
+*/
+func (ap *AllParameters) setBoolSet1(value bool) error {
+	ap.rwlock.Lock()
+	defer ap.rwlock.Unlock()
+
+	choices := []bool{
+
+		true,
+	}
+	if len(choices) != 0 {
+		if !isInSliceBool(value, choices) {
+			return fmt.Errorf("setBoolSet1,the value %t is not in set %v", value, choices)
+		}
+	} //else means any bool value: true or false
+
+	ap.boolSet1 = value
+	return nil
+}
+
+/**
+Set the value of the parameter boolSet2
+*/
+func (ap *AllParameters) setBoolSet2(value bool) error {
+	ap.rwlock.Lock()
+	defer ap.rwlock.Unlock()
+
+	choices := []bool{
+
+		false,
+	}
+	if len(choices) != 0 {
+		if !isInSliceBool(value, choices) {
+			return fmt.Errorf("setBoolSet2,the value %t is not in set %v", value, choices)
+		}
+	} //else means any bool value: true or false
+
+	ap.boolSet2 = value
+	return nil
+}
+
+/**
+Set the value of the parameter boolSet3
+*/
+func (ap *AllParameters) setBoolSet3(value bool) error {
+	ap.rwlock.Lock()
+	defer ap.rwlock.Unlock()
+
+	choices := []bool{}
+	if len(choices) != 0 {
+		if !isInSliceBool(value, choices) {
+			return fmt.Errorf("setBoolSet3,the value %t is not in set %v", value, choices)
+		}
+	} //else means any bool value: true or false
+
+	ap.boolSet3 = value
+	return nil
+}
+
+/**
+Set the value of the parameter stringSet1
+*/
+func (ap *AllParameters) setStringSet1(value string) error {
+	ap.rwlock.Lock()
+	defer ap.rwlock.Unlock()
+
+	choices := []string{
+
+		"ss1",
+
+		"ss2",
+
+		"ss3",
+	}
+	if len(choices) != 0 {
+		if !isInSlice(value, choices) {
+			return fmt.Errorf("setStringSet1,the value %s is not in set %v", value, choices)
+		}
+	} //else means any string
+
+	ap.stringSet1 = value
+	return nil
+}
+
+/**
+Set the value of the parameter stringSet2
+*/
+func (ap *AllParameters) setStringSet2(value string) error {
+	ap.rwlock.Lock()
+	defer ap.rwlock.Unlock()
+
+	choices := []string{}
+	if len(choices) != 0 {
+		if !isInSlice(value, choices) {
+			return fmt.Errorf("setStringSet2,the value %s is not in set %v", value, choices)
+		}
+	} //else means any string
+
+	ap.stringSet2 = value
+	return nil
+}
+
+/**
+Set the value of the parameter int64set1
+*/
+func (ap *AllParameters) setInt64set1(value int64) error {
+	ap.rwlock.Lock()
+	defer ap.rwlock.Unlock()
+
+	choices := []int64{
+
+		1,
+
+		2,
+
+		3,
+
+		4,
+
+		5,
+
+		6,
+	}
+	if len(choices) != 0 {
+		if !isInSliceInt64(value, choices) {
+			return fmt.Errorf("setInt64set1,the value %d is not in set %v", value, choices)
+		}
+	} //else means any int64
+
+	ap.int64set1 = value
+	return nil
+}
+
+/**
+Set the value of the parameter int64set2
+*/
+func (ap *AllParameters) setInt64set2(value int64) error {
+	ap.rwlock.Lock()
+	defer ap.rwlock.Unlock()
+
+	choices := []int64{
+
+		1,
+
+		3,
+
+		5,
+
+		7,
+	}
+	if len(choices) != 0 {
+		if !isInSliceInt64(value, choices) {
+			return fmt.Errorf("setInt64set2,the value %d is not in set %v", value, choices)
+		}
+	} //else means any int64
+
+	ap.int64set2 = value
+	return nil
+}
+
+/**
+Set the value of the parameter int64set3
+*/
+func (ap *AllParameters) setInt64set3(value int64) error {
+	ap.rwlock.Lock()
+	defer ap.rwlock.Unlock()
+
+	choices := []int64{}
+	if len(choices) != 0 {
+		if !isInSliceInt64(value, choices) {
+			return fmt.Errorf("setInt64set3,the value %d is not in set %v", value, choices)
+		}
+	} //else means any int64
+
+	ap.int64set3 = value
+	return nil
+}
+
+/**
+Set the value of the parameter int64Range1
+*/
+func (ap *AllParameters) setInt64Range1(value int64) error {
+	ap.rwlock.Lock()
+	defer ap.rwlock.Unlock()
+
+	choices := []int64{
+
+		1000,
+
+		0,
+
+		10000,
+	}
+	if !(value >= choices[1] && value <= choices[2]) {
+		return fmt.Errorf("setInt64Range1,the value %d is not in the range [%d,%d]", value, choices[1], choices[2])
+	}
+
+	ap.int64Range1 = value
+	return nil
+}
+
+/**
+Set the value of the parameter float64set1
+*/
+func (ap *AllParameters) setFloat64set1(value float64) error {
+	ap.rwlock.Lock()
+	defer ap.rwlock.Unlock()
+
+	choices := []float64{
+
+		1.0,
+
+		2.0,
+
+		3.0,
+
+		4.00,
+
+		5.0,
+
+		6.0,
+	}
+	if len(choices) != 0 {
+		if !isInSliceFloat64(value, choices) {
+			return fmt.Errorf("setFloat64set1,the value %f is not in set %v", value, choices)
+		}
+	} //else means any float64
+
+	ap.float64set1 = value
+	return nil
+}
+
+/**
+Set the value of the parameter float64set2
+*/
+func (ap *AllParameters) setFloat64set2(value float64) error {
+	ap.rwlock.Lock()
+	defer ap.rwlock.Unlock()
+
+	choices := []float64{
+
+		1.001,
+
+		3.003,
+
+		5.005,
+
+		7.007,
+	}
+	if len(choices) != 0 {
+		if !isInSliceFloat64(value, choices) {
+			return fmt.Errorf("setFloat64set2,the value %f is not in set %v", value, choices)
+		}
+	} //else means any float64
+
+	ap.float64set2 = value
+	return nil
+}
+
+/**
+Set the value of the parameter float64set3
+*/
+func (ap *AllParameters) setFloat64set3(value float64) error {
+	ap.rwlock.Lock()
+	defer ap.rwlock.Unlock()
+
+	choices := []float64{}
+	if len(choices) != 0 {
+		if !isInSliceFloat64(value, choices) {
+			return fmt.Errorf("setFloat64set3,the value %f is not in set %v", value, choices)
+		}
+	} //else means any float64
+
+	ap.float64set3 = value
+	return nil
+}
+
+/**
+Set the value of the parameter float64Range1
+*/
+func (ap *AllParameters) setFloat64Range1(value float64) error {
+	ap.rwlock.Lock()
+	defer ap.rwlock.Unlock()
+
+	choices := []float64{
+
+		1000.01,
+
+		0.02,
+
+		10000.03,
+	}
+	if !(value >= choices[1] && value <= choices[2]) {
+		return fmt.Errorf("setFloat64Range1,the value %f is not in the range [%f,%f]", value, choices[1], choices[2])
+	}
+
+	ap.float64Range1 = value
+	return nil
+}
+
+/**
+prepare something before anything else.
+it is unsafe in multi-thread environment.
+*/
+func (config *configuration) prepareAnything() {
+	if config.name2updatedFlags == nil {
+		config.name2updatedFlags = make(map[string]bool)
+	}
+}
+
+/**
+reset update flags of configuration items
+*/
+func (config *configuration) resetUpdatedFlags() {
+	config.rwlock.Lock()
+	defer config.rwlock.Unlock()
+	config.prepareAnything()
+
+	config.name2updatedFlags["boolSet1"] = false
+
+	config.name2updatedFlags["boolSet2"] = false
+
+	config.name2updatedFlags["boolSet3"] = false
+
+	config.name2updatedFlags["stringSet1"] = false
+
+	config.name2updatedFlags["stringSet2"] = false
+
+	config.name2updatedFlags["int64set1"] = false
+
+	config.name2updatedFlags["int64set3"] = false
+
+	config.name2updatedFlags["int64Range1"] = false
+
+	config.name2updatedFlags["float64set1"] = false
+
+	config.name2updatedFlags["float64set3"] = false
+
+	config.name2updatedFlags["float64Range1"] = false
+
+}
+
+/**
+set update flag of configuration item
+*/
+func (config *configuration) setUpdatedFlag(name string, updated bool) {
+	config.rwlock.Lock()
+	defer config.rwlock.Unlock()
+	config.prepareAnything()
+	config.name2updatedFlags[name] = updated
+}
+
+/**
+get update flag of configuration item
+*/
+func (config *configuration) getUpdatedFlag(name string) bool {
+	config.rwlock.RLock()
+	defer config.rwlock.RUnlock()
+	config.prepareAnything()
+	return config.name2updatedFlags[name]
+}
+
+/**
+Load parameters' values in the configuration string.
+*/
+func (config *configuration) LoadConfigurationFromString(input string) error {
+	config.resetUpdatedFlags()
+
+	metadata, err := toml.Decode(input, config)
+	if err != nil {
+		return err
+	} else if failed := metadata.Undecoded(); len(failed) > 0 {
+		var failedItems []string
+		for _, item := range failed {
+			failedItems = append(failedItems, item.String())
+		}
+		return fmt.Errorf("decode failed %s. error:%v", failedItems, err)
+	}
+
+	for _, k := range metadata.Keys() {
+		config.setUpdatedFlag(k[0], true)
+	}
+
+	return nil
+}
+
+/**
+Load parameters' values in the configuration file.
+*/
+func (config *configuration) LoadConfigurationFromFile(fname string) error {
+	config.resetUpdatedFlags()
+
+	metadata, err := toml.DecodeFile(fname, config)
+	if err != nil {
+		return err
+	} else if failed := metadata.Undecoded(); len(failed) > 0 {
+		var failedItems []string
+		for _, item := range failed {
+			failedItems = append(failedItems, item.String())
+		}
+		return fmt.Errorf("decode failed %s. error:%v", failedItems, err)
+	}
+
+	for _, k := range metadata.Keys() {
+		config.setUpdatedFlag(k[0], true)
+	}
+
+	return nil
+}
+
+/**
+Update parameters' values with configuration.
+*/
+func (ap *AllParameters) UpdateParametersWithConfiguration(config *configuration) error {
+	var err error
+
+	if config.getUpdatedFlag("boolSet1") {
+		if err = ap.setBoolSet1(config.BoolSet1); err != nil {
+			return fmt.Errorf("update parameter boolSet1 failed.error:%v", err)
+		}
+	}
+
+	if config.getUpdatedFlag("boolSet2") {
+		if err = ap.setBoolSet2(config.BoolSet2); err != nil {
+			return fmt.Errorf("update parameter boolSet2 failed.error:%v", err)
+		}
+	}
+
+	if config.getUpdatedFlag("boolSet3") {
+		if err = ap.setBoolSet3(config.BoolSet3); err != nil {
+			return fmt.Errorf("update parameter boolSet3 failed.error:%v", err)
+		}
+	}
+
+	if config.getUpdatedFlag("stringSet1") {
+		if err = ap.setStringSet1(config.StringSet1); err != nil {
+			return fmt.Errorf("update parameter stringSet1 failed.error:%v", err)
+		}
+	}
+
+	if config.getUpdatedFlag("stringSet2") {
+		if err = ap.setStringSet2(config.StringSet2); err != nil {
+			return fmt.Errorf("update parameter stringSet2 failed.error:%v", err)
+		}
+	}
+
+	if config.getUpdatedFlag("int64set1") {
+		if err = ap.setInt64set1(config.Int64set1); err != nil {
+			return fmt.Errorf("update parameter int64set1 failed.error:%v", err)
+		}
+	}
+
+	if config.getUpdatedFlag("int64set3") {
+		if err = ap.setInt64set3(config.Int64set3); err != nil {
+			return fmt.Errorf("update parameter int64set3 failed.error:%v", err)
+		}
+	}
+
+	if config.getUpdatedFlag("int64Range1") {
+		if err = ap.setInt64Range1(config.Int64Range1); err != nil {
+			return fmt.Errorf("update parameter int64Range1 failed.error:%v", err)
+		}
+	}
+
+	if config.getUpdatedFlag("float64set1") {
+		if err = ap.setFloat64set1(config.Float64set1); err != nil {
+			return fmt.Errorf("update parameter float64set1 failed.error:%v", err)
+		}
+	}
+
+	if config.getUpdatedFlag("float64set3") {
+		if err = ap.setFloat64set3(config.Float64set3); err != nil {
+			return fmt.Errorf("update parameter float64set3 failed.error:%v", err)
+		}
+	}
+
+	if config.getUpdatedFlag("float64Range1") {
+		if err = ap.setFloat64Range1(config.Float64Range1); err != nil {
+			return fmt.Errorf("update parameter float64Range1 failed.error:%v", err)
+		}
+	}
+
+	return nil
+}
+
+/**
+Load configuration from file into configuration.
+Then update items into AllParameters
+*/
+func LoadconfigurationFromFile(filename string, params *AllParameters) error {
+	config := &configuration{}
+	if err := config.LoadConfigurationFromFile(filename); err != nil {
+		return err
+	}
+
+	if err := params.UpdateParametersWithConfiguration(config); err != nil {
+		return err
+	}
+	return nil
+}
diff --git a/pkg/config/test/parameters_test.go b/pkg/config/test/parameters_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..090c2599ddc5c3406ec288247dca84ee99f0ae08
--- /dev/null
+++ b/pkg/config/test/parameters_test.go
@@ -0,0 +1,159 @@
+// Code generated by tool; DO NOT EDIT.
+package config
+
+import (
+	"sync"
+	"testing"
+)
+
+func TestAllParameters_LoadInitialValues(t *testing.T) {
+	ap := &AllParameters{}
+	if err := ap.LoadInitialValues(); err != nil {
+		t.Errorf("LoadInitialValues failed. error:%v", err)
+	}
+}
+
+func isconfigurationEqual(c1, c2 configuration) bool {
+
+	if c1.BoolSet1 != c2.BoolSet1 {
+		return false
+	}
+
+	if c1.BoolSet2 != c2.BoolSet2 {
+		return false
+	}
+
+	if c1.BoolSet3 != c2.BoolSet3 {
+		return false
+	}
+
+	if c1.StringSet1 != c2.StringSet1 {
+		return false
+	}
+
+	if c1.StringSet2 != c2.StringSet2 {
+		return false
+	}
+
+	if c1.Int64set1 != c2.Int64set1 {
+		return false
+	}
+
+	if c1.Int64set3 != c2.Int64set3 {
+		return false
+	}
+
+	if c1.Int64Range1 != c2.Int64Range1 {
+		return false
+	}
+
+	if c1.Float64set1 != c2.Float64set1 {
+		return false
+	}
+
+	if c1.Float64set3 != c2.Float64set3 {
+		return false
+	}
+
+	if c1.Float64Range1 != c2.Float64Range1 {
+		return false
+	}
+
+	return true
+}
+
+func Test_configuration_LoadConfigurationFromString(t *testing.T) {
+	t1 := `
+
+boolSet1=true
+
+boolSet2=false
+
+boolSet3= false
+
+stringSet1= "ss1"
+
+stringSet2= ""
+
+int64set1=1
+
+
+
+int64set3= 0
+
+int64Range1=1000
+
+float64set1=1.0
+
+
+
+float64set3= 0.0
+
+float64Range1=1000.01
+		
+`
+	t1_config := configuration{
+		rwlock: sync.RWMutex{},
+
+		BoolSet1: true,
+
+		BoolSet2: false,
+
+		BoolSet3: false,
+
+		StringSet1: "ss1",
+
+		StringSet2: "",
+
+		Int64set1: 1,
+
+		Int64set3: 0,
+
+		Int64Range1: 1000,
+
+		Float64set1: 1.0,
+
+		Float64set3: 0.0,
+
+		Float64Range1: 1000.01,
+
+		name2updatedFlags: nil,
+	}
+
+	type args struct {
+		input  string
+		config configuration
+	}
+	tests := []struct {
+		name     string
+		args     args
+		wantErr  bool
+		wantErr2 bool
+		wantErr3 bool
+	}{
+		{"t1", args{t1, t1_config}, false, false, false},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			ap := &AllParameters{}
+			if err := ap.LoadInitialValues(); err != nil {
+				t.Errorf("LoadInitialValues failed.error %v", err)
+			}
+			config := &configuration{}
+			if err := config.LoadConfigurationFromString(tt.args.input); (err != nil) != tt.wantErr {
+				t.Errorf("LoadConfigurationFromString() error = %v, wantErr %v", err, tt.wantErr)
+			} else if err != nil {
+				return
+			}
+
+			if err := ap.UpdateParametersWithConfiguration(config); (err != nil) != tt.wantErr2 {
+				t.Errorf("UpdateParametersWithConfiguration failed. error:%v", err)
+			}
+
+			if (isconfigurationEqual(*config, tt.args.config) != true) != tt.wantErr3 {
+				t.Errorf("Configuration are not equal. %v vs %v ", *config, tt.args.config)
+				return
+			}
+		})
+	}
+}
diff --git a/pkg/config/test/varconfig.toml b/pkg/config/test/varconfig.toml
new file mode 100644
index 0000000000000000000000000000000000000000..d520ee404abc67cd664d6cfe024387369b5d9ced
--- /dev/null
+++ b/pkg/config/test/varconfig.toml
@@ -0,0 +1,87 @@
+
+# Code generated by tool; DO NOT EDIT.
+
+
+	
+#	Name:	autoload
+#	Scope:	[global]
+#	Access:	[file]
+#	DataType:	bool
+#	DomainType:	set
+#	Values:	[]
+#	Comment:	autoload something
+#	UpdateMode:	dynamic
+	autoload= false
+
+
+	
+#	Name:	rootname
+#	Scope:	[global]
+#	Access:	[file]
+#	DataType:	string
+#	DomainType:	set
+#	Values:	[root]
+#	Comment:	root name
+#	UpdateMode:	dynamic
+	rootname= "root"
+
+
+	
+#	Name:	rootpassword
+#	Scope:	[global]
+#	Access:	[file]
+#	DataType:	string
+#	DomainType:	set
+#	Values:	[]
+#	Comment:	root password
+#	UpdateMode:	dynamic
+	rootpassword= ""
+
+
+	
+#	Name:	dumpuser
+#	Scope:	[global]
+#	Access:	[file]
+#	DataType:	string
+#	DomainType:	set
+#	Values:	[dump]
+#	Comment:	dump user name
+#	UpdateMode:	dynamic
+	dumpuser= "dump"
+
+
+	
+#	Name:	dumppassword
+#	Scope:	[global]
+#	Access:	[file]
+#	DataType:	string
+#	DomainType:	set
+#	Values:	[111]
+#	Comment:	dump user password
+#	UpdateMode:	dynamic
+	dumppassword= "111"
+
+
+	
+#	Name:	port
+#	Scope:	[global]
+#	Access:	[file]
+#	DataType:	int64
+#	DomainType:	set
+#	Values:	[9000]
+#	Comment:	port
+#	UpdateMode:	dynamic
+	port=9000
+
+
+	
+#	Name:	ip
+#	Scope:	[global]
+#	Access:	[file]
+#	DataType:	string
+#	DomainType:	set
+#	Values:	[localhost 127.0.0.1]
+#	Comment:	listening ip
+#	UpdateMode:	dynamic
+	ip= "localhost"
+
diff --git a/pkg/config/test/variables.go b/pkg/config/test/variables.go
new file mode 100644
index 0000000000000000000000000000000000000000..c7343b74b4eb28525f5a31ab2daf89745471cd54
--- /dev/null
+++ b/pkg/config/test/variables.go
@@ -0,0 +1,800 @@
+// Code generated by tool; DO NOT EDIT.
+package config
+
+import (
+	"fmt"
+	"github.com/BurntSushi/toml"
+	"sync"
+)
+
+//all parameters in the system
+type Variables struct {
+	//read and write lock
+	rwlock sync.RWMutex
+
+	/**
+	Name:	autoload
+	Scope:	[global]
+	Access:	[file]
+	DataType:	bool
+	DomainType:	set
+	Values:	[]
+	Comment:	autoload something
+	UpdateMode:	dynamic
+	*/
+	autoload bool
+
+	/**
+	Name:	rootname
+	Scope:	[global]
+	Access:	[file]
+	DataType:	string
+	DomainType:	set
+	Values:	[root]
+	Comment:	root name
+	UpdateMode:	dynamic
+	*/
+	rootname string
+
+	/**
+	Name:	rootpassword
+	Scope:	[global]
+	Access:	[file]
+	DataType:	string
+	DomainType:	set
+	Values:	[]
+	Comment:	root password
+	UpdateMode:	dynamic
+	*/
+	rootpassword string
+
+	/**
+	Name:	dumpuser
+	Scope:	[global]
+	Access:	[file]
+	DataType:	string
+	DomainType:	set
+	Values:	[dump]
+	Comment:	dump user name
+	UpdateMode:	dynamic
+	*/
+	dumpuser string
+
+	/**
+	Name:	dumppassword
+	Scope:	[global]
+	Access:	[file]
+	DataType:	string
+	DomainType:	set
+	Values:	[111]
+	Comment:	dump user password
+	UpdateMode:	dynamic
+	*/
+	dumppassword string
+
+	/**
+	Name:	port
+	Scope:	[global]
+	Access:	[file]
+	DataType:	int64
+	DomainType:	set
+	Values:	[9000]
+	Comment:	port
+	UpdateMode:	dynamic
+	*/
+	port int64
+
+	/**
+	Name:	ip
+	Scope:	[global]
+	Access:	[file]
+	DataType:	string
+	DomainType:	set
+	Values:	[localhost 127.0.0.1]
+	Comment:	listening ip
+	UpdateMode:	dynamic
+	*/
+	ip string
+
+	//parameter name -> parameter definition string
+	name2definition map[string]string
+} //end Variables
+
+//all parameters can be set in the configuration file.
+type vconfig struct {
+	//read and write lock
+	rwlock sync.RWMutex
+
+	/**
+	Name:	autoload
+	Scope:	[global]
+	Access:	[file]
+	DataType:	bool
+	DomainType:	set
+	Values:	[]
+	Comment:	autoload something
+	UpdateMode:	dynamic
+	*/
+	Autoload bool `toml:"autoload"`
+
+	/**
+	Name:	rootname
+	Scope:	[global]
+	Access:	[file]
+	DataType:	string
+	DomainType:	set
+	Values:	[root]
+	Comment:	root name
+	UpdateMode:	dynamic
+	*/
+	Rootname string `toml:"rootname"`
+
+	/**
+	Name:	rootpassword
+	Scope:	[global]
+	Access:	[file]
+	DataType:	string
+	DomainType:	set
+	Values:	[]
+	Comment:	root password
+	UpdateMode:	dynamic
+	*/
+	Rootpassword string `toml:"rootpassword"`
+
+	/**
+	Name:	dumpuser
+	Scope:	[global]
+	Access:	[file]
+	DataType:	string
+	DomainType:	set
+	Values:	[dump]
+	Comment:	dump user name
+	UpdateMode:	dynamic
+	*/
+	Dumpuser string `toml:"dumpuser"`
+
+	/**
+	Name:	dumppassword
+	Scope:	[global]
+	Access:	[file]
+	DataType:	string
+	DomainType:	set
+	Values:	[111]
+	Comment:	dump user password
+	UpdateMode:	dynamic
+	*/
+	Dumppassword string `toml:"dumppassword"`
+
+	/**
+	Name:	port
+	Scope:	[global]
+	Access:	[file]
+	DataType:	int64
+	DomainType:	set
+	Values:	[9000]
+	Comment:	port
+	UpdateMode:	dynamic
+	*/
+	Port int64 `toml:"port"`
+
+	/**
+	Name:	ip
+	Scope:	[global]
+	Access:	[file]
+	DataType:	string
+	DomainType:	set
+	Values:	[localhost 127.0.0.1]
+	Comment:	listening ip
+	UpdateMode:	dynamic
+	*/
+	Ip string `toml:"ip"`
+
+	//parameter name -> updated flag
+	name2updatedFlags map[string]bool
+} //end vconfig
+
+/**
+prepare something before anything else.
+it is unsafe in multi-thread environment.
+*/
+func (ap *Variables) prepareAnything() {
+	if ap.name2definition == nil {
+		ap.name2definition = make(map[string]string)
+	}
+}
+
+/**
+set parameter and its string of the definition.
+*/
+func (ap *Variables) PrepareDefinition() {
+	ap.rwlock.Lock()
+	defer ap.rwlock.Unlock()
+
+	ap.prepareAnything()
+
+	ap.name2definition["autoload"] = "	Name:	autoload	Scope:	[global]	Access:	[file]	DataType:	bool	DomainType:	set	Values:	[]	Comment:	autoload something	UpdateMode:	dynamic	"
+
+	ap.name2definition["rootname"] = "	Name:	rootname	Scope:	[global]	Access:	[file]	DataType:	string	DomainType:	set	Values:	[root]	Comment:	root name	UpdateMode:	dynamic	"
+
+	ap.name2definition["rootpassword"] = "	Name:	rootpassword	Scope:	[global]	Access:	[file]	DataType:	string	DomainType:	set	Values:	[]	Comment:	root password	UpdateMode:	dynamic	"
+
+	ap.name2definition["dumpuser"] = "	Name:	dumpuser	Scope:	[global]	Access:	[file]	DataType:	string	DomainType:	set	Values:	[dump]	Comment:	dump user name	UpdateMode:	dynamic	"
+
+	ap.name2definition["dumppassword"] = "	Name:	dumppassword	Scope:	[global]	Access:	[file]	DataType:	string	DomainType:	set	Values:	[111]	Comment:	dump user password	UpdateMode:	dynamic	"
+
+	ap.name2definition["port"] = "	Name:	port	Scope:	[global]	Access:	[file]	DataType:	int64	DomainType:	set	Values:	[9000]	Comment:	port	UpdateMode:	dynamic	"
+
+	ap.name2definition["ip"] = "	Name:	ip	Scope:	[global]	Access:	[file]	DataType:	string	DomainType:	set	Values:	[localhost 127.0.0.1]	Comment:	listening ip	UpdateMode:	dynamic	"
+
+}
+
+/**
+get the definition of the parameter.
+*/
+func (ap *Variables) GetDefinition(name string) (string, error) {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	ap.prepareAnything()
+	if p, ok := ap.name2definition[name]; !ok {
+		return "", fmt.Errorf("there is no parameter %s", name)
+	} else {
+		return p, nil
+	}
+}
+
+/**
+check if there is the parameter
+*/
+func (ap *Variables) HasParameter(name string) bool {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	ap.prepareAnything()
+	if _, ok := ap.name2definition[name]; !ok {
+		return false
+	} else {
+		return true
+	}
+}
+
+/**
+Load the initial values of all parameters.
+*/
+func (ap *Variables) LoadInitialValues() error {
+	ap.PrepareDefinition()
+	var err error
+
+	autoloadchoices := []bool{}
+	if len(autoloadchoices) != 0 {
+		if err = ap.setAutoload(autoloadchoices[0]); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Autoload", err)
+		}
+	} else {
+
+		if err = ap.setAutoload(false); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Autoload", err)
+		}
+
+	}
+
+	rootnamechoices := []string{
+
+		"root",
+	}
+	if len(rootnamechoices) != 0 {
+		if err = ap.setRootname(rootnamechoices[0]); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Rootname", err)
+		}
+	} else {
+		//empty string
+		if err = ap.setRootname(""); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Rootname", err)
+		}
+	}
+
+	rootpasswordchoices := []string{
+
+		"",
+	}
+	if len(rootpasswordchoices) != 0 {
+		if err = ap.setRootpassword(rootpasswordchoices[0]); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Rootpassword", err)
+		}
+	} else {
+		//empty string
+		if err = ap.setRootpassword(""); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Rootpassword", err)
+		}
+	}
+
+	dumpuserchoices := []string{
+
+		"dump",
+	}
+	if len(dumpuserchoices) != 0 {
+		if err = ap.setDumpuser(dumpuserchoices[0]); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Dumpuser", err)
+		}
+	} else {
+		//empty string
+		if err = ap.setDumpuser(""); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Dumpuser", err)
+		}
+	}
+
+	dumppasswordchoices := []string{
+
+		"111",
+	}
+	if len(dumppasswordchoices) != 0 {
+		if err = ap.setDumppassword(dumppasswordchoices[0]); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Dumppassword", err)
+		}
+	} else {
+		//empty string
+		if err = ap.setDumppassword(""); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Dumppassword", err)
+		}
+	}
+
+	portchoices := []int64{
+
+		9000,
+	}
+	if len(portchoices) != 0 {
+		if err = ap.setPort(portchoices[0]); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Port", err)
+		}
+	} else {
+
+		if err = ap.setPort(0); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Port", err)
+		}
+
+	}
+
+	ipchoices := []string{
+
+		"localhost",
+
+		"127.0.0.1",
+	}
+	if len(ipchoices) != 0 {
+		if err = ap.setIp(ipchoices[0]); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Ip", err)
+		}
+	} else {
+		//empty string
+		if err = ap.setIp(""); err != nil {
+			return fmt.Errorf("set%s failed.error:%v", "Ip", err)
+		}
+	}
+
+	return nil
+}
+
+/**
+Get the value of the parameter autoload
+*/
+func (ap *Variables) GetAutoload() bool {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	return ap.autoload
+}
+
+/**
+Get the value of the parameter rootname
+*/
+func (ap *Variables) GetRootname() string {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	return ap.rootname
+}
+
+/**
+Get the value of the parameter rootpassword
+*/
+func (ap *Variables) GetRootpassword() string {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	return ap.rootpassword
+}
+
+/**
+Get the value of the parameter dumpuser
+*/
+func (ap *Variables) GetDumpuser() string {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	return ap.dumpuser
+}
+
+/**
+Get the value of the parameter dumppassword
+*/
+func (ap *Variables) GetDumppassword() string {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	return ap.dumppassword
+}
+
+/**
+Get the value of the parameter port
+*/
+func (ap *Variables) GetPort() int64 {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	return ap.port
+}
+
+/**
+Get the value of the parameter ip
+*/
+func (ap *Variables) GetIp() string {
+	ap.rwlock.RLock()
+	defer ap.rwlock.RUnlock()
+	return ap.ip
+}
+
+/**
+Set the value of the parameter autoload
+*/
+func (ap *Variables) SetAutoload(value bool) error {
+	return ap.setAutoload(value)
+}
+
+/**
+Set the value of the parameter rootname
+*/
+func (ap *Variables) SetRootname(value string) error {
+	return ap.setRootname(value)
+}
+
+/**
+Set the value of the parameter rootpassword
+*/
+func (ap *Variables) SetRootpassword(value string) error {
+	return ap.setRootpassword(value)
+}
+
+/**
+Set the value of the parameter dumpuser
+*/
+func (ap *Variables) SetDumpuser(value string) error {
+	return ap.setDumpuser(value)
+}
+
+/**
+Set the value of the parameter dumppassword
+*/
+func (ap *Variables) SetDumppassword(value string) error {
+	return ap.setDumppassword(value)
+}
+
+/**
+Set the value of the parameter port
+*/
+func (ap *Variables) SetPort(value int64) error {
+	return ap.setPort(value)
+}
+
+/**
+Set the value of the parameter ip
+*/
+func (ap *Variables) SetIp(value string) error {
+	return ap.setIp(value)
+}
+
+/**
+Set the value of the parameter autoload
+*/
+func (ap *Variables) setAutoload(value bool) error {
+	ap.rwlock.Lock()
+	defer ap.rwlock.Unlock()
+
+	choices := []bool{}
+	if len(choices) != 0 {
+		if !isInSliceBool(value, choices) {
+			return fmt.Errorf("setAutoload,the value %t is not in set %v", value, choices)
+		}
+	} //else means any bool value: true or false
+
+	ap.autoload = value
+	return nil
+}
+
+/**
+Set the value of the parameter rootname
+*/
+func (ap *Variables) setRootname(value string) error {
+	ap.rwlock.Lock()
+	defer ap.rwlock.Unlock()
+
+	choices := []string{
+
+		"root",
+	}
+	if len(choices) != 0 {
+		if !isInSlice(value, choices) {
+			return fmt.Errorf("setRootname,the value %s is not in set %v", value, choices)
+		}
+	} //else means any string
+
+	ap.rootname = value
+	return nil
+}
+
+/**
+Set the value of the parameter rootpassword
+*/
+func (ap *Variables) setRootpassword(value string) error {
+	ap.rwlock.Lock()
+	defer ap.rwlock.Unlock()
+
+	choices := []string{
+
+		"",
+	}
+	if len(choices) != 0 {
+		if !isInSlice(value, choices) {
+			return fmt.Errorf("setRootpassword,the value %s is not in set %v", value, choices)
+		}
+	} //else means any string
+
+	ap.rootpassword = value
+	return nil
+}
+
+/**
+Set the value of the parameter dumpuser
+*/
+func (ap *Variables) setDumpuser(value string) error {
+	ap.rwlock.Lock()
+	defer ap.rwlock.Unlock()
+
+	choices := []string{
+
+		"dump",
+	}
+	if len(choices) != 0 {
+		if !isInSlice(value, choices) {
+			return fmt.Errorf("setDumpuser,the value %s is not in set %v", value, choices)
+		}
+	} //else means any string
+
+	ap.dumpuser = value
+	return nil
+}
+
+/**
+Set the value of the parameter dumppassword
+*/
+func (ap *Variables) setDumppassword(value string) error {
+	ap.rwlock.Lock()
+	defer ap.rwlock.Unlock()
+
+	choices := []string{
+
+		"111",
+	}
+	if len(choices) != 0 {
+		if !isInSlice(value, choices) {
+			return fmt.Errorf("setDumppassword,the value %s is not in set %v", value, choices)
+		}
+	} //else means any string
+
+	ap.dumppassword = value
+	return nil
+}
+
+/**
+Set the value of the parameter port
+*/
+func (ap *Variables) setPort(value int64) error {
+	ap.rwlock.Lock()
+	defer ap.rwlock.Unlock()
+
+	choices := []int64{
+
+		9000,
+	}
+	if len(choices) != 0 {
+		if !isInSliceInt64(value, choices) {
+			return fmt.Errorf("setPort,the value %d is not in set %v", value, choices)
+		}
+	} //else means any int64
+
+	ap.port = value
+	return nil
+}
+
+/**
+Set the value of the parameter ip
+*/
+func (ap *Variables) setIp(value string) error {
+	ap.rwlock.Lock()
+	defer ap.rwlock.Unlock()
+
+	choices := []string{
+
+		"localhost",
+
+		"127.0.0.1",
+	}
+	if len(choices) != 0 {
+		if !isInSlice(value, choices) {
+			return fmt.Errorf("setIp,the value %s is not in set %v", value, choices)
+		}
+	} //else means any string
+
+	ap.ip = value
+	return nil
+}
+
+/**
+prepare something before anything else.
+it is unsafe in multi-thread environment.
+*/
+func (config *vconfig) prepareAnything() {
+	if config.name2updatedFlags == nil {
+		config.name2updatedFlags = make(map[string]bool)
+	}
+}
+
+/**
+reset update flags of configuration items
+*/
+func (config *vconfig) resetUpdatedFlags() {
+	config.rwlock.Lock()
+	defer config.rwlock.Unlock()
+	config.prepareAnything()
+
+	config.name2updatedFlags["autoload"] = false
+
+	config.name2updatedFlags["rootname"] = false
+
+	config.name2updatedFlags["rootpassword"] = false
+
+	config.name2updatedFlags["dumpuser"] = false
+
+	config.name2updatedFlags["dumppassword"] = false
+
+	config.name2updatedFlags["port"] = false
+
+	config.name2updatedFlags["ip"] = false
+
+}
+
+/**
+set update flag of configuration item
+*/
+func (config *vconfig) setUpdatedFlag(name string, updated bool) {
+	config.rwlock.Lock()
+	defer config.rwlock.Unlock()
+	config.prepareAnything()
+	config.name2updatedFlags[name] = updated
+}
+
+/**
+get update flag of configuration item
+*/
+func (config *vconfig) getUpdatedFlag(name string) bool {
+	config.rwlock.RLock()
+	defer config.rwlock.RUnlock()
+	config.prepareAnything()
+	return config.name2updatedFlags[name]
+}
+
+/**
+Load parameters' values in the configuration string.
+*/
+func (config *vconfig) LoadConfigurationFromString(input string) error {
+	config.resetUpdatedFlags()
+
+	metadata, err := toml.Decode(input, config)
+	if err != nil {
+		return err
+	} else if failed := metadata.Undecoded(); len(failed) > 0 {
+		var failedItems []string
+		for _, item := range failed {
+			failedItems = append(failedItems, item.String())
+		}
+		return fmt.Errorf("decode failed %s. error:%v", failedItems, err)
+	}
+
+	for _, k := range metadata.Keys() {
+		config.setUpdatedFlag(k[0], true)
+	}
+
+	return nil
+}
+
+/**
+Load parameters' values in the configuration file.
+*/
+func (config *vconfig) LoadConfigurationFromFile(fname string) error {
+	config.resetUpdatedFlags()
+
+	metadata, err := toml.DecodeFile(fname, config)
+	if err != nil {
+		return err
+	} else if failed := metadata.Undecoded(); len(failed) > 0 {
+		var failedItems []string
+		for _, item := range failed {
+			failedItems = append(failedItems, item.String())
+		}
+		return fmt.Errorf("decode failed %s. error:%v", failedItems, err)
+	}
+
+	for _, k := range metadata.Keys() {
+		config.setUpdatedFlag(k[0], true)
+	}
+
+	return nil
+}
+
+/**
+Update parameters' values with configuration.
+*/
+func (ap *Variables) UpdateParametersWithConfiguration(config *vconfig) error {
+	var err error
+
+	if config.getUpdatedFlag("autoload") {
+		if err = ap.setAutoload(config.Autoload); err != nil {
+			return fmt.Errorf("update parameter autoload failed.error:%v", err)
+		}
+	}
+
+	if config.getUpdatedFlag("rootname") {
+		if err = ap.setRootname(config.Rootname); err != nil {
+			return fmt.Errorf("update parameter rootname failed.error:%v", err)
+		}
+	}
+
+	if config.getUpdatedFlag("rootpassword") {
+		if err = ap.setRootpassword(config.Rootpassword); err != nil {
+			return fmt.Errorf("update parameter rootpassword failed.error:%v", err)
+		}
+	}
+
+	if config.getUpdatedFlag("dumpuser") {
+		if err = ap.setDumpuser(config.Dumpuser); err != nil {
+			return fmt.Errorf("update parameter dumpuser failed.error:%v", err)
+		}
+	}
+
+	if config.getUpdatedFlag("dumppassword") {
+		if err = ap.setDumppassword(config.Dumppassword); err != nil {
+			return fmt.Errorf("update parameter dumppassword failed.error:%v", err)
+		}
+	}
+
+	if config.getUpdatedFlag("port") {
+		if err = ap.setPort(config.Port); err != nil {
+			return fmt.Errorf("update parameter port failed.error:%v", err)
+		}
+	}
+
+	if config.getUpdatedFlag("ip") {
+		if err = ap.setIp(config.Ip); err != nil {
+			return fmt.Errorf("update parameter ip failed.error:%v", err)
+		}
+	}
+
+	return nil
+}
+
+/**
+Load configuration from file into vconfig.
+Then update items into Variables
+*/
+func LoadvconfigFromFile(filename string, params *Variables) error {
+	config := &vconfig{}
+	if err := config.LoadConfigurationFromFile(filename); err != nil {
+		return err
+	}
+
+	if err := params.UpdateParametersWithConfiguration(config); err != nil {
+		return err
+	}
+	return nil
+}
diff --git a/pkg/config/test/variables_test.go b/pkg/config/test/variables_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..d6b3236b11128d74ce83cc34fe2e564e42461eed
--- /dev/null
+++ b/pkg/config/test/variables_test.go
@@ -0,0 +1,123 @@
+// Code generated by tool; DO NOT EDIT.
+package config
+
+import (
+	"sync"
+	"testing"
+)
+
+func TestVariables_LoadInitialValues(t *testing.T) {
+	ap := &Variables{}
+	if err := ap.LoadInitialValues(); err != nil {
+		t.Errorf("LoadInitialValues failed. error:%v", err)
+	}
+}
+
+func isvconfigEqual(c1, c2 vconfig) bool {
+
+	if c1.Autoload != c2.Autoload {
+		return false
+	}
+
+	if c1.Rootname != c2.Rootname {
+		return false
+	}
+
+	if c1.Rootpassword != c2.Rootpassword {
+		return false
+	}
+
+	if c1.Dumpuser != c2.Dumpuser {
+		return false
+	}
+
+	if c1.Dumppassword != c2.Dumppassword {
+		return false
+	}
+
+	if c1.Port != c2.Port {
+		return false
+	}
+
+	if c1.Ip != c2.Ip {
+		return false
+	}
+
+	return true
+}
+
+func Test_vconfig_LoadConfigurationFromString(t *testing.T) {
+	t1 := `
+
+autoload= false
+
+rootname= "root"
+
+rootpassword= ""
+
+dumpuser= "dump"
+
+dumppassword= "111"
+
+port=9000
+
+ip= "localhost"
+		
+`
+	t1_config := vconfig{
+		rwlock: sync.RWMutex{},
+
+		Autoload: false,
+
+		Rootname: "root",
+
+		Rootpassword: "",
+
+		Dumpuser: "dump",
+
+		Dumppassword: "111",
+
+		Port: 9000,
+
+		Ip: "localhost",
+
+		name2updatedFlags: nil,
+	}
+
+	type args struct {
+		input  string
+		config vconfig
+	}
+	tests := []struct {
+		name     string
+		args     args
+		wantErr  bool
+		wantErr2 bool
+		wantErr3 bool
+	}{
+		{"t1", args{t1, t1_config}, false, false, false},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			ap := &Variables{}
+			if err := ap.LoadInitialValues(); err != nil {
+				t.Errorf("LoadInitialValues failed.error %v", err)
+			}
+			config := &vconfig{}
+			if err := config.LoadConfigurationFromString(tt.args.input); (err != nil) != tt.wantErr {
+				t.Errorf("LoadConfigurationFromString() error = %v, wantErr %v", err, tt.wantErr)
+			} else if err != nil {
+				return
+			}
+
+			if err := ap.UpdateParametersWithConfiguration(config); (err != nil) != tt.wantErr2 {
+				t.Errorf("UpdateParametersWithConfiguration failed. error:%v", err)
+			}
+
+			if (isvconfigEqual(*config, tt.args.config) != true) != tt.wantErr3 {
+				t.Errorf("Configuration are not equal. %v vs %v ", *config, tt.args.config)
+				return
+			}
+		})
+	}
+}
diff --git a/pkg/server/profiler.go b/pkg/server/profiler.go
new file mode 100644
index 0000000000000000000000000000000000000000..45662078e63d514d618bcf6a86401c32452c3c40
--- /dev/null
+++ b/pkg/server/profiler.go
@@ -0,0 +1,53 @@
+package server
+
+/**
+phase statistics
+ */
+type PhaseProfiler interface {
+	/**
+	start the statistics for the phase.
+	name: the name of the phase
+	 */
+	StartPhase(name string)
+
+	/**
+	stop the statistics for the phase
+	 */
+	EndPhase()
+
+	// ToString convert the phase info into the string
+	ToString()string
+}
+
+//OperatorProfiler : operator statistics
+type OperatorProfiler interface {
+	//start the statistics for the operator
+	StartOperator(operator interface{})
+
+	//end the statistics for the operator
+	EndOperator()
+
+	//add the operator into the profiler
+	AddOperator(operator interface{})
+
+	//convert the operator info into the string
+	ToString()string
+}
+
+//query statistics
+type QueryProfiler interface {
+	//start the statistics for the query
+	StartQuery(string)
+
+	//stop the statistics for the query
+	EndQuery()
+
+	//generate the statistics tree from the physical plan
+	InitWithPlan()
+
+	//add OperatorProfiler information into the query profiler
+	AddOperatorProfiler(OperatorProfiler)
+
+	//convert the profiler into the string
+	ToString()
+}
\ No newline at end of file
diff --git a/pkg/sql/tree/accept.go b/pkg/sql/tree/accept.go
new file mode 100644
index 0000000000000000000000000000000000000000..46f6d30af34ee0f09d9a7a43d60151fd9714d296
--- /dev/null
+++ b/pkg/sql/tree/accept.go
@@ -0,0 +1,8 @@
+package tree
+
+//Visitor Design Pattern
+//Visitor visits the node or sub nodes
+type Visitor interface {
+	Enter(Expr)(bool,Expr)
+	Exit(Expr)(Expr)
+}
\ No newline at end of file
diff --git a/pkg/sql/tree/constant.go b/pkg/sql/tree/constant.go
new file mode 100644
index 0000000000000000000000000000000000000000..8d2a248cf1ea63ace4c881ed3cd6a6f2d2562315
--- /dev/null
+++ b/pkg/sql/tree/constant.go
@@ -0,0 +1,32 @@
+package tree
+
+import "go/constant"
+
+//the AST for literals like string,numeric,bool and etc.
+type Constant interface {
+	Expr
+}
+
+//the AST for the constant numeric value.
+type NumVal struct {
+	Constant
+	value constant.Value
+
+	// negative is the sign label
+	negative bool
+
+	// origString is the "original" string literals that should remain sign-less.
+	origString string
+
+	//converted result
+	resInt     int64
+	resFloat   float64
+}
+
+func (n *NumVal) String() string {
+	return n.origString
+}
+
+func NewNumVal(value constant.Value, origString string, negative bool) *NumVal {
+	return &NumVal{value: value, origString: origString, negative: negative}
+}
\ No newline at end of file
diff --git a/pkg/sql/tree/expr.go b/pkg/sql/tree/expr.go
new file mode 100644
index 0000000000000000000000000000000000000000..f0c05c79601f4c4acd9982eeb24b80fd09a16840
--- /dev/null
+++ b/pkg/sql/tree/expr.go
@@ -0,0 +1,401 @@
+package tree
+
+import (
+	"fmt"
+)
+
+//AST for the expression
+type Expr interface {
+	fmt.Stringer
+	NodePrinter
+
+	//Visitor Design Pattern
+	//Accept the visitor to access the node.
+	Accept(Visitor) Expr
+}
+
+type exprImpl struct {
+}
+
+func (ei *exprImpl) String() string {
+	return ""
+}
+
+func (ei *exprImpl) Print(ctx *PrintCtx) {
+}
+
+func (ei *exprImpl) Accept(_ Visitor) Expr {
+	return ei
+}
+
+//Binary Operator
+type BinaryOp int
+
+const (
+	PLUS BinaryOp = iota
+	MINUS
+	MULTI
+	DIV         // /
+	INTEGER_DIV //
+	BIT_OR      // |
+	BIT_AND     // &
+	BIT_XOR     // ^
+	LEFT_SHIFT  // <<
+	RIGHT_SHIFT // >>
+	MOD         // %
+)
+
+var binaryOpName = []string{
+	"+",
+	"-",
+	"*",
+	"/",
+}
+
+//binary expression
+type BinaryExpr struct {
+	exprImpl
+
+	//operator
+	Op BinaryOp
+
+	//left expression
+	Left Expr
+
+	//right expression
+	Right Expr
+}
+
+func NewBinaryExpr(op BinaryOp, left Expr, right Expr) *BinaryExpr {
+	return &BinaryExpr{
+		Op:    op,
+		Left:  left,
+		Right: right,
+	}
+}
+
+//unary expression
+type UnaryOp int
+
+const (
+	//-
+	UNARY_MINUS UnaryOp = iota
+	//+
+	UNARY_PLUS
+	//~
+	UNARY_TILDE
+	//!
+	UNARY_MARK
+)
+
+var unaryOpName = []string{
+	"-",
+	"+",
+	"~",
+	"!",
+}
+
+//unary expression
+type UnaryExpr struct {
+	exprImpl
+
+	//operator
+	Op UnaryOp
+
+	//expression
+	Expr Expr
+}
+
+func NewUnaryExpr(op UnaryOp, expr Expr) *UnaryExpr {
+	return &UnaryExpr{
+		Op:   op,
+		Expr: expr,
+	}
+}
+
+//comparion operation
+type ComparisonOp int
+
+const (
+	EQUAL            ComparisonOp = iota // =
+	LESS_THAN                            // <
+	LESS_THAN_EQUAL                      // <=
+	GREAT_THAN                           // >
+	GREAT_THAN_EQUAL                     // >=
+	NOT_EQUAL                            // <>, !=
+	IN                                   // IN
+	NOT_IN                               // NOT IN
+	LIKE                                 // LIKE
+	NOT_LIKE                             // NOT LIKE
+	REG_MATCH                            // REG_MATCH
+	NOT_REG_MATCH                        // NOT REG_MATCH
+
+	//reference: https://dev.mysql.com/doc/refman/8.0/en/all-subqueries.html
+	//subquery with ANY,SOME,ALL
+	//operand comparison_operator [ANY | SOME | ALL] (subquery)
+	ANY
+	SOME
+	ALL
+)
+
+var comparionName = []string{
+	"=",
+	"<",
+	"<=",
+	">",
+	">=",
+	"!=",
+	"IN",
+	"NOT IN",
+	"LIKE",
+	"NOT LIKE",
+}
+
+type ComparisonExpr struct {
+	exprImpl
+	Op ComparisonOp
+
+	//ANY SOME ALL with subquery
+	SubOp ComparisonOp
+	Left  Expr
+	Right Expr
+}
+
+func NewComparisonExpr(op ComparisonOp, l, r Expr) *ComparisonExpr {
+	return &ComparisonExpr{
+		Op:    op,
+		SubOp: ComparisonOp(0),
+		Left:  l,
+		Right: r,
+	}
+}
+
+func NewComparisonExprWithSubop(op, subop ComparisonOp, l, r Expr) *ComparisonExpr {
+	return &ComparisonExpr{
+		Op:    op,
+		SubOp: subop,
+		Left:  l,
+		Right: r,
+	}
+}
+
+//and expression
+type AndExpr struct {
+	exprImpl
+	Left, Right Expr
+}
+
+func NewAndExpr(l, r Expr) *AndExpr {
+	return &AndExpr{
+		Left:  l,
+		Right: r,
+	}
+}
+
+//xor expression
+type XorExpr struct {
+	exprImpl
+	Left, Right Expr
+}
+
+func NewXorExpr(l, r Expr) *XorExpr {
+	return &XorExpr{
+		Left:  l,
+		Right: r,
+	}
+}
+
+//or expression
+type OrExpr struct {
+	exprImpl
+	Left, Right Expr
+}
+
+func NewOrExpr(l, r Expr) *OrExpr {
+	return &OrExpr{
+		Left:  l,
+		Right: r,
+	}
+}
+
+//not expression
+type NotExpr struct {
+	exprImpl
+	Expr Expr
+}
+
+func NewNotExpr(e Expr) *NotExpr {
+	return &NotExpr{
+		Expr: e,
+	}
+}
+
+//is null expression
+type IsNullExpr struct {
+	exprImpl
+	Expr Expr
+}
+
+func NewIsNullExpr(e Expr) *IsNullExpr {
+	return &IsNullExpr{
+		Expr: e,
+	}
+}
+
+//is not null expression
+type IsNotNullExpr struct {
+	exprImpl
+	Expr Expr
+}
+
+func NewIsNotNullExpr(e Expr) *IsNotNullExpr {
+	return &IsNotNullExpr{
+		Expr: e,
+	}
+}
+
+//subquery interface
+type SubqueryExpr interface {
+	Expr
+}
+
+//subquery
+type Subquery struct {
+	SubqueryExpr
+
+	Select SelectStatement
+	Exists bool
+}
+
+func NewSubquery(s SelectStatement, e bool) *Subquery {
+	return &Subquery{
+		Select: s,
+		Exists: e,
+	}
+}
+
+//a list of expression.
+type Exprs []Expr
+
+//ast fir the list of expression
+type ExprList struct {
+	exprImpl
+	Exprs Exprs
+}
+
+//the parenthesized expression.
+type ParenExpr struct {
+	exprImpl
+	Expr Expr
+}
+
+func NewParenExpr(e Expr) *ParenExpr {
+	return &ParenExpr{
+		Expr: e,
+	}
+}
+
+type funcType int
+
+const (
+	_ funcType = iota
+	FUNC_TYPE_DISTINCT
+	FUNC_TYPE_ALL
+)
+
+// AggType specifies the type of aggregation.
+type AggType int
+
+const (
+	_ AggType = iota
+	AGG_TYPE_GENERAL
+)
+
+//the common interface to UnresolvedName and QualifiedFunctionName.
+type FunctionReference interface {
+	fmt.Stringer
+	NodePrinter
+}
+
+var _ FunctionReference = &UnresolvedName{}
+
+//function reference
+type ResolvableFunctionReference struct {
+	FunctionReference
+}
+
+func FuncName2ResolvableFunctionReference(funcName *UnresolvedName) ResolvableFunctionReference {
+	return ResolvableFunctionReference{FunctionReference: funcName}
+}
+
+//function call expression
+type FuncExpr struct {
+	exprImpl
+	Func  ResolvableFunctionReference
+	Type  funcType
+	Exprs Exprs
+
+	//specify the type of aggregation.
+	AggType AggType
+
+	//aggregations which specify an order.
+	OrderBy OrderBy
+}
+
+func NewFuncExpr(ft funcType, name *UnresolvedName, e Exprs, order OrderBy) *FuncExpr {
+	return &FuncExpr{
+		Func:    FuncName2ResolvableFunctionReference(name),
+		Type:    ft,
+		Exprs:   e,
+		AggType: AGG_TYPE_GENERAL,
+		OrderBy: order,
+	}
+}
+
+//type reference
+type ResolvableTypeReference interface {
+}
+
+var _ ResolvableTypeReference = &UnresolvedObjectName{}
+var _ ResolvableTypeReference = &T{}
+
+//the Cast expression
+type CastExpr struct {
+	exprImpl
+	Expr Expr
+	Type ResolvableTypeReference
+}
+
+func NewCastExpr(e Expr, t ResolvableTypeReference) *CastExpr {
+	return &CastExpr{
+		Expr: e,
+		Type: t,
+	}
+}
+
+//the parenthesized list of expressions.
+type Tuple struct {
+	exprImpl
+	Exprs Exprs
+}
+
+func NewTuple(e Exprs) *Tuple {
+	return &Tuple{Exprs: e}
+}
+
+//the BETWEEN or a NOT BETWEEN expression
+type RangeCond struct {
+	exprImpl
+	Not      bool
+	Left     Expr
+	From, To Expr
+}
+
+func NewRangeCond(n bool, l, f, t Expr) *RangeCond {
+	return &RangeCond{
+		Not:  n,
+		Left: l,
+		From: f,
+		To:   t,
+	}
+}
diff --git a/pkg/sql/tree/identifier.go b/pkg/sql/tree/identifier.go
new file mode 100644
index 0000000000000000000000000000000000000000..139f4e35fc00ab24bd1733e4636d7d68cc5cad36
--- /dev/null
+++ b/pkg/sql/tree/identifier.go
@@ -0,0 +1,89 @@
+package tree
+
+import "fmt"
+
+// IdentifierName is referenced in the expression
+type IdentifierName interface {
+	Expr
+}
+
+//sql indentifier
+type Identifier string
+
+//
+type UnrestrictedIdentifier string
+
+//the list of identifiers.
+type IdentifierList []Identifier
+
+type ColumnItem struct {
+	IdentifierName
+
+	//the name of the column
+	ColumnName Identifier
+}
+
+//the unresolved qualified name like column name.
+type UnresolvedName struct {
+	exprImpl
+	//the number of name parts specified, including the star. Always 1 or greater.
+	NumParts int
+
+	//the name ends with a star. then the first element is empty in the Parts
+	Star bool
+
+	// Parts are the name components (at most 4: column, table, schema, catalog/db.), in reverse order.
+	Parts NameParts
+}
+
+//the path in an UnresolvedName.
+type NameParts = [4]string
+
+func NewUnresolvedName(parts ...string)(*UnresolvedName,error){
+	l:=len(parts)
+	if l < 1 || l > 4{
+		return nil,fmt.Errorf("the count of name parts among [1,4]")
+	}
+	u:= &UnresolvedName{
+		NumParts: len(parts),
+		Star:     false,
+	}
+	for i:=0 ; i < len(parts);i++{
+		u.Parts[i] = parts[l - 1 - i]
+	}
+	return u,nil
+}
+
+func NewUnresolvedNameWithStar(parts ...string)(*UnresolvedName,error){
+	l:=len(parts)
+	if l < 1 || l > 3{
+		return nil,fmt.Errorf("the count of name parts among [1,3]")
+	}
+	u:= &UnresolvedName{
+		NumParts: 1+len(parts),
+		Star:     true,
+	}
+	u.Parts[0] = ""
+	for i:=0 ; i < len(parts);i++{
+		u.Parts[i+1] = parts[l - 1 - i]
+	}
+	return u,nil
+}
+//variable in the scalar expression
+type VarName interface {
+	Expr
+}
+
+var _ VarName = &UnresolvedName{}
+var _ VarName = UnqualifiedStar{}
+
+//'*' in the scalar expression
+type UnqualifiedStar struct{
+	VarName
+}
+
+var starName VarName = UnqualifiedStar{}
+
+func StarExpr()VarName{
+	return starName
+}
diff --git a/pkg/sql/tree/object_name.go b/pkg/sql/tree/object_name.go
new file mode 100644
index 0000000000000000000000000000000000000000..519133376041a21883bc89f7c35c4cfa9dbcab08
--- /dev/null
+++ b/pkg/sql/tree/object_name.go
@@ -0,0 +1,63 @@
+package tree
+
+import "fmt"
+
+//the common interface for qualified object names
+type ObjectName interface {
+	NodePrinter
+}
+
+//the internal type for a qualified object.
+type objName struct {
+	//the path to the object.
+	ObjectNamePrefix
+
+	//the unqualified name for the object
+	ObjectName Identifier
+}
+
+//the path prefix of an object name.
+type ObjectNamePrefix struct {
+	CatalogName Identifier
+	SchemaName  Identifier
+
+	//true iff the catalog was explicitly specified
+	ExplicitCatalog bool
+	//true iff the schema was explicitly specified
+	ExplicitSchema bool
+}
+
+//the unresolved qualified name for a database object (table, view, etc)
+type UnresolvedObjectName struct {
+	//the number of name parts; >= 1
+	NumParts int
+
+	//At most three components, in reverse order.
+	//object name, schema, catalog/db.
+	Parts [3]string
+}
+
+func (u *UnresolvedObjectName) ToTableName() TableName {
+	return TableName{
+		objName: objName{
+			ObjectNamePrefix: ObjectNamePrefix{
+				SchemaName: Identifier(u.Parts[1]),
+				CatalogName: Identifier(u.Parts[2]),
+				ExplicitSchema: u.NumParts >= 2,
+				ExplicitCatalog: u.NumParts >= 3,
+			},
+			ObjectName:       Identifier(u.Parts[0]),
+		},
+	}
+}
+
+func NewUnresolvedObjectName(num int,parts [3]string)(*UnresolvedObjectName,error){
+	if num < 1 || num > 3{
+		return nil,fmt.Errorf("invalid number of parts.")
+	}
+	return &UnresolvedObjectName{
+		NumParts: num,
+		Parts:    parts,
+	},nil
+}
+
diff --git a/pkg/sql/tree/parser.go b/pkg/sql/tree/parser.go
new file mode 100644
index 0000000000000000000000000000000000000000..738e8ccadcecfc38f278e91e9db49851a4139714
--- /dev/null
+++ b/pkg/sql/tree/parser.go
@@ -0,0 +1,32 @@
+package tree
+
+import (
+	"fmt"
+	"github.com/pingcap/parser"
+	"github.com/pingcap/parser/ast"
+)
+
+type Parser struct {
+	p *parser.Parser
+}
+
+func NewParser() *Parser {
+	return &Parser{p: parser.New()}
+}
+
+func (p *Parser) Parse(sql string) ([]Statement, error) {
+	stmtNodes, _, err := p.p.Parse(sql, "", "")
+	if err != nil {
+		return nil, fmt.Errorf("parser parse failed.error:%v", err)
+	}
+
+	var tree_stmt []Statement = make([]Statement, len(stmtNodes))
+	for i, stmt := range stmtNodes {
+		if ss, ok := stmt.(*ast.SelectStmt); !ok {
+			return nil, fmt.Errorf("parser parse failed.error:%v", err)
+		} else {
+			tree_stmt[i] = transformSelectStmtToSelect(ss)
+		}
+	}
+	return tree_stmt, nil
+}
diff --git a/pkg/sql/tree/parser_test.go b/pkg/sql/tree/parser_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..315fd2f563357128682742e299cc82a6a89312ea
--- /dev/null
+++ b/pkg/sql/tree/parser_test.go
@@ -0,0 +1,45 @@
+package tree
+
+import (
+	"reflect"
+	"testing"
+)
+
+func TestParse(t *testing.T) {
+	type args struct {
+		sql string
+	}
+	//_,s :=gen_transform_t15()
+	//sql :=`SELECT u.a,(SELECT t.a FROM sa.t,u)
+	//	from u,(SELECT t.a,u.a FROM sa.t,u where t.a = u.a)
+	//	where (u.a,u.b,u.c) in (SELECT t.a,u.a,t.b * u.b tubb
+	//	FROM sa.t join u on t.c = u.c or t.d != u.d
+	//			  join v on u.a != v.a
+	//	where t.a = u.a and t.b > u.b
+	//	group by t.a,u.a,(t.b+u.b+v.b)
+	//	having t.a = 'jj' and v.c > 1000
+	//	order by t.a asc,u.a desc,v.d asc,tubb
+	//	limit 100,2000);`
+
+	tests := []struct {
+		name    string
+		args    args
+		want    []Statement
+		wantErr bool
+	}{}
+
+	p := NewParser()
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, err := p.Parse(tt.args.sql)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("Parse() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("Parse() got = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
diff --git a/pkg/sql/tree/print.go b/pkg/sql/tree/print.go
new file mode 100644
index 0000000000000000000000000000000000000000..dcfeb782776c6def9dae20aefa05b01bb145e70e
--- /dev/null
+++ b/pkg/sql/tree/print.go
@@ -0,0 +1,13 @@
+package tree
+
+import "bytes"
+
+// PrintCtx contains formatted text of the node.
+type PrintCtx struct {
+	bytes.Buffer
+}
+
+// NodePrinter for formatted output of the node.
+type NodePrinter interface {
+	Print(ctx *PrintCtx)
+}
\ No newline at end of file
diff --git a/pkg/sql/tree/readme.md b/pkg/sql/tree/readme.md
new file mode 100644
index 0000000000000000000000000000000000000000..22d185cff4f74118974c43484f67e519579e483e
--- /dev/null
+++ b/pkg/sql/tree/readme.md
@@ -0,0 +1,22 @@
+Until now, I have only implemented the transformers in SelectStmt.
+
+# usage
+Parser is in parser.go
+
+```
+p := NewParser()
+ast, err := p.Parse(sql)
+```
+
+# unsupported expression transformers that will be implemented in the future
+
+CaseExpr{}  -> CaseExpr
+DefaultExpr{} -> ColumnItem
+PositionExpr{} -> OrderBy / GroupBy position
+
+ValuesExpr{} -> ValuesClause  keyword: VALUES
+VariableExpr{} -> system / session variables
+           -> DDate / DTime / DTimestamp
+
+# supported expression transformers
+All transformers are in the file transformer.go
diff --git a/pkg/sql/tree/select.go b/pkg/sql/tree/select.go
new file mode 100644
index 0000000000000000000000000000000000000000..b4bdfdce644560601a185d948d8b88837ce8dc08
--- /dev/null
+++ b/pkg/sql/tree/select.go
@@ -0,0 +1,221 @@
+package tree
+
+type SelectStatement interface {
+	Statement
+}
+
+//the SelectStatement with an ORDER and/or LIMIT.
+type Select struct {
+	statementImpl
+	Select  SelectStatement
+	OrderBy OrderBy
+	Limit   *Limit
+}
+
+// OrderBy represents an ORDER BY clause.
+type OrderBy []*Order
+
+//the ordering expression.
+type Order struct {
+	Expr      Expr
+	Direction Direction
+	//without order
+	NullOrder bool
+}
+
+func NewOrder(e Expr, d Direction, o bool) *Order {
+	return &Order{
+		Expr:      e,
+		Direction: d,
+		NullOrder: o,
+	}
+}
+
+// Direction for ordering results.
+type Direction int8
+
+// Direction values.
+const (
+	Ascending Direction = iota
+	Descending
+)
+
+var directionName = []string{
+	"ASC",
+	"DESC",
+}
+
+//the LIMIT clause.
+type Limit struct {
+	Offset, Count Expr
+}
+
+func NewLimit(o, c Expr) *Limit {
+	return &Limit{
+		Offset: o,
+		Count:  c,
+	}
+}
+
+// the parenthesized SELECT/UNION/VALUES statement.
+type ParenSelect struct {
+	SelectStatement
+	Select *Select
+}
+
+type SelectClause struct {
+	SelectStatement
+	From     *From
+	Distinct bool
+	Where    *Where
+	Exprs    SelectExprs
+	GroupBy  GroupBy
+	Having   *Where
+}
+
+//WHERE or HAVING clause.
+type Where struct {
+	Expr Expr
+}
+
+func NewWhere(e Expr) *Where {
+	return &Where{Expr: e}
+}
+
+//SELECT expressions.
+type SelectExprs []SelectExpr
+
+//a SELECT expression.
+type SelectExpr struct {
+	Expr Expr
+	As   UnrestrictedIdentifier
+}
+
+//a GROUP BY clause.
+type GroupBy []Expr
+
+const (
+	JOIN_TYPE_FULL  = "FULL"
+	JOIN_TYPE_LEFT  = "LEFT"
+	JOIN_TYPE_RIGHT = "RIGHT"
+	JOIN_TYPE_CROSS = "CROSS"
+	JOIN_TYPE_INNER = "INNER"
+)
+
+//the table expression
+type TableExpr interface {
+	NodePrinter
+}
+
+type tableExprImpl struct {
+}
+
+func (tei *tableExprImpl) Print(ctx *PrintCtx) {}
+
+var _ TableExpr = &Subquery{}
+
+type JoinTableExpr struct {
+	TableExpr
+	JoinType string
+	Left     TableExpr
+	Right    TableExpr
+	Cond     JoinCond
+}
+
+func NewJoinTableExpr(jt string, l, r TableExpr, jc JoinCond) *JoinTableExpr {
+	return &JoinTableExpr{
+		JoinType: jt,
+		Left:     l,
+		Right:    r,
+		Cond:     jc,
+	}
+}
+
+//the join condition.
+type JoinCond interface {
+	NodePrinter
+}
+
+// the NATURAL join condition
+type NaturalJoinCond struct {
+	JoinCond
+}
+
+func NewNaturalJoinCond() *NaturalJoinCond {
+	return &NaturalJoinCond{}
+}
+
+//the ON condition for join
+type OnJoinCond struct {
+	JoinCond
+	Expr Expr
+}
+
+func NewOnJoinCond(e Expr) *OnJoinCond {
+	return &OnJoinCond{Expr: e}
+}
+
+//the USING condition
+type UsingJoinCond struct {
+	JoinCond
+	Cols IdentifierList
+}
+
+func NewUsingJoinCond(c IdentifierList) *UsingJoinCond {
+	return &UsingJoinCond{Cols: c}
+}
+
+//the parenthesized TableExpr.
+type ParenTableExpr struct {
+	TableExpr
+	Expr TableExpr
+}
+
+func NewParenTableExpr(e TableExpr) *ParenTableExpr {
+	return &ParenTableExpr{Expr: e}
+}
+
+//The alias, optionally with a column list:
+// "AS name" or "AS name(col1, col2)".
+type AliasClause struct {
+	NodePrinter
+	Alias Identifier
+}
+
+//the table expression coupled with an optional alias.
+type AliasedTableExpr struct {
+	TableExpr
+	Expr TableExpr
+	As   AliasClause
+}
+
+func NewAliasedTableExpr(e TableExpr, a AliasClause) *AliasedTableExpr {
+	return &AliasedTableExpr{
+		Expr: e,
+		As:   a,
+	}
+}
+
+//the statements as a data source includes the select statement.
+type StatementSource struct {
+	TableExpr
+	Statement Statement
+}
+
+func NewStatementSource(s Statement) *StatementSource {
+	return &StatementSource{
+		Statement: s,
+	}
+}
+
+//the list of table expressions.
+type TableExprs []TableExpr
+
+//the FROM clause.
+type From struct {
+	Tables TableExprs
+}
+
+func NewFrom(t TableExprs) *From {
+	return &From{Tables: t}
+}
diff --git a/pkg/sql/tree/stmt.go b/pkg/sql/tree/stmt.go
new file mode 100644
index 0000000000000000000000000000000000000000..b06aa98dc7bba660155a49d8514994ae3acce5af
--- /dev/null
+++ b/pkg/sql/tree/stmt.go
@@ -0,0 +1,12 @@
+package tree
+
+import "fmt"
+
+type Statement interface {
+	fmt.Stringer
+	NodePrinter
+}
+
+type statementImpl struct {
+	Statement
+}
diff --git a/pkg/sql/tree/table_name.go b/pkg/sql/tree/table_name.go
new file mode 100644
index 0000000000000000000000000000000000000000..2497690ce09db4022fd09fcc5ffa97519970e6bd
--- /dev/null
+++ b/pkg/sql/tree/table_name.go
@@ -0,0 +1,17 @@
+package tree
+
+type TableName struct {
+	TableExpr
+	objName
+}
+
+var _ TableExpr = &TableName{}
+
+func NewTableName(name Identifier,prefix ObjectNamePrefix)*TableName{
+	return &TableName{
+		objName:    objName{
+			ObjectName: name,
+			ObjectNamePrefix:prefix,
+		},
+	}
+}
\ No newline at end of file
diff --git a/pkg/sql/tree/transformer.go b/pkg/sql/tree/transformer.go
new file mode 100644
index 0000000000000000000000000000000000000000..f5bcd2f80e030694653c6d91be94b9348a583739
--- /dev/null
+++ b/pkg/sql/tree/transformer.go
@@ -0,0 +1,841 @@
+package tree
+
+import (
+	"fmt"
+	"github.com/pingcap/parser/ast"
+	"github.com/pingcap/parser/mysql"
+	"github.com/pingcap/parser/opcode"
+	"github.com/pingcap/parser/test_driver"
+	"go/constant"
+)
+
+//transform test_driver.ValueExpr::Datum to tree.NumVal
+//decimal -> ?
+//null -> unknown
+func transformDatumToNumVal(datum *test_driver.Datum) *NumVal {
+	switch datum.Kind() {
+	case test_driver.KindNull: //go Unknown Value expresses the null value.
+		return NewNumVal(constant.MakeUnknown(), "", false)
+	case test_driver.KindInt64: //include mysql true,false
+		return NewNumVal(constant.MakeInt64(datum.GetInt64()), "", false)
+	case test_driver.KindUint64:
+		return NewNumVal(constant.MakeUint64(datum.GetUint64()), "", false)
+	case test_driver.KindFloat32:
+		return NewNumVal(constant.MakeFloat64(datum.GetFloat64()), "", false)
+	case test_driver.KindFloat64: //mysql 1.2E3, 1.2E-3, -1.2E3, -1.2E-3;
+		return NewNumVal(constant.MakeFloat64(datum.GetFloat64()), "", false)
+	case test_driver.KindString:
+		return NewNumVal(constant.MakeString(datum.GetString()), "", false)
+	case test_driver.KindBytes:
+		fallthrough
+	case test_driver.KindBinaryLiteral:
+		fallthrough
+	case test_driver.KindMysqlDecimal: //mysql .2, 3.4, -6.78, +9.10
+		fallthrough
+	case test_driver.KindMysqlDuration:
+		fallthrough
+	case test_driver.KindMysqlEnum:
+		fallthrough
+	case test_driver.KindMysqlBit:
+		fallthrough
+	case test_driver.KindMysqlSet:
+		fallthrough
+	case test_driver.KindMysqlTime:
+		fallthrough
+	case test_driver.KindInterface:
+		fallthrough
+	case test_driver.KindMinNotNull:
+		fallthrough
+	case test_driver.KindMaxValue:
+		fallthrough
+	case test_driver.KindRaw:
+		fallthrough
+	case test_driver.KindMysqlJSON:
+		fallthrough
+	default:
+		panic("unsupported datum type")
+	}
+}
+
+//transform ast.UnaryOperationExpr to tree.UnaryExpr
+func transformUnaryOperatorExprToUnaryExpr(uoe *ast.UnaryOperationExpr) *UnaryExpr {
+	switch uoe.Op {
+	case opcode.Minus:
+		e := transformExprNodeToExpr(uoe.V)
+		return NewUnaryExpr(UNARY_MINUS, e)
+	case opcode.Plus:
+		e := transformExprNodeToExpr(uoe.V)
+		return NewUnaryExpr(UNARY_PLUS, e)
+	case opcode.BitNeg: //~
+		e := transformExprNodeToExpr(uoe.V)
+		return NewUnaryExpr(UNARY_TILDE, e)
+	case opcode.Not2: //!
+		e := transformExprNodeToExpr(uoe.V)
+		return NewUnaryExpr(UNARY_MARK, e)
+
+	}
+	panic(fmt.Errorf("unsupported unary expr. op:%s ", uoe.Op.String()))
+	return nil
+}
+
+//transform ast.UnaryOperationExpr to tree.NotExpr
+func transformUnaryOperatorExprToNotExpr(uoe *ast.UnaryOperationExpr) *NotExpr {
+	switch uoe.Op {
+	case opcode.Not: //not,!
+		e := transformExprNodeToExpr(uoe.V)
+		return NewNotExpr(e)
+	}
+	panic(fmt.Errorf("unsupported not expr. op:%s ", uoe.Op.String()))
+	return nil
+}
+
+//transform ast.BinaryOperationExpr to tree.BinaryExpr
+func transformBinaryOperationExprToBinaryExpr(boe *ast.BinaryOperationExpr) *BinaryExpr {
+	switch boe.Op {
+	//math operation
+	case opcode.Plus:
+		l := transformExprNodeToExpr(boe.L)
+		r := transformExprNodeToExpr(boe.R)
+		return NewBinaryExpr(PLUS, l, r)
+	case opcode.Minus:
+		l := transformExprNodeToExpr(boe.L)
+		r := transformExprNodeToExpr(boe.R)
+		return NewBinaryExpr(MINUS, l, r)
+	case opcode.Mul:
+		l := transformExprNodeToExpr(boe.L)
+		r := transformExprNodeToExpr(boe.R)
+		return NewBinaryExpr(MULTI, l, r)
+	case opcode.Div: // /
+		l := transformExprNodeToExpr(boe.L)
+		r := transformExprNodeToExpr(boe.R)
+		return NewBinaryExpr(DIV, l, r)
+	case opcode.Mod: //%
+		l := transformExprNodeToExpr(boe.L)
+		r := transformExprNodeToExpr(boe.R)
+		return NewBinaryExpr(MOD, l, r)
+	case opcode.IntDiv: // integer division
+		l := transformExprNodeToExpr(boe.L)
+		r := transformExprNodeToExpr(boe.R)
+		return NewBinaryExpr(INTEGER_DIV, l, r)
+	//bit wise operation
+	case opcode.Or: //bit or |
+		l := transformExprNodeToExpr(boe.L)
+		r := transformExprNodeToExpr(boe.R)
+		return NewBinaryExpr(BIT_OR, l, r)
+	case opcode.And: //bit and &
+		l := transformExprNodeToExpr(boe.L)
+		r := transformExprNodeToExpr(boe.R)
+		return NewBinaryExpr(BIT_AND, l, r)
+	case opcode.Xor: //bit xor ^
+		l := transformExprNodeToExpr(boe.L)
+		r := transformExprNodeToExpr(boe.R)
+		return NewBinaryExpr(BIT_XOR, l, r)
+	case opcode.LeftShift: //<<
+		l := transformExprNodeToExpr(boe.L)
+		r := transformExprNodeToExpr(boe.R)
+		return NewBinaryExpr(LEFT_SHIFT, l, r)
+	case opcode.RightShift: //>>
+		l := transformExprNodeToExpr(boe.L)
+		r := transformExprNodeToExpr(boe.R)
+		return NewBinaryExpr(RIGHT_SHIFT, l, r)
+		//logic operation
+	}
+	panic(fmt.Errorf("unsupported binary expr. op:%s ", boe.Op.String()))
+	return nil
+}
+
+//transform ast.BinaryOperationExpr to tree.ComparisonExpr
+func transformBinaryOperationExprToComparisonExpr(boe *ast.BinaryOperationExpr) *ComparisonExpr {
+	switch boe.Op {
+	//comparison operation
+	case opcode.EQ: // =
+		l := transformExprNodeToExpr(boe.L)
+		r := transformExprNodeToExpr(boe.R)
+		return NewComparisonExpr(EQUAL, l, r)
+	case opcode.LT: // <
+		l := transformExprNodeToExpr(boe.L)
+		r := transformExprNodeToExpr(boe.R)
+		return NewComparisonExpr(LESS_THAN, l, r)
+	case opcode.LE: // <=
+		l := transformExprNodeToExpr(boe.L)
+		r := transformExprNodeToExpr(boe.R)
+		return NewComparisonExpr(LESS_THAN_EQUAL, l, r)
+	case opcode.GT: // >
+		l := transformExprNodeToExpr(boe.L)
+		r := transformExprNodeToExpr(boe.R)
+		return NewComparisonExpr(GREAT_THAN, l, r)
+	case opcode.GE: // >=
+		l := transformExprNodeToExpr(boe.L)
+		r := transformExprNodeToExpr(boe.R)
+		return NewComparisonExpr(GREAT_THAN_EQUAL, l, r)
+	case opcode.NE: // <>,!=
+		l := transformExprNodeToExpr(boe.L)
+		r := transformExprNodeToExpr(boe.R)
+		return NewComparisonExpr(NOT_EQUAL, l, r)
+	}
+	panic(fmt.Errorf("unsupported comparison expr. op:%s ", boe.Op.String()))
+	return nil
+}
+
+//transform ast.BinaryOperationExpr to tree.AndExpr
+func transformBinaryOperationExprToAndExpr(boe *ast.BinaryOperationExpr) *AndExpr {
+	switch boe.Op {
+	//logic operation
+	case opcode.LogicAnd: // and,&&
+		l := transformExprNodeToExpr(boe.L)
+		r := transformExprNodeToExpr(boe.R)
+		return NewAndExpr(l, r)
+	}
+	panic(fmt.Errorf("unsupported and expr. op:%s ", boe.Op.String()))
+	return nil
+}
+
+//transform ast.BinaryOperationExpr to tree.OrExpr
+func transformBinaryOperationExprToOrExpr(boe *ast.BinaryOperationExpr) *OrExpr {
+	switch boe.Op {
+	//logic operation
+	case opcode.LogicOr: // or,||
+		l := transformExprNodeToExpr(boe.L)
+		r := transformExprNodeToExpr(boe.R)
+		return NewOrExpr(l, r)
+	}
+	panic(fmt.Errorf("unsupported or expr. op:%s ", boe.Op.String()))
+	return nil
+}
+
+//transform ast.BinaryOperationExpr to tree.XorExpr
+func transformBinaryOperationExprToXorExpr(boe *ast.BinaryOperationExpr) *XorExpr {
+	switch boe.Op {
+	//logic operation
+	case opcode.LogicXor: // xor
+		l := transformExprNodeToExpr(boe.L)
+		r := transformExprNodeToExpr(boe.R)
+		return NewXorExpr(l, r)
+	}
+	panic(fmt.Errorf("unsupported xor expr. op:%s ", boe.Op.String()))
+	return nil
+}
+
+//transform ast.IsNullExpr to tree.IsNullExpr
+func transformIsNullExprToIsNullExpr(ine *ast.IsNullExpr) *IsNullExpr {
+	if !ine.Not {
+		e := transformExprNodeToExpr(ine.Expr)
+		return NewIsNullExpr(e)
+	}
+	panic(fmt.Errorf("unsupported is null expr. %v ", ine))
+	return nil
+}
+
+//transform ast.IsNotNullExpr to tree.IsNotNullExpr
+func transformIsNullExprToIsNotNullExpr(ine *ast.IsNullExpr) *IsNotNullExpr {
+	if ine.Not {
+		e := transformExprNodeToExpr(ine.Expr)
+		return NewIsNotNullExpr(e)
+	}
+	panic(fmt.Errorf("unsupported is not null expr. %v ", ine))
+	return nil
+}
+
+//transform ast.PatternInExpr (in expression) to tree.ComparisonExpr.In
+func transformPatternInExprToComparisonExprIn(pie *ast.PatternInExpr) *ComparisonExpr {
+	e1 := transformExprNodeToExpr(pie.Expr)
+	var e2 Expr
+	var op ComparisonOp
+	if len(pie.List) != 0 {
+		// => ExprList
+		l := &ExprList{
+			Exprs: make([]Expr, len(pie.List)),
+		}
+		for i, x := range pie.List {
+			l.Exprs[i] = transformExprNodeToExpr(x)
+		}
+		e2 = l
+	} else if pie.Sel != nil {
+		e2 = transformExprNodeToExpr(pie.Sel)
+	}
+
+	if pie.Not {
+		op = NOT_IN
+	} else {
+		op = IN
+	}
+
+	return NewComparisonExpr(op, e1, e2)
+}
+
+//transform ast.PatternLikeExpr (in expression) to tree.ComparisonExpr.LIKE
+func transformPatternLikeExprToComparisonExprIn(ple *ast.PatternLikeExpr) *ComparisonExpr {
+	e1 := transformExprNodeToExpr(ple.Expr)
+	e2 := transformExprNodeToExpr(ple.Pattern)
+	//TODO:escape
+
+	var op ComparisonOp
+
+	if ple.Not {
+		op = NOT_LIKE
+	} else {
+		op = LIKE
+	}
+
+	return NewComparisonExpr(op, e1, e2)
+}
+
+//transform ast.PatternRegexpExpr (in expression) to tree.ComparisonExpr.REG_MATCH
+func transformPatternRegexpExprToComparisonExprIn(pre *ast.PatternRegexpExpr) *ComparisonExpr {
+	e1 := transformExprNodeToExpr(pre.Expr)
+	e2 := transformExprNodeToExpr(pre.Pattern)
+
+	var op ComparisonOp
+
+	if pre.Not {
+		op = NOT_REG_MATCH
+	} else {
+		op = REG_MATCH
+	}
+
+	return NewComparisonExpr(op, e1, e2)
+}
+
+//transform ast.ResultSetNode to tree.SelectStatement
+func transformResultSetNodeToSelectStatement(rsn ast.ResultSetNode) SelectStatement {
+	switch n := rsn.(type) {
+	case *ast.SelectStmt:
+		return transformSelectStmtToSelectStatement(n)
+	}
+	panic(fmt.Errorf("unsupported resultSetNode"))
+	return nil
+}
+
+//transform ast.SubqueryExpr to tree.Subquery
+func transformSubqueryExprToSubquery(se *ast.SubqueryExpr) *Subquery {
+	e := transformResultSetNodeToSelectStatement(se.Query)
+	return NewSubquery(e, se.Exists)
+}
+
+//transform ast.ExistsSubqueryExpr to tree.Subquery
+func transformExistsSubqueryExprToSubquery(ese *ast.ExistsSubqueryExpr) *Subquery {
+	e := transformExprNodeToExpr(ese.Sel)
+	return NewSubquery(e, ese.Not)
+}
+
+//transform ast.CompareSubqueryExpr to tree.ComparisonExpr.SubOp
+func transformCompareSubqueryExprToSubquery(cse *ast.CompareSubqueryExpr) *ComparisonExpr {
+	l := transformExprNodeToExpr(cse.L)
+	r := transformExprNodeToExpr(cse.R)
+	var subop ComparisonOp
+
+	if cse.All {
+		subop = ALL
+	} else {
+		subop = ANY
+	}
+
+	switch cse.Op {
+	//comparison operation
+	case opcode.EQ: // =
+		return NewComparisonExprWithSubop(EQUAL, subop, l, r)
+	case opcode.LT: // <
+		return NewComparisonExprWithSubop(LESS_THAN, subop, l, r)
+	case opcode.LE: // <=
+		return NewComparisonExprWithSubop(LESS_THAN_EQUAL, subop, l, r)
+	case opcode.GT: // >
+		return NewComparisonExprWithSubop(GREAT_THAN, subop, l, r)
+	case opcode.GE: // >=
+		return NewComparisonExprWithSubop(GREAT_THAN_EQUAL, subop, l, r)
+	case opcode.NE: // <>,!=
+		return NewComparisonExprWithSubop(NOT_EQUAL, subop, l, r)
+	}
+	panic(fmt.Errorf("unsupported CompareSubqueryExpr expr. op:%s ", cse.Op.String()))
+	return nil
+}
+
+//transform ast.ParenthesesExpr to tree.ParenExpr
+func transformParenthesesExprToParenExpr(pe *ast.ParenthesesExpr) *ParenExpr {
+	e := transformExprNodeToExpr(pe.Expr)
+	return NewParenExpr(e)
+}
+
+//transform ast.TableName to tree.TableName
+func transformTableNameToTableName(tn *ast.TableName) *TableName {
+	return NewTableName(Identifier(tn.Name.O), ObjectNamePrefix{
+		CatalogName:     "",
+		SchemaName:      Identifier(tn.Schema.O),
+		ExplicitCatalog: false,
+		ExplicitSchema:  len(tn.Schema.O) != 0,
+	})
+}
+
+//transform ast.TableSource to tree.AliasedTableExpr
+func transformTableSourceToAliasedTableExpr(ts *ast.TableSource) *AliasedTableExpr {
+	te := transformResultSetNodeToTableExpr(ts.Source)
+	return NewAliasedTableExpr(te, AliasClause{
+		Alias: Identifier(ts.AsName.O),
+	})
+}
+
+//transform ast.SelectStmt to tree.StatementSource
+func transformSelectStmtToStatementSource(ss *ast.SelectStmt) *StatementSource {
+	sts := transformSelectStmtToSelectStatement(ss)
+	return NewStatementSource(sts)
+}
+
+//transform ast.ResultSetNode to tree.TableExpr
+func transformResultSetNodeToTableExpr(rsn ast.ResultSetNode) TableExpr {
+	switch n := rsn.(type) {
+	case *ast.SubqueryExpr:
+		return transformSubqueryExprToSubquery(n)
+	case *ast.Join:
+		if n.ExplicitParens {
+			return transformJoinToParenTableExpr(n)
+		}
+		return transformJoinToJoinTableExpr(n)
+	case *ast.TableName:
+		return transformTableNameToTableName(n)
+	case *ast.TableSource:
+		return transformTableSourceToAliasedTableExpr(n)
+	case *ast.SelectStmt:
+		return transformSelectStmtToStatementSource(n)
+	}
+	panic(fmt.Errorf("unsupported ResultSetNode type:%v ", rsn))
+	return nil
+}
+
+//transform []*ast.ColumnName to tree.IdentifierList
+func transformColumnNameListToNameList(cn []*ast.ColumnName) IdentifierList {
+	var l IdentifierList
+	for _, x := range cn {
+		l = append(l, Identifier(x.Name.O))
+	}
+	return l
+}
+
+/*
+transform ast.Join to tree.JoinTableExpr
+This is core of transformation from ast.TableRefsClause to tree.From
+
+FROM: https://dev.mysql.com/doc/refman/8.0/en/join.html
+In MySQL, JOIN, CROSS JOIN, and INNER JOIN are syntactic equivalents (they can replace each other).
+In standard SQL, they are not equivalent. INNER JOIN is used with an ON clause, CROSS JOIN is used otherwise.
+
+INNER JOIN is used with the ON condition.
+NATURAL JOIN has implicit ON condition -  columns with same names in both tables.
+STRAIGHT JOIN defines the order among the tables from the left to the right.
+*/
+func transformJoinToJoinTableExpr(j *ast.Join) *JoinTableExpr {
+	var t string
+	var joinCon JoinCond
+
+	switch j.Tp {
+	case ast.CrossJoin:
+		t = JOIN_TYPE_CROSS
+	case ast.LeftJoin:
+		t = JOIN_TYPE_LEFT
+	case ast.RightJoin:
+		t = JOIN_TYPE_RIGHT
+	}
+
+	if j.NaturalJoin {
+		joinCon = NewNaturalJoinCond()
+	} else if j.StraightJoin {
+		//TODO:
+	}
+
+	if j.ExplicitParens {
+		//TODO:
+	}
+
+	l := transformResultSetNodeToTableExpr(j.Left)
+
+	if j.Right == nil {
+		return NewJoinTableExpr(t, l, nil, joinCon)
+	}
+	r := transformResultSetNodeToTableExpr(j.Right)
+
+	if j.On != nil {
+		onE := transformExprNodeToExpr(j.On.Expr)
+		joinCon = NewOnJoinCond(onE)
+	} else if j.Using != nil {
+		iList := transformColumnNameListToNameList(j.Using)
+		joinCon = NewUsingJoinCond(iList)
+	}
+
+	return NewJoinTableExpr(t, l, r, joinCon)
+}
+
+//transform ast.Join to tree.ParenTableExpr
+func transformJoinToParenTableExpr(j *ast.Join) *ParenTableExpr {
+	if j.ExplicitParens {
+		j.ExplicitParens = false
+		jt := transformJoinToJoinTableExpr(j)
+		return NewParenTableExpr(jt)
+	}
+	panic(fmt.Errorf("Need ExplicitParens :%v ", j))
+	return nil
+}
+
+//transform ast.TableRefsClause to tree.From
+func transformTableRefsClauseToFrom(trc *ast.TableRefsClause) *From {
+	var te []TableExpr = make([]TableExpr, 1)
+	t := transformJoinToJoinTableExpr(trc.TableRefs)
+	te[0] = t
+	return NewFrom(te)
+}
+
+//transform ast.ColumnNameExpr to tree.UnresolvedName
+func transformColumnNameExprToUnresolvedName(cne *ast.ColumnNameExpr) *UnresolvedName {
+	cn := cne.Name
+	ud, _ := NewUnresolvedName(cn.Schema.O, cn.Table.O, cn.Name.O)
+	return ud
+}
+
+//transform ast.FuncCallExpr to tree.FuncExpr
+func transformFuncCallExprToFuncExpr(fce *ast.FuncCallExpr) *FuncExpr {
+	fname, _ := NewUnresolvedName(fce.Schema.O, fce.FnName.O)
+	var es Exprs = make([]Expr, len(fce.Args))
+	for i, arg := range fce.Args {
+		e := transformExprNodeToExpr(arg)
+		es[i] = e
+	}
+
+	return NewFuncExpr(0, fname, es, nil)
+}
+
+//transform ast.AggregateFuncExpr to tree.FuncExpr
+func transformAggregateFuncExprToFuncExpr(afe *ast.AggregateFuncExpr) *FuncExpr {
+	fname, _ := NewUnresolvedName(afe.F)
+	var es Exprs = make([]Expr, len(afe.Args))
+	for i, arg := range afe.Args {
+		e := transformExprNodeToExpr(arg)
+		es[i] = e
+	}
+
+	var ft funcType = 0
+	if afe.Distinct {
+		ft = FUNC_TYPE_DISTINCT
+	}
+
+	var ob OrderBy
+	if afe.Order != nil {
+		ob = transformOrderByClauseToOrderBy(afe.Order)
+	}
+	return NewFuncExpr(ft, fname, es, ob)
+}
+
+//transform ast.FuncCastExpr to tree.CastExpr
+func transformFuncCastExprToCastExpr(fce *ast.FuncCastExpr) *CastExpr {
+	e := transformExprNodeToExpr(fce.Expr)
+	var t ResolvableTypeReference
+	switch fce.Tp.Tp {
+	case mysql.TypeUnspecified:
+		panic(fmt.Errorf("unsupported type"))
+	case mysql.TypeTiny:
+		t = TYPE_TINY
+	case mysql.TypeShort:
+		t = TYPE_SHORT
+	case mysql.TypeLong:
+		t = TYPE_LONG
+	case mysql.TypeFloat:
+		t = TYPE_FLOAT
+	case mysql.TypeDouble:
+		t = TYPE_DOUBLE
+	case mysql.TypeNull:
+		t = TYPE_NULL
+	case mysql.TypeTimestamp:
+		t = TYPE_TIMESTAMP
+	case mysql.TypeLonglong:
+		t = TYPE_LONGLONG
+	case mysql.TypeInt24:
+		t = TYPE_INT24
+	case mysql.TypeDate:
+		t = TYPE_DATE
+	case mysql.TypeDuration:
+		t = TYPE_DURATION
+	case mysql.TypeDatetime:
+		t = TYPE_DATETIME
+	case mysql.TypeYear:
+		t = TYPE_YEAR
+	case mysql.TypeNewDate:
+		t = TYPE_NEWDATE
+	case mysql.TypeVarchar:
+		t = TYPE_VARCHAR
+	case mysql.TypeBit:
+		t = TYPE_BIT
+	case mysql.TypeJSON:
+		t = TYPE_JSON
+	case mysql.TypeNewDecimal:
+		t = TYPE_NEWDATE
+	case mysql.TypeEnum:
+		t = TYPE_ENUM
+	case mysql.TypeSet:
+		t = TYPE_SET
+	case mysql.TypeTinyBlob:
+		t = TYPE_TINY_BLOB
+	case mysql.TypeMediumBlob:
+		t = TYPE_MEDIUM_BLOB
+	case mysql.TypeLongBlob:
+		t = TYPE_LONG_BLOB
+	case mysql.TypeBlob:
+		t = TYPE_BLOB
+	case mysql.TypeVarString:
+		t = TYPE_VARSTRING
+	case mysql.TypeString:
+		t = TYPE_STRING
+	case mysql.TypeGeometry:
+		t = TYPE_GEOMETRY
+	default:
+		panic("unsupported cast type")
+	}
+	return NewCastExpr(e, t)
+}
+
+//transform ast.RowExpr to tree.Tuple
+func transformRowExprToTuple(re *ast.RowExpr) *Tuple {
+	var ar []Expr = make([]Expr, len(re.Values))
+	for i, re := range re.Values {
+		ar[i] = transformExprNodeToExpr(re)
+	}
+	return NewTuple(ar)
+}
+
+//transform ast.BetweenExpr to tree.RangeCond
+func transformBetweenExprToRangeCond(be *ast.BetweenExpr) *RangeCond {
+	e := transformExprNodeToExpr(be.Expr)
+	l := transformExprNodeToExpr(be.Left)
+	r := transformExprNodeToExpr(be.Right)
+	return NewRangeCond(be.Not, e, l, r)
+}
+
+//transform ast.ExprNode to tree.Expr
+func transformExprNodeToExpr(node ast.ExprNode) Expr {
+	switch n := node.(type) {
+	case ast.ValueExpr:
+		if ve, ok := n.(*test_driver.ValueExpr); !ok {
+			panic("convert to test_driver.ValueExpr failed.")
+		} else {
+			return transformDatumToNumVal(&ve.Datum)
+		}
+	case *ast.BinaryOperationExpr:
+		switch n.Op {
+		case opcode.Plus,
+			opcode.Minus,
+			opcode.Mul,
+			opcode.Div,
+			opcode.Mod,
+			opcode.IntDiv,
+			opcode.Or,
+			opcode.And,
+			opcode.Xor,
+			opcode.LeftShift,
+			opcode.RightShift:
+			return transformBinaryOperationExprToBinaryExpr(n)
+		case opcode.EQ,
+			opcode.LT,
+			opcode.LE,
+			opcode.GT,
+			opcode.GE,
+			opcode.NE:
+			return transformBinaryOperationExprToComparisonExpr(n)
+		case opcode.LogicAnd:
+			return transformBinaryOperationExprToAndExpr(n)
+		case opcode.LogicOr:
+			return transformBinaryOperationExprToOrExpr(n)
+		case opcode.LogicXor:
+			return transformBinaryOperationExprToXorExpr(n)
+		}
+
+	case *ast.UnaryOperationExpr:
+		switch n.Op {
+		case opcode.Not:
+			return transformUnaryOperatorExprToNotExpr(n)
+		}
+		return transformUnaryOperatorExprToUnaryExpr(n)
+	case *ast.IsNullExpr:
+		if n.Not {
+			return transformIsNullExprToIsNotNullExpr(n)
+		} else {
+			return transformIsNullExprToIsNullExpr(n)
+		}
+	case *ast.PatternInExpr:
+		return transformPatternInExprToComparisonExprIn(n)
+	case *ast.PatternLikeExpr:
+		return transformPatternLikeExprToComparisonExprIn(n)
+	case *ast.PatternRegexpExpr:
+		return transformPatternRegexpExprToComparisonExprIn(n)
+	case *ast.SubqueryExpr:
+		return transformSubqueryExprToSubquery(n)
+	case *ast.ExistsSubqueryExpr:
+		return transformExistsSubqueryExprToSubquery(n)
+	case *ast.CompareSubqueryExpr:
+		return transformCompareSubqueryExprToSubquery(n)
+	case *ast.ParenthesesExpr:
+		return transformParenthesesExprToParenExpr(n)
+	case *ast.ColumnNameExpr:
+		return transformColumnNameExprToUnresolvedName(n)
+	case *ast.FuncCallExpr:
+		return transformFuncCallExprToFuncExpr(n)
+	case *ast.AggregateFuncExpr:
+		return transformAggregateFuncExprToFuncExpr(n)
+	case *ast.FuncCastExpr:
+		return transformFuncCastExprToCastExpr(n)
+	case *ast.RowExpr:
+		return transformRowExprToTuple(n)
+	case *ast.BetweenExpr:
+		return transformBetweenExprToRangeCond(n)
+	}
+	panic(fmt.Errorf("unsupported node %v ", node))
+	return nil
+}
+
+//transform ast.WildCardField to
+func transformWildCardFieldToVarName(wcf *ast.WildCardField) VarName {
+	sch := len(wcf.Schema.O) != 0
+	tbl := len(wcf.Table.O) != 0
+	if sch && tbl {
+		//UnresolvedName
+		u, _ := NewUnresolvedNameWithStar(wcf.Schema.O, wcf.Table.O)
+		return u
+	} else if tbl {
+		//UnresolvedName
+		u, _ := NewUnresolvedNameWithStar(wcf.Table.O)
+		return u
+	} else {
+		//*
+		return StarExpr()
+	}
+}
+
+//transform ast.FieldList to tree.SelectExprs
+func transformFieldListToSelectExprs(fl *ast.FieldList) SelectExprs {
+	var sea []SelectExpr = make([]SelectExpr, len(fl.Fields))
+	for i, se := range fl.Fields {
+		var e Expr
+		if se.Expr != nil {
+			e = transformExprNodeToExpr(se.Expr)
+		} else {
+			e = transformWildCardFieldToVarName(se.WildCard)
+		}
+
+		sea[i].Expr = e
+		sea[i].As = UnrestrictedIdentifier(se.AsName.O)
+	}
+	return sea
+}
+
+//transform ast.GroupByClause to tree.GroupBy
+func transformGroupByClauseToGroupBy(gbc *ast.GroupByClause) GroupBy {
+	var gb []Expr = make([]Expr, len(gbc.Items))
+	for i, bi := range gbc.Items {
+		gb[i] = transformExprNodeToExpr(bi.Expr)
+	}
+	return gb
+}
+
+//transform ast.ByItem to tree.Order
+func transformByItemToOrder(bi *ast.ByItem) *Order {
+	e := transformExprNodeToExpr(bi.Expr)
+	var a Direction
+	if bi.Desc {
+		a = Descending
+	} else {
+		a = Ascending
+	}
+	return NewOrder(e, a, bi.NullOrder)
+}
+
+//transform ast.OrderByClause to tree.OrderBy
+func transformOrderByClauseToOrderBy(obc *ast.OrderByClause) OrderBy {
+	var ob []*Order = make([]*Order, len(obc.Items))
+	for i, obi := range obc.Items {
+		ob[i] = transformByItemToOrder(obi)
+	}
+	return ob
+}
+
+//transform ast.HavingClause to tree.Where
+func transformHavingClauseToWhere(hc *ast.HavingClause) *Where {
+	e := transformExprNodeToExpr(hc.Expr)
+	return NewWhere(e)
+}
+
+//transform ast.Limit to tree.Limit
+func transformLimitToLimit(l *ast.Limit) *Limit {
+	o := transformExprNodeToExpr(l.Offset)
+	c := transformExprNodeToExpr(l.Count)
+	return NewLimit(o, c)
+}
+
+//transform ast.SelectStmt to tree.SelectClause
+func transformSelectStmtToSelectClause(ss *ast.SelectStmt) *SelectClause {
+	var from *From = nil
+	if ss.From != nil {
+		from = transformTableRefsClauseToFrom(ss.From)
+	}
+
+	var where *Where = nil
+	if ss.Where != nil {
+		where = NewWhere(transformExprNodeToExpr(ss.Where))
+	}
+
+	sea := transformFieldListToSelectExprs(ss.Fields)
+
+	var gb []Expr = nil
+	if ss.GroupBy != nil {
+		gb = transformGroupByClauseToGroupBy(ss.GroupBy)
+	}
+
+	var having *Where = nil
+	if ss.Having != nil {
+		having = transformHavingClauseToWhere(ss.Having)
+	}
+
+	return &SelectClause{
+		From:     from,
+		Distinct: ss.Distinct,
+		Where:    where,
+		Exprs:    sea,
+		GroupBy:  gb,
+		Having:   having,
+	}
+}
+
+//transform ast.SelectStmt to tree.Select
+func transformSelectStmtToSelect(ss *ast.SelectStmt) *Select {
+	sc := transformSelectStmtToSelectClause(ss)
+
+	var ob []*Order = nil
+	if ss.OrderBy != nil {
+		ob = transformOrderByClauseToOrderBy(ss.OrderBy)
+	}
+
+	var lmt *Limit
+	if ss.Limit != nil {
+		lmt = transformLimitToLimit(ss.Limit)
+	}
+
+	return &Select{
+		Select:  sc,
+		OrderBy: ob,
+		Limit:   lmt,
+	}
+}
+
+//transform ast.SelectStmt(IsInBraces is true) to tree.ParenSelect
+func transformSelectStmtToParenSelect(ss *ast.SelectStmt) *ParenSelect {
+	if !ss.IsInBraces {
+		panic(fmt.Errorf("only in brace"))
+	}
+	ss.IsInBraces = false
+	s := transformSelectStmtToSelect(ss)
+	return &ParenSelect{
+		Select: s,
+	}
+}
+
+//transform ast.SelectStmt to tree.SelectStatement
+func transformSelectStmtToSelectStatement(ss *ast.SelectStmt) SelectStatement {
+	if ss.IsInBraces {
+		return transformSelectStmtToParenSelect(ss)
+	} else {
+		return transformSelectStmtToSelectClause(ss)
+	}
+}
diff --git a/pkg/sql/tree/transformer_test.go b/pkg/sql/tree/transformer_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..f81a130c044c8dcc63874f7464d42a0ce3559e91
--- /dev/null
+++ b/pkg/sql/tree/transformer_test.go
@@ -0,0 +1,3539 @@
+package tree
+
+import (
+	"github.com/pingcap/parser"
+	"github.com/pingcap/parser/ast"
+	"github.com/pingcap/parser/model"
+	"github.com/pingcap/parser/opcode"
+	"github.com/pingcap/parser/test_driver"
+	_ "github.com/pingcap/parser/test_driver"
+	"github.com/pingcap/parser/types"
+	"go/constant"
+	"math"
+	"reflect"
+	"testing"
+)
+
+/**
+https://github.com/pingcap/parser/blob/master/docs/quickstart.md
+*/
+func TestParser(t *testing.T) {
+	p := parser.New()
+
+	sql := `SELECT u.a,(SELECT t.a FROM sa.t,u)
+		from u,(SELECT t.a,u.a FROM sa.t,u where t.a = u.a)
+		where (u.a,u.b,u.c) in (SELECT t.a,u.a,t.b * u.b tubb
+		FROM sa.t join u on t.c = u.c or t.d != u.d
+				  join v on u.a != v.a
+		where t.a = u.a and t.b > u.b
+		group by t.a,u.a,(t.b+u.b+v.b)
+		having t.a = 'jj' and v.c > 1000
+		order by t.a asc,u.a desc,v.d asc,tubb
+		limit 100,2000)
+
+;`
+
+	stmtNodes, _, err := p.Parse(sql, "", "")
+	if err != nil {
+		t.Errorf("parser parse failed.error:%v", err)
+		return
+	}
+
+	for _, _ = range stmtNodes {
+
+	}
+}
+
+func Test_transformDatumToNumVal(t *testing.T) {
+	type args struct {
+		datum *test_driver.Datum
+	}
+
+	t1 := test_driver.NewDatum(math.MaxInt64)
+	t2 := test_driver.NewDatum(math.MinInt64)
+	t3 := test_driver.NewDatum(nil)
+	//this case is unwanted. Datum.SetUint64 is wrong.
+	t4 := test_driver.NewDatum(math.MaxUint64 / 2)
+	t5 := test_driver.NewDatum(0)
+	t6 := test_driver.NewDatum(math.MaxFloat32)
+	t7 := test_driver.NewDatum(-math.MaxFloat32)
+	t8 := test_driver.NewDatum(math.MaxFloat64)
+	t9 := test_driver.NewDatum(-math.MaxFloat64)
+
+	s := "a string"
+	t10 := test_driver.NewDatum(s)
+	t11 := test_driver.NewDatum(true)
+	t12 := test_driver.NewDatum(false)
+
+	tests := []struct {
+		name string
+		args args
+		want *NumVal
+	}{
+		{"t1", args{&t1}, NewNumVal(constant.MakeInt64(math.MaxInt64), "", false)},
+		{"t2", args{&t2}, NewNumVal(constant.MakeInt64(math.MinInt64), "", false)},
+		{"t3", args{&t3}, NewNumVal(constant.MakeUnknown(), "", false)},
+		{"t4", args{&t4}, NewNumVal(constant.MakeUint64(math.MaxUint64/2), "", false)},
+		{"t5", args{&t5}, NewNumVal(constant.MakeUint64(0), "", false)},
+		{"t6", args{&t6}, NewNumVal(constant.MakeFloat64(math.MaxFloat32), "", false)},
+		{"t7", args{&t7}, NewNumVal(constant.MakeFloat64(-math.MaxFloat32), "", false)},
+		{"t8", args{&t8}, NewNumVal(constant.MakeFloat64(math.MaxFloat64), "", false)},
+		{"t9", args{&t9}, NewNumVal(constant.MakeFloat64(-math.MaxFloat64), "", false)},
+		{"t10", args{&t10}, NewNumVal(constant.MakeString(s), "", false)},
+		{"t11", args{&t11}, NewNumVal(constant.MakeInt64(1), "", false)},
+		{"t12", args{&t12}, NewNumVal(constant.MakeInt64(0), "", false)},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := transformDatumToNumVal(tt.args.datum); !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("transformDatumToNumVal() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func Test_transformExprNodeToExpr(t *testing.T) {
+	type args struct {
+		node ast.ExprNode
+	}
+
+	t1 := ast.NewValueExpr(math.MaxInt64, "", "")
+	t2 := ast.NewValueExpr(math.MinInt64, "", "")
+	t3 := ast.NewValueExpr(nil, "", "")
+	//this case is unwanted. Datum.SetUint64 is wrong.
+	t4 := ast.NewValueExpr(math.MaxUint64/2, "", "")
+	t5 := ast.NewValueExpr(0, "", "")
+	t6 := ast.NewValueExpr(math.MaxFloat32, "", "")
+	t7 := ast.NewValueExpr(-math.MaxFloat32, "", "")
+	t8 := ast.NewValueExpr(math.MaxFloat64, "", "")
+	t9 := ast.NewValueExpr(-math.MaxFloat64, "", "")
+	s := "a string"
+	t10 := ast.NewValueExpr(s, "", "")
+
+	e1 := ast.NewValueExpr(1, "", "")
+	e2 := ast.NewValueExpr(2, "", "")
+	e3 := ast.NewValueExpr(3, "", "")
+	e4 := ast.NewValueExpr(4, "", "")
+	e5 := ast.NewValueExpr(5, "", "")
+	e6 := ast.NewValueExpr(6, "", "")
+	eTrue := ast.NewValueExpr(true, "", "")
+	eFalse := ast.NewValueExpr(false, "", "")
+
+	f1 := NewNumVal(constant.MakeInt64(1), "", false)
+	f2 := NewNumVal(constant.MakeInt64(2), "", false)
+	f3 := NewNumVal(constant.MakeInt64(3), "", false)
+	f4 := NewNumVal(constant.MakeInt64(4), "", false)
+	f5 := NewNumVal(constant.MakeInt64(5), "", false)
+	f6 := NewNumVal(constant.MakeInt64(6), "", false)
+	fTrue := NewNumVal(constant.MakeInt64(1), "", false)
+	fFalse := NewNumVal(constant.MakeInt64(0), "", false)
+
+	//2 * 3
+	t11 := &ast.BinaryOperationExpr{
+		Op: opcode.Mul,
+		L:  e2,
+		R:  e3,
+	}
+
+	t11Want := NewBinaryExpr(MULTI,
+		f2,
+		f3)
+
+	//1 + 2 * 3
+	t12 := &ast.BinaryOperationExpr{
+		Op: opcode.Plus,
+		L:  e1,
+		R:  t11,
+	}
+
+	t12Want := NewBinaryExpr(PLUS,
+		f1,
+		t11Want)
+
+	//1 + 2 * 3 + 4
+	t13 := &ast.BinaryOperationExpr{
+		Op: opcode.Plus,
+		L:  t12,
+		R:  e4,
+	}
+
+	t13Want := NewBinaryExpr(PLUS,
+		t12Want,
+		f4,
+	)
+
+	//1 + 2 * 3 + 4 - 5
+	t14 := &ast.BinaryOperationExpr{
+		Op: opcode.Minus,
+		L:  t13,
+		R:  e5,
+	}
+
+	t14Want := NewBinaryExpr(MINUS,
+		t13Want,
+		f5,
+	)
+
+	//-1 * 2
+	t15_1 := &ast.UnaryOperationExpr{
+		Op: opcode.Minus,
+		V:  e1,
+	}
+
+	t15 := &ast.BinaryOperationExpr{
+		Op: opcode.Mul,
+		L:  t15_1,
+		R:  e2,
+	}
+
+	t15Want := NewBinaryExpr(MULTI,
+		NewUnaryExpr(UNARY_MINUS, f1),
+		f2,
+	)
+
+	//+1 * 2
+	t16_1 := &ast.UnaryOperationExpr{
+		Op: opcode.Plus,
+		V:  e1,
+	}
+
+	t16 := &ast.BinaryOperationExpr{
+		Op: opcode.Mul,
+		L:  t16_1,
+		R:  e2,
+	}
+
+	t16Want := NewBinaryExpr(MULTI,
+		NewUnaryExpr(UNARY_PLUS, f1),
+		f2,
+	)
+
+	//~1 * 2
+	t17_1 := &ast.UnaryOperationExpr{
+		Op: opcode.BitNeg,
+		V:  e1,
+	}
+
+	t17 := &ast.BinaryOperationExpr{
+		Op: opcode.Mul,
+		L:  t17_1,
+		R:  e2,
+	}
+
+	t17Want := NewBinaryExpr(MULTI,
+		NewUnaryExpr(UNARY_TILDE, f1),
+		f2,
+	)
+
+	//!1
+	t18 := &ast.UnaryOperationExpr{
+		Op: opcode.Not2,
+		V:  e1,
+	}
+
+	t18Want := NewUnaryExpr(UNARY_MARK, f1)
+
+	//1 | 2
+	t21 := &ast.BinaryOperationExpr{
+		Op: opcode.Or,
+		L:  e1,
+		R:  e2,
+	}
+
+	t21Want := NewBinaryExpr(BIT_OR,
+		f1,
+		f2)
+
+	//1 & 2
+	t22 := &ast.BinaryOperationExpr{
+		Op: opcode.And,
+		L:  e1,
+		R:  e2,
+	}
+
+	t22Want := NewBinaryExpr(BIT_AND,
+		f1,
+		f2)
+
+	//1 ^ 2
+	t23 := &ast.BinaryOperationExpr{
+		Op: opcode.Xor,
+		L:  e1,
+		R:  e2,
+	}
+
+	t23Want := NewBinaryExpr(BIT_XOR,
+		f1,
+		f2)
+
+	//1 << 2
+	t24 := &ast.BinaryOperationExpr{
+		Op: opcode.LeftShift,
+		L:  e1,
+		R:  e2,
+	}
+
+	t24Want := NewBinaryExpr(LEFT_SHIFT,
+		f1,
+		f2)
+
+	//1 >> 2
+	t25 := &ast.BinaryOperationExpr{
+		Op: opcode.RightShift,
+		L:  e1,
+		R:  e2,
+	}
+
+	t25Want := NewBinaryExpr(RIGHT_SHIFT,
+		f1,
+		f2)
+
+	//1 + 2 * 3 + 4 - 5 / 6
+	t26_1 := &ast.BinaryOperationExpr{
+		Op: opcode.Div,
+		L:  e5,
+		R:  e6,
+	}
+
+	t26 := &ast.BinaryOperationExpr{
+		Op: opcode.Minus,
+		L:  t13,
+		R:  t26_1,
+	}
+
+	t26want_1 := NewBinaryExpr(DIV, f5, f6)
+	t26Want := NewBinaryExpr(MINUS,
+		t13Want,
+		t26want_1,
+	)
+
+	//1 % 2
+	t27 := &ast.BinaryOperationExpr{
+		Op: opcode.Mod,
+		L:  e1,
+		R:  e2,
+	}
+
+	t27Want := NewBinaryExpr(MOD,
+		f1,
+		f2)
+
+	//1 div 2
+	t28 := &ast.BinaryOperationExpr{
+		Op: opcode.IntDiv,
+		L:  e1,
+		R:  e2,
+	}
+
+	t28Want := NewBinaryExpr(INTEGER_DIV,
+		f1,
+		f2)
+
+	//1 = 2
+	t29 := &ast.BinaryOperationExpr{
+		Op: opcode.EQ,
+		L:  e1,
+		R:  e2,
+	}
+
+	t29Want := NewComparisonExpr(EQUAL,
+		f1,
+		f2)
+
+	//1 < 2
+	t30 := &ast.BinaryOperationExpr{
+		Op: opcode.LT,
+		L:  e1,
+		R:  e2,
+	}
+
+	t30Want := NewComparisonExpr(LESS_THAN,
+		f1,
+		f2)
+
+	//1 <= 2
+	t31 := &ast.BinaryOperationExpr{
+		Op: opcode.LE,
+		L:  e1,
+		R:  e2,
+	}
+
+	t31Want := NewComparisonExpr(LESS_THAN_EQUAL,
+		f1,
+		f2)
+
+	//1 > 2
+	t32 := &ast.BinaryOperationExpr{
+		Op: opcode.GT,
+		L:  e1,
+		R:  e2,
+	}
+
+	t32Want := NewComparisonExpr(GREAT_THAN,
+		f1,
+		f2)
+
+	//1 >= 2
+	t33 := &ast.BinaryOperationExpr{
+		Op: opcode.GE,
+		L:  e1,
+		R:  e2,
+	}
+
+	t33Want := NewComparisonExpr(GREAT_THAN_EQUAL,
+		f1,
+		f2)
+
+	//1 <>,!= 2
+	t34 := &ast.BinaryOperationExpr{
+		Op: opcode.NE,
+		L:  e1,
+		R:  e2,
+	}
+
+	t34Want := NewComparisonExpr(NOT_EQUAL,
+		f1,
+		f2)
+
+	//1 and 0
+	t35 := &ast.BinaryOperationExpr{
+		Op: opcode.LogicAnd,
+		L:  e1,
+		R:  e2,
+	}
+
+	t35Want := NewAndExpr(f1, f2)
+
+	//1 or 0
+	t36 := &ast.BinaryOperationExpr{
+		Op: opcode.LogicOr,
+		L:  e1,
+		R:  e2,
+	}
+
+	t36Want := NewOrExpr(f1, f2)
+
+	//not 1
+	t37 := &ast.UnaryOperationExpr{
+		Op: opcode.Not,
+		V:  e1,
+	}
+
+	t37Want := NewNotExpr(f1)
+
+	//1 xor 0
+	t38 := &ast.BinaryOperationExpr{
+		Op: opcode.LogicXor,
+		L:  e1,
+		R:  e2,
+	}
+
+	t38Want := NewXorExpr(f1, f2)
+
+	// is null
+	t39 := &ast.IsNullExpr{
+		Expr: e1,
+		Not:  false,
+	}
+
+	t39Want := NewIsNullExpr(f1)
+
+	// is not null
+	t40 := &ast.IsNullExpr{
+		Expr: e1,
+		Not:  true,
+	}
+
+	t40Want := NewIsNotNullExpr(f1)
+
+	//2 IN (1,2,3,4);
+	t41 := &ast.PatternInExpr{
+		Expr: e2,
+		List: []ast.ExprNode{e1, e2, e3, e4},
+		Not:  false,
+		Sel:  nil,
+	}
+
+	t41Want := NewComparisonExpr(IN, f2, &ExprList{
+		Exprs: []Expr{f1, f2, f3, f4},
+	})
+
+	//2 NOT IN (1,2,3,4);
+	t42 := &ast.PatternInExpr{
+		Expr: e2,
+		List: []ast.ExprNode{e1, e2, e3, e4},
+		Not:  true,
+		Sel:  nil,
+	}
+
+	t42Want := NewComparisonExpr(NOT_IN, f2, &ExprList{
+		Exprs: []Expr{f1, f2, f3, f4},
+	})
+
+	//2 LIKE 'xxx';
+	t43 := &ast.PatternLikeExpr{
+		Expr:     e1,
+		Pattern:  e2,
+		Not:      false,
+		Escape:   0,
+		PatChars: nil,
+		PatTypes: nil,
+	}
+
+	t43Want := NewComparisonExpr(LIKE, f1, f2)
+
+	//2 NOT LIKE 'xxx';
+	t44 := &ast.PatternLikeExpr{
+		Expr:     e1,
+		Pattern:  e2,
+		Not:      true,
+		Escape:   0,
+		PatChars: nil,
+		PatTypes: nil,
+	}
+
+	t44Want := NewComparisonExpr(NOT_LIKE, f1, f2)
+
+	//2 REGEXP 'xxx';
+	t45 := &ast.PatternRegexpExpr{
+		Expr:    e1,
+		Pattern: e2,
+		Not:     false,
+		Re:      nil,
+		Sexpr:   nil,
+	}
+
+	t45Want := NewComparisonExpr(REG_MATCH, f1, f2)
+
+	//2 NOT REGEXP 'xxx';
+	t46 := &ast.PatternRegexpExpr{
+		Expr:    e1,
+		Pattern: e2,
+		Not:     true,
+		Re:      nil,
+		Sexpr:   nil,
+	}
+
+	t46Want := NewComparisonExpr(NOT_REG_MATCH, f1, f2)
+
+	t47subq, t47want_subq := gen_transform_t1()
+
+	//SubqueryExpr SELECT t.a FROM sa.t,u
+	t47 := &ast.SubqueryExpr{
+		Query:      t47subq,
+		Evaluated:  false,
+		Correlated: false,
+		MultiRows:  false,
+		Exists:     false,
+	}
+
+	t47Want := NewSubquery(t47want_subq.Select, false)
+
+	//ExistsSubqueryExpr
+	t48 := &ast.ExistsSubqueryExpr{
+		Sel: e1,
+		Not: true,
+	}
+
+	//just for passing the case
+	var _ SelectStatement = f1
+	t48Want := NewSubquery(f1, true)
+
+	//CompareSubqueryExpr
+	t49 := &ast.CompareSubqueryExpr{
+		L:   e1,
+		Op:  opcode.GT,
+		R:   e2,
+		All: true,
+	}
+
+	//just for passing the case
+	var _ SelectStatement = f2
+	t49Want := NewComparisonExprWithSubop(GREAT_THAN, ALL, f1, f2)
+
+	// '(' e1 ')'
+	t50 := &ast.ParenthesesExpr{Expr: e1}
+
+	t50Want := NewParenExpr(f1)
+
+	tests := []struct {
+		name string
+		args args
+		want Expr
+	}{
+		{"t1", args{t1}, NewNumVal(constant.MakeInt64(math.MaxInt64), "", false)},
+		{"t2", args{t2}, NewNumVal(constant.MakeInt64(math.MinInt64), "", false)},
+		{"t3", args{t3}, NewNumVal(constant.MakeUnknown(), "", false)},
+		{"t4", args{t4}, NewNumVal(constant.MakeUint64(math.MaxUint64/2), "", false)},
+		{"t5", args{t5}, NewNumVal(constant.MakeUint64(0), "", false)},
+		{"t6", args{t6}, NewNumVal(constant.MakeFloat64(math.MaxFloat32), "", false)},
+		{"t7", args{t7}, NewNumVal(constant.MakeFloat64(-math.MaxFloat32), "", false)},
+		{"t8", args{t8}, NewNumVal(constant.MakeFloat64(math.MaxFloat64), "", false)},
+		{"t9", args{t9}, NewNumVal(constant.MakeFloat64(-math.MaxFloat64), "", false)},
+		{"t10", args{t10}, NewNumVal(constant.MakeString(s), "", false)},
+		{"t11", args{t11}, t11Want},
+		{"t12", args{t12}, t12Want},
+		{"t13", args{t13}, t13Want},
+		{"t14", args{t14}, t14Want},
+		{"t15", args{t15}, t15Want},
+		{"t16", args{t16}, t16Want},
+		{"t17", args{t17}, t17Want},
+		{"t18", args{t18}, t18Want},
+		{"t19", args{eTrue}, fTrue},
+		{"t20", args{eFalse}, fFalse},
+		{"t21", args{t21}, t21Want},
+		{"t22", args{t22}, t22Want},
+		{"t23", args{t23}, t23Want},
+		{"t24", args{t24}, t24Want},
+		{"t25", args{t25}, t25Want},
+		{"t26", args{t26}, t26Want},
+		{"t27", args{t27}, t27Want},
+		{"t28", args{t28}, t28Want},
+		{"t29", args{t29}, t29Want},
+		{"t30", args{t30}, t30Want},
+		{"t31", args{t31}, t31Want},
+		{"t32", args{t32}, t32Want},
+		{"t33", args{t33}, t33Want},
+		{"t34", args{t34}, t34Want},
+		{"t35", args{t35}, t35Want},
+		{"t36", args{t36}, t36Want},
+		{"t37", args{t37}, t37Want},
+		{"t38", args{t38}, t38Want},
+		{"t39", args{t39}, t39Want},
+		{"t40", args{t40}, t40Want},
+		{"t41", args{t41}, t41Want},
+		{"t42", args{t42}, t42Want},
+		{"t43", args{t43}, t43Want},
+		{"t44", args{t44}, t44Want},
+		{"t45", args{t45}, t45Want},
+		{"t46", args{t46}, t46Want},
+		{"t47", args{t47}, t47Want},
+		{"t48", args{t48}, t48Want},
+		{"t49", args{t49}, t49Want},
+		{"t50", args{t50}, t50Want},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := transformExprNodeToExpr(tt.args.node); !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("transformExprNodeToExpr() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func Test_transformColumnNameListToNameList(t *testing.T) {
+	type args struct {
+		cn []*ast.ColumnName
+	}
+	l1 := []*ast.ColumnName{
+		&ast.ColumnName{
+			Schema: model.CIStr{},
+			Table:  model.CIStr{},
+			Name:   model.CIStr{"A", "a"},
+		},
+		&ast.ColumnName{
+			Schema: model.CIStr{},
+			Table:  model.CIStr{},
+			Name:   model.CIStr{"B", "b"},
+		},
+		&ast.ColumnName{
+			Schema: model.CIStr{},
+			Table:  model.CIStr{},
+			Name:   model.CIStr{"C", "c"},
+		},
+	}
+
+	l1Want := IdentifierList{
+		"A",
+		"B",
+		"C",
+	}
+	tests := []struct {
+		name string
+		args args
+		want IdentifierList
+	}{
+		{"t1", args{l1}, l1Want},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := transformColumnNameListToNameList(tt.args.cn); !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("transformColumnNameListToNameList() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func gen_transform_t1() (*ast.SelectStmt, *Select) {
+	//SELECT t.a FROM sa.t ;
+	//SELECT t.a FROM sa.t,u ;
+	t1TableName := &ast.TableName{
+		Schema:         model.CIStr{"sa", "sa"},
+		Name:           model.CIStr{"t", "t"},
+		DBInfo:         nil,
+		TableInfo:      nil,
+		IndexHints:     nil,
+		PartitionNames: nil,
+		TableSample:    nil,
+	}
+
+	t1TableSource := &ast.TableSource{
+		Source: t1TableName,
+		AsName: model.CIStr{},
+	}
+
+	t1TableName2 := &ast.TableName{
+		Schema:         model.CIStr{},
+		Name:           model.CIStr{"u", "u"},
+		DBInfo:         nil,
+		TableInfo:      nil,
+		IndexHints:     nil,
+		PartitionNames: nil,
+		TableSample:    nil,
+	}
+
+	t1TableSource2 := &ast.TableSource{
+		Source: t1TableName2,
+		AsName: model.CIStr{},
+	}
+
+	t1Join := &ast.Join{
+		Left:           t1TableSource,
+		Right:          t1TableSource2,
+		Tp:             ast.CrossJoin,
+		On:             nil,
+		Using:          nil,
+		NaturalJoin:    false,
+		StraightJoin:   false,
+		ExplicitParens: false,
+	}
+	t1TableRef := &ast.TableRefsClause{TableRefs: t1Join}
+
+	t1ColumnName := &ast.ColumnName{
+		Schema: model.CIStr{},
+		Table:  model.CIStr{"t", "t"},
+		Name:   model.CIStr{"a", "a"},
+	}
+	t1ColumnNameExpr := &ast.ColumnNameExpr{
+		Name:  t1ColumnName,
+		Refer: nil,
+	}
+	t1SelectField := []*ast.SelectField{
+		&ast.SelectField{
+			Offset:    0,
+			WildCard:  nil,
+			Expr:      t1ColumnNameExpr,
+			AsName:    model.CIStr{},
+			Auxiliary: false,
+		},
+	}
+
+	t1FieldList := &ast.FieldList{Fields: t1SelectField}
+
+	t1 := &ast.SelectStmt{
+		SelectStmtOpts:   nil,
+		Distinct:         false,
+		From:             t1TableRef,
+		Where:            nil,
+		Fields:           t1FieldList,
+		GroupBy:          nil,
+		Having:           nil,
+		WindowSpecs:      nil,
+		OrderBy:          nil,
+		Limit:            nil,
+		LockInfo:         nil,
+		TableHints:       nil,
+		IsInBraces:       false,
+		QueryBlockOffset: 0,
+		SelectIntoOpt:    nil,
+		AfterSetOperator: nil,
+		Kind:             0,
+		Lists:            nil,
+	}
+
+	t1wantTableName := &TableName{
+		objName: objName{
+			ObjectName: "t",
+			ObjectNamePrefix: ObjectNamePrefix{
+				CatalogName:     "",
+				SchemaName:      "sa",
+				ExplicitCatalog: false,
+				ExplicitSchema:  true,
+			},
+		},
+	}
+
+	t1wantAliasedTableExpr := &AliasedTableExpr{
+		Expr: t1wantTableName,
+		As:   AliasClause{},
+	}
+
+	t1wantTableName2 := &TableName{
+		objName: objName{
+			ObjectName: "u",
+			ObjectNamePrefix: ObjectNamePrefix{
+				CatalogName:     "",
+				SchemaName:      "",
+				ExplicitCatalog: false,
+				ExplicitSchema:  false,
+			},
+		},
+	}
+
+	t1wantAliasedTableExpr2 := &AliasedTableExpr{
+		Expr: t1wantTableName2,
+		As:   AliasClause{},
+	}
+
+	t1wantTableExprArray := []TableExpr{
+		&JoinTableExpr{
+			JoinType: JOIN_TYPE_CROSS,
+			Left:     t1wantAliasedTableExpr,
+			Right:    t1wantAliasedTableExpr2,
+			Cond:     nil,
+		},
+	}
+	t1wantFrom := &From{Tables: t1wantTableExprArray}
+
+	t1wantFied, _ := NewUnresolvedName("", "t", "a")
+
+	t1wantFieldList := []SelectExpr{
+		{
+			Expr: t1wantFied,
+			As:   "",
+		},
+	}
+
+	t1wantSelectClause := &SelectClause{
+		From:     t1wantFrom,
+		Distinct: false,
+		Where:    nil,
+		Exprs:    t1wantFieldList,
+		GroupBy:  nil,
+		Having:   nil,
+	}
+
+	t1want := &Select{
+		Select:  t1wantSelectClause,
+		OrderBy: nil,
+		Limit:   nil,
+	}
+	return t1, t1want
+}
+
+func gen_transform_t2() (*ast.SelectStmt, *Select) {
+	//SELECT t.a FROM sa.t,u,v
+	t1TableName := &ast.TableName{
+		Schema:         model.CIStr{"sa", "sa"},
+		Name:           model.CIStr{"t", "t"},
+		DBInfo:         nil,
+		TableInfo:      nil,
+		IndexHints:     nil,
+		PartitionNames: nil,
+		TableSample:    nil,
+	}
+
+	t1TableSource := &ast.TableSource{
+		Source: t1TableName,
+		AsName: model.CIStr{},
+	}
+
+	t1TableName2 := &ast.TableName{
+		Schema:         model.CIStr{},
+		Name:           model.CIStr{"u", "u"},
+		DBInfo:         nil,
+		TableInfo:      nil,
+		IndexHints:     nil,
+		PartitionNames: nil,
+		TableSample:    nil,
+	}
+
+	t1TableSource2 := &ast.TableSource{
+		Source: t1TableName2,
+		AsName: model.CIStr{},
+	}
+
+	t1TableName3 := &ast.TableName{
+		Schema:         model.CIStr{},
+		Name:           model.CIStr{"v", "v"},
+		DBInfo:         nil,
+		TableInfo:      nil,
+		IndexHints:     nil,
+		PartitionNames: nil,
+		TableSample:    nil,
+	}
+
+	t1TableSource3 := &ast.TableSource{
+		Source: t1TableName3,
+		AsName: model.CIStr{},
+	}
+
+	t1Join := &ast.Join{
+		Left:           t1TableSource,
+		Right:          t1TableSource2,
+		Tp:             ast.CrossJoin,
+		On:             nil,
+		Using:          nil,
+		NaturalJoin:    false,
+		StraightJoin:   false,
+		ExplicitParens: false,
+	}
+
+	t1Join2 := &ast.Join{
+		Left:           t1Join,
+		Right:          t1TableSource3,
+		Tp:             ast.CrossJoin,
+		On:             nil,
+		Using:          nil,
+		NaturalJoin:    false,
+		StraightJoin:   false,
+		ExplicitParens: false,
+	}
+
+	t1TableRef := &ast.TableRefsClause{TableRefs: t1Join2}
+
+	t1ColumnName := &ast.ColumnName{
+		Schema: model.CIStr{},
+		Table:  model.CIStr{"t", "t"},
+		Name:   model.CIStr{"a", "a"},
+	}
+	t1ColumnNameExpr := &ast.ColumnNameExpr{
+		Name:  t1ColumnName,
+		Refer: nil,
+	}
+	t1SelectField := []*ast.SelectField{
+		&ast.SelectField{
+			Offset:    0,
+			WildCard:  nil,
+			Expr:      t1ColumnNameExpr,
+			AsName:    model.CIStr{},
+			Auxiliary: false,
+		},
+	}
+
+	t1FieldList := &ast.FieldList{Fields: t1SelectField}
+
+	t1 := &ast.SelectStmt{
+		SelectStmtOpts:   nil,
+		Distinct:         false,
+		From:             t1TableRef,
+		Where:            nil,
+		Fields:           t1FieldList,
+		GroupBy:          nil,
+		Having:           nil,
+		WindowSpecs:      nil,
+		OrderBy:          nil,
+		Limit:            nil,
+		LockInfo:         nil,
+		TableHints:       nil,
+		IsInBraces:       false,
+		QueryBlockOffset: 0,
+		SelectIntoOpt:    nil,
+		AfterSetOperator: nil,
+		Kind:             0,
+		Lists:            nil,
+	}
+
+	t1wantTableName := &TableName{
+		objName: objName{
+			ObjectName: "t",
+			ObjectNamePrefix: ObjectNamePrefix{
+				CatalogName:     "",
+				SchemaName:      "sa",
+				ExplicitCatalog: false,
+				ExplicitSchema:  true,
+			},
+		},
+	}
+
+	t1wantAliasedTableExpr := &AliasedTableExpr{
+		Expr: t1wantTableName,
+		As:   AliasClause{},
+	}
+
+	t1wantTableName2 := &TableName{
+		objName: objName{
+			ObjectName: "u",
+			ObjectNamePrefix: ObjectNamePrefix{
+				CatalogName:     "",
+				SchemaName:      "",
+				ExplicitCatalog: false,
+				ExplicitSchema:  false,
+			},
+		},
+	}
+
+	t1wantAliasedTableExpr2 := &AliasedTableExpr{
+		Expr: t1wantTableName2,
+		As:   AliasClause{},
+	}
+
+	t1wantTableName3 := &TableName{
+		objName: objName{
+			ObjectName: "v",
+			ObjectNamePrefix: ObjectNamePrefix{
+				CatalogName:     "",
+				SchemaName:      "",
+				ExplicitCatalog: false,
+				ExplicitSchema:  false,
+			},
+		},
+	}
+
+	t1wantAliasedTableExpr3 := &AliasedTableExpr{
+		Expr: t1wantTableName3,
+		As:   AliasClause{},
+	}
+
+	t1wantJoin_1_2 := &JoinTableExpr{
+		JoinType: JOIN_TYPE_CROSS,
+		Left:     t1wantAliasedTableExpr,
+		Right:    t1wantAliasedTableExpr2,
+		Cond:     nil,
+	}
+
+	t1wantJoin_1_2_Join_3 := &JoinTableExpr{
+		JoinType: JOIN_TYPE_CROSS,
+		Left:     t1wantJoin_1_2,
+		Right:    t1wantAliasedTableExpr3,
+		Cond:     nil,
+	}
+
+	t1wantTableExprArray := []TableExpr{
+		t1wantJoin_1_2_Join_3,
+	}
+
+	t1wantFrom := &From{Tables: t1wantTableExprArray}
+
+	t1wantFied, _ := NewUnresolvedName("", "t", "a")
+
+	t1wantFieldList := []SelectExpr{
+		{
+			Expr: t1wantFied,
+			As:   "",
+		},
+	}
+
+	t1wantSelectClause := &SelectClause{
+		From:     t1wantFrom,
+		Distinct: false,
+		Where:    nil,
+		Exprs:    t1wantFieldList,
+		GroupBy:  nil,
+		Having:   nil,
+	}
+
+	t1want := &Select{
+		Select:  t1wantSelectClause,
+		OrderBy: nil,
+		Limit:   nil,
+	}
+	return t1, t1want
+}
+
+func gen_transform_t3() (*ast.SelectStmt, *Select) {
+	//SELECT t.a,u.a FROM sa.t,u where t.a = u.a
+	t1TableName := &ast.TableName{
+		Schema:         model.CIStr{"sa", "sa"},
+		Name:           model.CIStr{"t", "t"},
+		DBInfo:         nil,
+		TableInfo:      nil,
+		IndexHints:     nil,
+		PartitionNames: nil,
+		TableSample:    nil,
+	}
+
+	t1TableSource := &ast.TableSource{
+		Source: t1TableName,
+		AsName: model.CIStr{},
+	}
+
+	t1TableName2 := &ast.TableName{
+		Schema:         model.CIStr{},
+		Name:           model.CIStr{"u", "u"},
+		DBInfo:         nil,
+		TableInfo:      nil,
+		IndexHints:     nil,
+		PartitionNames: nil,
+		TableSample:    nil,
+	}
+
+	t1TableSource2 := &ast.TableSource{
+		Source: t1TableName2,
+		AsName: model.CIStr{},
+	}
+
+	t1Join := &ast.Join{
+		Left:           t1TableSource,
+		Right:          t1TableSource2,
+		Tp:             ast.CrossJoin,
+		On:             nil,
+		Using:          nil,
+		NaturalJoin:    false,
+		StraightJoin:   false,
+		ExplicitParens: false,
+	}
+	t1TableRef := &ast.TableRefsClause{TableRefs: t1Join}
+
+	t1ColumnName := &ast.ColumnName{
+		Schema: model.CIStr{},
+		Table:  model.CIStr{"t", "t"},
+		Name:   model.CIStr{"a", "a"},
+	}
+	t1ColumnNameExpr := &ast.ColumnNameExpr{
+		Name:  t1ColumnName,
+		Refer: nil,
+	}
+
+	t1ColumnName2 := &ast.ColumnName{
+		Schema: model.CIStr{},
+		Table:  model.CIStr{"u", "u"},
+		Name:   model.CIStr{"a", "a"},
+	}
+	t1ColumnNameExpr2 := &ast.ColumnNameExpr{
+		Name:  t1ColumnName2,
+		Refer: nil,
+	}
+
+	t1SelectField := []*ast.SelectField{
+		&ast.SelectField{
+			Offset:    0,
+			WildCard:  nil,
+			Expr:      t1ColumnNameExpr,
+			AsName:    model.CIStr{},
+			Auxiliary: false,
+		},
+		&ast.SelectField{
+			Offset:    0,
+			WildCard:  nil,
+			Expr:      t1ColumnNameExpr2,
+			AsName:    model.CIStr{},
+			Auxiliary: false,
+		},
+	}
+
+	t1FieldList := &ast.FieldList{Fields: t1SelectField}
+
+	t1ColumnName3 := &ast.ColumnName{
+		Schema: model.CIStr{},
+		Table:  model.CIStr{"t", "t"},
+		Name:   model.CIStr{"a", "a"},
+	}
+	t1Where1 := &ast.ColumnNameExpr{
+		Name:  t1ColumnName3,
+		Refer: nil,
+	}
+
+	t1ColumnName4 := &ast.ColumnName{
+		Schema: model.CIStr{},
+		Table:  model.CIStr{"u", "u"},
+		Name:   model.CIStr{"a", "a"},
+	}
+	t1Where2 := &ast.ColumnNameExpr{
+		Name:  t1ColumnName4,
+		Refer: nil,
+	}
+
+	t1Where := &ast.BinaryOperationExpr{
+		Op: opcode.EQ,
+		L:  t1Where1,
+		R:  t1Where2,
+	}
+	t1 := &ast.SelectStmt{
+		SelectStmtOpts:   nil,
+		Distinct:         false,
+		From:             t1TableRef,
+		Where:            t1Where,
+		Fields:           t1FieldList,
+		GroupBy:          nil,
+		Having:           nil,
+		WindowSpecs:      nil,
+		OrderBy:          nil,
+		Limit:            nil,
+		LockInfo:         nil,
+		TableHints:       nil,
+		IsInBraces:       false,
+		QueryBlockOffset: 0,
+		SelectIntoOpt:    nil,
+		AfterSetOperator: nil,
+		Kind:             0,
+		Lists:            nil,
+	}
+
+	t1wantTableName := &TableName{
+		objName: objName{
+			ObjectName: "t",
+			ObjectNamePrefix: ObjectNamePrefix{
+				CatalogName:     "",
+				SchemaName:      "sa",
+				ExplicitCatalog: false,
+				ExplicitSchema:  true,
+			},
+		},
+	}
+
+	t1wantAliasedTableExpr := &AliasedTableExpr{
+		Expr: t1wantTableName,
+		As:   AliasClause{},
+	}
+
+	t1wantTableName2 := &TableName{
+		objName: objName{
+			ObjectName: "u",
+			ObjectNamePrefix: ObjectNamePrefix{
+				CatalogName:     "",
+				SchemaName:      "",
+				ExplicitCatalog: false,
+				ExplicitSchema:  false,
+			},
+		},
+	}
+
+	t1wantAliasedTableExpr2 := &AliasedTableExpr{
+		Expr: t1wantTableName2,
+		As:   AliasClause{},
+	}
+
+	t1wantTableExprArray := []TableExpr{
+		&JoinTableExpr{
+			JoinType: JOIN_TYPE_CROSS,
+			Left:     t1wantAliasedTableExpr,
+			Right:    t1wantAliasedTableExpr2,
+			Cond:     nil,
+		},
+	}
+	t1wantFrom := &From{Tables: t1wantTableExprArray}
+
+	t1wantField1, _ := NewUnresolvedName("", "t", "a")
+	t1wantField2, _ := NewUnresolvedName("", "u", "a")
+
+	t1wantWhere1, _ := NewUnresolvedName("", "t", "a")
+	t1wantWhere2, _ := NewUnresolvedName("", "u", "a")
+
+	t1wantWhereExpr := &ComparisonExpr{
+		Op:    EQUAL,
+		SubOp: 0,
+		Left:  t1wantWhere1,
+		Right: t1wantWhere2,
+	}
+
+	t1wantFieldList := []SelectExpr{
+		{
+			Expr: t1wantField1,
+			As:   "",
+		},
+		{
+			Expr: t1wantField2,
+			As:   "",
+		},
+	}
+
+	t1wantSelectClause := &SelectClause{
+		From:     t1wantFrom,
+		Distinct: false,
+		Where:    NewWhere(t1wantWhereExpr),
+		Exprs:    t1wantFieldList,
+		GroupBy:  nil,
+		Having:   nil,
+	}
+
+	t1want := &Select{
+		Select:  t1wantSelectClause,
+		OrderBy: nil,
+		Limit:   nil,
+	}
+	return t1, t1want
+}
+
+func gen_var_ref(schema, table, name string) *ast.ColumnNameExpr {
+	var_name := &ast.ColumnName{
+		Schema: model.CIStr{schema, schema},
+		Table:  model.CIStr{table, table},
+		Name:   model.CIStr{name, name},
+	}
+	var_ := &ast.ColumnNameExpr{
+		Name:  var_name,
+		Refer: nil,
+	}
+	return var_
+}
+
+func gen_binary_expr(op opcode.Op, l, r ast.ExprNode) *ast.BinaryOperationExpr {
+	return &ast.BinaryOperationExpr{
+		Op: op,
+		L:  l,
+		R:  r,
+	}
+}
+
+func gen_table(sch, name string) *ast.TableSource {
+	sa_t_name := &ast.TableName{
+		Schema:         model.CIStr{sch, sch},
+		Name:           model.CIStr{name, name},
+		DBInfo:         nil,
+		TableInfo:      nil,
+		IndexHints:     nil,
+		PartitionNames: nil,
+		TableSample:    nil,
+	}
+
+	sa_t := &ast.TableSource{
+		Source: sa_t_name,
+		AsName: model.CIStr{},
+	}
+	return sa_t
+}
+
+func gen_want_table(sch, name string) *AliasedTableExpr {
+	want_sa_t_name := NewTableName(Identifier(name), ObjectNamePrefix{
+		CatalogName:     "",
+		SchemaName:      Identifier(sch),
+		ExplicitCatalog: false,
+		ExplicitSchema:  len(sch) != 0,
+	})
+
+	want_sa_t := &AliasedTableExpr{
+		Expr: want_sa_t_name,
+		As:   AliasClause{},
+	}
+	return want_sa_t
+}
+
+func gen_transform_t4() (*ast.SelectStmt, *Select) {
+	//SELECT t.a,u.a,t.b * u.b FROM sa.t,u where t.a = u.a and t.b > u.b
+	sa_t := gen_table("sa", "t")
+
+	u := gen_table("", "u")
+
+	sa_t_cross_u := &ast.Join{
+		Left:           sa_t,
+		Right:          u,
+		Tp:             ast.CrossJoin,
+		On:             nil,
+		Using:          nil,
+		NaturalJoin:    false,
+		StraightJoin:   false,
+		ExplicitParens: false,
+	}
+	t1TableRef := &ast.TableRefsClause{TableRefs: sa_t_cross_u}
+
+	t_a := gen_var_ref("", "t", "a")
+	t_b := gen_var_ref("", "t", "b")
+
+	u_a := gen_var_ref("", "u", "a")
+	u_b := gen_var_ref("", "u", "b")
+
+	t_b_multi_u_b := gen_binary_expr(opcode.Mul, t_b, u_b)
+	select_fields := []*ast.SelectField{
+		&ast.SelectField{
+			Offset:    0,
+			WildCard:  nil,
+			Expr:      t_a,
+			AsName:    model.CIStr{},
+			Auxiliary: false,
+		},
+		&ast.SelectField{
+			Offset:    0,
+			WildCard:  nil,
+			Expr:      u_a,
+			AsName:    model.CIStr{},
+			Auxiliary: false,
+		},
+		&ast.SelectField{
+			Offset:    0,
+			WildCard:  nil,
+			Expr:      t_b_multi_u_b,
+			AsName:    model.CIStr{},
+			Auxiliary: false,
+		},
+	}
+
+	t1FieldList := &ast.FieldList{Fields: select_fields}
+
+	//t.a = u.a
+	t_a_eq_u_a := gen_binary_expr(opcode.EQ, t_a, u_a)
+
+	//t.b > u.b
+	t_b_gt_u_b := gen_binary_expr(opcode.GT, t_b, u_b)
+
+	//t.a = u.a and t.b > u.b
+	t_a_eq_u_a_and_t_b_gt_u_b := gen_binary_expr(opcode.LogicAnd, t_a_eq_u_a, t_b_gt_u_b)
+
+	t1 := &ast.SelectStmt{
+		SelectStmtOpts:   nil,
+		Distinct:         false,
+		From:             t1TableRef,
+		Where:            t_a_eq_u_a_and_t_b_gt_u_b,
+		Fields:           t1FieldList,
+		GroupBy:          nil,
+		Having:           nil,
+		WindowSpecs:      nil,
+		OrderBy:          nil,
+		Limit:            nil,
+		LockInfo:         nil,
+		TableHints:       nil,
+		IsInBraces:       false,
+		QueryBlockOffset: 0,
+		SelectIntoOpt:    nil,
+		AfterSetOperator: nil,
+		Kind:             0,
+		Lists:            nil,
+	}
+
+	want_sa_t := gen_want_table("sa", "t")
+
+	want_u := gen_want_table("", "u")
+
+	want_table_refs := []TableExpr{
+		&JoinTableExpr{
+			JoinType: JOIN_TYPE_CROSS,
+			Left:     want_sa_t,
+			Right:    want_u,
+			Cond:     nil,
+		},
+	}
+	t1wantFrom := &From{Tables: want_table_refs}
+
+	want_t_a, _ := NewUnresolvedName("", "t", "a")
+	want_t_b, _ := NewUnresolvedName("", "t", "b")
+
+	want_u_a, _ := NewUnresolvedName("", "u", "a")
+	want_u_b, _ := NewUnresolvedName("", "u", "b")
+
+	//t.b * u.b
+	want_t_b_multi_u_b := NewBinaryExpr(MULTI, want_t_b, want_u_b)
+
+	//t.a = u.a
+	want_t_a_eq_u_a := NewComparisonExpr(EQUAL, want_t_a, want_u_a)
+
+	//t.b > u.b
+	want_t_b_gt_u_b := NewComparisonExpr(GREAT_THAN, want_t_b, want_u_b)
+
+	//t.a = u.a and t.b > u.b
+	want_t_a_eq_u_a_logicand_t_b_gt_u_b := NewAndExpr(want_t_a_eq_u_a, want_t_b_gt_u_b)
+
+	t1wantFieldList := []SelectExpr{
+		{
+			Expr: want_t_a,
+			As:   "",
+		},
+		{
+			Expr: want_u_a,
+			As:   "",
+		},
+		{
+			Expr: want_t_b_multi_u_b,
+			As:   "",
+		},
+	}
+
+	t1wantSelectClause := &SelectClause{
+		From:     t1wantFrom,
+		Distinct: false,
+		Where:    NewWhere(want_t_a_eq_u_a_logicand_t_b_gt_u_b),
+		Exprs:    t1wantFieldList,
+		GroupBy:  nil,
+		Having:   nil,
+	}
+
+	t1want := &Select{
+		Select:  t1wantSelectClause,
+		OrderBy: nil,
+		Limit:   nil,
+	}
+	return t1, t1want
+}
+
+func gen_transform_t5() (*ast.SelectStmt, *Select) {
+	//SELECT t.a,u.a,t.b * u.b FROM sa.t join u on t.c = u.c or t.d != u.d where t.a = u.a and t.b > u.b
+	t_a := gen_var_ref("", "t", "a")
+	t_b := gen_var_ref("", "t", "b")
+	t_c := gen_var_ref("", "t", "c")
+	t_d := gen_var_ref("", "t", "d")
+
+	u_a := gen_var_ref("", "u", "a")
+	u_b := gen_var_ref("", "u", "b")
+	u_c := gen_var_ref("", "u", "c")
+	u_d := gen_var_ref("", "u", "d")
+
+	sa_t := gen_table("sa", "t")
+
+	u := gen_table("", "u")
+
+	t_c_eq_u_c := gen_binary_expr(opcode.EQ, t_c, u_c)
+	t_d_ne_u_d := gen_binary_expr(opcode.NE, t_d, u_d)
+	t_c_eq_u_c_or_t_d_ne_u_d := gen_binary_expr(opcode.LogicOr, t_c_eq_u_c, t_d_ne_u_d)
+
+	onCond := &ast.OnCondition{Expr: t_c_eq_u_c_or_t_d_ne_u_d}
+
+	sa_t_cross_u := &ast.Join{
+		Left:           sa_t,
+		Right:          u,
+		Tp:             ast.CrossJoin,
+		On:             onCond,
+		Using:          nil,
+		NaturalJoin:    false,
+		StraightJoin:   false,
+		ExplicitParens: false,
+	}
+	t1TableRef := &ast.TableRefsClause{TableRefs: sa_t_cross_u}
+
+	t_b_multi_u_b := gen_binary_expr(opcode.Mul, t_b, u_b)
+	select_fields := []*ast.SelectField{
+		&ast.SelectField{
+			Offset:    0,
+			WildCard:  nil,
+			Expr:      t_a,
+			AsName:    model.CIStr{},
+			Auxiliary: false,
+		},
+		&ast.SelectField{
+			Offset:    0,
+			WildCard:  nil,
+			Expr:      u_a,
+			AsName:    model.CIStr{},
+			Auxiliary: false,
+		},
+		&ast.SelectField{
+			Offset:    0,
+			WildCard:  nil,
+			Expr:      t_b_multi_u_b,
+			AsName:    model.CIStr{},
+			Auxiliary: false,
+		},
+	}
+
+	t1FieldList := &ast.FieldList{Fields: select_fields}
+
+	//t.a = u.a
+	t_a_eq_u_a := gen_binary_expr(opcode.EQ, t_a, u_a)
+
+	//t.b > u.b
+	t_b_gt_u_b := gen_binary_expr(opcode.GT, t_b, u_b)
+
+	//t.a = u.a and t.b > u.b
+	t_a_eq_u_a_and_t_b_gt_u_b := gen_binary_expr(opcode.LogicAnd, t_a_eq_u_a, t_b_gt_u_b)
+
+	t1 := &ast.SelectStmt{
+		SelectStmtOpts:   nil,
+		Distinct:         false,
+		From:             t1TableRef,
+		Where:            t_a_eq_u_a_and_t_b_gt_u_b,
+		Fields:           t1FieldList,
+		GroupBy:          nil,
+		Having:           nil,
+		WindowSpecs:      nil,
+		OrderBy:          nil,
+		Limit:            nil,
+		LockInfo:         nil,
+		TableHints:       nil,
+		IsInBraces:       false,
+		QueryBlockOffset: 0,
+		SelectIntoOpt:    nil,
+		AfterSetOperator: nil,
+		Kind:             0,
+		Lists:            nil,
+	}
+
+	//=========
+
+	want_t_a, _ := NewUnresolvedName("", "t", "a")
+	want_t_b, _ := NewUnresolvedName("", "t", "b")
+	want_t_c, _ := NewUnresolvedName("", "t", "c")
+	want_t_d, _ := NewUnresolvedName("", "t", "d")
+
+	want_u_a, _ := NewUnresolvedName("", "u", "a")
+	want_u_b, _ := NewUnresolvedName("", "u", "b")
+	want_u_c, _ := NewUnresolvedName("", "u", "c")
+	want_u_d, _ := NewUnresolvedName("", "u", "d")
+
+	//t.c = u.c or t.d != u.d
+	want_t_c_eq_u_c := NewComparisonExpr(EQUAL, want_t_c, want_u_c)
+	want_t_d_ne_u_d := NewComparisonExpr(NOT_EQUAL, want_t_d, want_u_d)
+	want_t_c_eq_u_c_or_t_d_ne_u_d := NewOrExpr(want_t_c_eq_u_c, want_t_d_ne_u_d)
+
+	want_join_on := NewOnJoinCond(want_t_c_eq_u_c_or_t_d_ne_u_d)
+
+	want_sa_t := gen_want_table("sa", "t")
+
+	want_u := gen_want_table("", "u")
+
+	want_table_refs := []TableExpr{
+		&JoinTableExpr{
+			JoinType: JOIN_TYPE_CROSS,
+			Left:     want_sa_t,
+			Right:    want_u,
+			Cond:     want_join_on,
+		},
+	}
+	t1wantFrom := &From{Tables: want_table_refs}
+
+	//t.b * u.b
+	want_t_b_multi_u_b := NewBinaryExpr(MULTI, want_t_b, want_u_b)
+
+	//t.a = u.a
+	want_t_a_eq_u_a := NewComparisonExpr(EQUAL, want_t_a, want_u_a)
+
+	//t.b > u.b
+	want_t_b_gt_u_b := NewComparisonExpr(GREAT_THAN, want_t_b, want_u_b)
+
+	//t.a = u.a and t.b > u.b
+	want_t_a_eq_u_a_logicand_t_b_gt_u_b := NewAndExpr(want_t_a_eq_u_a, want_t_b_gt_u_b)
+
+	t1wantFieldList := []SelectExpr{
+		{
+			Expr: want_t_a,
+			As:   "",
+		},
+		{
+			Expr: want_u_a,
+			As:   "",
+		},
+		{
+			Expr: want_t_b_multi_u_b,
+			As:   "",
+		},
+	}
+
+	t1wantSelectClause := &SelectClause{
+		From:     t1wantFrom,
+		Distinct: false,
+		Where:    NewWhere(want_t_a_eq_u_a_logicand_t_b_gt_u_b),
+		Exprs:    t1wantFieldList,
+		GroupBy:  nil,
+		Having:   nil,
+	}
+
+	t1want := &Select{
+		Select:  t1wantSelectClause,
+		OrderBy: nil,
+		Limit:   nil,
+	}
+	return t1, t1want
+}
+
+func gen_transform_t6() (*ast.SelectStmt, *Select) {
+	/*
+		SELECT t.a,u.a,t.b * u.b
+					FROM sa.t join u on t.c = u.c or t.d != u.d
+							  join v on u.a != v.a
+					where t.a = u.a and t.b > u.b
+	*/
+	t_a := gen_var_ref("", "t", "a")
+	t_b := gen_var_ref("", "t", "b")
+	t_c := gen_var_ref("", "t", "c")
+	t_d := gen_var_ref("", "t", "d")
+
+	u_a := gen_var_ref("", "u", "a")
+	u_b := gen_var_ref("", "u", "b")
+	u_c := gen_var_ref("", "u", "c")
+	u_d := gen_var_ref("", "u", "d")
+
+	v_a := gen_var_ref("", "v", "a")
+	//v_b := gen_var_ref("","v","b")
+	//v_c := gen_var_ref("","v","c")
+	//v_d := gen_var_ref("","v","d")
+
+	sa_t := gen_table("sa", "t")
+
+	u := gen_table("", "u")
+
+	v := gen_table("", "v")
+
+	t_c_eq_u_c := gen_binary_expr(opcode.EQ, t_c, u_c)
+	t_d_ne_u_d := gen_binary_expr(opcode.NE, t_d, u_d)
+	t_c_eq_u_c_or_t_d_ne_u_d := gen_binary_expr(opcode.LogicOr, t_c_eq_u_c, t_d_ne_u_d)
+
+	t_u_onCond := &ast.OnCondition{Expr: t_c_eq_u_c_or_t_d_ne_u_d}
+
+	sa_t_cross_u := &ast.Join{
+		Left:           sa_t,
+		Right:          u,
+		Tp:             ast.CrossJoin,
+		On:             t_u_onCond,
+		Using:          nil,
+		NaturalJoin:    false,
+		StraightJoin:   false,
+		ExplicitParens: false,
+	}
+
+	//u.a != v.a
+	u_a_ne_v_a := gen_binary_expr(opcode.NE, u_a, v_a)
+
+	u_v_onCond := &ast.OnCondition{Expr: u_a_ne_v_a}
+
+	sa_t_cross_u_cross_v := &ast.Join{
+		Left:           sa_t_cross_u,
+		Right:          v,
+		Tp:             ast.CrossJoin,
+		On:             u_v_onCond,
+		Using:          nil,
+		NaturalJoin:    false,
+		StraightJoin:   false,
+		ExplicitParens: false,
+	}
+
+	t1TableRef := &ast.TableRefsClause{TableRefs: sa_t_cross_u_cross_v}
+
+	t_b_multi_u_b := gen_binary_expr(opcode.Mul, t_b, u_b)
+	select_fields := []*ast.SelectField{
+		&ast.SelectField{
+			Offset:    0,
+			WildCard:  nil,
+			Expr:      t_a,
+			AsName:    model.CIStr{},
+			Auxiliary: false,
+		},
+		&ast.SelectField{
+			Offset:    0,
+			WildCard:  nil,
+			Expr:      u_a,
+			AsName:    model.CIStr{},
+			Auxiliary: false,
+		},
+		&ast.SelectField{
+			Offset:    0,
+			WildCard:  nil,
+			Expr:      t_b_multi_u_b,
+			AsName:    model.CIStr{},
+			Auxiliary: false,
+		},
+	}
+
+	t1FieldList := &ast.FieldList{Fields: select_fields}
+
+	//t.a = u.a
+	t_a_eq_u_a := gen_binary_expr(opcode.EQ, t_a, u_a)
+
+	//t.b > u.b
+	t_b_gt_u_b := gen_binary_expr(opcode.GT, t_b, u_b)
+
+	//t.a = u.a and t.b > u.b
+	t_a_eq_u_a_and_t_b_gt_u_b := gen_binary_expr(opcode.LogicAnd, t_a_eq_u_a, t_b_gt_u_b)
+
+	t1 := &ast.SelectStmt{
+		SelectStmtOpts:   nil,
+		Distinct:         false,
+		From:             t1TableRef,
+		Where:            t_a_eq_u_a_and_t_b_gt_u_b,
+		Fields:           t1FieldList,
+		GroupBy:          nil,
+		Having:           nil,
+		WindowSpecs:      nil,
+		OrderBy:          nil,
+		Limit:            nil,
+		LockInfo:         nil,
+		TableHints:       nil,
+		IsInBraces:       false,
+		QueryBlockOffset: 0,
+		SelectIntoOpt:    nil,
+		AfterSetOperator: nil,
+		Kind:             0,
+		Lists:            nil,
+	}
+
+	//=========
+
+	want_t_a, _ := NewUnresolvedName("", "t", "a")
+	want_t_b, _ := NewUnresolvedName("", "t", "b")
+	want_t_c, _ := NewUnresolvedName("", "t", "c")
+	want_t_d, _ := NewUnresolvedName("", "t", "d")
+
+	want_u_a, _ := NewUnresolvedName("", "u", "a")
+	want_u_b, _ := NewUnresolvedName("", "u", "b")
+	want_u_c, _ := NewUnresolvedName("", "u", "c")
+	want_u_d, _ := NewUnresolvedName("", "u", "d")
+
+	want_v_a, _ := NewUnresolvedName("", "v", "a")
+
+	//t.c = u.c or t.d != u.d
+	want_t_c_eq_u_c := NewComparisonExpr(EQUAL, want_t_c, want_u_c)
+	want_t_d_ne_u_d := NewComparisonExpr(NOT_EQUAL, want_t_d, want_u_d)
+	want_t_c_eq_u_c_or_t_d_ne_u_d := NewOrExpr(want_t_c_eq_u_c, want_t_d_ne_u_d)
+
+	want_join_on := NewOnJoinCond(want_t_c_eq_u_c_or_t_d_ne_u_d)
+
+	//u.a != v.a
+	want_u_a_ne_v_a := NewComparisonExpr(NOT_EQUAL, want_u_a, want_v_a)
+	want_u_v_join_on := NewOnJoinCond(want_u_a_ne_v_a)
+
+	want_sa_t := gen_want_table("sa", "t")
+
+	want_u := gen_want_table("", "u")
+
+	want_v := gen_want_table("", "v")
+
+	want_t_u_join := &JoinTableExpr{
+		JoinType: JOIN_TYPE_CROSS,
+		Left:     want_sa_t,
+		Right:    want_u,
+		Cond:     want_join_on,
+	}
+
+	want_u_v_join := &JoinTableExpr{
+		JoinType: JOIN_TYPE_CROSS,
+		Left:     want_t_u_join,
+		Right:    want_v,
+		Cond:     want_u_v_join_on,
+	}
+
+	want_table_refs := []TableExpr{
+		want_u_v_join,
+	}
+
+	t1wantFrom := &From{Tables: want_table_refs}
+
+	//t.b * u.b
+	want_t_b_multi_u_b := NewBinaryExpr(MULTI, want_t_b, want_u_b)
+
+	//t.a = u.a
+	want_t_a_eq_u_a := NewComparisonExpr(EQUAL, want_t_a, want_u_a)
+
+	//t.b > u.b
+	want_t_b_gt_u_b := NewComparisonExpr(GREAT_THAN, want_t_b, want_u_b)
+
+	//t.a = u.a and t.b > u.b
+	want_t_a_eq_u_a_logicand_t_b_gt_u_b := NewAndExpr(want_t_a_eq_u_a, want_t_b_gt_u_b)
+
+	t1wantFieldList := []SelectExpr{
+		{
+			Expr: want_t_a,
+			As:   "",
+		},
+		{
+			Expr: want_u_a,
+			As:   "",
+		},
+		{
+			Expr: want_t_b_multi_u_b,
+			As:   "",
+		},
+	}
+
+	t1wantSelectClause := &SelectClause{
+		From:     t1wantFrom,
+		Distinct: false,
+		Where:    NewWhere(want_t_a_eq_u_a_logicand_t_b_gt_u_b),
+		Exprs:    t1wantFieldList,
+		GroupBy:  nil,
+		Having:   nil,
+	}
+
+	t1want := &Select{
+		Select:  t1wantSelectClause,
+		OrderBy: nil,
+		Limit:   nil,
+	}
+	return t1, t1want
+}
+
+func gen_transform_t7() (*ast.SelectStmt, *Select) {
+	/*
+		SELECT t.a,u.a,t.b * u.b
+		FROM sa.t join u on t.c = u.c or t.d != u.d
+				  join v on u.a != v.a
+		where t.a = u.a and t.b > u.b
+		group by t.a,u.a,(t.b+u.b+v.b)
+	*/
+	t_a := gen_var_ref("", "t", "a")
+	t_b := gen_var_ref("", "t", "b")
+	t_c := gen_var_ref("", "t", "c")
+	t_d := gen_var_ref("", "t", "d")
+
+	u_a := gen_var_ref("", "u", "a")
+	u_b := gen_var_ref("", "u", "b")
+	u_c := gen_var_ref("", "u", "c")
+	u_d := gen_var_ref("", "u", "d")
+
+	v_a := gen_var_ref("", "v", "a")
+	v_b := gen_var_ref("", "v", "b")
+	//v_c := gen_var_ref("","v","c")
+	//v_d := gen_var_ref("","v","d")
+
+	sa_t := gen_table("sa", "t")
+
+	u := gen_table("", "u")
+
+	v := gen_table("", "v")
+
+	t_c_eq_u_c := gen_binary_expr(opcode.EQ, t_c, u_c)
+	t_d_ne_u_d := gen_binary_expr(opcode.NE, t_d, u_d)
+	t_c_eq_u_c_or_t_d_ne_u_d := gen_binary_expr(opcode.LogicOr, t_c_eq_u_c, t_d_ne_u_d)
+
+	t_u_onCond := &ast.OnCondition{Expr: t_c_eq_u_c_or_t_d_ne_u_d}
+
+	sa_t_cross_u := &ast.Join{
+		Left:           sa_t,
+		Right:          u,
+		Tp:             ast.CrossJoin,
+		On:             t_u_onCond,
+		Using:          nil,
+		NaturalJoin:    false,
+		StraightJoin:   false,
+		ExplicitParens: false,
+	}
+
+	//u.a != v.a
+	u_a_ne_v_a := gen_binary_expr(opcode.NE, u_a, v_a)
+
+	u_v_onCond := &ast.OnCondition{Expr: u_a_ne_v_a}
+
+	sa_t_cross_u_cross_v := &ast.Join{
+		Left:           sa_t_cross_u,
+		Right:          v,
+		Tp:             ast.CrossJoin,
+		On:             u_v_onCond,
+		Using:          nil,
+		NaturalJoin:    false,
+		StraightJoin:   false,
+		ExplicitParens: false,
+	}
+
+	t1TableRef := &ast.TableRefsClause{TableRefs: sa_t_cross_u_cross_v}
+
+	t_b_multi_u_b := gen_binary_expr(opcode.Mul, t_b, u_b)
+	select_fields := []*ast.SelectField{
+		&ast.SelectField{
+			Offset:    0,
+			WildCard:  nil,
+			Expr:      t_a,
+			AsName:    model.CIStr{},
+			Auxiliary: false,
+		},
+		&ast.SelectField{
+			Offset:    0,
+			WildCard:  nil,
+			Expr:      u_a,
+			AsName:    model.CIStr{},
+			Auxiliary: false,
+		},
+		&ast.SelectField{
+			Offset:    0,
+			WildCard:  nil,
+			Expr:      t_b_multi_u_b,
+			AsName:    model.CIStr{},
+			Auxiliary: false,
+		},
+	}
+
+	t1FieldList := &ast.FieldList{Fields: select_fields}
+
+	//t.a = u.a
+	t_a_eq_u_a := gen_binary_expr(opcode.EQ, t_a, u_a)
+
+	//t.b > u.b
+	t_b_gt_u_b := gen_binary_expr(opcode.GT, t_b, u_b)
+
+	//t.a = u.a and t.b > u.b
+	t_a_eq_u_a_and_t_b_gt_u_b := gen_binary_expr(opcode.LogicAnd, t_a_eq_u_a, t_b_gt_u_b)
+
+	//group by t.a,u.a,(t.b+u.b+v.b)
+
+	byitem_t_a := &ast.ByItem{
+		Expr:      t_a,
+		Desc:      false,
+		NullOrder: true,
+	}
+
+	byitem_u_a := &ast.ByItem{
+		Expr:      u_a,
+		Desc:      false,
+		NullOrder: true,
+	}
+
+	t_b_plus_u_b_plus_v_b := gen_binary_expr(opcode.Plus, gen_binary_expr(opcode.Plus, t_b, u_b), v_b)
+
+	paren_t_b_plus_u_b_plus_v_b := &ast.ParenthesesExpr{Expr: t_b_plus_u_b_plus_v_b}
+
+	byitem_t_b_plus_u_b_plus_v_b := &ast.ByItem{
+		Expr:      paren_t_b_plus_u_b_plus_v_b,
+		Desc:      false,
+		NullOrder: true,
+	}
+
+	t_groupby_item := []*ast.ByItem{
+		byitem_t_a,
+		byitem_u_a,
+		byitem_t_b_plus_u_b_plus_v_b,
+	}
+
+	t_groupby := &ast.GroupByClause{Items: t_groupby_item}
+
+	t1 := &ast.SelectStmt{
+		SelectStmtOpts:   nil,
+		Distinct:         false,
+		From:             t1TableRef,
+		Where:            t_a_eq_u_a_and_t_b_gt_u_b,
+		Fields:           t1FieldList,
+		GroupBy:          t_groupby,
+		Having:           nil,
+		WindowSpecs:      nil,
+		OrderBy:          nil,
+		Limit:            nil,
+		LockInfo:         nil,
+		TableHints:       nil,
+		IsInBraces:       false,
+		QueryBlockOffset: 0,
+		SelectIntoOpt:    nil,
+		AfterSetOperator: nil,
+		Kind:             0,
+		Lists:            nil,
+	}
+
+	//=========
+
+	want_t_a, _ := NewUnresolvedName("", "t", "a")
+	want_t_b, _ := NewUnresolvedName("", "t", "b")
+	want_t_c, _ := NewUnresolvedName("", "t", "c")
+	want_t_d, _ := NewUnresolvedName("", "t", "d")
+
+	want_u_a, _ := NewUnresolvedName("", "u", "a")
+	want_u_b, _ := NewUnresolvedName("", "u", "b")
+	want_u_c, _ := NewUnresolvedName("", "u", "c")
+	want_u_d, _ := NewUnresolvedName("", "u", "d")
+
+	want_v_a, _ := NewUnresolvedName("", "v", "a")
+	want_v_b, _ := NewUnresolvedName("", "v", "b")
+
+	//t.c = u.c or t.d != u.d
+	want_t_c_eq_u_c := NewComparisonExpr(EQUAL, want_t_c, want_u_c)
+	want_t_d_ne_u_d := NewComparisonExpr(NOT_EQUAL, want_t_d, want_u_d)
+	want_t_c_eq_u_c_or_t_d_ne_u_d := NewOrExpr(want_t_c_eq_u_c, want_t_d_ne_u_d)
+
+	want_join_on := NewOnJoinCond(want_t_c_eq_u_c_or_t_d_ne_u_d)
+
+	//u.a != v.a
+	want_u_a_ne_v_a := NewComparisonExpr(NOT_EQUAL, want_u_a, want_v_a)
+	want_u_v_join_on := NewOnJoinCond(want_u_a_ne_v_a)
+
+	want_sa_t := gen_want_table("sa", "t")
+
+	want_u := gen_want_table("", "u")
+
+	want_v := gen_want_table("", "v")
+
+	want_t_u_join := &JoinTableExpr{
+		JoinType: JOIN_TYPE_CROSS,
+		Left:     want_sa_t,
+		Right:    want_u,
+		Cond:     want_join_on,
+	}
+
+	want_u_v_join := &JoinTableExpr{
+		JoinType: JOIN_TYPE_CROSS,
+		Left:     want_t_u_join,
+		Right:    want_v,
+		Cond:     want_u_v_join_on,
+	}
+
+	want_table_refs := []TableExpr{
+		want_u_v_join,
+	}
+
+	t1wantFrom := &From{Tables: want_table_refs}
+
+	//t.b * u.b
+	want_t_b_multi_u_b := NewBinaryExpr(MULTI, want_t_b, want_u_b)
+
+	//t.a = u.a
+	want_t_a_eq_u_a := NewComparisonExpr(EQUAL, want_t_a, want_u_a)
+
+	//t.b > u.b
+	want_t_b_gt_u_b := NewComparisonExpr(GREAT_THAN, want_t_b, want_u_b)
+
+	//t.a = u.a and t.b > u.b
+	want_t_a_eq_u_a_logicand_t_b_gt_u_b := NewAndExpr(want_t_a_eq_u_a, want_t_b_gt_u_b)
+
+	want_t_b_plus_u_b_plus_v_b := NewBinaryExpr(PLUS, NewBinaryExpr(PLUS, want_t_b, want_u_b), want_v_b)
+
+	want_paren_t_b_plus_u_b_plus_v_b := NewParenExpr(want_t_b_plus_u_b_plus_v_b)
+
+	//group by t.a,u.a,(t.b+u.b+v.b)
+	want_groupby := []Expr{
+		want_t_a,
+		want_u_a,
+		want_paren_t_b_plus_u_b_plus_v_b,
+	}
+
+	t1wantFieldList := []SelectExpr{
+		{
+			Expr: want_t_a,
+			As:   "",
+		},
+		{
+			Expr: want_u_a,
+			As:   "",
+		},
+		{
+			Expr: want_t_b_multi_u_b,
+			As:   "",
+		},
+	}
+
+	t1wantSelectClause := &SelectClause{
+		From:     t1wantFrom,
+		Distinct: false,
+		Where:    NewWhere(want_t_a_eq_u_a_logicand_t_b_gt_u_b),
+		Exprs:    t1wantFieldList,
+		GroupBy:  want_groupby,
+		Having:   nil,
+	}
+
+	t1want := &Select{
+		Select:  t1wantSelectClause,
+		OrderBy: nil,
+		Limit:   nil,
+	}
+	return t1, t1want
+}
+
+func gen_transform_t8() (*ast.SelectStmt, *Select) {
+	/*
+		SELECT t.a,u.a,t.b * u.b
+		FROM sa.t join u on t.c = u.c or t.d != u.d
+				  join v on u.a != v.a
+		where t.a = u.a and t.b > u.b
+		group by t.a,u.a,(t.b+u.b+v.b)
+		having t.a = 'jj' and v.c > 1000
+	*/
+	t_a := gen_var_ref("", "t", "a")
+	t_b := gen_var_ref("", "t", "b")
+	t_c := gen_var_ref("", "t", "c")
+	t_d := gen_var_ref("", "t", "d")
+
+	u_a := gen_var_ref("", "u", "a")
+	u_b := gen_var_ref("", "u", "b")
+	u_c := gen_var_ref("", "u", "c")
+	u_d := gen_var_ref("", "u", "d")
+
+	v_a := gen_var_ref("", "v", "a")
+	v_b := gen_var_ref("", "v", "b")
+	v_c := gen_var_ref("", "v", "c")
+	//v_d := gen_var_ref("","v","d")
+
+	sa_t := gen_table("sa", "t")
+
+	u := gen_table("", "u")
+
+	v := gen_table("", "v")
+
+	t_c_eq_u_c := gen_binary_expr(opcode.EQ, t_c, u_c)
+	t_d_ne_u_d := gen_binary_expr(opcode.NE, t_d, u_d)
+	t_c_eq_u_c_or_t_d_ne_u_d := gen_binary_expr(opcode.LogicOr, t_c_eq_u_c, t_d_ne_u_d)
+
+	t_u_onCond := &ast.OnCondition{Expr: t_c_eq_u_c_or_t_d_ne_u_d}
+
+	sa_t_cross_u := &ast.Join{
+		Left:           sa_t,
+		Right:          u,
+		Tp:             ast.CrossJoin,
+		On:             t_u_onCond,
+		Using:          nil,
+		NaturalJoin:    false,
+		StraightJoin:   false,
+		ExplicitParens: false,
+	}
+
+	//u.a != v.a
+	u_a_ne_v_a := gen_binary_expr(opcode.NE, u_a, v_a)
+
+	u_v_onCond := &ast.OnCondition{Expr: u_a_ne_v_a}
+
+	sa_t_cross_u_cross_v := &ast.Join{
+		Left:           sa_t_cross_u,
+		Right:          v,
+		Tp:             ast.CrossJoin,
+		On:             u_v_onCond,
+		Using:          nil,
+		NaturalJoin:    false,
+		StraightJoin:   false,
+		ExplicitParens: false,
+	}
+
+	t1TableRef := &ast.TableRefsClause{TableRefs: sa_t_cross_u_cross_v}
+
+	t_b_multi_u_b := gen_binary_expr(opcode.Mul, t_b, u_b)
+	select_fields := []*ast.SelectField{
+		&ast.SelectField{
+			Offset:    0,
+			WildCard:  nil,
+			Expr:      t_a,
+			AsName:    model.CIStr{},
+			Auxiliary: false,
+		},
+		&ast.SelectField{
+			Offset:    0,
+			WildCard:  nil,
+			Expr:      u_a,
+			AsName:    model.CIStr{},
+			Auxiliary: false,
+		},
+		&ast.SelectField{
+			Offset:    0,
+			WildCard:  nil,
+			Expr:      t_b_multi_u_b,
+			AsName:    model.CIStr{},
+			Auxiliary: false,
+		},
+	}
+
+	t1FieldList := &ast.FieldList{Fields: select_fields}
+
+	//t.a = u.a
+	t_a_eq_u_a := gen_binary_expr(opcode.EQ, t_a, u_a)
+
+	//t.b > u.b
+	t_b_gt_u_b := gen_binary_expr(opcode.GT, t_b, u_b)
+
+	//t.a = u.a and t.b > u.b
+	t_a_eq_u_a_and_t_b_gt_u_b := gen_binary_expr(opcode.LogicAnd, t_a_eq_u_a, t_b_gt_u_b)
+
+	//group by t.a,u.a,(t.b+u.b+v.b)
+
+	byitem_t_a := &ast.ByItem{
+		Expr:      t_a,
+		Desc:      false,
+		NullOrder: true,
+	}
+
+	byitem_u_a := &ast.ByItem{
+		Expr:      u_a,
+		Desc:      false,
+		NullOrder: true,
+	}
+
+	t_b_plus_u_b_plus_v_b := gen_binary_expr(opcode.Plus, gen_binary_expr(opcode.Plus, t_b, u_b), v_b)
+
+	paren_t_b_plus_u_b_plus_v_b := &ast.ParenthesesExpr{Expr: t_b_plus_u_b_plus_v_b}
+
+	byitem_t_b_plus_u_b_plus_v_b := &ast.ByItem{
+		Expr:      paren_t_b_plus_u_b_plus_v_b,
+		Desc:      false,
+		NullOrder: true,
+	}
+
+	t_groupby_item := []*ast.ByItem{
+		byitem_t_a,
+		byitem_u_a,
+		byitem_t_b_plus_u_b_plus_v_b,
+	}
+
+	t_groupby := &ast.GroupByClause{Items: t_groupby_item}
+
+	//having t.a = 'jj' and v.c > 1000
+
+	t_jj := ast.NewValueExpr("jj", "", "")
+	t_a_eq_tjj := gen_binary_expr(opcode.EQ, t_a, t_jj)
+	v_c_gt_1000 := gen_binary_expr(opcode.GT, v_c, ast.NewValueExpr(1000, "", ""))
+	t_a_eq_tjj_and_v_c_gt_1000 := gen_binary_expr(opcode.LogicAnd, t_a_eq_tjj, v_c_gt_1000)
+
+	t_having := &ast.HavingClause{Expr: t_a_eq_tjj_and_v_c_gt_1000}
+
+	t1 := &ast.SelectStmt{
+		SelectStmtOpts:   nil,
+		Distinct:         false,
+		From:             t1TableRef,
+		Where:            t_a_eq_u_a_and_t_b_gt_u_b,
+		Fields:           t1FieldList,
+		GroupBy:          t_groupby,
+		Having:           t_having,
+		WindowSpecs:      nil,
+		OrderBy:          nil,
+		Limit:            nil,
+		LockInfo:         nil,
+		TableHints:       nil,
+		IsInBraces:       false,
+		QueryBlockOffset: 0,
+		SelectIntoOpt:    nil,
+		AfterSetOperator: nil,
+		Kind:             0,
+		Lists:            nil,
+	}
+
+	//=========
+
+	want_t_a, _ := NewUnresolvedName("", "t", "a")
+	want_t_b, _ := NewUnresolvedName("", "t", "b")
+	want_t_c, _ := NewUnresolvedName("", "t", "c")
+	want_t_d, _ := NewUnresolvedName("", "t", "d")
+
+	want_u_a, _ := NewUnresolvedName("", "u", "a")
+	want_u_b, _ := NewUnresolvedName("", "u", "b")
+	want_u_c, _ := NewUnresolvedName("", "u", "c")
+	want_u_d, _ := NewUnresolvedName("", "u", "d")
+
+	want_v_a, _ := NewUnresolvedName("", "v", "a")
+	want_v_b, _ := NewUnresolvedName("", "v", "b")
+	want_v_c, _ := NewUnresolvedName("", "v", "c")
+
+	//t.c = u.c or t.d != u.d
+	want_t_c_eq_u_c := NewComparisonExpr(EQUAL, want_t_c, want_u_c)
+	want_t_d_ne_u_d := NewComparisonExpr(NOT_EQUAL, want_t_d, want_u_d)
+	want_t_c_eq_u_c_or_t_d_ne_u_d := NewOrExpr(want_t_c_eq_u_c, want_t_d_ne_u_d)
+
+	want_join_on := NewOnJoinCond(want_t_c_eq_u_c_or_t_d_ne_u_d)
+
+	//u.a != v.a
+	want_u_a_ne_v_a := NewComparisonExpr(NOT_EQUAL, want_u_a, want_v_a)
+	want_u_v_join_on := NewOnJoinCond(want_u_a_ne_v_a)
+
+	want_sa_t := gen_want_table("sa", "t")
+
+	want_u := gen_want_table("", "u")
+
+	want_v := gen_want_table("", "v")
+
+	want_t_u_join := &JoinTableExpr{
+		JoinType: JOIN_TYPE_CROSS,
+		Left:     want_sa_t,
+		Right:    want_u,
+		Cond:     want_join_on,
+	}
+
+	want_u_v_join := &JoinTableExpr{
+		JoinType: JOIN_TYPE_CROSS,
+		Left:     want_t_u_join,
+		Right:    want_v,
+		Cond:     want_u_v_join_on,
+	}
+
+	want_table_refs := []TableExpr{
+		want_u_v_join,
+	}
+
+	t1wantFrom := &From{Tables: want_table_refs}
+
+	//t.b * u.b
+	want_t_b_multi_u_b := NewBinaryExpr(MULTI, want_t_b, want_u_b)
+
+	//t.a = u.a
+	want_t_a_eq_u_a := NewComparisonExpr(EQUAL, want_t_a, want_u_a)
+
+	//t.b > u.b
+	want_t_b_gt_u_b := NewComparisonExpr(GREAT_THAN, want_t_b, want_u_b)
+
+	//t.a = u.a and t.b > u.b
+	want_t_a_eq_u_a_logicand_t_b_gt_u_b := NewAndExpr(want_t_a_eq_u_a, want_t_b_gt_u_b)
+
+	want_t_b_plus_u_b_plus_v_b := NewBinaryExpr(PLUS, NewBinaryExpr(PLUS, want_t_b, want_u_b), want_v_b)
+
+	want_paren_t_b_plus_u_b_plus_v_b := NewParenExpr(want_t_b_plus_u_b_plus_v_b)
+
+	//group by t.a,u.a,(t.b+u.b+v.b)
+	want_groupby := []Expr{
+		want_t_a,
+		want_u_a,
+		want_paren_t_b_plus_u_b_plus_v_b,
+	}
+
+	//having t.a = 'jj' and v.c > 1000
+	want_tjj := NewNumVal(constant.MakeString("jj"), "", false)
+	want_t_a_eq_tjj := NewComparisonExpr(EQUAL, want_t_a, want_tjj)
+	want_v_c_gt_1000 := NewComparisonExpr(GREAT_THAN, want_v_c, NewNumVal(constant.MakeInt64(1000), "", false))
+	want_t_a_eq_tjj_and_v_c_gt_1000 := NewAndExpr(want_t_a_eq_tjj, want_v_c_gt_1000)
+	want_having := NewWhere(want_t_a_eq_tjj_and_v_c_gt_1000)
+	t1wantFieldList := []SelectExpr{
+		{
+			Expr: want_t_a,
+			As:   "",
+		},
+		{
+			Expr: want_u_a,
+			As:   "",
+		},
+		{
+			Expr: want_t_b_multi_u_b,
+			As:   "",
+		},
+	}
+
+	t1wantSelectClause := &SelectClause{
+		From:     t1wantFrom,
+		Distinct: false,
+		Where:    NewWhere(want_t_a_eq_u_a_logicand_t_b_gt_u_b),
+		Exprs:    t1wantFieldList,
+		GroupBy:  want_groupby,
+		Having:   want_having,
+	}
+
+	t1want := &Select{
+		Select:  t1wantSelectClause,
+		OrderBy: nil,
+		Limit:   nil,
+	}
+	return t1, t1want
+}
+
+func gen_transform_t9() (*ast.SelectStmt, *Select) {
+	/*
+		SELECT t.a,u.a,t.b * u.b tubb
+		FROM sa.t join u on t.c = u.c or t.d != u.d
+				  join v on u.a != v.a
+		where t.a = u.a and t.b > u.b
+		group by t.a,u.a,(t.b+u.b+v.b)
+		having t.a = 'jj' and v.c > 1000
+		order by t.a asc,u.a desc,v.d asc,tubb
+		limit 100,2000
+	*/
+	t_a := gen_var_ref("", "t", "a")
+	t_b := gen_var_ref("", "t", "b")
+	t_c := gen_var_ref("", "t", "c")
+	t_d := gen_var_ref("", "t", "d")
+
+	u_a := gen_var_ref("", "u", "a")
+	u_b := gen_var_ref("", "u", "b")
+	u_c := gen_var_ref("", "u", "c")
+	u_d := gen_var_ref("", "u", "d")
+
+	v_a := gen_var_ref("", "v", "a")
+	v_b := gen_var_ref("", "v", "b")
+	v_c := gen_var_ref("", "v", "c")
+	v_d := gen_var_ref("", "v", "d")
+	tubb := gen_var_ref("", "", "tubb")
+
+	sa_t := gen_table("sa", "t")
+
+	u := gen_table("", "u")
+
+	v := gen_table("", "v")
+
+	t_c_eq_u_c := gen_binary_expr(opcode.EQ, t_c, u_c)
+	t_d_ne_u_d := gen_binary_expr(opcode.NE, t_d, u_d)
+	t_c_eq_u_c_or_t_d_ne_u_d := gen_binary_expr(opcode.LogicOr, t_c_eq_u_c, t_d_ne_u_d)
+
+	t_u_onCond := &ast.OnCondition{Expr: t_c_eq_u_c_or_t_d_ne_u_d}
+
+	sa_t_cross_u := &ast.Join{
+		Left:           sa_t,
+		Right:          u,
+		Tp:             ast.CrossJoin,
+		On:             t_u_onCond,
+		Using:          nil,
+		NaturalJoin:    false,
+		StraightJoin:   false,
+		ExplicitParens: false,
+	}
+
+	//u.a != v.a
+	u_a_ne_v_a := gen_binary_expr(opcode.NE, u_a, v_a)
+
+	u_v_onCond := &ast.OnCondition{Expr: u_a_ne_v_a}
+
+	sa_t_cross_u_cross_v := &ast.Join{
+		Left:           sa_t_cross_u,
+		Right:          v,
+		Tp:             ast.CrossJoin,
+		On:             u_v_onCond,
+		Using:          nil,
+		NaturalJoin:    false,
+		StraightJoin:   false,
+		ExplicitParens: false,
+	}
+
+	t1TableRef := &ast.TableRefsClause{TableRefs: sa_t_cross_u_cross_v}
+
+	t_b_multi_u_b := gen_binary_expr(opcode.Mul, t_b, u_b)
+	select_fields := []*ast.SelectField{
+		&ast.SelectField{
+			Offset:    0,
+			WildCard:  nil,
+			Expr:      t_a,
+			AsName:    model.CIStr{},
+			Auxiliary: false,
+		},
+		&ast.SelectField{
+			Offset:    0,
+			WildCard:  nil,
+			Expr:      u_a,
+			AsName:    model.CIStr{},
+			Auxiliary: false,
+		},
+		&ast.SelectField{
+			Offset:    0,
+			WildCard:  nil,
+			Expr:      t_b_multi_u_b,
+			AsName:    model.CIStr{"tubb", "tubb"},
+			Auxiliary: false,
+		},
+	}
+
+	t1FieldList := &ast.FieldList{Fields: select_fields}
+
+	//t.a = u.a
+	t_a_eq_u_a := gen_binary_expr(opcode.EQ, t_a, u_a)
+
+	//t.b > u.b
+	t_b_gt_u_b := gen_binary_expr(opcode.GT, t_b, u_b)
+
+	//t.a = u.a and t.b > u.b
+	t_a_eq_u_a_and_t_b_gt_u_b := gen_binary_expr(opcode.LogicAnd, t_a_eq_u_a, t_b_gt_u_b)
+
+	//group by t.a,u.a,(t.b+u.b+v.b)
+
+	byitem_t_a := &ast.ByItem{
+		Expr:      t_a,
+		Desc:      false,
+		NullOrder: true,
+	}
+
+	byitem_u_a := &ast.ByItem{
+		Expr:      u_a,
+		Desc:      false,
+		NullOrder: true,
+	}
+
+	t_b_plus_u_b_plus_v_b := gen_binary_expr(opcode.Plus, gen_binary_expr(opcode.Plus, t_b, u_b), v_b)
+
+	paren_t_b_plus_u_b_plus_v_b := &ast.ParenthesesExpr{Expr: t_b_plus_u_b_plus_v_b}
+
+	byitem_t_b_plus_u_b_plus_v_b := &ast.ByItem{
+		Expr:      paren_t_b_plus_u_b_plus_v_b,
+		Desc:      false,
+		NullOrder: true,
+	}
+
+	t_groupby_item := []*ast.ByItem{
+		byitem_t_a,
+		byitem_u_a,
+		byitem_t_b_plus_u_b_plus_v_b,
+	}
+
+	t_groupby := &ast.GroupByClause{Items: t_groupby_item}
+
+	//having t.a = 'jj' and v.c > 1000
+
+	t_jj := ast.NewValueExpr("jj", "", "")
+	t_a_eq_tjj := gen_binary_expr(opcode.EQ, t_a, t_jj)
+	v_c_gt_1000 := gen_binary_expr(opcode.GT, v_c, ast.NewValueExpr(1000, "", ""))
+	t_a_eq_tjj_and_v_c_gt_1000 := gen_binary_expr(opcode.LogicAnd, t_a_eq_tjj, v_c_gt_1000)
+
+	t_having := &ast.HavingClause{Expr: t_a_eq_tjj_and_v_c_gt_1000}
+
+	//order by t.a asc,u.a desc,v.d asc,tubb
+	byitem_t_a_asc := &ast.ByItem{
+		Expr:      t_a,
+		Desc:      false,
+		NullOrder: false,
+	}
+
+	byitem_u_a_desc := &ast.ByItem{
+		Expr:      u_a,
+		Desc:      true,
+		NullOrder: false,
+	}
+
+	byitem_v_d_asc := &ast.ByItem{
+		Expr:      v_d,
+		Desc:      false,
+		NullOrder: false,
+	}
+
+	byitem_tubb := &ast.ByItem{
+		Expr:      tubb,
+		Desc:      false,
+		NullOrder: false,
+	}
+
+	t_orderby_items := []*ast.ByItem{
+		byitem_t_a_asc,
+		byitem_u_a_desc,
+		byitem_v_d_asc,
+		byitem_tubb,
+	}
+
+	t_orderby := &ast.OrderByClause{
+		Items:    t_orderby_items,
+		ForUnion: false,
+	}
+
+	//limit 100,2000
+	t_limit := &ast.Limit{
+		Count:  ast.NewValueExpr(2000, "", ""),
+		Offset: ast.NewValueExpr(100, "", ""),
+	}
+
+	t1 := &ast.SelectStmt{
+		SelectStmtOpts:   nil,
+		Distinct:         false,
+		From:             t1TableRef,
+		Where:            t_a_eq_u_a_and_t_b_gt_u_b,
+		Fields:           t1FieldList,
+		GroupBy:          t_groupby,
+		Having:           t_having,
+		WindowSpecs:      nil,
+		OrderBy:          t_orderby,
+		Limit:            t_limit,
+		LockInfo:         nil,
+		TableHints:       nil,
+		IsInBraces:       false,
+		QueryBlockOffset: 0,
+		SelectIntoOpt:    nil,
+		AfterSetOperator: nil,
+		Kind:             0,
+		Lists:            nil,
+	}
+
+	//=========
+
+	want_t_a, _ := NewUnresolvedName("", "t", "a")
+	want_t_b, _ := NewUnresolvedName("", "t", "b")
+	want_t_c, _ := NewUnresolvedName("", "t", "c")
+	want_t_d, _ := NewUnresolvedName("", "t", "d")
+
+	want_u_a, _ := NewUnresolvedName("", "u", "a")
+	want_u_b, _ := NewUnresolvedName("", "u", "b")
+	want_u_c, _ := NewUnresolvedName("", "u", "c")
+	want_u_d, _ := NewUnresolvedName("", "u", "d")
+
+	want_v_a, _ := NewUnresolvedName("", "v", "a")
+	want_v_b, _ := NewUnresolvedName("", "v", "b")
+	want_v_c, _ := NewUnresolvedName("", "v", "c")
+	want_v_d, _ := NewUnresolvedName("", "v", "d")
+
+	want_tubb, _ := NewUnresolvedName("", "", "tubb")
+
+	//t.c = u.c or t.d != u.d
+	want_t_c_eq_u_c := NewComparisonExpr(EQUAL, want_t_c, want_u_c)
+	want_t_d_ne_u_d := NewComparisonExpr(NOT_EQUAL, want_t_d, want_u_d)
+	want_t_c_eq_u_c_or_t_d_ne_u_d := NewOrExpr(want_t_c_eq_u_c, want_t_d_ne_u_d)
+
+	want_join_on := NewOnJoinCond(want_t_c_eq_u_c_or_t_d_ne_u_d)
+
+	//u.a != v.a
+	want_u_a_ne_v_a := NewComparisonExpr(NOT_EQUAL, want_u_a, want_v_a)
+	want_u_v_join_on := NewOnJoinCond(want_u_a_ne_v_a)
+
+	want_sa_t := gen_want_table("sa", "t")
+
+	want_u := gen_want_table("", "u")
+
+	want_v := gen_want_table("", "v")
+
+	want_t_u_join := &JoinTableExpr{
+		JoinType: JOIN_TYPE_CROSS,
+		Left:     want_sa_t,
+		Right:    want_u,
+		Cond:     want_join_on,
+	}
+
+	want_u_v_join := &JoinTableExpr{
+		JoinType: JOIN_TYPE_CROSS,
+		Left:     want_t_u_join,
+		Right:    want_v,
+		Cond:     want_u_v_join_on,
+	}
+
+	want_table_refs := []TableExpr{
+		want_u_v_join,
+	}
+
+	t1wantFrom := &From{Tables: want_table_refs}
+
+	//t.b * u.b
+	want_t_b_multi_u_b := NewBinaryExpr(MULTI, want_t_b, want_u_b)
+
+	//t.a = u.a
+	want_t_a_eq_u_a := NewComparisonExpr(EQUAL, want_t_a, want_u_a)
+
+	//t.b > u.b
+	want_t_b_gt_u_b := NewComparisonExpr(GREAT_THAN, want_t_b, want_u_b)
+
+	//t.a = u.a and t.b > u.b
+	want_t_a_eq_u_a_logicand_t_b_gt_u_b := NewAndExpr(want_t_a_eq_u_a, want_t_b_gt_u_b)
+
+	want_t_b_plus_u_b_plus_v_b := NewBinaryExpr(PLUS, NewBinaryExpr(PLUS, want_t_b, want_u_b), want_v_b)
+
+	want_paren_t_b_plus_u_b_plus_v_b := NewParenExpr(want_t_b_plus_u_b_plus_v_b)
+
+	//group by t.a,u.a,(t.b+u.b+v.b)
+	want_groupby := []Expr{
+		want_t_a,
+		want_u_a,
+		want_paren_t_b_plus_u_b_plus_v_b,
+	}
+
+	//having t.a = 'jj' and v.c > 1000
+	want_tjj := NewNumVal(constant.MakeString("jj"), "", false)
+	want_t_a_eq_tjj := NewComparisonExpr(EQUAL, want_t_a, want_tjj)
+	num1000 := NewNumVal(constant.MakeInt64(1000), "", false)
+	want_v_c_gt_1000 := NewComparisonExpr(GREAT_THAN, want_v_c, num1000)
+	want_t_a_eq_tjj_and_v_c_gt_1000 := NewAndExpr(want_t_a_eq_tjj, want_v_c_gt_1000)
+	want_having := NewWhere(want_t_a_eq_tjj_and_v_c_gt_1000)
+
+	////order by t.a asc,u.a desc,v.d asc,tubb
+	want_orderby := []*Order{
+		NewOrder(want_t_a, Ascending, false),
+		NewOrder(want_u_a, Descending, false),
+		NewOrder(want_v_d, Ascending, false),
+		NewOrder(want_tubb, Ascending, false),
+	}
+
+	//limit 100,2000
+	num100 := NewNumVal(constant.MakeInt64(100), "", false)
+	num2000 := NewNumVal(constant.MakeInt64(2000), "", false)
+
+	want_limit := NewLimit(num100, num2000)
+
+	t1wantFieldList := []SelectExpr{
+		{
+			Expr: want_t_a,
+			As:   "",
+		},
+		{
+			Expr: want_u_a,
+			As:   "",
+		},
+		{
+			Expr: want_t_b_multi_u_b,
+			As:   "tubb",
+		},
+	}
+
+	t1wantSelectClause := &SelectClause{
+		From:     t1wantFrom,
+		Distinct: false,
+		Where:    NewWhere(want_t_a_eq_u_a_logicand_t_b_gt_u_b),
+		Exprs:    t1wantFieldList,
+		GroupBy:  want_groupby,
+		Having:   want_having,
+	}
+
+	t1want := &Select{
+		Select:  t1wantSelectClause,
+		OrderBy: want_orderby,
+		Limit:   want_limit,
+	}
+	return t1, t1want
+}
+
+func gen_transform_t10() (*ast.SelectStmt, *Select) {
+	//SELECT *	FROM u;
+
+	u := gen_table("", "u")
+
+	t1Join := &ast.Join{
+		Left:           u,
+		Right:          nil,
+		Tp:             0,
+		On:             nil,
+		Using:          nil,
+		NaturalJoin:    false,
+		StraightJoin:   false,
+		ExplicitParens: false,
+	}
+
+	t1TableRef := &ast.TableRefsClause{TableRefs: t1Join}
+
+	t1_wildcard := &ast.WildCardField{}
+
+	t1SelectField := []*ast.SelectField{
+		&ast.SelectField{
+			Offset:    0,
+			WildCard:  t1_wildcard,
+			Expr:      nil,
+			AsName:    model.CIStr{},
+			Auxiliary: false,
+		},
+	}
+
+	t1FieldList := &ast.FieldList{Fields: t1SelectField}
+
+	t1 := &ast.SelectStmt{
+		SelectStmtOpts:   nil,
+		Distinct:         false,
+		From:             t1TableRef,
+		Where:            nil,
+		Fields:           t1FieldList,
+		GroupBy:          nil,
+		Having:           nil,
+		WindowSpecs:      nil,
+		OrderBy:          nil,
+		Limit:            nil,
+		LockInfo:         nil,
+		TableHints:       nil,
+		IsInBraces:       false,
+		QueryBlockOffset: 0,
+		SelectIntoOpt:    nil,
+		AfterSetOperator: nil,
+		Kind:             0,
+		Lists:            nil,
+	}
+
+	want_u := gen_want_table("", "u")
+
+	t1wantTableExprArray := []TableExpr{
+		&JoinTableExpr{
+			JoinType: "",
+			Left:     want_u,
+			Right:    nil,
+			Cond:     nil,
+		},
+	}
+	t1wantFrom := &From{Tables: t1wantTableExprArray}
+
+	want_star := StarExpr()
+
+	t1wantFieldList := []SelectExpr{
+		{
+			Expr: want_star,
+			As:   "",
+		},
+	}
+
+	t1wantSelectClause := &SelectClause{
+		From:     t1wantFrom,
+		Distinct: false,
+		Where:    nil,
+		Exprs:    t1wantFieldList,
+		GroupBy:  nil,
+		Having:   nil,
+	}
+
+	t1want := &Select{
+		Select:  t1wantSelectClause,
+		OrderBy: nil,
+		Limit:   nil,
+	}
+	return t1, t1want
+}
+
+func gen_transform_t11() (*ast.SelectStmt, *Select) {
+	//SELECT u.*	FROM u;
+
+	u := gen_table("", "u")
+
+	t1Join := &ast.Join{
+		Left:           u,
+		Right:          nil,
+		Tp:             0,
+		On:             nil,
+		Using:          nil,
+		NaturalJoin:    false,
+		StraightJoin:   false,
+		ExplicitParens: false,
+	}
+
+	t1TableRef := &ast.TableRefsClause{TableRefs: t1Join}
+
+	t1_wildcard := &ast.WildCardField{Table: model.NewCIStr("u")}
+
+	t1SelectField := []*ast.SelectField{
+		&ast.SelectField{
+			Offset:    0,
+			WildCard:  t1_wildcard,
+			Expr:      nil,
+			AsName:    model.CIStr{},
+			Auxiliary: false,
+		},
+	}
+
+	t1FieldList := &ast.FieldList{Fields: t1SelectField}
+
+	t1 := &ast.SelectStmt{
+		SelectStmtOpts:   nil,
+		Distinct:         false,
+		From:             t1TableRef,
+		Where:            nil,
+		Fields:           t1FieldList,
+		GroupBy:          nil,
+		Having:           nil,
+		WindowSpecs:      nil,
+		OrderBy:          nil,
+		Limit:            nil,
+		LockInfo:         nil,
+		TableHints:       nil,
+		IsInBraces:       false,
+		QueryBlockOffset: 0,
+		SelectIntoOpt:    nil,
+		AfterSetOperator: nil,
+		Kind:             0,
+		Lists:            nil,
+	}
+
+	want_u := gen_want_table("", "u")
+
+	t1wantTableExprArray := []TableExpr{
+		&JoinTableExpr{
+			JoinType: "",
+			Left:     want_u,
+			Right:    nil,
+			Cond:     nil,
+		},
+	}
+	t1wantFrom := &From{Tables: t1wantTableExprArray}
+
+	want_star, _ := NewUnresolvedNameWithStar("u")
+
+	t1wantFieldList := []SelectExpr{
+		{
+			Expr: want_star,
+			As:   "",
+		},
+	}
+
+	t1wantSelectClause := &SelectClause{
+		From:     t1wantFrom,
+		Distinct: false,
+		Where:    nil,
+		Exprs:    t1wantFieldList,
+		GroupBy:  nil,
+		Having:   nil,
+	}
+
+	t1want := &Select{
+		Select:  t1wantSelectClause,
+		OrderBy: nil,
+		Limit:   nil,
+	}
+	return t1, t1want
+}
+
+func gen_transform_t12() (*ast.SelectStmt, *Select) {
+	/*
+		SELECT abs(u.a),count(u.b),cast(u.c as char)
+		from u
+	*/
+
+	u := gen_table("", "u")
+
+	t1Join := &ast.Join{
+		Left:           u,
+		Right:          nil,
+		Tp:             0,
+		On:             nil,
+		Using:          nil,
+		NaturalJoin:    false,
+		StraightJoin:   false,
+		ExplicitParens: false,
+	}
+
+	t1TableRef := &ast.TableRefsClause{TableRefs: t1Join}
+
+	t1_func_call_agg := []ast.ExprNode{
+		gen_var_ref("", "u", "a"),
+	}
+
+	t1_func_call := &ast.FuncCallExpr{
+		Tp:     0,
+		Schema: model.CIStr{},
+		FnName: model.CIStr{"abs", "abs"},
+		Args:   t1_func_call_agg,
+	}
+
+	t1_agg_func_agg := []ast.ExprNode{
+		gen_var_ref("", "u", "b"),
+	}
+
+	t1_agg_func := &ast.AggregateFuncExpr{
+		F:        "count",
+		Args:     t1_agg_func_agg,
+		Distinct: false,
+		Order:    nil,
+	}
+
+	t1_func_cast := &ast.FuncCastExpr{
+		Expr:            gen_var_ref("", "u", "c"),
+		Tp:              types.NewFieldType(253),
+		FunctionType:    0,
+		ExplicitCharSet: false,
+	}
+
+	t1SelectField := []*ast.SelectField{
+		&ast.SelectField{
+			Offset:    0,
+			WildCard:  nil,
+			Expr:      t1_func_call,
+			AsName:    model.CIStr{},
+			Auxiliary: false,
+		},
+		&ast.SelectField{
+			Offset:    0,
+			WildCard:  nil,
+			Expr:      t1_agg_func,
+			AsName:    model.CIStr{},
+			Auxiliary: false,
+		},
+		&ast.SelectField{
+			Offset:    0,
+			WildCard:  nil,
+			Expr:      t1_func_cast,
+			AsName:    model.CIStr{},
+			Auxiliary: false,
+		},
+	}
+
+	t1FieldList := &ast.FieldList{Fields: t1SelectField}
+
+	t1 := &ast.SelectStmt{
+		SelectStmtOpts:   nil,
+		Distinct:         false,
+		From:             t1TableRef,
+		Where:            nil,
+		Fields:           t1FieldList,
+		GroupBy:          nil,
+		Having:           nil,
+		WindowSpecs:      nil,
+		OrderBy:          nil,
+		Limit:            nil,
+		LockInfo:         nil,
+		TableHints:       nil,
+		IsInBraces:       false,
+		QueryBlockOffset: 0,
+		SelectIntoOpt:    nil,
+		AfterSetOperator: nil,
+		Kind:             0,
+		Lists:            nil,
+	}
+
+	want_u := gen_want_table("", "u")
+
+	t1wantTableExprArray := []TableExpr{
+		&JoinTableExpr{
+			JoinType: "",
+			Left:     want_u,
+			Right:    nil,
+			Cond:     nil,
+		},
+	}
+	t1wantFrom := &From{Tables: t1wantTableExprArray}
+
+	want_u_a, _ := NewUnresolvedName("", "u", "a")
+	want_u_b, _ := NewUnresolvedName("", "u", "b")
+	want_u_c, _ := NewUnresolvedName("", "u", "c")
+
+	want_abs, _ := NewUnresolvedName("", "abs")
+	want_call_abs := NewFuncExpr(0, want_abs, []Expr{want_u_a}, nil)
+
+	want_count, _ := NewUnresolvedName("count")
+	want_call_count := NewFuncExpr(0, want_count, []Expr{want_u_b}, nil)
+
+	want_call_cast := NewCastExpr(want_u_c, TYPE_VARSTRING)
+
+	t1wantFieldList := []SelectExpr{
+		{
+			Expr: want_call_abs,
+			As:   "",
+		},
+		{
+			Expr: want_call_count,
+			As:   "",
+		},
+		{
+			Expr: want_call_cast,
+			As:   "",
+		},
+	}
+
+	t1wantSelectClause := &SelectClause{
+		From:     t1wantFrom,
+		Distinct: false,
+		Where:    nil,
+		Exprs:    t1wantFieldList,
+		GroupBy:  nil,
+		Having:   nil,
+	}
+
+	t1want := &Select{
+		Select:  t1wantSelectClause,
+		OrderBy: nil,
+		Limit:   nil,
+	}
+	return t1, t1want
+}
+
+func gen_transform_t13() (*ast.SelectStmt, *Select) {
+	/*
+		SELECT u.a,(SELECT t.a FROM sa.t,u)
+		from u
+	*/
+
+	sub, want_sub := gen_transform_t1()
+	subExpr := &ast.SubqueryExpr{
+		Query:      sub,
+		Evaluated:  false,
+		Correlated: false,
+		MultiRows:  false,
+		Exists:     false,
+	}
+
+	u := gen_table("", "u")
+
+	t1Join := &ast.Join{
+		Left:           u,
+		Right:          nil,
+		Tp:             0,
+		On:             nil,
+		Using:          nil,
+		NaturalJoin:    false,
+		StraightJoin:   false,
+		ExplicitParens: false,
+	}
+
+	t1TableRef := &ast.TableRefsClause{TableRefs: t1Join}
+
+	t1SelectField := []*ast.SelectField{
+		&ast.SelectField{
+			Offset:    0,
+			WildCard:  nil,
+			Expr:      gen_var_ref("", "u", "a"),
+			AsName:    model.CIStr{},
+			Auxiliary: false,
+		},
+		&ast.SelectField{
+			Offset:    0,
+			WildCard:  nil,
+			Expr:      subExpr,
+			AsName:    model.CIStr{},
+			Auxiliary: false,
+		},
+	}
+
+	t1FieldList := &ast.FieldList{Fields: t1SelectField}
+
+	t1 := &ast.SelectStmt{
+		SelectStmtOpts:   nil,
+		Distinct:         false,
+		From:             t1TableRef,
+		Where:            nil,
+		Fields:           t1FieldList,
+		GroupBy:          nil,
+		Having:           nil,
+		WindowSpecs:      nil,
+		OrderBy:          nil,
+		Limit:            nil,
+		LockInfo:         nil,
+		TableHints:       nil,
+		IsInBraces:       false,
+		QueryBlockOffset: 0,
+		SelectIntoOpt:    nil,
+		AfterSetOperator: nil,
+		Kind:             0,
+		Lists:            nil,
+	}
+
+	want_u := gen_want_table("", "u")
+
+	t1wantTableExprArray := []TableExpr{
+		&JoinTableExpr{
+			JoinType: "",
+			Left:     want_u,
+			Right:    nil,
+			Cond:     nil,
+		},
+	}
+	t1wantFrom := &From{Tables: t1wantTableExprArray}
+
+	want_u_a, _ := NewUnresolvedName("", "u", "a")
+
+	t1wantFieldList := []SelectExpr{
+		{
+			Expr: want_u_a,
+			As:   "",
+		},
+		{
+			Expr: NewSubquery(want_sub.Select, false),
+			As:   "",
+		},
+	}
+
+	t1wantSelectClause := &SelectClause{
+		From:     t1wantFrom,
+		Distinct: false,
+		Where:    nil,
+		Exprs:    t1wantFieldList,
+		GroupBy:  nil,
+		Having:   nil,
+	}
+
+	t1want := &Select{
+		Select:  t1wantSelectClause,
+		OrderBy: nil,
+		Limit:   nil,
+	}
+	return t1, t1want
+}
+
+func gen_transform_t14() (*ast.SelectStmt, *Select) {
+	/*
+		SELECT u.a,(SELECT t.a FROM sa.t,u)
+		from u,(SELECT t.a,u.a FROM sa.t,u where t.a = u.a)
+	*/
+
+	sub, want_sub := gen_transform_t1()
+	subExpr := &ast.SubqueryExpr{
+		Query:      sub,
+		Evaluated:  false,
+		Correlated: false,
+		MultiRows:  false,
+		Exists:     false,
+	}
+
+	sub1, want_sub1 := gen_transform_t3()
+	subExpr1 := &ast.SubqueryExpr{
+		Query:      sub1,
+		Evaluated:  false,
+		Correlated: false,
+		MultiRows:  false,
+		Exists:     false,
+	}
+
+	u := gen_table("", "u")
+
+	t1Join := &ast.Join{
+		Left:           u,
+		Right:          nil,
+		Tp:             0,
+		On:             nil,
+		Using:          nil,
+		NaturalJoin:    false,
+		StraightJoin:   false,
+		ExplicitParens: false,
+	}
+
+	from_sub := &ast.TableSource{
+		Source: subExpr1,
+		AsName: model.CIStr{},
+	}
+
+	t1Join2 := &ast.Join{
+		Left:           t1Join,
+		Right:          from_sub,
+		Tp:             ast.CrossJoin,
+		On:             nil,
+		Using:          nil,
+		NaturalJoin:    false,
+		StraightJoin:   false,
+		ExplicitParens: false,
+	}
+
+	t1TableRef := &ast.TableRefsClause{TableRefs: t1Join2}
+
+	t1SelectField := []*ast.SelectField{
+		&ast.SelectField{
+			Offset:    0,
+			WildCard:  nil,
+			Expr:      gen_var_ref("", "u", "a"),
+			AsName:    model.CIStr{},
+			Auxiliary: false,
+		},
+		&ast.SelectField{
+			Offset:    0,
+			WildCard:  nil,
+			Expr:      subExpr,
+			AsName:    model.CIStr{},
+			Auxiliary: false,
+		},
+	}
+
+	t1FieldList := &ast.FieldList{Fields: t1SelectField}
+
+	t1 := &ast.SelectStmt{
+		SelectStmtOpts:   nil,
+		Distinct:         false,
+		From:             t1TableRef,
+		Where:            nil,
+		Fields:           t1FieldList,
+		GroupBy:          nil,
+		Having:           nil,
+		WindowSpecs:      nil,
+		OrderBy:          nil,
+		Limit:            nil,
+		LockInfo:         nil,
+		TableHints:       nil,
+		IsInBraces:       false,
+		QueryBlockOffset: 0,
+		SelectIntoOpt:    nil,
+		AfterSetOperator: nil,
+		Kind:             0,
+		Lists:            nil,
+	}
+
+	want_u := gen_want_table("", "u")
+
+	from2 := NewAliasedTableExpr(NewSubquery(want_sub1.Select, false), AliasClause{
+		Alias: "",
+	})
+
+	wantjoin1 := NewJoinTableExpr("", want_u, nil, nil)
+
+	t1wantTableExprArray := []TableExpr{
+		&JoinTableExpr{
+			JoinType: JOIN_TYPE_CROSS,
+			Left:     wantjoin1,
+			Right:    from2,
+			Cond:     nil,
+		},
+	}
+	t1wantFrom := &From{Tables: t1wantTableExprArray}
+
+	want_u_a, _ := NewUnresolvedName("", "u", "a")
+
+	t1wantFieldList := []SelectExpr{
+		{
+			Expr: want_u_a,
+			As:   "",
+		},
+		{
+			Expr: NewSubquery(want_sub.Select, false),
+			As:   "",
+		},
+	}
+
+	t1wantSelectClause := &SelectClause{
+		From:     t1wantFrom,
+		Distinct: false,
+		Where:    nil,
+		Exprs:    t1wantFieldList,
+		GroupBy:  nil,
+		Having:   nil,
+	}
+
+	t1want := &Select{
+		Select:  t1wantSelectClause,
+		OrderBy: nil,
+		Limit:   nil,
+	}
+	return t1, t1want
+}
+
+func gen_transform_t15() (*ast.SelectStmt, *Select) {
+	/*
+		SELECT u.a,(SELECT t.a FROM sa.t,u)
+		from u,(SELECT t.a,u.a FROM sa.t,u where t.a = u.a)
+		where (u.a,u.b,u.c) in (SELECT t.a,u.a,t.b * u.b tubb
+		FROM sa.t join u on t.c = u.c or t.d != u.d
+				  join v on u.a != v.a
+		where t.a = u.a and t.b > u.b
+		group by t.a,u.a,(t.b+u.b+v.b)
+		having t.a = 'jj' and v.c > 1000
+		order by t.a asc,u.a desc,v.d asc,tubb
+		limit 100,2000)
+	*/
+
+	sub, want_sub := gen_transform_t1()
+	subExpr := &ast.SubqueryExpr{
+		Query:      sub,
+		Evaluated:  false,
+		Correlated: false,
+		MultiRows:  false,
+		Exists:     false,
+	}
+
+	sub1, want_sub1 := gen_transform_t3()
+	subExpr1 := &ast.SubqueryExpr{
+		Query:      sub1,
+		Evaluated:  false,
+		Correlated: false,
+		MultiRows:  false,
+		Exists:     false,
+	}
+
+	sub2, want_sub2 := gen_transform_t9()
+	subExpr2 := &ast.SubqueryExpr{
+		Query:      sub2,
+		Evaluated:  false,
+		Correlated: false,
+		MultiRows:  false,
+		Exists:     false,
+	}
+
+	t1row := []ast.ExprNode{
+		gen_var_ref("", "u", "a"),
+		gen_var_ref("", "u", "b"),
+		gen_var_ref("", "u", "c"),
+	}
+
+	t1rowExpr := &ast.RowExpr{Values: t1row}
+
+	t1_row_in_expr := &ast.PatternInExpr{
+		Expr: t1rowExpr,
+		List: nil,
+		Not:  false,
+		Sel:  subExpr2,
+	}
+
+	u := gen_table("", "u")
+
+	t1Join := &ast.Join{
+		Left:           u,
+		Right:          nil,
+		Tp:             0,
+		On:             nil,
+		Using:          nil,
+		NaturalJoin:    false,
+		StraightJoin:   false,
+		ExplicitParens: false,
+	}
+
+	from_sub := &ast.TableSource{
+		Source: subExpr1,
+		AsName: model.CIStr{},
+	}
+
+	t1Join2 := &ast.Join{
+		Left:           t1Join,
+		Right:          from_sub,
+		Tp:             ast.CrossJoin,
+		On:             nil,
+		Using:          nil,
+		NaturalJoin:    false,
+		StraightJoin:   false,
+		ExplicitParens: false,
+	}
+
+	t1TableRef := &ast.TableRefsClause{TableRefs: t1Join2}
+
+	t1SelectField := []*ast.SelectField{
+		&ast.SelectField{
+			Offset:    0,
+			WildCard:  nil,
+			Expr:      gen_var_ref("", "u", "a"),
+			AsName:    model.CIStr{},
+			Auxiliary: false,
+		},
+		&ast.SelectField{
+			Offset:    0,
+			WildCard:  nil,
+			Expr:      subExpr,
+			AsName:    model.CIStr{},
+			Auxiliary: false,
+		},
+	}
+
+	t1FieldList := &ast.FieldList{Fields: t1SelectField}
+
+	t1 := &ast.SelectStmt{
+		SelectStmtOpts:   nil,
+		Distinct:         false,
+		From:             t1TableRef,
+		Where:            t1_row_in_expr,
+		Fields:           t1FieldList,
+		GroupBy:          nil,
+		Having:           nil,
+		WindowSpecs:      nil,
+		OrderBy:          nil,
+		Limit:            nil,
+		LockInfo:         nil,
+		TableHints:       nil,
+		IsInBraces:       false,
+		QueryBlockOffset: 0,
+		SelectIntoOpt:    nil,
+		AfterSetOperator: nil,
+		Kind:             0,
+		Lists:            nil,
+	}
+
+	//
+	tp_want_u_a, _ := NewUnresolvedName("", "u", "a")
+	tp_want_u_b, _ := NewUnresolvedName("", "u", "b")
+	tp_want_u_c, _ := NewUnresolvedName("", "u", "c")
+
+	want_tuple := []Expr{
+		tp_want_u_a,
+		tp_want_u_b,
+		tp_want_u_c,
+	}
+
+	tupleExpr := NewTuple(want_tuple)
+
+	want_in_expr := NewComparisonExpr(IN, tupleExpr, NewSubquery(want_sub2.Select, false))
+
+	want_joinu := gen_want_table("", "u")
+
+	from2 := NewAliasedTableExpr(NewSubquery(want_sub1.Select, false), AliasClause{
+		Alias: "",
+	})
+
+	wantjoin1 := NewJoinTableExpr(JOIN_TYPE_CROSS, NewJoinTableExpr("", want_joinu, nil, nil), from2, nil)
+
+	t1wantTableExprArray := []TableExpr{
+		//&JoinTableExpr{
+		//	JoinType:  "",
+		//	Left:      wantjoin1,
+		//	Right:     nil,
+		//	Cond:      nil,
+		//},
+		wantjoin1,
+	}
+	t1wantFrom := &From{Tables: t1wantTableExprArray}
+
+	want_u_a, _ := NewUnresolvedName("", "u", "a")
+
+	t1wantFieldList := []SelectExpr{
+		{
+			Expr: want_u_a,
+			As:   "",
+		},
+		{
+			Expr: NewSubquery(want_sub.Select, false),
+			As:   "",
+		},
+	}
+
+	t1wantSelectClause := &SelectClause{
+		From:     t1wantFrom,
+		Distinct: false,
+		Where:    NewWhere(want_in_expr),
+		Exprs:    t1wantFieldList,
+		GroupBy:  nil,
+		Having:   nil,
+	}
+
+	t1want := &Select{
+		Select:  t1wantSelectClause,
+		OrderBy: nil,
+		Limit:   nil,
+	}
+	return t1, t1want
+}
+
+func Test_transformSelectStmtToSelect(t *testing.T) {
+	type args struct {
+		ss *ast.SelectStmt
+	}
+
+	t1, t1want := gen_transform_t1()
+	t2, t2want := gen_transform_t2()
+	t3, t3want := gen_transform_t3()
+	t4, t4want := gen_transform_t4()
+	t5, t5want := gen_transform_t5()
+	t6, t6want := gen_transform_t6()
+	t7, t7want := gen_transform_t7()
+	t8, t8want := gen_transform_t8()
+	t9, t9want := gen_transform_t9()
+	t10, t10want := gen_transform_t10()
+	t11, t11want := gen_transform_t11()
+	t12, t12want := gen_transform_t12()
+	t13, t13want := gen_transform_t13()
+	t14, t14want := gen_transform_t14()
+	t15, t15want := gen_transform_t15()
+
+	tests := []struct {
+		name string
+		args args
+		want *Select
+	}{
+		{"t1", args{t1}, t1want},
+		{"t2", args{t2}, t2want},
+		{"t3", args{t3}, t3want},
+		{"t4", args{t4}, t4want},
+		{"t5", args{t5}, t5want},
+		{"t6", args{t6}, t6want},
+		{"t7", args{t7}, t7want},
+		{"t8", args{t8}, t8want},
+		{"t9", args{t9}, t9want},
+		{"t10", args{t10}, t10want},
+		{"t11", args{t11}, t11want},
+		{"t12", args{t12}, t12want},
+		{"t13", args{t13}, t13want},
+		{"t14", args{t14}, t14want},
+		{"t15", args{t15}, t15want},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := transformSelectStmtToSelect(tt.args.ss); !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("transformSelectStmtToSelect() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
diff --git a/pkg/sql/tree/types.go b/pkg/sql/tree/types.go
new file mode 100644
index 0000000000000000000000000000000000000000..af7e9935c4af44b23415f260920c230a2f850f02
--- /dev/null
+++ b/pkg/sql/tree/types.go
@@ -0,0 +1,42 @@
+package tree
+
+import "matrixone/pkg/server"
+
+type InternalType uint8
+
+//sql type
+type T struct {
+	InternalType InternalType
+}
+
+var (
+	TYPE_TINY      = &T{InternalType: InternalType(server.MYSQL_TYPE_TINY)}
+	TYPE_SHORT     = &T{InternalType: InternalType(server.MYSQL_TYPE_SHORT)}
+	TYPE_LONG      = &T{InternalType: InternalType(server.MYSQL_TYPE_LONG)}
+	TYPE_FLOAT     = &T{InternalType: InternalType(server.MYSQL_TYPE_FLOAT)}
+	TYPE_DOUBLE    = &T{InternalType: InternalType(server.MYSQL_TYPE_DOUBLE)}
+	TYPE_NULL      = &T{InternalType: InternalType(server.MYSQL_TYPE_NULL)}
+	TYPE_TIMESTAMP = &T{InternalType: InternalType(server.MYSQL_TYPE_TIMESTAMP)}
+	TYPE_LONGLONG  = &T{InternalType: InternalType(server.MYSQL_TYPE_LONGLONG)}
+	TYPE_INT24     = &T{InternalType: InternalType(server.MYSQL_TYPE_INT24)}
+	TYPE_DATE      = &T{InternalType: InternalType(server.MYSQL_TYPE_DATE)}
+	TYPE_DURATION  = &T{InternalType: InternalType(server.MYSQL_TYPE_TIME)}
+	TYPE_TIME      = &T{InternalType: InternalType(server.MYSQL_TYPE_TIME)}
+	TYPE_DATETIME  = &T{InternalType: InternalType(server.MYSQL_TYPE_DATETIME)}
+	TYPE_YEAR      = &T{InternalType: InternalType(server.MYSQL_TYPE_YEAR)}
+	TYPE_NEWDATE   = &T{InternalType: InternalType(server.MYSQL_TYPE_NEWDATE)}
+	TYPE_VARCHAR   = &T{InternalType: InternalType(server.MYSQL_TYPE_VARCHAR)}
+	TYPE_BIT       = &T{InternalType: InternalType(server.MYSQL_TYPE_BIT)}
+
+	TYPE_BOOL        = &T{InternalType: InternalType(server.MYSQL_TYPE_BOOL)}
+	TYPE_JSON        = &T{InternalType: InternalType(server.MYSQL_TYPE_JSON)}
+	TYPE_ENUM        = &T{InternalType: InternalType(server.MYSQL_TYPE_ENUM)}
+	TYPE_SET         = &T{InternalType: InternalType(server.MYSQL_TYPE_SET)}
+	TYPE_TINY_BLOB   = &T{InternalType: InternalType(server.MYSQL_TYPE_TINY_BLOB)}
+	TYPE_MEDIUM_BLOB = &T{InternalType: InternalType(server.MYSQL_TYPE_MEDIUM_BLOB)}
+	TYPE_LONG_BLOB   = &T{InternalType: InternalType(server.MYSQL_TYPE_LONG_BLOB)}
+	TYPE_BLOB        = &T{InternalType: InternalType(server.MYSQL_TYPE_BLOB)}
+	TYPE_VARSTRING   = &T{InternalType: InternalType(server.MYSQL_TYPE_VAR_STRING)}
+	TYPE_STRING      = &T{InternalType: InternalType(server.MYSQL_TYPE_STRING)}
+	TYPE_GEOMETRY    = &T{InternalType: InternalType(server.MYSQL_TYPE_GEOMETRY)}
+)