package util.sqlparse.visitor.dm.test;

import bean.Column;
import bean.DataBase;
import bean.Schema;
import bean.Table;
import bean.View;
import com.alibaba.fastjson.JSONObject;
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.dm.SQLParser;

public class SQLParseTestSet {
   public static final String OUTPUT_PATH = "D:\\code\\sql-tools-2.0_bk\\src\\util\\sqlparse\\visitor\\dm\\test\\resource\\";

   public static void main(String[] args) {
      test();
   }

   static DataBase createDB() {
      DataBase db = new DataBase();
      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("ZJSJ_GD", "test");
      table.setColumnList(new ArrayList());
      table.getColumnList().add(new Column("JHDM", null, false, null));
      table.getColumnList().add(new Column("JXJ", null, false, null));
      table.getColumnList().add(new Column("JS", null, false, null));
      schema.getTableList().add(table);
      table = new Table("ZJGC_ZJSCRB", "test");
      table.setColumnList(new ArrayList());
      table.getColumnList().add(new Column("JHDM", null, false, null));
      table.getColumnList().add(new Column("RJC", null, false, null));
      table.getColumnList().add(new Column("JS", 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", "dm");
      return context;
   }

   static void test() {
      boolean isSave = false;
      String[] sqls = new String[]{"UPDATE t1 SET col1 = col1 + 1, col2 = col1;", "UPDATE PRODUCTION.PRODUCT SET NOWPRICE = NOWPRICE + 1.0000", "UPDATE PRODUCTION.PRODUCT SET NOWPRICE = NOWPRICE + 1.0000 WHERE PUBLISHER = '中华书局';", "UPDATE PRODUCTION.PRODUCT SET NOWPRICE = NOWPRICE + 1.0000, WRITER='me' WHERE PUBLISHER = '中华书局';", "UPDATE PRODUCTION.PRODUCT SET NOWPRICE = NOWPRICE + 1.0000, WRITER=DEFAULT WHERE PUBLISHER = '中华书局';", "UPDATE PRODUCTION.PRODUCT SET NOWPRICE = NOWPRICE + 1.0000 from PRODUCTION.PRODUCT,PRODUCTION.location WHERE PRODUCT.productid = location.locationid", "UPDATE TEST.T SET ID=ID+1 FROM TEST.T WHERE ID=1", "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", "update people p set p.name = (SELECT i.address from people_info i where i.pid = p.id),age = 18 where id = 1", "UPDATE PRODUCTION.PRODUCT SET NOWPRICE = NOWPRICE + 1.0000 WHERE PUBLISHER = (select name from table2 limit 1);", "UPDATE  PRODUCTION.PRODUCT  SET  DISCOUNT =\n( SELECT  AVG(DISCOUNT) \n    FROM  PRODUCTION.PRODUCT  \nWHERE PUBLISHER = '中华书局')\nWHERE  DISCOUNT > 7.0  AND  PUBLISHER != '中华书局';", "UPDATE T1 SET C2=4 WHERE C3 = 2 RETURN C1,C2 INTO A,B;", "UPDATE T1 SET C2=4 WHERE C3 = 2 RETURNING C1 INTO A;", "UPDATE T1 SET C2=4 WHERE C3 = 2 RETURN C1 BULK COLLECT INTO A;", "UPDATE T1 SET C2=4 WHERE C3 = 2 RETURNING C1 BULK COLLECT INTO A;", "UPDATE PURCHASING.PURCHASEORDER_HEADER SET(TAX,FREIGHT)=(select ORIGINALPRICE,  NOWPRICE from PRODUCTION.PRODUCT where NAME='长征');", "UPDATE ajzx_gn_sqr_t SET shenqingrxm=?, update_user=?, update_time=? WHERE ajzx_gn_sqr_t_rid=? AND del_flag='0' ", "UPDATE product p, product_price pp SET pp.price = p.price * 0.8 WHERE p.productid= pp.productId", " update test.t1 set (id,name) = (select id,name from test.t1 limit 1)"};
      testSet("D:\\code\\sql-tools-2.0_bk\\src\\util\\sqlparse\\visitor\\dm\\test\\resource\\", "update.json", isSave, sqls);
      sqls = new String[]{"DELETE  FROM  RESOURCES.EMPLOYEE_ADDRESS  WHERE  EMPLOYEEID  IN  ( SELECT  EMPLOYEEID    FROM  RESOURCES.EMPLOYEE  WHERE  EMPLOYEEID  NOT  IN  ( SELECT  EMPLOYEEID  FROM  RESOURCES.EMPLOYEE_DEPARTMENT))", "DELETE  FROM  RESOURCES.EMPLOYEE_ADDRESS WHERE  EMPLOYEEID  = 'sdfs'", "DELETE  FROM  RESOURCES.EMPLOYEE_ADDRESS b WHERE  EMPLOYEEID  = 'sdfs'", "DELETE  RESOURCES.EMPLOYEE_ADDRESS WHERE  EMPLOYEEID  = 'sdfs'"};
      testSet("D:\\code\\sql-tools-2.0_bk\\src\\util\\sqlparse\\visitor\\dm\\test\\resource\\", "delete.json", isSave, sqls);
      sqls = new String[]{"insert into (select ACCOUNTNO,NAME,ACTIVEFLAG, CREDIT from PURCHASING.VENDOR where ACCOUNTNO>50 ) values (90,'Tough',1,2);", "insert into (select ACCOUNTNO,NAME from PURCHASING.VENDOR where ACCOUNTNO>50 ) values (90,'Tough');", "INSERT INTO PURCHASING.VENDOR(ACCOUNTNO, NAME, ACTIVEFLAG, WEBURL, CREDIT) VALUES ('00', '华中科技大学出版社', 1, '', 2);", "INSERT INTO PURCHASING.VENDOR(ACCOUNTNO, NAME, ACTIVEFLAG, WEBURL, CREDIT) VALUES ('00', '华中科技大学出版社', 1, '', 2) RETURNING C1 INTO A;", "INSERT INTO PURCHASING.VENDOR(ACCOUNTNO, NAME, ACTIVEFLAG, WEBURL, CREDIT) VALUES ('00', '华中科技大学出版社', 1, '', 2) RETURN C1 INTO A;", "INSERT INTO PURCHASING.VENDOR(ACCOUNTNO, NAME, ACTIVEFLAG, WEBURL, CREDIT) VALUES ('00', '华中科技大学出版社', 1, '', 2) RETURN C1 BULK COLLECT INTO A;", "INSERT INTO PURCHASING.VENDOR(ACCOUNTNO, NAME, ACTIVEFLAG, WEBURL, CREDIT) VALUES ('00', '华中科技大学出版社', 1, '', 2) RETURNING C1 BULK COLLECT INTO A;", "INSERT INTO PURCHASING.VENDOR as t (ACCOUNTNO, NAME, ACTIVEFLAG, WEBURL, CREDIT) VALUES ('00', '华中科技大学出版社', 1, '', 2);", "INSERT INTO PURCHASING.VENDOR(ACCOUNTNO, NAME, ACTIVEFLAG, WEBURL, CREDIT)  VALUES ('00', '华中科技大学出版社', 1, '', 2), ('00', '清华大学出版社', 1, '',3);", "INSERT  INTO  PURCHASING.VENDOR(ACCOUNTNO, NAME, ACTIVEFLAG, WEBURL, CREDIT)  VALUES('00', (SELECT  PUBLISHER  FROM  PRODUCTION.PRODUCT  WHERE  NAME ='长征'),1, '', 1);", "INSERT  INTO  person.person (sex,name) (SELECT  'F',PUBLISHER  FROM  PRODUCTION.PRODUCT  WHERE  NAME ='长征');", "INSERT  INTO  person.person (sex,name) SELECT  'F',PUBLISHER  FROM  PRODUCTION.PRODUCT  WHERE  NAME ='长征';", "INSERT INTO PURCHASING.VENDOR(ACCOUNTNO, NAME, ACTIVEFLAG, WEBURL, CREDIT) VALUES ('00', '华中科技大学出版社', 1, default, 2);", "INSERT INTO PURCHASING.VENDOR(ACCOUNTNO, NAME, ACTIVEFLAG, WEBURL, CREDIT) VALUES (('00'), ('华中科技大学出版社'), (1), (''）, （2）);", "INSERT INTO PURCHASING.VENDOR(ACCOUNTNO, NAME, ACTIVEFLAG, WEBURL, CREDIT) VALUES (('00'), ('华中科技大学出版社'), (1), (''）, （2）);", " INSERT ALL    INTO PURCHASING.VENDOR(ACCOUNTNO, NAME, ACTIVEFLAG, WEBURL, CREDIT) VALUES ('99', '华中科技大学出版社', 1, '', 2)    INTO PURCHASING.VENDOR(ACCOUNTNO, NAME, ACTIVEFLAG, WEBURL, CREDIT) VALUES ('991', '华中科技大学出版社', 1, '', 2)   select A from dual;", "INSERT ALL        INTO sales (prod_id, cust_id, time_id, amount)        VALUES (product_id, customer_id, weekly_start_date, sales_sun)        INTO sales (prod_id, cust_id, time_id, amount)        VALUES (product_id, customer_id, weekly_start_date+1, sales_mon)        INTO sales (prod_id, cust_id, time_id, amount)        VALUES (product_id, customer_id, weekly_start_date+2, sales_tue)        INTO sales (prod_id, cust_id, time_id, amount)        VALUES (product_id, customer_id, weekly_start_date+3, sales_wed)        INTO sales (prod_id, cust_id, time_id, amount)        VALUES (product_id, customer_id, weekly_start_date+4, sales_thu)        INTO sales (prod_id, cust_id, time_id, amount)        VALUES (product_id, customer_id, weekly_start_date+5, sales_fri)        INTO sales (prod_id, cust_id, time_id, amount)        VALUES (product_id, customer_id, weekly_start_date+6, sales_sat)     SELECT product_id, customer_id, weekly_start_date, sales_sun,        sales_mon, sales_tue, sales_wed, sales_thu, sales_fri, sales_sat        FROM sales_input_table;", "INSERT  INTO  PRODUCTION.PRODUCT_SELL  SELECT  DISTINCT  T1.NAME ,  T5.NAME  FROM  PRODUCTION.PRODUCT  T1,  SALES.SALESORDER_DETAIL  T2,          SALES.SALESORDER_HEADER  T3,  SALES.CUSTOMER  T4,          PERSON.PERSON  T5  WHERE  T1.PRODUCTID = T2.PRODUCTID  AND  T2.SALESORDERID = T3.SALESORDERID           AND  T3.CUSTOMERID = T4.CUSTOMERID  AND  T4.PERSONID = T5.PERSONID;", "INSERT INTO (SELECT ID FROM TEST.T) as b VALUES (1)", "INSERT INTO (SELECT ID FROM TEST.T)  b VALUES (1)", "INSERT INTO (SELECT ID FROM TEST.T)  VALUES (1)"};
      testSet("D:\\code\\sql-tools-2.0_bk\\src\\util\\sqlparse\\visitor\\dm\\test\\resource\\", "insert.json", isSave, sqls);
      sqls = new String[]{" INSERT ALL    INTO PURCHASING.VENDOR(ACCOUNTNO, NAME, ACTIVEFLAG, WEBURL, CREDIT) VALUES ('99', '华中科技大学出版社', 1, '', 2)    INTO PURCHASING.VENDOR(ACCOUNTNO, NAME, ACTIVEFLAG, WEBURL, CREDIT) VALUES ('991', '华中科技大学出版社', 1, '', 2)   select A from dual;", "INSERT ALL \n\tINTO films (code, title, did, date_prod, kind)\n\tVALUES ('UA502', 'Bananas', 105, DEFAULT, 'Comedy', '82 minutes') \n\tINTO films1 (code, title, did, date_prod, kind)\n\tVALUES ('T_601', 'Yojimbo', 106, DEFAULT, 'Drama')\n\tSELECT dd FROM dual;", "INSERT ALL INTO films VALUES\n('UA502', 'Bananas', 105, '1971-07-13', 'Comedy', '82 minutes')\nINTO films1 VALUES\n('UA502', 'Bananas', 105, '1971-07-13', 'Comedy', '82 minutes')\nSELECT d FROM dual;", "INSERT ALL INTO films (code, title, did, date_prod, kind)\nVALUES ('T_601', 'Yojimbo', 106, '1961-06-16', 'Drama')\nINTO films1 (code, title, did, date_prod, kind, len)\nVALUES ('UA502', 'Bananas', 105, '1971-07-13', 'Comedy', '82 minutes')\nSELECT dd FROM dual;", "INSERT ALL INTO films VALUES\n('UA502', 'Bananas', 105, DEFAULT, 'Comedy', '82 minutes')\nINTO films1 (code, title, did, date_prod, kind)\nVALUES ('T_601', 'Yojimbo', 106, DEFAULT, 'Drama')\nSELECT dd FROM dual;", "INSERT FIRST\nWHEN date_prod < '2004-05-00' THEN INTO films\nWHEN date_prod < '2004-04-07' THEN INTO films1\nSELECT d FROM tmp_films WHERE date_prod < '2004-05-07';", "INSERT FIRST\nWHEN date_prod < '2004-05-00' THEN INTO films\nELSE INTO films1\nSELECT dd FROM tmp_films WHERE date_prod < '2004-05-07'"};
      testSet("D:\\code\\sql-tools-2.0_bk\\src\\util\\sqlparse\\visitor\\dm\\test\\resource\\", "insert_all.json", isSave, sqls);
      sqls = new String[]{"SELECT INTERVAL '0015-08' YEAR TO MONTH FROM DUAL", "SELECT INTERVAL '9 23' DAY TO HOUR FROM DUAL", "SELECT INTERVAL '09 23:12' DAY TO MINUTE FROM DUAL", "SELECT INTERVAL '09 23:12:01.1' DAY TO SECOND FROM DUAL", "SELECT INTERVAL '150' HOUR FROM DUAL", "SELECT INTERVAL '23:12' HOUR TO MINUTE FROM DUAL", "SELECT INTERVAL '23:12:01.1' HOUR TO SECOND FROM DUAL", "SELECT INTERVAL '12:01.1' MINUTE TO SECOND FROM DUAL", "SELECT INTERVAL '0015' YEAR  AS C1 FROM DUAL", "SELECT INTERVAL '0015-08' YEAR TO MONTH AS C1 FROM DUAL", "SELECT INTERVAL '0015' YEAR  AS C1 FROM DUAL", "select DATE '1999-10-01' AS C1 from dual", "select DATE '1999-10-01' from dual", "select TIME '09:10:21'  AS C1 from dual", "select TIME '09:10:21' from dual", "SELECT INTERVAL '0015' YEAR  AS C1 FROM DUAL", "select a.name from ast.$t1 a where a.name like '%111%' ", "select a.name from ast.\"$T1\" a where a.name like '%111%' ", "select DATE '1999-10-01' AS C1 from dual;", "select TIME '09:10:21'  AS C1 from dual;", "SELECT INTERVAL '0015-08' YEAR TO MONTH AS C1 FROM DUAL", "SELECT TIMESTAMP '2002-12-12 09:10:21' FROM DUAL", "SELECT INTERVAL '0015' YEAR  AS C1 FROM DUAL", "SELECT INTERVAL '0015' MONTH AS C1 FROM DUAL", "SELECT INTERVAL '157' DAY FROM DUAL", "SELECT INTERVAL '9 23' DAY TO HOUR FROM DUAL", "SELECT INTERVAL '09 23:12' DAY TO MINUTE FROM DUAL", "SELECT INTERVAL '09 23:12:01.1' DAY TO SECOND FROM DUAL", "SELECT INTERVAL '150' HOUR FROM DUAL", "SELECT INTERVAL '23:12' HOUR TO MINUTE FROM DUAL", "SELECT INTERVAL '23:12:01.1' HOUR TO SECOND FROM DUAL", "SELECT INTERVAL '150' MINUTE FROM DUAL", "SELECT INTERVAL '12:01.1' MINUTE TO SECOND FROM DUAL", "SELECT INTERVAL '51.1' SECOND FROM DUAL", "SELECT TIME '09:10:21 +8:00' FROM DUAL", "SELECT TIMESTAMP '2002-12-12 09:10:21 +8:00' FROM DUAL", "SELECT TIMESTAMP '2002-12-12 09:10:21' FROM DUAL", "SELECT 0x61626364 FROM DUAL", "SELECT -2 FROM DUAL;", "SELECT +1 FROM DUAL;", "SELECT 1 FROM DUAL;", "SELECT ~1 FROM DUAL;", "SELECT +1 + (-2) FROM DUAL;", "SELECT +1 - (-2) FROM DUAL;", "SELECT +1 - -2 FROM DUAL;", "SELECT 1 * 2 FROM DUAL;", "SELECT 1 / 2 FROM DUAL;", "SELECT 8 >> 3 FROM DUAL;", "SELECT 8 << 3 FROM DUAL;", "SELECT 8 | 3 FROM DUAL;", "SELECT 8 & 3 FROM DUAL;", "SELECT 8 | -3 FROM DUAL;", "SELECT 8 & -3 FROM DUAL;", "SELECT '111' || '222' FROM DUAL;", "select SYSDATE + INTERVAL '1' YEAR, SYSDATE - INTERVAL '1' YEAR from DUAL;", "SELECT SYSDATE + TIME '19:00:00'+INTERVAL '9' HOUR, TIME '19:00:00'-INTERVAL '9' HOUR;", "select * from sys_user order by user_name", "select * from sys_user order by user_name nulls first", "select * from sys_user order by user_name nulls last", "select * from sys_user order siblings by user_name", "select * from sys_user order siblings by user_name nulls first", "select * from sys_user order siblings by user_name nulls last", "select * from sys_user union select * from sys_user", "select * from sys_user except select * from sys_user", "select * from sys_user minus select * from sys_user", "select * from sys_user intersect select * from sys_user", "select * from sys_user union all select * from sys_user", "select * from sys_user except all select * from sys_user", "select * from sys_user minus all select * from sys_user", "select * from sys_user intersect all select * from sys_user", "select * from sys_user union distinct select * from sys_user", "select * from sys_user except distinct select * from sys_user", "select * from sys_user minus distinct select * from sys_user", "select * from sys_user intersect distinct select * from sys_user", "SELECT * FROM TEST.SYS_USER FOR UPDATE;", "SELECT * FROM TEST.SYS_USER LIMIT 10,10;", "SELECT * FROM TEST.SYS_USER LIMIT 10 OFFSET 10;", "SELECT * FROM TEST.SYS_USER OFFSET 10 ROW ;", "SELECT * FROM TEST.SYS_USER OFFSET 10 ROWS ;", "SELECT * FROM TEST.SYS_USER OFFSET 10 ROWS FETCH FIRST 10 ROW ONLY;", "SELECT * FROM TEST.SYS_USER OFFSET 10 ROWS FETCH FIRST 10 ROWS ONLY;", "SELECT * FROM TEST.SYS_USER OFFSET 10 ROWS FETCH NEXT 10 ROW ONLY;", "SELECT * FROM TEST.SYS_USER OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY;", "SELECT * FROM TEST.SYS_USER OFFSET 10 ROWS FETCH FIRST 10 PERCENT ROW ONLY;", "SELECT * FROM TEST.SYS_USER OFFSET 10 ROWS FETCH FIRST 10 PERCENT ROWS ONLY;", "SELECT * FROM TEST.SYS_USER OFFSET 10 ROWS FETCH NEXT 10 PERCENT ROW ONLY;", "SELECT * FROM TEST.SYS_USER OFFSET 10 ROWS FETCH NEXT 10 PERCENT ROWS ONLY;", "SELECT +1 + (-1) FROM DUAL", "SELECT +1 - -1 FROM DUAL", "SELECT +1 + (~1) FROM DUAL", "  SELECT STU_NAME,TERM,SUBJECT,SCORE          FROM (SELECT 'A' STU_NAME,            '2001-2002' TERM,            '90' \"微积分\",            '88' \"线性代数\",            '99' \"数据结构\"           FROM DUAL  )  UNPIVOT  (SCORE  FOR SUBJECT IN ( \"微积分\" AS 'wjf', \"线性代数\" AS 'xxds',\"数据结构\" AS 'sjjg')  )  ", "SELECT *  FROM T_EMP pivot ( count(name ) FOR addr IN ('bj','tj'  ) )  ", "SELECT * FROM T S", "SELECT *  FROM TEST.SYS_USER  pivot ( count(* ) FOR USER_NAME IN ('admin' as \"master\",'ry' as \"user\")  ) S", "SELECT * FROM TEST.SYS_USER;", "SELECT * FROM TEST.SYS_USER order by user_name LIMIT 1,10 for update;", " SELECT * FROM TEST.SYS_USER order  by user_name ;", "SELECT * FROM TEST.SYS_USER order  by user_name  for update;", "SELECT * FROM TEST.SYS_USER order  by user_name  LIMIT 1,10;", "SELECT * FROM TEST.SYS_USER order  by user_name  for update  LIMIT 1,10;", "SELECT * FROM TEST.SYS_USER LIMIT 1,10 order  by user_name;", "SELECT * FROM TEST.SYS_USER LIMIT 1,10 order  by user_name for update;", "SELECT * FROM TEST.SYS_USER for update;", "SELECT * FROM TEST.SYS_USER for update LIMIT 1,10 ;", "SELECT * FROM TEST.SYS_USER LIMIT 1,10  for update;", "SELECT NAME FROM TEST.SYS_USER LIMIT 1,10  ;", "select a from production.product natural join production.product_inventory", "select a from production.product natural inner join production.product_inventory", "select a from production.product natural outer join production.product_inventory", "select * from production.product natural FULL outer join production.product_inventory", "select * from production.product natural left outer join production.product_inventory", "select * from production.product natural right outer join production.product_inventory", "select ACCOUNTNO,ACCOUNT from table3 PARTITION (p2)", "select ACCOUNTNO,ACCOUNT from table3 PARTITION for(field)", "select ACCOUNTNO,ACCOUNT from table3 SUBPARTITION (p2)", "select ACCOUNTNO,ACCOUNT from table3 SUBPARTITION for(field)", "SELECT *  FROM (SELECT 'A' STU_NAME,                   '2001-2002' TERM,                   '90' \"微积分\",                    '88' \"线性代数\",                    '99' \"数据结构\"                   FROM DUAL  )  UNPIVOT  (SCORE  FOR SUBJECT IN ( \"微积分\" AS 'wjf', \"线性代数\" AS 'xxds',\"数据结构\" AS 'sjjg')  )", "select user_name from (select * from test.sys_user) a", "select user_name from test.sys_user a group by a.user_name;", "select user_name from test.sys_user a group by rollup ( a.user_name);", "select user_name from test.sys_user a group by cube ( a.user_name);", "select user_name from test.sys_user a group by grouping sets ( a.user_name);", "WITH   CTE1(K) AS(SELECT USER_NAME FROM TEST.SYS_USER),   CTE2(G) AS(SELECT USER_NAME FROM TEST.SYS_USER)  SELECT K, G FROM CTE1, CTE2;  ", "INSERT INTO (SELECT ID FROM TEST.T) VALUES (1)", "SELECT * FROM SYS_USER@A123", "select a from t1 union select b from t2", "SELECT * FROM SYS_DEPT   a CONNECT BY nocycle a.dept_id=101 START  WITH a.DEPT_ID =100", "SELECT * FROM SYS_DEPT   a CONNECT BY  a.dept_id=101 START  WITH a.DEPT_ID =100", "SELECT * FROM SYS_DEPT   a START  WITH a.DEPT_ID =100  CONNECT BY a.dept_id=101", "SELECT * FROM SYS_DEPT   a START  WITH a.DEPT_ID =100  CONNECT BY NOCYCLE a.dept_id=101", "SELECT    TOP 1     * FROM sys_user a  WHERE user_name='1' and a.dept_id=1  ;", "SELECT SYSDATE + INTERVAL '1' YEAR, SYSDATE - INTERVAL '1' YEAR from DUAL;", "select *  from sys_user a left join sys_dept b using(dept_id)", "select *  from sys_user a left inner join sys_dept b using(dept_id)", "select *  from sys_user a left OUTER join sys_dept b using(dept_id)", "select *  from sys_user a left join sys_dept b using(dept_id)", "select *  from sys_user a  full join sys_dept b using(dept_id)", "select *  from sys_user a  natural join sys_dept b ", "select * from vtest1", "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 (select name from tb2) as fd1 from tb1", "select * from (select id from t) a", "select a.id,b.name from a left join (select f1,f2 from xtb)b on a.id=b.id where a.name in (select xx.name from xx)", "select a.id,a.name from a  union select b.id,b.name from b join (select c.aa1 from tb3 c) d on d.aa1=b.id ", "select id,name from a  union select id,name from b join (select aa1 from tb3 c) d on d.aa1=b.id ", "SELECT ( SELECT MIN(SYJS) AS \"MIN(SYJS)\"\n FROM  ( SELECT JHDM AS JHDM, JXJ AS JXJ, JS AS JS\n , LAG(JS) OVER (PARTITION BY JHDM ORDER BY JS) AS SYJS\n FROM ZJSJ_GD ) GHCATB2\n WHERE JXJ <> 0\n AND JHDM = SZ.JHDM\n ) AS SJZXDJS , (   SELECT SUM(RJC) AS \"SUM(RJC)\"\n  FROM ZJGC_ZJSCRB\n  WHERE ZJDH = SZ.ZJDH\n   AND TO_CHAR(RQ, 'YYYYMMDD') <= TO_CHAR(SZ.RQ, 'YYYYMMDD')\n   AND RQ >= TO_DATE(TO_CHAR(SZ.RQ, 'YYYY') - 1 || '-12-26', 'YYYY-MM-DD')\n ) AS JDNLJJC  , (   SELECT SUM(RJC) AS \"SUM(RJC)\"\n  FROM ZJGC_ZJSCRB\n  WHERE JHDM = SZ.JHDM\n ) AS DJLNLJJC\n , (\n  SELECT SUM(RJC) AS \"SUM(RJC)\"\n  FROM ZJGC_ZJSCRB\n  WHERE ZJDH = SZ.ZJDH\n ) AS JDLNLJJC  FROM SZLEFT OUTER JOIN DJJCXX D ON D.JHDM = SZ.JHDM\n\tLEFT OUTER JOIN BLBM_JBDM BJ ON BJ.JBDM = D.JBDM", "select lead(dept_id)  OVER (order by user_name)  AS XH from test.sys_user", "SELECT ROW_NUMBER() OVER(PARTITION BY user_name ORDER BY dept_id DESC) XH  from test.sys_user"};
      testSet("D:\\code\\sql-tools-2.0_bk\\src\\util\\sqlparse\\visitor\\dm\\test\\resource\\", "select.json", false, sqls);
   }

   static void testSet(String path, String testSetName, boolean isSave, String[] sqls) {
      StopWatch sw = new StopWatch();
      JSONObject json = new JSONObject();
      JSONObject jsonObject = null;
      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);
            if (isSave) {
               TestSet.saveToJson(result, sql, json);
            } else {
               jsonObject = TestSet.test(result, sql, path + testSetName, jsonObject);
            }
         } catch (Exception e) {
            e.printStackTrace();
            System.out.println(sql);
         }
      }

      if (isSave) {
         JsonUtil.writeJson(path, json, testSetName);
      }

      sw.printAvg();
   }

   static void assertResult(SQLResult result) {
      System.out.println("------------------[TABLES-INFO]----------------");
      System.out.println(result.statement.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 && 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 + "-");
      }

   }
}
