package util.sqlparse.visitor.kingbase.test;

import bean.Column;
import bean.DataBase;
import bean.Schema;
import bean.Table;
import bean.View;
import java.util.ArrayList;
import java.util.Map;
import test.StopWatch;
import util.sqlparse.visitor.common.Context;
import util.sqlparse.visitor.common.bean.SQLResult;
import util.sqlparse.visitor.common.memo.FieldMemo;
import util.sqlparse.visitor.common.memo.TableMemo;
import util.sqlparse.visitor.common.memo.ValueMemo;
import util.sqlparse.visitor.common.scope.Scope;
import util.sqlparse.visitor.kingbase.SQLParser;

public class SQLParseTest {
   public static void main(String[] args) {
      testSelect();
   }

   static DataBase createDB() {
      DataBase db = new DataBase();
      db.setDbType("kingbase");
      db.setIsIgnorecase("0");
      db.setSchemaList(new ArrayList());
      Schema schema = new Schema("test");
      schema.setViewList(new ArrayList());
      View view = new View("vtest", "create or replace view vtest  as with a as (select login_name as lname,dept_id as did from vtest1) select b.dept_id as did,b.dept_name as dept_name, a.lname as account from a left join sys_dept b on a.did=b.dept_id");
      View view1 = new View("vtest1", "create or replace view vtest1 as select a.user_id,a.user_name,a.login_name,a.dept_id from sys_user a");
      schema.getViewList().add(view);
      schema.getViewList().add(view1);
      db.getSchemaList().add(schema);
      Table table = new Table("sys_user", "test");
      table.setColumnList(new ArrayList());
      table.getColumnList().add(new Column("user_id", null, false, null));
      table.getColumnList().add(new Column("user_name", null, false, null));
      table.getColumnList().add(new Column("login_name", null, false, null));
      table.getColumnList().add(new Column("dept_id", null, false, null));
      table.getColumnList().add(new Column("user_type", null, false, null));
      table.getColumnList().add(new Column("email", null, false, null));
      table.getColumnList().add(new Column("sex", null, false, null));
      table.getColumnList().add(new Column("avatar", null, false, null));
      table.getColumnList().add(new Column("password", null, false, null));
      table.getColumnList().add(new Column("salt", null, false, null));
      table.getColumnList().add(new Column("status", null, false, null));
      table.getColumnList().add(new Column("del_flag", null, false, null));
      table.getColumnList().add(new Column("login_ip", null, false, null));
      table.getColumnList().add(new Column("login_date", null, false, null));
      table.getColumnList().add(new Column("pwd_update_date", null, false, null));
      table.getColumnList().add(new Column("create_by", null, false, null));
      table.getColumnList().add(new Column("create_time", null, false, null));
      table.getColumnList().add(new Column("update_by", null, false, null));
      table.getColumnList().add(new Column("update_time", null, false, null));
      table.getColumnList().add(new Column("phonenumber", null, false, null));
      table.getColumnList().add(new Column("remark", null, false, null));
      schema.getTableList().add(table);
      table = new Table("sys_dept", "test");
      table.setColumnList(new ArrayList());
      table.getColumnList().add(new Column("dept_id", null, false, null));
      table.getColumnList().add(new Column("parent_id", null, false, null));
      table.getColumnList().add(new Column("ancestors", null, false, null));
      table.getColumnList().add(new Column("dept_name", null, false, null));
      table.getColumnList().add(new Column("order_num", null, false, null));
      table.getColumnList().add(new Column("leader", null, false, null));
      table.getColumnList().add(new Column("status", null, false, null));
      table.getColumnList().add(new Column("del_flag", null, false, null));
      table.getColumnList().add(new Column("create_by", null, false, null));
      table.getColumnList().add(new Column("create_time", null, false, null));
      table.getColumnList().add(new Column("update_by", null, false, null));
      table.getColumnList().add(new Column("update_time", null, false, null));
      table.getColumnList().add(new Column("phone", null, false, null));
      table.getColumnList().add(new Column("email", null, false, null));
      schema.getTableList().add(table);
      table = new Table("tb", "test");
      table.setColumnList(new ArrayList());
      table.getColumnList().add(new Column("c1", null, false, null));
      table.getColumnList().add(new Column("c2", null, false, null));
      table.getColumnList().add(new Column("c3", null, false, null));
      schema.getTableList().add(table);
      table = new Table("tc", "test");
      table.setColumnList(new ArrayList());
      table.getColumnList().add(new Column("c1", null, false, null));
      table.getColumnList().add(new Column("c2", null, false, null));
      table.getColumnList().add(new Column("c3", null, false, null));
      schema.getTableList().add(table);
      table = new Table("td", "test");
      table.setColumnList(new ArrayList());
      table.getColumnList().add(new Column("c1", null, false, null));
      table.getColumnList().add(new Column("c2", null, false, null));
      table.getColumnList().add(new Column("c3", null, false, null));
      table.getColumnList().add(new Column("c4", null, false, null));
      schema.getTableList().add(table);
      table = new Table("tx1", "test");
      table.setColumnList(new ArrayList());
      table.getColumnList().add(new Column("f1", null, false, null));
      table.getColumnList().add(new Column("f2", null, false, null));
      table.getColumnList().add(new Column("f3", null, false, null));
      table.getColumnList().add(new Column("f4", null, false, null));
      schema.getTableList().add(table);
      table = new Table("tx2", "test");
      table.setColumnList(new ArrayList());
      table.getColumnList().add(new Column("f1", null, false, null));
      table.getColumnList().add(new Column("f2", null, false, null));
      table.getColumnList().add(new Column("f3", null, false, null));
      table.getColumnList().add(new Column("f4", null, false, null));
      schema.getTableList().add(table);
      table = new Table("tx3", "test");
      table.setColumnList(new ArrayList());
      table.getColumnList().add(new Column("f1", null, false, null));
      table.getColumnList().add(new Column("f2", null, false, null));
      table.getColumnList().add(new Column("f3", null, false, null));
      table.getColumnList().add(new Column("f4", null, false, null));
      schema.getTableList().add(table);
      table = new Table("tb1", "test");
      table.setColumnList(new ArrayList());
      table.getColumnList().add(new Column("c1", null, false, null));
      table.getColumnList().add(new Column("c2", null, false, null));
      table.getColumnList().add(new Column("c3", null, false, null));
      table.getColumnList().add(new Column("name", null, false, null));
      schema.getTableList().add(table);
      table = new Table("tb2", "test");
      table.setColumnList(new ArrayList());
      table.getColumnList().add(new Column("c1", null, false, null));
      table.getColumnList().add(new Column("c2", null, false, null));
      table.getColumnList().add(new Column("c4", null, false, null));
      table.getColumnList().add(new Column("name", null, false, null));
      schema.getTableList().add(table);
      table = new Table("tb4", "test");
      table.setColumnList(new ArrayList());
      table.getColumnList().add(new Column("c2", null, false, null));
      table.getColumnList().add(new Column("c3", null, false, null));
      table.getColumnList().add(new Column("c4", null, false, null));
      table.getColumnList().add(new Column("name", null, false, null));
      schema.getTableList().add(table);
      table = new Table("tb5", "test");
      table.setColumnList(new ArrayList());
      table.getColumnList().add(new Column("c1", null, false, null));
      table.getColumnList().add(new Column("c2", null, false, null));
      table.getColumnList().add(new Column("c3", null, false, null));
      table.getColumnList().add(new Column("name", null, false, null));
      schema.getTableList().add(table);
      return db;
   }

   static Context createContext() {
      Context context = new Context();
      DataBase db = createDB();
      context.setDataBase(db);
      context.initialize(db, "test", "kingbase");
      return context;
   }

   static void testSelect() {
      StopWatch sw = new StopWatch();
      String[] sqls = new String[]{"select user_id as uid,user_name as uname,login_name as lname,did,dept_name as dname from vtest1 a join vtest b on a.dept_id=b.did where user_id=1", "select a.name from sys_user a where a.id=1", "SELECT * FROM sys_user JOIN (SELECT A FROM Z) x", "select  * from sys_user a join sys_dept b on a.dept_id=b.dept_id where a.dept_id=103", "select  * from (select a.* from sys_user a) t where t.dept_id=103", "with a as (select * from sys_user) select  * from a t where t.dept_id=103", "select (a.user_name + a.user_id) as xx from sys_user a ", "SELECT salesperson.name, max_sale.amount, max_sale_customer.customer_name FROM salesperson,   \nLATERAL (SELECT MAX(amount) AS amount FROM all_sales WHERE all_sales.salesperson_id = salesperson.id) AS max_sale,   \nLATERAL (SELECT customer_name FROM all_sales WHERE all_sales.salesperson_id = salesperson.id AND all_sales.amount =  max_sale.amount) AS max_sale_customer;\n", "SELECT salesperson.name, max_sale.amount, max_sale_customer.customer_name FROM salesperson,   LATERAL (SELECT MAX(amount) AS amount FROM all_sales WHERE all_sales.salesperson_id = salesperson.id) AS max_sale,   LATERAL (SELECT customer_name FROM all_sales WHERE all_sales.salesperson_id = salesperson.id AND all_sales.amount =  max_sale.amount) AS max_sale_customer;\n", "\nSELECT salesperson.name, max_sale.amount, max_sale.customer_name FROM salesperson, LATERAL (SELECT amount, customer_name FROM all_sales WHERE all_sales.salesperson_id = salesperson.id ORDER BY amount DESC LIMIT 1) AS max_sale;", "with tbx (ipath) as ( select fn(id,name) from tb1)  select * from tbx", "with tbx (ipath) as ( select fn(id,name) from tb1)  select tbx.ipath from tbx", "UPDATE items, (SELECT id FROM items WHERE id IN (SELECT id FROM items WHERE retail / wholesale >= 1.3 AND quantity < 100)) AS discounted SET items.retail = items.retail * 0.9 WHERE items.id = discounted.id;\n", "WITH cte1 AS (SELECT 1) SELECT * FROM (WITH cte2 AS (SELECT 2) SELECT * FROM cte2 JOIN cte1) AS dt;\n", "WITH RECURSIVE cte (n) AS ( SELECT 1 UNION ALL SELECT n + 1 FROM cte WHERE n < 5 ) SELECT * FROM cte;\n", "WITH RECURSIVE employee_paths (id, name, path) AS (\n\t\tSELECT id AS id, name AS name, CAST(id AS CHAR(200)) AS `CAST(id AS CHAR(200))`\n\t\tFROM employees\n\t\tWHERE manager_id IS NULL\n\t\tUNION ALL\n\t\tSELECT e.id AS id, e.name AS name\n\t\t\t, CONCAT(ep.path, ',', e.id) AS `CONCAT(ep.path, ',', e.id)`\n\t\tFROM employee_paths ep\n\t\t\tJOIN employees e ON ep.id = e.manager_id\n\t)\nSELECT employee_paths.id AS id, employee_paths.name AS name, employee_paths.path AS path\nFROM employee_paths\nORDER BY path;", "SELECT * FROM (SELECT *FROM SYS_USER)", "SELECT * FROM sys_user JOIN (SELECT A FROM Z) x", "select a.dept_name,(select c.user_id from sys_month c ) as id from sys_dept a join (select user_name from sys_user) b left join tb4  on tb4.id=1 left join (select *  from sys_user) tb5 on tb4.id=tb5.id ", "select * from ( select cg.dianzisqajbh,bn.wenjianbbs,bn.wenjianbs,bn.wenjianlx,v.codename wenjianmc, bn.wenjiancflj,bn.yewubid,bn.zhuwenjbj,bn.geshilx,bn.dabaowjjcflj, case when (bn.dabaowjjcflj is not null and bn.dabaowjjcflj != '') then '0' else '1' end viewflag from zxsq_wjbnxx_t bn join zxsq_dzsqqqjl_cg_t cg on bn.wenjianbbs = cg.wenjianbbs left join ( select t.wenjiandm as codevalue, t.mobanmc as codename from zpt_wjgl_mbdy t where (t.mobanlx = '1' and t.del_flag = '0' and length(t.wenjiandm) = 6 ) or wenjiandm in('210405','210403','220301','230302','210401','21030107','10000701','10002701') )v on v.codevalue = bn.wenjianlx where exists ( select * from ( select glyw.guanliandzsqajbh dianzisqajbh from zxsq_glyw_t glyw where glyw.zhutiyw_dzsqajbh = ? and glyw.del_flag = '0' union all select dianzisqajbh from zxsq_dzsqqqjl_cg_t t1 where t1.dianzisqajbh = ? and t1.del_flag = '0' ) t where t.dianzisqajbh = cg.dianzisqajbh) and bn.wenjianlx not in ('999998', '999999','100045','100047','100048','150111') and cg.del_flag = '0' and bn.del_flag = '0' union all select cg.dianzisqajbh,bn.wenjianbbs,bn.wenjianbs,bn.wenjianlx,v.codename wenjianmc, bn.wenjiancflj,bn.yewubid,bn.zhuwenjbj,bn.geshilx,bn.dabaowjjcflj, case when (bn.dabaowjjcflj is not null and bn.dabaowjjcflj != '') then '0' else '1' end viewflag from zxsq_wjbnxx_t bn join zxsq_dzsqqqjl_ls_t cg on bn.wenjianbbs = cg.wenjianbbs left join ( select t.wenjiandm as codevalue, t.mobanmc as codename from zpt_wjgl_mbdy t where (t.mobanlx = '1' and t.del_flag = '0' and length(t.wenjiandm) = 6 ) or wenjiandm in('210405','210403','220301','230302','210401','21030107','10000701','10002701') )v on v.codevalue = bn.wenjianlx where exists ( select * from ( select glyw.guanliandzsqajbh dianzisqajbh from zxsq_glyw_t glyw where glyw.zhutiyw_dzsqajbh = ? and glyw.del_flag = '0' union all select dianzisqajbh from zxsq_dzsqqqjl_ls_t t1 where t1.dianzisqajbh = ? and t1.del_flag = '0' ) t where t.dianzisqajbh = cg.dianzisqajbh) and bn.wenjianlx not in ('999998', '999999','100045','100047','100048','150111') and cg.del_flag = '0' and bn.del_flag = '0' ) t1 order by t1.wenjianlx asc", "select * from sys_user t  where t.user_id=1", "insert into sys_user select * from sys_user", "select user_id,user_name from sys_user", "select a1.name from tb1 a1  left join (select c.id from tb2 c group by c.name having count(c.id) > 0) a2 on a2.id=a.id left join (select d.id from tb3 d group by d.name) a3 on a3.id=a.id left join (select e.id from tb4 e group by e.name) a4 on a4.id=a.id ", "select * from (select a.menuname,a.tid from  t_base_menu a) t where t.tid = 1 ", "SELECT count(0) FROM sys_user u LEFT JOIN sys_dept d ON u.dept_id = d.dept_id WHERE u.del_flag = '0'", "SELECT t.STUDENT_ID AS STUDENT_ID, t.TID AS TID, t.FLAG AS FLAG, t.NOTE AS NOTE, t.STUDENT_NAME AS STUDENT_NAME   , t.STUDENT_PASSWORD AS STUDENT_PASSWORD  FROM student t  WHERE t.student_id = '22222'  ", "WITH RECURSIVE search_graph(id, link, data, depth) AS (  SELECT g.id, g.link, g.data, 1  FROM graph g  UNION ALL  SELECT g.id, g.link, g.data, sg.depth + 1  FROM graph g, search_graph sg  WHERE g.id = sg.link  )  SELECT * FROM search_graph as d;", "select a.* from sys_user a ,sys_dept b where a.dept_id=b.dept_id", " SELECT * FROM TX1 JOIN TX2 USING (F1,F2,F3) WHERE F1=1", " SELECT * FROM TX1 JOIN TX2 USING (F1,F2,F3) JOIN TX3 USING(F11,F12) WHERE F1=1", " SELECT * FROM (select a1 from yy)c JOIN (select b1 from xx)a USING (F1,F2,F3) JOIN (select c1 from zz)b USING(F11,F12) WHERE F1=1", "EXPLAIN SELECT * FROM TX1 JOIN (select F1 from tx2) X2 USING (F1,F2,F3,F4) WHERE F1=1\n", "SELECT id,name from tb1 join tb2 on tb1.f1=tb2.f1", "(SELECT 1 AS result UNION SELECT 2)", "SELECT (SELECT s2 FROM t1);", "SELECT name FROM t1 WHERE column1 = (SELECT MAX(column2) FROM t2);", "SELECT name FROM t1 AS t WHERE 2 = (SELECT COUNT(t1.name1) FROM t1 WHERE t1.id = t.id);", "SELECT name FROM t1 AS t WHERE 2 = (SELECT COUNT(name1) FROM t1 WHERE t1.id = t.id);", "SELECT s12 FROM t1 WHERE s1 = ANY (SELECT sX FROM t2)", "SELECT s1 FROM t1 WHERE s1 IN (SELECT s1 FROM t2);", "SELECT s1 FROM t1 WHERE s1 <> ANY (SELECT s1 FROM t2); ", "SELECT s1 FROM t1 WHERE s1 <> SOME (SELECT s1 FROM t2);", "SELECT s1 FROM t1 WHERE s1 > ANY (TABLE t2); ", "SELECT s1 FROM t1 WHERE s1 = ANY (TABLE t2); ", "SELECT s1 FROM t1 WHERE s1 IN (TABLE t2); ", "SELECT s1 FROM t1 WHERE s1 <> ANY (TABLE t2); ", "SELECT s1 FROM t1 WHERE s1 <> SOME (TABLE t2);", "SELECT s1 FROM t1 WHERE s1 > ALL (SELECT s1 FROM t2);", "SELECT s1 FROM t1 WHERE 1 > ALL (SELECT s1 FROM t2);", "SELECT s1 FROM t1 WHERE 1 > (SELECT s1 FROM t2);", "SELECT s1 FROM t1 WHERE 1 > ALL (SELECT MAX(s1) FROM t2);", "SELECT s1 FROM t1 WHERE s1 <> ALL (SELECT s1 FROM t2);", "SELECT s1 FROM t1 WHERE s1 NOT IN (SELECT s1 FROM t2);", "SELECT s1 FROM t1 WHERE s1 <> ALL (TABLE t2); ", "SELECT s1 FROM t1 WHERE s1 NOT IN (TABLE t2);", "SELECT sss FROM t1 WHERE (col1,col2) = (SELECT col3, col4 FROM t2 WHERE id = 10)", "SELECT s1 FROM t1 WHERE ROW(col1,col2) = (SELECT col3, col4 FROM t2 WHERE id = 10);", "SELECT s1 FROM t1 WHERE ROW(1) = (SELECT column1 FROM t2)", "SELECT s1 FROM t1 WHERE (column1,column2) = (1,1); ", "SELECT s1 FROM t1 WHERE column1 = 1 AND column2 = 1;", "SELECT column1,column2,column3 FROM t1 WHERE (column1,column2,column3) IN (SELECT column1,column2,column3 FROM t2);", "SELECT column1 FROM t1 WHERE EXISTS (SELECT columnXX1  FROM t2);", "SELECT DISTINCT store_type FROM stores WHERE EXISTS (SELECT columnXX1   FROM cities_stores WHERE cities_stores.store_type = stores.store_type);", "SELECT DISTINCT store_type FROM stores WHERE NOT EXISTS (SELECT f1 FROM cities_stores WHERE cities_stores.store_type = stores.store_type);", "SELECT DISTINCT store_type FROM stores s1 WHERE NOT EXISTS ( SELECT ss FROM cities WHERE NOT EXISTS ( SELECT AAA FROM cities_stores WHERE cities_stores.city = cities.city AND cities_stores.store_type = stores.store_type));", "SELECT DISTINCT store_type FROM stores s1 WHERE NOT EXISTS ( SELECT A2 FROM cities WHERE NOT EXISTS ( SELECT A1 FROM cities_stores WHERE cities_stores.city = cities.city AND cities_stores.store_type = stores.store_type));", "SELECT A1 FROM t1 WHERE column1 = ANY (SELECT column1 FROM t2 WHERE t2.column2 = t1.column2);", "SELECT column1 FROM t1 AS x WHERE x.column1 = (SELECT column1 FROM t2 AS x WHERE x.column1 = (SELECT column1 FROM t3 WHERE x.column2 = t3.column1));", "SELECT column1  FROM t1 WHERE ( SELECT a FROM t2 WHERE t2.a=t1.a ) > 0;", "SELECT t1.xxx FROM t1 LEFT OUTER JOIN (SELECT a, COUNT(*) AS ct FROM t2 GROUP BY a) AS derived ON t1.a = derived.a AND REJECT_IF( (ct > 1), \"ERROR 1242 (21000): Subquery returns more than 1 row\" ) WHERE derived.a > 0;", "SELECT XX FROM JSON_TABLE(arg_list) AS tbl_name", "SELECT sb1,sb2,sb3 FROM (SELECT s1 AS sb1, s2 AS sb2, s3*2 AS sb3 FROM t1) AS sb WHERE sb1 > 1;", "SELECT AVG(SUM(column1)) FROM t1 GROUP BY column1;", "SELECT AVG(sum_column1) FROM (SELECT SUM(column1) AS sum_column1 FROM t1 GROUP BY column1) AS t1;", "select a1 from (select sum(a1) as a1 from tb)x", "SELECT * FROM (SELECT 1, 2, 3, 4 from test) AS dt (a, b, c, d);", "SELECT * FROM (SELECT 1, 2, 3, 4) AS dt;", "SELECT aname,bname FROM t1 WHERE t1.d > (SELECT AVG(dt.a) FROM (SELECT SUM(t2.a) AS a FROM t2 WHERE t2.b = t1.b GROUP BY t2.c) dt WHERE dt.a > 10);", "SELECT salesperson.name,   (SELECT MAX(amount) AS amount FROM all_sales WHERE all_sales.salesperson_id = salesperson.id) AS amount,   (SELECT customer_name FROM all_sales WHERE all_sales.salesperson_id = salesperson.id AND all_sales.amount =   (SELECT MAX(amount) AS amount FROM all_sales WHERE all_sales.salesperson_id = salesperson.id)) AS customer_name FROM salesperson;", "SELECT salesperson.name, max_sale.amount, max_sale_customer.customer_name FROM salesperson,   (SELECT MAX(amount) AS amount FROM all_sales WHERE all_sales.salesperson_id = salesperson.id) AS max_sale,   (SELECT customer_name FROM all_sales WHERE all_sales.salesperson_id = salesperson.id AND all_sales.amount =   max_sale.amount) AS max_sale_customer;", "SELECT salesperson.name, max_sale.amount, max_sale_customer.customer_name FROM salesperson,   LATERAL (SELECT MAX(amount) AS amount FROM all_sales WHERE all_sales.salesperson_id = salesperson.id) AS max_sale,   LATERAL (SELECT customer_name FROM all_sales WHERE all_sales.salesperson_id = salesperson.id AND all_sales.amount =  max_sale.amount) AS max_sale_customer;", "SELECT z FROM t1 WHERE column1 = (SELECT column1 FROM t2);", "SELECT salesperson.name,(SELECT amount, customer_name FROM all_sales WHERE all_sales.salesperson_id = salesperson.id ORDER BY amount DESC LIMIT 1) FROM salesperson;", "SELECT salesperson.name, max_sale.amount, max_sale.customer_name FROM salesperson, LATERAL (SELECT amount, customer_name FROM all_sales WHERE all_sales.salesperson_id = salesperson.id ORDER BY amount DESC LIMIT 1) AS max_sale;", "SELECT salesperson.name,(SELECT amount, customer_name FROM all_sales WHERE all_sales.salesperson_id = salesperson.id   LIMIT 1) FROM salesperson;", "SELECT salesperson.name, max_sale.amount, max_sale.customer_name FROM salesperson, LATERAL (SELECT amount, customer_name FROM all_sales WHERE all_sales.salesperson_id = salesperson.id ORDER BY amount DESC LIMIT 1) AS max_sale;", "SELECT salesperson.name, max_sale.amount, max_sale_customer.customer_name FROM salesperson,   (SELECT MAX(amount) AS amount FROM all_sales WHERE all_sales.salesperson_id = salesperson.id) AS max_sale,   (SELECT customer_name FROM all_sales WHERE all_sales.salesperson_id = salesperson.id AND all_sales.amount =   max_sale.amount) AS max_sale_customer;", "SELECT salesperson.name,   (SELECT MAX(amount) AS amount FROM all_sales WHERE all_sales.salesperson_id = salesperson.id) AS amount,   (SELECT customer_name FROM all_sales WHERE all_sales.salesperson_id = salesperson.id AND all_sales.amount =   (SELECT MAX(amount) AS amount FROM all_sales WHERE all_sales.salesperson_id = salesperson.id)) AS customer_name FROM salesperson;", "SELECT f1 FROM t1 WHERE s1 IN (SELECT s1 FROM t1 UNION ALL SELECT s1 FROM t2);", "SELECT (SELECT column1 FROM t1) + 5 FROM t2", "SELECT (SELECT column1 + 5 FROM t1) FROM t2", "SELECT xx FROM t1 WHERE s1 IN (SELECT s1 FROM t1) OR s1 IN (SELECT s1 FROM t2)", "SELECT xx FROM SYS_USER WHERE (DEPT_ID,USER_ID ) IN(SELECT DEPT_ID,USER_ID FROM SYS_USER)", "SELECT a2 FROM t1 UNION SELECT a1 FROM t2", "UPDATE t1 SET c=c+1 WHERE a=1;  ", "UPDATE t1 SET col1 = col1 + 1;", "UPDATE t1 SET col1 = col1 + 1, col2 = col1;", "UPDATE t SET id = id + 1;", "UPDATE t SET id = id + 1 ORDER BY id DESC", "UPDATE items,month SET items.price=month.price WHERE items.id=month.id", "UPDATE items, (SELECT id FROM items WHERE id IN (SELECT id FROM items WHERE retail / wholesale >= 1.3 AND quantity < 100)) AS discounted SET items.retail = items.retail * 0.9 WHERE items.id = discounted.id;", "UPDATE /*+ NO_MERGE(discounted) */ items, (SELECT id FROM items WHERE retail / wholesale >= 1.3 AND quantity < 100) AS discounted SET items.retail = items.retail * 0.9 WHERE items.id = discounted.id;", "UPDATE items, (SELECT id, retail / wholesale AS markup, quantity FROM items) AS discounted SET items.retail = items.retail * 0.9 WHERE discounted.markup >= 1.3 AND discounted.quantity < 100 AND items.id = discounted.id;", "VALUES ROW(1,-2,3), ROW(5,7,9), ROW(4,6,8);", "SELECT 1,2 UNION SELECT 10,15;", "VALUES ROW(1,2) UNION VALUES ROW(10,15);", "VALUES ROW(1,2), ROW(3,4), ROW(5,6), ROW(10,15), ROW(20,25);", "WITH cte1 AS (SELECT a, b FROM table1), cte2 AS (SELECT c, d FROM table2) SELECT b, d FROM cte1 JOIN cte2 WHERE cte1.a = cte2.c;", "WITH cte (col1, col2) AS ( SELECT 1, 2 UNION ALL SELECT 3, 4 ) SELECT col1, col2 FROM cte;", "WITH cte AS ( SELECT 1 AS col1, 2 AS col2 UNION ALL SELECT 3, 4 ) SELECT col1, col2 FROM cte;", "WITH cte1 AS (SELECT 1) SELECT * FROM (WITH cte2 AS (SELECT 2) SELECT * FROM cte2 JOIN cte1) AS dt;", "WITH RECURSIVE cte (n) AS ( SELECT 1 UNION ALL SELECT n + 1 FROM cte WHERE n < 5 ) SELECT * FROM cte;", "WITH RECURSIVE cte AS ( SELECT 1 AS n, CAST('abc' AS CHAR(20)) AS str UNION ALL SELECT n + 1, CONCAT(str, str) FROM cte WHERE n < 3 ) SELECT * FROM cte;", "WITH RECURSIVE employee_paths (id, name, path) AS ( SELECT id, name, CAST(id AS CHAR(200)) FROM employees WHERE manager_id IS NULL UNION ALL SELECT e.id, e.name, CONCAT(ep.path, ',', e.id) FROM employee_paths AS ep JOIN employees AS e ON ep.id = e.manager_id ) SELECT * FROM employee_paths ORDER BY path;", "WITH RECURSIVE employee_paths (id, name, path) AS ( SELECT id, name, CAST(id AS CHAR(200)) FROM employees WHERE manager_id IS NULL UNION ALL SELECT e.id, e.name, CONCAT(ep.path, ',', e.id) FROM employee_paths AS ep JOIN employees AS e ON ep.id = e.manager_id ) SELECT * FROM employee_paths ORDER BY path;", "SELECT z FROM t1 WHERE column1 = (SELECT MAX(column2) FROM t2)", "SELECT z FROM t1 AS t WHERE 2 = (SELECT COUNT(*) FROM t1 WHERE t1.id = t.id);", "SELECT (SELECT s1 FROM t2) FROM t1;", "SELECT UPPER((SELECT s1 FROM t1)) FROM t2", "SELECT (TABLE t2) FROM t1;", " SELECT z FROM table1 LEFT JOIN table2 ON table1.id = table2.id LEFT JOIN table3 ON table2.id = table3.id;", " SELECT a FROM t1 NATURAL RIGHT JOIN t2;", "SELECT sys_user.user_name FROM sys_dept JOIN sys_user USING (dept_id);", "INSERT INTO sys_user VALUES(1, 1);", "SELECT 1 + 1", " SELECT college, region AS r, seed AS s FROM tournament ORDER BY r, s; SELECT college, region, seed FROM tournament ORDER BY 2, 3;", "INSERT INTO t1 (a, b) SELECT c, d FROM t2 UNION SELECT e, f FROM t3 ON DUPLICATE KEY UPDATE b = b + c;", "INSERT INTO t1 (a, b) SELECT * FROM (SELECT c, d FROM t2 UNION SELECT e, f FROM t3) AS dt ON DUPLICATE KEY UPDATE b = b + c;", "select * from (SELECT f1,f2 from tb1 where f3=34 union all select a1,a2 from tb2 where a3=3) x", "select * from ( select t1.a,t1.b,t2.c,t2.d from t1,t2 ) x", "DELETE FROM somelog WHERE user = 'jcole' ;", "select a.name from sys_user a where a.id=1", "select c1 from tb  window test as (\n\tpartition  by c1\n\torder by c2 asc nulls first\n\t\n)\n, test1 as (\n\ttest\n\tROWS UNBOUNDED PRECEDING EXCLUDE CURRENT row\n)\n", "select timestamp  '2014-01-01';", "select timestamp (6) '2014-01-01';", "select timestamp (6) with time zone '2014-01-01';", "select timestamp (6) with local time zone '2014-01-01';", "select timestamp with time zone '2014-01-01';", "select timestamp with local time zone '2014-01-01';", "select timestamptz '2012-01-02';", "select timestamptz (6) '2012-01-02';", "select timestamp (6) '2014-01-01';", "select timestamp (6) with time zone '2014-01-01';", "select date '2014-01-01'", "select date '2014-01-01 11'", "select time '3';", "select time (6) '3:1';", "select time (6) without time zone '3:1';", "select time (6) without time zone '3:1';", "select time (6) with time zone '3:1';", "select time (6) with local time zone '3:1';", "select time without time zone '3:1';", "select time with time zone '3:1';", "select time with local time zone '3:1';", "select interval '@ 1 year 1 day 1 hour (6)'", "select interval  '@ 3 days 4 hours 5 mins 6 secs' hour to minute", "select interval  '1 day 2:03:04'", "select interval (6) '1 YEAR ago'", "select 1 from dual where now() >  date '2014-01-01'", "select 1 from dual where now() >  timestamp  '2014-01-01';", "select c1,c2,c3 from tb union all select c1,c2,c3 from tb;", "select c1,c2,c3 from tb union select c1,c2,c3 from tb;", "select c1,c2,c3 from tb union DISTINCT select c1,c2,c3 from tb;", "select c1,c2,c3 from tb INTERSECT ALL select c1,c2,c3 from tb;", "select c1,c2,c3 from tb INTERSECT DISTINCT select c1,c2,c3 from tb;", "select c1,c2,c3 from tb Intersect select c1,c2,c3 from tb;", "select c1,c2,c3 from tb Except ALL select c1,c2,c3 from tb;", "select c1,c2,c3 from tb Except DISTINCT select c1,c2,c3 from tb;", "select c1,c2,c3 from tb Except select c1,c2,c3 from tb;", "select c1,c2,c3 from tb Minus ALL select c1,c2,c3 from tb;", "select c1,c2,c3 from tb Minus DISTINCT select c1,c2,c3 from tb;", "select c1,c2,c3 from tb Minus select c1,c2,c3 from tb;", "select c1,c2,c3 from TB order by c1", "select c1,c2,c3 from TB order by c1 asc", "select c1,c2,c3 from TB order by c1 ,c2 desc", "select c1,c2,c3 from TB order by c1 asc ,c2", "select c1,c2,c3 from TB order by c1 ,c2", "select c1,c2,c3 from TB order by c1 asc ,c2 desc", "select c1,c2,c3 from TB order by c1 asc ,c2 desc nulls first", "select c1,c2,c3 from TB order by c1 asc ,c2 desc nulls last", "select c1,c2,c3 from TB order by c1   nulls first", "select c1,c2,c3 from TB order by c1   nulls last", "select c1,c2,c3 from TB order by c1 asc  nulls first", "select c1,c2,c3 from TB order by c1 asc  nulls last", "select c1,c2,c3 from TB order by c1 ,c2  nulls last", "select c1,c2,c3 from TB order by c1 ,c2  nulls first", "SELECT * FROM TEST.SYS_USER LIMIT 10 OFFSET 1;", "SELECT a FROM TEST.SYS_USER LIMIT ALL OFFSET 10;", "SELECT a FROM TEST.SYS_USER LIMIT ALL, 1;", "SELECT a FROM TEST.SYS_USER LIMIT 10, 1;", "SELECT * FROM TEST.SYS_USER OFFSET 1 ROW ;", "SELECT * FROM TEST.SYS_USER OFFSET 1 ROWS ;", "SELECT * FROM TEST.SYS_USER OFFSET 1 ROWS FETCH FIRST 10 ROW ONLY;", "SELECT * FROM TEST.SYS_USER OFFSET 1 ROWS FETCH FIRST 10 ROWS ONLY;", "SELECT * FROM TEST.SYS_USER OFFSET 1 ROWS FETCH NEXT 10 ROW ONLY;", "SELECT * FROM TEST.SYS_USER OFFSET 1 ROWS FETCH NEXT 10 ROWS ONLY;", "SELECT * FROM TEST.SYS_USER OFFSET 1 ROW FETCH FIRST 10 ROW ONLY;", "SELECT * FROM TEST.SYS_USER OFFSET 1 ROW FETCH FIRST 10 ROWS ONLY;", "SELECT * FROM TEST.SYS_USER OFFSET 1 ROW FETCH NEXT 10 ROW ONLY;", "SELECT * FROM TEST.SYS_USER OFFSET 1 ROW FETCH NEXT 10 ROWS ONLY;", "select c1,c2,c3 from tb for update;", "select c1,c2,c3 from tb for no key update;", "select c1,c2,c3 from tb for share;", "select c1,c2,c3 from tb for key share;", "select c1,c2,c3 from tb for update of tb,tb2;", "select c1,c2,c3 from tb for no key update of tb;", "select c1,c2,c3 from tb for share of tb;", "select c1,c2,c3 from tb for key share of tb;", "select c1,c2,c3 from tb for update nowait;", "select c1,c2,c3 from tb for no key update nowait;", "select c1,c2,c3 from tb for share nowait;", "select c1,c2,c3 from tb for key share nowait;", "select c1,c2,c3 from tb for update of tb nowait;", "select c1,c2,c3 from tb for no key update of tb nowait;", "select c1,c2,c3 from tb for share of tb nowait;", "select c1,c2,c3 from tb for key share of tb nowait;", "select c1,c2,c3 from tb for update skip locked;", "select c1,c2,c3 from tb for no key update skip locked;", "select c1,c2,c3 from tb for share skip locked;", "select c1,c2,c3 from tb for key share skip locked;", "select c1,c2,c3 from tb for update of tb skip locked;", "select c1,c2,c3 from tb for no key update of tb skip locked;", "select c1,c2,c3 from tb for share of tb skip locked;", "select c1,c2,c3 from tb for key share of tb skip locked;", "select xx.x from TB t,lateral (select a.c3 as x from  timetest a  where t.c1=a.c1) as xx,lateral (select C2) as x", "with T (c) as  (update tb set c1=1 where c1=2 returning  c1) select * from T\n", "select a from test@test_dblink", "select a from test@test as t", "select lead(c1,1) over ( partition  by c1 order by c1 asc),c1,c2,c3 from tb t", " delete from timetest;", " delete from only timetest;", " delete from timetest *", " delete from timetest a;", " delete from only timetest a;", " delete from timetest * a", " delete from timetest as a;", " delete from only timetest as a;", " delete from timetest *  as a", " delete from timetest  where 1<>1;", " delete from only timetest  where 1<>1;", " delete from timetest * where 1<>1", " delete from timetest a  where 1<>1;", " delete from only timetest a where 1<>1;", " delete from timetest * a where 1<>1", " delete from timetest as a where 1<>1;", " delete from only timetest as a  where 1<>1;", " delete from timetest * as a where 1<>1", "delete from tb using timetest a,tc  where a.c1 =1", "with k as (select c1 from tb)  delete from tb using public.timetest a,tc  where a.c1 =1", "table only sys_user *", "with k as not materialized  (select * from  tb)  select * from k", "with k as not materialized (table sys_user) select * from k", "select * from (table sys_user) as a", "SELECT F1 FROM ONLY T", "select f1 from t1 group by  CUBE ( t1)", "select c1 from tb group by GROUPING SETS( rollup (c1),cube(c1))", "select B'10'", "select c1 from tb where c1 ^=1", "select c1 from tb where c1 !=1", "select c1 from tb where c1 <>1", "select 1 + 1;", "select 1 - 1;", "select 1 * 1 ;", "select 1 / 1;", "select 3%2;", "select 2^3;", "select a ^ b from tb", "select 1~1 ;", "select a ~ b from tb", "select 1 & 1;", "select 1 << 1;", "select 1 >> 1;", "select 1 | 1;", "select (c1+c2) # (c2+c3) from tb;", "select 1 # 1;", "select |/2;", "select |/ (c1+c2) from tb;", "select ||/2;", "select 5!;", "select (c1+c2)! from tb;", "select !!5;", "select !!(c1+c2)from tb;", "select @ -5;", "select ~1;", "select ~fd1 from tb", "SELECT Infinity,Nan,today FROM DUAL", "insert into tb default values;", "insert into tb (c1,c2) values (default,default);", "insert into tb (c1,c2) values (default,default),(1,default);", "insert into tb values(1,default,2);", "insert into tc select * from tc;", "insert into tb (c1,c2) select c1,c2 from tc;", "insert into tb  set c1=1;", "insert into tb  set c1=1,c2=default;", "insert into tb  set (c1,c2,c3)=(1,2,3);", "insert into tb  set (c1,c2,c3)=(1,default,3);", "insert into tb  set (c1,c2)=(11111,default),(c3)=(3);", "insert into tb  set (c1)=(1),(c2)=(default),(c3)=(3);", "insert into tb overriding  system value default values;", "insert into tb (c1,c2) values (default,default);", "insert into tb (c1,c2) values (default,default),(1,default);", "insert into tb values(1,default,2);", "insert into tc select * from tc;", "insert into tb (c1,c2) select c1,c2 from tc;", "insert into tb  set c1=1;", "insert into tb  set c1=1,c2=default;", "insert into tb  set (c1,c2,c3)=(1,2,3);", "insert into tb  set (c1,c2,c3)=(1,default,3);", "insert into tb  set (c1,c2)=(1,default),(c3)=(3);", "insert into tb  set (c1)=(1),(c2)=(default),(c3)=(3);", "insert into tb default values on conflict do nothing ;", "insert into tb (c1,c2) values (default,default)  on conflict do nothing ;", "insert into tb (c1,c2) values (default,default),(1,default)  on conflict do nothing ;", "insert into tb values(1,default,2)  on conflict do nothing ;", "insert into tc select * from tc  on conflict do nothing ;", "insert into tb (c1,c2) select c1,c2 from tc  on conflict do nothing ;", "insert into tb  set c1=1  on conflict do nothing ;", "insert into tb  set c1=1,c2=default  on conflict do nothing ;", "insert into tb  set (c1,c2,c3)=(1,2,3)  on conflict do nothing ;", "insert into tb  set (c1,c2,c3)=(1,default,3)  on conflict do nothing ;", "insert into tb  set (c1,c2)=(1,default),(c3)=(3)  on conflict do nothing ;", "insert into tb  set (c1)=(1),(c2)=(default),(c3)=(3)  on conflict do nothing ;", "insert into tb default values on conflict(c1) do update set c1=105 ;", "insert into tb default values on conflict(c1) do update set c1=104 ;", "insert into tb (c1,c2) values (default,default)  on conflict(c1) do update set c1=114;", "insert into tb (c1,c2) values (default,default),(1,default) on conflict(c1) do update set c1=113;", "insert into tb values(1,default,2)  on conflict(c1) do update set c1=112;", "insert into tb select * from tc where rownum<2 on conflict(c1) do update set c1=111 ;", "insert into tb (c1,c2) select c1,c2 from tc where rownum<2   on conflict(c1) do update set c1=110 ;", "insert into tb  set c1=1  on conflict(c1) do update set c1=109 ;", "insert into tb  set c1=1,c2=default  on conflict(c1) do update set c1=108;", "insert into tb  set (c1,c2,c3)=(1,2,3)  on conflict(c1) do update set c1=107;", "insert into tb  set (c1,c2,c3)=(1,default,3)  on conflict(c1) do update set c1=106;", "insert into tb  set (c1,c2)=(1,default),(c3)=(3)  on conflict(c1) do update set c1=105 ;", "insert into tb  set (c1)=(1),(c2)=(default),(c3)=(3)  on conflict(c1) do update set c1=107;", "insert into td default values on conflict(c1,c2) do update set (c1,c2)=(105,105) ;", "insert into td default values on conflict(c1,c2) do update set (c1,c2)=(106,106);", "insert into td (c1,c2) values (default,default)  on conflict(c1,c2) do update set (c1,c2)=(107,107);", "insert into td (c1,c2) values (default,default),(1,default) on conflict(c1,c2) do update set (c1,c2)=(108,108);", "insert into td values(1,default,2)  on conflict(c1,c2) do update set (c1,c2)=(109,109);", "insert into td select * from tc where rownum<2 on conflict(c1,c2) do update set (c1,c2)=(101,101);", "insert into td (c1,c2) select c1,c2 from tc where rownum<2   on conflict(c1,c2) do update set (c1,c2)=(102,102);", "insert into td  set c1=1  on conflict(c1,c2) do update set (c1,c2)=(103,103);", "insert into td  set c1=1,c2=default  on conflict(c1,c2) do update set (c1,c2)=(104,104);", "insert into td  set (c1,c2,c3)=(1,2,3)  on conflict(c1,c2) do update set (c1,c2)=(110,110);", "insert into td  set (c1,c2,c3)=(1,default,3)  on conflict(c1,c2) do update set (c1,c2)=(111,111);", "insert into td  set (c1,c2)=(1,default),(c3)=(3)  on conflict(c1,c2) do update set (c1,c2)=(112,112);", "insert into td  set (c1)=(1),(c2)=(default),(c3)=(3)  on conflict(c1,c2) do update set (c1,c2)=(113,113);", "insert into td as t default values on conflict(c1,c2) do update set (c1,c2)=(105,105) where t.c1=1;", "insert into td as t default values on conflict(c1,c2) do update set (c1,c2)=(106,106)  where t.c1=1;", "insert into td as t (c1,c2) values (default,default)  on conflict(c1,c2) do update set (c1,c2)=(107,107)  where t.c1=1;", "insert into td as t (c1,c2) values (default,default),(1,default) on conflict(c1,c2) do update set (c1,c2)=(108,108)  where t.c1=1;", "insert into td as t values(1,default,2)  on conflict(c1,c2) do update set (c1,c2)=(109,109)  where t.c1=1;", "insert into td as t select * from tc where rownum<2 on conflict(c1,c2) do update set (c1,c2)=(101,101)  where t.c1=1;", "insert into td as t (c1,c2) select c1,c2 from tc where rownum<2   on conflict(c1,c2) do update set (c1,c2)=(102,102)  where t.c1=1;", "insert into td as t  set c1=1  on conflict(c1,c2) do update set (c1,c2)=(103,103)  where t.c1=1;", "insert into td as t  set c1=1,c2=default  on conflict(c1,c2) do update set (c1,c2)=(104,104)  where t.c1=1;", "insert into td as t  set (c1,c2,c3)=(1,2,3)  on conflict(c1,c2) do update set (c1,c2)=(110,110)  where t.c1=1;", "insert into td as t  set (c1,c2,c3)=(1,default,3)  on conflict(c1,c2) do update set (c1,c2)=(111,111)  where t.c1=1;", "insert into td as t  set (c1,c2)=(1,default),(c3)=(3)  on conflict(c1,c2) do update set (c1,c2)=(112,112)  where t.c1=1;", "insert into td as t  set (c1)=(1),(c2)=(default),(c3)=(3)  on conflict(c1,c2) do update set (c1,c2)=(113,113)  where t.c1=1;", "INSERT INTO tb    DEFAULT VALUES  ON CONFLICT   ( c1 )   DO UPDATE SET c1 = 105", "SELECT config_id AS config_id, config_name AS config_name, config_key AS config_key, config_value AS config_value, config_type AS config_type\n, create_by AS create_by, create_time AS create_time, update_by AS update_by, update_time AS update_time, remark AS remark\nFROM public.sys_config", "select dict_code, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time, remark \n\t\tfrom public.sys_dict_data\n     \n\t\twhere status = '0' and dict_type = ? order by dict_sort asc", " select dict_code, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time, remark \n\t\tfrom public.sys_dict_data\n     \n\t\twhere status = '0' and dict_type = ? order by dict_sort asc -- appUsername=unLogin", "select * from sys_user where concat('%',user_id,'%')<>0", "select * from sys_user where concat(user_id) != 'a'", "INSERT INTO \"Test\".\"Table_name\" (\"c1\", \"c2\", \"cc3\", \"c3\", \"Cc3\")\nVALUES (9999, NULL, NULL, NULL, NULL)", "SELECT \"aaA\", \"aaa\"\nFROM \"test\".\"test\";\n"};
      int i1 = 0;

      for(String sql : sqls) {
         try {
            System.out.println(i1++);
            System.out.println(sql);
            sw.begin();
            SQLParser parser = new SQLParser();
            SQLResult result = parser.parse(sql, createDB(), "test");
            sw.end();
            sw.print();
            assertResult(result);
         } catch (Exception e) {
            e.printStackTrace();
            System.out.println(sql);
         }
      }

      sw.printAvg();
   }

   static void assertResult(SQLResult result) {
      System.out.println(result.statement.toString());
   }

   static String getString(FieldMemo memo) {
      StringBuffer s = new StringBuffer();
      s.append(memo.getAtomName());
      if (memo.children.size() > 0) {
         s.append(" [ ");
         if (memo.children != null) {
            for(FieldMemo child : memo.children) {
               s.append(getString(child));
               s.append(",");
            }

            s.deleteCharAt(s.length() - 1);
         }

         s.append(" ] ");
      }

      return s.toString();
   }

   static void log(Scope scope, String space) {
      System.out.println(space + "<scope>" + scope.getClass() + "--------------------------" + (scope.ref == null ? "" : scope.ref.getClass().toString()));

      for(Map.Entry<String, TableMemo> e : scope.getTableMap().entrySet()) {
         System.out.println("[T]" + (String)e.getKey() + "->" + ((TableMemo)e.getValue()).getQualifiedName() + "->" + ((TableMemo)e.getValue()).name + "->" + ((TableMemo)e.getValue()).alias);
      }

      for(Map.Entry<String, FieldMemo> e : scope.getFieldMap().entrySet()) {
         System.out.println("[F]" + (String)e.getKey() + "->" + ((FieldMemo)e.getValue()).getQualifiedName() + "->" + ((FieldMemo)e.getValue()).name + "->" + ((FieldMemo)e.getValue()).alias + "->" + ((FieldMemo)e.getValue()).isSelectItem);
         outputFieldChildren((FieldMemo)e.getValue(), "  -");
      }

      for(Scope child : scope.getChildren()) {
         log(child, space + "+");
      }

   }

   static void logValue(Scope scope, String space) {
      System.out.println(space + "<scope>" + scope.getClass() + "--------------------------" + (scope.ref == null ? "" : scope.getClass().toString()));

      for(ValueMemo value : scope.getValues()) {
         FieldMemo field = value.field;
         System.out.println("[F]" + (field != null ? field.getQualifiedName() + "->" + field.name + "->" + field.alias : "none") + "->" + (field == null ? false : field.isSelectItem));
         System.out.println("[V]" + value.value + "->" + value.operator + "->" + value.expr.getClass().toString());
      }

      for(Scope child : scope.getChildren()) {
         logValue(child, space + "+");
      }

   }

   static void outputFieldChildren(FieldMemo field, String space) {
      for(FieldMemo child : field.children) {
         System.out.println(space + "[F]" + child.getQualifiedName() + "->" + child.name + "->" + child.alias);
         outputFieldChildren(child, space + "-");
      }

   }
}
