github.com/matrixorigin/matrixone@v1.2.0/pkg/frontend/util_test.go (about)

     1  // Copyright 2021 Matrix Origin
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package frontend
    16  
    17  import (
    18  	"context"
    19  	"encoding/binary"
    20  	"fmt"
    21  	"math"
    22  	"sort"
    23  	"strings"
    24  	"testing"
    25  	"time"
    26  
    27  	"github.com/matrixorigin/matrixone/pkg/txn/clock"
    28  
    29  	"github.com/matrixorigin/matrixone/pkg/defines"
    30  	"github.com/matrixorigin/matrixone/pkg/vm/engine/memoryengine"
    31  
    32  	"github.com/stretchr/testify/assert"
    33  
    34  	"github.com/matrixorigin/matrixone/pkg/common/moerr"
    35  	"github.com/matrixorigin/matrixone/pkg/pb/txn"
    36  	"github.com/matrixorigin/matrixone/pkg/util/toml"
    37  	"github.com/matrixorigin/matrixone/pkg/vm/engine"
    38  
    39  	"github.com/golang/mock/gomock"
    40  	cvey "github.com/smartystreets/goconvey/convey"
    41  
    42  	"github.com/matrixorigin/matrixone/pkg/common/mpool"
    43  	"github.com/matrixorigin/matrixone/pkg/config"
    44  	"github.com/matrixorigin/matrixone/pkg/container/types"
    45  	"github.com/matrixorigin/matrixone/pkg/container/vector"
    46  	mock_frontend "github.com/matrixorigin/matrixone/pkg/frontend/test"
    47  	"github.com/matrixorigin/matrixone/pkg/sql/parsers"
    48  	"github.com/matrixorigin/matrixone/pkg/sql/parsers/dialect"
    49  	"github.com/matrixorigin/matrixone/pkg/sql/parsers/tree"
    50  	"github.com/matrixorigin/matrixone/pkg/sql/plan"
    51  	"github.com/matrixorigin/matrixone/pkg/sql/util"
    52  	"github.com/matrixorigin/matrixone/pkg/testutil"
    53  	"github.com/matrixorigin/matrixone/pkg/vm/process"
    54  
    55  	"github.com/stretchr/testify/require"
    56  )
    57  
    58  func init() {
    59  	testutil.SetupAutoIncrService()
    60  }
    61  
    62  func Test_PathExists(t *testing.T) {
    63  	cases := [...]struct {
    64  		path   string
    65  		exist  bool
    66  		isfile bool
    67  		noerr  bool
    68  	}{
    69  		{"test/file", true, true, true},
    70  		{"test/file-no", false, false, false},
    71  		//{"test/dir",true,false,true},
    72  		{"test/dir-no", false, false, false},
    73  		{"testx", false, false, false},
    74  	}
    75  
    76  	for _, c := range cases {
    77  		exist, isfile, err := PathExists(c.path)
    78  		require.True(t, (err == nil) == c.noerr)
    79  		require.True(t, exist == c.exist)
    80  		require.True(t, isfile == c.isfile)
    81  	}
    82  }
    83  
    84  func Test_MinMax(t *testing.T) {
    85  	cvey.Convey("min", t, func() {
    86  		cvey.So(Min(10, 9), cvey.ShouldEqual, 9)
    87  		cvey.So(Min(9, 10), cvey.ShouldEqual, 9)
    88  	})
    89  
    90  	cvey.Convey("max", t, func() {
    91  		cvey.So(Max(10, 9), cvey.ShouldEqual, 10)
    92  		cvey.So(Max(9, 10), cvey.ShouldEqual, 10)
    93  	})
    94  }
    95  
    96  func Test_routineid(t *testing.T) {
    97  	cvey.Convey("rtid", t, func() {
    98  		x := GetRoutineId()
    99  		cvey.So(x, cvey.ShouldBeGreaterThanOrEqualTo, 0)
   100  	})
   101  }
   102  
   103  func Test_timeout(t *testing.T) {
   104  	cvey.Convey("timeout", t, func() {
   105  		to := NewTimeout(5*time.Second, true)
   106  		to.UpdateTime(time.Now())
   107  		cvey.So(to.isTimeout(), cvey.ShouldBeFalse)
   108  	})
   109  }
   110  
   111  func Test_substringFromBegin(t *testing.T) {
   112  	cvey.Convey("ssfb", t, func() {
   113  		cvey.So(SubStringFromBegin("abcdef", 3), cvey.ShouldEqual, "abc...")
   114  	})
   115  }
   116  
   117  func TestWildcardMatch(t *testing.T) {
   118  	//sort by string
   119  
   120  	patterns := []string{
   121  		"%",
   122  		"%%%%%%%%a%%%%%%%%b%%%%%%%%b%%%%%%%%",
   123  		"%%%%%%%%a%%%%%%%%b%%%%%%%%c%%%%%%%%",
   124  		"%%%a%b%c%%%",
   125  		"%.%",
   126  		"%.zi%",
   127  		"%.zi_",
   128  		"%.zip",
   129  		"%12%12%",
   130  		"%12%23",
   131  		"%Abac%",
   132  		"%SIP%",
   133  		"%_",
   134  		"%_%_%",
   135  		"%_%_%.zip",
   136  		"%_%_.zip",
   137  		"%_.zip",
   138  		"%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%",
   139  		"%a%b%ba%ca%a%aa%aaa%fa%ga%b%",
   140  		"%a%b%ba%ca%a%x%aaa%fa%ga%b%",
   141  		"%a%b%ba%ca%aaaa%fa%ga%ggg%b%",
   142  		"%a%b%ba%ca%aaaa%fa%ga%gggg%b%",
   143  		"%aa%",
   144  		"%aa_",
   145  		"%aabbaa%a%",
   146  		"%ab%cd%",
   147  		"%abac%",
   148  		"%ccd",
   149  		"%issip%PI",
   150  		"%issip%ss%",
   151  		"%oWn%",
   152  		"%sip%",
   153  		"%zi%",
   154  		"%zi_",
   155  		"%zip",
   156  		"._",
   157  		"XY%Z%XYz",
   158  		"_",
   159  		"_%",
   160  		"_%%_%&_",
   161  		"_%%_%_",
   162  		"_%%_c_",
   163  		"_%%_d_",
   164  		"_%._%",
   165  		"_%_",
   166  		"_%_.zip",
   167  		"_%b%_%d%_",
   168  		"_.",
   169  		"_._",
   170  		"_.zip",
   171  		"_LaH",
   172  		"_Lah",
   173  		"__",
   174  		"_a",
   175  		"_a%__",
   176  		"_a_",
   177  		"_aa%",
   178  		"_b%__",
   179  		"a%",
   180  		"a%_%_",
   181  		"a%_%_%.zip",
   182  		"a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%",
   183  		"a%a%a%a%a%a%aa%aaa%a%a%b",
   184  		"a%aar",
   185  		"a%b",
   186  		"a%zz%",
   187  		"a12b",
   188  		"a_",
   189  		"ab%_%xy",
   190  		"ab%cd%xy",
   191  		"abc",
   192  		"abc%abc%abc%abc%abc",
   193  		"abc%abc%abc%abc%abc%abc%abc%abc%abc%abc%abc%abc%",
   194  		"abc%abc%abc%abc%abc%abc%abc%abc%abc%abc%abc%abc%abc%abc%abc%abc%abc%",
   195  		"abc%abc%abc%abc%abc%abc%abc%abc%abc%abc%abcd",
   196  		"bL_h",
   197  		"bLaH",
   198  		"bLa_",
   199  		"bLah",
   200  		"mi%Sip%",
   201  		"mi%sip%",
   202  		"xxx%zzy%f",
   203  		"xxxx%zzy%f",
   204  		"xxxx%zzy%fffff",
   205  		"xy%xyz",
   206  		"xy%z%xyz",
   207  	}
   208  
   209  	targets := []string{
   210  		"%",
   211  		"%%%%%%%%a%%%%%%%%b%%%%%%%%c%%%%%%%%",
   212  		"%abc%",
   213  		".a",
   214  		".a.",
   215  		".a.a",
   216  		".a.aa",
   217  		".a.b",
   218  		".a.bcd",
   219  		".aa.",
   220  		".ab",
   221  		".ab.ab.ab.cd.cd.",
   222  		".ab.cd.ab.cd.abcd.",
   223  		".axb.cxd.ab.cd.abcd.",
   224  		".axb.cxd.ab.cd.abcd.xy",
   225  		".axb.cyd.ab.cyd.axbcd.",
   226  		".zip",
   227  		"A12b12",
   228  		"XYXYXYZYXYz",
   229  		"a",
   230  		"a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%",
   231  		"a%abab",
   232  		"a%ar",
   233  		"a%r",
   234  		"a.",
   235  		"a.a",
   236  		"a.a.zip",
   237  		"a.a.zippo",
   238  		"a.ab.ab.ab.cd.cd.xy",
   239  		"a.b",
   240  		"a.bcd",
   241  		"a.zip",
   242  		"a12B12",
   243  		"a12b12",
   244  		"aAazz",
   245  		"aa",
   246  		"aa.",
   247  		"aa.a",
   248  		"aa.ba.ba",
   249  		"aaa",
   250  		"aaaa.zip",
   251  		"aaaaaaaaaaaaaaaa",
   252  		"aaaaaaaaaaaaaaaaa",
   253  		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab",
   254  		"aaabbaabbaab",
   255  		"aaazz",
   256  		"aannn",
   257  		"ab",
   258  		"ab.",
   259  		"ab.ab.cd.ab.cd.abcdxy.",
   260  		"ab.axb.cd.xyab.cyd.axbcd.",
   261  		"ab.axb.cd.xyab.cyd.axbcd.xy",
   262  		"ab.xy",
   263  		"abAbac",
   264  		"abababababababababababababababababababaacacacacacacacadaeafagahaiajakalaaaaaaaaaaaaaaaaaffafagaagggagaaaaaaaab",
   265  		"ababac",
   266  		"abanabnabncd",
   267  		"abanabnabncdef",
   268  		"abancda.bnxyabncdefxy",
   269  		"abancdabnxyabncdef",
   270  		"abancdabnxyabncdefxy",
   271  		"abc",
   272  		"abc%abcd%abcd%abc%abcd",
   273  		"abc%abcd%abcd%abc%abcd%abcd%abc%abcd%abc%abc%abcd",
   274  		"abc%abcd%abcde%abcdef%abcdefg%abcdefgh%abcdefghi%abcdefghij%abcdefghijk%abcdefghijkl%abcdefghijklm%abcdefghijklmn",
   275  		"abcccd",
   276  		"abcd",
   277  		"abcde",
   278  		"abcdx_y",
   279  		"abxy",
   280  		"ax",
   281  		"bLaH",
   282  		"bLaaa",
   283  		"bLah",
   284  		"baa.",
   285  		"caa.ba.ba",
   286  		"miSsissippi",
   287  		"missisSIPpi",
   288  		"mississipPI",
   289  		"mississipissippi",
   290  		"mississippi",
   291  		"oWn",
   292  		"xa",
   293  		"xaab",
   294  		"xab",
   295  		"xab_anabnabncd_xy",
   296  		"xxa",
   297  		"xxab",
   298  		"xxxx%zzzzzzzzy%f",
   299  		"xxxxzzzzzzzzyf",
   300  		"xyxyxyxyz",
   301  		"xyxyxyzyxyz",
   302  		"xyz.bcd",
   303  		"zip"}
   304  
   305  	want := map[int][]int{
   306  		0:  {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93},
   307  		1:  {11, 12, 13, 14, 15, 21, 28, 38, 44, 49, 50, 51, 53, 54, 55, 56, 57, 58, 59, 60, 62, 63, 64, 75, 85},
   308  		2:  {1, 2, 8, 11, 12, 13, 14, 15, 28, 30, 49, 50, 51, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 85},
   309  		3:  {1, 2, 8, 11, 12, 13, 14, 15, 28, 30, 49, 50, 51, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 85},
   310  		4:  {3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 24, 25, 26, 27, 28, 29, 30, 31, 36, 37, 38, 40, 48, 49, 50, 51, 52, 58, 74, 75, 92},
   311  		5:  {16, 26, 27, 31, 40},
   312  		6:  {16, 26, 31, 40},
   313  		7:  {16, 26, 31, 40},
   314  		8:  {17, 32, 33},
   315  		9:  {},
   316  		10: {53},
   317  		11: {77},
   318  		12: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93},
   319  		13: {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93},
   320  		14: {26, 40},
   321  		15: {26, 40},
   322  		16: {26, 31, 40},
   323  		17: {20, 42, 43, 54},
   324  		18: {54},
   325  		19: {},
   326  		20: {54},
   327  		21: {},
   328  		22: {6, 9, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 54, 72, 74, 75, 83},
   329  		23: {9, 36, 39, 41, 42, 43, 44, 54, 72, 74, 83},
   330  		24: {44},
   331  		25: {11, 12, 13, 14, 15, 28, 49, 50, 51, 56, 57, 58, 59, 60, 62, 63, 64, 65, 66, 67, 68, 85},
   332  		26: {55},
   333  		27: {65},
   334  		28: {78},
   335  		29: {79},
   336  		30: {81},
   337  		31: {76, 78, 79, 80},
   338  		32: {16, 26, 27, 31, 40, 93},
   339  		33: {16, 26, 31, 40, 93},
   340  		34: {16, 26, 31, 40, 93},
   341  		35: {3},
   342  		36: {18},
   343  		37: {0, 19},
   344  		38: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93},
   345  		39: {},
   346  		40: {1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 22, 23, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93},
   347  		41: {2, 8, 30, 56, 62, 63, 65, 66, 92},
   348  		42: {11, 12, 13, 15, 50, 67},
   349  		43: {5, 6, 7, 8, 11, 12, 13, 14, 15, 25, 26, 27, 28, 29, 30, 31, 37, 38, 40, 49, 50, 51, 52, 58, 75, 92},
   350  		44: {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93},
   351  		45: {26, 40},
   352  		46: {11, 12, 13, 14, 15, 28, 49, 50, 51, 54, 57, 58, 59, 60, 62, 63, 64, 67, 68, 85},
   353  		47: {24},
   354  		48: {25, 29},
   355  		49: {31},
   356  		50: {71},
   357  		51: {73},
   358  		52: {3, 24, 35, 47, 70, 82},
   359  		53: {3, 35, 82},
   360  		54: {2, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 37, 38, 40, 41, 42, 43, 44, 45, 46, 74, 75, 83, 85},
   361  		55: {4, 10, 36, 39, 84},
   362  		56: {9, 39, 40, 41, 42, 43, 44, 45, 74, 75, 83},
   363  		57: {49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 62, 63, 64, 65, 66, 67, 68, 69},
   364  		58: {19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70},
   365  		59: {20, 21, 22, 23, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69},
   366  		60: {26, 40},
   367  		61: {20, 42, 43, 54},
   368  		62: {43, 54},
   369  		63: {},
   370  		64: {21, 29, 43, 44, 47, 54},
   371  		65: {34, 45},
   372  		66: {},
   373  		67: {24, 35, 47, 70},
   374  		68: {51, 52, 58, 60},
   375  		69: {51, 58, 60},
   376  		70: {61},
   377  		71: {},
   378  		72: {64},
   379  		73: {},
   380  		74: {63},
   381  		75: {73},
   382  		76: {71},
   383  		77: {71, 73},
   384  		78: {73},
   385  		79: {},
   386  		80: {76, 78, 79, 80},
   387  		81: {88, 89},
   388  		82: {88, 89},
   389  		83: {},
   390  		84: {90, 91},
   391  		85: {91},
   392  	}
   393  
   394  	cvey.Convey("", t, func() {
   395  		for i := 0; i < len(patterns); i++ {
   396  			for j := 0; j < len(targets); j++ {
   397  
   398  				//fmt.Println(pat[i], str[j])
   399  				ret := WildcardMatch(patterns[i], targets[j])
   400  				resArr := want[i]
   401  				idx := sort.SearchInts(resArr, j)
   402  				if idx >= len(resArr) || resArr[idx] != j {
   403  					cvey.So(ret, cvey.ShouldBeFalse)
   404  				} else {
   405  					cvey.So(ret, cvey.ShouldBeTrue)
   406  				}
   407  			}
   408  		}
   409  	})
   410  }
   411  
   412  func TestGetSimpleExprValue(t *testing.T) {
   413  	ctx := context.TODO()
   414  	cvey.Convey("", t, func() {
   415  		type args struct {
   416  			sql     string
   417  			wantErr bool
   418  			want    interface{}
   419  		}
   420  
   421  		kases := []args{
   422  			{"set @@x=1", false, 1},
   423  			{"set @@x=-1", false, -1},
   424  			{fmt.Sprintf("set @@x=%d", math.MaxInt64), false, math.MaxInt64},
   425  			{fmt.Sprintf("set @@x=%d", -math.MaxInt64), false, -math.MaxInt64},
   426  			{"set @@x=true", false, true},
   427  			{"set @@x=false", false, false},
   428  			{"set @@x=on", false, "on"},
   429  			{"set @@x=off", false, "off"},
   430  			{"set @@x=abc", false, "abc"},
   431  			{"set @@x=null", false, nil},
   432  			{"set @@x=-null", false, nil},
   433  			{"set @@x=-x", true, nil},
   434  		}
   435  		ctrl := gomock.NewController(t)
   436  		ses := newTestSession(t, ctrl)
   437  		//ses := NewSession(&FakeProtocol{}, testutil.NewProc().Mp(), config.NewParameterUnit(nil, mock_frontend.NewMockEngine(ctrl), mock_frontend.NewMockTxnClient(ctrl), nil), GSysVariables, false, nil, nil)
   438  		ec := newTestExecCtx(ctx, ctrl)
   439  		ec.proc = testutil.NewProc()
   440  		ec.ses = ses
   441  		ses.txnCompileCtx.execCtx = ec
   442  		for _, kase := range kases {
   443  			stmt, err := parsers.ParseOne(ctx, dialect.MYSQL, kase.sql, 1, 0)
   444  			cvey.So(err, cvey.ShouldBeNil)
   445  
   446  			sv, ok := stmt.(*tree.SetVar)
   447  			cvey.So(ok, cvey.ShouldBeTrue)
   448  			value, err := GetSimpleExprValue(ctx, sv.Assignments[0].Value, ses)
   449  			if kase.wantErr {
   450  				cvey.So(err, cvey.ShouldNotBeNil)
   451  			} else {
   452  				cvey.So(err, cvey.ShouldBeNil)
   453  				cvey.So(value, cvey.ShouldEqual, kase.want)
   454  			}
   455  		}
   456  
   457  	})
   458  
   459  	cvey.Convey("", t, func() {
   460  		type args struct {
   461  			sql     string
   462  			wantErr bool
   463  			want    interface{}
   464  		}
   465  
   466  		dec1, _, _ := types.Parse64("1.0")
   467  		dec2, _, _ := types.Parse64("-1.0")
   468  		dec3, _, _ := types.Parse64("-1.2345670")
   469  
   470  		kases := []args{
   471  			{"set @@x=1.0", false, fmt.Sprintf("%v", dec1.Format(1))},
   472  			{"set @@x=-1.0", false, fmt.Sprintf("%v", dec2.Format(1))},
   473  			{"set @@x=-1.2345670", false, fmt.Sprintf("%v", dec3.Format(7))},
   474  		}
   475  		ctrl := gomock.NewController(t)
   476  		ses := newTestSession(t, ctrl)
   477  		//ses := NewSession(&FakeProtocol{}, testutil.NewProc().Mp(), config.NewParameterUnit(nil, mock_frontend.NewMockEngine(ctrl), mock_frontend.NewMockTxnClient(ctrl), nil), GSysVariables, false, nil, nil)
   478  		ec := newTestExecCtx(ctx, ctrl)
   479  		ec.proc = testutil.NewProc()
   480  		ec.ses = ses
   481  		ses.txnCompileCtx.execCtx = ec
   482  		for _, kase := range kases {
   483  			stmt, err := parsers.ParseOne(ctx, dialect.MYSQL, kase.sql, 1, 0)
   484  			cvey.So(err, cvey.ShouldBeNil)
   485  
   486  			sv, ok := stmt.(*tree.SetVar)
   487  			cvey.So(ok, cvey.ShouldBeTrue)
   488  			value, err := GetSimpleExprValue(ctx, sv.Assignments[0].Value, ses)
   489  			if kase.wantErr {
   490  				cvey.So(err, cvey.ShouldNotBeNil)
   491  			} else {
   492  				cvey.So(err, cvey.ShouldBeNil)
   493  				cvey.So(value, cvey.ShouldResemble, kase.want)
   494  			}
   495  		}
   496  
   497  	})
   498  }
   499  
   500  func TestGetExprValue(t *testing.T) {
   501  	ctx := defines.AttachAccountId(context.TODO(), sysAccountID)
   502  	cvey.Convey("", t, func() {
   503  		type args struct {
   504  			sql     string
   505  			wantErr bool
   506  			want    interface{}
   507  		}
   508  
   509  		// dec1280, _, err := types.Parse128("-9223372036854775808")
   510  		// assert.NoError(t, err)
   511  
   512  		// dec1281, _, err := types.Parse128("99999999999999999999999999999999999999")
   513  		// assert.NoError(t, err)
   514  
   515  		// dec1282, _, err := types.Parse128("-99999999999999999999999999999999999999")
   516  		// assert.NoError(t, err)
   517  
   518  		// dec1283, _, err := types.Parse128("9223372036854775807")
   519  		// assert.NoError(t, err)
   520  
   521  		kases := []args{
   522  			{"set @@x=1", false, 1},
   523  			{"set @@x=-1", false, -1},
   524  			{fmt.Sprintf("set @@x=%d", math.MaxInt64), false, math.MaxInt64},
   525  			{fmt.Sprintf("set @@x=%d", -math.MaxInt64), false, -math.MaxInt64},
   526  			{"set @@x=true", false, true},
   527  			{"set @@x=false", false, false},
   528  			{"set @@x=on", false, "on"},
   529  			{"set @@x=off", false, "off"},
   530  			{"set @@x=abc", false, "abc"},
   531  			{"set @@x=null", false, nil},
   532  			{"set @@x=-null", false, nil},
   533  			{"set @@x=-x", true, nil},
   534  			{"set @@x=(select -t.b from t)", true, nil},
   535  			{"set @@x=(select 1)", false, 1},
   536  			{"set @@x=(select -1)", false, -1},
   537  			{fmt.Sprintf("set @@x=(select %d)", math.MaxInt64), false, math.MaxInt64},
   538  			{fmt.Sprintf("set @@x=(select %d)", -math.MaxInt64), false, -math.MaxInt64},
   539  			{"set @@x=(select true)", false, true},
   540  			{"set @@x=(select false)", false, false},
   541  			{"set @@x=(select 'on')", false, "on"},
   542  			{"set @@x=(select 'off')", false, "off"},
   543  			{"set @@x=(select 'abc')", false, "abc"},
   544  			{"set @@x=(select null)", false, nil},
   545  			{"set @@x=(select -null)", false, nil},
   546  			{"set @@x=(select true != false)", false, true},
   547  			{"set @@x=(select true = false)", false, false},
   548  			{"set @@x=(" +
   549  				"select true = (" +
   550  				"				select 1 = (select 0 + (" +
   551  				"											select (select 1 + (select 2 - 0))" +
   552  				"										)" +
   553  				"							)" +
   554  				"				)" +
   555  				")", false, false},
   556  			{"set @@x=(" +
   557  				"			(select (3 < 4))" +
   558  				" = " +
   559  				"			(select (1 > 4))" +
   560  				"		)", false, false},
   561  			{"set @@x=(select 127)", false, 127},
   562  			{"set @@x=(select -128)", false, -128},
   563  			{"set @@x=(select -2147483648)", false, -2147483648},
   564  			{"set @@x=(select -9223372036854775808)", false, "-9223372036854775808"},
   565  			{"set @@x=(select 18446744073709551615)", false, uint64(math.MaxUint64)},
   566  			{"set @@x=(select 1.1754943508222875e-38)", false, float32(1.1754943508222875e-38)},
   567  			{"set @@x=(select 3.4028234663852886e+38)", false, float32(3.4028234663852886e+38)},
   568  			{"set @@x=(select  2.2250738585072014e-308)", false, float64(2.2250738585072014e-308)},
   569  			{"set @@x=(select  1.7976931348623157e+308)", false, float64(1.7976931348623157e+308)},
   570  			{"set @@x=(select cast(9223372036854775807 as decimal))", false, "9223372036854775807"},
   571  			{"set @@x=(select cast(99999999999999999999999999999999999999 as decimal))", false, "99999999999999999999999999999999999999"},
   572  			{"set @@x=(select cast(-99999999999999999999999999999999999999 as decimal))", false, "-99999999999999999999999999999999999999"},
   573  			{"set @@x=(select cast('{\"a\":1,\"b\":2}' as json))", false, "{\"a\": 1, \"b\": 2}"},
   574  			{"set @@x=(select cast('00000000-0000-0000-0000-000000000000' as uuid))", false, "00000000-0000-0000-0000-000000000000"},
   575  			{"set @@x=(select cast('00:00:00' as time))", false, "00:00:00"},
   576  			{"set @@x=(select cast('1000-01-01 00:00:00' as datetime))", false, "1000-01-01 00:00:00"},
   577  			{"set @@x=(select cast('1970-01-01 00:00:00' as timestamp))", false, "1970-01-01 00:00:00"},
   578  			{"set @@x=(select 1 into outfile './test.csv')", false, 1}, //!!!NOTE: there is no file './test.csv'.
   579  			{"set @@x=(((select true = false)))", false, false},
   580  		}
   581  		ctrl := gomock.NewController(t)
   582  		defer ctrl.Finish()
   583  
   584  		eng := mock_frontend.NewMockEngine(ctrl)
   585  		eng.EXPECT().New(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
   586  		db := mock_frontend.NewMockDatabase(ctrl)
   587  		db.EXPECT().Relations(ctx).Return([]string{"t"}, nil).AnyTimes()
   588  		db.EXPECT().IsSubscription(gomock.Any()).Return(false).AnyTimes()
   589  
   590  		table := mock_frontend.NewMockRelation(ctrl)
   591  		table.EXPECT().GetTableID(gomock.Any()).Return(uint64(0xABC)).AnyTimes()
   592  		db.EXPECT().Relation(gomock.Any(), "t", nil).Return(table, moerr.NewInternalErrorNoCtx("no such table")).AnyTimes()
   593  		defs := []engine.TableDef{
   594  			&engine.AttributeDef{Attr: engine.Attribute{Name: "a", Type: types.T_char.ToType()}},
   595  			&engine.AttributeDef{Attr: engine.Attribute{Name: "b", Type: types.T_int32.ToType()}},
   596  		}
   597  
   598  		table.EXPECT().TableDefs(gomock.Any()).Return(defs, nil).AnyTimes()
   599  		table.EXPECT().GetEngineType().Return(engine.Disttae).AnyTimes()
   600  
   601  		var ranges memoryengine.ShardIdSlice
   602  		id := make([]byte, 8)
   603  		binary.LittleEndian.PutUint64(id, 1)
   604  		ranges.Append(id)
   605  
   606  		table.EXPECT().Ranges(gomock.Any(), gomock.Any()).Return(&ranges, nil).AnyTimes()
   607  		table.EXPECT().NewReader(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, moerr.NewInvalidInputNoCtx("new reader failed")).AnyTimes()
   608  
   609  		eng.EXPECT().Database(gomock.Any(), gomock.Any(), gomock.Any()).Return(db, nil).AnyTimes()
   610  		eng.EXPECT().Hints().Return(engine.Hints{
   611  			CommitOrRollbackTimeout: time.Second,
   612  		}).AnyTimes()
   613  		eng.EXPECT().Nodes(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil).AnyTimes()
   614  
   615  		ws := mock_frontend.NewMockWorkspace(ctrl)
   616  		ws.EXPECT().IncrStatementID(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
   617  		ws.EXPECT().IncrSQLCount().AnyTimes()
   618  		ws.EXPECT().GetSQLCount().AnyTimes()
   619  		ws.EXPECT().StartStatement().AnyTimes()
   620  		ws.EXPECT().EndStatement().AnyTimes()
   621  		ws.EXPECT().GetSnapshotWriteOffset().Return(0).AnyTimes()
   622  		ws.EXPECT().UpdateSnapshotWriteOffset().AnyTimes()
   623  		ws.EXPECT().Adjust(gomock.Any()).AnyTimes()
   624  		ws.EXPECT().CloneSnapshotWS().AnyTimes()
   625  		ws.EXPECT().BindTxnOp(gomock.Any()).AnyTimes()
   626  
   627  		txnOperator := mock_frontend.NewMockTxnOperator(ctrl)
   628  		txnOperator.EXPECT().Commit(gomock.Any()).Return(nil).AnyTimes()
   629  		txnOperator.EXPECT().Rollback(gomock.Any()).Return(nil).AnyTimes()
   630  		txnOperator.EXPECT().GetWorkspace().Return(ws).AnyTimes()
   631  		txnOperator.EXPECT().Txn().Return(txn.TxnMeta{}).AnyTimes()
   632  		txnOperator.EXPECT().ResetRetry(gomock.Any()).AnyTimes()
   633  		txnOperator.EXPECT().TxnOptions().Return(txn.TxnOptions{}).AnyTimes()
   634  		txnOperator.EXPECT().NextSequence().Return(uint64(0)).AnyTimes()
   635  		txnOperator.EXPECT().EnterRunSql().Return().AnyTimes()
   636  		txnOperator.EXPECT().ExitRunSql().Return().AnyTimes()
   637  		txnOperator.EXPECT().GetWaitActiveCost().Return(time.Duration(0)).AnyTimes()
   638  		txnClient := mock_frontend.NewMockTxnClient(ctrl)
   639  		txnClient.EXPECT().New(gomock.Any(), gomock.Any(), gomock.Any()).Return(txnOperator, nil).AnyTimes()
   640  
   641  		sv := &config.FrontendParameters{
   642  			SessionTimeout: toml.Duration{Duration: 10 * time.Second},
   643  		}
   644  
   645  		pu := config.NewParameterUnit(sv, eng, txnClient, nil)
   646  		setGlobalPu(pu)
   647  		ses := NewSession(ctx, &FakeProtocol{}, testutil.NewProc().Mp(), GSysVariables, true, nil)
   648  		ses.SetDatabaseName("db")
   649  		var c clock.Clock
   650  		err := ses.GetTxnHandler().CreateTempStorage(c)
   651  		assert.Nil(t, err)
   652  		ec := newTestExecCtx(ctx, ctrl)
   653  		ec.proc = testutil.NewProc()
   654  		ec.ses = ses
   655  		ses.txnCompileCtx.execCtx = ec
   656  		for _, kase := range kases {
   657  			fmt.Println("++++>", kase.sql)
   658  			stmt, err := parsers.ParseOne(ctx, dialect.MYSQL, kase.sql, 1, 0)
   659  			cvey.So(err, cvey.ShouldBeNil)
   660  
   661  			sv, ok := stmt.(*tree.SetVar)
   662  			cvey.So(ok, cvey.ShouldBeTrue)
   663  			value, err := getExprValue(sv.Assignments[0].Value, ses, ec)
   664  			if kase.wantErr {
   665  				cvey.So(err, cvey.ShouldNotBeNil)
   666  			} else {
   667  				cvey.So(err, cvey.ShouldBeNil)
   668  				switch ret := value.(type) {
   669  				case *plan.Expr:
   670  					if types.T(ret.GetTyp().Id) == types.T_decimal64 {
   671  						cvey.So(ret.GetLit().GetDecimal64Val().GetA(), cvey.ShouldEqual, kase.want)
   672  					} else if types.T(ret.GetTyp().Id) == types.T_decimal128 {
   673  						temp := kase.want.(types.Decimal128)
   674  						cvey.So(uint64(ret.GetLit().GetDecimal128Val().GetA()), cvey.ShouldEqual, temp.B0_63)
   675  						cvey.So(uint64(ret.GetLit().GetDecimal128Val().GetB()), cvey.ShouldEqual, temp.B64_127)
   676  					} else {
   677  						panic(fmt.Sprintf("unknown expr type %v", ret.GetTyp()))
   678  					}
   679  				default:
   680  					cvey.So(value, cvey.ShouldEqual, kase.want)
   681  				}
   682  			}
   683  		}
   684  
   685  	})
   686  
   687  	cvey.Convey("", t, func() {
   688  		type args struct {
   689  			sql     string
   690  			wantErr bool
   691  			want    interface{}
   692  		}
   693  
   694  		// dec1, _, _ := types.Parse64("1.0")
   695  		// dec2, _, _ := types.Parse64("-1.0")
   696  		// dec3, _, _ := types.Parse64("-1.2345670")
   697  
   698  		kases := []args{
   699  			{"set @@x=1.0", false, "1.0"},
   700  			{"set @@x=-1.0", false, "-1.0"},
   701  			{"set @@x=-1.2345670", false, "-1.2345670"},
   702  		}
   703  		ctrl := gomock.NewController(t)
   704  		defer ctrl.Finish()
   705  
   706  		eng := mock_frontend.NewMockEngine(ctrl)
   707  		eng.EXPECT().New(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
   708  		db := mock_frontend.NewMockDatabase(ctrl)
   709  		db.EXPECT().Relations(ctx).Return([]string{"t"}, nil).AnyTimes()
   710  
   711  		table := mock_frontend.NewMockRelation(ctrl)
   712  		db.EXPECT().Relation(ctx, "t", nil).Return(table, nil).AnyTimes()
   713  		defs := []engine.TableDef{
   714  			&engine.AttributeDef{Attr: engine.Attribute{Name: "a", Type: types.T_char.ToType()}},
   715  			&engine.AttributeDef{Attr: engine.Attribute{Name: "b", Type: types.T_int32.ToType()}},
   716  		}
   717  
   718  		table.EXPECT().TableDefs(ctx).Return(defs, nil).AnyTimes()
   719  		eng.EXPECT().Database(ctx, gomock.Any(), nil).Return(db, nil).AnyTimes()
   720  		eng.EXPECT().Hints().Return(engine.Hints{
   721  			CommitOrRollbackTimeout: time.Second,
   722  		}).AnyTimes()
   723  		eng.EXPECT().Nodes(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil).AnyTimes()
   724  
   725  		ws := mock_frontend.NewMockWorkspace(ctrl)
   726  		ws.EXPECT().IncrStatementID(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
   727  		ws.EXPECT().StartStatement().AnyTimes()
   728  		ws.EXPECT().EndStatement().AnyTimes()
   729  		ws.EXPECT().GetSnapshotWriteOffset().Return(0).AnyTimes()
   730  		ws.EXPECT().UpdateSnapshotWriteOffset().AnyTimes()
   731  		ws.EXPECT().Adjust(uint64(0)).AnyTimes()
   732  		ws.EXPECT().IncrSQLCount().AnyTimes()
   733  		ws.EXPECT().GetSQLCount().AnyTimes()
   734  		ws.EXPECT().CloneSnapshotWS().AnyTimes()
   735  		ws.EXPECT().BindTxnOp(gomock.Any()).AnyTimes()
   736  
   737  		txnOperator := mock_frontend.NewMockTxnOperator(ctrl)
   738  		txnOperator.EXPECT().Commit(gomock.Any()).Return(nil).AnyTimes()
   739  		txnOperator.EXPECT().Rollback(gomock.Any()).Return(nil).AnyTimes()
   740  		txnOperator.EXPECT().GetWorkspace().Return(ws).AnyTimes()
   741  		txnOperator.EXPECT().Txn().Return(txn.TxnMeta{}).AnyTimes()
   742  		txnOperator.EXPECT().ResetRetry(gomock.Any()).AnyTimes()
   743  		txnOperator.EXPECT().TxnOptions().Return(txn.TxnOptions{}).AnyTimes()
   744  		txnOperator.EXPECT().NextSequence().Return(uint64(0)).AnyTimes()
   745  		txnOperator.EXPECT().EnterRunSql().Return().AnyTimes()
   746  		txnOperator.EXPECT().ExitRunSql().Return().AnyTimes()
   747  		txnOperator.EXPECT().GetWaitActiveCost().Return(time.Duration(0)).AnyTimes()
   748  		txnClient := mock_frontend.NewMockTxnClient(ctrl)
   749  		txnClient.EXPECT().New(gomock.Any(), gomock.Any(), gomock.Any()).Return(txnOperator, nil).AnyTimes()
   750  
   751  		sv := &config.FrontendParameters{
   752  			SessionTimeout: toml.Duration{Duration: 5 * time.Minute},
   753  		}
   754  
   755  		pu := config.NewParameterUnit(sv, eng, txnClient, nil)
   756  		setGlobalPu(pu)
   757  		ses := NewSession(ctx, &FakeProtocol{}, testutil.NewProc().Mp(), GSysVariables, true, nil)
   758  		var c clock.Clock
   759  		err := ses.GetTxnHandler().CreateTempStorage(c)
   760  		assert.Nil(t, err)
   761  		ec := newTestExecCtx(ctx, ctrl)
   762  		ec.reqCtx = ctx
   763  		ses.txnCompileCtx.execCtx = ec
   764  		for _, kase := range kases {
   765  			stmt, err := parsers.ParseOne(ctx, dialect.MYSQL, kase.sql, 1, 0)
   766  			cvey.So(err, cvey.ShouldBeNil)
   767  
   768  			sv, ok := stmt.(*tree.SetVar)
   769  			cvey.So(ok, cvey.ShouldBeTrue)
   770  			value, err := getExprValue(sv.Assignments[0].Value, ses, ec)
   771  			if kase.wantErr {
   772  				cvey.So(err, cvey.ShouldNotBeNil)
   773  			} else {
   774  				cvey.So(err, cvey.ShouldBeNil)
   775  				cvey.So(value, cvey.ShouldResemble, kase.want)
   776  			}
   777  		}
   778  
   779  	})
   780  }
   781  
   782  var _ error = &testError{}
   783  
   784  type testError struct {
   785  	s string
   786  }
   787  
   788  func (t testError) Error() string {
   789  	return t.s
   790  }
   791  
   792  func TestRewriteError(t *testing.T) {
   793  	type args struct {
   794  		err      error
   795  		username string
   796  	}
   797  
   798  	tests := []struct {
   799  		name  string
   800  		args  args
   801  		want  uint16
   802  		want1 string
   803  		want2 string
   804  	}{
   805  		{
   806  			name: "t1",
   807  			args: args{
   808  				err: &testError{s: "non moerr"},
   809  			},
   810  			want:  moerr.ER_INTERNAL_ERROR,
   811  			want1: "HY000",
   812  			want2: "non moerr",
   813  		},
   814  		{
   815  			name:  "t2",
   816  			args:  args{},
   817  			want:  moerr.ER_INTERNAL_ERROR,
   818  			want1: "",
   819  			want2: "",
   820  		},
   821  		{
   822  			name: "t3",
   823  			args: args{
   824  				err:      moerr.NewInternalErrorNoCtx("check password failed"),
   825  				username: "abc",
   826  			},
   827  			want:  moerr.ER_ACCESS_DENIED_ERROR,
   828  			want1: "28000",
   829  			want2: "Access denied for user abc. internal error: check password failed",
   830  		},
   831  		{
   832  			name: "t4",
   833  			args: args{
   834  				err:      moerr.NewInternalErrorNoCtx("suspended"),
   835  				username: "abc",
   836  			},
   837  			want:  moerr.ER_ACCESS_DENIED_ERROR,
   838  			want1: "28000",
   839  			want2: "Access denied for user abc. internal error: suspended",
   840  		},
   841  		{
   842  			name: "t5",
   843  			args: args{
   844  				err:      moerr.NewInternalErrorNoCtx("suspended"),
   845  				username: "abc",
   846  			},
   847  			want:  moerr.ER_ACCESS_DENIED_ERROR,
   848  			want1: "28000",
   849  			want2: "Access denied for user abc. internal error: suspended",
   850  		},
   851  		{
   852  			name: "t6",
   853  			args: args{
   854  				err:      moerr.NewInternalErrorNoCtx("source address     is not authorized"),
   855  				username: "abc",
   856  			},
   857  			want:  moerr.ER_ACCESS_DENIED_ERROR,
   858  			want1: "28000",
   859  			want2: "Access denied for user abc. internal error: source address     is not authorized",
   860  		},
   861  		{
   862  			name: "t7",
   863  			args: args{
   864  				err:      moerr.NewInternalErrorNoCtx("xxxx"),
   865  				username: "abc",
   866  			},
   867  			want:  moerr.ErrInternal,
   868  			want1: "HY000",
   869  			want2: "internal error: xxxx",
   870  		},
   871  		{
   872  			name: "t8",
   873  			args: args{
   874  				err:      moerr.NewBadDBNoCtx("yyy"),
   875  				username: "abc",
   876  			},
   877  			want:  moerr.ER_BAD_DB_ERROR,
   878  			want1: "HY000",
   879  			want2: "invalid database yyy",
   880  		},
   881  	}
   882  	for _, tt := range tests {
   883  		t.Run(tt.name, func(t *testing.T) {
   884  			got, got1, got2 := RewriteError(tt.args.err, tt.args.username)
   885  			assert.Equalf(t, tt.want, got, "RewriteError(%v, %v)", tt.args.err, tt.args.username)
   886  			assert.Equalf(t, tt.want1, got1, "RewriteError(%v, %v)", tt.args.err, tt.args.username)
   887  			assert.Equalf(t, tt.want2, got2, "RewriteError(%v, %v)", tt.args.err, tt.args.username)
   888  		})
   889  	}
   890  }
   891  
   892  func Test_makeExecuteSql(t *testing.T) {
   893  	type args struct {
   894  		ses  *Session
   895  		stmt tree.Statement
   896  	}
   897  
   898  	ctrl := gomock.NewController(t)
   899  	defer ctrl.Finish()
   900  
   901  	eng := mock_frontend.NewMockEngine(ctrl)
   902  	eng.EXPECT().New(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
   903  
   904  	txnClient := mock_frontend.NewMockTxnClient(ctrl)
   905  
   906  	sv := &config.FrontendParameters{
   907  		SessionTimeout: toml.Duration{Duration: 5 * time.Minute},
   908  	}
   909  	ctx := context.TODO()
   910  	pu := config.NewParameterUnit(sv, eng, txnClient, nil)
   911  	setGlobalPu(pu)
   912  	ses1 := NewSession(ctx, &FakeProtocol{}, testutil.NewProc().Mp(), GSysVariables, true,
   913  		nil)
   914  
   915  	ses1.SetUserDefinedVar("var2", "val2", "set var2 = val2")
   916  	ses1.SetUserDefinedVar("var3", "val3", "set var3 = val3")
   917  	ses1.SetPrepareStmt(ctx, "st2", &PrepareStmt{
   918  		Name: "st2",
   919  		Sql:  "prepare st2 select * from t where a = ?",
   920  	})
   921  	ses1.SetPrepareStmt(ctx, "st3", &PrepareStmt{
   922  		Name: "st3",
   923  		Sql:  "prepare st3 select * from t where a = ? and b = ?",
   924  	})
   925  
   926  	mp, err := mpool.NewMPool("ut_pool", 0, mpool.NoFixed)
   927  	if err != nil {
   928  		assert.NoError(t, err)
   929  	}
   930  	defer mpool.DeleteMPool(mp)
   931  
   932  	testProc := process.New(context.Background(), mp, nil, nil, nil, nil, nil, nil, nil, nil)
   933  
   934  	params1 := testProc.GetVector(types.T_text.ToType())
   935  	for i := 0; i < 3; i++ {
   936  		err = vector.AppendBytes(params1, []byte{}, false, testProc.GetMPool())
   937  		assert.NoError(t, err)
   938  	}
   939  
   940  	util.SetAnyToStringVector(testProc, "aVal", params1, 0)
   941  	util.SetAnyToStringVector(testProc, "NULL", params1, 1)
   942  	util.SetAnyToStringVector(testProc, "bVal", params1, 2)
   943  
   944  	ses1.SetPrepareStmt(ctx, "st4", &PrepareStmt{
   945  		Name:   "st4",
   946  		Sql:    "prepare st4 select * from t where a = ? and b = ?",
   947  		params: params1,
   948  	})
   949  
   950  	ses1.SetPrepareStmt(ctx, "st5", nil)
   951  
   952  	tests := []struct {
   953  		name string
   954  		args args
   955  		want string
   956  	}{
   957  		{
   958  			name: "t1",
   959  			args: args{},
   960  			want: "",
   961  		},
   962  		{
   963  			name: "t2",
   964  			args: args{
   965  				ses:  &Session{},
   966  				stmt: &tree.SetVar{},
   967  			},
   968  			want: "",
   969  		},
   970  		{
   971  			name: "t3",
   972  			args: args{
   973  				ses: ses1,
   974  				stmt: &tree.Execute{
   975  					Name: "st1",
   976  				},
   977  			},
   978  			want: "",
   979  		},
   980  		{
   981  			name: "t4-no variables - no params",
   982  			args: args{
   983  				ses: ses1,
   984  				stmt: &tree.Execute{
   985  					Name: "st2",
   986  				},
   987  			},
   988  			want: "prepare st2 select * from t where a = ? ;",
   989  		},
   990  		{
   991  			name: "t5 - variables",
   992  			args: args{
   993  				ses: ses1,
   994  				stmt: &tree.Execute{
   995  					Name: "st3",
   996  					Variables: []*tree.VarExpr{
   997  						{
   998  							Name: "var2",
   999  						},
  1000  						{
  1001  							Name: "var-none",
  1002  						},
  1003  						{
  1004  							Name: "var3",
  1005  						},
  1006  					},
  1007  				},
  1008  			},
  1009  			want: "prepare st3 select * from t where a = ? and b = ? ; set var2 = val2 ;  ; set var3 = val3",
  1010  		},
  1011  		{
  1012  			name: "t6 - params",
  1013  			args: args{
  1014  				ses: ses1,
  1015  				stmt: &tree.Execute{
  1016  					Name: "st4",
  1017  				},
  1018  			},
  1019  			want: "prepare st4 select * from t where a = ? and b = ? ; aVal ; NULL ; bVal",
  1020  		},
  1021  		{
  1022  			name: "t7 - params is nil",
  1023  			args: args{
  1024  				ses: ses1,
  1025  				stmt: &tree.Execute{
  1026  					Name: "st5",
  1027  				},
  1028  			},
  1029  			want: "",
  1030  		},
  1031  	}
  1032  	for _, tt := range tests {
  1033  		t.Run(tt.name, func(t *testing.T) {
  1034  			if got := makeExecuteSql(ctx, tt.args.ses, tt.args.stmt); strings.TrimSpace(got) != strings.TrimSpace(tt.want) {
  1035  				t.Errorf("makeExecuteSql() = %v, want %v", got, tt.want)
  1036  			}
  1037  		})
  1038  	}
  1039  }
  1040  
  1041  func Test_getVariableValue(t *testing.T) {
  1042  	type args struct {
  1043  		varDefault interface{}
  1044  	}
  1045  	tests := []struct {
  1046  		name string
  1047  		args args
  1048  		want string
  1049  	}{
  1050  		{name: "0.1", args: args{varDefault: 0.1}, want: "0.100000"},
  1051  		{name: "0.000001", args: args{varDefault: 0.000001}, want: "0.000001"},
  1052  		{name: "0.0000009", args: args{varDefault: 0.0000009}, want: "9.000000e-07"},
  1053  		{name: "7.43e-14", args: args{varDefault: 7.43e-14}, want: "7.430000e-14"},
  1054  	}
  1055  	for _, tt := range tests {
  1056  		t.Run(tt.name, func(t *testing.T) {
  1057  			got := getVariableValue(tt.args.varDefault)
  1058  			assert.Equalf(t, tt.want, got, "getVariableValue(%v)", tt.args.varDefault)
  1059  		})
  1060  	}
  1061  }
  1062  
  1063  var _ error = &testErr{}
  1064  
  1065  type testErr struct {
  1066  }
  1067  
  1068  func (t testErr) Error() string {
  1069  	return "test"
  1070  }
  1071  
  1072  func Test_isErrorRollbackWholeTxn(t *testing.T) {
  1073  	assert.Equal(t, false, isErrorRollbackWholeTxn(nil))
  1074  	assert.Equal(t, false, isErrorRollbackWholeTxn(&testError{}))
  1075  	assert.Equal(t, true, isErrorRollbackWholeTxn(moerr.NewDeadLockDetectedNoCtx()))
  1076  	assert.Equal(t, true, isErrorRollbackWholeTxn(moerr.NewLockTableBindChangedNoCtx()))
  1077  	assert.Equal(t, true, isErrorRollbackWholeTxn(moerr.NewLockTableNotFoundNoCtx()))
  1078  	assert.Equal(t, true, isErrorRollbackWholeTxn(moerr.NewDeadlockCheckBusyNoCtx()))
  1079  	assert.Equal(t, true, isErrorRollbackWholeTxn(moerr.NewLockConflictNoCtx()))
  1080  }
  1081  
  1082  func TestUserInput_getSqlSourceType(t *testing.T) {
  1083  	type fields struct {
  1084  		sql           string
  1085  		stmt          tree.Statement
  1086  		sqlSourceType []string
  1087  	}
  1088  	type args struct {
  1089  		i int
  1090  	}
  1091  	tests := []struct {
  1092  		name   string
  1093  		fields fields
  1094  		args   args
  1095  		want   string
  1096  	}{
  1097  		{
  1098  			name: "t1",
  1099  			fields: fields{
  1100  				sql:           "select * from t1",
  1101  				sqlSourceType: nil,
  1102  			},
  1103  			args: args{
  1104  				i: 0,
  1105  			},
  1106  			want: "external_sql",
  1107  		},
  1108  		{
  1109  			name: "t2",
  1110  			fields: fields{
  1111  				sql:           "select * from t1",
  1112  				sqlSourceType: nil,
  1113  			},
  1114  			args: args{
  1115  				i: 1,
  1116  			},
  1117  			want: "external_sql",
  1118  		},
  1119  		{
  1120  			name: "t3",
  1121  			fields: fields{
  1122  				sql: "select * from t1",
  1123  				sqlSourceType: []string{
  1124  					"a",
  1125  					"b",
  1126  					"c",
  1127  				},
  1128  			},
  1129  			args: args{
  1130  				i: 2,
  1131  			},
  1132  			want: "c",
  1133  		},
  1134  	}
  1135  	for _, tt := range tests {
  1136  		t.Run(tt.name, func(t *testing.T) {
  1137  			ui := &UserInput{
  1138  				sql:           tt.fields.sql,
  1139  				stmt:          tt.fields.stmt,
  1140  				sqlSourceType: tt.fields.sqlSourceType,
  1141  			}
  1142  			assert.Equalf(t, tt.want, ui.getSqlSourceType(tt.args.i), "getSqlSourceType(%v)", tt.args.i)
  1143  		})
  1144  	}
  1145  }
  1146  
  1147  func TestTopsort(t *testing.T) {
  1148  	cvey.Convey("create graph", t, func() {
  1149  		g := topsort{next: make(map[string][]string)}
  1150  		g.addVertex("0")
  1151  		g.addVertex("1")
  1152  		g.addVertex("2")
  1153  		g.addVertex("3")
  1154  		g.addVertex("4")
  1155  		g.addVertex("5")
  1156  		g.addEdge("0", "2")
  1157  		g.addEdge("1", "2")
  1158  		g.addEdge("2", "3")
  1159  		g.addEdge("3", "4")
  1160  		g.addEdge("3", "5")
  1161  
  1162  		ans, ok := g.sort()
  1163  		cvey.So(ok, cvey.ShouldBeTrue)
  1164  
  1165  		sort.StringSlice(ans[:2]).Sort()
  1166  		cvey.So(ans[:2], cvey.ShouldResemble, []string{"0", "1"})
  1167  		cvey.So(ans[2], cvey.ShouldResemble, "2")
  1168  		cvey.So(ans[3], cvey.ShouldResemble, "3")
  1169  		sort.StringSlice(ans[4:]).Sort()
  1170  		cvey.So(ans[4:], cvey.ShouldResemble, []string{"4", "5"})
  1171  	})
  1172  
  1173  	cvey.Convey("create graph", t, func() {
  1174  		g := topsort{next: make(map[string][]string)}
  1175  		g.addVertex("0")
  1176  		g.addVertex("1")
  1177  		g.addVertex("2")
  1178  
  1179  		// can be in any order
  1180  		_, ok := g.sort()
  1181  		cvey.So(ok, cvey.ShouldBeTrue)
  1182  	})
  1183  
  1184  	cvey.Convey("create graph", t, func() {
  1185  		g := topsort{next: make(map[string][]string)}
  1186  		g.addVertex("0")
  1187  		g.addVertex("1")
  1188  		g.addVertex("2")
  1189  		g.addEdge("0", "1")
  1190  		g.addEdge("1", "2")
  1191  		g.addEdge("2", "0")
  1192  
  1193  		// has a cycle
  1194  		_, ok := g.sort()
  1195  		cvey.So(ok, cvey.ShouldBeFalse)
  1196  	})
  1197  }