diff --git a/assembly.xml b/assembly.xml
new file mode 100755
index 000000000..80f4cabd8
--- /dev/null
+++ b/assembly.xml
@@ -0,0 +1,40 @@
+
+ test
+
+ tar.gz
+
+ false
+
+
+
+ true
+ runtime
+ ./lib
+ 755
+
+
+
+
+ ./
+ true
+
+ mo.yml
+ run.yml
+ log4j.properties
+
+ 755
+ ./
+
+
+ ./
+
+ run.sh
+
+ 755
+ ./
+
+
+
+
\ No newline at end of file
diff --git a/cases/builtin.test b/cases/builtin.test
new file mode 100644
index 000000000..624f18c1f
--- /dev/null
+++ b/cases/builtin.test
@@ -0,0 +1,268 @@
+drop table if exists t1;
+create table t1(a int,b int);
+insert into t1 values(5,-2),(10,3),(100,0),(4,3),(6,-3);
+select power(a,b) from t1;
+select power(a,2) as a1, power(b,2) as b1 from t1 where power(a,2) > power(b,2) order by a1 asc;
+drop table if exists t1;
+create table t1(a date,b datetime);
+insert into t1 values("2022-06-01","2022-07-01 00:00:00");
+insert into t1 values("2022-12-31","2011-01-31 12:00:00");
+select month(a),month(b) from t1;
+select * from t1 where month(a)>month(b);
+select * from t1 where month(a) between 1 and 6;
+drop table if exists t1;
+create table t1(a varchar(12),c char(30));
+insert into t1 values('sdfad ','2022-02-02 22:22:22');
+insert into t1 values(' sdfad ','2022-02-02 22:22:22');
+insert into t1 values('adsf sdfad','2022-02-02 22:22:22');
+insert into t1 values(' sdfad','2022-02-02 22:22:22');
+select reverse(a),reverse(c) from t1;
+select a from t1 where reverse(a) like 'daf%';
+select reverse(a) reversea,reverse(reverse(a)) normala from t1;
+drop table if exists t1;
+create table t1(a int,b float);
+insert into t1 values(0,0),(-15,-20),(-22,-12.5);
+insert into t1 values(0,360),(30,390),(90,450),(180,270),(180,180);
+select acos(a*pi()/180) as acosa,acos(b*pi()/180) acosb from t1;
+select acos(a*pi()/180)*acos(b*pi()/180) as acosab,acos(acos(a*pi()/180)) as c from t1;
+select b from t1 where acos(a*pi()/180)<=acos(b*pi()/180) order by a;
+drop table if exists t1;
+create table t1(a int,b float);
+insert into t1 values(0,0),(-15,-20),(-22,-12.5);
+insert into t1 values(0,360),(30,390),(90,450),(180,270),(180,180);
+select atan(a*pi()/180) as atana,atan(b*pi()/180) atanb from t1;
+select atan(a*pi()/180)*atan(b*pi()/180) as atanab,atan(atan(a*pi()/180)) as c from t1;
+select b from t1 where atan(a*pi()/180)<=atan(b*pi()/180) order by a;
+drop table if exists t1;
+CREATE TABLE t1(
+Employee_Name VARCHAR(100) NOT NULL,
+Working_At VARCHAR(20) NOT NULL,
+Work_Location VARCHAR(20) NOT NULL,
+Joining_Date DATE NOT NULL,
+Annual_Income INT NOT NULL);
+INSERT INTO t1
+VALUES
+('Amit Khan', 'XYZ Digital', 'Kolkata', '2019-10-06', 350000),
+('Shreetama Pal', 'ABC Corp.', 'Kolkata', '2018-12-16', 500000),
+('Aniket Sharma', 'PQR Soln.', 'Delhi', '2020-01-11', 300000),
+('Maitree Jana', 'XYZ Digital', 'Kolkata', '2019-05-01', 400000),
+('Priyanka Ojha', 'ABC Corp.', 'Delhi', '2019-02-13', 350000),
+('Sayani Mitra', 'XYZ Digital', 'Kolkata', '2019-09-15', 320000),
+('Nitin Dey', 'PQR Soln.', 'Delhi', '2019-10-06', 250000),
+('Sujata Samanta', 'PQR Soln.', 'Kolkata', '2020-10-06', 350000),
+('Sudip Majhi', 'ABC Corp.', 'Delhi', '2018-10-30', 600000),
+('Sanjoy Kohli', 'XYZ Digital', 'Delhi', '2019-04-18', 450000);
+SELECT Working_At, BIT_AND(Annual_Income) AS BITORINCOME FROM t1 group by Working_At;
+SELECT Work_Location, BIT_AND(Annual_Income) AS BITORINCOME FROM t1 Group By Work_Location;
+drop table if exists t1;
+CREATE TABLE t1(
+Employee_Name VARCHAR(100) NOT NULL,
+Working_At VARCHAR(20) NOT NULL,
+Work_Location VARCHAR(20) NOT NULL,
+Joining_Date DATE NOT NULL,
+Annual_Income INT NOT NULL);
+INSERT INTO t1
+VALUES
+('Amit Khan', 'XYZ Digital', 'Kolkata', '2019-10-06', 350000),
+('Shreetama Pal', 'ABC Corp.', 'Kolkata', '2018-12-16', 500000),
+('Aniket Sharma', 'PQR Soln.', 'Delhi', '2020-01-11', 300000),
+('Maitree Jana', 'XYZ Digital', 'Kolkata', '2019-05-01', 400000),
+('Priyanka Ojha', 'ABC Corp.', 'Delhi', '2019-02-13', 350000),
+('Sayani Mitra', 'XYZ Digital', 'Kolkata', '2019-09-15', 320000),
+('Nitin Dey', 'PQR Soln.', 'Delhi', '2019-10-06', 250000),
+('Sujata Samanta', 'PQR Soln.', 'Kolkata', '2020-10-06', 350000),
+('Sudip Majhi', 'ABC Corp.', 'Delhi', '2018-10-30', 600000),
+('Sanjoy Kohli', 'XYZ Digital', 'Delhi', '2019-04-18', 450000);
+SELECT Work_Location, BIT_AND(Annual_Income) AS BITORINCOME FROM t1 Group By Work_Location;
+SELECT Working_At, BIT_AND(Annual_Income) AS BITORINCOME FROM t1 group by Working_At;
+drop table if exists t1;
+CREATE TABLE t1(
+Employee_Name VARCHAR(100) NOT NULL,
+Working_At VARCHAR(20) NOT NULL,
+Work_Location VARCHAR(20) NOT NULL,
+Joining_Date DATE NOT NULL,
+Annual_Income INT NOT NULL);
+INSERT INTO t1
+VALUES
+('Amit Khan', 'XYZ Digital', 'Kolkata', '2019-10-06', 350000),
+('Shreetama Pal', 'ABC Corp.', 'Kolkata', '2018-12-16', 500000),
+('Aniket Sharma', 'PQR Soln.', 'Delhi', '2020-01-11', 300000),
+('Maitree Jana', 'XYZ Digital', 'Kolkata', '2019-05-01', 400000),
+('Priyanka Ojha', 'ABC Corp.', 'Delhi', '2019-02-13', 350000),
+('Sayani Mitra', 'XYZ Digital', 'Kolkata', '2019-09-15', 320000),
+('Nitin Dey', 'PQR Soln.', 'Delhi', '2019-10-06', 250000),
+('Sujata Samanta', 'PQR Soln.', 'Kolkata', '2020-10-06', 350000),
+('Sudip Majhi', 'ABC Corp.', 'Delhi', '2018-10-30', 600000),
+('Sanjoy Kohli', 'XYZ Digital', 'Delhi', '2019-04-18', 450000);
+SELECT Work_Location, BIT_XOR(Annual_Income) AS BITORINCOME FROM t1 Group By Work_Location;
+SELECT Working_At, BIT_XOR(Annual_Income) AS BITORINCOME FROM t1 group by Working_At;
+drop table if exists t1;
+create table t1(a int,b float);
+insert into t1 values(0,0);
+insert into t1 values(0,360),(30,390),(90,450),(180,270),(180,180);
+select cos(a),cos(b) from t1;
+select cos(a)*cos(b),cos(cos(a)) as c from t1;
+select distinct a from t1 where cos(a)<=cos(b) order by a desc;
+drop table if exists t1;
+create table t1(a int,b float);
+insert into t1 values(0,0),(-15,-20),(-22,-12.5);
+insert into t1 values(0,360),(30,390),(90,450),(180,270),(180,180);
+select cot(a*pi()/180) as cota,cot(b*pi()/180) cotb from t1;
+select cot(a*pi()/180)*cot(b*pi()/180) as cotab,cot(cot(a*pi()/180)) as c from t1;
+select b from t1 where cot(a*pi()/180)<=cot(b*pi()/180) order by a;
+drop table if exists t1;
+create table t1(a date, b datetime,c varchar(30));
+insert into t1 values('2022-01-01','2022-01-01 01:01:01','2022-01-01 01:01:01');
+insert into t1 values('2022-01-01','2022-01-01 01:01:01','2022-01-01 01:01:01');
+insert into t1 values(20220101,'2022-01-01 01:01:01','2022-13-13 01:01:01');
+insert into t1 values('2022-01-02','2022-01-02 23:01:01','2022-01-01 23:01:01');
+insert into t1 values('2021-12-31','2021-12-30 23:59:59','2021-12-30 23:59:59');
+insert into t1 values('2022-06-30','2021-12-30 23:59:59','2021-12-30 23:59:59');
+select distinct dayofyear(a) as dya from t1;
+select * from t1 where dayofyear(a)>120;
+select * from t1 where dayofyear(a) between 1 and 184;
+drop table if exists t1;
+CREATE TABLE t1(a INT,b VARCHAR(100),c CHAR(20));
+INSERT INTO t1
+VALUES
+(1,'Ananya Majumdar', 'XI'),
+(2,'Anushka Samanta', 'X'),
+(3,'Aniket Sharma', 'XI'),
+(4,'Anik Das', 'X'),
+(5,'Riya Jain', 'IX'),
+(6,'Tapan Samanta', 'XI');
+select a,endswith(b,'a') from t1;
+select a,b,c from t1 where endswith(b,'a')=1 and endswith(c,'I')=1;
+drop table if exists t1;
+CREATE TABLE t1(Student_id INT,Student_name VARCHAR(100),Student_Class CHAR(20));
+INSERT INTO t1
+VALUES
+(1,'Ananya Majumdar', 'IX'),
+(2,'Anushka Samanta', 'X'),
+(3,'Aniket Sharma', 'XI'),
+(4,'Anik Das', 'X'),
+(5,'Riya Jain', 'IX'),
+(6,'Tapan Samanta', 'X');
+SELECT Student_id, Student_name,LPAD(Student_Class, 10, ' _') AS LeftPaddedString FROM t1;
+SELECT Student_id, lpad(Student_name,4,'new') AS LeftPaddedString FROM t1;
+SELECT Student_id, lpad(Student_name,-4,'new') AS LeftPaddedString FROM t1;
+SELECT Student_id, lpad(Student_name,0,'new') AS LeftPaddedString FROM t1;
+drop table if exists t1;
+CREATE TABLE t1(Student_id INT,Student_name VARCHAR(100),Student_Class CHAR(20));
+INSERT INTO t1
+VALUES
+(1,'Ananya Majumdar', 'IX'),
+(2,'Anushka Samanta', 'X'),
+(3,'Aniket Sharma', 'XI'),
+(4,'Anik Das', 'X'),
+(5,'Riya Jain', 'IX'),
+(6,'Tapan Samanta', 'X');
+SELECT Student_id, Student_name,RPAD(Student_Class, 10, ' _') AS LeftPaddedString FROM t1;
+SELECT Student_id, rpad(Student_name,4,'new') AS LeftPaddedString FROM t1;
+SELECT Student_id, rpad(Student_name,-4,'new') AS LeftPaddedString FROM t1;
+SELECT Student_id, rpad(Student_name,0,'new') AS LeftPaddedString FROM t1;
+drop table if exists t1;
+CREATE TABLE t1
+(
+Employee_name VARCHAR(100) NOT NULL,
+Joining_Date DATE NOT NULL
+);
+INSERT INTO t1
+(Employee_name, Joining_Date )
+VALUES
+(' Ananya Majumdar', '2000-01-11'),
+(' Anushka Samanta', '2002-11-10' ),
+(' Aniket Sharma ', '2005-06-11' ),
+(' Anik Das', '2008-01-21' ),
+(' Riya Jain', '2008-02-01' ),
+(' Tapan Samanta', '2010-01-11' ),
+(' Deepak Sharma', '2014-12-01' ),
+(' Ankana Jana', '2018-08-17'),
+(' Shreya Ghosh', '2020-09-10') ;
+SELECT LTRIM( Employee_name) LTrimName,RTRIM(Employee_name) AS RTrimName FROM t1 order by RTrimName desc;
+SELECT LTRIM(RTRIM(Employee_name)) as TrimName from t1 where Employee_name like '%Ani%' order by TrimName asc;
+drop table if exists t1;
+create table t1(a int,b float);
+insert into t1 values(0,0);
+insert into t1 values(0,360),(30,390),(90,450),(180,270),(180,180);
+select sin(a),sin(b) from t1;
+select sin(a)*sin(b),sin(sin(a)) as c from t1;
+select distinct a from t1 where sin(a)<=sin(b) order by a desc;
+drop table if exists t1;
+create table t1(a int,b float);
+insert into t1 values(0,0),(-15,-20),(-22,-12.5);
+insert into t1 values(0,360),(30,390),(90,450),(180,270),(180,180);
+select sinh(a*pi()/180) as sinha,sinh(b*pi()/180) sinhb from t1;
+select sinh(a*pi()/180)*sinh(b*pi()/180) as sinhab,sinh(sinh(a*pi()/180)) as c from t1;
+select b from t1 where sinh(a*pi()/180)<=sinh(b*pi()/180) order by a;
+drop table if exists t1;
+CREATE TABLE t1
+(
+Employee_name VARCHAR(100) NOT NULL,
+Joining_Date DATE NOT NULL
+);
+INSERT INTO t1
+(Employee_name, Joining_Date )
+VALUES
+(' Ananya Majumdar', '2000-01-11'),
+(' Anushka Samanta', '2002-11-10' ),
+(' Aniket Sharma ', '2005-06-11' ),
+(' Anik Das', '2008-01-21' ),
+(' Riya Jain', '2008-02-01' ),
+(' Tapan Samanta', '2010-01-11' ),
+(' Deepak Sharma', '2014-12-01' ),
+(' Ankana Jana', '2018-08-17'),
+(' Shreya Ghosh', '2020-09-10') ;
+INSERT INTO t1
+(Employee_name, Joining_Date ) values(' ','2014-12-01');
+select * from t1 where Employee_name=space(5);
+drop table if exists t1;
+CREATE TABLE t1(a INT,b VARCHAR(100),c CHAR(20));
+INSERT INTO t1
+VALUES
+(1,'Ananya Majumdar', 'IX'),
+(2,'Anushka Samanta', 'X'),
+(3,'Aniket Sharma', 'XI'),
+(4,'Anik Das', 'X'),
+(5,'Riya Jain', 'IX'),
+(6,'Tapan Samanta', 'X');
+select a,startswith(b,'An') from t1;
+select a,b,c from t1 where startswith(b,'An')=1 and startswith(c,'I')=1;
+drop table if exists t1;
+CREATE TABLE t1(PlayerName VARCHAR(100) NOT NULL,RunScored INT NOT NULL,WicketsTaken INT NOT NULL);
+INSERT INTO t1 VALUES('KL Rahul', 52, 0 ),('Hardik Pandya', 30, 1 ),('Ravindra Jadeja', 18, 2 ),('Washington Sundar', 10, 1),('D Chahar', 11, 2 ), ('Mitchell Starc', 0, 3);
+SELECT STDDEV_POP(RunScored) as Pop_Standard_Deviation FROM t1;
+SELECT STDDEV_POP(WicketsTaken) as Pop_Std_Dev_Wickets FROM t1;
+drop table if exists t1;
+create table t1(a int,b float);
+insert into t1 values(0,0),(-15,-20),(-22,-12.5);
+insert into t1 values(0,360),(30,390),(90,450),(180,270),(180,180);
+select tan(a*pi()/180) as tana,tan(b*pi()/180) tanb from t1;
+select tan(a*pi()/180)*tan(b*pi()/180) as tanab,tan(tan(a*pi()/180)) as c from t1;
+select b from t1 where tan(a*pi()/180)<=tan(b*pi()/180) order by a;
+drop table if exists t1;
+create table t1(a date,b datetime);
+insert into t1 values("2022-06-01","2022-07-01 00:00:00");
+insert into t1 values("2022-12-31","2011-01-31 12:00:00");
+insert into t1 values("2022-06-12","2022-07-01 00:00:00");
+select a,weekday(a),b,weekday(b) from t1;
+select * from t1 where weekday(a)>weekday(b);
+select * from t1 where weekday(a) between 0 and 4;
+drop table if exists t1;
+create table t1(a date,b datetime);
+insert into t1 values("2022-06-01","2022-07-01 00:00:00");
+insert into t1 values("2022-12-31","2011-01-31 12:00:00");
+insert into t1 values("2022-06-12","2022-07-01 00:00:00");
+select a,weekday(a),b,weekday(b) from t1;
+select * from t1 where weekday(a)>weekday(b);
+select * from t1 where weekday(a) between 0 and 4;
+drop table if exists t1;
+create table t1(a date, b datetime);
+insert into t1 values('2022-01-01','2022-01-01 01:01:01');
+insert into t1 values('2022-01-01','2022-01-01 01:01:01');
+insert into t1 values(20220101,'2022-01-01 01:01:01');
+insert into t1 values('2022-01-02','2022-01-02 23:01:01');
+insert into t1 values('2021-12-31','2021-12-30 23:59:59');
+insert into t1 values('2022-06-30','2021-12-30 23:59:59');
+select date(a),date(b) from t1;
+select date(a),date(date(a)) as dda from t1;
diff --git a/cases/create_database.test b/cases/create_database.test
new file mode 100644
index 000000000..6ff62438d
--- /dev/null
+++ b/cases/create_database.test
@@ -0,0 +1,19 @@
+drop database if exists test01;
+drop database if exists test03;
+drop database if exists test04;
+drop database if exists test05;
+drop database if exists `测试数据库`;
+drop database if exists t01234567890123456789012345678901234567890123456789012345678901234567890123456789;
+create database test01;
+create database IF NOT EXISTS test01;
+create database `测试数据库`;
+create database test03 default character set utf8 collate utf8_general_ci encryption 'Y';
+create database test04 character set=utf8 collate=utf8_general_ci encryption='N';
+create database t01234567890123456789012345678901234567890123456789012345678901234567890123456789;
+show databases;
+drop database if exists test01;
+drop database if exists test03;
+drop database if exists test04;
+drop database if exists test05;
+drop database if exists `测试数据库`;
+drop database if exists t01234567890123456789012345678901234567890123456789012345678901234567890123456789;
diff --git a/cases/create_table.test b/cases/create_table.test
new file mode 100644
index 000000000..f9316f9f4
--- /dev/null
+++ b/cases/create_table.test
@@ -0,0 +1,16 @@
+create table table01(a TINYINT primary key, b SMALLINT SIGNED, c INT UNSIGNED,d BIGINT not null , e FLOAT unique,f DOUBLE, g CHAR(10), h VARCHAR(20));
+create table table15 (a varchar(5) default 'abcde');
+create temporary table table05 ( a int, b char(10));
+create table table06 (a int primary key, b varchar(10));
+create table table10 (a int primary key, b varchar(10)) checksum=0 COMMENT="asdf";
+create table `测试表` (`测试1` int);
+create table `table11 ` (a int);
+create table table12 (`a ` int);
+create table `a/a` (a int);
+create table `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa int);
+create table table14 (`aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` int);
+create table table16 (1a20 int,1e int);
+create table $table18 (a$1 int, $b int, c$ int);
+create table table19$ (a int);
+create table table17 (`index` int);
+show tables;
diff --git a/cases/datatype.test b/cases/datatype.test
new file mode 100644
index 000000000..59c302abd
--- /dev/null
+++ b/cases/datatype.test
@@ -0,0 +1,50 @@
+drop table if exists numtable;
+create table numtable(id int,fl float, dl double);
+insert into numtable values(1,123456,123456);
+insert into numtable values(2,123.456,123.456);
+insert into numtable values(3,1.234567,1.234567);
+insert into numtable values(4,1.234567891,1.234567891);
+insert into numtable values(5,1.2345678912345678912,1.2345678912345678912);
+select id,fl,dl from numtable order by id;
+drop table if exists numtable;
+create table numtable(id int,fl float(5,3));
+insert into numtable values(2,99);
+insert into numtable values(3,99.123);
+insert into numtable values(4,99.1236);
+select id,fl from numtable;
+drop table if exists numtable;
+create table numtable(id int,fl float(23));
+insert into numtable values(1,1.2345678901234567890123456789);
+select id,fl from numtable;
+drop table if exists numtable;
+create table numtable(id int,dl double);
+insert into numtable values(1,1.2345678901234567890123456789);
+select id,dl from numtable;
+drop table if exists numtable;
+create table numtable(a tinyint unsigned, b smallint unsigned, c int unsigned, d bigint unsigned);
+insert into numtable values(255,65535,4294967295,18446744073709551615);
+select a,b,c,d from numtable;
+drop table if exists numtable;
+create table numtable(a tinyint signed, b smallint signed, c int signed, d bigint signed);
+insert into numtable values(127,32767,2147483647,9223372036854775807);
+insert into numtable values(-128,-32768,-2147483648,-9223372036854775808);
+select a,b,c,d from numtable;
+drop table if exists names;
+create table names(name varchar(255),age char(255));
+insert into names(name, age) values('Abby', '24');
+insert into names(name, age) values("Bob", '25');
+insert into names(name, age) values('Carol', "23");
+insert into names(name, age) values("Dora", "29");
+select name,age from names;
+drop table if exists t4;
+create table t4(a int, b date, c datetime);
+insert into t4 values(1, '2021-12-13','2021-12-13 13:00:00');
+insert into t4 values(2, '20211214','20211213');
+insert into t4 values(3,'2021-12-14','2021-12-14');
+insert into t4 values(4,'2021-12-15','2021-12-14');
+select * from t4 where b>'20211213';
+select * from t4 where c>'20211213';
+select * from t4 where b>'2021-12-13';
+select * from t4 where c>'2021-12-13';
+select * from t4 where b between '2021-12-13' and '2021-12-14';
+select * from t4 where b not between '2021-12-13' and '2021-12-14';
diff --git a/cases/drop_database.test b/cases/drop_database.test
new file mode 100644
index 000000000..b36b27ab1
--- /dev/null
+++ b/cases/drop_database.test
@@ -0,0 +1,5 @@
+drop database if exists test01;
+drop database if exists drop_database;
+create database test01;
+drop database test01;
+show databases;
diff --git a/cases/drop_table.test b/cases/drop_table.test
new file mode 100644
index 000000000..732440069
--- /dev/null
+++ b/cases/drop_table.test
@@ -0,0 +1,4 @@
+drop table if exists table01;
+create table table01(a int);
+drop table table01;
+show tables;
diff --git a/cases/dtype_decimal.sql b/cases/dtype_decimal.sql
new file mode 100644
index 000000000..bcd8243e7
--- /dev/null
+++ b/cases/dtype_decimal.sql
@@ -0,0 +1,168 @@
+create database if not exists decimal_test;
+use decimal_test;
+drop table if exists numtable;
+-- test for min length of decimal type
+create table numtable(id int, dt decimal(1,0));
+-- test for insertion of type[int]
+insert into numtable values(1,1);
+insert into numtable values(2,2);
+insert into numtable values(2,-2);
+-- expectation:return error
+insert into numtable values(2,20);
+select * from numtable;
+
+drop table if exists numtable;
+-- test for normal length of decimal type
+create table numtable(id int, dt decimal(10,5));
+-- test for insertion of type[int]
+insert into numtable values(1,1);
+insert into numtable values(2,99999);
+insert into numtable values(2,-99999);
+-- expectation:return error
+insert into numtable values(3,100000);
+select * from numtable;
+
+drop table if exists numtable;
+create table numtable(id int, dt decimal(10,5));
+-- test for insertion of type[float]
+insert into numtable values(1,1.0);
+insert into numtable values(2,99999.999999);
+insert into numtable values(2,99999.9999999);
+insert into numtable values(2,99999.99999);
+insert into numtable values(2,12345.12345);
+insert into numtable values(2,9999.999999);
+insert into numtable values(2,9999.999994);
+insert into numtable values(2,9999.9999);
+insert into numtable values(2,-9999.9999);
+insert into numtable values(2,-9999.999999);
+-- insert into numtable values(2, 1.01e4);
+-- insert into numtable values(5,9.9999999994e4);
+select * from numtable;
+-- test for rounding
+insert into numtable values(6,99999.000001);
+insert into numtable values(6,99999.000005);
+insert into numtable values(7,99999.000011);
+insert into numtable values(7,99999.000014);
+insert into numtable values(7,99999.000025);
+insert into numtable values(4,99999.999985);
+insert into numtable values(4,-99999.999985);
+insert into numtable values(4,99999.999994);
+
+-- expectation:return error
+insert into numtable values(3,100000.0);
+insert into numtable values(3,999999.9999);
+insert into numtable values(5,99999.999995);
+insert into numtable values(5,-99999.999995);
+insert into numtable values(5,9.9999999995e4);
+select * from numtable;
+
+drop table if exists numtable;
+create table numtable(id int, dt decimal(10,5));
+-- test for insertion of type[transferabled char]
+insert into numtable values(1,'123.45');
+insert into numtable values(2,'99999.999985');
+-- test for insertion of null
+insert into numtable values(1,null);
+-- test for insertion of illegal value
+insert into numtable values(1,'abc');
+select * from numtable;
+
+drop table if exists numtable;
+-- test for max length of decimal type
+create table numtable(id int, dt decimal(38,10));
+insert into numtable values(1,123.45);
+insert into numtable values(1,1000000000000000000000000000.45);
+insert into numtable values(1,100000000000000000000000000000.45);
+select * from numtable;
+drop table if exists numtable;
+
+
+drop table if exists numtable;
+-- test for default value of precision(10) and scale(0)
+create table dec_s_defalut(id int, dt decimal(5));
+insert into dec_s_defalut values(1,100);
+insert into dec_s_defalut values(2,99.99);
+select * from dec_s_defalut;
+create table dec_p_defalut(id int, dt decimal);
+insert into dec_p_defalut values(1,100);
+insert into dec_p_defalut values(2,9999.999999);
+insert into dec_p_defalut values(2,999999999.9);
+insert into dec_p_defalut values(2,9999999999.4);
+insert into dec_p_defalut values(2,10000000000.4);
+select * from dec_p_defalut;
+drop table if exists dec_s_defalut;
+drop table if exists dec_p_defalut;
+
+-- test for exception of ddl
+#maybe error
+create table numtable(id int, dt decimal(0,0));
+create table numtable(id int, dt decimal(-1,0));
+create table numtable(id int, dt decimal(39,10));
+create table numtable(id int, dt decimal(a,10));
+create table numtable(id int, dt decimal(10,-1));
+create table numtable(id int, dt decimal(10,11));
+create table numtable(id int, dt decimal(10,b));
+
+-- test for distinct type of decimal column
+drop table if exists dt_dis;
+create table dt_dis(id int, dt decimal(10,5));
+insert into dt_dis values(1,100);
+insert into dt_dis values(1,100.00);
+insert into dt_dis values(1,'100.00');
+insert into dt_dis values(1,99999.99999);
+insert into dt_dis values(1,99999.999994);
+insert into dt_dis values(1,99998.999995);
+insert into dt_dis values(1,99999);
+insert into dt_dis values(1,99999.00);
+insert into dt_dis values(1,'99998.999995');
+insert into dt_dis values(2,null);
+insert into dt_dis values(3,null);
+select distinct dt from dt_dis;
+drop table if exists dt_dis;
+
+-- test for numeric func of decimal column
+drop table if exists dt_func;
+create table dt_func(id int, dt decimal(10,5));
+insert into dt_func values(1,100),(2,200),(2,-200.12),(2,-0.321);
+insert into dt_func values(1,100.00);
+insert into dt_func values(1,99999.99999);
+insert into dt_func values(1,99999.999994);
+insert into dt_func values(1,-99999.99999);
+insert into dt_func values(2,null);
+insert into dt_func values(3,null);
+select min(dt) from dt_func;
+select max(dt) from dt_func;
+select avg(dt) from dt_func;
+select sum(dt) from dt_func;
+select count(dt) from dt_func;
+select round(dt) from dt_func;
+drop table if exists dt_func;
+
+--test for operation
+drop table if exists dt_opt;
+create table dt_opt(id int, dt decimal(10,5));
+insert into dt_opt values(1,100),(2,200),(2,-200.12),(2,-0.321);
+insert into dt_opt values(1,100.00);
+insert into dt_opt values(1,99999.99999);
+insert into dt_opt values(1,99999.999994);
+insert into dt_opt values(1,-99999.99999);
+insert into dt_opt values(2,null);
+insert into dt_opt values(3,null);
+select dt+1 from dt_opt;
+select dt+1 from dt_opt;
+select dt-10 from dt_opt;
+select dt*3.5 from dt_opt;
+select dt*5 from dt_opt;
+select dt/2 from dt_opt;
+select dt/4.3 from dt_opt;
+select dt%10 from dt_opt;
+select * from dt_opt where dt > 0;
+select * from dt_opt where dt < 100.30;
+select * from dt_opt where dt <> 99999.99999;
+
+-- test for addition for the length > 18
+drop table if exists dt_opt;
+create table dt_opt(id int, dt decimal(38,5));
+insert into dt_opt values(1,999999999999999999);
+select dt + 999999999999999999999999999999999999.11 from dt_opt;
+drop table if exists dt_opt;
\ No newline at end of file
diff --git a/cases/func_aggr.sql b/cases/func_aggr.sql
new file mode 100644
index 000000000..f23fc4601
--- /dev/null
+++ b/cases/func_aggr.sql
@@ -0,0 +1,14 @@
+create database if not exists aggr;
+use aggr;
+
+-- test for stddev_pop
+drop table if exists t1;
+CREATE TABLE t1 (id int(11),value1 float(10,2));
+INSERT INTO t1 VALUES (1,0.00),(1,1.00), (1,2.00), (2,10.00), (2,11.00), (2,12.00), (2,13.00);
+select id, stddev_pop(value1) from t1 group by id;
+
+drop table if exists t;
+CREATE TABLE t(txt char(1), i INT);
+INSERT INTO t VALUES ('a', 2), ('b', 8), ('b', 0), ('c', 2);
+SELECT txt, STDDEV_POP(i) s FROM t GROUP BY txt ORDER BY s, txt;
+
diff --git a/cases/func_date.sql b/cases/func_date.sql
new file mode 100644
index 000000000..1ba4f3bf5
--- /dev/null
+++ b/cases/func_date.sql
@@ -0,0 +1,53 @@
+create database if not exists datedb;
+use datedb;
+drop table if exists t1;
+create table t1 (id int,d date, dt datetime,c char(10),vc varchar(20));
+insert into t1 values (1,"2021-01-13", "2021-01-13 13:00:00", "2021-12-15", "2021-12-16");
+insert into t1 values (1,"2021-01-31", "2021-01-31 13:00:00", "2021-12-15", "2021-12-16");
+insert into t1 values (2,"2022-02-15", "2022-02-15 18:54:29", "2021-02-15", "2021-02-15");
+insert into t1 values (2,"2022-02-28", "2022-02-28 18:54:29", "2021-02-15", "2021-02-15");
+insert into t1 values (3,"2000-02-29", "2000-02-29 18:54:29", "2021-02-15", "2021-02-15");
+insert into t1 values (4,"2023-03-17", "2021-02-17 23:54:59", "2021-03-17", "2021-03-17");
+insert into t1 values (5,"1985-04-18", "1985-04-18 00:00:01", "1985-04-18", "1985-04-18");
+insert into t1 values (6,"1987-05-20", "1987-05-20 22:59:59", "1987-05-20", "1987-05-20");
+insert into t1 values (7,"1989-06-22", "1989-06-22 15:00:30", "1989-06-22", "1989-06-22");
+insert into t1 values (8,"1993-07-25", "1987-07-25 03:04:59", "1993-07-25", "1993-07-25");
+insert into t1 values (9,"1995-08-27", "1987-08-27 04:32:33", "1995-08-27", "1995-08-27");
+insert into t1 values (10,"1999-09-30", "1999-09-30 10:11:12", "1999-09-30", "1999-09-30");
+insert into t1 values (11,"2005-10-30", "2005-10-30 18:18:59", "2005-10-30", "2005-10-30");
+insert into t1 values (12,"2008-11-30", "2008-11-30 22:59:59", "2008-11-30", "2008-11-30");
+insert into t1 values (13,"2013-12-01", "2013-12-01 22:59:59", "2013-12-01", "2013-12-01");
+insert into t1 values (14,null, null, null, null);
+select month(d),month(dt) from t1;
+select month(c),month(vc) from t1;
+select weekday(d),weekday(dt) from t1;
+select weekday(c),weekday(vc) from t1;
+-- select week(d),week(dt) from t1;
+-- select day(d),day(dt) from t1;
+-- select dayofmonth(d),dayofmonth(dt) from t1;
+-- select date(c),date(vc) from t1;
+-- select dayofyear(d),dayofyear(dt) from t1;
+-- select hour(d),hour(dt) from t1;
+-- select minute(d),minute(dt) from t1;
+-- select second(d),second(dt) from t1;
+
+-- test for max,min,etc
+select max(month(d)),max(month(dt)) from t1;
+select min(month(d)),min(month(d)) from t1;
+select avg(month(d)),avg(month(d)) from t1;
+select sum(month(d)),sum(month(d)) from t1;
+
+select max(weekday(d)),max(weekday(dt)) from t1;
+select min(weekday(d)),min(weekday(d)) from t1;
+select avg(weekday(d)),avg(weekday(d)) from t1;
+select sum(weekday(d)),sum(weekday(d)) from t1;
+
+-- test for distinct
+select distinct(month(d)) from t1;
+select id,c,vc from t1 where month(d) > 2;
+select id,c,vc from t1 where month(d) < 3;
+select id,c,vc from t1 where month(d) <> 4;
+
+select id,count(weekday(d))) from t1;
+
+--test for to_date
\ No newline at end of file
diff --git a/cases/func_math.sql b/cases/func_math.sql
new file mode 100644
index 000000000..fec09a36c
--- /dev/null
+++ b/cases/func_math.sql
@@ -0,0 +1,45 @@
+create database if not exists mathdb;
+use mathdb;
+drop table if exists t1;
+create table t1 (id int,d int,fl float,de decimal);
+insert into t1 values(1,1,123.0213,1.001);
+insert into t1 values(2,2,1.0213,1.001);
+insert into t1 values(3,null,null,null);
+insert into t1 values(4,0,0,0);
+select sinh(d),sinh(fl)from t1;
+select atan(d),atan(fl)from t1;
+select acos(d),acos(fl)from t1;
+select cot(d),cot(fl) from t1;
+select tan(d),tan(fl) from t1;
+select sin(d),sin(fl) from t1;
+
+-- test for abs
+drop table if exists abs;
+create table abs(id int,d int,dl double,fl float,de decimal);
+insert into abs values(1,-10,-10,-10.0321,-10.312);
+insert into abs values(2,-2,-2,-2.0321,-2.3765);
+insert into abs values(3,-10,-18446744073709551614,-10.0321,-10.312);
+insert into abs values(4,-31232,-9223372036854775808,-1312.0321,-973.3072);
+insert into abs values(1,-6,-432432.43,-8756.4321,-356.421);
+insert into abs values(1,null,null,null,null);
+
+select abs(d),abs(dl),abs(fl) from abs;
+select abs(d)-2 from t1;
+select abs(d)*2 from t1;
+select abs(tan(d))*2 from t1;
+
+drop table if exists ceil;
+create table ceil(id int,d int,dl double,fl float,de decimal);
+insert into ceil values(1,5,5,-5.5,-5.5);
+insert into ceil values(2,-2,18446744073709551614,-2.5,-5.2);
+insert into ceil values(2,-1,18446744073709551614,1.23,-1.23);
+insert into ceil values(2,-1,1844674407370955161,1.23,-1.23);
+insert into ceil values(2,-1,-9223372036854775808,1.23,-1.23);
+insert into ceil values(2,-1,-184467440737095516,1.23,-1.23);
+insert into ceil values(2,-1,-922337203685477580,1.23,-1.23);
+insert into ceil values(2,-1,-922337203685477580,1.23,-1.23);
+insert into ceil values(2,-1,-99999999999999999.9,1.23,-1.23);
+insert into ceil values(2,-1,-99999999999999999.9,1.23,-1.23);
+
+select ceil(d),ceil(dl),ceil(fl) from ceil;
+
diff --git a/cases/func_substr.sql b/cases/func_substr.sql
new file mode 100644
index 000000000..74e724ab9
--- /dev/null
+++ b/cases/func_substr.sql
@@ -0,0 +1,128 @@
+create database if not exists func;
+use func;
+drop table if exists t1;
+create table t1 ( id int, c char(10),vc varchar(20));
+insert into t1 values (1,'Daffy','Aducklife');
+insert into t1 values (1,'Daffy','Aducklife');
+insert into t1 values (2,'Bugs','Arabbitlife');
+insert into t1 values (3,'Cowboy','Lifeontherange');
+insert into t1 values (4,'Anonymous','Wannabuythisbook?');
+insert into t1 values (5,'BestSeller','OneHeckuvabook');
+insert into t1 values (5,'BestSeller','OneHeckuvabook');
+insert into t1 values (6,'EveryoneBu','Thisverybook');
+insert into t1 values (7,'SanFran','Itisasanfranlifetyle');
+insert into t1 values (8,'BerkAuthor','Cool.Berkly.the.book');
+insert into t1 values (9,null,null);
+insert into t1 values (10,'北京市','中关村');
+insert into t1 values (10,'','');
+select SUBSTRING(c,1),SUBSTR(vc,1) from t1;
+select SUBSTRING(c,2),SUBSTR(vc,2) from t1;
+select SUBSTRING(c,5),SUBSTR(vc,9) from t1 where id = 1 ;
+select substring(c,11),substr(vc,13) from t1 where id = 6 ;
+
+select SUBSTRING(c,-1),SUBSTR(vc,-1) from t1;
+select SUBSTRING(c,-2),SUBSTR(vc,-2) from t1;
+select SUBSTRING(c,-5),SUBSTR(vc,-9) from t1 where id = 1 ;
+select substring(c,-11),substr(vc,-13) from t1 where id = 6 ;
+
+select SUBSTRING(c,1,1),SUBSTR(vc,1,1) from t1 where id = 1 ;
+select SUBSTRING(c,2,2),SUBSTR(vc,3,3) from t1 where id = 1 ;
+select SUBSTRING(c,2,5),SUBSTR(vc,3,9) from t1 where id = 1 ;
+select substring(c,2,9),substr(vc,3,17) from t1 where id = 4 ;
+select substring(c,2,10),substr(vc,3,18) from t1 where id = 4 ;
+select substring(c,5,4),substr(vc,5,4) from t1 where id = 4 ;
+select substring(c,10,10),substr(vc,18,18) from t1 where id = 4 ;
+select substring(c,2,-1),substr(vc,3,-1) from t1 where id = 4 ;
+
+select SUBSTRING(c,-1,1),SUBSTR(vc,1,1) from t1 where id = 1 ;
+select SUBSTRING(c,-2,2),SUBSTR(vc,3,3) from t1 where id = 1 ;
+select SUBSTRING(c,-2,5),SUBSTR(vc,3,9) from t1 where id = 1 ;
+select substring(c,-2,9),substr(vc,3,17) from t1 where id = 4 ;
+select substring(c,-2,10),substr(vc,3,18) from t1 where id = 4 ;
+
+select substring(c,1,-1),substr(vc,3,-2) from t1 where id = 4 ;
+
+select substring(c,1,a),substr(vc,3,1) from t1 where id = 4 ;
+select substring(c,1,2),substr(vc,a,1) from t1 where id = 4 ;
+
+-- test for func
+select max(substr(c,2)) from t1;
+select min(substr(c,2)) from t1;
+
+-- test for where filter
+select * from t1 where substr(c,2) = 'affy';
+select * from t1 where substr(c,2) <> 'affy';
+select * from t1 where substr(c,2) > 'affy';
+select * from t1 where substr(c,2) > substring('fdasfsad',2);
+
+-- test for distinct
+select distinct(substr(c,2)) from t1;
+select distinct(substr(vc,3)) from t1;
+
+
+-- test for endswith
+select endswith(c,'a'),endswith(vc,'a') from t1;
+select endswith(c,'y'),endswith(vc,'e') from t1;
+select * from t1 where endswith(c,'y') = 1;
+select * from t1 where endswith(c,'y') = 1 and endswith(vc,'ge') = 1;
+
+-- test for startswith
+select startswith(c,'B'),startswith(vc,'A') from t1;
+select startswith(c,'y'),startswith(vc,'e') from t1;
+select * from t1 where startswith(c,'B') = 1;
+select * from t1 where startswith(c,'B') = 1 and startswith(vc,'A') = 1;
+
+--test for lpad
+select lpad(c,0,'*') from t1;
+select lpad(c,1,'*') from t1;
+select lpad(c,5,'*') from t1;
+select lpad(c,10,'*') from t1;
+select rpad(c,'1','*') from t1;
+
+select rpad(c,0,'*') from t1;
+select rpad(c,1,'*') from t1;
+select rpad(c,5,'*') from t1;
+select rpad(c,10,'*') from t1;
+select rpad(c,'1','*') from t1;
+
+
+drop table if exists t1;
+
+--test for ltrim and rtrim
+drop table if exists t1;
+create table t1 ( id int, c char(20),vc varchar(50));
+insert into t1 values (1,'Daffy ',' Aducklife');
+insert into t1 values (1,' Daffy ','Aducklife ');
+insert into t1 values (2,' Bugs',' Arabbitlife ');
+insert into t1 values (3,' Cowboy',' Lifeontherange');
+insert into t1 values (4,' Anonymous ',' Wannabuythisbook? ');
+insert into t1 values (5,' BestSeller',' OneHeckuvabook ');
+insert into t1 values (5,' BestSeller','OneHeckuvabook ');
+insert into t1 values (6,' EveryoneBu',' Thisverybook ');
+insert into t1 values (7,' SanFran',' Itisasanfranlifetyle ');
+insert into t1 values (8,' BerkAuthor',' Cool.Berkly.the.book ');
+insert into t1 values (9,null,null);
+insert into t1 values (10,' 北京市 ',' 中关村 ');
+insert into t1 values (10,'','');
+select ltrim(c),ltrim(vc) from t1;
+select rtrim(c),rtrim(vc) from t1;
+select ltrim(rtrim(c)),rtrim(ltrim(vc)) from t1;
+select * from t1 where ltrim(c) = 'BestSeller';
+select * from t1 where ltrim(c) = 'BestSeller' and rtrim(vc) = 'OneHeckuvabook';
+
+
+-- test for space()
+drop table if exists t1;
+create table t1 ( d int);
+insert into t1 values(0),(-1),(2),(10);
+select space(d) from t1 where d <> -1;
+select space(d) from t1;
+
+
+
+
+
+-- test for insert
+drop table if exists t2;
+create table t2 ( id int, c char(10),vc varchar(20));
+insert into t2 values (1,substr('EveryoneBu',2),substr('Itisasanfranlifetyle',5));
\ No newline at end of file
diff --git a/cases/func_to_decimal.sql b/cases/func_to_decimal.sql
new file mode 100644
index 000000000..e69de29bb
diff --git a/cases/functions.test b/cases/functions.test
new file mode 100644
index 000000000..bd99387f7
--- /dev/null
+++ b/cases/functions.test
@@ -0,0 +1,75 @@
+drop table if exists tbl1,tbl2;
+create table tbl1 (col_1a tinyint, col_1b smallint, col_1c int, col_1d bigint, col_1e char(10) not null);
+insert into tbl1 values (0,1,1,7,"a");
+insert into tbl1 values (0,1,2,8,"b");
+insert into tbl1 values (0,1,3,9,"c");
+insert into tbl1 values (0,1,4,10,"D");
+insert into tbl1 values (0,1,5,11,"a");
+insert into tbl1 values (0,1,6,12,"c");
+select sum(col_1a),count(col_1b),avg(col_1c),min(col_1d),max(col_1d) from tbl1;
+select sum(col_1d) as s1,count(col_1d) as c2,avg(col_1d) as a3,min(col_1d) as m4,max(col_1d) as m5 from tbl1 group by col_1e order by s1 desc;
+select sum(col_1d) as c1 from tbl1 where col_1d < 13 group by col_1e order by c1;
+select sum(col_1d) from tbl1 where col_1d > 10;
+select sum(col_1c)+count(col_1c)-avg(col_1c)*min(col_1c)/max(col_1c)%min(col_1c)+max(col_1c) as func from tbl1 group by col_1c;
+CREATE TABLE t1 (spID int,userID int,score smallint);
+INSERT INTO t1 VALUES (1,1,1);
+INSERT INTO t1 VALUES (2,2,2);
+INSERT INTO t1 VALUES (2,1,4);
+INSERT INTO t1 VALUES (3,3,3);
+INSERT INTO t1 VALUES (1,1,5);
+INSERT INTO t1 VALUES (4,6,10);
+INSERT INTO t1 VALUES (5,11,99);
+select * from t1 where CAST(spID AS CHAR)='1';
+select CAST(userID AS CHAR) userid_cast from t1 where CAST(spID AS CHAR)='1';
+select spID+score from t1;
+drop table if exists t1;
+create table t1(a date);
+insert into t1 values('2021-12-23');
+insert into t1 values('2021-12-24');
+select year(a) from t1;
+drop table if exists t1;
+create table t1(a int ,b float);
+insert into t1 values(1,0.5);
+insert into t1 values(2,0.499);
+insert into t1 values(3,0.501);
+insert into t1 values(4,20.5);
+insert into t1 values(5,20.499);
+insert into t1 values(6,13.500);
+insert into t1 values(7,-0.500);
+insert into t1 values(8,-0.499);
+insert into t1 values(9,-0.501);
+insert into t1 values(10,-20.499);
+insert into t1 values(11,-20.500);
+insert into t1 values(12,-13.500);
+select a,round(b) from t1;
+select a,round(b,-1) from t1;
+select round(a*b) from t1;
+select a,floor(b) from t1;
+select sum(round(b)) from t1;
+select sum(floor(b)) from t1;
+select a,sum(floor(b)) from t1 group by a order by a;
+select a,floor(b) as floorb from t1 order by floorb desc;
+select a,avg(round(b)) as roundb from t1 where a>3 group by a order by roundb;
+select a,avg(round(b)) as roundb from t1 where a in (3,5,7) group by a order by roundb;
+select a,round(b,2),max(b) from t1 group by b order by a;
+drop table if exists t1;
+CREATE TABLE IF NOT EXISTS t1 (
+pub_id varchar(8) COLLATE latin1_general_ci NOT NULL DEFAULT '',
+pub_name varchar(50) COLLATE latin1_general_ci NOT NULL DEFAULT '',
+pub_city varchar(25) COLLATE latin1_general_ci NOT NULL DEFAULT '',
+country varchar(25) COLLATE latin1_general_ci NOT NULL DEFAULT '',
+country_office varchar(25) COLLATE latin1_general_ci NOT NULL DEFAULT '',
+no_of_branch int NOT NULL DEFAULT 0,
+estd date NOT NULL DEFAULT '2000-01-01'
+);
+INSERT INTO t1 (pub_id, pub_name, pub_city, country, country_office, no_of_branch, estd) VALUES
+('P001', 'Jex Max Publication', 'New York', 'USA', 'New York', 15, '1969-12-25'),
+('P002', 'BPP Publication', 'Mumbai', 'India', 'New Delhi', 10, '1985-10-01'),
+('P003', 'New Harrold Publication', 'Adelaide', 'Australia', 'Sydney', 6, '1975-09-05'),
+('P004', 'Ultra Press Inc.', 'London', 'UK', 'London', 8, '1948-07-10'),
+('P005', 'Mountain Publication', 'Houstan', 'USA', 'Sun Diego', 25, '1975-01-01'),
+('P006', 'Summer Night Publication', 'New York', 'USA', 'Atlanta', 10, '1990-12-10'),
+('P007', 'Pieterson Grp. of Publishers', 'Cambridge', 'UK', 'London', 6, '1950-07-15'),
+('P008', 'Novel Publisher Ltd.', 'New Delhi', 'India', 'Bangalore', 10, '2000-01-01');
+SELECT pub_name, SUBSTR(pub_name,4,5) FROM t1 WHERE country='USA';
+SELECT pub_name, SUBSTR(pub_name,5) FROM t1 WHERE country='USA';
diff --git a/cases/insert.test b/cases/insert.test
new file mode 100644
index 000000000..9a7e2f344
--- /dev/null
+++ b/cases/insert.test
@@ -0,0 +1,33 @@
+drop table if exists names;
+create table names(id int PRIMARY KEY AUTO_INCREMENT,name VARCHAR(255) UNIQUE,age int);
+insert into names(name, age) values("Abby", 24);
+insert into names(name, age) values("Bob", 25);
+insert into names(name, age) values("Carol", 23);
+insert into names(name, age) values("Dora", 29);
+select id,name,age from names;
+drop table if exists weights;
+create table weights(a int unique);
+insert into weights values(1);
+select * from weights;
+drop table if exists test;
+create table test(id int primary key, name varchar(10), age int);
+insert into test values(1, 'Abby', 20);
+insert into test values(2, 'Bob', 21);
+select id,name,age from test;
+drop table if exists pet;
+create table pet(name char(10),owner char(10), species char(10), gender char(1), weight float,age int);
+insert into pet values ('Sunsweet01','Dsant01','otter','f',30.11,2),
+('Sunsweet02','Dsant02','otter','m',30.11,3);
+insert into pet(name, owner, species, gender, weight, age) values ('Sunsweet03','Dsant01','otter','f',30.11,2),
+('Sunsweet04','Dsant02','otter','m',30.11,3);
+select * from pet;
+drop table if exists t1;
+create table t1 (a bigint unsigned not null, primary key(a));
+insert into t1 values (18446744073709551615), (0xFFFFFFFFFFFFFFFE), (18446744073709551613), (18446744073709551612);
+select * from t1;
+drop table if exists t1;
+create table t1 (name char(20) not null primary key ) charset latin1;
+insert into t1 values ("å");
+insert into t1 values ("ä");
+insert into t1 values ("ö");
+select * from t1 order by name;
diff --git a/cases/join.test b/cases/join.test
new file mode 100644
index 000000000..7e83dd25c
--- /dev/null
+++ b/cases/join.test
@@ -0,0 +1,130 @@
+drop table if exists t1,t2;
+CREATE TABLE t1 (S1 INT);
+CREATE TABLE t2 (S1 INT);
+INSERT INTO t1 VALUES (1),(3),(4),(6);
+INSERT INTO t2 VALUES (2),(4),(5);
+SELECT * FROM t1 JOIN t2 on t1.S1=t2.S1;
+drop table if exists t1,t2;
+create table t1 (id int);
+create table t2 (id int);
+insert into t1 values (75);
+insert into t1 values (79);
+insert into t1 values (78);
+insert into t1 values (77);
+insert into t1 values (76);
+insert into t1 values (76);
+insert into t1 values (104);
+insert into t1 values (103);
+insert into t1 values (102);
+insert into t1 values (101);
+insert into t1 values (105);
+insert into t1 values (106);
+insert into t1 values (107);
+insert into t2 values (107),(75),(1000);
+select t1.id, t2.id from t1, t2 where t2.id = t1.id;
+select t1.id, count(t2.id) from t1,t2 where t2.id = t1.id group by t1.id;
+select t1.id, count(t2.id) from t1,t2 where t2.id = t1.id group by t2.id;
+select t1.id,t2.id from t2 join t1 on t1.id=t2.id where t2.id=75;
+drop table if exists t1,t2;
+CREATE TABLE t1 (
+id int,
+token varchar(100) DEFAULT '' NOT NULL,
+count int DEFAULT 0 NOT NULL,
+qty int,
+phone char(1) DEFAULT '' NOT NULL,
+times datetime DEFAULT '2000-01-01 00:00:00' NOT NULL
+);
+INSERT INTO t1 VALUES (21,'e45703b64de71482360de8fec94c3ade',3,7800,'n','1999-12-23 17:22:21');
+INSERT INTO t1 VALUES (22,'e45703b64de71482360de8fec94c3ade',4,5000,'y','1999-12-23 17:22:21');
+INSERT INTO t1 VALUES (18,'346d1cb63c89285b2351f0ca4de40eda',3,13200,'b','1999-12-23 11:58:04');
+INSERT INTO t1 VALUES (17,'ca6ddeb689e1b48a04146b1b5b6f936a',4,15000,'b','1999-12-23 11:36:53');
+INSERT INTO t1 VALUES (16,'ca6ddeb689e1b48a04146b1b5b6f936a',3,13200,'b','1999-12-23 11:36:53');
+INSERT INTO t1 VALUES (26,'a71250b7ed780f6ef3185bfffe027983',5,1500,'b','1999-12-27 09:44:24');
+INSERT INTO t1 VALUES (24,'4d75906f3c37ecff478a1eb56637aa09',3,5400,'y','1999-12-23 17:29:12');
+INSERT INTO t1 VALUES (25,'4d75906f3c37ecff478a1eb56637aa09',4,6500,'y','1999-12-23 17:29:12');
+INSERT INTO t1 VALUES (27,'a71250b7ed780f6ef3185bfffe027983',3,6200,'b','1999-12-27 09:44:24');
+INSERT INTO t1 VALUES (28,'a71250b7ed780f6ef3185bfffe027983',3,5400,'y','1999-12-27 09:44:36');
+INSERT INTO t1 VALUES (29,'a71250b7ed780f6ef3185bfffe027983',4,17700,'b','1999-12-27 09:45:05');
+CREATE TABLE t2 (
+id int,
+category int DEFAULT 0 NOT NULL,
+county int DEFAULT 0 NOT NULL,
+state int DEFAULT 0 NOT NULL,
+phones int DEFAULT 0 NOT NULL,
+nophones int DEFAULT 0 NOT NULL
+);
+INSERT INTO t2 VALUES (3,2,11,12,5400,7800);
+INSERT INTO t2 VALUES (4,2,25,12,6500,11200);
+INSERT INTO t2 VALUES (5,1,37,6,10000,12000);
+select t1.id, category as catid, state as stateid, county as countyid from t1 join t2 on count=t2.id where token='a71250b7ed780f6ef3185bfffe027983';
+select t1.id, category as catid, state as stateid, county as countyid from t1 join t2 on count=t2.id where token='a71250b7ed780f6ef3185bfffe027983' and t1.id>26 order by t1.id;
+drop table if exists t1,t2,t3;
+CREATE TABLE t1 (
+t1_id int default NULL,
+t2_id int default NULL,
+type varchar(12) default NULL,
+cost_unit varchar(5) default NULL,
+min_value double default NULL,
+max_value double default NULL,
+t3_id int default NULL,
+item_id int default NULL
+);
+CREATE TABLE t2 (
+id int NOT NULL auto_increment,
+name varchar(255) default NULL,
+PRIMARY KEY (id)
+);
+INSERT INTO t1 VALUES (12,5,'Percent','Cost',-1,0,-1,-1),(14,4,'Percent','Cost',-1,0,-1,-1),(18,5,'Percent','Cost',-1,0,-1,-1),(19,4,'Percent','Cost',-1,0,-1,-1),(20,5,'Percent','Cost',100,-1,22,291),(21,5,'Percent','Cost',100,-1,18,291),(22,1,'Percent','Cost',100,-1,6,291),(23,1,'Percent','Cost',100,-1,21,291),(24,1,'Percent','Cost',100,-1,9,291),(25,1,'Percent','Cost',100,-1,4,291),(26,1,'Percent','Cost',100,-1,20,291),(27,4,'Percent','Cost',100,-1,7,202),(28,1,'Percent','Cost',50,-1,-1,137),(29,2,'Percent','Cost',100,-1,4,354),(30,2,'Percent','Cost',100,-1,9,137),(93,2,'Cost','Cost',-1,10000000,-1,-1);
+INSERT INTO t2 VALUES (1,'s1'),(2,'s2'),(3,'s3'),(4,'s4'),(5,'s5');
+select t2_id,name, type from t1 join t2 on t2.id=t1.t2_id order by id;
+drop table t1,t2;
+CREATE TABLE t1 (ID INTEGER NOT NULL PRIMARY KEY, Value1 VARCHAR(255));
+CREATE TABLE t2 (ID INTEGER NOT NULL PRIMARY KEY, Value2 VARCHAR(255));
+INSERT INTO t1 VALUES (1, 'A');
+INSERT INTO t2 VALUES (1, 'B');
+SELECT t1.ID,Value2 FROM t1 JOIN t2 on t1.ID=t2.ID WHERE Value1 = 'A';
+SELECT t1.ID,Value2 FROM t1 JOIN t2 on t1.ID=t2.ID WHERE Value1 = 'A' and Value2 <> 'B';
+drop table if exists t1,t2,t3;
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (b int);
+CREATE TABLE t3 (c int);
+insert into t1 values(1),(2),(3),(4),(5);
+insert into t2 values(1),(3),(5),(7),(9);
+insert into t3 values(1),(1),(3),(4),(7);
+select a,b,c from t1 join t2 on t1.a=t2.b join t3 on t1.a=t3.c where a>1;
+DROP TABLE if exists t1, t2, t3;
+create table t1 (i int);
+create table t2 (i int);
+create table t3 (i int);
+insert into t1 values(1),(2);
+insert into t2 values(2),(3);
+insert into t3 values (2),(4);
+select t3.i from t1 join t2 on t1.i=t2.i join t3 on t2.i=t3.i;
+DROP TABLE if exists t1,t2,t3,t4,t5,t6;
+create table t1 (c int, b int);
+create table t2 (a int, b int);
+create table t3 (b int, c int);
+create table t4 (y int, c int);
+create table t5 (y int, z int);
+create table t6 (a int, c int);
+insert into t1 values (10,1);
+insert into t1 values (3 ,1);
+insert into t1 values (3 ,2);
+insert into t2 values (2, 1);
+insert into t3 values (1, 3);
+insert into t3 values (1,10);
+insert into t4 values (11,3);
+insert into t4 values (2, 3);
+insert into t5 values (11,4);
+insert into t6 values (2, 3);
+select distinct a,t1.b,t3.c from t1 join t2 on t1.b=t2.b join t3 on t1.b=t3.c;
+drop table if exists t1,t2,t3,t4;
+create table t1 (a1 int, a2 int);
+create table t2 (a1 int, b int);
+create table t3 (c1 int, c2 int);
+create table t4 (c2 int);
+insert into t1 values (1,1);
+insert into t2 values (1,1);
+insert into t3 values (1,1);
+insert into t4 values (1);
+select * from t1 join t2 on t1.a1=t2.a1 join t3 on b=c1 join t4 on t3.c2=t4.c2;
diff --git a/cases/operator.test b/cases/operator.test
new file mode 100644
index 000000000..2576d8480
--- /dev/null
+++ b/cases/operator.test
@@ -0,0 +1,107 @@
+drop table if exists t1;
+create table t1 (spID smallint,userID bigint,score int);
+insert into t1 values (1,1,1);
+insert into t1 values (2,2,2);
+insert into t1 values (2,1,4);
+insert into t1 values (3,3,3);
+insert into t1 values (1,1,5);
+insert into t1 values (4,6,10);
+insert into t1 values (5,11,99);
+create table t2(product VARCHAR(32),country_id INTEGER NOT NULL,year INTEGER,profit INTEGER);
+insert into t2 values ( 'Computer', 2,2000, 1200),
+( 'TV', 1, 1999, 150),
+( 'Calculator', 1, 1999,50),
+( 'Computer', 1, 1999,1500),
+( 'Computer', 1, 2000,1500),
+( 'TV', 1, 2000, 150),
+( 'TV', 2, 2000, 100),
+( 'TV', 2, 2000, 100),
+( 'Calculator', 1, 2000,75),
+( 'Calculator', 2, 2000,75),
+( 'TV', 1, 1999, 100),
+( 'Computer', 1, 1999,1200),
+( 'Computer', 2, 2000,1500),
+( 'Calculator', 2, 2000,75),
+( 'Phone', 3, 2003,10);
+select userID,spID,score from t1 where userID=spID and userID<>score;
+select userID,spID,score from t1 where userID=spID and userID!=score;
+select userID,spID,score from t1 where userID between spID and score;
+select userID,spID,score from t1 where userID not between spID and score;
+select * from t1 where userID between 3 and 6;
+select userID,spID,score from t1 where spID>=userID*score;
+select userID,score,spID from t1 where userID<=score/spID;
+select spID,userID,score from t1 where spID>(userID-1);
+select spID,userID,score from t1 where score<(spID*userID+1);
+select userID, AVG(score) from t1 WHERE spID=2 group by userID order by userID;
+select product, SUM(profit) from t2 where year>1999 group by product order by product desc;
+select product, SUM(profit),AVG(profit) from t2 where product!='TV' group by product order by product asc;
+select product, SUM(profit),AVG(profit) from t2 where product<>'TV' group by product order by product asc;
+select product, SUM(profit),AVG(profit) from t2 where product='Phone' group by product order by product asc;
+select product, SUM(profit) from t2 where year>1999 and year<=2002 group by product order by product desc;
+select * from t1 where 2<10;
+select userID, userID DIV 2 as user_div, userID%2 as user_percent, userID MOD 2 as user_mod from t1 WHERE userID > 3;
+select * from t1 where userID-2>2 && (userID+spID)/3<>0 && score MOD 2 > 0;
+select * from t1 where spID >2 && userID < 6 && score != 1;
+drop table if exists t2;
+create table t2(c1 int, c2 int);
+insert into t2 values (-3, 2);
+insert into t2 values (1, 2);
+select -c1 from t2;
+select c1, c2 from t2 order by -c1 desc;
+drop table if exists t3;
+create table t3 (c1 varchar(80));
+insert into t3 values ("a"),
+("abc"),
+("abcd"),
+("hello"),
+("test"),
+("C:\Program Files(x86)"),
+("C:\\Program Files(x86)");
+select * from t3;
+create database if not exists likedb;
+create database if not exists dblike;
+show databases like 'like%';
+show databases like "%like%";
+show databases like "%aa%";
+drop database likedb;
+drop database dblike;
+SELECT * FROM t1 where t1.userID<6 OR NOT t1.userID;
+SELECT * FROM t1 where NOT t1.userID OR t1.userID<6;
+SELECT * FROM t1 where NOT t1.userID || t1.userID<6;
+drop table if exists t1;
+create table t1 (a int);
+insert into t1 values (0),(1),(NULL);
+select * from t1;
+select * from t1 where not a between 2 and 3;
+drop table if exists t3;
+CREATE TABLE t3(
+cont_nr int(11) NOT NULL auto_increment primary key,
+ver_nr int(11) NOT NULL default 0,
+aufnr int(11) NOT NULL default 0,
+username varchar(50) NOT NULL default ''
+);
+INSERT INTO t3 VALUES (3359356,405,3359356,'Mustermann Musterfrau');
+INSERT INTO t3 VALUES (3359357,468,3359357,'Mustermann Musterfrau');
+INSERT INTO t3 VALUES (3359359,468,3359359,'Mustermann musterfrau');
+INSERT INTO t3 VALUES (3359360,0,0,'Mustermann Masterfrau');
+INSERT INTO t3 VALUES (3359361,406,3359361,'Mastermann Masterfrau');
+INSERT INTO t3 VALUES (3359362,406,3359362,'Mustermann MusterFrau');
+select username from t3 where username like 'Ma%';
+select username from t3 where username like '%Frau';
+select username from t3 where username like '%Mast%';
+select username from t3 where username like '%a_t%';
+drop table if exists t2;
+create table t2(a int,b varchar(5),c float, d date, e datetime);
+insert into t2 values(1,'a',1.001,'2022-02-08','2022-02-08 12:00:00');
+insert into t2 values(2,'b',2.001,'2022-02-09','2022-02-09 12:00:00');
+insert into t2 values(1,'c',3.001,'2022-02-10','2022-02-10 12:00:00');
+insert into t2 values(4,'d',4.001,'2022-02-11','2022-02-11 12:00:00');
+select * from t2 where a in (2,4);
+select * from t2 where a not in (2,4);
+select * from t2 where c in (2.001,2.002);
+select * from t2 where b not in ('e',"f");
+select sum(a),c from t2 where a in (1,2) and d in ('2022-02-10','2022-02-11') group by c order by c;
+select * from t2 where d in ('20220208','2022-02-09');
+select * from t2 where e not in ('2022-02-09 12:00:00') and a in (4,5);
+select sum(a) as suma,e from t2 where e not in ('2022-02-09 12:00:00') and a in (4,5) group by e order by suma;
+select * from t2 where c in (2.001,3);
\ No newline at end of file
diff --git a/cases/select.test b/cases/select.test
new file mode 100644
index 000000000..8a4c10311
--- /dev/null
+++ b/cases/select.test
@@ -0,0 +1,182 @@
+drop table if exists t1;
+create table t1 (spID int,userID int,score smallint);
+insert into t1 values (1,1,1);
+insert into t1 values (2,2,2);
+insert into t1 values (2,1,4);
+insert into t1 values (3,3,3);
+insert into t1 values (1,1,5);
+insert into t1 values (4,6,10);
+insert into t1 values (5,11,99);
+select userID, MIN(score) from t1 group by userID order by userID desc;
+select userID, MIN(score) from t1 group by userID order by userID asc;
+select userID, SUM(score) from t1 group by userID order by userID desc;
+select userID as a, MIN(score) as b from t1 group by userID order by userID;
+select userID as user, MAX(score) as max from t1 group by userID order by user;
+select userID as user, MAX(score) as max from t1 group by userID order by max desc;
+select userID,count(score) from t1 group by userID having count(score)>1 order by userID;
+select userID,count(score) from t1 where userID>2 group by userID having count(score)>1 order by userID;
+select distinct userID, count(score) from t1 group by userID order by userID;
+select distinct spID,userID from t1;
+select distinct spID,userID from t1 where score>2;
+select distinct spID,userID from t1 where score>2 order by spID asc;
+select distinct spID,userID from t1 where spID>2 order by userID desc;
+select distinct sum(spID) as sum from t1 group by userID order by sum asc;
+select distinct sum(spID) as sum from t1 where score>1 group by userID order by sum asc;
+select userID,MAX(score) from t1 where userID between 2 and 3 group by userID order by userID;
+select userID,MAX(score) from t1 where userID not between 2 and 3 group by userID order by userID desc;
+select spID,userID,score from t1 limit 2,1;
+select spID,userID,score from t1 limit 2 offset 1;
+select sum(score) as sum from t1 where spID=6 group by score order by sum desc;
+select userID, userID DIV 2 as user_dir, userID%2 as user_percent, userID MOD 2 as user_mod from t1;
+drop table if exists a;
+create table a(a int);
+insert into a values(1),(2),(3),(4),(5),(6),(7),(8);
+select count(*) from a where a>=2 and a<=8;
+drop table if exists t1;
+create table t1 ( id int, name varchar(50) );
+insert into t1 values (1, 'aaaaa');
+insert into t1 values (3, "aaaaa");
+insert into t1 values (2, 'eeeeeee');
+select distinct name as name1 from t1;
+drop table if exists t2;
+create table t2(name char(10),owner char(10), species char(10), gender char(1), weight float,age int);
+insert into t2 values ('Sunsweet01','Dsant01','otter','f',30.11,2), ('Sunsweet02','Dsant02','otter','m',30.11,3);
+insert into t2(name, owner, species, gender, weight, age) values ('Sunsweet03','Dsant01','otter','f',30.11,2), ('Sunsweet04','Dsant02','otter','m',30.11,3);
+select * from t2 limit 2, 18446744073709551615;
+drop table if exists t3;
+create table t3 (spID int,userID int,score smallint);
+insert into t3 values (1,1,1);
+insert into t3 values (2,2,2);
+insert into t3 values (2,1,4);
+insert into t3 values (3,3,3);
+insert into t3 values (1,1,5);
+insert into t3 values (4,6,10);
+insert into t3 values (5,11,99);
+select userID,MAX(score) max_score from t3 where userID <2 || userID > 3 group by userID order by max_score;
+select userID, userID DIV 2 as user_dir, userID%2 as user_percent, userID MOD 2 as user_mod from t3 where userID > 3 ;
+select CAST(userID AS CHAR) userid_cast, userID from t3 where CAST(spID AS CHAR)='1';
+select CAST(userID AS DOUBLE) cast_double, CAST(userID AS FLOAT(3)) cast_float , CAST(userID AS REAL) cast_real, CAST(userID AS SIGNED) cast_signed, CAST(userID AS UNSIGNED) cast_unsigned from t3 limit 2;
+select * from t3 where spID>2 AND userID <2 || userID >=2 OR userID < 2 limit 3;
+select * from t3 where (spID >2 or spID <= 2) && score <> 1 AND userID/2>2;
+select * from t3 where spID >2 || spID <= 2 && score !=1 limit 3;
+select userID,MAX(score) max_score from t3 where userID <2 || userID > 3 group by userID order by max_score;
+select * from t3 where userID/2>2;
+drop table if exists t4;
+create table t4(c1 int, c2 int);
+insert into t4 values (-3, 2);
+insert into t4 values (1, 2);
+select c1, -c2 from t4 order by -c1 desc;
+drop table if exists t5;
+create table t5(a int,b varchar(10),c varchar(10));
+insert into t5 values(1,'ab','cd'),(2,'ba','dc'),(3,'bc','de'),(4,'cb','ed'),(5,'cd','ef'),(6,'dc','fe'),(2,'de','fg'),(1,'ed','gf');
+select * from t5 where (b='ba' or b='cb') and (c='dc' or c='ed');
+drop table if exists tbl_01;
+create table tbl_01 (col1 int, a bigint unsigned, c char(10) not null);
+insert into tbl_01 values (1,1,"a");
+insert into tbl_01 values (2,2,"b");
+insert into tbl_01 values (2,3,"c");
+insert into tbl_01 values (3,4,"E");
+insert into tbl_01 values (3,5,"C");
+insert into tbl_01 values (3,6,"D");
+select a,c,sum(a) from tbl_01 group by a;
+drop table if exists t1;
+drop table if exists t2;
+create table t1 (id int primary key);
+create table t2 (id int);
+insert into t1 values (75);
+insert into t1 values (79);
+insert into t1 values (78);
+insert into t1 values (77);
+insert into t1 values (104);
+insert into t1 values (103);
+insert into t1 values (102);
+insert into t1 values (101);
+insert into t1 values (105);
+insert into t1 values (106);
+insert into t1 values (107);
+insert into t2 values (107),(75),(1000);
+select t1.id, count(t2.id) from t1,t2 where t2.id = t1.id group by t1.id order by t1.id desc;
+drop table t1;
+create table t1 ( a int not null default 1, big bigint );
+insert into t1 (big) values (-1),(12345678901234567),(9223372036854775807);
+select * from t1;
+select min(big),max(big),max(big)-1 from t1;
+drop table t1;
+create table t1 ( a int not null default 1, big bigint unsigned);
+insert into t1 (big) values (12345678901234567),(9223372036854775807),(18446744073709551615);
+select * from t1;
+select min(big),max(big),max(big)-1 from t1;
+select min(big),max(big),max(big)-1 from t1 group by a;
+drop table if exists t1;
+create table t1 (
+value64 bigint unsigned not null,
+value32 int not null
+);
+insert into t1 values(17156792991891826145, 1);
+insert into t1 values(9223372036854775807, 2);
+select * from t1;
+drop table if exists t1,t2,t3;
+create table t1 (libname1 varchar(21) not null primary key, city varchar(20));
+create table t2 (isbn2 varchar(21) not null primary key, author varchar(20), title varchar(60));
+create table t3 (isbn3 varchar(21) not null, libname3 varchar(21) not null, quantity int);
+insert into t2 values ('001','Daffy','Aducklife');
+insert into t2 values ('002','Bugs','Arabbitlife');
+insert into t2 values ('003','Cowboy','Lifeontherange');
+insert into t2 values ('000','Anonymous','Wannabuythisbook?');
+insert into t2 values ('004','BestSeller','OneHeckuvabook');
+insert into t2 values ('005','EveryoneBuys','Thisverybook');
+insert into t2 values ('006','SanFran','Itisasanfranlifestyle');
+insert into t2 values ('007','BerkAuthor','Cool.Berkley.the.book');
+insert into t3 values('000','NewYorkPublicLibra',1);
+insert into t3 values('001','NewYorkPublicLibra',2);
+insert into t3 values('002','NewYorkPublicLibra',3);
+insert into t3 values('003','NewYorkPublicLibra',4);
+insert into t3 values('004','NewYorkPublicLibra',5);
+insert into t3 values('005','NewYorkPublicLibra',6);
+insert into t3 values('006','SanFransiscoPublic',5);
+insert into t3 values('007','BerkeleyPublic1',3);
+insert into t3 values('007','BerkeleyPublic2',3);
+insert into t3 values('001','NYC Lib',8);
+insert into t1 values ('NewYorkPublicLibra','NewYork');
+insert into t1 values ('SanFransiscoPublic','SanFran');
+insert into t1 values ('BerkeleyPublic1','Berkeley');
+insert into t1 values ('BerkeleyPublic2','Berkeley');
+insert into t1 values ('NYCLib','NewYork');
+select city,libname1,count(libname1) as a from t3 join t1 on libname1=libname3 join t2 on isbn3=isbn2 group by city,libname1;
+drop table if exists t1;
+create table t1(a int,b varchar(5));
+insert into t1 values(1,'a');
+insert into t1 values(null,null);
+insert into t1 values(null,'b');
+insert into t1 values(1,null);
+select avg(a),b from t1 group by b order by b;
+drop table if exists t1;
+CREATE TABLE t1 (a int LL);
+INSERT INTO t1 VALUES (NULL),(NULL);
+select * from t1;
+DROP TABLE if EXISTS t1,t2;
+create table t1 (a int, b int);
+insert into t1 values(10,null);
+create table t2 (c int, d int);
+insert into t2 values(20,null);
+select * from t1 join t2 on a=c group by a order by a;
+drop table if exists t1;
+CREATE TABLE t1 (a int default null, b varchar(16) default null, c datetime DEFAULT null);
+INSERT INTO t1(a, c) values (1,"2003-01-14 03:54:55");
+INSERT INTO t1(a, c) values (1,"2004-01-14 03:54:55");
+INSERT INTO t1(a, c) values (1,"2005-01-14 03:54:55");
+INSERT INTO t1(a, b) values (1,"2022year");
+INSERT INTO t1(b,c) values ("2022year","2003-01-14 03:54:55");
+INSERT INTO t1(b,c) values ("2021year","2003-01-14 03:54:55");
+INSERT INTO t1(b,c) values ("2020year","2003-01-14 03:54:55");
+select max(a),b,c from t1 group by b,c order by b,c;
+drop table if exists t1;
+create table t1(i int);
+insert into t1 values(1),(2),(3),(4),(5);
+insert into t1 values(null);
+select count(*) from t1 where i=2;
+drop table if exists t1;
+CREATE TABLE t1 (c0 varchar(0) DEFAULT NULL);
+insert into t1 values();
+insert into t1 values('');
+select * from t1;
diff --git a/cases/show.test b/cases/show.test
new file mode 100644
index 000000000..8d58b54f2
--- /dev/null
+++ b/cases/show.test
@@ -0,0 +1,8 @@
+drop database if exists test01;
+create database test01;
+use test01;
+create table t1 (id int not null, str char(10),name varchar(10));
+create table t2 (a int);
+show tables;
+show tables from test01;
+show columns from t1;
diff --git a/cases/subquery.sql b/cases/subquery.sql
new file mode 100644
index 000000000..a17f0df9f
--- /dev/null
+++ b/cases/subquery.sql
@@ -0,0 +1,93 @@
+create database if not exists sub;
+use sub;
+drop table if exists t1;
+create table t1 (id int,ti tinyint unsigned,si smallint,bi bigint unsigned,fl float,dl double,de decimal,ch char(20),vch varchar(20),dd date,dt datetime);
+insert into t1 values(1,1,4,3,1113.32,111332,1113.32,'hello','subquery','2022-04-28','2022-04-28 22:40:11');
+insert into t1 values(2,2,5,2,2252.05,225205,2252.05,'bye','sub query','2022-04-28','2022-04-28 22:40:11');
+insert into t1 values(3,6,6,3,3663.21,366321,3663.21,'hi','subquery','2022-04-28','2022-04-28 22:40:11');
+insert into t1 values(4,7,1,5,4715.22,471522,4715.22,'good morning','my subquery','2022-04-28','2022-04-28 22:40:11');
+insert into t1 values(5,1,2,6,51.26,5126,51.26,'byebye',' is subquery?','2022-04-28','2022-04-28 22:40:11');
+insert into t1 values(6,3,2,1,632.1,6321,632.11,'good night','maybe subquery','2022-04-28','2022-04-28 22:40:11');
+insert into t1 values(7,4,4,3,7443.11,744311,7443.11,'yes','subquery','2022-04-28','2022-04-28 22:40:11');
+insert into t1 values(8,7,5,8,8758.00,875800,8758.11,'nice to meet','just subquery','2022-04-28','2022-04-28 22:40:11');
+insert into t1 values(9,8,4,9,9849.312,9849312,9849.312,'see you','subquery','2022-04-28','2022-04-28 22:40:11');
+
+drop table if exists t2;
+create table t2 (id int,ti tinyint unsigned,si smallint,bi bigint unsigned,fl float,dl double,de decimal,ch char(20),vch varchar(20),dd date,dt datetime);
+insert into t2 values(1,1,4,3,1113.32,111332,1113.32,'hello','subquery','2022-04-28','2022-04-28 22:40:11');
+insert into t2 values(2,2,5,2,2252.05,225205,2252.05,'bye','sub query','2022-04-28','2022-04-28 22:40:11');
+insert into t2 values(3,6,6,3,3663.21,366321,3663.21,'hi','subquery','2022-04-28','2022-04-28 22:40:11');
+insert into t2 values(4,7,1,5,4715.22,471522,4715.22,'good morning','my subquery','2022-04-28','2022-04-28 22:40:11');
+insert into t2 values(5,1,2,6,51.26,5126,51.26,'byebye',' is subquery?','2022-04-28','2022-04-28 22:40:11');
+insert into t2 values(6,3,2,1,632.1,6321,632.11,'good night','maybe subquery','2022-04-28','2022-04-28 22:40:11');
+insert into t2 values(7,4,4,3,7443.11,744311,7443.11,'yes','subquery','2022-04-28','2022-04-28 22:40:11');
+insert into t2 values(8,7,5,8,8758.00,875800,8758.11,'nice to meet','just subquery','2022-04-28','2022-04-28 22:40:11');
+insert into t2 values(9,8,4,9,9849.312,9849312,9849.312,'see you','subquery','2022-04-28','2022-04-28 22:40:11');
+
+select * from (select * from t1) sub where id > 4;
+select ti as t,fl as f from (select * from t1) sub where dl <> 4;
+select * from (select ti as t,fl as f from t1 where dl <> 4) sub;
+
+select id,min(ti) from (select * from t1) sub group by id;
+select * from (select id,min(ti) from (select * from t1) t1 group by id) sub;
+
+--待确认
+--select id,min(ti) from (select * from t1) sub order by id desc;
+--select * from (select id,min(ti) from t1 sub order by id desc) sub;
+
+select id,min(ti) from (select * from t1) sub group by id order by id desc;
+select id,sum(ti) from (select * from t1) sub group by id;
+
+select distinct(ti) from (select * from t1) sub;
+select distinct(ti) from (select * from t1) sub where id <6;
+
+-- mysql 不同,待确认
+select distinct(ti),de from (select * from t1) sub where id < 6 order by ti asc;
+
+select count(*) from (select * from t1) sub where id > 4 ;
+select * from (select * from t1) sub where id > 1 limit 3;
+select max(ti),min(si),avg(fl) from (select * from t1) sub where id < 4 || id > 5;
+select max(ti)+10,min(si)-1,avg(fl) from (select * from t1) sub where id < 4 || id > 5;
+
+select substr from (select * from t1) sub where id < 4 || id > 5;
+
+select ti,-si from (select * from t1) sub order by -si desc;
+
+select * from (select * from t1) sub where (ti=2 or si=3) and (ch = 'bye' or vch = 'subquery');
+
+select * from (select * from (select * from (select id,ti,si,de from (select * from t1 ) sub3 where fl <> 4.5 ) sub2 where ti > 1) sub1 where id >2 ) sub where id > 4;
+
+select * from (select * from t1 where id > 100) sub ;
+
+
+
+-- test for join in subquery
+drop table if exists t1,t2,t3;
+create table t1 (libname1 varchar(21) not null primary key, city varchar(20));
+create table t2 (isbn2 varchar(21) not null primary key, author varchar(20), title varchar(60));
+create table t3 (isbn3 varchar(21) not null, libname3 varchar(21) not null, quantity int);
+insert into t2 values ('001','Daffy','Aducklife');
+insert into t2 values ('002','Bugs','Arabbitlife');
+insert into t2 values ('003','Cowboy','Lifeontherange');
+insert into t2 values ('000','Anonymous','Wannabuythisbook?');
+insert into t2 values ('004','BestSeller','OneHeckuvabook');
+insert into t2 values ('005','EveryoneBuys','Thisverybook');
+insert into t2 values ('006','SanFran','Itisasanfranlifestyle');
+insert into t2 values ('007','BerkAuthor','Cool.Berkley.the.book');
+insert into t3 values('000','NewYorkPublicLibra',1);
+insert into t3 values('001','NewYorkPublicLibra',2);
+insert into t3 values('002','NewYorkPublicLibra',3);
+insert into t3 values('003','NewYorkPublicLibra',4);
+insert into t3 values('004','NewYorkPublicLibra',5);
+insert into t3 values('005','NewYorkPublicLibra',6);
+insert into t3 values('006','SanFransiscoPublic',5);
+insert into t3 values('007','BerkeleyPublic1',3);
+insert into t3 values('007','BerkeleyPublic2',3);
+insert into t3 values('001','NYC Lib',8);
+insert into t1 values ('NewYorkPublicLibra','NewYork');
+insert into t1 values ('SanFransiscoPublic','SanFran');
+insert into t1 values ('BerkeleyPublic1','Berkeley');
+insert into t1 values ('BerkeleyPublic2','Berkeley');
+insert into t1 values ('NYCLib','NewYork');
+select * from (select city,libname1,count(libname1) as a from t3 join t1 on libname1=libname3 join t2 on isbn3=isbn2 group by city,libname1) sub ;
+
diff --git a/lib/commons-codec-1.10.jar b/lib/commons-codec-1.10.jar
new file mode 100755
index 000000000..1d7417c40
Binary files /dev/null and b/lib/commons-codec-1.10.jar differ
diff --git a/lib/commons-collections4-4.1.jar b/lib/commons-collections4-4.1.jar
new file mode 100755
index 000000000..43a9413b9
Binary files /dev/null and b/lib/commons-collections4-4.1.jar differ
diff --git a/lib/commons-io-2.6.jar b/lib/commons-io-2.6.jar
new file mode 100755
index 000000000..00556b119
Binary files /dev/null and b/lib/commons-io-2.6.jar differ
diff --git a/lib/commons-lang3-3.7.jar b/lib/commons-lang3-3.7.jar
new file mode 100755
index 000000000..f37ded60f
Binary files /dev/null and b/lib/commons-lang3-3.7.jar differ
diff --git a/lib/commons-text-1.3.jar b/lib/commons-text-1.3.jar
new file mode 100755
index 000000000..0ec9e4814
Binary files /dev/null and b/lib/commons-text-1.3.jar differ
diff --git a/lib/curvesapi-1.04.jar b/lib/curvesapi-1.04.jar
new file mode 100755
index 000000000..f097d0b3a
Binary files /dev/null and b/lib/curvesapi-1.04.jar differ
diff --git a/lib/dom4j-1.6.1.jar b/lib/dom4j-1.6.1.jar
new file mode 100755
index 000000000..c8c4dbb92
Binary files /dev/null and b/lib/dom4j-1.6.1.jar differ
diff --git a/lib/freemarker-2.3.28.jar b/lib/freemarker-2.3.28.jar
new file mode 100755
index 000000000..75edf6c03
Binary files /dev/null and b/lib/freemarker-2.3.28.jar differ
diff --git a/lib/gson-2.8.5.jar b/lib/gson-2.8.5.jar
new file mode 100755
index 000000000..0d5baf3fa
Binary files /dev/null and b/lib/gson-2.8.5.jar differ
diff --git a/lib/hamcrest-2.1.jar b/lib/hamcrest-2.1.jar
new file mode 100755
index 000000000..e323d5e81
Binary files /dev/null and b/lib/hamcrest-2.1.jar differ
diff --git a/lib/hamcrest-core-1.3.jar b/lib/hamcrest-core-1.3.jar
new file mode 100755
index 000000000..9d5fe16e3
Binary files /dev/null and b/lib/hamcrest-core-1.3.jar differ
diff --git a/lib/java-diff-utils-4.7.jar b/lib/java-diff-utils-4.7.jar
new file mode 100755
index 000000000..71554a74f
Binary files /dev/null and b/lib/java-diff-utils-4.7.jar differ
diff --git a/lib/jbehave-core-4.6.jar b/lib/jbehave-core-4.6.jar
new file mode 100755
index 000000000..d10579640
Binary files /dev/null and b/lib/jbehave-core-4.6.jar differ
diff --git a/lib/junit-4.12.jar b/lib/junit-4.12.jar
new file mode 100755
index 000000000..3a7fc266c
Binary files /dev/null and b/lib/junit-4.12.jar differ
diff --git a/lib/log4j-1.2.17.jar b/lib/log4j-1.2.17.jar
new file mode 100755
index 000000000..1d425cf7d
Binary files /dev/null and b/lib/log4j-1.2.17.jar differ
diff --git a/lib/mo-tester-1.0-SNAPSHOT.jar b/lib/mo-tester-1.0-SNAPSHOT.jar
new file mode 100755
index 000000000..0c8fcdfba
Binary files /dev/null and b/lib/mo-tester-1.0-SNAPSHOT.jar differ
diff --git a/lib/mybatis-3.3.0.jar b/lib/mybatis-3.3.0.jar
new file mode 100755
index 000000000..1cc5f4e8b
Binary files /dev/null and b/lib/mybatis-3.3.0.jar differ
diff --git a/lib/mysql-connector-java-8.0.15.jar b/lib/mysql-connector-java-8.0.15.jar
new file mode 100755
index 000000000..fa0979fa7
Binary files /dev/null and b/lib/mysql-connector-java-8.0.15.jar differ
diff --git a/lib/paranamer-2.8.jar b/lib/paranamer-2.8.jar
new file mode 100755
index 000000000..0bf659b93
Binary files /dev/null and b/lib/paranamer-2.8.jar differ
diff --git a/lib/plexus-utils-3.1.0.jar b/lib/plexus-utils-3.1.0.jar
new file mode 100755
index 000000000..d5c008ef5
Binary files /dev/null and b/lib/plexus-utils-3.1.0.jar differ
diff --git a/lib/poi-3.15.jar b/lib/poi-3.15.jar
new file mode 100755
index 000000000..ab368bd61
Binary files /dev/null and b/lib/poi-3.15.jar differ
diff --git a/lib/poi-ooxml-3.15.jar b/lib/poi-ooxml-3.15.jar
new file mode 100755
index 000000000..6de995605
Binary files /dev/null and b/lib/poi-ooxml-3.15.jar differ
diff --git a/lib/poi-ooxml-schemas-3.15.jar b/lib/poi-ooxml-schemas-3.15.jar
new file mode 100755
index 000000000..f3ed2053b
Binary files /dev/null and b/lib/poi-ooxml-schemas-3.15.jar differ
diff --git a/lib/protobuf-java-3.6.1.jar b/lib/protobuf-java-3.6.1.jar
new file mode 100755
index 000000000..8a187891f
Binary files /dev/null and b/lib/protobuf-java-3.6.1.jar differ
diff --git a/lib/snakeyaml-1.26.jar b/lib/snakeyaml-1.26.jar
new file mode 100755
index 000000000..8f301fd04
Binary files /dev/null and b/lib/snakeyaml-1.26.jar differ
diff --git a/lib/stax-api-1.0.1.jar b/lib/stax-api-1.0.1.jar
new file mode 100755
index 000000000..d9a166515
Binary files /dev/null and b/lib/stax-api-1.0.1.jar differ
diff --git a/lib/xml-apis-1.0.b2.jar b/lib/xml-apis-1.0.b2.jar
new file mode 100755
index 000000000..ad33a5afa
Binary files /dev/null and b/lib/xml-apis-1.0.b2.jar differ
diff --git a/lib/xmlbeans-2.6.0.jar b/lib/xmlbeans-2.6.0.jar
new file mode 100755
index 000000000..d1b66271f
Binary files /dev/null and b/lib/xmlbeans-2.6.0.jar differ
diff --git a/lib/xmlpull-1.1.3.1.jar b/lib/xmlpull-1.1.3.1.jar
new file mode 100755
index 000000000..cbc149d0d
Binary files /dev/null and b/lib/xmlpull-1.1.3.1.jar differ
diff --git a/lib/xpp3_min-1.1.4c.jar b/lib/xpp3_min-1.1.4c.jar
new file mode 100755
index 000000000..813a9a830
Binary files /dev/null and b/lib/xpp3_min-1.1.4c.jar differ
diff --git a/lib/xstream-1.4.9.jar b/lib/xstream-1.4.9.jar
new file mode 100755
index 000000000..c754e0ab7
Binary files /dev/null and b/lib/xstream-1.4.9.jar differ
diff --git a/log4j.properties b/log4j.properties
new file mode 100755
index 000000000..fdb1a3930
--- /dev/null
+++ b/log4j.properties
@@ -0,0 +1,19 @@
+# Root logger option
+log4j.rootLogger=INFO, stdout, file
+
+# Redirect log messages to console
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
+
+# Redirect log messages to a log file, support file rolling.
+log4j.appender.file=org.apache.log4j.RollingFileAppender
+log4j.appender.file.File=log/run.log
+log4j.appender.file.MaxFileSize=5MB
+log4j.appender.file.MaxBackupIndex=10
+log4j.appender.file.layout=org.apache.log4j.PatternLayout
+log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
+
+log4j.logger.com.ibatis=DEBUG
+log4j.logger.com.ibatis.common.jdbc.ScriptRunner=DEBUG
\ No newline at end of file
diff --git a/mo.yml b/mo.yml
new file mode 100755
index 000000000..15f9b19ac
--- /dev/null
+++ b/mo.yml
@@ -0,0 +1,23 @@
+#jdbc
+jdbc:
+ driver: "com.mysql.cj.jdbc.Driver"
+ server:
+ - addr: "127.0.0.1:6001"
+ #- addr: "127.0.0.1:3306"
+ #- addr: "127.0.0.1:3306"
+ database:
+ default: "test"
+ paremeter:
+ characterSetResults: "utf8"
+ continueBatchOnError: "false"
+ useServerPrepStmts: "true"
+ alwaysSendSetIsolation: "false"
+ useLocalSessionState: "true"
+ zeroDateTimeBehavior: "CONVERT_TO_NULL"
+ failoverReadOnly: "false"
+ serverTimezone: "Asia/Shanghai"
+
+#users
+user:
+ name: "dump"
+ passwrod: "111"
diff --git a/pom.xml b/pom.xml
new file mode 100755
index 000000000..b92812a5d
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,114 @@
+
+
+
+ 4.0.0
+
+ io.mo
+ mo-tester
+ 1.0-SNAPSHOT
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ 1.8
+ UTF-8
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 2.3.1
+
+
+
+
+ io.mo.Tester
+
+ true
+
+ ./lib
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+
+
+ make-assembly
+ package
+
+ single
+
+
+ assembly.xml
+
+
+
+
+
+
+ jar
+
+ morunner
+ http://maven.apache.org
+
+
+ UTF-8
+
+
+
+
+ junit
+ junit
+ 3.8.1
+ test
+
+
+ org.mybatis
+ mybatis
+ 3.3.0
+
+
+ org.jbehave
+ jbehave-core
+ 4.6
+
+
+ mysql
+ mysql-connector-java
+ 8.0.15
+
+
+ org.yaml
+ snakeyaml
+ 1.26
+
+
+ log4j
+ log4j
+ 1.2.17
+
+
+ io.github.java-diff-utils
+ java-diff-utils
+ 4.7
+
+
+ org.apache.poi
+ poi-ooxml
+ 3.15
+
+
+ dom4j
+ dom4j
+ 1.6.1
+
+
+
diff --git a/result/builtin.result b/result/builtin.result
new file mode 100644
index 000000000..1db6e97a7
--- /dev/null
+++ b/result/builtin.result
@@ -0,0 +1,618 @@
+drop table if exists t1;
+create table t1(a int,b int);
+insert into t1 values(5,-2),(10,3),(100,0),(4,3),(6,-3);
+select power(a,b) from t1;
+power(a, b)
+0.0400
+1000.0000
+1.0000
+64.0000
+0.0046
+select power(a,2) as a1, power(b,2) as b1 from t1 where power(a,2) > power(b,2) order by a1 asc;
+a1 b1
+16.0000 9.0000
+25.0000 4.0000
+36.0000 9.0000
+100.0000 9.0000
+10000.0000 0.0000
+drop table if exists t1;
+create table t1(a date,b datetime);
+insert into t1 values("2022-06-01","2022-07-01 00:00:00");
+insert into t1 values("2022-12-31","2011-01-31 12:00:00");
+select month(a),month(b) from t1;
+month(a) month(b)
+6 7
+12 1
+select * from t1 where month(a)>month(b);
+a b
+2022-12-31 2011-01-31 12:00:00
+select * from t1 where month(a) between 1 and 6;
+a b
+2022-06-01 2022-07-01 00:00:00
+drop table if exists t1;
+create table t1(a varchar(12),c char(30));
+insert into t1 values('sdfad ','2022-02-02 22:22:22');
+insert into t1 values(' sdfad ','2022-02-02 22:22:22');
+insert into t1 values('adsf sdfad','2022-02-02 22:22:22');
+insert into t1 values(' sdfad','2022-02-02 22:22:22');
+select reverse(a),reverse(c) from t1;
+reverse(a) reverse(c)
+ dafds 22:22:22 20-20-2202
+ dafds 22:22:22 20-20-2202
+dafds fsda 22:22:22 20-20-2202
+dafds 22:22:22 20-20-2202
+select a from t1 where reverse(a) like 'daf%';
+a
+adsf sdfad
+ sdfad
+select reverse(a) reversea,reverse(reverse(a)) normala from t1;
+reversea normala
+ dafds sdfad
+ dafds sdfad
+dafds fsda adsf sdfad
+dafds sdfad
+drop table if exists t1;
+create table t1(a int,b float);
+insert into t1 values(0,0),(-15,-20),(-22,-12.5);
+insert into t1 values(0,360),(30,390),(90,450),(180,270),(180,180);
+select acos(a*pi()/180) as acosa,acos(b*pi()/180) acosb from t1;
+acosa acosb
+1.5708 1.5708
+1.8357 1.9274
+1.9649 1.7907
+1.5708 NULL
+1.0197 NULL
+NULL NULL
+NULL NULL
+NULL NULL
+select acos(a*pi()/180)*acos(b*pi()/180) as acosab,acos(acos(a*pi()/180)) as c from t1;
+acosab c
+2.4674 NULL
+3.5380 NULL
+3.5186 NULL
+NULL NULL
+NULL NULL
+NULL NULL
+NULL NULL
+NULL NULL
+select b from t1 where acos(a*pi()/180)<=acos(b*pi()/180) order by a;
+b
+-20.0000
+0.0000
+drop table if exists t1;
+create table t1(a int,b float);
+insert into t1 values(0,0),(-15,-20),(-22,-12.5);
+insert into t1 values(0,360),(30,390),(90,450),(180,270),(180,180);
+select atan(a*pi()/180) as atana,atan(b*pi()/180) atanb from t1;
+atana atanb
+0.0000 0.0000
+-0.2561 -0.3358
+-0.3666 -0.2148
+0.0000 1.4130
+0.4823 1.4249
+1.0039 1.4442
+1.2626 1.3617
+1.2626 1.2626
+select atan(a*pi()/180)*atan(b*pi()/180) as atanab,atan(atan(a*pi()/180)) as c from t1;
+atanab c
+0.0000 0.0000
+0.0860 -0.2507
+0.0787 -0.3514
+0.0000 0.0000
+0.6873 0.4494
+1.4498 0.7873
+1.7193 0.9010
+1.5942 0.9010
+select b from t1 where atan(a*pi()/180)<=atan(b*pi()/180) order by a;
+b
+-12.5000
+0.0000
+360.0000
+390.0000
+450.0000
+270.0000
+180.0000
+drop table if exists t1;
+CREATE TABLE t1(
+Employee_Name VARCHAR(100) NOT NULL,
+Working_At VARCHAR(20) NOT NULL,
+Work_Location VARCHAR(20) NOT NULL,
+Joining_Date DATE NOT NULL,
+Annual_Income INT NOT NULL);
+INSERT INTO t1
+VALUES
+('Amit Khan', 'XYZ Digital', 'Kolkata', '2019-10-06', 350000),
+('Shreetama Pal', 'ABC Corp.', 'Kolkata', '2018-12-16', 500000),
+('Aniket Sharma', 'PQR Soln.', 'Delhi', '2020-01-11', 300000),
+('Maitree Jana', 'XYZ Digital', 'Kolkata', '2019-05-01', 400000),
+('Priyanka Ojha', 'ABC Corp.', 'Delhi', '2019-02-13', 350000),
+('Sayani Mitra', 'XYZ Digital', 'Kolkata', '2019-09-15', 320000),
+('Nitin Dey', 'PQR Soln.', 'Delhi', '2019-10-06', 250000),
+('Sujata Samanta', 'PQR Soln.', 'Kolkata', '2020-10-06', 350000),
+('Sudip Majhi', 'ABC Corp.', 'Delhi', '2018-10-30', 600000),
+('Sanjoy Kohli', 'XYZ Digital', 'Delhi', '2019-04-18', 450000);
+SELECT Working_At, BIT_AND(Annual_Income) AS BITORINCOME FROM t1 group by Working_At;
+working_at bitorincome
+XYZ Digital 262144
+ABC Corp. 65792
+PQR Soln. 4096
+SELECT Work_Location, BIT_AND(Annual_Income) AS BITORINCOME FROM t1 Group By Work_Location;
+work_location bitorincome
+Kolkata 262144
+Delhi 0
+drop table if exists t1;
+CREATE TABLE t1(
+Employee_Name VARCHAR(100) NOT NULL,
+Working_At VARCHAR(20) NOT NULL,
+Work_Location VARCHAR(20) NOT NULL,
+Joining_Date DATE NOT NULL,
+Annual_Income INT NOT NULL);
+INSERT INTO t1
+VALUES
+('Amit Khan', 'XYZ Digital', 'Kolkata', '2019-10-06', 350000),
+('Shreetama Pal', 'ABC Corp.', 'Kolkata', '2018-12-16', 500000),
+('Aniket Sharma', 'PQR Soln.', 'Delhi', '2020-01-11', 300000),
+('Maitree Jana', 'XYZ Digital', 'Kolkata', '2019-05-01', 400000),
+('Priyanka Ojha', 'ABC Corp.', 'Delhi', '2019-02-13', 350000),
+('Sayani Mitra', 'XYZ Digital', 'Kolkata', '2019-09-15', 320000),
+('Nitin Dey', 'PQR Soln.', 'Delhi', '2019-10-06', 250000),
+('Sujata Samanta', 'PQR Soln.', 'Kolkata', '2020-10-06', 350000),
+('Sudip Majhi', 'ABC Corp.', 'Delhi', '2018-10-30', 600000),
+('Sanjoy Kohli', 'XYZ Digital', 'Delhi', '2019-04-18', 450000);
+SELECT Work_Location, BIT_AND(Annual_Income) AS BITORINCOME FROM t1 Group By Work_Location;
+work_location bitorincome
+Kolkata 262144
+Delhi 0
+SELECT Working_At, BIT_AND(Annual_Income) AS BITORINCOME FROM t1 group by Working_At;
+working_at bitorincome
+XYZ Digital 262144
+ABC Corp. 65792
+PQR Soln. 4096
+drop table if exists t1;
+CREATE TABLE t1(
+Employee_Name VARCHAR(100) NOT NULL,
+Working_At VARCHAR(20) NOT NULL,
+Work_Location VARCHAR(20) NOT NULL,
+Joining_Date DATE NOT NULL,
+Annual_Income INT NOT NULL);
+INSERT INTO t1
+VALUES
+('Amit Khan', 'XYZ Digital', 'Kolkata', '2019-10-06', 350000),
+('Shreetama Pal', 'ABC Corp.', 'Kolkata', '2018-12-16', 500000),
+('Aniket Sharma', 'PQR Soln.', 'Delhi', '2020-01-11', 300000),
+('Maitree Jana', 'XYZ Digital', 'Kolkata', '2019-05-01', 400000),
+('Priyanka Ojha', 'ABC Corp.', 'Delhi', '2019-02-13', 350000),
+('Sayani Mitra', 'XYZ Digital', 'Kolkata', '2019-09-15', 320000),
+('Nitin Dey', 'PQR Soln.', 'Delhi', '2019-10-06', 250000),
+('Sujata Samanta', 'PQR Soln.', 'Kolkata', '2020-10-06', 350000),
+('Sudip Majhi', 'ABC Corp.', 'Delhi', '2018-10-30', 600000),
+('Sanjoy Kohli', 'XYZ Digital', 'Delhi', '2019-04-18', 450000);
+SELECT Work_Location, BIT_XOR(Annual_Income) AS BITORINCOME FROM t1 Group By Work_Location;
+work_location bitorincome
+Kolkata 350624
+Delhi 912976
+SELECT Working_At, BIT_XOR(Annual_Income) AS BITORINCOME FROM t1 group by Working_At;
+working_at bitorincome
+XYZ Digital 94816
+ABC Corp. 774608
+PQR Soln. 136256
+drop table if exists t1;
+create table t1(a int,b float);
+insert into t1 values(0,0);
+insert into t1 values(0,360),(30,390),(90,450),(180,270),(180,180);
+select cos(a),cos(b) from t1;
+cos(a) cos(b)
+1.0000 1.0000
+1.0000 -0.2837
+0.1543 0.9037
+-0.4481 -0.7302
+-0.5985 0.9844
+-0.5985 -0.5985
+select cos(a)*cos(b),cos(cos(a)) as c from t1;
+cos(a) * cos(b) c
+1.0000 0.5403
+-0.2837 0.5403
+0.1394 0.9881
+0.3272 0.9013
+-0.5891 0.8262
+0.3582 0.8262
+select distinct a from t1 where cos(a)<=cos(b) order by a desc;
+a
+180
+30
+0
+drop table if exists t1;
+create table t1(a int,b float);
+insert into t1 values(0,0),(-15,-20),(-22,-12.5);
+insert into t1 values(0,360),(30,390),(90,450),(180,270),(180,180);
+select cot(a*pi()/180) as cota,cot(b*pi()/180) cotb from t1;
+cota cotb
+1.0000 1.0000
+1.2679 1.3640
+1.4040 1.2217
+1.0000 1.0000
+0.4226 0.4226
+-16331239353195392.0000 -3266247870639077.5000
+1.0000 -5443746451065130.0000
+1.0000 1.0000
+select cot(a*pi()/180)*cot(b*pi()/180) as cotab,cot(cot(a*pi()/180)) as c from t1;
+cotab c
+1.0000 -0.5574
+1.7294 -2.2004
+1.7153 -4.9406
+1.0000 -0.5574
+0.1786 0.5502
+53341875762271551926265173770240.0000 4.4834
+-5443746451065131.0000 -0.5574
+1.0000 -0.5574
+select b from t1 where cot(a*pi()/180)<=cot(b*pi()/180) order by a;
+b
+-20.0000
+0.0000
+360.0000
+390.0000
+450.0000
+180.0000
+drop table if exists t1;
+create table t1(a date, b datetime,c varchar(30));
+insert into t1 values('2022-01-01','2022-01-01 01:01:01','2022-01-01 01:01:01');
+insert into t1 values('2022-01-01','2022-01-01 01:01:01','2022-01-01 01:01:01');
+insert into t1 values(20220101,'2022-01-01 01:01:01','2022-13-13 01:01:01');
+insert into t1 values('2022-01-02','2022-01-02 23:01:01','2022-01-01 23:01:01');
+insert into t1 values('2021-12-31','2021-12-30 23:59:59','2021-12-30 23:59:59');
+insert into t1 values('2022-06-30','2021-12-30 23:59:59','2021-12-30 23:59:59');
+select distinct dayofyear(a) as dya from t1;
+dya
+1
+2
+365
+181
+select * from t1 where dayofyear(a)>120;
+a b c
+2021-12-31 2021-12-30 23:59:59 2021-12-30 23:59:59
+2022-06-30 2021-12-30 23:59:59 2021-12-30 23:59:59
+select * from t1 where dayofyear(a) between 1 and 184;
+a b c
+2022-01-01 2022-01-01 01:01:01 2022-01-01 01:01:01
+2022-01-01 2022-01-01 01:01:01 2022-01-01 01:01:01
+2022-01-01 2022-01-01 01:01:01 2022-13-13 01:01:01
+2022-01-02 2022-01-02 23:01:01 2022-01-01 23:01:01
+2022-06-30 2021-12-30 23:59:59 2021-12-30 23:59:59
+drop table if exists t1;
+CREATE TABLE t1(a INT,b VARCHAR(100),c CHAR(20));
+INSERT INTO t1
+VALUES
+(1,'Ananya Majumdar', 'XI'),
+(2,'Anushka Samanta', 'X'),
+(3,'Aniket Sharma', 'XI'),
+(4,'Anik Das', 'X'),
+(5,'Riya Jain', 'IX'),
+(6,'Tapan Samanta', 'XI');
+select a,endswith(b,'a') from t1;
+a endswith(b, a)
+1 0
+2 1
+3 1
+4 0
+5 0
+6 1
+select a,b,c from t1 where endswith(b,'a')=1 and endswith(c,'I')=1;
+a b c
+3 Aniket Sharma XI
+6 Tapan Samanta XI
+drop table if exists t1;
+CREATE TABLE t1(Student_id INT,Student_name VARCHAR(100),Student_Class CHAR(20));
+INSERT INTO t1
+VALUES
+(1,'Ananya Majumdar', 'IX'),
+(2,'Anushka Samanta', 'X'),
+(3,'Aniket Sharma', 'XI'),
+(4,'Anik Das', 'X'),
+(5,'Riya Jain', 'IX'),
+(6,'Tapan Samanta', 'X');
+SELECT Student_id, Student_name,LPAD(Student_Class, 10, ' _') AS LeftPaddedString FROM t1;
+student_id student_name leftpaddedstring
+1 Ananya Majumdar _ _ _ _IX
+2 Anushka Samanta _ _ _ _ X
+3 Aniket Sharma _ _ _ _XI
+4 Anik Das _ _ _ _ X
+5 Riya Jain _ _ _ _IX
+6 Tapan Samanta _ _ _ _ X
+SELECT Student_id, lpad(Student_name,4,'new') AS LeftPaddedString FROM t1;
+student_id leftpaddedstring
+1 Anan
+2 Anus
+3 Anik
+4 Anik
+5 Riya
+6 Tapa
+SELECT Student_id, lpad(Student_name,-4,'new') AS LeftPaddedString FROM t1;
+student_id leftpaddedstring
+1 NULL
+2 NULL
+3 NULL
+4 NULL
+5 NULL
+6 NULL
+SELECT Student_id, lpad(Student_name,0,'new') AS LeftPaddedString FROM t1;
+student_id leftpaddedstring
+1
+2
+3
+4
+5
+6
+drop table if exists t1;
+CREATE TABLE t1(Student_id INT,Student_name VARCHAR(100),Student_Class CHAR(20));
+INSERT INTO t1
+VALUES
+(1,'Ananya Majumdar', 'IX'),
+(2,'Anushka Samanta', 'X'),
+(3,'Aniket Sharma', 'XI'),
+(4,'Anik Das', 'X'),
+(5,'Riya Jain', 'IX'),
+(6,'Tapan Samanta', 'X');
+SELECT Student_id, Student_name,RPAD(Student_Class, 10, ' _') AS LeftPaddedString FROM t1;
+student_id student_name leftpaddedstring
+1 Ananya Majumdar IX _ _ _ _
+2 Anushka Samanta X _ _ _ _
+3 Aniket Sharma XI _ _ _ _
+4 Anik Das X _ _ _ _
+5 Riya Jain IX _ _ _ _
+6 Tapan Samanta X _ _ _ _
+SELECT Student_id, rpad(Student_name,4,'new') AS LeftPaddedString FROM t1;
+student_id leftpaddedstring
+1 Anan
+2 Anus
+3 Anik
+4 Anik
+5 Riya
+6 Tapa
+SELECT Student_id, rpad(Student_name,-4,'new') AS LeftPaddedString FROM t1;
+student_id leftpaddedstring
+1 NULL
+2 NULL
+3 NULL
+4 NULL
+5 NULL
+6 NULL
+SELECT Student_id, rpad(Student_name,0,'new') AS LeftPaddedString FROM t1;
+student_id leftpaddedstring
+1
+2
+3
+4
+5
+6
+drop table if exists t1;
+CREATE TABLE t1
+(
+Employee_name VARCHAR(100) NOT NULL,
+Joining_Date DATE NOT NULL
+);
+INSERT INTO t1
+(Employee_name, Joining_Date )
+VALUES
+(' Ananya Majumdar', '2000-01-11'),
+(' Anushka Samanta', '2002-11-10' ),
+(' Aniket Sharma ', '2005-06-11' ),
+(' Anik Das', '2008-01-21' ),
+(' Riya Jain', '2008-02-01' ),
+(' Tapan Samanta', '2010-01-11' ),
+(' Deepak Sharma', '2014-12-01' ),
+(' Ankana Jana', '2018-08-17'),
+(' Shreya Ghosh', '2020-09-10') ;
+SELECT LTRIM( Employee_name) LTrimName,RTRIM(Employee_name) AS RTrimName FROM t1 order by RTrimName desc;
+ltrimname rtrimname
+Shreya Ghosh Shreya Ghosh
+Riya Jain Riya Jain
+Deepak Sharma Deepak Sharma
+Anushka Samanta Anushka Samanta
+Ankana Jana Ankana Jana
+Aniket Sharma Aniket Sharma
+Anik Das Anik Das
+Tapan Samanta Tapan Samanta
+Ananya Majumdar Ananya Majumdar
+SELECT LTRIM(RTRIM(Employee_name)) as TrimName from t1 where Employee_name like '%Ani%' order by TrimName asc;
+trimname
+Anik Das
+Aniket Sharma
+drop table if exists t1;
+create table t1(a int,b float);
+insert into t1 values(0,0);
+insert into t1 values(0,360),(30,390),(90,450),(180,270),(180,180);
+select sin(a),sin(b) from t1;
+sin(a) sin(b)
+0.0000 0.0000
+0.0000 0.9589
+-0.9880 0.4282
+0.8940 -0.6833
+-0.8012 -0.1760
+-0.8012 -0.8012
+select sin(a)*sin(b),sin(sin(a)) as c from t1;
+sin(a) * sin(b) c
+0.0000 0.0000
+0.0000 0.0000
+-0.4231 -0.8349
+-0.6109 0.7796
+0.1410 -0.7182
+0.6418 -0.7182
+select distinct a from t1 where sin(a)<=sin(b) order by a desc;
+a
+180
+30
+0
+drop table if exists t1;
+create table t1(a int,b float);
+insert into t1 values(0,0),(-15,-20),(-22,-12.5);
+insert into t1 values(0,360),(30,390),(90,450),(180,270),(180,180);
+select sinh(a*pi()/180) as sinha,sinh(b*pi()/180) sinhb from t1;
+sinha sinhb
+0.0000 0.0000
+-0.2648 -0.3562
+-0.3935 -0.2199
+0.0000 267.7449
+0.5479 451.9790
+2.3013 1287.9851
+11.5487 55.6544
+11.5487 11.5487
+select sinh(a*pi()/180)*sinh(b*pi()/180) as sinhab,sinh(sinh(a*pi()/180)) as c from t1;
+sinhab c
+0.0000 0.0000
+0.0943 -0.2679
+0.0865 -0.4037
+0.0000 0.0000
+247.6183 0.5757
+2964.0386 4.9435
+642.7381 51823.1467
+133.3734 51823.1467
+select b from t1 where sinh(a*pi()/180)<=sinh(b*pi()/180) order by a;
+b
+-12.5000
+0.0000
+360.0000
+390.0000
+450.0000
+270.0000
+180.0000
+drop table if exists t1;
+CREATE TABLE t1
+(
+Employee_name VARCHAR(100) NOT NULL,
+Joining_Date DATE NOT NULL
+);
+INSERT INTO t1
+(Employee_name, Joining_Date )
+VALUES
+(' Ananya Majumdar', '2000-01-11'),
+(' Anushka Samanta', '2002-11-10' ),
+(' Aniket Sharma ', '2005-06-11' ),
+(' Anik Das', '2008-01-21' ),
+(' Riya Jain', '2008-02-01' ),
+(' Tapan Samanta', '2010-01-11' ),
+(' Deepak Sharma', '2014-12-01' ),
+(' Ankana Jana', '2018-08-17'),
+(' Shreya Ghosh', '2020-09-10') ;
+INSERT INTO t1
+(Employee_name, Joining_Date ) values(' ','2014-12-01');
+select * from t1 where Employee_name=space(5);
+employee_name joining_date
+ 2014-12-01
+drop table if exists t1;
+CREATE TABLE t1(a INT,b VARCHAR(100),c CHAR(20));
+INSERT INTO t1
+VALUES
+(1,'Ananya Majumdar', 'IX'),
+(2,'Anushka Samanta', 'X'),
+(3,'Aniket Sharma', 'XI'),
+(4,'Anik Das', 'X'),
+(5,'Riya Jain', 'IX'),
+(6,'Tapan Samanta', 'X');
+select a,startswith(b,'An') from t1;
+a startswith(b, An)
+1 1
+2 1
+3 1
+4 1
+5 0
+6 0
+select a,b,c from t1 where startswith(b,'An')=1 and startswith(c,'I')=1;
+a b c
+1 Ananya Majumdar IX
+drop table if exists t1;
+CREATE TABLE t1(PlayerName VARCHAR(100) NOT NULL,RunScored INT NOT NULL,WicketsTaken INT NOT NULL);
+INSERT INTO t1 VALUES('KL Rahul', 52, 0 ),('Hardik Pandya', 30, 1 ),('Ravindra Jadeja', 18, 2 ),('Washington Sundar', 10, 1),('D Chahar', 11, 2 ), ('Mitchell Starc', 0, 3);
+SELECT STDDEV_POP(RunScored) as Pop_Standard_Deviation FROM t1;
+pop_standard_deviation
+16.8762
+SELECT STDDEV_POP(WicketsTaken) as Pop_Std_Dev_Wickets FROM t1;
+pop_std_dev_wickets
+0.9574
+drop table if exists t1;
+create table t1(a int,b float);
+insert into t1 values(0,0),(-15,-20),(-22,-12.5);
+insert into t1 values(0,360),(30,390),(90,450),(180,270),(180,180);
+select tan(a*pi()/180) as tana,tan(b*pi()/180) tanb from t1;
+tana tanb
+0.0000 0.0000
+-0.2679 -0.3640
+-0.4040 -0.2217
+0.0000 -0.0000
+0.5774 0.5774
+16331239353195392.0000 3266247870639078.5000
+-0.0000 5443746451065131.0000
+-0.0000 -0.0000
+select tan(a*pi()/180)*tan(b*pi()/180) as tanab,tan(tan(a*pi()/180)) as c from t1;
+tanab c
+0.0000 0.0000
+0.0975 -0.2746
+0.0896 -0.4275
+-0.0000 0.0000
+0.3333 0.6514
+53341875762271569940663683252224.0000 3.4834
+-0.6667 -0.0000
+0.0000 -0.0000
+select b from t1 where tan(a*pi()/180)<=tan(b*pi()/180) order by a;
+b
+-12.5000
+0.0000
+270.0000
+180.0000
+drop table if exists t1;
+create table t1(a date,b datetime);
+insert into t1 values("2022-06-01","2022-07-01 00:00:00");
+insert into t1 values("2022-12-31","2011-01-31 12:00:00");
+insert into t1 values("2022-06-12","2022-07-01 00:00:00");
+select a,weekday(a),b,weekday(b) from t1;
+a weekday(a) b weekday(b)
+2022-06-01 2 2022-07-01 00:00:00 4
+2022-12-31 5 2011-01-31 12:00:00 0
+2022-06-12 6 2022-07-01 00:00:00 4
+select * from t1 where weekday(a)>weekday(b);
+a b
+2022-12-31 2011-01-31 12:00:00
+2022-06-12 2022-07-01 00:00:00
+select * from t1 where weekday(a) between 0 and 4;
+a b
+2022-06-01 2022-07-01 00:00:00
+drop table if exists t1;
+create table t1(a date,b datetime);
+insert into t1 values("2022-06-01","2022-07-01 00:00:00");
+insert into t1 values("2022-12-31","2011-01-31 12:00:00");
+insert into t1 values("2022-06-12","2022-07-01 00:00:00");
+select a,weekday(a),b,weekday(b) from t1;
+a weekday(a) b weekday(b)
+2022-06-01 2 2022-07-01 00:00:00 4
+2022-12-31 5 2011-01-31 12:00:00 0
+2022-06-12 6 2022-07-01 00:00:00 4
+select * from t1 where weekday(a)>weekday(b);
+a b
+2022-12-31 2011-01-31 12:00:00
+2022-06-12 2022-07-01 00:00:00
+select * from t1 where weekday(a) between 0 and 4;
+a b
+2022-06-01 2022-07-01 00:00:00
+drop table if exists t1;
+create table t1(a date, b datetime);
+insert into t1 values('2022-01-01','2022-01-01 01:01:01');
+insert into t1 values('2022-01-01','2022-01-01 01:01:01');
+insert into t1 values(20220101,'2022-01-01 01:01:01');
+insert into t1 values('2022-01-02','2022-01-02 23:01:01');
+insert into t1 values('2021-12-31','2021-12-30 23:59:59');
+insert into t1 values('2022-06-30','2021-12-30 23:59:59');
+select date(a),date(b) from t1;
+date(a) date(b)
+2022-01-01 2022-01-01
+2022-01-01 2022-01-01
+2022-01-01 2022-01-01
+2022-01-02 2022-01-02
+2021-12-31 2021-12-30
+2022-06-30 2021-12-30
+select date(a),date(date(a)) as dda from t1;
+date(a) dda
+2022-01-01 2022-01-01
+2022-01-01 2022-01-01
+2022-01-01 2022-01-01
+2022-01-02 2022-01-02
+2021-12-31 2021-12-31
+2022-06-30 2022-06-30
diff --git a/result/create_database.result b/result/create_database.result
new file mode 100644
index 000000000..ec67969fd
--- /dev/null
+++ b/result/create_database.result
@@ -0,0 +1,26 @@
+drop database if exists test01;
+drop database if exists test03;
+drop database if exists test04;
+drop database if exists test05;
+drop database if exists `测试数据库`;
+drop database if exists t01234567890123456789012345678901234567890123456789012345678901234567890123456789;
+create database test01;
+create database IF NOT EXISTS test01;
+create database `测试数据库`;
+create database test03 default character set utf8 collate utf8_general_ci encryption 'Y';
+create database test04 character set=utf8 collate=utf8_general_ci encryption='N';
+create database t01234567890123456789012345678901234567890123456789012345678901234567890123456789;
+show databases;
+Databases
+create_database
+test01
+测试数据库
+test03
+test04
+t01234567890123456789012345678901234567890123456789012345678901234567890123456789
+drop database if exists test01;
+drop database if exists test03;
+drop database if exists test04;
+drop database if exists test05;
+drop database if exists `测试数据库`;
+drop database if exists t01234567890123456789012345678901234567890123456789012345678901234567890123456789;
diff --git a/result/create_table.result b/result/create_table.result
new file mode 100644
index 000000000..8998b9458
--- /dev/null
+++ b/result/create_table.result
@@ -0,0 +1,34 @@
+create table table01(a TINYINT primary key, b SMALLINT SIGNED, c INT UNSIGNED,d BIGINT not null , e FLOAT unique,f DOUBLE, g CHAR(10), h VARCHAR(20));
+create table table15 (a varchar(5) default 'abcde');
+create temporary table table05 ( a int, b char(10));
+create table table06 (a int primary key, b varchar(10));
+create table table10 (a int primary key, b varchar(10)) checksum=0 COMMENT="asdf";
+create table `测试表` (`测试1` int);
+create table `table11 ` (a int);
+create table table12 (`a ` int);
+create table `a/a` (a int);
+create table `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa int);
+create table table14 (`aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` int);
+create table table16 (1a20 int,1e int);
+create table $table18 (a$1 int, $b int, c$ int);
+create table table19$ (a int);
+create table table17 (`index` int);
+show tables;
+Tables
+table01
+table15
+table05
+table06
+table10
+测试表
+table11
+table12
+a/a
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+table14
+table16
+$table18
+table19$
+table17
+
+table20
diff --git a/result/datatype.result b/result/datatype.result
new file mode 100644
index 000000000..6c8241ca7
--- /dev/null
+++ b/result/datatype.result
@@ -0,0 +1,96 @@
+drop table if exists numtable;
+create table numtable(id int,fl float, dl double);
+insert into numtable values(1,123456,123456);
+insert into numtable values(2,123.456,123.456);
+insert into numtable values(3,1.234567,1.234567);
+insert into numtable values(4,1.234567891,1.234567891);
+insert into numtable values(5,1.2345678912345678912,1.2345678912345678912);
+select id,fl,dl from numtable order by id;
+id fl dl
+1 123456.0000 123456.0000
+2 123.4560 123.4560
+3 1.2346 1.2346
+4 1.2346 1.2346
+5 1.2346 1.2346
+drop table if exists numtable;
+create table numtable(id int,fl float(5,3));
+insert into numtable values(2,99);
+insert into numtable values(3,99.123);
+insert into numtable values(4,99.1236);
+select id,fl from numtable;
+id fl
+2 99.0000
+3 99.1230
+4 99.1236
+drop table if exists numtable;
+create table numtable(id int,fl float(23));
+insert into numtable values(1,1.2345678901234567890123456789);
+select id,fl from numtable;
+id fl
+1 1.2346
+drop table if exists numtable;
+create table numtable(id int,dl double);
+insert into numtable values(1,1.2345678901234567890123456789);
+select id,dl from numtable;
+id dl
+1 1.2346
+drop table if exists numtable;
+create table numtable(a tinyint unsigned, b smallint unsigned, c int unsigned, d bigint unsigned);
+insert into numtable values(255,65535,4294967295,18446744073709551615);
+select a,b,c,d from numtable;
+a b c d
+255 65535 4294967295 18446744073709551615
+drop table if exists numtable;
+create table numtable(a tinyint signed, b smallint signed, c int signed, d bigint signed);
+insert into numtable values(127,32767,2147483647,9223372036854775807);
+insert into numtable values(-128,-32768,-2147483648,-9223372036854775808);
+select a,b,c,d from numtable;
+a b c d
+127 32767 2147483647 9223372036854775807
+-128 -32768 -2147483648 -9223372036854775808
+drop table if exists names;
+create table names(name varchar(255),age char(255));
+insert into names(name, age) values('Abby', '24');
+insert into names(name, age) values("Bob", '25');
+insert into names(name, age) values('Carol', "23");
+insert into names(name, age) values("Dora", "29");
+select name,age from names;
+name age
+Abby 24
+Bob 25
+Carol 23
+Dora 29
+drop table if exists t4;
+create table t4(a int, b date, c datetime);
+insert into t4 values(1, '2021-12-13','2021-12-13 13:00:00');
+insert into t4 values(2, '20211214','20211213');
+insert into t4 values(3,'2021-12-14','2021-12-14');
+insert into t4 values(4,'2021-12-15','2021-12-14');
+select * from t4 where b>'20211213';
+a b c
+2 2021-12-14 2021-12-13 00:00:00
+3 2021-12-14 2021-12-14 00:00:00
+4 2021-12-15 2021-12-14 00:00:00
+select * from t4 where c>'20211213';
+a b c
+1 2021-12-13 2021-12-13 13:00:00
+3 2021-12-14 2021-12-14 00:00:00
+4 2021-12-15 2021-12-14 00:00:00
+select * from t4 where b>'2021-12-13';
+a b c
+2 2021-12-14 2021-12-13 00:00:00
+3 2021-12-14 2021-12-14 00:00:00
+4 2021-12-15 2021-12-14 00:00:00
+select * from t4 where c>'2021-12-13';
+a b c
+1 2021-12-13 2021-12-13 13:00:00
+3 2021-12-14 2021-12-14 00:00:00
+4 2021-12-15 2021-12-14 00:00:00
+select * from t4 where b between '2021-12-13' and '2021-12-14';
+a b c
+1 2021-12-13 2021-12-13 13:00:00
+2 2021-12-14 2021-12-13 00:00:00
+3 2021-12-14 2021-12-14 00:00:00
+select * from t4 where b not between '2021-12-13' and '2021-12-14';
+a b c
+4 2021-12-15 2021-12-14 00:00:00
diff --git a/result/drop_database.result b/result/drop_database.result
new file mode 100644
index 000000000..020510bd1
--- /dev/null
+++ b/result/drop_database.result
@@ -0,0 +1,6 @@
+drop database if exists test01;
+drop database if exists drop_database;
+create database test01;
+drop database test01;
+show databases;
+Databases
diff --git a/result/drop_table.result b/result/drop_table.result
new file mode 100644
index 000000000..cc98af3d2
--- /dev/null
+++ b/result/drop_table.result
@@ -0,0 +1,5 @@
+drop table if exists table01;
+create table table01(a int);
+drop table table01;
+show tables;
+Tables
diff --git a/result/functions.result b/result/functions.result
new file mode 100644
index 000000000..342eb5e9e
--- /dev/null
+++ b/result/functions.result
@@ -0,0 +1,230 @@
+drop table if exists tbl1,tbl2;
+create table tbl1 (col_1a tinyint, col_1b smallint, col_1c int, col_1d bigint, col_1e char(10) not null);
+insert into tbl1 values (0,1,1,7,"a");
+insert into tbl1 values (0,1,2,8,"b");
+insert into tbl1 values (0,1,3,9,"c");
+insert into tbl1 values (0,1,4,10,"D");
+insert into tbl1 values (0,1,5,11,"a");
+insert into tbl1 values (0,1,6,12,"c");
+select sum(col_1a),count(col_1b),avg(col_1c),min(col_1d),max(col_1d) from tbl1;
+sum(col_1a) count(col_1b) avg(col_1c) min(col_1d) max(col_1d)
+0 6 3.5000 7 12
+select sum(col_1d) as s1,count(col_1d) as c2,avg(col_1d) as a3,min(col_1d) as m4,max(col_1d) as m5 from tbl1 group by col_1e order by s1 desc;
+s1 c2 a3 m4 m5
+21 2 10.5000 9 12
+18 2 9.0000 7 11
+10 1 10.0000 10 10
+8 1 8.0000 8 8
+select sum(col_1d) as c1 from tbl1 where col_1d < 13 group by col_1e order by c1;
+c1
+8
+10
+18
+21
+select sum(col_1d) from tbl1 where col_1d > 10;
+sum(col_1d)
+23
+select sum(col_1c)+count(col_1c)-avg(col_1c)*min(col_1c)/max(col_1c)%min(col_1c)+max(col_1c) as func from tbl1 group by col_1c;
+func
+3.0000
+5.0000
+7.0000
+9.0000
+11.0000
+13.0000
+CREATE TABLE t1 (spID int,userID int,score smallint);
+INSERT INTO t1 VALUES (1,1,1);
+INSERT INTO t1 VALUES (2,2,2);
+INSERT INTO t1 VALUES (2,1,4);
+INSERT INTO t1 VALUES (3,3,3);
+INSERT INTO t1 VALUES (1,1,5);
+INSERT INTO t1 VALUES (4,6,10);
+INSERT INTO t1 VALUES (5,11,99);
+select * from t1 where CAST(spID AS CHAR)='1';
+spid userid score
+1 1 1
+1 1 5
+select CAST(userID AS CHAR) userid_cast from t1 where CAST(spID AS CHAR)='1';
+userid_cast
+1
+1
+select spID+score from t1;
+spid + score
+2
+4
+6
+6
+6
+14
+104
+drop table if exists t1;
+create table t1(a date);
+insert into t1 values('2021-12-23');
+insert into t1 values('2021-12-24');
+select year(a) from t1;
+year(a)
+2021
+2021
+drop table if exists t1;
+create table t1(a int ,b float);
+insert into t1 values(1,0.5);
+insert into t1 values(2,0.499);
+insert into t1 values(3,0.501);
+insert into t1 values(4,20.5);
+insert into t1 values(5,20.499);
+insert into t1 values(6,13.500);
+insert into t1 values(7,-0.500);
+insert into t1 values(8,-0.499);
+insert into t1 values(9,-0.501);
+insert into t1 values(10,-20.499);
+insert into t1 values(11,-20.500);
+insert into t1 values(12,-13.500);
+select a,round(b) from t1;
+a round(b)
+1 0.0000
+2 0.0000
+3 1.0000
+4 20.0000
+5 20.0000
+6 14.0000
+7 -0.0000
+8 -0.0000
+9 -1.0000
+10 -20.0000
+11 -20.0000
+12 -14.0000
+select a,round(b,-1) from t1;
+a round(b, -1)
+1 0.0000
+2 0.0000
+3 0.0000
+4 20.0000
+5 20.0000
+6 10.0000
+7 -0.0000
+8 -0.0000
+9 -0.0000
+10 -20.0000
+11 -20.0000
+12 -10.0000
+select round(a*b) from t1;
+round(a * b)
+0.0000
+1.0000
+2.0000
+82.0000
+102.0000
+81.0000
+-4.0000
+-4.0000
+-5.0000
+-205.0000
+-226.0000
+-162.0000
+select a,floor(b) from t1;
+a floor(b)
+1 0.0000
+2 0.0000
+3 0.0000
+4 20.0000
+5 20.0000
+6 13.0000
+7 -1.0000
+8 -1.0000
+9 -1.0000
+10 -21.0000
+11 -21.0000
+12 -14.0000
+select sum(round(b)) from t1;
+sum(round(b))
+0.0000
+select sum(floor(b)) from t1;
+sum(floor(b))
+-6.0000
+select a,sum(floor(b)) from t1 group by a order by a;
+a sum(floor(b))
+1 0.0000
+2 0.0000
+3 0.0000
+4 20.0000
+5 20.0000
+6 13.0000
+7 -1.0000
+8 -1.0000
+9 -1.0000
+10 -21.0000
+11 -21.0000
+12 -14.0000
+select a,floor(b) as floorb from t1 order by floorb desc;
+a floorb
+5 20.0000
+4 20.0000
+6 13.0000
+3 0.0000
+2 0.0000
+1 0.0000
+9 -1.0000
+8 -1.0000
+7 -1.0000
+12 -14.0000
+11 -21.0000
+10 -21.0000
+select a,avg(round(b)) as roundb from t1 where a>3 group by a order by roundb;
+a roundb
+10 -20.0000
+11 -20.0000
+12 -14.0000
+9 -1.0000
+7 0.0000
+8 0.0000
+6 14.0000
+4 20.0000
+5 20.0000
+select a,avg(round(b)) as roundb from t1 where a in (3,5,7) group by a order by roundb;
+a roundb
+7 0.0000
+3 1.0000
+5 20.0000
+select a,round(b,2),max(b) from t1 group by b order by a;
+a round(b, 2) max(b)
+1 0.5000 0.5000
+2 0.5000 0.4990
+3 0.5000 0.5010
+4 20.5000 20.5000
+5 20.5000 20.4990
+6 13.5000 13.5000
+7 -0.5000 -0.5000
+8 -0.5000 -0.4990
+9 -0.5000 -0.5010
+10 -20.5000 -20.4990
+11 -20.5000 -20.5000
+12 -13.5000 -13.5000
+drop table if exists t1;
+CREATE TABLE IF NOT EXISTS t1 (
+pub_id varchar(8) COLLATE latin1_general_ci NOT NULL DEFAULT '',
+pub_name varchar(50) COLLATE latin1_general_ci NOT NULL DEFAULT '',
+pub_city varchar(25) COLLATE latin1_general_ci NOT NULL DEFAULT '',
+country varchar(25) COLLATE latin1_general_ci NOT NULL DEFAULT '',
+country_office varchar(25) COLLATE latin1_general_ci NOT NULL DEFAULT '',
+no_of_branch int NOT NULL DEFAULT 0,
+estd date NOT NULL DEFAULT '2000-01-01'
+);
+INSERT INTO t1 (pub_id, pub_name, pub_city, country, country_office, no_of_branch, estd) VALUES
+('P001', 'Jex Max Publication', 'New York', 'USA', 'New York', 15, '1969-12-25'),
+('P002', 'BPP Publication', 'Mumbai', 'India', 'New Delhi', 10, '1985-10-01'),
+('P003', 'New Harrold Publication', 'Adelaide', 'Australia', 'Sydney', 6, '1975-09-05'),
+('P004', 'Ultra Press Inc.', 'London', 'UK', 'London', 8, '1948-07-10'),
+('P005', 'Mountain Publication', 'Houstan', 'USA', 'Sun Diego', 25, '1975-01-01'),
+('P006', 'Summer Night Publication', 'New York', 'USA', 'Atlanta', 10, '1990-12-10'),
+('P007', 'Pieterson Grp. of Publishers', 'Cambridge', 'UK', 'London', 6, '1950-07-15'),
+('P008', 'Novel Publisher Ltd.', 'New Delhi', 'India', 'Bangalore', 10, '2000-01-01');
+SELECT pub_name, SUBSTR(pub_name,4,5) FROM t1 WHERE country='USA';
+pub_name substr(pub_name, 4, 5)
+Jex Max Publication Max
+Mountain Publication ntain
+Summer Night Publication mer N
+SELECT pub_name, SUBSTR(pub_name,5) FROM t1 WHERE country='USA';
+pub_name substr(pub_name, 5)
+Jex Max Publication Max Publication
+Mountain Publication tain Publication
+Summer Night Publication er Night Publication
diff --git a/result/insert.result b/result/insert.result
new file mode 100644
index 000000000..858629549
--- /dev/null
+++ b/result/insert.result
@@ -0,0 +1,57 @@
+drop table if exists names;
+create table names(id int PRIMARY KEY AUTO_INCREMENT,name VARCHAR(255) UNIQUE,age int);
+insert into names(name, age) values("Abby", 24);
+insert into names(name, age) values("Bob", 25);
+insert into names(name, age) values("Carol", 23);
+insert into names(name, age) values("Dora", 29);
+select id,name,age from names;
+id name age
+NULL Abby 24
+NULL Bob 25
+NULL Carol 23
+NULL Dora 29
+drop table if exists weights;
+create table weights(a int unique);
+insert into weights values(1);
+select * from weights;
+a
+1
+drop table if exists test;
+create table test(id int primary key, name varchar(10), age int);
+insert into test values(1, 'Abby', 20);
+insert into test values(2, 'Bob', 21);
+select id,name,age from test;
+id name age
+1 Abby 20
+2 Bob 21
+drop table if exists pet;
+create table pet(name char(10),owner char(10), species char(10), gender char(1), weight float,age int);
+insert into pet values ('Sunsweet01','Dsant01','otter','f',30.11,2),
+('Sunsweet02','Dsant02','otter','m',30.11,3);
+insert into pet(name, owner, species, gender, weight, age) values ('Sunsweet03','Dsant01','otter','f',30.11,2),
+('Sunsweet04','Dsant02','otter','m',30.11,3);
+select * from pet;
+name owner species gender weight age
+Sunsweet01 Dsant01 otter f 30.1100 2
+Sunsweet02 Dsant02 otter m 30.1100 3
+Sunsweet03 Dsant01 otter f 30.1100 2
+Sunsweet04 Dsant02 otter m 30.1100 3
+drop table if exists t1;
+create table t1 (a bigint unsigned not null, primary key(a));
+insert into t1 values (18446744073709551615), (0xFFFFFFFFFFFFFFFE), (18446744073709551613), (18446744073709551612);
+select * from t1;
+a
+18446744073709551615
+18446744073709551614
+18446744073709551613
+18446744073709551612
+drop table if exists t1;
+create table t1 (name char(20) not null primary key ) charset latin1;
+insert into t1 values ("å");
+insert into t1 values ("ä");
+insert into t1 values ("ö");
+select * from t1 order by name;
+name
+ä
+å
+ö
diff --git a/result/join.result b/result/join.result
new file mode 100644
index 000000000..8ec30f9e6
--- /dev/null
+++ b/result/join.result
@@ -0,0 +1,179 @@
+drop table if exists t1,t2;
+CREATE TABLE t1 (S1 INT);
+CREATE TABLE t2 (S1 INT);
+INSERT INTO t1 VALUES (1),(3),(4),(6);
+INSERT INTO t2 VALUES (2),(4),(5);
+SELECT * FROM t1 JOIN t2 on t1.S1=t2.S1;
+t1.s1 t2.s1
+4 4
+drop table if exists t1,t2;
+create table t1 (id int);
+create table t2 (id int);
+insert into t1 values (75);
+insert into t1 values (79);
+insert into t1 values (78);
+insert into t1 values (77);
+insert into t1 values (76);
+insert into t1 values (76);
+insert into t1 values (104);
+insert into t1 values (103);
+insert into t1 values (102);
+insert into t1 values (101);
+insert into t1 values (105);
+insert into t1 values (106);
+insert into t1 values (107);
+insert into t2 values (107),(75),(1000);
+select t1.id, t2.id from t1, t2 where t2.id = t1.id;
+t1.id t2.id
+75 75
+107 107
+select t1.id, count(t2.id) from t1,t2 where t2.id = t1.id group by t1.id;
+t1.id count(t2.id)
+75 1
+107 1
+select t1.id, count(t2.id) from t1,t2 where t2.id = t1.id group by t2.id;
+t1.id count(t2.id)
+75 1
+107 1
+select t1.id,t2.id from t2 join t1 on t1.id=t2.id where t2.id=75;
+t1.id t2.id
+75 75
+drop table if exists t1,t2;
+CREATE TABLE t1 (
+id int,
+token varchar(100) DEFAULT '' NOT NULL,
+count int DEFAULT 0 NOT NULL,
+qty int,
+phone char(1) DEFAULT '' NOT NULL,
+times datetime DEFAULT '2000-01-01 00:00:00' NOT NULL
+);
+INSERT INTO t1 VALUES (21,'e45703b64de71482360de8fec94c3ade',3,7800,'n','1999-12-23 17:22:21');
+INSERT INTO t1 VALUES (22,'e45703b64de71482360de8fec94c3ade',4,5000,'y','1999-12-23 17:22:21');
+INSERT INTO t1 VALUES (18,'346d1cb63c89285b2351f0ca4de40eda',3,13200,'b','1999-12-23 11:58:04');
+INSERT INTO t1 VALUES (17,'ca6ddeb689e1b48a04146b1b5b6f936a',4,15000,'b','1999-12-23 11:36:53');
+INSERT INTO t1 VALUES (16,'ca6ddeb689e1b48a04146b1b5b6f936a',3,13200,'b','1999-12-23 11:36:53');
+INSERT INTO t1 VALUES (26,'a71250b7ed780f6ef3185bfffe027983',5,1500,'b','1999-12-27 09:44:24');
+INSERT INTO t1 VALUES (24,'4d75906f3c37ecff478a1eb56637aa09',3,5400,'y','1999-12-23 17:29:12');
+INSERT INTO t1 VALUES (25,'4d75906f3c37ecff478a1eb56637aa09',4,6500,'y','1999-12-23 17:29:12');
+INSERT INTO t1 VALUES (27,'a71250b7ed780f6ef3185bfffe027983',3,6200,'b','1999-12-27 09:44:24');
+INSERT INTO t1 VALUES (28,'a71250b7ed780f6ef3185bfffe027983',3,5400,'y','1999-12-27 09:44:36');
+INSERT INTO t1 VALUES (29,'a71250b7ed780f6ef3185bfffe027983',4,17700,'b','1999-12-27 09:45:05');
+CREATE TABLE t2 (
+id int,
+category int DEFAULT 0 NOT NULL,
+county int DEFAULT 0 NOT NULL,
+state int DEFAULT 0 NOT NULL,
+phones int DEFAULT 0 NOT NULL,
+nophones int DEFAULT 0 NOT NULL
+);
+INSERT INTO t2 VALUES (3,2,11,12,5400,7800);
+INSERT INTO t2 VALUES (4,2,25,12,6500,11200);
+INSERT INTO t2 VALUES (5,1,37,6,10000,12000);
+select t1.id, category as catid, state as stateid, county as countyid from t1 join t2 on count=t2.id where token='a71250b7ed780f6ef3185bfffe027983';
+t1.id catid stateid countyid
+26 1 6 37
+27 2 12 11
+28 2 12 11
+29 2 12 25
+select t1.id, category as catid, state as stateid, county as countyid from t1 join t2 on count=t2.id where token='a71250b7ed780f6ef3185bfffe027983' and t1.id>26 order by t1.id;
+t1.id catid stateid countyid
+27 2 12 11
+28 2 12 11
+29 2 12 25
+drop table if exists t1,t2,t3;
+CREATE TABLE t1 (
+t1_id int default NULL,
+t2_id int default NULL,
+type varchar(12) default NULL,
+cost_unit varchar(5) default NULL,
+min_value double default NULL,
+max_value double default NULL,
+t3_id int default NULL,
+item_id int default NULL
+);
+CREATE TABLE t2 (
+id int NOT NULL auto_increment,
+name varchar(255) default NULL,
+PRIMARY KEY (id)
+);
+INSERT INTO t1 VALUES (12,5,'Percent','Cost',-1,0,-1,-1),(14,4,'Percent','Cost',-1,0,-1,-1),(18,5,'Percent','Cost',-1,0,-1,-1),(19,4,'Percent','Cost',-1,0,-1,-1),(20,5,'Percent','Cost',100,-1,22,291),(21,5,'Percent','Cost',100,-1,18,291),(22,1,'Percent','Cost',100,-1,6,291),(23,1,'Percent','Cost',100,-1,21,291),(24,1,'Percent','Cost',100,-1,9,291),(25,1,'Percent','Cost',100,-1,4,291),(26,1,'Percent','Cost',100,-1,20,291),(27,4,'Percent','Cost',100,-1,7,202),(28,1,'Percent','Cost',50,-1,-1,137),(29,2,'Percent','Cost',100,-1,4,354),(30,2,'Percent','Cost',100,-1,9,137),(93,2,'Cost','Cost',-1,10000000,-1,-1);
+INSERT INTO t2 VALUES (1,'s1'),(2,'s2'),(3,'s3'),(4,'s4'),(5,'s5');
+select t2_id,name, type from t1 join t2 on t2.id=t1.t2_id order by id;
+t2_id name type
+2 s1 Percent
+2 s1 Percent
+5 s1 Percent
+4 s1 Percent
+4 s1 Percent
+2 s1 Percent
+5 s2 Percent
+5 s2 Percent
+5 s2 Cost
+4 s4 Percent
+1 s4 Percent
+1 s4 Percent
+1 s5 Percent
+1 s5 Percent
+1 s5 Percent
+1 s5 Percent
+drop table t1,t2;
+CREATE TABLE t1 (ID INTEGER NOT NULL PRIMARY KEY, Value1 VARCHAR(255));
+CREATE TABLE t2 (ID INTEGER NOT NULL PRIMARY KEY, Value2 VARCHAR(255));
+INSERT INTO t1 VALUES (1, 'A');
+INSERT INTO t2 VALUES (1, 'B');
+SELECT t1.ID,Value2 FROM t1 JOIN t2 on t1.ID=t2.ID WHERE Value1 = 'A';
+t1.id value2
+1 B
+SELECT t1.ID,Value2 FROM t1 JOIN t2 on t1.ID=t2.ID WHERE Value1 = 'A' and Value2 <> 'B';
+t1.id value2
+drop table if exists t1,t2,t3;
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (b int);
+CREATE TABLE t3 (c int);
+insert into t1 values(1),(2),(3),(4),(5);
+insert into t2 values(1),(3),(5),(7),(9);
+insert into t3 values(1),(1),(3),(4),(7);
+select a,b,c from t1 join t2 on t1.a=t2.b join t3 on t1.a=t3.c where a>1;
+a b c
+3 3 3
+DROP TABLE if exists t1, t2, t3;
+create table t1 (i int);
+create table t2 (i int);
+create table t3 (i int);
+insert into t1 values(1),(2);
+insert into t2 values(2),(3);
+insert into t3 values (2),(4);
+select t3.i from t1 join t2 on t1.i=t2.i join t3 on t2.i=t3.i;
+t3.i
+2
+DROP TABLE if exists t1,t2,t3,t4,t5,t6;
+create table t1 (c int, b int);
+create table t2 (a int, b int);
+create table t3 (b int, c int);
+create table t4 (y int, c int);
+create table t5 (y int, z int);
+create table t6 (a int, c int);
+insert into t1 values (10,1);
+insert into t1 values (3 ,1);
+insert into t1 values (3 ,2);
+insert into t2 values (2, 1);
+insert into t3 values (1, 3);
+insert into t3 values (1,10);
+insert into t4 values (11,3);
+insert into t4 values (2, 3);
+insert into t5 values (11,4);
+insert into t6 values (2, 3);
+select distinct a,t1.b,t3.c from t1 join t2 on t1.b=t2.b join t3 on t1.b=t3.c;
+a t1.b t3.c
+drop table if exists t1,t2,t3,t4;
+create table t1 (a1 int, a2 int);
+create table t2 (a1 int, b int);
+create table t3 (c1 int, c2 int);
+create table t4 (c2 int);
+insert into t1 values (1,1);
+insert into t2 values (1,1);
+insert into t3 values (1,1);
+insert into t4 values (1);
+select * from t1 join t2 on t1.a1=t2.a1 join t3 on b=c1 join t4 on t3.c2=t4.c2;
+t1.a1 a2 t2.a1 b c1 t3.c2 t4.c2
+1 1 1 1 1 1 1
diff --git a/result/operator.result b/result/operator.result
new file mode 100644
index 000000000..df73e9ecd
--- /dev/null
+++ b/result/operator.result
@@ -0,0 +1,257 @@
+drop table if exists t1;
+create table t1 (spID smallint,userID bigint,score int);
+insert into t1 values (1,1,1);
+insert into t1 values (2,2,2);
+insert into t1 values (2,1,4);
+insert into t1 values (3,3,3);
+insert into t1 values (1,1,5);
+insert into t1 values (4,6,10);
+insert into t1 values (5,11,99);
+create table t2(product VARCHAR(32),country_id INTEGER NOT NULL,year INTEGER,profit INTEGER);
+insert into t2 values ( 'Computer', 2,2000, 1200),
+( 'TV', 1, 1999, 150),
+( 'Calculator', 1, 1999,50),
+( 'Computer', 1, 1999,1500),
+( 'Computer', 1, 2000,1500),
+( 'TV', 1, 2000, 150),
+( 'TV', 2, 2000, 100),
+( 'TV', 2, 2000, 100),
+( 'Calculator', 1, 2000,75),
+( 'Calculator', 2, 2000,75),
+( 'TV', 1, 1999, 100),
+( 'Computer', 1, 1999,1200),
+( 'Computer', 2, 2000,1500),
+( 'Calculator', 2, 2000,75),
+( 'Phone', 3, 2003,10);
+select userID,spID,score from t1 where userID=spID and userID<>score;
+userid spid score
+1 1 5
+select userID,spID,score from t1 where userID=spID and userID!=score;
+userid spid score
+1 1 5
+select userID,spID,score from t1 where userID between spID and score;
+userid spid score
+1 1 1
+2 2 2
+3 3 3
+1 1 5
+6 4 10
+11 5 99
+select userID,spID,score from t1 where userID not between spID and score;
+userid spid score
+1 2 4
+select * from t1 where userID between 3 and 6;
+spid userid score
+3 3 3
+4 6 10
+select userID,spID,score from t1 where spID>=userID*score;
+userid spid score
+1 1 1
+select userID,score,spID from t1 where userID<=score/spID;
+userid score spid
+1 1 1
+1 4 2
+1 5 1
+11 99 5
+select spID,userID,score from t1 where spID>(userID-1);
+spid userid score
+1 1 1
+2 2 2
+2 1 4
+3 3 3
+1 1 5
+select spID,userID,score from t1 where score<(spID*userID+1);
+spid userid score
+1 1 1
+2 2 2
+3 3 3
+4 6 10
+select userID, AVG(score) from t1 WHERE spID=2 group by userID order by userID;
+userid avg(score)
+1 4.0000
+2 2.0000
+select product, SUM(profit) from t2 where year>1999 group by product order by product desc;
+product sum(profit)
+TV 350
+Phone 10
+Computer 4200
+Calculator 225
+select product, SUM(profit),AVG(profit) from t2 where product!='TV' group by product order by product asc;
+product sum(profit) avg(profit)
+Calculator 275 68.7500
+Computer 6900 1380.0000
+Phone 10 10.0000
+select product, SUM(profit),AVG(profit) from t2 where product<>'TV' group by product order by product asc;
+product sum(profit) avg(profit)
+Calculator 275 68.7500
+Computer 6900 1380.0000
+Phone 10 10.0000
+select product, SUM(profit),AVG(profit) from t2 where product='Phone' group by product order by product asc;
+product sum(profit) avg(profit)
+Phone 10 10.0000
+select product, SUM(profit) from t2 where year>1999 and year<=2002 group by product order by product desc;
+product sum(profit)
+TV 350
+Computer 4200
+Calculator 225
+select * from t1 where 2<10;
+spid userid score
+1 1 1
+2 2 2
+2 1 4
+3 3 3
+1 1 5
+4 6 10
+5 11 99
+select userID, userID DIV 2 as user_div, userID%2 as user_percent, userID MOD 2 as user_mod from t1 WHERE userID > 3;
+userid user_div user_percent user_mod
+6 3 0 0
+11 5 1 1
+select * from t1 where userID-2>2 && (userID+spID)/3<>0 && score MOD 2 > 0;
+spid userid score
+5 11 99
+select * from t1 where spID >2 && userID < 6 && score != 1;
+spid userid score
+3 3 3
+drop table if exists t2;
+create table t2(c1 int, c2 int);
+insert into t2 values (-3, 2);
+insert into t2 values (1, 2);
+select -c1 from t2;
+-c1
+3
+-1
+select c1, c2 from t2 order by -c1 desc;
+c1 c2
+-3 2
+1 2
+drop table if exists t3;
+create table t3 (c1 varchar(80));
+insert into t3 values ("a"),
+("abc"),
+("abcd"),
+("hello"),
+("test"),
+("C:\Program Files(x86)"),
+("C:\\Program Files(x86)");
+select * from t3;
+c1
+a
+abc
+abcd
+hello
+test
+C:Program Files(x86)
+C:\Program Files(x86)
+create database if not exists likedb;
+create database if not exists dblike;
+show databases like 'like%';
+Databases
+likedb
+show databases like "%like%";
+Databases
+likedb
+dblike
+show databases like "%aa%";
+Databases
+drop database likedb;
+drop database dblike;
+SELECT * FROM t1 where t1.userID<6 OR NOT t1.userID;
+spid userid score
+1 1 1
+2 2 2
+2 1 4
+3 3 3
+1 1 5
+SELECT * FROM t1 where NOT t1.userID OR t1.userID<6;
+spid userid score
+1 1 1
+2 2 2
+2 1 4
+3 3 3
+1 1 5
+SELECT * FROM t1 where NOT t1.userID || t1.userID<6;
+spid userid score
+1 1 1
+2 2 2
+2 1 4
+3 3 3
+1 1 5
+drop table if exists t1;
+create table t1 (a int);
+insert into t1 values (0),(1),(NULL);
+select * from t1;
+a
+0
+1
+NULL
+select * from t1 where not a between 2 and 3;
+a
+0
+1
+drop table if exists t3;
+CREATE TABLE t3(
+cont_nr int(11) NOT NULL auto_increment primary key,
+ver_nr int(11) NOT NULL default 0,
+aufnr int(11) NOT NULL default 0,
+username varchar(50) NOT NULL default ''
+);
+INSERT INTO t3 VALUES (3359356,405,3359356,'Mustermann Musterfrau');
+INSERT INTO t3 VALUES (3359357,468,3359357,'Mustermann Musterfrau');
+INSERT INTO t3 VALUES (3359359,468,3359359,'Mustermann musterfrau');
+INSERT INTO t3 VALUES (3359360,0,0,'Mustermann Masterfrau');
+INSERT INTO t3 VALUES (3359361,406,3359361,'Mastermann Masterfrau');
+INSERT INTO t3 VALUES (3359362,406,3359362,'Mustermann MusterFrau');
+select username from t3 where username like 'Ma%';
+username
+Mastermann Masterfrau
+select username from t3 where username like '%Frau';
+username
+Mustermann MusterFrau
+select username from t3 where username like '%Mast%';
+username
+Mustermann Masterfrau
+Mastermann Masterfrau
+select username from t3 where username like '%a_t%';
+username
+Mustermann Masterfrau
+Mastermann Masterfrau
+drop table if exists t2;
+create table t2(a int,b varchar(5),c float, d date, e datetime);
+insert into t2 values(1,'a',1.001,'2022-02-08','2022-02-08 12:00:00');
+insert into t2 values(2,'b',2.001,'2022-02-09','2022-02-09 12:00:00');
+insert into t2 values(1,'c',3.001,'2022-02-10','2022-02-10 12:00:00');
+insert into t2 values(4,'d',4.001,'2022-02-11','2022-02-11 12:00:00');
+select * from t2 where a in (2,4);
+a b c d e
+2 b 2.0010 2022-02-09 2022-02-09 12:00:00
+4 d 4.0010 2022-02-11 2022-02-11 12:00:00
+select * from t2 where a not in (2,4);
+a b c d e
+1 a 1.0010 2022-02-08 2022-02-08 12:00:00
+1 c 3.0010 2022-02-10 2022-02-10 12:00:00
+select * from t2 where c in (2.001,2.002);
+a b c d e
+2 b 2.0010 2022-02-09 2022-02-09 12:00:00
+select * from t2 where b not in ('e',"f");
+a b c d e
+1 a 1.0010 2022-02-08 2022-02-08 12:00:00
+2 b 2.0010 2022-02-09 2022-02-09 12:00:00
+1 c 3.0010 2022-02-10 2022-02-10 12:00:00
+4 d 4.0010 2022-02-11 2022-02-11 12:00:00
+select sum(a),c from t2 where a in (1,2) and d in ('2022-02-10','2022-02-11') group by c order by c;
+sum(a) c
+1 3.0010
+select * from t2 where d in ('20220208','2022-02-09');
+a b c d e
+1 a 1.0010 2022-02-08 2022-02-08 12:00:00
+2 b 2.0010 2022-02-09 2022-02-09 12:00:00
+select * from t2 where e not in ('2022-02-09 12:00:00') and a in (4,5);
+a b c d e
+4 d 4.0010 2022-02-11 2022-02-11 12:00:00
+select sum(a) as suma,e from t2 where e not in ('2022-02-09 12:00:00') and a in (4,5) group by e order by suma;
+suma e
+4 2022-02-11 12:00:00
+select * from t2 where c in (2.001,3);
+a b c d e
+2 b 2.0010 2022-02-09 2022-02-09 12:00:00
diff --git a/result/select.result b/result/select.result
new file mode 100644
index 000000000..a4e18234b
--- /dev/null
+++ b/result/select.result
@@ -0,0 +1,379 @@
+drop table if exists t1;
+create table t1 (spID int,userID int,score smallint);
+insert into t1 values (1,1,1);
+insert into t1 values (2,2,2);
+insert into t1 values (2,1,4);
+insert into t1 values (3,3,3);
+insert into t1 values (1,1,5);
+insert into t1 values (4,6,10);
+insert into t1 values (5,11,99);
+select userID, MIN(score) from t1 group by userID order by userID desc;
+userid min(score)
+11 99
+6 10
+3 3
+2 2
+1 1
+select userID, MIN(score) from t1 group by userID order by userID asc;
+userid min(score)
+1 1
+2 2
+3 3
+6 10
+11 99
+select userID, SUM(score) from t1 group by userID order by userID desc;
+userid sum(score)
+11 99
+6 10
+3 3
+2 2
+1 10
+select userID as a, MIN(score) as b from t1 group by userID order by userID;
+a b
+1 1
+2 2
+3 3
+6 10
+11 99
+select userID as user, MAX(score) as max from t1 group by userID order by user;
+user max
+1 5
+2 2
+3 3
+6 10
+11 99
+select userID as user, MAX(score) as max from t1 group by userID order by max desc;
+user max
+11 99
+6 10
+1 5
+3 3
+2 2
+select userID,count(score) from t1 group by userID having count(score)>1 order by userID;
+userid count(score)
+1 3
+select userID,count(score) from t1 where userID>2 group by userID having count(score)>1 order by userID;
+userid count(score)
+select distinct userID, count(score) from t1 group by userID order by userID;
+userid count(score)
+1 3
+2 1
+3 1
+6 1
+11 1
+select distinct spID,userID from t1;
+spid userid
+1 1
+2 2
+2 1
+3 3
+4 6
+5 11
+select distinct spID,userID from t1 where score>2;
+spid userid
+2 1
+3 3
+1 1
+4 6
+5 11
+select distinct spID,userID from t1 where score>2 order by spID asc;
+spid userid
+1 1
+2 1
+3 3
+4 6
+5 11
+select distinct spID,userID from t1 where spID>2 order by userID desc;
+spid userid
+5 11
+4 6
+3 3
+select distinct sum(spID) as sum from t1 group by userID order by sum asc;
+sum
+2
+3
+4
+5
+select distinct sum(spID) as sum from t1 where score>1 group by userID order by sum asc;
+sum
+2
+3
+4
+5
+select userID,MAX(score) from t1 where userID between 2 and 3 group by userID order by userID;
+userid max(score)
+2 2
+3 3
+select userID,MAX(score) from t1 where userID not between 2 and 3 group by userID order by userID desc;
+userid max(score)
+11 99
+6 10
+1 5
+select spID,userID,score from t1 limit 2,1;
+spid userid score
+2 1 4
+select spID,userID,score from t1 limit 2 offset 1;
+spid userid score
+2 2 2
+2 1 4
+select sum(score) as sum from t1 where spID=6 group by score order by sum desc;
+sum
+select userID, userID DIV 2 as user_dir, userID%2 as user_percent, userID MOD 2 as user_mod from t1;
+userid user_dir user_percent user_mod
+1 0 1 1
+2 1 0 0
+1 0 1 1
+3 1 1 1
+1 0 1 1
+6 3 0 0
+11 5 1 1
+drop table if exists a;
+create table a(a int);
+insert into a values(1),(2),(3),(4),(5),(6),(7),(8);
+select count(*) from a where a>=2 and a<=8;
+count(*)
+7
+drop table if exists t1;
+create table t1 ( id int, name varchar(50) );
+insert into t1 values (1, 'aaaaa');
+insert into t1 values (3, "aaaaa");
+insert into t1 values (2, 'eeeeeee');
+select distinct name as name1 from t1;
+name1
+aaaaa
+eeeeeee
+drop table if exists t2;
+create table t2(name char(10),owner char(10), species char(10), gender char(1), weight float,age int);
+insert into t2 values ('Sunsweet01','Dsant01','otter','f',30.11,2), ('Sunsweet02','Dsant02','otter','m',30.11,3);
+insert into t2(name, owner, species, gender, weight, age) values ('Sunsweet03','Dsant01','otter','f',30.11,2), ('Sunsweet04','Dsant02','otter','m',30.11,3);
+select * from t2 limit 2, 18446744073709551615;
+name owner species gender weight age
+Sunsweet03 Dsant01 otter f 30.1100 2
+Sunsweet04 Dsant02 otter m 30.1100 3
+drop table if exists t3;
+create table t3 (spID int,userID int,score smallint);
+insert into t3 values (1,1,1);
+insert into t3 values (2,2,2);
+insert into t3 values (2,1,4);
+insert into t3 values (3,3,3);
+insert into t3 values (1,1,5);
+insert into t3 values (4,6,10);
+insert into t3 values (5,11,99);
+select userID,MAX(score) max_score from t3 where userID <2 || userID > 3 group by userID order by max_score;
+userid max_score
+1 5
+6 10
+11 99
+select userID, userID DIV 2 as user_dir, userID%2 as user_percent, userID MOD 2 as user_mod from t3 where userID > 3 ;
+userid user_dir user_percent user_mod
+6 3 0 0
+11 5 1 1
+select CAST(userID AS CHAR) userid_cast, userID from t3 where CAST(spID AS CHAR)='1';
+userid_cast userid
+1 1
+1 1
+select CAST(userID AS DOUBLE) cast_double, CAST(userID AS FLOAT(3)) cast_float , CAST(userID AS REAL) cast_real, CAST(userID AS SIGNED) cast_signed, CAST(userID AS UNSIGNED) cast_unsigned from t3 limit 2;
+cast_double cast_float cast_real cast_signed cast_unsigned
+1.0000 1.0000 1.0000 1 1
+2.0000 2.0000 2.0000 2 2
+select * from t3 where spID>2 AND userID <2 || userID >=2 OR userID < 2 limit 3;
+spid userid score
+1 1 1
+2 2 2
+2 1 4
+select * from t3 where (spID >2 or spID <= 2) && score <> 1 AND userID/2>2;
+spid userid score
+4 6 10
+5 11 99
+select * from t3 where spID >2 || spID <= 2 && score !=1 limit 3;
+spid userid score
+2 2 2
+2 1 4
+3 3 3
+select userID,MAX(score) max_score from t3 where userID <2 || userID > 3 group by userID order by max_score;
+userid max_score
+1 5
+6 10
+11 99
+select * from t3 where userID/2>2;
+spid userid score
+4 6 10
+5 11 99
+drop table if exists t4;
+create table t4(c1 int, c2 int);
+insert into t4 values (-3, 2);
+insert into t4 values (1, 2);
+select c1, -c2 from t4 order by -c1 desc;
+c1 -c2
+-3 -2
+1 -2
+drop table if exists t5;
+create table t5(a int,b varchar(10),c varchar(10));
+insert into t5 values(1,'ab','cd'),(2,'ba','dc'),(3,'bc','de'),(4,'cb','ed'),(5,'cd','ef'),(6,'dc','fe'),(2,'de','fg'),(1,'ed','gf');
+select * from t5 where (b='ba' or b='cb') and (c='dc' or c='ed');
+a b c
+2 ba dc
+4 cb ed
+drop table if exists tbl_01;
+create table tbl_01 (col1 int, a bigint unsigned, c char(10) not null);
+insert into tbl_01 values (1,1,"a");
+insert into tbl_01 values (2,2,"b");
+insert into tbl_01 values (2,3,"c");
+insert into tbl_01 values (3,4,"E");
+insert into tbl_01 values (3,5,"C");
+insert into tbl_01 values (3,6,"D");
+select a,c,sum(a) from tbl_01 group by a;
+a c sum(a)
+1 a 1
+2 b 2
+3 c 3
+4 E 4
+5 C 5
+6 D 6
+drop table if exists t1;
+drop table if exists t2;
+create table t1 (id int primary key);
+create table t2 (id int);
+insert into t1 values (75);
+insert into t1 values (79);
+insert into t1 values (78);
+insert into t1 values (77);
+insert into t1 values (104);
+insert into t1 values (103);
+insert into t1 values (102);
+insert into t1 values (101);
+insert into t1 values (105);
+insert into t1 values (106);
+insert into t1 values (107);
+insert into t2 values (107),(75),(1000);
+select t1.id, count(t2.id) from t1,t2 where t2.id = t1.id group by t1.id order by t1.id desc;
+t1.id count(t2.id)
+107 1
+75 1
+drop table t1;
+create table t1 ( a int not null default 1, big bigint );
+insert into t1 (big) values (-1),(12345678901234567),(9223372036854775807);
+select * from t1;
+a big
+1 -1
+1 12345678901234567
+1 9223372036854775807
+select min(big),max(big),max(big)-1 from t1;
+min(big) max(big) max(big) - 1
+-1 9223372036854775807 9223372036854775806
+drop table t1;
+create table t1 ( a int not null default 1, big bigint unsigned);
+insert into t1 (big) values (12345678901234567),(9223372036854775807),(18446744073709551615);
+select * from t1;
+a big
+1 12345678901234567
+1 9223372036854775807
+1 18446744073709551615
+select min(big),max(big),max(big)-1 from t1;
+min(big) max(big) max(big) - 1
+12345678901234567 18446744073709551615 -2
+select min(big),max(big),max(big)-1 from t1 group by a;
+min(big) max(big) max(big) - 1
+12345678901234567 18446744073709551615 -2
+drop table if exists t1;
+create table t1 (
+value64 bigint unsigned not null,
+value32 int not null
+);
+insert into t1 values(17156792991891826145, 1);
+insert into t1 values(9223372036854775807, 2);
+select * from t1;
+value64 value32
+17156792991891826145 1
+9223372036854775807 2
+drop table if exists t1,t2,t3;
+create table t1 (libname1 varchar(21) not null primary key, city varchar(20));
+create table t2 (isbn2 varchar(21) not null primary key, author varchar(20), title varchar(60));
+create table t3 (isbn3 varchar(21) not null, libname3 varchar(21) not null, quantity int);
+insert into t2 values ('001','Daffy','Aducklife');
+insert into t2 values ('002','Bugs','Arabbitlife');
+insert into t2 values ('003','Cowboy','Lifeontherange');
+insert into t2 values ('000','Anonymous','Wannabuythisbook?');
+insert into t2 values ('004','BestSeller','OneHeckuvabook');
+insert into t2 values ('005','EveryoneBuys','Thisverybook');
+insert into t2 values ('006','SanFran','Itisasanfranlifestyle');
+insert into t2 values ('007','BerkAuthor','Cool.Berkley.the.book');
+insert into t3 values('000','NewYorkPublicLibra',1);
+insert into t3 values('001','NewYorkPublicLibra',2);
+insert into t3 values('002','NewYorkPublicLibra',3);
+insert into t3 values('003','NewYorkPublicLibra',4);
+insert into t3 values('004','NewYorkPublicLibra',5);
+insert into t3 values('005','NewYorkPublicLibra',6);
+insert into t3 values('006','SanFransiscoPublic',5);
+insert into t3 values('007','BerkeleyPublic1',3);
+insert into t3 values('007','BerkeleyPublic2',3);
+insert into t3 values('001','NYC Lib',8);
+insert into t1 values ('NewYorkPublicLibra','NewYork');
+insert into t1 values ('SanFransiscoPublic','SanFran');
+insert into t1 values ('BerkeleyPublic1','Berkeley');
+insert into t1 values ('BerkeleyPublic2','Berkeley');
+insert into t1 values ('NYCLib','NewYork');
+select city,libname1,count(libname1) as a from t3 join t1 on libname1=libname3 join t2 on isbn3=isbn2 group by city,libname1;
+city libname1 a
+NewYork NewYorkPublicLibra 6
+SanFran SanFransiscoPublic 1
+Berkeley BerkeleyPublic1 1
+Berkeley BerkeleyPublic2 1
+drop table if exists t1;
+create table t1(a int,b varchar(5));
+insert into t1 values(1,'a');
+insert into t1 values(null,null);
+insert into t1 values(null,'b');
+insert into t1 values(1,null);
+select avg(a),b from t1 group by b order by b;
+avg(a) b
+1.0000 NULL
+1.0000 a
+NULL b
+drop table if exists t1;
+CREATE TABLE t1 (a int default NULL);
+INSERT INTO t1 VALUES (NULL),(NULL);
+select * from t1;
+a
+NULL
+NULL
+DROP TABLE if EXISTS t1,t2;
+create table t1 (a int, b int);
+insert into t1 values(10,null);
+create table t2 (c int, d int);
+insert into t2 values(20,null);
+select * from t1 join t2 on a=c group by a order by a;
+a b c d
+drop table if exists t1;
+CREATE TABLE t1 (a int default null, b varchar(16) default null, c datetime DEFAULT null);
+INSERT INTO t1(a, c) values (1,"2003-01-14 03:54:55");
+INSERT INTO t1(a, c) values (1,"2004-01-14 03:54:55");
+INSERT INTO t1(a, c) values (1,"2005-01-14 03:54:55");
+INSERT INTO t1(a, b) values (1,"2022year");
+INSERT INTO t1(b,c) values ("2022year","2003-01-14 03:54:55");
+INSERT INTO t1(b,c) values ("2021year","2003-01-14 03:54:55");
+INSERT INTO t1(b,c) values ("2020year","2003-01-14 03:54:55");
+select max(a),b,c from t1 group by b,c order by b,c;
+max(a) b c
+1 NULL 2003-01-14 03:54:55
+1 NULL 2004-01-14 03:54:55
+1 NULL 2005-01-14 03:54:55
+NULL 2020year 2003-01-14 03:54:55
+NULL 2021year 2003-01-14 03:54:55
+1 2022year NULL
+NULL 2022year 2003-01-14 03:54:55
+drop table if exists t1;
+create table t1(i int);
+insert into t1 values(1),(2),(3),(4),(5);
+insert into t1 values(null);
+select count(*) from t1 where i=2;
+count(*)
+1
+drop table if exists t1;
+CREATE TABLE t1 (c0 varchar(0) DEFAULT NULL);
+insert into t1 values();
+insert into t1 values('');
+select * from t1;
+c0
+NULL
+
diff --git a/result/show.result b/result/show.result
new file mode 100644
index 000000000..7eb6e87d5
--- /dev/null
+++ b/result/show.result
@@ -0,0 +1,18 @@
+drop database if exists test01;
+create database test01;
+use test01;
+create table t1 (id int not null, str char(10),name varchar(10));
+create table t2 (a int);
+show tables;
+Tables
+t1
+t2
+show tables from test01;
+Tables
+t1
+t2
+show columns from t1;
+Field Type Null Key Default Extra
+id int(32)
+str char(10) NULL
+name varchar(10) NULL
diff --git a/run.sh b/run.sh
new file mode 100755
index 000000000..0d7ed04b5
--- /dev/null
+++ b/run.sh
@@ -0,0 +1,21 @@
+#!/usr/bin/env bash
+
+WORKSPACE=$(cd `dirname $0`; pwd)
+MO_YAML=$WORKSPACE/mo.yml
+RUN_YAML=$WORKSPACE/run.yml
+LIB_WORKSPACE=$WORKSPACE/lib
+
+
+function boot {
+local libJars libJar
+for libJar in `find ${LIB_WORKSPACE} -name "*.jar"`
+do
+ libJars=${libJars}:${libJar}
+done
+java -Xms1024M -Xmx1024M -cp ${libJars} \
+ -Dconf.yml=${MO_YAML} \
+ -Drun.yml=${RUN_YAML} \
+ io.mo.Tester
+}
+
+boot
\ No newline at end of file
diff --git a/run.yml b/run.yml
new file mode 100755
index 000000000..8bfcc54cb
--- /dev/null
+++ b/run.yml
@@ -0,0 +1,18 @@
+#version
+
+#sql scritps path,only support relative path from "cases/..."
+path: "cases/"
+
+#method
+#run: means execute test scripts configured by para[path] completely,and generate the test reprot,execution logs
+#debug: means execute test scripts configured by para[path] completely, only print the result to console,do not generate the test reprot,execution logs
+#genrs: means generate the expected result for the test scripts only
+method: "run"
+
+#type
+#script: means only execute the sql commands in the scripts file separately
+#suite: means execute the sql commands in the format of testsuit.
+type: "script"
+
+#rate: means the execution success rate,if the actual rate is less than this,the programe will exit with status 1
+rate: 90
diff --git a/src/main/java/io/mo/App.java b/src/main/java/io/mo/App.java
new file mode 100755
index 000000000..6dc43dfe7
--- /dev/null
+++ b/src/main/java/io/mo/App.java
@@ -0,0 +1,13 @@
+package io.mo;
+
+/**
+ * Hello world!
+ *
+ */
+public class App
+{
+ public static void main( String[] args )
+ {
+ System.out.println( "Hello World!" );
+ }
+}
diff --git a/src/main/java/io/mo/Tester.java b/src/main/java/io/mo/Tester.java
new file mode 100755
index 000000000..0ec52572d
--- /dev/null
+++ b/src/main/java/io/mo/Tester.java
@@ -0,0 +1,136 @@
+package io.mo;
+
+import io.mo.cases.TestScript;
+import io.mo.cases.TestSuite;
+import io.mo.db.Debugger;
+import io.mo.db.Executor;
+import io.mo.result.TestReport;
+import io.mo.util.RunConfUtil;
+import io.mo.util.ScriptParser;
+import org.apache.log4j.Logger;
+
+import java.io.File;
+import java.util.ArrayList;
+
+public class Tester {
+ private static ArrayList suites = new ArrayList();
+
+ private static TestReport report = new TestReport();
+
+ private static Logger LOG = Logger.getLogger(Tester.class.getName());
+
+
+
+ public static void main(String[] args){
+
+ String path = RunConfUtil.getPath();
+ String method = RunConfUtil.getMethod();
+ String type = RunConfUtil.getType();
+
+ if(path == null){
+ LOG.error("The scripts file path is not configured,pleas check the config file conf/run.yml.");
+ return;
+ }
+
+ /*if(version == null){
+ LOG.error("The kundb version is not configured,pleas check the config file conf/run.yml.");
+ return;
+ }*/
+
+ if(method == null){
+ LOG.error("The method of execution is not configured,pleas check the config file conf/run.yml.");
+ return;
+ }
+
+ File file = new File(path);
+
+ if(!file.exists()){
+ LOG.error("The scripts file path: "+path+" does not exist,please check.");
+ return;
+ }
+
+
+ if(method.equalsIgnoreCase("run")){
+ LOG.info("The method is [run],now start to run the scripts in the path["+path+"].");
+ run(file,type);
+ LOG.info("All the scripts in the path["+path+"] have been excuted.Now start to create the test report.");
+ report.write();
+ LOG.info("The test report has been generated in files[report.txt,report.xml].");
+
+ if(report.getRate() < RunConfUtil.getRate()){
+ LOG.error("The execution success rate is "+ report.getRate()+"%,and less than config value "+RunConfUtil.getRate()+"%,this test fail.");
+ System.exit(1);
+ }else {
+ LOG.error("The execution success rate is "+ report.getRate()+"%,and not less than config value "+RunConfUtil.getRate()+"%,this test succeed.");
+ System.exit(0);
+ }
+ }
+
+ if(method.equalsIgnoreCase("debug")){
+ debug(file,type);
+ }
+
+ if(method.equalsIgnoreCase("genrs")){
+ LOG.info("The method is [genrs],now start to generate the checkpoints in the path["+path+"].");
+ generateRs(file);
+ LOG.info("ALL the results in the path["+path+"] have been generated or updated.");
+ }
+
+ if(!method.equalsIgnoreCase("genrs")&&!method.equalsIgnoreCase("debug")&&!method.equalsIgnoreCase("run")){
+ LOG.info("The method is ["+method+"] can not been supported.Only[run,debug,genrs] can be supported.");
+ return;
+ }
+
+ }
+
+ public static void run(File file,String type){
+ if(file.isFile()){
+ if(type.equalsIgnoreCase("script")){
+ ScriptParser.parseScript(file.getPath());
+ TestScript script = ScriptParser.getTestScript();
+ Executor.run(script);
+ report.collect(script);
+ return;
+ }
+
+ if(type.equalsIgnoreCase("suite")){
+ ScriptParser.parseSuite(file.getPath());
+ ArrayList suites = ScriptParser.getTestSuites();
+ Executor.run(suites,file.getPath());
+ report.collect(suites);
+ return;
+ }
+ }
+ File[] fs = file.listFiles();
+ for(int i = 0;i < fs.length;i++){
+ run(fs[i], type);
+ }
+ }
+
+ public static void generateRs(File file){
+ if(file.isFile()){
+ ScriptParser.parseScript(file.getPath());
+ TestScript script = ScriptParser.getTestScript();
+ Executor.genRS(script);
+ return;
+ }
+ File[] fs = file.listFiles();
+ for(int i = 0;i < fs.length;i++){
+ generateRs(fs[i]);
+ }
+ }
+
+ public static void debug(File file,String type){
+ if(file.isFile()){
+ ScriptParser.parseScript(file.getPath());
+ TestScript script = ScriptParser.getTestScript();
+ Debugger.run(script);
+ return;
+ }
+ File[] fs = file.listFiles();
+ for(int i = 0;i < fs.length;i++){
+ debug(fs[i],type);
+ }
+
+ }
+}
diff --git a/src/main/java/io/mo/cases/SqlCommand.java b/src/main/java/io/mo/cases/SqlCommand.java
new file mode 100755
index 000000000..82819b5f8
--- /dev/null
+++ b/src/main/java/io/mo/cases/SqlCommand.java
@@ -0,0 +1,182 @@
+package io.mo.cases;
+
+import io.mo.constant.COMMON;
+import io.mo.constant.ESCAPE;
+import io.mo.result.TestResult;
+import java.lang.StringBuffer;
+
+import java.io.UnsupportedEncodingException;
+
+public class SqlCommand {
+
+ private String id;
+
+ private String golabId;
+
+ private TestResult result;
+
+ private StringBuffer command;
+
+
+ private boolean update = false;
+
+ private int conn_id = 0;
+ private String conn_user = null;
+ private String conn_pswd = null;
+
+
+ private String delimiter;
+
+ private String scriptFile;
+
+ public SqlCommand getNext() {
+ return next;
+ }
+
+ public void setNext(SqlCommand next) {
+ this.next = next;
+ }
+
+ private SqlCommand next;
+
+ public SqlCommand(){
+ this.delimiter = COMMON.DEFAUT_DELIMITER;
+ command = new StringBuffer();
+ result = new TestResult();
+ }
+
+ public SqlCommand(String id){
+ this.id = id;
+ this.delimiter = COMMON.DEFAUT_DELIMITER;
+ result = new TestResult();
+ }
+
+ public SqlCommand(String id,StringBuffer command){
+ this.command = command;
+ this.id = id;
+ this.delimiter = COMMON.DEFAUT_DELIMITER;
+ check();
+ result = new TestResult();
+ }
+
+ public void append(String command){
+ this.command.append(command);
+ this.command.append(COMMON.LINE_SEPARATOR);
+ check();
+ }
+
+ private void check() {
+ String command = this.command.toString();
+ String opt = command.split(" ")[0];
+ if (opt.equalsIgnoreCase("select") || opt.equalsIgnoreCase("show"))
+ this.update = false;
+ else
+ this.update = true;
+
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getCommand() {
+ if(command.length() == 0)
+ return null;
+ return command.toString();
+ }
+
+ public void setCommand(StringBuffer command) {
+ this.command = command;
+ }
+
+ public String getDelimiter() {
+ return delimiter;
+ }
+
+ public void setDelimiter(String delimiter) {
+ this.delimiter = delimiter;
+ }
+
+
+ public int getConn_id() {
+ return conn_id;
+ }
+
+ public void setConn_id(int conn_id) {
+ this.conn_id = conn_id;
+ }
+
+ public String getConn_user() {
+ return conn_user;
+ }
+
+ public void setConn_user(String conn_user) {
+ try {
+ this.conn_user = ESCAPE.parse(new String(conn_user.getBytes("utf-8")));
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public String getConn_pswd() {
+ return conn_pswd;
+ }
+
+ public void setConn_pswd(String conn_pswd) {
+ this.conn_pswd = conn_pswd;
+ }
+
+
+ public boolean isUpdate() {
+ return update;
+ }
+
+ public String getScriptFile() {
+ return scriptFile;
+ }
+
+ public void setScriptFile(String scriptFile) {
+ this.scriptFile = scriptFile;
+ }
+
+ public String getGolabId() {
+ return golabId;
+ }
+
+ public void setGolabId(String golabId) {
+ this.golabId = golabId;
+ }
+
+ public TestResult getResult() {
+ return result;
+ }
+
+ public void setResult(TestResult result) {
+ this.result = result;
+ }
+
+ public void print(){
+ if(id != null)
+ System.out.println("----------command: id = "+id+"-------------");
+
+ if(conn_id != 0) {
+ System.out.println("----------command: conn_id = " + conn_id + "-------------");
+ if(conn_user != null){
+ System.out.println("----------command: user = " + conn_user + ",password = "+ conn_pswd +"-------------");
+ }
+ }
+ System.out.println("----------command: delimiter = " + delimiter + "-------------");
+
+ System.out.println(this.command);
+
+ if(id != null)
+ System.out.println("----------command: id = "+id+"-------------");
+ }
+
+
+
+}
diff --git a/src/main/java/io/mo/cases/TestCase.java b/src/main/java/io/mo/cases/TestCase.java
new file mode 100755
index 000000000..f9868abe9
--- /dev/null
+++ b/src/main/java/io/mo/cases/TestCase.java
@@ -0,0 +1,147 @@
+package io.mo.cases;
+
+import io.mo.constant.RESULT;
+import io.mo.result.TestResult;
+
+import java.util.ArrayList;
+
+public class TestCase {
+ private String desc;
+ private TestResult result;
+ private String fileName;
+
+ private TestSuite suite;
+
+ private float duration = 0;
+
+ private boolean executed = true;
+ private StringBuffer remark = new StringBuffer();
+
+ private ArrayList commands = new ArrayList();
+ private ArrayList labels = new ArrayList();
+
+ public TestCase(){
+ result = new TestResult();
+ }
+
+ public ArrayList getCommands() {
+ return commands;
+ }
+
+ public void setCommands(ArrayList commands) {
+ this.commands = commands;
+ }
+
+ public ArrayList getLabels() {
+ return labels;
+ }
+
+ public void setLabels(ArrayList labels) {
+ this.labels = labels;
+ }
+
+ public String getFileName() {
+ return fileName;
+ }
+
+ public void setFileName(String fileName) {
+ this.fileName = fileName;
+ }
+
+ public void setExecStatus(boolean status){
+ this.executed = status;
+ }
+
+ public boolean getExecStatus(){
+ return this.executed;
+ }
+
+
+
+ public void addCommand(SqlCommand command){
+ commands.add(command);
+ }
+
+ public void addLabel(String label){
+ labels.add(label);
+ }
+
+ public String getDesc() {
+ return desc;
+ }
+
+ public void setDesc(String desc) {
+ this.desc = desc;
+ }
+
+ public String getRemark() {
+ return remark.toString();
+ }
+
+ public void addRemark(String remark) {
+ this.remark.append(remark);
+
+ }
+
+ public TestResult getResult() {
+ return result;
+ }
+
+ public void setResult(TestResult result) {
+ this.result = result;
+ }
+
+ public TestSuite getSuite() {
+ return suite;
+ }
+
+ public void setSuite(TestSuite suite) {
+ this.suite = suite;
+ }
+
+ public float getDuration() {
+ return duration;
+ }
+
+ public void setDuration(float duration) {
+ this.duration = duration;
+ }
+
+ public String getSqlCommands(){
+ StringBuffer buffer = new StringBuffer();
+ for(int i = 0; i < suite.getSetupSqls().size();i++){
+ buffer.append(suite.getSetupSqls().get(i).getCommand());
+ }
+
+ for(int i = 0; i < commands.size();i++){
+ buffer.append(commands.get(i).getCommand());
+ }
+
+ return buffer.toString();
+ }
+
+
+ public String toString(){
+ String _case = "CASE: ";
+ _case += desc + "\t" + result.getResult();
+ if(!result.getResult().equalsIgnoreCase(RESULT.RESULT_TYPE_PASS)){
+ _case += "\n\t[ERROR DESC]: "+result.getErrorDesc();
+ if(result.getErrorCode().equalsIgnoreCase(RESULT.ERROR_CHECK_FAILED_CODE)){
+ _case += "\n\t[EXPECT]: "+result.getExpResult();
+ _case += "\n\t[ACTUAL]: "+result.getActResult();
+ }
+
+ if(result.getRemark() != null){
+ _case += "\n\t[REMARK]: "+result.getRemark();
+ }
+ _case += "\n";
+ }
+ return _case;
+ }
+
+ public void print(){
+ System.out.println("----------case: desc = "+desc+"-------------");
+ }
+
+
+}
diff --git a/src/main/java/io/mo/cases/TestScript.java b/src/main/java/io/mo/cases/TestScript.java
new file mode 100755
index 000000000..37379e4ff
--- /dev/null
+++ b/src/main/java/io/mo/cases/TestScript.java
@@ -0,0 +1,109 @@
+package io.mo.cases;
+
+import io.mo.constant.COMMON;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+public class TestScript {
+
+ private ArrayList commands = new ArrayList();
+ private ArrayList errorcmds = new ArrayList();
+
+ private String fileName;
+ private String id;
+
+ private boolean executed = true;
+
+ private float duration = 0;
+
+ public TestScript(){
+
+ }
+
+ public void addCommand(SqlCommand command){
+ commands.add(command);
+ command.setScriptFile(fileName);
+ }
+
+ public void addCommand(String command){
+ SqlCommand sqlCommand = new SqlCommand();
+ sqlCommand.append(command);
+ commands.add(sqlCommand);
+ }
+
+ public void addErrorCmd(SqlCommand command){
+ errorcmds.add(command);
+ }
+
+ public int getSize(){
+ return commands.size();
+ }
+
+ public ArrayList getCommands(){
+ return commands;
+ }
+
+ public String getCommand(int i){
+ return commands.get(i).toString();
+ }
+
+ public String getScript(){
+ String script = "";
+ for(int i = 0;i < commands.size();i++){
+ script += commands.get(i).getCommand();
+ }
+ return script;
+ }
+
+ public void print(){
+ for(int i = 0; i < commands.size();i++){
+ commands.get(i).print();
+ }
+ }
+
+
+ public String getFileName() {
+ return fileName;
+ }
+
+ public void setFileName(String fileName) {
+ this.fileName = fileName;
+ }
+
+ public void setExecStatus(boolean status){
+ this.executed = status;
+ }
+
+ public boolean getExecStatus(){
+ return this.executed;
+ }
+
+
+ public float getDuration() {
+ return duration;
+ }
+
+ public void setDuration(float duration) {
+ this.duration = duration;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public int getErrorCount(){
+ return errorcmds.size();
+ }
+
+ public List getErrorList(){
+ return errorcmds;
+ }
+
+
+}
diff --git a/src/main/java/io/mo/cases/TestSuite.java b/src/main/java/io/mo/cases/TestSuite.java
new file mode 100755
index 000000000..f3b84a9eb
--- /dev/null
+++ b/src/main/java/io/mo/cases/TestSuite.java
@@ -0,0 +1,102 @@
+package io.mo.cases;
+
+import io.mo.result.TestResult;
+
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+
+public class TestSuite {
+
+ private String fileName;
+ private boolean executed = true;
+
+ private ArrayList setupSqls = new ArrayList();
+ private ArrayList teardownSqls = new ArrayList();
+ private ArrayList cases = new ArrayList();
+
+ public void addTestCase(TestCase _case){
+
+ cases.add(_case);
+ }
+
+ public void setResult(TestResult result){
+ for(int i = 0;i < cases.size();i++){
+ cases.get(i).setResult(result);
+ }
+ }
+
+ public ArrayList getSetupSqls() {
+ return setupSqls;
+ }
+
+ public void setSetupSqls(ArrayList setupSqls) {
+ this.setupSqls = setupSqls;
+ }
+
+ public ArrayList getTeardownSqls() {
+ return teardownSqls;
+ }
+
+ public void setTeardownSqls(ArrayList teardownSqls) {
+ this.teardownSqls = teardownSqls;
+ }
+
+ public ArrayList getCases() {
+ return cases;
+ }
+
+ public void setCases(ArrayList cases) {
+ this.cases = cases;
+ }
+
+ public String getFileName() {
+ return fileName;
+ }
+
+ public void setFileName(String fileName) {
+ this.fileName = fileName.replaceAll(".sql",".log");
+ }
+
+ public void addSetupCommand(SqlCommand command){
+ setupSqls.add(command);
+ }
+
+ public void addTeardownCommand(SqlCommand command){
+ teardownSqls.add(command);
+ }
+ public void setExecStatus(boolean status){
+ this.executed = status;
+ for(int i = 0; i < cases.size();i++){
+ cases.get(i).setExecStatus(status);
+ }
+ }
+
+ public boolean getExecStatus(){
+ return this.executed;
+ }
+
+
+ public void print(){
+ System.out.println("----------preSQLCommands-------------");
+ //preSqls.print();
+ System.out.println("----------preSQLCommands-------------");
+
+ System.out.print("\n\n");
+
+ for(int i = 0; i < cases.size();i++){
+ System.out.println("----------TestCases-------------");
+ cases.get(i).print();
+ System.out.print("\n\n");
+ System.out.println("----------TestCases-------------");
+ }
+
+ System.out.print("\n\n");
+
+ System.out.println("----------postSQLCommands-------------");
+ //preSqls.print();
+ System.out.println("----------postSQLCommands-------------");
+
+ }
+
+
+}
diff --git a/src/main/java/io/mo/constant/COMMON.java b/src/main/java/io/mo/constant/COMMON.java
new file mode 100755
index 000000000..6c1e70e79
--- /dev/null
+++ b/src/main/java/io/mo/constant/COMMON.java
@@ -0,0 +1,53 @@
+package io.mo.constant;
+
+public class COMMON {
+
+ public static String[] RESOURCES_DIR = new String[]{"conf","cases","checkpoints","resources","result"};
+
+ public static String T_FILE_SUFFIX = ".sql";
+
+
+ public static String R_FILE_SUFFIX = ".result";
+
+ public static int CONNECTION_ID = 0;//
+ public static int DEFAULT_CONNECTION_NUM = 10;
+
+ public static String DEFAUT_DELIMITER = ";";
+ public static String LINE_SEPARATOR = "\n";
+
+ public static String SUITE_FLAG = "-- @suite";
+ public static String SETUP_SUITE_FLAG = "-- @setup";
+ public static String TEARDOWN_SUITE_FLAG = "-- @teardown";
+
+ public static String CASE_START_FLAG = "-- @case";
+ public static String CASE_DESC_FLAG = "-- @desc:";
+ public static String CASE_LABEL_FLAG = "-- @label:";
+
+ public static String DELIMITER_FLAGE = "-- @delimiter:";
+
+ public static String NEW_SESSION_START_FLAG = "-- @ session";
+ public static String NEW_SESSION_END_FLAG = "-- session}";
+
+ public static String LOG_PATH = "log";
+ public static String RESULT_PATH = "result";
+ public static String TEST_PATH = "test";
+ public static String CASES_PATH = "cases";
+ public static String REPORT_PATH = "report";
+
+ public static String UPDATE_RESULT_TEMPLATE = "Query OK, {num} row affected";
+
+
+ public static int MAX_ROW_COUNT_IN_RS = 100;//the max row count in the resultset
+
+ //事务相关
+ public static String START_TRX = "begin";
+ public static String COMMIT_TRX = "commit";
+ public static String ROLLBACK_TRX = "rollback";
+
+
+
+
+
+
+
+}
\ No newline at end of file
diff --git a/src/main/java/io/mo/constant/ESCAPE.java b/src/main/java/io/mo/constant/ESCAPE.java
new file mode 100755
index 000000000..7d843df8b
--- /dev/null
+++ b/src/main/java/io/mo/constant/ESCAPE.java
@@ -0,0 +1,19 @@
+package io.mo.constant;
+
+public class ESCAPE {
+
+ //Escape character
+ public static String SPACE = " ";
+ public static String DOUBLE_QOUTE = """;
+ public static String SINGLE_QOUTE = "´";
+ public static String CROSSED = "¯";
+
+ public static String parse(String str){
+ return str
+ .replaceAll(SPACE," ")
+ .replaceAll(DOUBLE_QOUTE,"\"")
+ .replaceAll(SINGLE_QOUTE,"'")
+ .replaceAll(CROSSED,"-");
+ }
+
+}
diff --git a/src/main/java/io/mo/constant/RESULT.java b/src/main/java/io/mo/constant/RESULT.java
new file mode 100755
index 000000000..7ce9ba923
--- /dev/null
+++ b/src/main/java/io/mo/constant/RESULT.java
@@ -0,0 +1,28 @@
+package io.mo.constant;
+
+public class RESULT {
+ public static String SUCCESS_CODE = "0000";
+ public static String ERROR_EXEC_FAILED_CODE = "0001";
+ public static String ERROR_CHECK_FAILED_CODE = "0002";
+ public static String ERROR_PRECONDITION_FAILED_CODE = "0003";
+ public static String ERROR_POSTCONDITION_FAILED_CODE = "0004";
+ public static String ERROR_CKFILE_NOT_VALID_CODE = "0005";
+ public static String ERROR_CKFILE_CONTENT_WRONG_CODE = "0006";
+ public static String ERROR_NOT_EXEC_CODE = "0007";
+
+ public static String ERROR_EXEC_FAILED_DESC = "Some exceptions occured when executing this test case.More,See the detail.";
+ public static String ERROR_CHECK_FAILED_DESC = "The actual result is not in accordance with the expectation.More,See the detail.";
+ public static String ERROR_PRECONDITIONFAILED_DESC = "Some exceptions occured when executing the pre-condition .More,See the detail.";
+ public static String ERROR_POSTCONDITIONFAILED_DESC = "Some exceptions occured when executing the post-condition .More,See the detail.";
+ public static String ERROR_CKFILE_NOT_VALID_DESC = "The expected result file does not exist or is not valid.Please check this.";
+ public static String ERROR_CKFILE_CONTENT_WRONG_DESC = "The content of the expected result file can not be parsed.Please check this.";
+ public static String ERROR_NOT_EXEC_DESC = "The script does not been executed because the result file does not exists.";
+
+
+ public static String RESULT_TYPE_PASS = "PASS";
+ public static String RESULT_TYPE_FAILED="FAILED";
+ public static String RESULT_TYPE_NOEXEC="NOEXECUTED";
+ public static String RESULT_TYPE_UNKNOWN="UNKNOWN";
+
+}
+
diff --git a/src/main/java/io/mo/db/Connection.java b/src/main/java/io/mo/db/Connection.java
new file mode 100755
index 000000000..70b2a5cc6
--- /dev/null
+++ b/src/main/java/io/mo/db/Connection.java
@@ -0,0 +1,34 @@
+package io.mo.db;
+
+public class Connection {
+
+
+ private String user_name;
+ private String user_pswd;
+ private java.sql.Connection conn;
+
+ public String getUser_name() {
+ return user_name;
+ }
+
+ public void setUser_name(String user_name) {
+ this.user_name = user_name;
+ }
+
+ public String getUser_pswd() {
+ return user_pswd;
+ }
+
+ public void setUser_pswd(String user_pswd) {
+ this.user_pswd = user_pswd;
+ }
+
+ public java.sql.Connection getConn() {
+ return conn;
+ }
+
+ public void setConn(java.sql.Connection conn) {
+ this.conn = conn;
+ }
+
+}
diff --git a/src/main/java/io/mo/db/ConnectionManager.java b/src/main/java/io/mo/db/ConnectionManager.java
new file mode 100755
index 000000000..8d06693a3
--- /dev/null
+++ b/src/main/java/io/mo/db/ConnectionManager.java
@@ -0,0 +1,89 @@
+package io.mo.db;
+
+import io.mo.constant.COMMON;
+import io.mo.util.MoConfUtil;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+
+public class ConnectionManager {
+
+ private static String jdbcURL = MoConfUtil.getURL();
+ private static String userName = MoConfUtil.getUserName();
+ private static String pwd = MoConfUtil.getUserpwd();
+ private static String driver = MoConfUtil.getDriver();
+
+ private static Connection[] connections = new Connection[COMMON.DEFAULT_CONNECTION_NUM];
+
+ static {
+ try {
+ Class.forName(driver);
+ connections[0] = DriverManager.getConnection(jdbcURL, userName, pwd);
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static Connection getConnection(){
+
+ try {
+ Class.forName(driver);
+ if(connections[0] == null){
+ connections[0] = DriverManager.getConnection(jdbcURL, userName, pwd);
+ return connections[0];
+ }
+ return connections[0];
+ } catch (SQLException e) {
+ e.printStackTrace();
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+
+ return null;
+ }
+
+ public static Connection getConnection(int i){
+
+ try {
+ if(connections[i] == null){
+ connections[i] = DriverManager.getConnection(jdbcURL, userName, pwd);
+ return connections[i];
+ }
+ return connections[i];
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+
+ return null;
+ }
+
+ public static Connection getConnection(int i,String userName, String pwd){
+ try {
+ if(connections[i] == null){
+ connections[i] = DriverManager.getConnection(jdbcURL, userName, pwd);
+ return connections[i];
+ }
+ return connections[i];
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+
+ return null;
+ }
+
+ public static void reset(){
+ for(int i = 1; i < connections.length;i++){
+ if(connections[i] != null){
+ try {
+ connections[i].close();
+ connections[i] = null;
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/io/mo/db/Debugger.java b/src/main/java/io/mo/db/Debugger.java
new file mode 100755
index 000000000..c685139d7
--- /dev/null
+++ b/src/main/java/io/mo/db/Debugger.java
@@ -0,0 +1,324 @@
+package io.mo.db;
+
+import io.mo.cases.SqlCommand;
+import io.mo.cases.TestCase;
+import io.mo.cases.TestScript;
+import io.mo.cases.TestSuite;
+import io.mo.constant.COMMON;
+
+import java.io.*;
+import java.sql.Connection;
+import java.sql.*;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+
+public class Debugger {
+ private static PrintWriter logWriter;
+ private static SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd-HHmmss.SSS");
+
+ public static void run(TestScript script){
+
+ initWriter(COMMON.LOG_PATH+"/"+format.format(new Date()),script.getId()+".log");
+ ConnectionManager.reset();
+ boolean hasResults = false;
+ Statement statement = null;
+ Connection connection = ConnectionManager.getConnection();
+
+ ArrayList commands = script.getCommands();
+ for (int j = 0; j < commands.size(); j++) {
+ SqlCommand command = commands.get(j);
+ connection = getConnection(command);
+ try{
+ statement = connection.createStatement();
+ println("MySQL> "+command.getCommand());
+ if (command.isUpdate()) {
+ int num = statement.executeUpdate(command.getCommand());
+ String res = COMMON.UPDATE_RESULT_TEMPLATE.replace("{num}", String.valueOf(num));
+ if(j < commands.size() -1 )
+ printWithLineSeperator(res+"\n");
+ else
+ println(res+"\n");
+ } else {
+ hasResults = statement.execute(command.getCommand());
+ if(j < commands.size() -1 )
+ printResultsWithLineSeperator(statement, hasResults);
+ else
+ printResults(statement, hasResults);
+ }
+ statement.close();
+ }catch (SQLException e) {
+ printlnError(e.getMessage());
+ continue;
+ }
+ }
+ //script.print();
+ }
+
+ public static void run(String command) {
+
+ initWriter(COMMON.LOG_PATH,format.format(new Date()));
+
+ Connection connection = ConnectionManager.getConnection();
+
+ boolean hasResults = false;
+ Statement statement = null;
+ try {
+ statement = connection.createStatement();
+ SqlCommand sqlCommand = new SqlCommand();
+ sqlCommand.append(command);
+ println("MySQL [kundb]> "+command);
+ if(sqlCommand.isUpdate()){
+ int num = statement.executeUpdate(sqlCommand.getCommand());
+ String res = COMMON.UPDATE_RESULT_TEMPLATE.replace("{num}",String.valueOf(num));
+ printWithLineSeperator(res);
+ } else {
+ hasResults = statement.execute(sqlCommand.getCommand());
+ printResults(statement, hasResults);
+ }
+ statement.close();
+ } catch (SQLException e) {
+ printlnError(e.getMessage());
+ }
+
+ try {
+ statement.close();
+ } catch (Exception e) {
+ printErrorWithLineSeperator(e.getMessage());
+ }
+
+ }
+
+
+ private static void initWriter(String path,String name){
+ //String dir = path.replace(".","/");
+ String dir = path;
+ File directories = new File(dir);
+ if(!directories.exists())
+ directories.mkdirs();
+
+ try {
+ logWriter = new PrintWriter(new FileWriter(new File(dir+ "/" + name )));
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private static void printResults(Statement statement, boolean hasResults) {
+ try {
+ if (hasResults) {
+ ResultSet rs = statement.getResultSet();
+ if (rs != null) {
+ ResultSetMetaData md = rs.getMetaData();
+ int cols = md.getColumnCount();
+
+ int i;
+ String value;
+ for(i = 0; i < cols; ++i) {
+ value = md.getColumnLabel(i + 1);
+ print(value + "\t");
+ }
+
+ println("");
+
+ while(rs.next()) {
+ for(i = 0; i < cols; ++i) {
+ value = rs.getString(i + 1);
+ print(value + "\t");
+ }
+
+ println("");
+ }
+ }
+ }else {
+
+ }
+ } catch (SQLException var8) {
+ printlnError("Error printing results: " + var8.getMessage());
+ }
+ //logWriter.close();
+
+ }
+
+
+ private static void print(Object o) {
+ if (logWriter != null) {
+ logWriter.print(o);
+ logWriter.flush();
+ System.out.print(o);
+ }
+
+ }
+
+ private static void println(Object o) {
+ if (logWriter != null) {
+ logWriter.println(o);
+ logWriter.flush();
+ System.out.println(o);
+ }
+
+ }
+
+ private static void printlnError(Object o) {
+ if (logWriter != null) {
+ logWriter.println(o);
+ logWriter.println("");
+ logWriter.flush();
+ System.out.println(o);
+ System.out.println("");
+ }
+ }
+
+ private static void printResultsWithLineSeperator(Statement statement, boolean hasResults) {
+ try {
+ if (hasResults) {
+ ResultSet rs = statement.getResultSet();
+ if (rs != null) {
+ ResultSetMetaData md = rs.getMetaData();
+ int cols = md.getColumnCount();
+
+ int i;
+ String value;
+ for(i = 0; i < cols; ++i) {
+ value = md.getColumnLabel(i + 1);
+ print(value + "\t");
+ }
+
+ println("");
+
+ while(rs.next()) {
+ for(i = 0; i < cols; ++i) {
+ value = rs.getString(i + 1);
+ print(value + "\t");
+ }
+
+ println("");
+ }
+ }
+ logWriter.println("------------------------------------------------------------------------------------\n");
+ System.out.println("------------------------------------------------------------------------------------\n");
+ }else {
+
+ }
+ } catch (SQLException var8) {
+ printErrorWithLineSeperator("Error printing results: " + var8.getMessage());
+ }
+ //logWriter.close();
+
+ }
+
+
+ private static void printWithLineSeperator(Object o) {
+ if (logWriter != null) {
+ logWriter.println(o);
+ System.out.println(o);
+ logWriter.println("------------------------------------------------------------------------------------\n");
+ System.out.println("------------------------------------------------------------------------------------\n");
+ logWriter.flush();
+ }
+
+ }
+
+ private static void printErrorWithLineSeperator(Object o) {
+ if (logWriter != null) {
+ logWriter.println(o);
+ System.out.println(o);
+ logWriter.println("------------------------------------------------------------------------------------\n");
+ System.out.println("------------------------------------------------------------------------------------\n");
+ logWriter.flush();
+ }
+ }
+
+ private static void startCase(String case_desc){
+ if (logWriter != null) {
+ logWriter.println("--------------------------------------case: "+case_desc+" start---------------------------------------\n");
+ System.out.println("--------------------------------------case: "+case_desc+" start---------------------------------------\n");
+ logWriter.flush();
+ }
+ }
+
+ private static void finishCase(String case_desc){
+ if (logWriter != null) {
+ logWriter.println("--------------------------------------case: "+case_desc+" end-----------------------------------------\n");
+ System.out.println("--------------------------------------case: "+case_desc+" end-----------------------------------------\n");
+ logWriter.flush();
+ }
+ }
+
+ private static void startPreSql(){
+ if (logWriter != null) {
+ logWriter.println("--------------------------------------preSql start---------------------------------------\n");
+ System.out.println("--------------------------------------preSql start---------------------------------------\n");
+ logWriter.flush();
+ }
+ }
+
+ private static void finishPreSql(){
+ if (logWriter != null) {
+ logWriter.println("--------------------------------------preSql end-----------------------------------------\n");
+ System.out.println("--------------------------------------preSql end-----------------------------------------\n");
+ logWriter.flush();
+ }
+ }
+
+ private static void startPostSql(){
+ if (logWriter != null) {
+ logWriter.println("--------------------------------------postSql start---------------------------------------\n");
+ System.out.println("--------------------------------------postSql start---------------------------------------\n");
+ logWriter.flush();
+ }
+ }
+
+ private static void finishPostSql(){
+ if (logWriter != null) {
+ logWriter.println("--------------------------------------postSql end-----------------------------------------\n");
+ System.out.println("--------------------------------------postSql end-----------------------------------------\n");
+ logWriter.flush();
+ }
+ }
+
+
+ public static Connection getConnection(SqlCommand command){
+ Connection connection = null;
+ if(command.getConn_id() != 0){
+ if(command.getConn_user() == null){
+ System.out.println(command.getConn_id());
+ connection = ConnectionManager.getConnection(command.getConn_id());
+ try {
+ if (isTrxBeginning(command)) {
+ connection.setAutoCommit(false);
+ }
+
+ if(isTrxEndding(command)){
+ connection.setAutoCommit(true);
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+
+ return connection;
+ }else {
+ System.out.println(command.getConn_user()+" "+command.getConn_id()+" "+command.getConn_pswd());
+ connection = ConnectionManager.getConnection(command.getConn_id(),command.getConn_user(),command.getConn_pswd());
+ return connection;
+ }
+ }
+ connection = ConnectionManager.getConnection();
+ return connection;
+ }
+
+ public static boolean isTrxBeginning(SqlCommand command){
+ if(command.getCommand().toLowerCase().startsWith(COMMON.START_TRX))
+ return true;
+
+ return false;
+ }
+
+ public static boolean isTrxEndding(SqlCommand command){
+ if(command.getCommand().toLowerCase().startsWith(COMMON.COMMIT_TRX) || command.getCommand().toLowerCase().startsWith(COMMON.ROLLBACK_TRX))
+ return true;
+
+ return false;
+ }
+
+}
diff --git a/src/main/java/io/mo/db/Executor.java b/src/main/java/io/mo/db/Executor.java
new file mode 100755
index 000000000..a72a39201
--- /dev/null
+++ b/src/main/java/io/mo/db/Executor.java
@@ -0,0 +1,530 @@
+package io.mo.db;
+
+import io.mo.cases.SqlCommand;
+import io.mo.cases.TestCase;
+import io.mo.cases.TestScript;
+import io.mo.cases.TestSuite;
+import io.mo.constant.COMMON;
+import io.mo.constant.RESULT;
+import io.mo.result.TestResult;
+import io.mo.util.ResultParser;
+import org.apache.log4j.Logger;
+
+import java.io.*;
+import java.sql.*;
+import java.sql.Connection;
+import java.util.ArrayList;
+
+public class Executor {
+ private static PrintWriter logWriter;
+ //private static SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd-HHmmss.SSS");
+
+ private static Logger LOG = Logger.getLogger(Executor.class.getName());
+
+ public static void run(TestScript script){
+ LOG.info("Now start to run the file["+script.getFileName()+"]....................................................");
+ ConnectionManager.reset();
+ Connection connection = ConnectionManager.getConnection();
+
+ boolean hasResults = false;
+ Statement statement = null;
+ //check whether the result file exists
+ File rsf = new File(script.getFileName().replaceFirst(COMMON.CASES_PATH,COMMON.RESULT_PATH).replaceAll("\\.[A-Za-z]+",COMMON.R_FILE_SUFFIX));
+ if(!rsf.exists()) {
+ LOG.warn("The result of the test script file["+script.getFileName()+"] does not exists,please check....");
+
+ //set the execution status of test script to false
+ script.setExecStatus(false);
+ return;
+ }
+
+ ResultParser.reset();
+ ResultParser.parse(rsf.getPath());
+ ArrayList commands = script.getCommands();
+
+ long start = System.currentTimeMillis();
+
+ for (int j = 0; j < commands.size(); j++) {
+
+ SqlCommand command = null;
+ String exp_res = null;
+ String act_res = null;
+
+ try{
+ command = commands.get(j);
+ connection = getConnection(command);
+ statement = connection.createStatement();
+ if (command.isUpdate()) {
+ //if no-query-type statement is executed successfully,do not need check
+ int num = statement.executeUpdate(command.getCommand());
+ //but need to get the expected result,to skip the read pos
+ ResultParser.skip(command.getCommand());
+ LOG.info("["+script.getFileName()+"]["+command.getCommand().trim()+"] is executed successfully");
+ } else {
+ //if query-type statment is executed successfully,need compare the expected result and the actual result
+ hasResults = statement.execute(command.getCommand());
+ statement.executeQuery(command.getCommand());
+ act_res = getRS(statement.getResultSet());
+ if( j < commands.size() -1)
+ exp_res = ResultParser.getRS(command.getCommand(),commands.get(j + 1).getCommand());
+ else
+ exp_res = ResultParser.getRS(command.getCommand(),null);
+
+ //if compare failed
+ if(!act_res.equalsIgnoreCase(exp_res)){
+ script.addErrorCmd(command);
+ command.getResult().setErrorCode(RESULT.ERROR_CHECK_FAILED_CODE);
+ command.getResult().setErrorDesc(RESULT.ERROR_CHECK_FAILED_DESC);
+ command.getResult().setResult(RESULT.RESULT_TYPE_FAILED);
+ command.getResult().setExpResult(exp_res);
+ command.getResult().setActResult(act_res);
+ command.getResult().setRemark(command.getCommand()+"\n"+
+ "[EXPECT RESULT]:\n"+exp_res+"\n"+
+ "[ACTUAL RESULT]:\n"+act_res+"\n");
+ LOG.error("["+script.getFileName()+"]["+command.getCommand().trim()+"] is executed failed");
+ LOG.error("[EXPECT RESULT]:\n"+exp_res);
+ LOG.error("[ACTUAL RESULT]:\n"+act_res);
+ }else {
+ //compare successfully
+ LOG.info("["+script.getFileName()+"]["+command.getCommand().trim()+"] is executed successfully");
+ }
+ }
+ statement.close();
+ }catch (SQLException e) {
+ if(null == command){
+ break;
+ }
+
+ act_res = e.getMessage();
+ if( j < commands.size() -1)
+ exp_res = ResultParser.getRS(command.getCommand(),commands.get(j + 1).getCommand());
+ else
+ exp_res = ResultParser.getRS(command.getCommand(),null);
+
+ //if compare failed
+ if(!act_res.equalsIgnoreCase(exp_res)){
+ script.addErrorCmd(command);
+ command.getResult().setErrorCode(RESULT.ERROR_CHECK_FAILED_CODE);
+ command.getResult().setErrorDesc(RESULT.ERROR_CHECK_FAILED_DESC);
+ command.getResult().setResult(RESULT.RESULT_TYPE_FAILED);
+ command.getResult().setExpResult(exp_res);
+ command.getResult().setActResult(act_res);
+ command.getResult().setRemark(command.getCommand()+"\n"+
+ "[EXPECT RESULT]:\n"+exp_res+"\n"+
+ "[ACTUAL RESULT]:\n"+act_res+"\n");
+ LOG.error("["+script.getFileName()+"]["+command.getCommand().trim()+"] is executed failed");
+ LOG.error("[EXPECT RESULT]:\n"+exp_res);
+ LOG.error("[ACTUAL RESULT]:\n"+act_res);
+ }else {
+ //compare successfully
+ LOG.info("["+script.getFileName()+"]["+command.getCommand().trim()+"] is executed successfully");
+ }
+ }
+ }
+
+ long end = System.currentTimeMillis();
+ script.setDuration((float)(end - start)/1000);
+ }
+
+ public static void run(ArrayList suites,String path) {
+ ConnectionManager.reset();
+ Connection connection = ConnectionManager.getConnection();
+
+ boolean hasResults = false;
+ Statement statement = null;
+
+ //check whether the result file exists
+ File rsf = new File(path.replaceFirst(COMMON.CASES_PATH,COMMON.RESULT_PATH).replaceAll(".sql",".result"));
+ if(!rsf.exists()) {
+ LOG.warn("The result of the test script file["+path+"] does not exists,please check....");
+
+ //set all the suites and cases to RESULT_TYPE_NOEXEC
+ TestResult result = new TestResult();
+ result.setResult(RESULT.RESULT_TYPE_NOEXEC);
+ result.setErrorCode(RESULT.ERROR_NOT_EXEC_CODE);
+ result.setErrorDesc(RESULT.ERROR_NOT_EXEC_DESC);
+ for(int i = 0; i < suites.size();i++){
+ suites.get(i).setResult(result);
+ }
+ return;
+ }
+
+ ResultParser.reset();
+ ResultParser.parse(rsf.getPath());
+
+ String exp_res = null;
+ String act_res = null;
+
+ for(int i = 0; i < suites.size();i++){
+ TestSuite suite = suites.get(i);
+ ArrayList setups = suite.getSetupSqls();
+ LOG.info("["+path+"][suite]["+i+"] is now being executed.......................................................");
+ for(int j = 0; j < setups.size();j++){
+ SqlCommand command = null;
+
+ try {
+ command = setups.get(j);
+ connection = getConnection(command);
+ statement = connection.createStatement();
+ if (command.isUpdate()) {
+ //if no-query-type statement is executed successfully,do not need check
+ int num = statement.executeUpdate(command.getCommand());
+ //but need to get the expected result,to skip the read pos
+ ResultParser.skip(command.getCommand());
+ LOG.info("["+path+"][suite]["+i+"][setup]"+command.getCommand().trim()+"] is executed successfully");
+ }
+ statement.close();
+ }catch (SQLException e) {
+ LOG.error("["+path+"][suite]["+i+"][setup]"+command.getCommand().trim()+"] is executed failed,maybe will cause the following cases error");
+ ResultParser.skip(command.getCommand());
+ }
+ }
+
+ ArrayList cases = suite.getCases();
+ for(int j = 0; j < cases.size(); j++){
+ TestCase testCase = cases.get(j);
+ LOG.info("["+path+"][suite]["+i+"][case:"+testCase.getDesc()+"] is now being executed.......................................................");
+ ArrayList sqlCommands = testCase.getCommands();
+ for(int k = 0; k < sqlCommands.size();k++){
+ SqlCommand command = sqlCommands.get(k);
+ connection = getConnection(command);
+ try {
+ statement = connection.createStatement();
+ if (command.isUpdate()) {
+ //if no-query-type statement is executed successfully,do not need check
+ int num = statement.executeUpdate(command.getCommand());
+ //but need to get the expected result,to skip the read pos
+ ResultParser.skip(command.getCommand());
+ LOG.info("["+path+"]["+command.getCommand().trim()+"] is executed successfully");
+ } else {
+ //if query-type statment is executed successfully,need compare the expected result and the actual result
+ hasResults = statement.execute(command.getCommand());
+ act_res = getRS(statement.getResultSet());
+ /*if( k < sqlCommands.size() -1)
+ exp_res = ResultParser.getRS(command.getCommand(),sqlCommands.get(k + 1).getCommand());
+ else
+ exp_res = ResultParser.getRS(command.getCommand(),null);*/
+ exp_res = ResultParser.getRS(command.getCommand(),command.getNext().getCommand());
+
+ //if compare failed
+ if(!act_res.equalsIgnoreCase(exp_res)){
+ command.getResult().setErrorCode(RESULT.ERROR_CHECK_FAILED_CODE);
+ command.getResult().setErrorDesc(RESULT.ERROR_CHECK_FAILED_DESC);
+ command.getResult().setResult(RESULT.RESULT_TYPE_FAILED);
+ command.getResult().setExpResult(exp_res);
+ command.getResult().setActResult(act_res);
+ command.getResult().setRemark(command.getCommand()+"\n"+
+ "[EXPECT RESULT]:\n"+exp_res+"\n"+
+ "[ACTUAL RESULT]:\n"+act_res+"\n");
+
+ testCase.setResult(command.getResult());
+ testCase.addRemark(command.getResult().getRemark());
+
+ LOG.error("["+path+"]["+command.getCommand().trim()+"] is executed failed");
+ LOG.error("[EXPECT RESULT]:\n"+exp_res);
+ LOG.error("[ACTUAL RESULT]:\n"+act_res);
+ }else {
+ //compare successfully
+ LOG.info("["+path+"]["+command.getCommand().trim()+"] is executed successfully");
+ }
+ }
+ statement.close();
+ }catch (SQLException e) {
+ if(null == command){
+ break;
+ }
+
+ act_res = e.getMessage();
+ /*if( k < sqlCommands.size() -1)
+ exp_res = ResultParser.getRS(command.getCommand(),sqlCommands.get(k + 1).getCommand());
+ else
+ exp_res = ResultParser.getRS(command.getCommand(),null);*/
+ exp_res = ResultParser.getRS(command.getCommand(),command.getNext().getCommand());
+
+ //if compare failed
+ if(!act_res.equalsIgnoreCase(exp_res)){
+ command.getResult().setErrorCode(RESULT.ERROR_CHECK_FAILED_CODE);
+ command.getResult().setErrorDesc(RESULT.ERROR_CHECK_FAILED_DESC);
+ command.getResult().setResult(RESULT.RESULT_TYPE_FAILED);
+ command.getResult().setExpResult(exp_res);
+ command.getResult().setActResult(act_res);
+ command.getResult().setRemark(command.getCommand()+"\n"+
+ "[EXPECT RESULT]:\n"+exp_res+"\n"+
+ "[ACTUAL RESULT]:\n"+act_res+"\n");
+ testCase.setResult(command.getResult());
+ LOG.error("["+path+"]["+command.getCommand().trim()+"] is executed failed");
+ LOG.error("[EXPECT RESULT]:\n"+exp_res);
+ LOG.error("[ACTUAL RESULT]:\n"+act_res);
+ }else {
+ //compare successfully
+ LOG.info("["+path+"]["+command.getCommand().trim()+"] is executed successfully");
+ }
+ }
+ }
+ }
+ }
+
+ /* LOG.info("Now start to run the file["+script.getFileName()+"]....................................................");
+
+
+ //check whether the result file exists
+ File rsf = new File(script.getFileName().replaceFirst(COMMON.CASES_PATH,COMMON.RESULT_PATH).replaceAll(".sql",".result"));
+ if(!rsf.exists()) {
+ LOG.warn("The result of the test script file["+script.getFileName()+"] does not exists,please check....");
+
+ //set the execution status of test script to false
+ script.setExecStatus(false);
+ return;
+ }
+
+ ResultParser.reset();
+ ResultParser.parse(rsf.getPath());
+ ArrayList commands = script.getCommands();
+
+ long start = System.currentTimeMillis();
+
+ for (int j = 0; j < commands.size(); j++) {
+
+ SqlCommand command = null;
+ String exp_res = null;
+ String act_res = null;
+
+ try{
+ command = commands.get(j);
+ connection = getConnection(command);
+ statement = connection.createStatement();
+ if (command.isUpdate()) {
+ //if no-query-type statement is executed successfully,do not need check
+ int num = statement.executeUpdate(command.getCommand());
+ //but need to get the expected result,to skip the read pos
+ ResultParser.skip(command.getCommand());
+ LOG.info("["+script.getFileName()+"]["+command.getCommand().trim()+"] is executed successfully");
+ } else {
+ //if query-type statment is executed successfully,need compare the expected result and the actual result
+ hasResults = statement.execute(command.getCommand());
+ act_res = getRS(statement.getResultSet());
+ if( j < commands.size() -1)
+ exp_res = ResultParser.getRS(command.getCommand(),commands.get(j + 1).getCommand());
+ else
+ exp_res = ResultParser.getRS(command.getCommand(),null);
+
+ //if compare failed
+ if(!act_res.equalsIgnoreCase(exp_res)){
+ script.addErrorCmd(command);
+ command.getResult().setErrorCode(RESULT.ERROR_CHECK_FAILED_CODE);
+ command.getResult().setErrorDesc(RESULT.ERROR_CHECK_FAILED_DESC);
+ command.getResult().setResult(RESULT.RESULT_TYPE_FAILED);
+ command.getResult().setExpResult(exp_res);
+ command.getResult().setActResult(act_res);
+ command.getResult().setRemark(command.getCommand()+"\n"+
+ "[EXPECT RESULT]:\n"+exp_res+"\n"+
+ "[ACTUAL RESULT]:\n"+act_res+"\n");
+ LOG.error("["+script.getFileName()+"]["+command.getCommand().trim()+"] is executed failed");
+ LOG.error("[EXPECT RESULT]:\n"+exp_res);
+ LOG.error("[ACTUAL RESULT]:\n"+act_res);
+ }else {
+ //compare successfully
+ LOG.info("["+script.getFileName()+"]["+command.getCommand().trim()+"] is executed successfully");
+ }
+ }
+ statement.close();
+ }catch (SQLException e) {
+ if(null == command){
+ break;
+ }
+
+ act_res = e.getMessage();
+ if( j < commands.size() -1)
+ exp_res = ResultParser.getRS(command.getCommand(),commands.get(j + 1).getCommand());
+ else
+ exp_res = ResultParser.getRS(command.getCommand(),null);
+
+ //if compare failed
+ if(!act_res.equalsIgnoreCase(exp_res)){
+ script.addErrorCmd(command);
+ command.getResult().setErrorCode(RESULT.ERROR_CHECK_FAILED_CODE);
+ command.getResult().setErrorDesc(RESULT.ERROR_CHECK_FAILED_DESC);
+ command.getResult().setResult(RESULT.RESULT_TYPE_FAILED);
+ command.getResult().setExpResult(exp_res);
+ command.getResult().setActResult(act_res);
+ command.getResult().setRemark(command.getCommand()+"\n"+
+ "[EXPECT RESULT]:\n"+exp_res+"\n"+
+ "[ACTUAL RESULT]:\n"+act_res+"\n");
+ LOG.error("["+script.getFileName()+"]["+command.getCommand().trim()+"] is executed failed");
+ LOG.error("[EXPECT RESULT]:\n"+exp_res);
+ LOG.error("[ACTUAL RESULT]:\n"+act_res);
+ }else {
+ //compare successfully
+ LOG.info("["+script.getFileName()+"]["+command.getCommand().trim()+"] is executed successfully");
+ }
+ }
+ }
+
+ long end = System.currentTimeMillis();
+ script.setDuration((float)(end - start)/1000);*/
+ }
+
+ public static void genRS(TestScript script){
+ ConnectionManager.reset();
+ Connection connection = ConnectionManager.getConnection();
+
+ boolean hasResults = false;
+ Statement statement = null;
+ BufferedWriter rs_writer;
+ //check whether the result dir exists
+ File rsf = new File(script.getFileName().replaceFirst(COMMON.CASES_PATH,COMMON.RESULT_PATH).replaceAll(".sql",".result"));
+ if(!rsf.getParentFile().exists()){
+ rsf.getParentFile().mkdirs();
+ }
+
+ try {
+ rs_writer = new BufferedWriter(new FileWriter(rsf.getPath()));
+ ArrayList commands = script.getCommands();
+ for (int j = 0; j < commands.size(); j++) {
+ SqlCommand command = null;
+ try{
+ command = commands.get(j);
+ connection = getConnection(command);
+ statement = connection.createStatement();
+ if (command.isUpdate()) {
+ int num = statement.executeUpdate(command.getCommand());
+ rs_writer.write(command.getCommand().trim());
+ rs_writer.newLine();
+ } else {
+ hasResults = statement.execute(command.getCommand());
+ rs_writer.write(command.getCommand().trim());
+ rs_writer.newLine();
+ rs_writer.write(getRS(statement.getResultSet()));
+ rs_writer.newLine();
+ //writeRS(rs_writer,statement.getResultSet());
+ }
+ statement.close();
+ }catch (SQLException e) {
+ if(null == command){
+ break;
+ }
+ rs_writer.write(command.getCommand().trim());
+ rs_writer.newLine();
+ rs_writer.write(e.getMessage());
+ rs_writer.newLine();
+ }
+ }
+ rs_writer.flush();
+ rs_writer.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+ public static void writeRS(BufferedWriter writer, ResultSet rs){
+ ResultSetMetaData md = null;
+ StringBuffer labels = new StringBuffer();
+ StringBuffer[] values;
+ try {
+ md = rs.getMetaData();
+ int cols = md.getColumnCount();
+ values = new StringBuffer[COMMON.MAX_ROW_COUNT_IN_RS];
+ for(int i = 0; i < cols; ++i) {
+ labels.append(md.getColumnLabel(i + 1));
+ if(i < cols -1)
+ labels.append("\t");
+ }
+
+ writer.write(labels.toString());
+ writer.newLine();
+
+ int i = 0;
+ while(rs.next()) {
+ values[i] = new StringBuffer();
+ for(int j = 0; j < cols; ++j) {
+ values[i].append(rs.getString(j+1));
+ if(j < cols -1 )
+ values[i].append("\t");
+ }
+ writer.write(values[i].toString());
+ writer.newLine();
+ i++;
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ } catch (IOException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+ public static String getRS(ResultSet rs){
+ ResultSetMetaData md = null;
+ StringBuffer result = new StringBuffer();
+ try {
+ md = rs.getMetaData();
+ int cols = md.getColumnCount();
+ for(int i = 0; i < cols; ++i) {
+ result.append(md.getColumnLabel(i + 1));
+ if(i < cols -1)
+ result.append("\t");
+ }
+ result.append("\n");
+
+ int i = 0;
+ while(rs.next()) {
+ for(int j = 0; j < cols; ++j) {
+ result.append(rs.getString(j+1));
+ if(j < cols -1 )
+ result.append("\t");
+ }
+ result.append("\n");
+ i++;
+ }
+ //delete the last "\n"
+ return result.toString().trim();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ return null;
+ }
+
+
+ public static Connection getConnection(SqlCommand command){
+ Connection connection = null;
+ if(command.getConn_id() != 0){
+ if(command.getConn_user() == null){
+ connection = ConnectionManager.getConnection(command.getConn_id());
+ try {
+ if (isTrxBeginning(command)) {
+ connection.setAutoCommit(false);
+ }
+
+ if(isTrxEndding(command)){
+ connection.setAutoCommit(true);
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+
+ return connection;
+ }else {
+ connection = ConnectionManager.getConnection(command.getConn_id(),command.getConn_user(),command.getConn_pswd());
+ return connection;
+ }
+ }
+ connection = ConnectionManager.getConnection();
+ return connection;
+ }
+
+ public static boolean isTrxBeginning(SqlCommand command){
+ if(command.getCommand().toLowerCase().startsWith(COMMON.START_TRX))
+ return true;
+
+ return false;
+ }
+
+ public static boolean isTrxEndding(SqlCommand command){
+ if(command.getCommand().toLowerCase().startsWith(COMMON.COMMIT_TRX) || command.getCommand().toLowerCase().startsWith(COMMON.ROLLBACK_TRX))
+ return true;
+
+ return false;
+ }
+}
diff --git a/src/main/java/io/mo/result/TestReport.java b/src/main/java/io/mo/result/TestReport.java
new file mode 100755
index 000000000..1f7d80dcb
--- /dev/null
+++ b/src/main/java/io/mo/result/TestReport.java
@@ -0,0 +1,392 @@
+package io.mo.result;
+
+import io.mo.cases.SqlCommand;
+import io.mo.cases.TestCase;
+import io.mo.cases.TestScript;
+import io.mo.cases.TestSuite;
+import io.mo.constant.COMMON;
+import io.mo.constant.RESULT;
+import io.mo.util.RunConfUtil;
+import org.apache.log4j.Logger;
+import org.dom4j.Document;
+import org.dom4j.DocumentHelper;
+import org.dom4j.Element;
+import org.dom4j.io.OutputFormat;
+import org.dom4j.io.XMLWriter;
+
+import java.io.*;
+import java.util.*;
+
+
+public class TestReport {
+
+ //private ArrayList suites = new ArrayList();
+ Map> script_cases = new HashMap>();
+ private ArrayList _cases = new ArrayList();
+ private ArrayList scripts = new ArrayList();
+
+ private int total_cmd = 0;
+ private int error_cmd = 0;
+ private int noexec_cmd = 0;
+
+ private int total_case = 0;
+ private int error_case = 0;
+ private int noexec_case = 0;
+
+ private static Logger LOG = Logger.getLogger(TestReport.class.getName());
+
+ private String type = null;
+
+ private int rate = 0;
+
+ public TestReport(){
+ File dir = new File(COMMON.REPORT_PATH);
+ if(!dir.exists())
+ dir.mkdir();
+
+ }
+
+ public void write(){
+
+ //write typed-txt report
+ writeTXTReport();
+
+ //write typed-xml report
+ writeXMLReport();
+ }
+
+ public void writeXMLReport(){
+ int total = 0;
+ int errors = 0;
+ int failures = 0;
+ int tests = 0;
+ float time = 0;
+ /*if(total == 0){
+ LOG.info("There are no test results.................. ");
+ return;
+ }*/
+
+ type = type = RunConfUtil.getType();
+ if(type.equalsIgnoreCase("script")){
+ total = scripts.size();
+ Document doc = DocumentHelper.createDocument();
+ Element testscripts = doc.addElement("testsuite");
+ testscripts.addAttribute("name","test");
+
+ OutputFormat xmlFormat = new OutputFormat();
+ xmlFormat.setEncoding("UTF-8");
+ xmlFormat.setNewlines(true);
+ xmlFormat.setIndent(true);
+ xmlFormat.setIndent(" ");
+ for(int i = 0;i < total;i++){
+ TestScript script = scripts.get(i);
+ Element testscript = testscripts.addElement("testcase");
+ testscript.addAttribute("classname",script.getId());
+ testscript.addAttribute("name",script.getFileName());
+ testscript.addAttribute("time",String.valueOf(script.getDuration()));
+
+ time = time + script.getDuration();
+
+ if(script.getExecStatus() == false){
+ Element failure = testscript.addElement("failure");
+ failure.addAttribute("type",RESULT.ERROR_NOT_EXEC_CODE);
+ failure.addAttribute("message",RESULT.ERROR_NOT_EXEC_DESC);
+ continue;
+ }
+
+
+ StringBuffer error = new StringBuffer();
+ for(int j = 0; j < script.getSize();j++){
+ SqlCommand command = script.getCommands().get(j);
+ if(!command.getResult().getResult().equalsIgnoreCase(RESULT.RESULT_TYPE_PASS)){
+ error.append(command.getResult().getRemark()+"\n");
+ }
+ }
+ if(error.length() > 0){
+ Element failure = testscript.addElement("failure");
+ failure.addAttribute("type",RESULT.ERROR_CHECK_FAILED_CODE);
+ failure.addAttribute("message",RESULT.ERROR_CHECK_FAILED_DESC);
+ failure.addCDATA(error.toString());
+ errors++;
+ }
+ tests++;
+ }
+
+ testscripts.addAttribute("errors",String.valueOf(errors));
+ testscripts.addAttribute("failures",String.valueOf(failures));
+ testscripts.addAttribute("tests",String.valueOf(tests));
+ testscripts.addAttribute("time",String.valueOf(time));
+
+ try {
+ PrintWriter pw = new PrintWriter(COMMON.REPORT_PATH+"/report.xml");
+ XMLWriter xw = new XMLWriter(pw,xmlFormat);
+ xw.write(doc);
+ xw.flush();
+ xw.close();
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ System.out.println("Over");
+ }
+ }
+
+ if(type.equalsIgnoreCase("suite")){
+ total = _cases.size();
+ Document doc = DocumentHelper.createDocument();
+ Element testsuite = doc.addElement("testsuite");
+ testsuite.addAttribute("name","test");
+
+ OutputFormat xmlFormat = new OutputFormat();
+ xmlFormat.setEncoding("UTF-8");
+ xmlFormat.setNewlines(true);
+ xmlFormat.setIndent(true);
+ xmlFormat.setIndent(" ");
+ for(int i = 0;i < total;i++){
+ TestCase _case = _cases.get(i);
+ Element testcase = testsuite.addElement("testcase");
+ // testcase.addAttribute("classname",_case.getSuite().getId());
+ testcase.addAttribute("name",_case.getDesc());
+ testcase.addAttribute("time",String.valueOf(_case.getDuration()));
+ time = time + _case.getDuration();
+
+ if(!_case.getResult().getResult().equalsIgnoreCase(RESULT.RESULT_TYPE_PASS)){
+ Element failure = testcase.addElement("failure");
+ failure.addAttribute("type",_case.getResult().getErrorCode());
+ failure.addAttribute("message",_case.getResult().getErrorDesc());
+ if(null != _case.getResult().getRemark()) {
+ //failure.addText(_case.getResult().getErrorDesc());
+ failure.addCDATA(_case.getResult().getRemark());
+ }
+ /*if(null != _case.getResult().getExpResult()) {
+ failure.addText("[EXPECT]:");
+ failure.addText(_case.getResult().getExpResult());
+ }
+ if(null != _case.getResult().getActResult()) {
+ failure.addText("[ACTUAL]:");
+ failure.addText(_case.getResult().getActResult());
+ }*/
+ failure.addText("\n");
+ // failure.addText("[CASE SCRIPT]:\n"+_case.getOrignal_script());
+ errors += 1;
+ continue;
+ }
+ tests += 1;
+ }
+
+ testsuite.addAttribute("errors",String.valueOf(errors));
+ testsuite.addAttribute("failures",String.valueOf(failures));
+ testsuite.addAttribute("tests",String.valueOf(tests));
+ testsuite.addAttribute("time",String.valueOf(time));
+
+ try {
+ PrintWriter pw = new PrintWriter(COMMON.REPORT_PATH+"/report.xml");
+ XMLWriter xw = new XMLWriter(pw,xmlFormat);
+ xw.write(doc);
+ xw.flush();
+ xw.close();
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ System.out.println("Over");
+ }
+ }
+
+ }
+
+ public void writeTXTReport(){
+ type = type = RunConfUtil.getType();
+ if(type.equalsIgnoreCase("script")){
+ rate = (total_cmd - error_cmd - noexec_cmd)*100/total_cmd;
+ try {
+ BufferedWriter r_writer = new BufferedWriter(new FileWriter(COMMON.REPORT_PATH+"/report.txt"));
+ BufferedWriter e_writer = new BufferedWriter(new FileWriter(COMMON.REPORT_PATH+"/error.txt"));
+ r_writer.write(getReportSummaryTXT(total_cmd,error_cmd,noexec_cmd));
+ LOG.info(getReportSummaryTXT(total_cmd,error_cmd,noexec_cmd).trim());
+ for(int i = 0; i < scripts.size();i++){
+ TestScript script = scripts.get(i);
+ if(script.getExecStatus() == true){
+ r_writer.write(getScriptSummaryTXT(script));
+ LOG.info(getScriptSummaryTXT(script).trim());
+ }else {
+ r_writer.write("["+script.getId()+"] did not been executed because result file dose not exists.\n");
+ LOG.info(getScriptSummaryTXT(script).trim());
+ }
+ List errors = script.getErrorList();
+ for(int j = 0 ; j < errors.size();j++){
+ e_writer.write(getErrorInfo(errors.get(j)));
+ e_writer.newLine();
+ }
+ }
+ r_writer.flush();
+ e_writer.flush();
+ r_writer.close();
+ e_writer.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ if(type.equalsIgnoreCase("suite")){
+ rate = (total_case - error_case - noexec_case)*100/total_case;
+ try {
+ BufferedWriter r_writer = new BufferedWriter(new FileWriter(COMMON.REPORT_PATH+"/report.txt"));
+ BufferedWriter e_writer = new BufferedWriter(new FileWriter(COMMON.REPORT_PATH+"/error.txt"));
+ r_writer.write(getReportSummaryTXT(total_case,error_case,noexec_case));
+ LOG.info(getReportSummaryTXT(total_case,error_case,noexec_case).trim());
+
+ for(Object key : script_cases.keySet()){
+ r_writer.write(getScriptSummaryTXT(key.toString()));
+ LOG.info(getScriptSummaryTXT(key.toString()).trim());
+ }
+
+ for(int i = 0; i < _cases.size(); i++){
+ if(_cases.get(i).getResult().getResult().equalsIgnoreCase(RESULT.RESULT_TYPE_FAILED)){
+ e_writer.write(getErrorInfo(_cases.get(i)));
+ e_writer.newLine();
+ }
+ }
+
+ r_writer.flush();
+ e_writer.flush();
+ r_writer.close();
+ e_writer.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+
+ }
+
+ public void collect(TestCase _case){
+ _cases.add(_case);
+ total_case++;
+ if(!_case.getResult().getResult().equalsIgnoreCase(RESULT.RESULT_TYPE_PASS)){
+ if(_case.getResult().getResult().equalsIgnoreCase(RESULT.RESULT_TYPE_NOEXEC))
+ noexec_case++;
+
+ if(_case.getResult().getResult().equalsIgnoreCase(RESULT.RESULT_TYPE_FAILED))
+ error_case++;
+ }
+
+ if(script_cases.containsKey(_case.getFileName())){
+ script_cases.get(_case.getFileName()).add(_case);
+ }else {
+ ArrayList cases = new ArrayList();
+ cases.add(_case);
+ script_cases.put(_case.getFileName(),cases);
+ }
+ }
+
+ public void collect(TestSuite suite){
+ //suites.add(suite);
+ for(int i = 0; i < suite.getCases().size(); i++){
+ collect(suite.getCases().get(i));
+ }
+ }
+
+ public void collect(ArrayList suites){
+ for(int i = 0; i < suites.size(); i++){
+ collect(suites.get(i));
+ }
+ }
+
+ public void collect(TestScript script){
+ scripts.add(script);
+ total_cmd += script.getSize();
+ error_cmd += script.getErrorCount();
+ if(!script.getExecStatus())
+ noexec_cmd += script.getSize();
+ }
+
+ public String getReportSummaryTXT(int total,int error,int noexec){
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("[SUMMARY] TOTAL : "+total);
+ buffer.append(", ");
+ buffer.append("SUCCESS : "+(total - error - noexec));
+ buffer.append(", ");
+ buffer.append("ERROR :"+error);
+ buffer.append(", ");
+ buffer.append("NOEXE :"+noexec);
+ buffer.append(", ");
+ buffer.append("SUCCESS RATE : "+(((total - error - noexec)*100/total))+"%\n");
+ return buffer.toString();
+ }
+
+ public String getScriptSummaryTXT(TestScript script){
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("["+script.getFileName()+"] TOTAL : " + script.getSize());
+ buffer.append(", ");
+ buffer.append("SUCCESS : "+(script.getSize() - script.getErrorCount()));
+ buffer.append(", ");
+ buffer.append("ERROR :"+script.getErrorCount());
+ buffer.append(", ");
+ buffer.append("SUCCESS RATE : "+((script.getSize() - script.getErrorCount())*100/script.getSize())+"%\n");
+ return buffer.toString();
+ }
+
+ public String getScriptSummaryTXT(String fileName){
+ ArrayList cases = script_cases.get(fileName);
+ int suit_total_case = cases.size();
+ int suit_error_case = 0;
+ int suit_noexec_case = 0;
+ for(int i = 0; i < cases.size();i++){
+ TestCase testCase = cases.get(i);
+ if(!testCase.getResult().getResult().equalsIgnoreCase(RESULT.RESULT_TYPE_PASS)){
+ if(testCase.getResult().getResult().equalsIgnoreCase(RESULT.RESULT_TYPE_NOEXEC))
+ suit_noexec_case++;
+
+ if(testCase.getResult().getResult().equalsIgnoreCase(RESULT.RESULT_TYPE_FAILED))
+ suit_error_case++;
+ }
+ }
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("["+fileName+"] TOTAL : " + suit_total_case);
+ buffer.append(", ");
+ buffer.append("SUCCESS : "+(suit_total_case - suit_error_case - suit_noexec_case));
+ buffer.append(", ");
+ buffer.append("ERROR :"+suit_error_case);
+ buffer.append(", ");
+ buffer.append("NOEXE :"+suit_noexec_case);
+ buffer.append(", ");
+ buffer.append("SUCCESS RATE : "+((suit_total_case - suit_error_case - suit_noexec_case)*100/suit_total_case)+"%\n");
+ return buffer.toString();
+ }
+
+ public String getErrorInfo(SqlCommand command){
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("[ERROR]\n");
+ buffer.append("[SCRIPT FILE]: "+command.getScriptFile()+"\n");
+ buffer.append("[SQL STATEMENT]: "+command.getCommand()+"\n");
+ buffer.append("[EXPECT RESULT]:\n"+command.getResult().getExpResult()+"\n");
+ buffer.append("[ACTUAL RESULT]:\n"+command.getResult().getActResult()+"\n");
+ return buffer.toString();
+ }
+
+ public String getErrorInfo(TestCase _case){
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("[ERROR]\n");
+ buffer.append("[TESTCASE FILE]: "+_case.getFileName()+"\n");
+ buffer.append("[TESTCASE DESC]: "+_case.getDesc()+"\n");
+ buffer.append("[TESTCASE SQL]:\n"+_case.getSqlCommands()+"\n");
+ buffer.append("[ERROR INFO]:\n"+_case.getRemark()+"\n");
+ return buffer.toString();
+ }
+
+ public int getRate() {
+ return rate;
+ }
+
+ public void setRate(int rate) {
+ this.rate = rate;
+ }
+
+ public static void main(String args[]){
+ }
+
+
+}
diff --git a/src/main/java/io/mo/result/TestResult.java b/src/main/java/io/mo/result/TestResult.java
new file mode 100755
index 000000000..87e8eedc4
--- /dev/null
+++ b/src/main/java/io/mo/result/TestResult.java
@@ -0,0 +1,68 @@
+package io.mo.result;
+
+import io.mo.constant.RESULT;
+
+public class TestResult {
+
+ private String result;
+ private String errorCode;
+ private String errorDesc;
+ private String actResult;
+ private String expResult;
+ private String remark;
+
+ public TestResult(){
+ result = RESULT.RESULT_TYPE_PASS;
+ errorCode = RESULT.SUCCESS_CODE;
+ }
+
+ public String getActResult() {
+ return actResult;
+ }
+
+ public void setActResult(String actResult) {
+ this.actResult = actResult;
+ }
+
+ public String getExpResult() {
+ return expResult;
+ }
+
+ public void setExpResult(String expResult) {
+ this.expResult = expResult;
+ }
+
+ public String getRemark() {
+ return remark;
+ }
+
+ public void setRemark(String remark) {
+ this.remark = remark;
+ }
+
+ public String getErrorCode() {
+ return errorCode;
+ }
+
+ public void setErrorCode(String errorCode) {
+ this.errorCode = errorCode;
+ }
+
+ public String getErrorDesc() {
+ return errorDesc;
+ }
+
+ public void setErrorDesc(String errorDesc) {
+ this.errorDesc = errorDesc;
+ }
+
+ public String getResult() {
+ return result;
+ }
+
+ public void setResult(String result) {
+ this.result = result;
+ }
+
+
+}
diff --git a/src/main/java/io/mo/util/MoConfUtil.java b/src/main/java/io/mo/util/MoConfUtil.java
new file mode 100755
index 000000000..039cb6e02
--- /dev/null
+++ b/src/main/java/io/mo/util/MoConfUtil.java
@@ -0,0 +1,94 @@
+package io.mo.util;
+
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+public class MoConfUtil {
+ private static YamlUtil mo_conf = new YamlUtil();
+ private static Map conf = null;
+
+ public static void init(){
+ try {
+ conf = mo_conf.getInfo("mo.yml");
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+
+
+ public static String getURL(){
+
+ if(conf == null) init();
+
+ String URL = "jdbc:mysql://";
+ Map jdbc = (Map)conf.get("jdbc");
+ List gates = (ArrayList)jdbc.get("server");
+
+ for(int i = 0; i < gates.size();i++){
+ Map gate = (Map)gates.get(i);
+ URL += gate.get("addr");
+ if(i < gates.size() - 1)
+ URL += ",";
+ else
+ URL += "/";
+ }
+
+ URL += getDefaultDatabase()+"?";
+
+ Map paras = (Map)jdbc.get("paremeter");
+ Iterator it_para_key = paras.keySet().iterator();
+ Iterator it_para_value = paras.entrySet().iterator();
+ while(it_para_value.hasNext()){
+ URL += it_para_value.next();
+ if(it_para_value.hasNext())
+ URL += "&";
+ }
+
+ return URL;
+
+ }
+
+ public static String getDriver(){
+ if(conf == null) init();
+
+ Map jdbc = (Map)conf.get("jdbc");
+ String driver = jdbc.get("driver").toString();
+ return driver;
+ }
+
+ public static String getUserName(){
+ if(conf == null) init();
+
+ Map user = (Map)conf.get("user");
+ String name = user.get("name").toString();
+ return name;
+ }
+
+ public static String getUserpwd(){
+ if(conf == null) init();
+
+ Map user = (Map)conf.get("user");
+ String pwd = user.get("passwrod").toString();
+ return pwd;
+ }
+
+ public static String getDefaultDatabase(){
+ if(conf == null) init();
+
+ Map jdbc = (Map)conf.get("jdbc");
+ Map database = (Map)jdbc.get("database");
+ String def = database.get("default").toString();
+ return def;
+ }
+
+
+
+ public static void main(String[] args){
+ System.out.println(getDriver());
+ System.out.println(getURL());
+
+ }
+}
diff --git a/src/main/java/io/mo/util/ResultParser.java b/src/main/java/io/mo/util/ResultParser.java
new file mode 100755
index 000000000..37de46b1f
--- /dev/null
+++ b/src/main/java/io/mo/util/ResultParser.java
@@ -0,0 +1,85 @@
+package io.mo.util;
+
+import io.mo.cases.SqlCommand;
+import io.mo.db.Executor;
+import org.apache.log4j.Logger;
+
+import java.io.*;
+
+public class ResultParser {
+ private static BufferedReader lineReader;
+ private static Logger LOG = Logger.getLogger(ResultParser.class.getName());
+ private static boolean skip = false;
+ public static void parse(String path){
+ try {
+ lineReader = new BufferedReader(new InputStreamReader(new FileInputStream(path)));
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ LOG.warn("The result of the test script file["+path+"] does not exists,please check....");
+ }
+ }
+
+ public static String getRS(String cmd,String nextcmd){
+ String line = null;
+ StringBuffer buffer = new StringBuffer();
+ try {
+ while((line = lineReader.readLine()) != null) {
+ line = new String(line.getBytes(), "utf-8");
+ if (line.equals("")) continue;
+ buffer.append(line);
+ buffer.append("\n");
+ if(buffer.indexOf(cmd) != -1){
+ buffer.delete(0,buffer.length());
+ }
+
+ if(nextcmd != null){
+ if(buffer.indexOf(nextcmd) != -1){
+ buffer.delete(buffer.length()-nextcmd.length(),buffer.length());
+ //skip = true,means has read the next command,if call the skip() func,will do nothing;
+ skip = true;
+ return buffer.toString().trim();
+ }
+ }
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ return null;
+ }
+ return buffer.toString().trim();
+ }
+
+ public static void skip(String cmd){
+
+ //skip = true,means has read the next command,if call the skip() func,will do nothing;
+ if (skip) return;
+
+ String line = null;
+ StringBuffer buffer = new StringBuffer();
+ try {
+ while((line = lineReader.readLine()) != null) {
+ line = new String(line.getBytes(), "utf-8");
+ if (line.equals("")) continue;
+ buffer.append(line);
+ buffer.append("\n");
+ if(buffer.indexOf(cmd) != -1){
+ buffer.delete(0,buffer.length());
+ break;
+ }
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static void reset(){
+ skip = false;
+ if(lineReader != null){
+ try {
+ lineReader.close();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ lineReader = null;
+ }
+ }
+}
diff --git a/src/main/java/io/mo/util/RunConfUtil.java b/src/main/java/io/mo/util/RunConfUtil.java
new file mode 100755
index 000000000..e0d2427be
--- /dev/null
+++ b/src/main/java/io/mo/util/RunConfUtil.java
@@ -0,0 +1,44 @@
+package io.mo.util;
+
+import java.io.FileNotFoundException;
+import java.util.Map;
+
+public class RunConfUtil {
+ private static YamlUtil run_conf = new YamlUtil();
+ private static Map conf = null;
+
+
+ public static void init(){
+ try {
+ conf = run_conf.getInfo("run.yml");
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+
+
+ public static String getPath(){
+ if(conf == null) init();
+ return (String)conf.get("path");
+ }
+
+ public static String getMethod(){
+ if(conf == null) init();
+ return (String)conf.get("method");
+ }
+
+ public static String getType(){
+ if(conf == null) init();
+ return (String)conf.get("type");
+ }
+
+ public static int getRate(){
+ if(conf == null) init();
+ return (int)conf.get("rate");
+ }
+
+ public static void main(String[] args){
+ System.out.println(getPath());
+ System.out.println(getMethod());
+ }
+}
diff --git a/src/main/java/io/mo/util/ScriptParser.java b/src/main/java/io/mo/util/ScriptParser.java
new file mode 100755
index 000000000..0c76d11e8
--- /dev/null
+++ b/src/main/java/io/mo/util/ScriptParser.java
@@ -0,0 +1,255 @@
+package io.mo.util;
+
+import io.mo.cases.SqlCommand;
+import io.mo.cases.TestCase;
+import io.mo.cases.TestScript;
+import io.mo.cases.TestSuite;
+import io.mo.constant.COMMON;
+import org.apache.poi.ss.formula.functions.T;
+
+import java.io.*;
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+
+public class ScriptParser {
+ private static final String LINE_SEPARATOR = "\n";
+ private static String delimiter = COMMON.DEFAUT_DELIMITER;
+ private static int case_id = 0;
+
+ private static BufferedReader lineReader;
+ private static ArrayList testSuites;
+
+ private static TestScript testScript = new TestScript();;
+
+ private String path;
+
+ public ScriptParser(String path){
+ }
+
+
+ public static void parseScript(String path){
+ testScript = new TestScript();
+ testScript.setFileName(path);
+
+ try {
+ lineReader = new BufferedReader(new InputStreamReader(new FileInputStream(path)));
+ SqlCommand command = new SqlCommand();
+ String line = lineReader.readLine();
+ String trimmedLine = null;
+
+ while (line != null) {
+ line = new String(line.getBytes(), "utf-8");
+
+ trimmedLine = line.trim();
+
+ //extract sql commands from the script file
+ //if line is comment or null,ignore
+ if (trimmedLine.equals("") || lineIsComment(trimmedLine)) {
+ line = lineReader.readLine();
+ continue;
+ }
+
+ if(trimmedLine.contains(delimiter) || trimmedLine.equals(delimiter)){
+ command.append(trimmedLine);
+ command.setConn_id(COMMON.CONNECTION_ID);
+ testScript.addCommand(command);
+ command = new SqlCommand();
+ }else {
+ command.append(trimmedLine);
+ }
+ line = lineReader.readLine();
+ }
+ }catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ public static void parseSuite(String path){
+ testScript = new TestScript();
+ testScript.setFileName(path);
+
+ testSuites = new ArrayList();
+
+ SqlCommand sqlCommand = new SqlCommand();
+ SqlCommand preCommand = sqlCommand;
+ try {
+ lineReader = new BufferedReader(new InputStreamReader(new FileInputStream(path)));
+ SqlCommand command = new SqlCommand();
+ String line = lineReader.readLine();
+ String trimmedLine = null;
+
+ while(line != null){
+ line = new String(line.getBytes(),"utf-8");
+ if(line.equals("")) {
+ line = lineReader.readLine();
+ continue;
+ }
+
+ trimmedLine = line.trim();
+
+ //if suite
+ if(trimmedLine.startsWith(COMMON.SUITE_FLAG)) {
+ //handleTestSuite();
+ TestSuite suite = new TestSuite();
+ suite.setFileName(testScript.getFileName());
+ testSuites.add(suite);
+ line = lineReader.readLine();
+
+ while(line != null){
+ line = new String(line.getBytes(),"utf-8");
+ if(line.equals("")) {
+ line = lineReader.readLine();
+ continue;
+ }
+ trimmedLine = line.trim();
+
+ if(lineIsComment(trimmedLine)){
+ if(trimmedLine.startsWith(COMMON.SETUP_SUITE_FLAG)){
+ line = lineReader.readLine();
+ while(line != null){
+ line = new String(line.getBytes(),"utf-8");
+ if(line.equals("")) {
+ line = lineReader.readLine();
+ continue;
+ }
+
+ trimmedLine = line.trim();
+ if(!lineIsComment(trimmedLine)){
+ sqlCommand.setScriptFile(testScript.getFileName());
+ sqlCommand.setConn_id(COMMON.CONNECTION_ID);
+ if(trimmedLine.contains(delimiter) || trimmedLine.equals(delimiter)){
+ sqlCommand.append(trimmedLine);
+ suite.addSetupCommand(sqlCommand);
+ testScript.addCommand(sqlCommand);
+ sqlCommand = new SqlCommand();
+ preCommand.setNext(sqlCommand);
+ preCommand = sqlCommand;
+ }else {
+ sqlCommand.append(trimmedLine);
+ }
+ }else {
+ if(trimmedLine.startsWith(COMMON.CASE_START_FLAG))
+ break;
+ }
+ line = lineReader.readLine();
+ }
+ }
+
+ if(trimmedLine.startsWith(COMMON.CASE_START_FLAG)){
+ TestCase testCase = new TestCase();
+ testCase.setFileName(testScript.getFileName());
+ testCase.setSuite(suite);
+ suite.addTestCase(testCase);
+ line = lineReader.readLine();
+ while(line != null){
+ line = new String(line.getBytes(),"utf-8");
+ if(line.equals("")) {
+ line = lineReader.readLine();
+ continue;
+ }
+ trimmedLine = line.trim();
+ if(!lineIsComment(trimmedLine)){
+ sqlCommand.setScriptFile(testScript.getFileName());
+ command.setConn_id(COMMON.CONNECTION_ID);
+ if(trimmedLine.contains(delimiter) || trimmedLine.equals(delimiter)){
+ sqlCommand.append(trimmedLine);
+ testCase.addCommand(sqlCommand);
+ testScript.addCommand(sqlCommand);
+ sqlCommand = new SqlCommand();
+ preCommand.setNext(sqlCommand);
+ preCommand = sqlCommand;
+ }else
+ sqlCommand.append(trimmedLine);
+
+ }else {
+ if(trimmedLine.startsWith(COMMON.CASE_DESC_FLAG)){
+ testCase.setDesc(trimmedLine.substring(COMMON.CASE_DESC_FLAG.length(),trimmedLine.length()));
+ }
+
+ if(trimmedLine.startsWith(COMMON.CASE_LABEL_FLAG)){
+ testCase.addLabel(trimmedLine.substring(COMMON.CASE_LABEL_FLAG.length(),trimmedLine.length()));
+ }
+
+ if(trimmedLine.startsWith(COMMON.CASE_START_FLAG) || trimmedLine.startsWith(COMMON.SUITE_FLAG))
+ break;
+ }
+ line = lineReader.readLine();
+ }
+ }
+
+ if(trimmedLine.startsWith(COMMON.SUITE_FLAG)){
+ break;
+ }
+ }
+ }
+ }
+ }
+ //return testSuite;
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ //return null;
+ }
+
+ private static boolean lineIsComment(String trimmedLine) {
+ return trimmedLine.startsWith("//") || trimmedLine.startsWith("--") || trimmedLine.startsWith("#");
+ }
+
+ public static TestScript getTestScript(){
+ return testScript;
+ }
+
+ public static ArrayList getTestSuites(){
+ return testSuites;
+ }
+
+ //recovery to the initial state
+ public static void clear() {
+
+ try {
+ delimiter = COMMON.DEFAUT_DELIMITER;
+ case_id = 0;
+ lineReader.close();
+ COMMON.CONNECTION_ID = 0;
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+
+
+ public static void main(String[] args){
+ //ScriptParser.initSuiteId("c:\\fdasf\\fdsafd\\sdfa.sql");
+ ScriptParser.parseSuite("cases/test/builtin.sql");
+ ArrayList suites = ScriptParser.getTestSuites();
+ for(int i = 0; i < suites.size();i++){
+ TestSuite suite = suites.get(i);
+ ArrayList setups = suite.getSetupSqls();
+ for(int j = 0; j < setups.size();j++){
+ System.out.println(setups.get(j).getCommand().trim());
+ }
+
+ ArrayList cases = suite.getCases();
+ for(int j = 0; j < cases.size(); j++){
+ TestCase testCase = cases.get(j);
+ ArrayList sqlCommands = testCase.getCommands();
+ for(int k = 0; k < sqlCommands.size();k++){
+ SqlCommand command = sqlCommands.get(k);
+ System.out.println(command.getCommand().trim());
+ }
+ }
+
+ ArrayList teardowns = suite.getTeardownSqls();
+ for(int j = 0; j < teardowns.size();j++){
+ System.out.println(teardowns.get(j).getCommand().trim());
+ }
+ }
+
+ }
+}
diff --git a/src/main/java/io/mo/util/YamlUtil.java b/src/main/java/io/mo/util/YamlUtil.java
new file mode 100755
index 000000000..150b154bd
--- /dev/null
+++ b/src/main/java/io/mo/util/YamlUtil.java
@@ -0,0 +1,29 @@
+package io.mo.util;
+
+import org.yaml.snakeyaml.Yaml;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.UnsupportedEncodingException;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.util.Map;
+
+public class YamlUtil {
+ private Map info;
+
+ public Map getInfo(String filename) throws FileNotFoundException {
+ Yaml yaml = new Yaml();
+ URL url = YamlUtil.class.getClassLoader().getResource(filename);
+ //System.out.println(url);
+ if (url != null) {
+ try {
+ this.info = (Map) yaml.load(new FileInputStream(URLDecoder.decode(url.getFile(),"utf-8")));
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+ //System.out.println(url.getFile());
+ }
+ return info;
+ }
+}
diff --git a/src/test/java/io/mo/AppTest.java b/src/test/java/io/mo/AppTest.java
new file mode 100755
index 000000000..61f4f51cc
--- /dev/null
+++ b/src/test/java/io/mo/AppTest.java
@@ -0,0 +1,38 @@
+package io.mo;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Unit test for simple App.
+ */
+public class AppTest
+ extends TestCase
+{
+ /**
+ * Create the test case
+ *
+ * @param testName name of the test case
+ */
+ public AppTest( String testName )
+ {
+ super( testName );
+ }
+
+ /**
+ * @return the suite of tests being tested
+ */
+ public static Test suite()
+ {
+ return new TestSuite( AppTest.class );
+ }
+
+ /**
+ * Rigourous Test :-)
+ */
+ public void testApp()
+ {
+ assertTrue( true );
+ }
+}