001package gudusoft.gsqlparser;
002
003import gudusoft.gsqlparser.compiler.TASTEvaluator;
004import gudusoft.gsqlparser.compiler.TContext;
005import gudusoft.gsqlparser.compiler.TGlobalScope;
006import gudusoft.gsqlparser.compiler.TFrame;
007import gudusoft.gsqlparser.nodes.*;
008import gudusoft.gsqlparser.nodes.teradata.TTeradataHelper;
009import gudusoft.gsqlparser.resolver.*;
010import gudusoft.gsqlparser.sqlenv.TSQLEnv;
011import gudusoft.gsqlparser.stmt.*;
012import gudusoft.gsqlparser.stmt.dax.TDaxEvaluateStmt;
013import gudusoft.gsqlparser.stmt.dax.TDaxExprStmt;
014import gudusoft.gsqlparser.stmt.greenplum.TSlashCommand;
015import gudusoft.gsqlparser.stmt.mssql.TMssqlBlock;
016import gudusoft.gsqlparser.stmt.mssql.TMssqlCreateProcedure;
017import gudusoft.gsqlparser.stmt.mssql.TMssqlExecute;
018import gudusoft.gsqlparser.stmt.mysql.TMySQLSource;
019import gudusoft.gsqlparser.stmt.oracle.TPlsqlCreatePackage;
020import gudusoft.gsqlparser.stmt.oracle.TSqlplusCmdStatement;
021import gudusoft.gsqlparser.stmt.snowflake.TCreateTaskStmt;
022import gudusoft.gsqlparser.stmt.teradata.TTeradataBTEQCmd;
023import gudusoft.gsqlparser.stmt.teradata.TTeradataFastExportCmd;
024import gudusoft.gsqlparser.stmt.teradata.TTeradataFastLoadCmd;
025import gudusoft.gsqlparser.stmt.teradata.TTeradataMultiLoadCmd;
026import gudusoft.gsqlparser.stmt.teradata.utilities.BteqCmdType;
027import gudusoft.gsqlparser.stmt.teradata.utilities.TeradataUtilityType;
028import gudusoft.gsqlparser.util.TSnowflakeParameterChecker;
029
030
031import java.io.*;
032import java.nio.charset.Charset;
033import java.security.MessageDigest;
034import java.security.NoSuchAlgorithmException;
035import java.text.DateFormat;
036import java.text.ParseException;
037import java.util.*;
038
039import static gudusoft.gsqlparser.ESqlStatementType.*;
040
041
042
043/**
044 * This is the first class people start to use this SQL parser library.
045 * This class includes a lexer and a parser. The lexer is used to tokenize the input SQL, turn the input SQL text
046 * into a list of source tokens. The parser use this list source token as input, using the grammar rule of the specified
047 * database vendor to check the syntax of the input SQL and build the parse tree of this SQL if there is no syntax error
048 * in the input SQL.
049 * <p></p>
050 * Creating a SQL parser by specifing {@link gudusoft.gsqlparser.EDbObjectType a database vendor},
051 * then set SQL script text via {@link #setSqltext} method or reading the input SQL from a file via
052 * {@link #setSqlfilename} method.
053 * <p></p>
054 * After that, call one of the following methods to achieve what you need:
055 * <ul>
056 *  <li>{@link #tokenizeSqltext}, turns the input SQL into a sequence of token which is the
057 *  basic lexis element of SQL syntax. Token is categorized as keyword, identifier,
058 *  number, operator, whitespace and other types. All source tokens can be fetched
059 *  via the {@link #getSourcetokenlist()} method</li>
060 *
061 *  <li>{@link #getrawsqlstatements}, separates the SQL statements in the input SQL script without
062 *  doing syntax check, use the {@link #getSqlstatements()} method to get a list of SQL statements
063 *  which is the sub-class of {@link TCustomSqlStatement}, get SQL statement type
064 *  via the {@link TCustomSqlStatement#sqlstatementtype} field, and string representation of
065 *  each SQL statement via the {@link TCustomSqlStatement#toString} method. All source tokens in this SQL statement
066 *  is available by using {@link TCustomSqlStatement#sourcetokenlist} filed.
067 *  Since no parse tree is built by calling this method, no further detailed information about the SQL statement is available.
068 *  </li>
069 *
070 *  <li>{@link #parse}, Check syntax of the input SQL, doing some kind of semantic analysis without connecting to
071 *  a real database.
072 *  This method will do a in-depth analysis of the input SQL such as building the link between table and columns.
073 *  The parse tree of the input SQL is available after calling this method.
074 *  </li>
075 *  </ul>
076 *
077 *  The parser checks the syntax of those SQL statements one by one. If syntax error is found in a SQL statement,
078 *  an error will be logged, no parse tree will be built for this SQL statement,
079 *  the error message can be fetched using the {@link #getErrormessage()} method.
080 *  <p></p>
081 *  The syntax error in one SQL statement doesn't prevent the parser continue to check the syntax of the next SQL statement.
082 *  After checking syntax of all SQL statements, use the {@link #getErrorCount()} method to get the total number of errors.
083 *  <p></p>
084 *  A syntax error in a SQL stored procedure will cease this parser to check syntax of the rest SQL statements
085 *  in this stored procedure.
086 *
087 * <p>Format SQL script can be done after calling {@link #parse()}.
088 * <code>
089 *
090 *      int ret = sqlparser.parse();
091 *       if (ret == 0){
092 *           GFmtOpt option = GFmtOptFactory.newInstance();
093 *           String result = FormatterFactory.pp(sqlparser, option);
094 *           System.out.println(result);
095 *       }else{
096 *           System.out.println(sqlparser.getErrormessage());
097 *       }
098 *
099 * </code>
100 *
101 * <p> After paring SQL script, all parse tree nodes are available for use, some of use cases
102 * are:
103 * <ul>
104 *     <li>Table/column impact analysis</li>
105 *     <li>SQL rewriting</li>
106 *     <li>SQL translate between different databases</li>
107 *     <li>SQL migration analysis</li>
108 *     <li>Help to anti SQL injection</li>
109 *     <li><a href="http://support.sqlparser.com/">More use cases</a></li>
110 *     </ul>
111 *
112 * <p>Typically, SQL parse tree nodes generated by this SQL Parser were closely related to SQL
113 * elements defined in database vendor's SQL reference book. here is a brief summary of some
114 * most used SQL elements and corresponding classes defined in this SQL parser.
115 * <ul>
116 *     <li>SQL identifier: {@link gudusoft.gsqlparser.nodes.TObjectName}</li>
117 *     <li>SQL literal: {@link gudusoft.gsqlparser.nodes.TConstant}</li>
118 *     <li>SQL datatype: {@link gudusoft.gsqlparser.nodes.TTypeName}</li>
119 *     <li>SQL function: {@link gudusoft.gsqlparser.nodes.TFunctionCall}</li>
120 *     <li>SQL constraint: {@link gudusoft.gsqlparser.nodes.TConstraint}</li>
121 *     <li>SQL expression/condition: {@link gudusoft.gsqlparser.nodes.TExpression}</li>
122 *     <li>SQL select list item: {@link gudusoft.gsqlparser.nodes.TResultColumn}</li>
123 *      <li>More: {@link gudusoft.gsqlparser.nodes}</li>
124 * </ul>
125 *
126 * <p> Some major SQL statements:
127 * <ul>
128 *      <li>Select: {@link gudusoft.gsqlparser.stmt.TSelectSqlStatement}</li>
129 *      <li>Delete: {@link gudusoft.gsqlparser.stmt.TDeleteSqlStatement}</li>
130 *      <li>Insert: {@link gudusoft.gsqlparser.stmt.TInsertSqlStatement}</li>
131 *      <li>Update: {@link gudusoft.gsqlparser.stmt.TUpdateSqlStatement}</li>
132 *      <li>Create table: {@link gudusoft.gsqlparser.stmt.TCreateTableSqlStatement}</li>
133 *      <li>More: {@link   gudusoft.gsqlparser.stmt}</li>
134 * </ul>
135 *
136 * <p>Stored procedure</p>
137 * <ul>
138 *     <li>Create function: {@link gudusoft.gsqlparser.stmt.db2.TDb2CreateFunction },
139 *          {@link gudusoft.gsqlparser.stmt.mssql.TMssqlCreateProcedure},
140 *          {@link gudusoft.gsqlparser.stmt.mysql.TMySQLCreateFunction},
141 *          {@link gudusoft.gsqlparser.stmt.oracle.TPlsqlCreateFunction}</li>
142 *     <li>Create procedure: {@link gudusoft.gsqlparser.stmt.db2.TDb2CreateProcedure},
143 *          {@link gudusoft.gsqlparser.stmt.mssql.TMssqlCreateProcedure},
144 *          {@link gudusoft.gsqlparser.stmt.mysql.TMySQLCreateProcedure},
145 *          {@link gudusoft.gsqlparser.stmt.oracle.TPlsqlCreateProcedure}</li>
146 *     <li>Create trigger: {@link gudusoft.gsqlparser.stmt.TCreateTriggerStmt},
147 *          {@link gudusoft.gsqlparser.stmt.oracle.TPlsqlCreateTrigger}</li>
148 *     <li>Create package: {@link gudusoft.gsqlparser.stmt.oracle.TPlsqlCreatePackage}</li>
149 * </ul>
150 *
151 * For all available SQL parse tree node classes, please check the API reference.
152 *
153 *
154 */
155public class TGSqlParser {
156
157
158
159
160    public void setSqlCharset(String sqlCharset) {
161        this.sqlCharset = sqlCharset;
162    }
163
164    public String getSqlCharset() {
165        return sqlCharset;
166    }
167
168    private String sqlCharset = null;
169
170    public static EDbVendor currentDBVendor = EDbVendor.dbvoracle;
171
172
173    /**
174     * Turn the string name of database to dbvendor
175     * <ul>
176     *     <li>access: EDbVendor.dbvccess</li>
177     *     <li>ansi: EDbVendor.dbvansi</li>
178     *     <li>bigquery: EDbVendor.dbvbigquery</li>
179     *     <li>couchbase: EDbVendor.dbvcouchbase</li>
180     *     <li>dax: EDbVendor.dbvdax</li>
181     *     <li>db2: EDbVendor.dbvdb2</li>
182     *     <li>firebird: EDbVendor.dbvfirebird</li>
183     *     <li>generic: EDbVendor.dbvgeneric</li>
184     *     <li>greenplum: EDbVendor.dbvgreenplum</li>
185     *     <li>hana: EDbVendor.dbvhana</li>
186     *     <li>hive: EDbVendor.dbvhive</li>
187     *     <li>impala: EDbVendor.dbvimpala</li>
188     *     <li>informix: EDbVendor.dbvinformix</li>
189     *     <li>mdx: EDbVendor.dbvmdx</li>
190     *     <li>mssql or sqlserver: EDbVendor.dbvmssql</li>
191     *     <li>mysql: EDbVendor.dbvmysql</li>
192     *     <li>netezza: EDbVendor.dbvnetezza</li>
193     *     <li>odbc: EDbVendor.dbvodbc</li>
194     *     <li>openedge: EDbVendor.dbvopenedge</li>
195     *     <li>oracle: EDbVendor.dbvoracle</li>
196     *     <li>postgresql or postgres: EDbVendor.dbvpostgresql</li>
197     *     <li>redshift: EDbVendor.dbvredshift</li>
198     *     <li>snowflake: EDbVendor.dbvsnowflake</li>
199     *     <li>sybase: EDbVendor.dbvsybase</li>
200     *     <li>teradata: EDbVendor.dbvteradata</li>
201     *     <li>vertica: EDbVendor.dbvvertica</li>
202     * </ul>
203     * @param dbVendorName
204     * @return dbvendor
205     */
206    public static EDbVendor getDBVendorByName(String dbVendorName){
207        return  EDbVendor.valueOfWithDefault(dbVendorName);
208    }
209
210//    public void  teradataCmds(){
211//       // int cnt = 0;
212//        //((TLexerTeradata)getFlexer()).
213////         for(int i=0;i<TLexerTeradata.bteqCmdList.size();i++){
214////             for(int j=0;j<TLexerTeradata.multiLoadCmdList.size();j++){
215////                 if (TLexerTeradata.bteqCmdList.get(i).toString().equalsIgnoreCase(TLexerTeradata.multiLoadCmdList.get(j).toString())){
216////                   System.out.println("multiLoad: "+TLexerTeradata.bteqCmdList.get(i).toString());
217////                 }
218////             }
219////             for(int j=0;j<TLexerTeradata.fastExportCmdList.size();j++){
220////                 if (TLexerTeradata.bteqCmdList.get(i).toString().equalsIgnoreCase(TLexerTeradata.fastExportCmdList.get(j).toString())){
221////                     System.out.println("fastExport: "+TLexerTeradata.bteqCmdList.get(i).toString());
222////                 }
223////             }
224////             for(int j=0;j<TLexerTeradata.fastLoadCmdList.size();j++){
225////                 if (TLexerTeradata.bteqCmdList.get(i).toString().equalsIgnoreCase(TLexerTeradata.fastLoadCmdList.get(j).toString())){
226////                     System.out.println("FastLoad: "+TLexerTeradata.bteqCmdList.get(i).toString());
227////                 }
228////             }
229////         } //bteqCmdList
230//
231////        for(int i=0;i<TLexerTeradata.fastLoadCmdList.size();i++){
232////            for(int j=0;j<TLexerTeradata.multiLoadCmdList.size();j++){
233////                if (TLexerTeradata.fastLoadCmdList.get(i).toString().equalsIgnoreCase(TLexerTeradata.multiLoadCmdList.get(j).toString())){
234////                    System.out.println("multiLoad: "+TLexerTeradata.fastLoadCmdList.get(i).toString());
235////                }
236////            }
237////            for(int j=0;j<TLexerTeradata.fastExportCmdList.size();j++){
238////                if (TLexerTeradata.fastLoadCmdList.get(i).toString().equalsIgnoreCase(TLexerTeradata.fastExportCmdList.get(j).toString())){
239////                    System.out.println("fastExport: "+TLexerTeradata.fastLoadCmdList.get(i).toString());
240////                }
241////            }
242////
243////        }
244//
245//    }
246
247    private Stack<TFrame> frameStack = null;
248
249    public Stack<TFrame> getFrameStack(){
250        if (frameStack == null){
251            frameStack = new Stack<TFrame>();
252        }
253
254        return  frameStack;
255    }
256
257    public void setFrameStack(Stack<TFrame> frameStack) {
258        this.frameStack = frameStack;
259    }
260
261    void closeFileStream(){
262        if (streamFromSqlFile != null) {
263            try {
264                streamFromSqlFile.close();
265            } catch (IOException e) {
266                e.printStackTrace();
267            }
268        }
269    }
270
271    FileInputStream streamFromSqlFile = null;
272    InputStreamReader sqlStreamReader = null;
273    /**
274     * A sequence of source tokens created by the lexer after tokenize the input SQL
275     *
276     * @return a sequence of source tokens
277     */
278    public TSourceTokenList getSourcetokenlist() {
279        return sourcetokenlist;
280    }
281
282    /**
283     * A list of SQL statements created by the parser.
284     * If this list is created after calling the {@link #getrawsqlstatements} method, the syntax of each SQL statement
285     * is not checked and the parse tree of each statement is not created. If the {@link #parse} method is called to build
286     * this SQL statement list, then every thing is ready.
287     *
288     * @return a list of SQL statement
289     */
290    public TStatementList getSqlstatements() {
291        return sqlstatements;
292    }
293
294    enum stored_procedure_status {start,is_as,body,bodyend,end, cursor_declare};
295    enum stored_procedure_type {function,procedure,package_spec,package_body, block_with_begin,block_with_declare,
296        create_trigger,create_library,cursor_in_package_spec,others};
297
298    static final int stored_procedure_nested_level = 1024;
299
300    /**
301    ** The input SQL Text.
302    ** If {@link #sqlfilename} is specified, then this field will be ignored.
303    */
304    public String sqltext;
305
306    /**
307     * set the input SQL text, If {@link #sqlfilename} is specified before this method, the parser will using
308     * the SQL text in this field instead of read SQL from {@link #sqlfilename}.
309     *
310     * @param sqltext the input SQL text
311     */
312    public void setSqltext(String sqltext) {
313        this.sqltext = sqltext;
314        this.sqlfilename = "";
315        this.sqlInputStream = null;
316    }
317
318    /**
319     *  The SQL text that being processed.
320     *
321     * @return the SQL text that being processed
322     */
323    public String getSqltext() {
324        return sqltext;
325    }
326
327
328    /**
329    ** The input SQL will be read from this file
330     *
331    ** If field is specified, then {@link #sqltext} will be ignored.
332     * This must be the full path to the file, relative path doesn't work.
333    */
334    public String sqlfilename;
335
336
337    /**
338     * set the filename from which the input SQL will be read.
339     *
340     * @param sqlfilename the SQL file name from which the input SQL will be read
341     */
342    public void setSqlfilename(String sqlfilename) {
343        this.sqlfilename = sqlfilename;
344        this.sqltext = "";
345        this.sqlInputStream = null;
346    }
347
348    /**
349     * The input SQL filename. This parser can process the unicode encoded SQL file.
350     *
351     * @return the input SQL filename
352     */
353    public String getSqlfilename() {
354        return sqlfilename;
355    }
356
357    /**
358     * set the InputStream from which SQL will be read.
359     * If this method is called, {@link #sqlfilename} and {@link #sqltext} will be ignored.
360     *
361     * @param sqlInputStream the InputStream from which SQL will be read
362     */
363    public void setSqlInputStream(InputStream sqlInputStream) {
364        if (sqlInputStream instanceof BufferedInputStream){
365            this.sqlInputStream = (BufferedInputStream)sqlInputStream;
366        }else{
367            this.sqlInputStream = new BufferedInputStream(sqlInputStream);
368        }
369
370        this.sqlfilename = "";
371        this.sqltext = "";
372    }
373
374    private BufferedInputStream  sqlInputStream;
375
376    /**
377     *  the InputStream from which SQL will be read
378     * @return the InputStream from which SQL will be read
379     */
380    public InputStream getSqlInputStream() {
381        return sqlInputStream;
382    }
383
384    /**
385    ** Tokens generated by lexer from the input SQL script.
386     * Tokens are always available even if there are syntax errors in input the SQL script.
387    */
388    public TSourceTokenList sourcetokenlist;
389
390    /**
391    ** SQL statements generated by this parser from the input SQL script.
392     * statements are always available even if there are syntax errors in input SQL script.
393     * if there is no syntax error in a statement, you can access the parse tree of the statement to fetch more information
394     * such as tables, columns, etc.
395    */
396    public TStatementList sqlstatements;
397
398
399    /**
400     * The array of syntax error generated by the parser during checking the syntax of the input SQL,
401     * element of this list is type of {@link TSyntaxError}
402     *
403     * @return the array of errors
404     */
405    public ArrayList <TSyntaxError> getSyntaxErrors() {
406        return syntaxErrors;
407    }
408
409    private ArrayList <TSyntaxError> syntaxErrors;
410
411//    public ArrayList<TSyntaxError> getSyntaxHints() {
412//        return syntaxHints;
413//    }
414
415    //private ArrayList <TSyntaxError> syntaxHints;
416
417    /**
418     * The database vendor specified when creating this parser.
419     * The grammar rule of this database vendor will be used to validate the syntax of the input SQL.
420     *
421     * @return the database vendor
422     */
423    public EDbVendor getDbVendor() {
424        return dbVendor;
425    }
426
427    /**
428     * @deprecated As of v1.4.3.4
429     * enable GSP to parse the rest of sql statements inside stored procedure
430     * when a SQL statement in the stored procedure cannot be parsed
431     *
432     * <p>Available to parse sybase stored procedure currently.
433     *
434     * @param enablePartialParsing set true to enable this partial parsing, default is false
435     */
436    public void setEnablePartialParsing(boolean enablePartialParsing) {
437        this.enablePartialParsing = enablePartialParsing;
438    }
439
440    /**
441     * enable GSP to parse the rest of sql statements inside stored procedure
442     * when a SQL statement in the stored procedure cannot be parsed
443     *
444     * <p>Available to parse sybase stored procedure currently.
445     *
446     * <p> default is false;
447     *
448     *  @deprecated As of v1.4.3.4
449     */
450    private boolean isEnablePartialParsing() {
451
452        return enablePartialParsing;
453    }
454
455    private boolean enablePartialParsing = false;
456
457    private static String userName;
458    private static String machineId = null;
459    private static String licenseKey;
460    private static String licenseType;
461    private static boolean licenseOK = false;
462    private static String licenseMessage;
463
464    /**
465     * Not used.
466     *
467     * @return the user name
468     */
469    public static String getUserName() {
470        return userName;
471    }
472
473    /**
474     * Not used.
475     *
476     * @return the machine id
477     */
478    public static String getMachineId() {
479
480        return machineId;
481    }
482
483    /**
484     * Not used.
485     *
486     * @return the license message
487     */
488    public static String getLicenseMessage() {
489        return licenseMessage;
490    }
491
492
493    static {
494        licenseOK = validateLicense();
495    }
496
497    /**
498     * Not used.
499     *
500     * @return trial license or developer license or distribution license
501     */
502    public static String getLicenseType() {
503        return licenseType;
504    }
505
506    private EDbVendor dbVendor;
507    private String errormessage;
508
509    /**
510     * The lexer which is used to tokenize the input SQL.
511     *
512     * @return the lexer
513     */
514    public TCustomLexer getFlexer() {
515        return flexer;
516    }
517
518    private TCustomLexer flexer;
519    TCustomParser fparser,fplsqlparser;
520    BufferedReader finputstream = null; //used by lexer
521    TCustomSqlStatement gcurrentsqlstatement,nextStmt;
522    TSqlCmds sqlcmds;
523
524    HashMap sqlpluskeywordList;
525
526    char delimiterchar;
527    String defaultDelimiterStr;
528
529    private ISQLStatementHandle sqlStatementHandle = null;
530
531    public void setSqlStatementHandle(ISQLStatementHandle sqlStatementHandle) {
532        this.sqlStatementHandle = sqlStatementHandle;
533    }
534
535    private ITokenHandle tokenHandle = null;
536
537    /**
538     * Set an event handler which will be fired when a new source token is created by the lexer during tokenize the
539     * input SQL.
540     *
541     * @param tokenHandle the event handler to process the new created source token
542     */
543    public void setTokenHandle(ITokenHandle tokenHandle) {
544        this.tokenHandle = tokenHandle;
545    }
546
547    private ITokenListHandle tokenListHandle = null;
548
549    public void setTokenListHandle(ITokenListHandle tokenListHandle) {
550        this.tokenListHandle = tokenListHandle;
551    }
552
553    private IMetaDatabase metaDatabase = null;
554
555    /**
556     * @deprecated As of v2.0.3.1, please use {@link #getSqlEnv()} instead
557     *
558     *  set an instance of a class which implement the interface: {@link IMetaDatabase}.
559     *  The parser will call {@link IMetaDatabase#checkColumn} method when it needs to know
560     *  whether a column is belonged to a table.
561     *  <p></p>
562     *  The class that implements the interface: {@link IMetaDatabase} usually fetch the metadata from the database
563     *  by connecting to a database instance.
564     *  <p></p>
565     *  If the class is not provided, the parser has to guess the relationship between a un-qualified column and table
566     *  in the input SQL which may lead to a un-determined result between the column and table.
567     *
568     * @param metaDatabase a new instance of the class which implements the {@link IMetaDatabase} interface
569     * @see IMetaDatabase
570     */
571    public void setMetaDatabase(IMetaDatabase metaDatabase) {
572        this.metaDatabase = metaDatabase;
573    }
574
575    /**
576     * @deprecated As of v2.0.3.1, please use {@link #getSqlEnv()} instead
577     *
578     * a new instance of the class which implements the {@link IMetaDatabase} interface
579     *
580     * @return a new instance of the class which implements the {@link IMetaDatabase} interface
581     * @see #setMetaDatabase
582     */
583    public IMetaDatabase getMetaDatabase() {
584
585        return metaDatabase;
586    }
587
588    /**
589     * Not used.
590     *
591     */
592    public void freeParseTable() {
593        flexer.yystack = null;
594        flexer.yytextbuf = null;
595        flexer.buf = null;
596
597//        TLexerOracle.yyk = null;
598//        TLexerOracle.yykl = null;
599//        TLexerOracle.yykh = null;
600//        TLexerOracle.yym = null;
601//        TLexerOracle.yyml = null;
602//        TLexerOracle.yymh = null;
603//        TLexerOracle.yyt = null;
604//        TLexerOracle.yytl = null;
605//        TLexerOracle.yyth = null;
606//        TParserOracleSql.yyah = null;
607//        TParserOracleSql.yyal = null;
608//        TParserOracleSql.yygh = null;
609//        TParserOracleSql.yygl = null;
610//        TParserOracleSql.yyd = null;
611//        TParserOracleSql.yya_sym= null;
612//        TParserOracleSql.yya_act= null;
613//        TParserOracleSql.yyr_len= null;
614//        TParserOracleSql.yyr_sym= null;
615//        TParserOracleSql.yyg_sym= null;
616//        TParserOracleSql.yyg_act= null;
617//
618//        TParserOraclePLSql.yyah = null;
619//        TParserOraclePLSql.yyal = null;
620//        TParserOraclePLSql.yygh = null;
621//        TParserOraclePLSql.yygl = null;
622//        TParserOraclePLSql.yyd = null;
623//        TParserOraclePLSql.yya_sym= null;
624//        TParserOraclePLSql.yya_act= null;
625//        TParserOraclePLSql.yyr_len= null;
626//        TParserOraclePLSql.yyr_sym= null;
627//        TParserOraclePLSql.yyg_sym= null;
628//        TParserOraclePLSql.yyg_act= null;
629//
630//        TLexerMssql.yyk = null;
631//        TLexerMssql.yykl = null;
632//        TLexerMssql.yykh = null;
633//        TLexerMssql.yym = null;
634//        TLexerMssql.yyml = null;
635//        TLexerMssql.yymh = null;
636//        TLexerMssql.yyt = null;
637//        TLexerMssql.yytl = null;
638//        TLexerMssql.yyth = null;
639//        TParserMssqlSql.yyah = null;
640//        TParserMssqlSql.yyal = null;
641//        TParserMssqlSql.yygh = null;
642//        TParserMssqlSql.yygl = null;
643//        TParserMssqlSql.yyd = null;
644//        TParserMssqlSql.yya_sym= null;
645//        TParserMssqlSql.yya_act= null;
646//        TParserMssqlSql.yyr_len= null;
647//        TParserMssqlSql.yyr_sym= null;
648//        TParserMssqlSql.yyg_sym= null;
649//        TParserMssqlSql.yyg_act= null;
650//
651//        TLexerMysql.yyk = null;
652//        TLexerMysql.yykl = null;
653//        TLexerMysql.yykh = null;
654//        TLexerMysql.yym = null;
655//        TLexerMysql.yyml = null;
656//        TLexerMysql.yymh = null;
657//        TLexerMysql.yyt = null;
658//        TLexerMysql.yytl = null;
659//        TLexerMysql.yyth = null;
660//        TParserMysqlSql.yyah = null;
661//        TParserMysqlSql.yyal = null;
662//        TParserMysqlSql.yygh = null;
663//        TParserMysqlSql.yygl = null;
664//        TParserMysqlSql.yyd = null;
665//        TParserMysqlSql.yya_sym= null;
666//        TParserMysqlSql.yya_act= null;
667//        TParserMysqlSql.yyr_len= null;
668//        TParserMysqlSql.yyr_sym= null;
669//        TParserMysqlSql.yyg_sym= null;
670//        TParserMysqlSql.yyg_act= null;
671    }
672
673    /**
674     *  Class constructor, create a new instance of the parser by setting the database vendor
675     *
676     * @param pdbvendor the database vendor whose grammar rule will be used to validate the syntax of the input SQL
677     */
678    public TGSqlParser(EDbVendor pdbvendor) {
679        dbVendor = pdbvendor;
680        sqltext = "";
681        sqlfilename = "";
682
683        delimiterchar = ';';
684        defaultDelimiterStr = ";";
685        switch(pdbvendor){
686            case dbvmssql :
687            case dbvaccess:
688            case dbvazuresql:
689            {
690                if (TBaseType.enterprise_edition ||(!TBaseType.full_edition) ||TBaseType.sqlserver_edition||TBaseType.azuresql_edition){
691                    flexer = new TLexerMssql();
692                    flexer.delimiterchar = delimiterchar;
693                    flexer.defaultDelimiterStr = defaultDelimiterStr;
694                    fparser = new TParserMssqlSql(null);
695                    fparser.lexer = flexer;
696                }
697                if (pdbvendor == EDbVendor.dbvazuresql){
698                    dbVendor = EDbVendor.dbvmssql;
699                }
700                break;
701            }
702            case dbvsybase:{
703                if (TBaseType.enterprise_edition ||(!TBaseType.full_edition) ||TBaseType.sybase_edition){
704                    flexer = new TLexerSybase();
705                    flexer.delimiterchar = delimiterchar;
706                    flexer.defaultDelimiterStr = defaultDelimiterStr;
707                    fparser = new TParserSybase(null);
708                    fparser.lexer = flexer;
709                }
710                enablePartialParsing = false;
711                break;
712            }
713            case dbvinformix:{
714                if (TBaseType.enterprise_edition ||(!TBaseType.full_edition) ||TBaseType.informix_edition){
715                    flexer = new TLexerInformix();
716                    flexer.delimiterchar = delimiterchar;
717                    flexer.defaultDelimiterStr = defaultDelimiterStr;
718                    fparser = new TParserInformix(null);
719                    fparser.lexer = flexer;
720                }
721                enablePartialParsing = false;
722                break;
723            }
724            case dbvoracle :{
725                if (TBaseType.enterprise_edition ||(!TBaseType.full_edition) ||TBaseType.oracle_edition){
726                    delimiterchar = '/';
727                    flexer = new TLexerOracle();
728                    flexer.delimiterchar = delimiterchar;
729                    flexer.defaultDelimiterStr = defaultDelimiterStr;
730                    fparser = new TParserOracleSql(null);
731                    fplsqlparser = new TParserOraclePLSql(null);
732                    fparser.lexer = flexer;
733                    fplsqlparser.lexer = flexer;
734                    fplsqlparser.getNf().setGsqlParser(this);
735                }
736                break;
737            }
738//            case dbvaccess :{
739//                if (TBaseType.enterprise_edition ||(!TBaseType.full_edition) ||TBaseType.sqlserver_edition){
740//                    flexer = new TLexerAccess();
741//                    flexer.delimiterchar = delimiterchar;
742//                    flexer.defaultDelimiterStr = defaultDelimiterStr;
743//                    fparser = new TParserAccessSql(null);
744//                    fparser.lexer = flexer;
745//                }
746//                break;
747//            }
748            case dbvdb2 :{
749                if (TBaseType.enterprise_edition ||(!TBaseType.full_edition) ||TBaseType.db2_edition){
750                    delimiterchar = '@';
751                    flexer = new TLexerDb2();
752                    flexer.delimiterchar = delimiterchar;
753                    flexer.defaultDelimiterStr = defaultDelimiterStr;
754                    fparser = new TParserDb2Sql(null);
755                    fparser.lexer = flexer;
756                }
757                break;
758            }
759            case dbvmysql :{
760                if (TBaseType.enterprise_edition ||(!TBaseType.full_edition) ||TBaseType.mysql_edition){
761                    delimiterchar = '$';
762                    defaultDelimiterStr = "$";
763                    flexer = new TLexerMysql();
764                    flexer.delimiterchar = delimiterchar;
765                    flexer.defaultDelimiterStr = defaultDelimiterStr;
766                    fparser = new TParserMysqlSql(null);
767                    fparser.lexer = flexer;
768                }
769                break;
770            }
771            case dbvteradata :{
772                if (TBaseType.enterprise_edition ||(!TBaseType.full_edition) ||TBaseType.teradata_edition){
773                    delimiterchar = '/';
774                    flexer = new TLexerTeradata();
775                    flexer.delimiterchar = delimiterchar;
776                    flexer.defaultDelimiterStr = defaultDelimiterStr;
777                    fparser = new TParserTeradata(null);
778                    fparser.lexer = flexer;
779                }
780                break;
781            }
782            case dbvpostgresql:{
783                if (TBaseType.enterprise_edition ||(!TBaseType.full_edition) ||TBaseType.postgresql_edition){
784                    delimiterchar = '/';
785                    flexer = new TLexerPostgresql();
786                    flexer.delimiterchar = delimiterchar;
787                    flexer.defaultDelimiterStr = defaultDelimiterStr;
788                    fparser = new TParserPostgresql(null);
789                    fparser.lexer = flexer;
790                }
791                break;
792            }
793            case dbvredshift:{
794                if (TBaseType.enterprise_edition ||(!TBaseType.full_edition) ||TBaseType.redshift_edition){
795                    delimiterchar = '/';
796                    flexer = new TLexerRedshift();
797                    flexer.delimiterchar = delimiterchar;
798                    flexer.defaultDelimiterStr = defaultDelimiterStr;
799                    fparser = new TParserRedshift(null);
800                    fparser.lexer = flexer;
801                }
802                break;
803            }
804            case dbvgreenplum:{
805                if (TBaseType.enterprise_edition ||(!TBaseType.full_edition) ||TBaseType.greenplum_edition){
806                    delimiterchar = '/';
807                    flexer = new TLexerGreenplum();
808                    flexer.delimiterchar = delimiterchar;
809                    flexer.defaultDelimiterStr = defaultDelimiterStr;
810                    fparser = new TParserGreenplum(null);
811                    fparser.lexer = flexer;
812                }
813                break;
814            }
815            case dbvmdx:{
816                if (TBaseType.enterprise_edition ||(!TBaseType.full_edition) ||TBaseType.mdx_edition){
817                    delimiterchar = ';';
818                    flexer = new TLexerMdx();
819                    flexer.delimiterchar = delimiterchar;
820                    flexer.defaultDelimiterStr = defaultDelimiterStr;
821                    fparser = new TParserMdx(null);
822                    fparser.lexer = flexer;
823                }
824                break;
825            }
826            case dbvnetezza:{
827                if (TBaseType.enterprise_edition ||(!TBaseType.full_edition) ||TBaseType.netezza_edition){
828                    delimiterchar = ';';
829                    flexer = new TLexerNetezza();
830                    flexer.delimiterchar = delimiterchar;
831                    flexer.defaultDelimiterStr = defaultDelimiterStr;
832                    fparser = new TParserNetezza(null);
833                    fparser.lexer = flexer;
834                }
835                break;
836            }
837            case dbvhive:{
838                if (TBaseType.enterprise_edition ||(!TBaseType.full_edition) ||TBaseType.hive_edition){
839                    delimiterchar = ';';
840                    flexer = new TLexerHive();
841                    flexer.delimiterchar = delimiterchar;
842                    flexer.defaultDelimiterStr = defaultDelimiterStr;
843                    fparser = new TParserHive(null);
844                    fparser.lexer = flexer;
845                }
846                break;
847            }
848            case dbvimpala:{
849                if (TBaseType.enterprise_edition ||(!TBaseType.full_edition) ||TBaseType.impala_edition){
850                    delimiterchar = ';';
851                    flexer = new TLexerImpala();
852                    flexer.delimiterchar = delimiterchar;
853                    flexer.defaultDelimiterStr = defaultDelimiterStr;
854                    fparser = new TParserImpala(null);
855                    fparser.lexer = flexer;
856                }
857                break;
858            }
859            case dbvhana:{
860                if (TBaseType.enterprise_edition ||(!TBaseType.full_edition) ||TBaseType.hana_edition){
861                    delimiterchar = ';';
862                    flexer = new TLexerHana();
863                    flexer.delimiterchar = delimiterchar;
864                    flexer.defaultDelimiterStr = defaultDelimiterStr;
865                    fparser = new TParserHana(null);
866                    fparser.lexer = flexer;
867                }
868                break;
869            }
870            case dbvdax:{
871                if (TBaseType.enterprise_edition ||(!TBaseType.full_edition) ||TBaseType.dax_edition){
872                    delimiterchar = ';';
873                    flexer = new TLexerDax();
874                    flexer.delimiterchar = delimiterchar;
875                    flexer.defaultDelimiterStr = defaultDelimiterStr;
876                    fparser = new TParserDax(null);
877                    fparser.lexer = flexer;
878                }
879                break;
880            }
881            case dbvodbc:{
882                if (TBaseType.enterprise_edition ||(!TBaseType.full_edition) ||TBaseType.odbc_edition){
883                    delimiterchar = ';';
884                    flexer = new TLexerOdbc();
885                    flexer.delimiterchar = delimiterchar;
886                    flexer.defaultDelimiterStr = defaultDelimiterStr;
887                    fparser = new TParserOdbc(null);
888                    fparser.lexer = flexer;
889                }
890                break;
891            }
892            case dbvvertica:{
893                if (TBaseType.enterprise_edition ||(!TBaseType.full_edition) ||TBaseType.vertica_edition){
894                    delimiterchar = ';';
895                    flexer = new TLexerVertica();
896                    flexer.delimiterchar = delimiterchar;
897                    flexer.defaultDelimiterStr = defaultDelimiterStr;
898                    fparser = new TParserVertica(null);
899                    fparser.lexer = flexer;
900                }
901                break;
902            }
903            case dbvopenedge:{
904                if (TBaseType.enterprise_edition ||(!TBaseType.full_edition) ||TBaseType.openedge_edition){
905                    delimiterchar = ';';
906                    flexer = new TLexerOpenedge();
907                    flexer.delimiterchar = delimiterchar;
908                    flexer.defaultDelimiterStr = defaultDelimiterStr;
909                    fparser = new TParserOpenedge(null);
910                    fparser.lexer = flexer;
911                }
912                break;
913            }
914            case dbvcouchbase:{
915                if (TBaseType.enterprise_edition ||(!TBaseType.full_edition) ||TBaseType.couchbase_edition){
916                    delimiterchar = ';';
917                    flexer = new TLexerCouchbase();
918                    flexer.delimiterchar = delimiterchar;
919                    flexer.defaultDelimiterStr = defaultDelimiterStr;
920                    fparser = new TParserCouchbase(null);
921                    fparser.lexer = flexer;
922                }
923                break;
924            }
925            case dbvsnowflake:{
926                if (TBaseType.enterprise_edition ||(!TBaseType.full_edition) ||TBaseType.snowflake_edition){
927                    delimiterchar = ';';
928                    flexer = new TLexerSnowflake();
929                    flexer.delimiterchar = delimiterchar;
930                    flexer.defaultDelimiterStr = defaultDelimiterStr;
931                    fparser = new TParserSnowflake(null);
932                    fparser.lexer = flexer;
933                }
934                break;
935            }
936            case dbvbigquery:{
937                if (TBaseType.enterprise_edition ||(!TBaseType.full_edition) ||TBaseType.bigquery_edition){
938                    delimiterchar = ';';
939                    flexer = new TLexerBigquery();
940                    flexer.delimiterchar = delimiterchar;
941                    flexer.defaultDelimiterStr = defaultDelimiterStr;
942                    fparser = new TParserBigquery(null);
943                    fparser.lexer = flexer;
944                }
945                break;
946            }
947            case dbvansi:
948                if (TBaseType.enterprise_edition ||(!TBaseType.full_edition) ||TBaseType.ansi_edition){
949                    delimiterchar = ';';
950                    flexer = new TLexerAnsi();
951                    flexer.delimiterchar = delimiterchar;
952                    flexer.defaultDelimiterStr = defaultDelimiterStr;
953                    fparser = new TParserAnsi(null);
954                    fparser.lexer = flexer;
955                }
956                break;
957            case dbvgeneric: {
958                if (TBaseType.enterprise_edition || (!TBaseType.full_edition) || TBaseType.generic_edition) {
959                    flexer = new TLexerMssql();
960                    flexer.delimiterchar = delimiterchar;
961                    flexer.defaultDelimiterStr = defaultDelimiterStr;
962                    fparser = new TParserMssqlSql(null);
963                    fparser.lexer = flexer;
964                }
965                break;
966            }
967            case dbvsoql:{
968                if (TBaseType.enterprise_edition ||(!TBaseType.full_edition) ||TBaseType.soql_edition){
969                    delimiterchar = ';';
970                    flexer = new TLexerSoql();
971                    flexer.delimiterchar = delimiterchar;
972                    flexer.defaultDelimiterStr = defaultDelimiterStr;
973                    fparser = new TParserSoql(null);
974                    fparser.lexer = flexer;
975                }
976                break;
977            }
978            case dbvsparksql:{
979                if (TBaseType.enterprise_edition ||(!TBaseType.full_edition) ||TBaseType.sparksql_edition){
980                    delimiterchar = ';';
981                    flexer = new TLexerSparksql();
982                    flexer.delimiterchar = delimiterchar;
983                    flexer.defaultDelimiterStr = defaultDelimiterStr;
984                    fparser = new TParserSparksql(null);
985                    fparser.lexer = flexer;
986                }
987                break;
988            }
989            case dbvathena:
990                {
991                if (TBaseType.enterprise_edition ||(!TBaseType.full_edition) ||TBaseType.athena_edition){
992                    delimiterchar = ';';
993                    flexer = new TLexerathena();
994                    flexer.delimiterchar = delimiterchar;
995                    flexer.defaultDelimiterStr = defaultDelimiterStr;
996                    fparser = new TParserAthena(null);
997                    fparser.lexer = flexer;
998                }
999                break;
1000            }
1001            case dbvpresto:
1002            {
1003                if (TBaseType.enterprise_edition ||(!TBaseType.full_edition) ||TBaseType.presto_edition){
1004                    delimiterchar = ';';
1005                    flexer = new TLexerPresto();
1006                    flexer.delimiterchar = delimiterchar;
1007                    flexer.defaultDelimiterStr = defaultDelimiterStr;
1008                    fparser = new TParserPresto(null);
1009                    fparser.lexer = flexer;
1010                }
1011                break;
1012            }
1013            case dbvtrino:
1014            {
1015                if (TBaseType.enterprise_edition ||(!TBaseType.full_edition) ||TBaseType.trino_edition){
1016                    delimiterchar = ';';
1017                    flexer = new TLexerPresto();
1018                    flexer.delimiterchar = delimiterchar;
1019                    flexer.defaultDelimiterStr = defaultDelimiterStr;
1020                    fparser = new TParserPresto(null);
1021                    fparser.lexer = flexer;
1022                }
1023                break;
1024            }
1025            case dbvdatabricks:
1026            {
1027                if (TBaseType.enterprise_edition ||(!TBaseType.full_edition) ||TBaseType.databricks_edition){
1028                    delimiterchar = ';';
1029                    flexer = new TLexerDatabricks();
1030                    flexer.delimiterchar = delimiterchar;
1031                    flexer.defaultDelimiterStr = defaultDelimiterStr;
1032                    fparser = new TParserDatabricks(null);
1033                    fparser.lexer = flexer;
1034                }
1035                break;
1036            }
1037            case dbvgaussdb:
1038            {
1039                if (TBaseType.enterprise_edition ||(!TBaseType.full_edition) ||TBaseType.gaussdb_edition){
1040                    delimiterchar = ';';
1041                    flexer = new TLexerGaussDB();
1042                    flexer.delimiterchar = delimiterchar;
1043                    flexer.defaultDelimiterStr = defaultDelimiterStr;
1044                    fparser = new TParserGaussDB(null);
1045                    fparser.lexer = flexer;
1046                   // fplsqlparser = new TParserOraclePLSql(null);
1047                   // fplsqlparser.lexer = new TLexerOracle();// must use oracle lexer, not gauss lexer
1048                }
1049                break;
1050            }
1051            default:  {
1052                if (TBaseType.enterprise_edition ||(!TBaseType.full_edition) ||TBaseType.sqlserver_edition){
1053                    flexer = new TLexerMssql();
1054                    flexer.delimiterchar = delimiterchar;
1055                    flexer.defaultDelimiterStr = defaultDelimiterStr;
1056                    fparser = new TParserMssqlSql(null);
1057                    fparser.lexer = flexer;
1058                }
1059                break;
1060            }
1061        }
1062
1063        fparser.getNf().setGsqlParser(this);
1064
1065        sourcetokenlist = new TSourceTokenList();
1066        sourcetokenlist.setGsqlparser(this);
1067        sqlstatements = new TStatementList();
1068        sqlcmds = new TSqlCmds() ;
1069        sqlpluskeywordList = new HashMap();
1070        syntaxErrors = new ArrayList();
1071        //syntaxHints = new ArrayList();
1072
1073
1074        errormessage = "";
1075
1076        if (TBaseType.license_expired_check){
1077            if (!check_license_time()) {
1078                flexer = null;
1079                fparser = null;
1080               // System.out.println("license is expired");
1081            }
1082        }
1083
1084        TGSqlParser.currentDBVendor = dbVendor;
1085    }
1086
1087    TContext globalContext;
1088
1089//     public TExpression parseExpression(String expr){
1090//        sqltext = "select"+TBaseType.newline+expr+TBaseType.newline+"from t";
1091//        int iRet = doparse();
1092//        if (iRet!= 0) {
1093//            for (int i= 0; i< syntaxErrors.size(); i++)
1094//            {
1095//                TSyntaxError t = (TSyntaxError) syntaxErrors.get(i);
1096//                t.lineNo--;
1097//            }
1098//
1099//            return null;
1100//        }
1101//        return ((TSelectSqlStatement)sqlstatements.get(0)).getResultColumnList().getResultColumn(0).getExpr();
1102//    }
1103
1104    /**
1105     * Create a select statement object from the parameter: subquery
1106     *
1107     * @param subquery a plain text select statement which need to be converted to a {@link gudusoft.gsqlparser.stmt.TSelectSqlStatement} object
1108     * @return a select statement object, return null if the input select string is syntax invalid.
1109     */
1110    public TSelectSqlStatement parseSubquery(String subquery){
1111        return parseSubquery(this.dbVendor,subquery);
1112    }
1113
1114    public static TSelectSqlStatement parseSubquery(EDbVendor dbVendor, String subquery){
1115//        TGSqlParser localParser = new TGSqlParser(dbVendor);
1116//        localParser.sqltext = subquery;
1117//        int iRet = localParser.doparse();
1118//        if (iRet != 0) {
1119//            return null;
1120//        }
1121
1122        TSingletonParser singletonParser = TSingletonParser.getInstance();
1123        TStatementList statements = singletonParser.getStmts(dbVendor,subquery);
1124        if (statements.size() == 0) return null;
1125
1126        return (TSelectSqlStatement)statements.get(0);
1127    }
1128
1129    /**
1130     * Create an expression object from the parameter: expr
1131     *
1132     * @param expr a plain text expression which will be converted to {@link gudusoft.gsqlparser.nodes.TExpression} object
1133     * @return an expression object, return null if the input expression string is not syntax valid.
1134     */
1135    public TExpression parseExpression(String expr){
1136        return parseExpression(this.dbVendor,expr);
1137    }
1138    public static TExpression parseExpression(EDbVendor dbVendor, String expr){
1139        TSingletonParser singletonParser = TSingletonParser.getInstance();
1140        TStatementList statements = singletonParser.getStmts(dbVendor,"select 1 from t where "+TBaseType.newline+expr);
1141        if (statements.size() == 0) return null;
1142
1143//        TGSqlParser localParser = new TGSqlParser(dbVendor);
1144//        localParser.sqltext = "select 1 from t where "+TBaseType.newline+expr;
1145//        int iRet = localParser.doparse();
1146//        if (iRet != 0) {
1147//            return null;
1148//        }
1149
1150        return ((TSelectSqlStatement)statements.get(0)).getWhereClause().getCondition();
1151    }
1152
1153    /**
1154     *  Create a function object from the parameter: newFunction
1155     *
1156     * @param newFunction a plain text function which will be converted to {@link gudusoft.gsqlparser.nodes.TFunctionCall} object
1157     * @return a function object, or return null if the input string is not a valid function call.
1158     */
1159    public TFunctionCall parseFunctionCall(String newFunction){
1160        return parseFunctionCall(this.dbVendor,newFunction);
1161    }
1162
1163    public static TFunctionCall parseFunctionCall(EDbVendor dbVendor, String newFunction){
1164        TSingletonParser singletonParser = TSingletonParser.getInstance();
1165        TStatementList statements = singletonParser.getStmts(dbVendor,"select"+TBaseType.newline+newFunction+TBaseType.newline+"from t");
1166        if (statements.size() == 0) return null;
1167
1168
1169//        TGSqlParser localParser = new TGSqlParser(dbVendor);
1170//        localParser.sqltext = "select"+TBaseType.newline+newFunction+TBaseType.newline+"from t";
1171//        int iRet = localParser.doparse();
1172//        if (iRet!= 0) {
1173//            return null;
1174//        }
1175
1176        return statements.get(0).getResultColumnList().getResultColumn(0).getExpr().getFunctionCall();
1177    }
1178
1179    /**
1180     * Create a database objectName from the parameter: newObjectName
1181     *
1182     * @param newObjectName a plain text objectName which will be converted to {@link gudusoft.gsqlparser.nodes.TObjectName} object
1183     * @return a database objectName object, return null is the input string is not a valid objectName.
1184     */
1185    public TObjectName parseObjectName(String newObjectName){
1186        //return parseObjectName(this.dbVendor,newObjectName);
1187        return TObjectName.createObjectName(this.dbVendor,EDbObjectType.column,newObjectName);
1188    }
1189
1190
1191
1192    /**
1193     *
1194     * @param dbVendor
1195     * @param newObjectName
1196     * @return
1197     */
1198    public static TObjectName parseObjectName(EDbVendor dbVendor, String newObjectName){
1199
1200        TSingletonParser singletonParser = TSingletonParser.getInstance();
1201        TStatementList statements = singletonParser.getStmts(dbVendor,"select"+TBaseType.newline+newObjectName+TBaseType.newline+"from t");
1202        if (statements.size() == 0) return null;
1203        TExpression e = statements.get(0).getResultColumnList().getResultColumn(0).getExpr();
1204
1205//        TGSqlParser localParser = new TGSqlParser(dbVendor);
1206//        localParser.sqltext = "select"+TBaseType.newline+newObjectName+TBaseType.newline+"from t";
1207//        int iRet = localParser.doparse();
1208//        if (iRet!= 0) {
1209//            return null;
1210//        }
1211//        TExpression e = ((TSelectSqlStatement)localParser.sqlstatements.get(0)).getResultColumnList().getResultColumn(0).getExpr();
1212
1213        TObjectName lcResult = null;
1214        switch (e.getExpressionType()){
1215            case simple_object_name_t:
1216                lcResult = e.getObjectOperand();
1217                break;
1218            case simple_constant_t:
1219                lcResult = new TObjectName();
1220                lcResult.init(e.getConstantOperand().getValueToken());
1221                break;
1222            default:
1223                break;
1224        }
1225
1226        return lcResult;
1227    }
1228
1229    /**
1230     * Create an constant object from the parameter: newConstant
1231     *
1232     * @param newConstant a plian text constant which will be converted to {@link gudusoft.gsqlparser.nodes.TConstant} object
1233     * @return new constant object, returns null if the input is not a valid constant string.
1234     */
1235    public TConstant parseConstant(String newConstant){
1236        return parseConstant(this.dbVendor,newConstant);
1237    }
1238
1239    public static TConstant parseConstant(EDbVendor dbVendor, String newConstant){
1240//        TGSqlParser localParser = new TGSqlParser(dbVendor);
1241//        localParser.sqltext = "select"+TBaseType.newline+newConstant+TBaseType.newline+"from t";
1242//        int iRet = localParser.doparse();
1243//        if (iRet!= 0) {
1244//            return null;
1245//        }
1246
1247        TSingletonParser singletonParser = TSingletonParser.getInstance();
1248        TStatementList statements = singletonParser.getStmts(dbVendor,"select"+TBaseType.newline+newConstant+TBaseType.newline+"from t");
1249        if (statements.size() == 0) return null;
1250
1251        return statements.get(0).getResultColumnList().getResultColumn(0).getExpr().getConstantOperand();
1252    }
1253
1254
1255    /**
1256     * The total number of syntax errors founded in the input SQL script.
1257     * <br>Only the first syntax error in a SQL statement is counted if there are more than one syntax errors in
1258     * a single SQL statement.
1259     * <br> In a SQL script, only the first syntax error in each SQL statement is counted.
1260     *
1261     * @return The total number of syntax errors founded in the input SQL script. Returns 0 if no syntax error is founded.
1262     */
1263    public int getErrorCount(){
1264        return   syntaxErrors.size();
1265    }
1266
1267    /**
1268     * The text of error message generated by iterating all items in {@link #getSyntaxErrors}.
1269     * User may generate error message in their own format by iterating all items in {@link #getSyntaxErrors}.
1270     *
1271     * @return error message
1272     */
1273    public String getErrormessage(){
1274
1275        String s="",hint="Syntax error";
1276        TSyntaxError t;
1277        for (int i= 0; i< syntaxErrors.size(); i++)
1278        {
1279            t = (TSyntaxError) syntaxErrors.get(i);
1280            if (t.hint.length() > 0) hint = t.hint;
1281            s= s+hint+"("+t.errorno+") near: "+t.tokentext;
1282            s=s+"("+t.lineNo;
1283            s=s+","+t.columnNo +", token code:"+t.tokencode+")";
1284                //s=s+" expected tokentext:"+t.hint;
1285
1286           // break;//get only one message, remove this one and uncomment next line to get all error messages
1287            if (i !=  syntaxErrors.size() - 1)
1288              s = s +TBaseType.linebreak;
1289        }
1290
1291        if (errormessage.length() > 0){
1292            s = errormessage+TBaseType.linebreak+s; 
1293        }
1294        return s;
1295
1296    }
1297
1298    /**
1299     * check syntax of the input SQL. This method works exactly the same as {@link #parse} method.
1300     *
1301     * @return   0 means parse SQL script successfully, otherwise, use {@link #getErrorCount}, {@link #getErrormessage}
1302     * to get detailed error information.
1303     * @see #parse
1304     */
1305    public int checkSyntax(){
1306        return doparse();
1307    }
1308
1309    /**
1310     *   Check syntax of the input SQL, doing some kind of semantic analysis without connecting to a real database.
1311     *   <p></p>
1312     *  This method will do a in-depth analysis of the input SQL such as building the link between table and columns.
1313     *  The parse tree of the input SQL is available after calling this method.
1314     *
1315     *  The parser checks the syntax of those SQL statements one by one. If syntax error is found in a SQL statement,
1316     *  an error will be logged, no parse tree will be built for this SQL statement,
1317     *  the error message can be fetched using the {@link #getErrormessage()} method.
1318     *  <p></p>
1319     *  The syntax error in one SQL statement doesn't prevent the parser continue to check the syntax of the next SQL statement.
1320     *  After checking syntax of all SQL statements, use the {@link #getErrorCount()} method to get the total number of errors.
1321     *  <p></p>
1322     *  A syntax error in a SQL stored procedure will cease this parser to check syntax of the rest SQL statements
1323     *  in this stored procedure.
1324     *
1325     * @return   0 means parse SQL script successfully, otherwise, use {@link #getErrorCount}, {@link #getErrormessage}
1326     * to get detailed error information.
1327     * @see #getSyntaxErrors
1328     */
1329
1330    public int parse(){
1331        return doparse();
1332    }
1333
1334    public int validate(){
1335        if (sqlstatements.size() == 0) return 0;
1336
1337        TRelationValidator relationValidate = new TRelationValidator(globalContext);
1338        for(TCustomSqlStatement sqlStatement:sqlstatements){
1339            sqlStatement.acceptChildren(relationValidate);
1340        }
1341        return 0;
1342    }
1343
1344    void setdelimiterchar(char ch){
1345        delimiterchar = ch;
1346        flexer.delimiterchar = ch;
1347    }
1348    char curdelimiterchar;
1349    String userDelimiterStr ="";
1350
1351    boolean includesqlstatementtype(ESqlStatementType search, ESqlStatementType[] src){
1352        boolean ret = false;
1353        for(int i=0;i<src.length;i++){
1354            if (src[i] == search){
1355                ret = true;
1356                break;
1357            }
1358        }
1359        return ret;
1360    }
1361
1362    // private int getfileEncodingType(FileInputStream inputStream){
1363    //     BufferedInputStream fr = new BufferedInputStream(inputStream,8);
1364    //     return getfileEncodingType(fr);
1365    // }
1366
1367    private int getfileEncodingType(BufferedInputStream fr){
1368        int ret = 0; // default, 1: utf-16, 2: utf-32
1369       // BufferedInputStream fr = new BufferedInputStream(inputStream,8);
1370        try {
1371            byte[] bom = new byte[4];
1372            fr.mark(bom.length+1);
1373
1374            fr.read(bom,0,bom.length);
1375            if ( ((bom[0] == (byte)0xFF) && (bom[1] == (byte)0xFE))
1376                    ||((bom[0] == (byte)0xFE) && (bom[1] == (byte)0xFF))
1377                    )
1378            {
1379                ret = 1;
1380                if ( ((bom[2] == (byte)0xFF) && (bom[3] == (byte)0xFE))
1381                        ||((bom[2] == (byte)0xFE) && (bom[3] == (byte)0xFF))
1382                        ){
1383                    ret = 2;
1384                }
1385            }else{
1386                if ((bom[0] == (byte)0xEF) && (bom[1] == (byte)0xBB)&& (bom[2] == (byte)0xBF)){
1387                    ret = 3; //UTF-8,EF BB BF
1388                }
1389            }
1390            fr.reset();
1391        } catch (FileNotFoundException e) {
1392            // e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
1393        } catch (IOException e) {
1394            //e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
1395        }
1396        return ret;
1397    }
1398
1399    // private int getfileEncodingType(String fn){
1400    //     int ret = 0; // default, 1: utf-16, 2: utf-32
1401    //     try {
1402    //         FileInputStream fr =   new FileInputStream(fn);
1403    //         ret = getfileEncodingType(fr);
1404    //         fr.close();
1405
1406    //     } catch (FileNotFoundException e) {
1407    //        // e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
1408    //     } catch (IOException e) {
1409    //         //e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
1410    //     }
1411    //     return ret;
1412    // }
1413
1414    int readsql(){
1415        int ret  = 0;
1416
1417        syntaxErrors.clear();
1418        //syntaxHints.clear();
1419
1420        if (((!TBaseType.full_edition))||(!TBaseType.need_license_file)){
1421            if (!TBaseType.need_license_file){
1422                licenseType = TBaseType.license_type_dist;
1423                userName = "dist";
1424            }else {
1425                licenseType = TBaseType.license_type_trial;
1426                userName = TBaseType.license_trail_username;
1427            }
1428           // machineId = new HardwareBinder().getMachineIdString();
1429        }else {
1430            if (!licenseOK){
1431                errormessage = licenseMessage;
1432                return -1;
1433            }
1434        }
1435
1436        try{
1437            if (finputstream != null) finputstream.close();
1438            if (flexer == null){
1439                ret = -1;
1440                errormessage = "requested database not supported:"+this.dbVendor.toString();
1441                return ret;
1442            }
1443            if (flexer.yyinput != null)    flexer.yyinput.close();
1444
1445        }catch(IOException e){
1446            ret = -1;
1447            errormessage = "requested database not supported";
1448        }
1449        
1450        if (sqltext.length() > 0){
1451            finputstream = new BufferedReader(new StringReader(sqltext));
1452            if ((!TBaseType.full_edition) && (sqltext.length() > TBaseType.query_size_limitation)){
1453                errormessage = TBaseType.trail_version_query_message;
1454                ret = -1;
1455            }
1456        }else if (sqlfilename.length() > 0){
1457            try{
1458
1459             streamFromSqlFile =   new FileInputStream(sqlfilename);
1460            // Buffer it for mark/reset support
1461            BufferedInputStream bufferedStream = new BufferedInputStream(streamFromSqlFile,8);             
1462            int encodingtype = getfileEncodingType(bufferedStream);
1463            streamFromSqlFile.getChannel().position(0);
1464
1465           if(encodingtype == 1){
1466                sqlStreamReader = new InputStreamReader(streamFromSqlFile,"UTF-16");
1467           }else if(encodingtype == 2){
1468                sqlStreamReader = new InputStreamReader(streamFromSqlFile,"UTF-32");
1469           }else if(encodingtype == 3){
1470              // System.out.println("utf-8");
1471                sqlStreamReader = new InputStreamReader(streamFromSqlFile,"UTF-8");
1472           }
1473           else{
1474               if (sqlCharset == null){
1475                   sqlCharset = Charset.defaultCharset().name();
1476                   //System.out.println("Charset used: "+Charset.defaultCharset().name());
1477               }
1478                sqlStreamReader = new InputStreamReader(streamFromSqlFile, sqlCharset);
1479              // isr = new InputStreamReader(fr,"Cp737");
1480           }
1481
1482            finputstream =  new BufferedReader(sqlStreamReader);
1483            if (encodingtype == 3){
1484                //EF BB BF was not stripped by the InputStreamReader, so we do it
1485                finputstream.skip(1);
1486            }
1487
1488            if ((!TBaseType.full_edition)){
1489                File file = new File(sqlfilename);
1490                if (!file.exists() || !file.isFile()) {
1491                    ret = -1;
1492                    errormessage = "not a valid sql file.";
1493                }else{
1494                    if (file.length() > TBaseType.query_size_limitation){
1495                        errormessage = TBaseType.trail_version_file_message;
1496                        ret = -1;
1497                    }
1498                }
1499            }
1500
1501            }catch(FileNotFoundException e){
1502                ret = -1;
1503                errormessage = e.toString();
1504            } catch (UnsupportedEncodingException e) {
1505                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
1506            } catch (IOException e) {
1507                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
1508            }
1509
1510        }else if(this.sqlInputStream != null){
1511            int encodingtype = getfileEncodingType(sqlInputStream);
1512            InputStream fr =   sqlInputStream;
1513
1514            InputStreamReader isr = null;
1515            try{
1516
1517                if(encodingtype == 1){
1518                    isr = new InputStreamReader(fr,"UTF-16");
1519                }else if(encodingtype == 2){
1520                    isr = new InputStreamReader(fr,"UTF-32");
1521                }else if(encodingtype == 3){
1522                    // System.out.println("utf-8");
1523                    isr = new InputStreamReader(fr,"UTF-8");
1524                }
1525                else{
1526                    if (sqlCharset == null){
1527                        sqlCharset = Charset.defaultCharset().name();
1528                    }
1529
1530                    isr = new InputStreamReader(fr, sqlCharset);
1531                }
1532
1533                finputstream =  new BufferedReader(isr);
1534                if (encodingtype == 3){
1535                    //EF BB BF was not stripped by the InputStreamReader, so we do it
1536                    finputstream.skip(1);
1537                }
1538
1539            }catch(FileNotFoundException e){
1540                ret = -1;
1541                errormessage = e.toString();
1542            } catch (UnsupportedEncodingException e) {
1543                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
1544            } catch (IOException e) {
1545                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
1546            }
1547
1548            try {
1549                if ((!TBaseType.full_edition) && (sqlInputStream.available() > TBaseType.query_size_limitation)){
1550                    errormessage = TBaseType.trail_version_query_message;
1551                    ret = -1;
1552                }
1553            } catch (IOException e) {
1554                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
1555            }
1556        }
1557
1558       if (finputstream == null) ret = -1;
1559
1560       if (ret == 0)
1561       {
1562           flexer.yyinput =  finputstream;
1563           flexer.setSqlCharset(this.sqlCharset);
1564           flexer.reset();
1565
1566       }
1567
1568        sourcetokenlist.clear();
1569        sourcetokenlist.curpos = -1;
1570
1571       flexer.resetTokenTable();
1572
1573
1574        return ret;
1575    }
1576
1577    TSourceToken getanewsourcetoken(){
1578        TSourceToken pst = null,prevst;
1579        
1580        while (true) {
1581            pst = new TSourceToken("");
1582            if (flexer.yylexwrap(pst) == 0) { pst = null; break;}
1583            
1584            pst.setDbvendor(dbVendor);
1585            pst.tokenstatus = ETokenStatus.tsoriginal;
1586            if (pst.tokentype == ETokenType.ttreturn){
1587               pst.astext = towinlinebreak(pst.astext);
1588            }
1589            //combine space && linebreak after a linebreak into one
1590            if ( (pst.tokentype == ETokenType.ttwhitespace)
1591             && (sourcetokenlist.curpos >= 0) )
1592              {
1593                prevst =  sourcetokenlist.get(sourcetokenlist.curpos);
1594                if ( prevst.tokentype == ETokenType.ttreturn )
1595                  {
1596                    //can't discard  whitespace after linebreak, it will be used
1597                    // to judge whether / at the { of the line is a sqlplus cmd or not
1598                    // check isvalidplacefordivtosqlpluscmd for more
1599                    prevst.astext = prevst.astext+pst.astext;
1600                    //newst.free;
1601                    //newst = nil;
1602                    continue;
1603                  }
1604              }
1605
1606            if ( (pst.tokentype == ETokenType.ttreturn)
1607             && (sourcetokenlist.curpos >= 0) )
1608              {
1609                prevst =  sourcetokenlist.get(sourcetokenlist.curpos);
1610
1611                if ( prevst.tokentype == ETokenType.ttreturn )
1612                  {
1613                    prevst.astext = prevst.astext+pst.astext;
1614                    //newst.free;
1615                    //newst = nil;
1616                    continue;
1617                  }
1618
1619                if ( prevst.tokentype == ETokenType.ttwhitespace )
1620                  {
1621                    //merge previous whitespace with this linebreak
1622                    //doesn't work for sqlplus cmd
1623
1624                   // prevst.sourcecode = newst.sourcecode;
1625                   // prevst.tokentype = newst.tokentype;
1626                   // prevst.tokencode = newst.tokencode;
1627                   // newst.free;
1628                   // newst = nil;
1629                   // continue;
1630
1631                   //prevst.prevsourcecode = prevst.astext;
1632                   //prevst.astext =  "";
1633                  }
1634              }
1635
1636            break;
1637
1638        }
1639
1640        if (pst != null){
1641            pst.container = sourcetokenlist;
1642            sourcetokenlist.curpos = sourcetokenlist.curpos+1;
1643            pst.posinlist = sourcetokenlist.curpos;
1644            if (tokenHandle != null){
1645                tokenHandle.processToken(pst);
1646            }
1647        }
1648
1649       // System.out.println(pst);
1650        flexer.setTokenTableValue(pst);
1651        return pst;
1652        
1653    }
1654
1655  String towinlinebreak(String s){
1656      return s;
1657// todo not implemented yet     
1658  }
1659
1660void checkconstarinttoken(TSourceToken lcprevtoken){
1661    TSourceTokenList lcStList = lcprevtoken.container;
1662    if (TBaseType.assigned(lcStList))
1663    {
1664         TSourceToken lcPPToken = lcStList.nextsolidtoken(lcprevtoken.posinlist,-2,false);
1665         if (TBaseType.assigned(lcPPToken))
1666        {
1667
1668             if (lcPPToken.tokencode == flexer.getkeywordvalue("constraint"))
1669             {
1670                 //System.out.println(lcPPToken);
1671                 lcPPToken.tokencode = TBaseType.rw_constraint2;
1672             }
1673        }
1674    }
1675
1676}
1677
1678TSourceToken getprevtoken(TSourceToken ptoken){
1679   // ETokenType[] lcnonsolidtokenset = {ETokenType.ttwhitespace,ETokenType.ttreturn,ETokenType.ttsimplecomment,ETokenType.ttbracketedcomment} ;
1680    TSourceTokenList lcstlist = ptoken.container;
1681    if (TBaseType.assigned(lcstlist)){
1682        if ((ptoken.posinlist > 0)  && (lcstlist.size() > ptoken.posinlist-1))
1683        {
1684            if (!(
1685                    (lcstlist.get(ptoken.posinlist-1).tokentype ==  ETokenType.ttwhitespace)
1686                    ||(lcstlist.get(ptoken.posinlist-1).tokentype ==  ETokenType.ttreturn)
1687                    ||(lcstlist.get(ptoken.posinlist-1).tokentype ==  ETokenType.ttsimplecomment)
1688                    ||(lcstlist.get(ptoken.posinlist-1).tokentype ==  ETokenType.ttbracketedcomment)
1689                    )
1690                )
1691            {return lcstlist.get(ptoken.posinlist-1);}
1692            else{
1693            { return lcstlist.nextsolidtoken(ptoken.posinlist-1,-1,false);}
1694        }
1695        }
1696    }
1697    
1698    return null;
1699}
1700
1701void doinformixtexttotokenlist(){
1702      TSourceToken lcprevtoken = null;
1703      int lcsteps = 0;
1704      TSourceToken asourcetoken,lctoken, lctoken2,lctoken3;
1705      int yychar;
1706      boolean iskeywordgo;
1707
1708      asourcetoken = getanewsourcetoken();
1709
1710      if ( asourcetoken == null ) return;
1711
1712      yychar = asourcetoken.tokencode;
1713
1714
1715      boolean lcinopenrowset = false;
1716      int lcnested = 0;
1717
1718      while (yychar > 0)
1719        {
1720
1721          if ( asourcetoken.tokencode == TBaseType.rrw_openrowset )
1722            {
1723              // openrowset(....)
1724              lcinopenrowset = true;
1725              lcnested = 0;
1726            }
1727          else if ( asourcetoken.tokentype == ETokenType.ttleftparenthesis)
1728            {
1729              if ( (lcsteps > 0) && TBaseType.assigned(lcprevtoken))
1730                {
1731                  if ( lcprevtoken.tokencode == TBaseType.rrw_primary )
1732                    {
1733                     lcprevtoken.tokencode = TBaseType.rrw_select - 2;  //rw_primary2
1734                     //checkconstarinttoken(lcprevtoken);
1735                    }
1736                  else if ( lcprevtoken.tokencode == TBaseType.rrw_foreign )
1737                    {
1738                     lcprevtoken.tokencode = TBaseType.rrw_select - 4;  //rw_foreign2
1739                     //checkconstarinttoken(lcprevtoken);
1740                    }
1741                  else if ( lcprevtoken.tokencode == TBaseType.rrw_unique )
1742                    {
1743                      lcprevtoken.tokencode = TBaseType.rrw_select - 1;  //rw_unique2
1744                     // checkconstarinttoken(lcprevtoken);
1745                    }
1746                  else if ( lcprevtoken.tokencode == TBaseType.rrw_distinct )
1747                    {
1748                      lcprevtoken.tokencode = TBaseType.rrw_select - 6;  //rw_distinct2
1749                      //checkconstarinttoken(lcprevtoken);
1750                    }
1751                  lcprevtoken = null;
1752                  lcsteps = 0;
1753                }
1754
1755              // openrowset(....)
1756              if ( lcinopenrowset )
1757                lcnested++;
1758            }
1759          else if ( asourcetoken.tokentype == ETokenType.ttrightparenthesis)
1760            {
1761              // openrowset(....)
1762              if ( lcinopenrowset  )
1763                {
1764                  if ( (lcnested > 0) )
1765                    lcnested--;
1766                  if ( lcnested == 0 )
1767                    lcinopenrowset = false;
1768                }
1769            }
1770          else if ( asourcetoken.tokentype == ETokenType.ttsemicolon )
1771            {
1772              if ( lcinopenrowset ){
1773                asourcetoken.tokentype = ETokenType.ttsemicolon2;
1774              }else{
1775                lctoken2 = asourcetoken.searchToken(TBaseType.rrw_begin,-1);
1776                  if (lctoken2 != null){
1777                     asourcetoken.tokencode = TBaseType.SEMI_COLON_AFTER_BEGIN;
1778                     asourcetoken.tokentype = ETokenType.ttsemicolon3;
1779                  }else{
1780                      lctoken2 = asourcetoken.searchToken(TBaseType.rrw_try,-1);
1781                      if (lctoken2 == null){
1782                          lctoken2 = asourcetoken.searchToken(TBaseType.rrw_catch,-1);
1783                      }
1784                      if (lctoken2 != null){
1785                          lctoken3 = asourcetoken.searchToken(TBaseType.rrw_begin,-2);
1786                          if (lctoken3 != null){
1787                              asourcetoken.tokencode = TBaseType.SEMI_COLON_AFTER_BEGIN;
1788                              asourcetoken.tokentype = ETokenType.ttsemicolon3;
1789                          }
1790                      }
1791                  }
1792              }
1793            }
1794          else if ( asourcetoken.tokentype == ETokenType.ttperiod)
1795            {
1796              lctoken = getprevtoken(asourcetoken);
1797             //  System.out.println(lctoken);
1798              if ( TBaseType.assigned(lctoken) )
1799                { // go.fieldname, go is a table alias, not a go statement
1800                  if ( lctoken.tokencode == TBaseType.rrw_go )
1801                    {
1802                      lctoken.tokencode = TBaseType.ident;
1803                      lctoken.tokentype = ETokenType.ttidentifier;
1804                    }
1805                }
1806            }
1807          else if ( asourcetoken.tokencode == TBaseType.rrw_table ){
1808              lctoken = getprevtoken(asourcetoken);
1809              if (TBaseType.assigned(lctoken))
1810              {
1811                  if (lctoken.tokencode == TBaseType.rrw_lock )
1812                  {
1813                      lctoken.tokencode = TBaseType.rw_locktable; //TBaseType.rw_locktable
1814                  }
1815              }
1816          }
1817          else if ( asourcetoken.tokencode == TBaseType.rrw_to ){
1818              lctoken = getprevtoken(asourcetoken);
1819              if (TBaseType.assigned(lctoken))
1820              {
1821                  if (lctoken.tokencode == TBaseType.rrw_connect )
1822                  {
1823                      lctoken.tokencode = TBaseType.rrw_informix_connect_to;//connect to statement
1824                  }
1825              }
1826          }
1827          else if ( asourcetoken.tokencode == TBaseType.rrw_go )
1828            {
1829              iskeywordgo = true;
1830              lctoken = getprevtoken(asourcetoken);
1831              if ( TBaseType.assigned(lctoken) )
1832                { // go should not at same line as other sql statement
1833                  if ( lctoken.lineNo == asourcetoken.lineNo)
1834                    {
1835                      iskeywordgo = false;
1836                    }
1837                }
1838
1839              if ( iskeywordgo )
1840                {
1841                  lcinopenrowset = false;
1842                  lcnested = 0;
1843                  lcprevtoken = asourcetoken;
1844                }
1845              else
1846                {
1847                  //  System.out.println(asourcetoken);
1848                  asourcetoken.tokencode = TBaseType.ident;
1849                  asourcetoken.tokentype = ETokenType.ttidentifier;
1850                }
1851            }
1852          else if ( asourcetoken.tokencode == TBaseType.rrw_primary )
1853            {
1854              // primary key [clustered | nonclustered ] ( column list)
1855              lcsteps = 2;
1856              lcprevtoken = asourcetoken;
1857            }
1858          else if ( asourcetoken.tokencode == TBaseType.rrw_foreign )
1859            {
1860              // foreign key [clustered | nonclustered ] ( column list)
1861              lcsteps = 2;
1862              lcprevtoken = asourcetoken;
1863            }
1864          else if ( asourcetoken.tokencode == TBaseType.rrw_unique )
1865            {
1866              // unique [clustered | nonclustered ] ( column list)
1867              lcsteps = 1;
1868              lcprevtoken = asourcetoken;
1869            }
1870          else if ( asourcetoken.issolidtoken() )
1871            {
1872              if ( lcsteps > 0 )
1873                {
1874                  if (  !(TBaseType.mysametext("clustered",asourcetoken.astext)
1875                     || TBaseType.mysametext("nonclustered",asourcetoken.astext)) )
1876                    lcsteps--;
1877                }
1878            }
1879
1880           //System.out.println(asourcetoken);
1881           sourcetokenlist.add(asourcetoken);
1882
1883
1884          //flexer.yylexwrap(asourcetoken);
1885          asourcetoken = getanewsourcetoken();
1886          if (asourcetoken != null){
1887              yychar = asourcetoken.tokencode;
1888          }else{
1889            yychar = 0;
1890          }
1891
1892        }
1893
1894  }
1895
1896  void domssqlsqltexttotokenlist(){
1897      TSourceToken lcprevtoken = null;
1898      int lcsteps = 0;
1899      TSourceToken asourcetoken,lctoken, lctoken2,lctoken3;
1900      int yychar;
1901      boolean iskeywordgo;
1902
1903      asourcetoken = getanewsourcetoken();
1904      
1905      if ( asourcetoken == null ) return;
1906
1907      yychar = asourcetoken.tokencode;
1908
1909
1910      boolean lcinopenrowset = false;
1911      int lcnested = 0;
1912
1913      while (yychar > 0)
1914        {
1915
1916          if ( asourcetoken.tokencode == TBaseType.rrw_openrowset )
1917            {
1918              // openrowset(....)
1919              lcinopenrowset = true;
1920              lcnested = 0;
1921            }
1922          else if ( asourcetoken.tokentype == ETokenType.ttleftparenthesis)
1923            {
1924              if ( (lcsteps > 0) && TBaseType.assigned(lcprevtoken))
1925                {
1926                  if ( lcprevtoken.tokencode == TBaseType.rrw_primary )
1927                    {
1928                     lcprevtoken.tokencode = TBaseType.rrw_select - 2;  //rw_primary2
1929                     checkconstarinttoken(lcprevtoken);
1930                    }
1931                  else if ( lcprevtoken.tokencode == TBaseType.rrw_foreign )
1932                    {
1933                     lcprevtoken.tokencode = TBaseType.rrw_select - 4;  //rw_foreign2
1934                     checkconstarinttoken(lcprevtoken);
1935                    }
1936                  else if ( lcprevtoken.tokencode == TBaseType.rrw_unique )
1937                    {
1938                      lcprevtoken.tokencode = TBaseType.rrw_select - 1;  //rw_unique2
1939                      checkconstarinttoken(lcprevtoken);
1940                    }
1941                  lcprevtoken = null;
1942                  lcsteps = 0;
1943                }
1944
1945              // openrowset(....)
1946              if ( lcinopenrowset )
1947                lcnested++;
1948            }
1949          else if ( asourcetoken.tokentype == ETokenType.ttrightparenthesis)
1950            {
1951              // openrowset(....)
1952              if ( lcinopenrowset  )
1953                {
1954                  if ( (lcnested > 0) )
1955                    lcnested--;
1956                  if ( lcnested == 0 )
1957                    lcinopenrowset = false;
1958                }
1959            }
1960          else if ( asourcetoken.tokentype == ETokenType.ttsemicolon )
1961            {
1962              if ( lcinopenrowset ){
1963                asourcetoken.tokentype = ETokenType.ttsemicolon2;
1964              }else{
1965                lctoken2 = asourcetoken.searchToken(TBaseType.rrw_begin,-1);
1966                  if (lctoken2 != null){
1967                     asourcetoken.tokencode = TBaseType.SEMI_COLON_AFTER_BEGIN;
1968                     asourcetoken.tokentype = ETokenType.ttsemicolon3;
1969                  }else{
1970                      lctoken2 = asourcetoken.searchToken(TBaseType.rrw_try,-1);
1971                      if (lctoken2 == null){
1972                          lctoken2 = asourcetoken.searchToken(TBaseType.rrw_catch,-1);
1973                      }
1974                      if (lctoken2 != null){
1975                          lctoken3 = asourcetoken.searchToken(TBaseType.rrw_begin,-2);
1976                          if (lctoken3 != null){
1977                              asourcetoken.tokencode = TBaseType.SEMI_COLON_AFTER_BEGIN;
1978                              asourcetoken.tokentype = ETokenType.ttsemicolon3;
1979                          }
1980                      }
1981                  }
1982              }
1983
1984                lctoken = getprevtoken(asourcetoken);
1985                if ((lctoken != null)){
1986                    if (lctoken.tokentype == ETokenType.ttsemicolon){
1987                        // treat this semicolon as a whitespace
1988                        asourcetoken.tokencode = TBaseType.lexspace;
1989                    }
1990                }
1991            }
1992          else if ( asourcetoken.tokentype == ETokenType.ttperiod)
1993            {
1994              lctoken = getprevtoken(asourcetoken);
1995             //  System.out.println(lctoken);
1996              if ( TBaseType.assigned(lctoken) )
1997                { // go.fieldname, go is a table alias, not a go statement
1998                  if ( lctoken.tokencode == TBaseType.rrw_go )
1999                    {
2000                      lctoken.tokencode = TBaseType.ident;
2001                      lctoken.tokentype = ETokenType.ttidentifier;
2002                    }
2003                }
2004            }
2005          else if ( asourcetoken.tokencode == TBaseType.rrw_table ){
2006              lctoken = getprevtoken(asourcetoken);
2007              if (TBaseType.assigned(lctoken))
2008              {
2009                  if (lctoken.tokencode == TBaseType.rrw_lock )
2010                  {
2011                      lctoken.tokencode = TBaseType.rw_locktable; //TBaseType.rw_locktable
2012                  }
2013              }
2014          }
2015          else if ( asourcetoken.tokencode == TBaseType.rrw_into ){
2016              lctoken = getprevtoken(asourcetoken);
2017              if (TBaseType.assigned(lctoken))
2018              {
2019                  if (lctoken.tokencode == TBaseType.rrw_sqlserver_copy )
2020                  {
2021                     lctoken.tokencode = TBaseType.rrw_sqlserver_copyinto;
2022                  }
2023              }
2024          }
2025          else if ( asourcetoken.tokencode == TBaseType.rrw_sqlserver_column ){
2026              lctoken = getprevtoken(asourcetoken);
2027              if (TBaseType.assigned(lctoken))
2028              {
2029                  if (lctoken.tokencode == TBaseType.rrw_drop )
2030                  {
2031                      asourcetoken.tokencode = TBaseType.rrw_sqlserver_drop_column;
2032                  }
2033              }
2034          }
2035          else if ( asourcetoken.tokencode == TBaseType.rrw_go )
2036            {
2037              iskeywordgo = true;
2038              lctoken = getprevtoken(asourcetoken);
2039              if ( TBaseType.assigned(lctoken) )
2040                { // go should not at same line as other sql statement
2041                  if (( lctoken.lineNo == asourcetoken.lineNo)&&(lctoken.tokencode != ';'))
2042                    {
2043                      iskeywordgo = false;
2044                    }
2045                }
2046
2047              if ( iskeywordgo )
2048                {
2049                  lcinopenrowset = false;
2050                  lcnested = 0;
2051                  lcprevtoken = asourcetoken;
2052                }
2053              else
2054                {
2055                  //  System.out.println(asourcetoken);
2056                  asourcetoken.tokencode = TBaseType.ident;
2057                  asourcetoken.tokentype = ETokenType.ttidentifier;
2058                }
2059            }
2060          else if ( asourcetoken.tokencode == TBaseType.rrw_primary )
2061            {
2062              // primary key [clustered | nonclustered ] [hash] ( column list)
2063              lcsteps = 2;
2064              lcprevtoken = asourcetoken;
2065            }
2066          else if ( asourcetoken.tokencode == TBaseType.rrw_foreign )
2067            {
2068              // foreign key [clustered | nonclustered ] ( column list)
2069              lcsteps = 2;
2070              lcprevtoken = asourcetoken;
2071            }
2072          else if ( asourcetoken.tokencode == TBaseType.rrw_unique )
2073            {
2074              // unique [clustered | nonclustered ] [hash] ( column list)
2075              lcsteps = 1;
2076              lcprevtoken = asourcetoken;
2077            }
2078          else if ( asourcetoken.issolidtoken() )
2079            {
2080              if ( lcsteps > 0 )
2081                {
2082                  if (  !(TBaseType.mysametext("clustered",asourcetoken.astext)
2083                     || TBaseType.mysametext("nonclustered",asourcetoken.astext)
2084                     || TBaseType.mysametext("hash",asourcetoken.astext)
2085                  ) )
2086                    lcsteps--;
2087                }
2088            }
2089
2090           //System.out.println(asourcetoken); 
2091           sourcetokenlist.add(asourcetoken);
2092
2093
2094          //flexer.yylexwrap(asourcetoken);
2095          asourcetoken = getanewsourcetoken();
2096          if (asourcetoken != null){
2097              yychar = asourcetoken.tokencode;
2098          }else{
2099            yychar = 0;
2100          }
2101
2102        }
2103
2104  }
2105
2106  void dosybasesqltexttotokenlist(){
2107      TSourceToken lcprevtoken = null;
2108      int lcsteps = 0;
2109      TSourceToken asourcetoken,lctoken, lctoken2,lctoken3;
2110      int yychar;
2111      boolean iskeywordgo;
2112
2113
2114      asourcetoken = getanewsourcetoken();
2115
2116      if ( asourcetoken == null ) return;
2117
2118      yychar = asourcetoken.tokencode;
2119
2120
2121      boolean lcinopenrowset = false;
2122      int lcnested = 0;
2123
2124      while (yychar > 0)
2125        {
2126
2127          if ( asourcetoken.tokencode == TBaseType.rrw_openrowset )
2128            {
2129              // openrowset(....)
2130              lcinopenrowset = true;
2131              lcnested = 0;
2132            }
2133          else if ( asourcetoken.tokentype == ETokenType.ttleftparenthesis)
2134            {
2135              if ( (lcsteps > 0) && TBaseType.assigned(lcprevtoken))
2136                {
2137                  if ( lcprevtoken.tokencode == TBaseType.rrw_primary )
2138                    {
2139                     lcprevtoken.tokencode = TBaseType.rrw_select - 2;  //rw_primary2
2140                     checkconstarinttoken(lcprevtoken);
2141                    }
2142                  else if ( lcprevtoken.tokencode == TBaseType.rrw_foreign )
2143                    {
2144                     lcprevtoken.tokencode = TBaseType.rrw_select - 4;  //rw_foreign2
2145                     checkconstarinttoken(lcprevtoken);
2146                    }
2147                  else if ( lcprevtoken.tokencode == TBaseType.rrw_unique )
2148                    {
2149                      lcprevtoken.tokencode = TBaseType.rrw_select - 1;  //rw_unique2
2150                      checkconstarinttoken(lcprevtoken);
2151                    }
2152                  lcprevtoken = null;
2153                  lcsteps = 0;
2154                }
2155
2156              // openrowset(....)
2157              if ( lcinopenrowset )
2158                lcnested++;
2159            }
2160          else if ( asourcetoken.tokentype == ETokenType.ttrightparenthesis)
2161            {
2162              // openrowset(....)
2163              if ( lcinopenrowset  )
2164                {
2165                  if ( (lcnested > 0) )
2166                    lcnested--;
2167                  if ( lcnested == 0 )
2168                    lcinopenrowset = false;
2169                }
2170            }
2171          else if ( asourcetoken.tokentype == ETokenType.ttsemicolon )
2172            {
2173              if ( lcinopenrowset ){
2174                asourcetoken.tokentype = ETokenType.ttsemicolon2;
2175              }else{
2176                lctoken2 = asourcetoken.searchToken(TBaseType.rrw_begin,-1);
2177                  if (lctoken2 != null){
2178                     asourcetoken.tokencode = TBaseType.SEMI_COLON_AFTER_BEGIN;
2179                     asourcetoken.tokentype = ETokenType.ttsemicolon3;
2180                  }else{
2181                      lctoken2 = asourcetoken.searchToken(TBaseType.rrw_try,-1);
2182                      if (lctoken2 == null){
2183                          lctoken2 = asourcetoken.searchToken(TBaseType.rrw_catch,-1);
2184                      }
2185                      if (lctoken2 != null){
2186                          lctoken3 = asourcetoken.searchToken(TBaseType.rrw_begin,-2);
2187                          if (lctoken3 != null){
2188                              asourcetoken.tokencode = TBaseType.SEMI_COLON_AFTER_BEGIN;
2189                              asourcetoken.tokentype = ETokenType.ttsemicolon3;
2190                          }
2191                      }
2192                  }
2193              }
2194            }
2195          else if ( asourcetoken.tokentype == ETokenType.ttperiod)
2196            {
2197              lctoken = getprevtoken(asourcetoken);
2198             //  System.out.println(lctoken);
2199              if ( TBaseType.assigned(lctoken) )
2200                { // go.fieldname, go is a table alias, not a go statement
2201                  if ( lctoken.tokencode == TBaseType.rrw_go )
2202                    {
2203                      lctoken.tokencode = TBaseType.ident;
2204                      lctoken.tokentype = ETokenType.ttidentifier;
2205                    }
2206                }
2207            }
2208          else if ( asourcetoken.tokencode == TBaseType.rrw_table ){
2209              lctoken = getprevtoken(asourcetoken);
2210              if (TBaseType.assigned(lctoken))
2211              {
2212                  if (lctoken.tokencode == TBaseType.rrw_lock )
2213                  {
2214                      lctoken.tokencode = TBaseType.rw_locktable; //TBaseType.rw_locktable
2215                  }
2216              }
2217          }
2218          else if ( asourcetoken.tokencode == TBaseType.rrw_sybase_isolation ){
2219              lctoken = getprevtoken(asourcetoken);
2220              if (TBaseType.assigned(lctoken))
2221              {
2222                  if (lctoken.tokencode == TBaseType.rrw_sybase_at )
2223                  {
2224                      lctoken.tokencode = TBaseType.rw_sybase_at1; //TBaseType.rw_locktable
2225                  }
2226              }
2227          }
2228          else if ( asourcetoken.tokencode == TBaseType.rrw_update ){
2229              lctoken = getprevtoken(asourcetoken);
2230              if (TBaseType.assigned(lctoken))
2231              {
2232                  if ((lctoken.tokencode == TBaseType.rrw_not )
2233                          ||(lctoken.tokencode == TBaseType.rrw_and )
2234                          ||(lctoken.tokencode == TBaseType.rrw_or )
2235                          ||(lctoken.tokencode == TBaseType.rrw_if )
2236                      )
2237                  {
2238                      // this is update(column) in create trigger
2239                      asourcetoken.tokencode = TBaseType.rw_sybase_update1;
2240                  }
2241              }
2242          }
2243          else if ( asourcetoken.tokencode == TBaseType.rrw_go )
2244            {
2245              iskeywordgo = true;
2246              lctoken = getprevtoken(asourcetoken);
2247              if ( TBaseType.assigned(lctoken) )
2248                { // go should not at same line as other sql statement
2249                  if ( lctoken.lineNo == asourcetoken.lineNo)
2250                    {
2251                      iskeywordgo = false;
2252                    }
2253                }
2254
2255              if ( iskeywordgo )
2256                {
2257                  lcinopenrowset = false;
2258                  lcnested = 0;
2259                  lcprevtoken = asourcetoken;
2260                }
2261              else
2262                {
2263                  //  System.out.println(asourcetoken);
2264                  asourcetoken.tokencode = TBaseType.ident;
2265                  asourcetoken.tokentype = ETokenType.ttidentifier;
2266                }
2267            }
2268          else if ( asourcetoken.tokencode == TBaseType.rrw_primary )
2269            {
2270              // primary key [clustered | nonclustered ] ( column list)
2271              lcsteps = 2;
2272              lcprevtoken = asourcetoken;
2273            }
2274          else if ( asourcetoken.tokencode == TBaseType.rrw_foreign )
2275            {
2276              // foreign key [clustered | nonclustered ] ( column list)
2277              lcsteps = 2;
2278              lcprevtoken = asourcetoken;
2279            }
2280          else if ( asourcetoken.tokencode == TBaseType.rrw_unique )
2281            {
2282              // unique [clustered | nonclustered ] ( column list)
2283              lcsteps = 1;
2284              lcprevtoken = asourcetoken;
2285            }
2286          else if ( asourcetoken.issolidtoken() )
2287            {
2288              if ( lcsteps > 0 )
2289                {
2290                  if (  !(TBaseType.mysametext("clustered",asourcetoken.astext)
2291                     || TBaseType.mysametext("nonclustered",asourcetoken.astext)) )
2292                    lcsteps--;
2293                }
2294            }
2295
2296           //System.out.println(asourcetoken);
2297           sourcetokenlist.add(asourcetoken);
2298
2299
2300          //flexer.yylexwrap(asourcetoken);
2301          asourcetoken = getanewsourcetoken();
2302          if (asourcetoken != null){
2303              yychar = asourcetoken.tokencode;
2304          }else{
2305            yychar = 0;
2306          }
2307
2308        }
2309
2310  }
2311
2312boolean IsValidPlaceForDivToSqlplusCmd(TSourceTokenList pstlist, int pPos){
2313   boolean ret = false;
2314
2315    if ((pPos <= 0) || (pPos > pstlist.size() - 1 ) ) return ret;
2316    //tokentext directly before div must be ttreturn without space appending it
2317    TSourceToken lcst = pstlist.get(pPos - 1);
2318    if (lcst.tokentype != ETokenType.ttreturn) { return ret;}
2319
2320    //I := Length(lcst.AsText);
2321    //if not (lcst.AsText[I] = ' ') then result := true;
2322
2323    if (!(lcst.astext.charAt(lcst.astext.length()-1) == ' ')) {ret = true;}
2324
2325    return ret;
2326}
2327
2328// place holder function, always return false
2329boolean isvalidsqlpluscmdInPostgresql(String astr){
2330    return false;
2331}
2332
2333//boolean isvalidsqlpluscmd(String astr){
2334//    boolean ret = false;
2335//    if (sqlpluskeywordList.size() == 0){
2336//    sqlpluskeywordList.put("ACC","1");
2337//        sqlpluskeywordList.put("ACCEPT","1");
2338//        sqlpluskeywordList.put("A","1");
2339//        sqlpluskeywordList.put("APPEND","1");
2340//        sqlpluskeywordList.put("ATTRIBUTE","1");
2341//        sqlpluskeywordList.put("BRE","1");
2342//        sqlpluskeywordList.put("BREAK","1");
2343//        sqlpluskeywordList.put("BTI","1");
2344//        sqlpluskeywordList.put("BTITLE","1");
2345//        sqlpluskeywordList.put("C","1");
2346//        sqlpluskeywordList.put("CHANGE","1");
2347//        sqlpluskeywordList.put("CL","1");
2348//        sqlpluskeywordList.put("CLEAR","1");
2349//        sqlpluskeywordList.put("COL","1");
2350//        sqlpluskeywordList.put("COLUMN","1");
2351//        sqlpluskeywordList.put("COMP","1");
2352//        sqlpluskeywordList.put("COMPUTE","1");
2353//        sqlpluskeywordList.put("CONN","1");
2354//        sqlpluskeywordList.put("CONNECT","1");
2355//        sqlpluskeywordList.put("COPY","1");
2356//        sqlpluskeywordList.put("DEF","1");
2357//        sqlpluskeywordList.put("DEFINE","1");
2358//        sqlpluskeywordList.put("DEL","1");
2359//        sqlpluskeywordList.put("DESC","1");
2360//        sqlpluskeywordList.put("DESCRIBE","1");
2361//        sqlpluskeywordList.put("DISC","1");
2362//        sqlpluskeywordList.put("DISCONNECT","1");
2363//        sqlpluskeywordList.put("ED","1");
2364//        sqlpluskeywordList.put("EDIT","1");
2365//        sqlpluskeywordList.put("EXEC","1");
2366//        sqlpluskeywordList.put("EXIT","1");
2367//        sqlpluskeywordList.put("QUIT","1");
2368//        sqlpluskeywordList.put("GET","1");
2369//        sqlpluskeywordList.put("HELP","1");
2370//        sqlpluskeywordList.put("HO","1");
2371//        sqlpluskeywordList.put("HOST","1");
2372//        sqlpluskeywordList.put("I","1");
2373//        sqlpluskeywordList.put("INPUT","1");
2374//        sqlpluskeywordList.put("L","1");
2375//        sqlpluskeywordList.put("LIST","1");
2376//        sqlpluskeywordList.put("PASSW","1");
2377//        sqlpluskeywordList.put("PASSWORD","1");
2378//        sqlpluskeywordList.put("PAU","1");
2379//        sqlpluskeywordList.put("PAUSE","1");
2380//        sqlpluskeywordList.put("PRI","1");
2381//        sqlpluskeywordList.put("PRINT","1");
2382//        sqlpluskeywordList.put("PROMPT","1");
2383//        sqlpluskeywordList.put("REM","1");
2384//        sqlpluskeywordList.put("REMARK","1");
2385//        sqlpluskeywordList.put("REPF","1");
2386//        sqlpluskeywordList.put("REPFOOTER","1");
2387//        sqlpluskeywordList.put("REPH","1");
2388//        sqlpluskeywordList.put("REPHEADER","1");
2389//        sqlpluskeywordList.put("R","1");
2390//        sqlpluskeywordList.put("RUN","1");
2391//        sqlpluskeywordList.put("SAV","1");
2392//        sqlpluskeywordList.put("SAVE","1");
2393//        sqlpluskeywordList.put("SET","1");
2394//        sqlpluskeywordList.put("SHO","1");
2395//        sqlpluskeywordList.put("SHOW","1");
2396//        sqlpluskeywordList.put("SPO","1");
2397//        sqlpluskeywordList.put("SPOOL","1");
2398//        sqlpluskeywordList.put("STA","1");
2399//        sqlpluskeywordList.put("START","1");
2400//        sqlpluskeywordList.put("STORE","1");
2401//        sqlpluskeywordList.put("TIMI","1");
2402//        sqlpluskeywordList.put("TIMING","1");
2403//        sqlpluskeywordList.put("TTI","1");
2404//        sqlpluskeywordList.put("TTITLE","1");
2405//        sqlpluskeywordList.put("UNDEF","1");
2406//        sqlpluskeywordList.put("UNDEFINE","1");
2407//        sqlpluskeywordList.put("VAR","1");
2408//        sqlpluskeywordList.put("VARIABLE","1");
2409//        sqlpluskeywordList.put("WHENEVER","1");
2410//        sqlpluskeywordList.put("@","1");
2411//        sqlpluskeywordList.put("@@","1");
2412//    }
2413//
2414//    try{
2415//     ret =   (Integer.parseInt( (String) sqlpluskeywordList.get(astr.toUpperCase()) ) ) == 1 ;
2416//    }catch(NumberFormatException e){
2417//        ret = false;
2418//    }
2419//
2420//    return ret;
2421//}
2422
2423TSourceToken getprevsolidtoken(TSourceToken ptoken){
2424    TSourceToken ret = null;
2425    TSourceTokenList lctokenlist = ptoken.container;
2426    if (lctokenlist != null){
2427        if ((ptoken.posinlist > 0)  &&  (lctokenlist.size() > ptoken.posinlist-1))
2428        {
2429            if( !(
2430                    (lctokenlist.get(ptoken.posinlist-1).tokentype == ETokenType.ttwhitespace)
2431                    ||(lctokenlist.get(ptoken.posinlist-1).tokentype == ETokenType.ttreturn)
2432                ||(lctokenlist.get(ptoken.posinlist-1).tokentype == ETokenType.ttsimplecomment)
2433                ||(lctokenlist.get(ptoken.posinlist-1).tokentype == ETokenType.ttbracketedcomment)
2434            ))
2435            { ret = lctokenlist.get(ptoken.posinlist-1);}
2436            else
2437            { ret = lctokenlist.nextsolidtoken(ptoken.posinlist-1,-1,false);}
2438        }
2439    }
2440    return ret;
2441}
2442
2443    void doredshifttexttotokenlist(){
2444
2445        boolean insqlpluscmd = false;
2446        boolean isvalidplace = true;
2447        boolean waitingreturnforfloatdiv = false;
2448        boolean waitingreturnforsemicolon = false;
2449        boolean continuesqlplusatnewline = false;
2450
2451
2452        TSourceToken lct = null, prevst = null;
2453
2454        TSourceToken asourcetoken,lcprevst;
2455        int yychar;
2456
2457        asourcetoken = getanewsourcetoken();
2458        if ( asourcetoken == null ) return;
2459        yychar = asourcetoken.tokencode;
2460
2461        while (yychar > 0)
2462        {
2463
2464
2465            sourcetokenlist.add(asourcetoken);
2466            switch(yychar){
2467                case TBaseType.cmtdoublehyphen:
2468                case TBaseType.cmtslashstar:
2469                case TBaseType.lexspace:{
2470                    if (insqlpluscmd){
2471                        asourcetoken.insqlpluscmd = true;
2472                    }
2473                    break;
2474                }
2475                case TBaseType.lexnewline:{
2476                    if (insqlpluscmd){
2477                        insqlpluscmd = false;
2478                        isvalidplace = true;
2479
2480                        if (continuesqlplusatnewline) {
2481                            insqlpluscmd = true;
2482                            isvalidplace = false;
2483                            asourcetoken.insqlpluscmd = true ;
2484                        }
2485                    }
2486
2487                    if (waitingreturnforsemicolon){
2488                        isvalidplace = true;
2489                    }
2490                    if (waitingreturnforfloatdiv)
2491                    {
2492                        isvalidplace = true;
2493                        lct.tokencode = TBaseType.sqlpluscmd;
2494                        if (lct.tokentype != ETokenType.ttslash){
2495                            lct.tokentype = ETokenType.ttsqlpluscmd;
2496                        }
2497                    }
2498                    flexer.insqlpluscmd = insqlpluscmd;
2499                    break;
2500                } //case newline
2501                default:{
2502                    //solid tokentext
2503                    continuesqlplusatnewline = false;
2504                    waitingreturnforsemicolon = false;
2505                    waitingreturnforfloatdiv = false;
2506                    if (insqlpluscmd)
2507                    {
2508                        asourcetoken.insqlpluscmd = true ;
2509                        if (asourcetoken.astext.equalsIgnoreCase("-")) { continuesqlplusatnewline = true;}
2510                    }
2511                    else
2512                    {
2513                        if (asourcetoken.tokentype == ETokenType.ttsemicolon)
2514                        {waitingreturnforsemicolon = true;}
2515                        if ( (asourcetoken.tokentype == ETokenType.ttslash)
2516                                // and (isvalidplace or sourcetokenlist.TokenBeforeCurToken(#10,false,false,false)) then
2517                                && (isvalidplace ||  (IsValidPlaceForDivToSqlplusCmd(sourcetokenlist,asourcetoken.posinlist)) ) )
2518                        {
2519                            lct = asourcetoken;
2520                            waitingreturnforfloatdiv = true;
2521                        }
2522                        if ((isvalidplace) && isvalidsqlpluscmdInPostgresql(asourcetoken.astext) )
2523                        {
2524                            asourcetoken.tokencode = TBaseType.sqlpluscmd;
2525                            if (asourcetoken.tokentype != ETokenType.ttslash)
2526                            {asourcetoken.tokentype = ETokenType.ttsqlpluscmd;}
2527                            insqlpluscmd = true;
2528                            flexer.insqlpluscmd = insqlpluscmd;
2529                        }
2530                    }
2531                    isvalidplace = false;
2532
2533                    if (asourcetoken.tokencode == TBaseType.rrw_redshift_rowtype) {
2534                        TSourceToken stPercent = asourcetoken.searchToken('%', -1);
2535                        if (stPercent != null) {
2536                            stPercent.tokencode = TBaseType.rowtype_operator;
2537                        }
2538                    }
2539
2540                }
2541            }
2542
2543            //flexer.yylexwrap(asourcetoken);
2544            asourcetoken = getanewsourcetoken();
2545            if (asourcetoken != null){
2546                yychar = asourcetoken.tokencode;
2547            }else{
2548                yychar = 0;
2549
2550                if (waitingreturnforfloatdiv)
2551                { // / at the end of line treat as sqlplus command
2552                    //isvalidplace = true;
2553                    lct.tokencode = TBaseType.sqlpluscmd;
2554                    if (lct.tokentype != ETokenType.ttslash){
2555                        lct.tokentype = ETokenType.ttsqlpluscmd;
2556                    }
2557                }
2558            }
2559
2560            if ((yychar == 0) && (prevst != null))
2561            {
2562            }
2563
2564        }// while
2565    }
2566
2567    void doansitexttotokenlist(){
2568        dodb2sqltexttotokenlist();
2569    }
2570    void dogaussdbtexttotokenlist(){
2571
2572        boolean insqlpluscmd = false;
2573        boolean isvalidplace = true;
2574        boolean waitingreturnforfloatdiv = false;
2575        boolean waitingreturnforsemicolon = false;
2576        boolean continuesqlplusatnewline = false;
2577
2578        TSourceToken lct = null, prevst = null;
2579
2580        TSourceToken asourcetoken,lcprevst;
2581        int yychar;
2582
2583        asourcetoken = getanewsourcetoken();
2584        if ( asourcetoken == null ) return;
2585        yychar = asourcetoken.tokencode;
2586
2587        while (yychar > 0)
2588        {
2589            sourcetokenlist.add(asourcetoken);
2590            switch(yychar){
2591                case TBaseType.cmtdoublehyphen:
2592                case TBaseType.cmtslashstar:
2593                case TBaseType.lexspace:{
2594                    if (insqlpluscmd){
2595                        asourcetoken.insqlpluscmd = true;
2596                    }
2597                    break;
2598                }
2599                case TBaseType.lexnewline:{
2600                    if (insqlpluscmd){
2601                        insqlpluscmd = false;
2602                        isvalidplace = true;
2603
2604                        if (continuesqlplusatnewline) {
2605                            insqlpluscmd = true;
2606                            isvalidplace = false;
2607                            asourcetoken.insqlpluscmd = true ;
2608                        }
2609                    }
2610
2611                    if (waitingreturnforsemicolon){
2612                        isvalidplace = true;
2613                    }
2614                    if (waitingreturnforfloatdiv)
2615                    {
2616                        isvalidplace = true;
2617                        lct.tokencode = TBaseType.sqlpluscmd;
2618                        if (lct.tokentype != ETokenType.ttslash){
2619                            lct.tokentype = ETokenType.ttsqlpluscmd;
2620                        }
2621                    }
2622                    flexer.insqlpluscmd = insqlpluscmd;
2623                    break;
2624                } //case newline
2625                default:{
2626                    //solid tokentext
2627                    continuesqlplusatnewline = false;
2628                    waitingreturnforsemicolon = false;
2629                    waitingreturnforfloatdiv = false;
2630                    if (insqlpluscmd)
2631                    {
2632                        asourcetoken.insqlpluscmd = true ;
2633                        if (asourcetoken.astext.equalsIgnoreCase("-")) { continuesqlplusatnewline = true;}
2634                    }
2635                    else
2636                    {
2637                        if (asourcetoken.tokentype == ETokenType.ttsemicolon)
2638                        {waitingreturnforsemicolon = true;}
2639                        if ( (asourcetoken.tokentype == ETokenType.ttslash)
2640                                && (isvalidplace ||  (IsValidPlaceForDivToSqlplusCmd(sourcetokenlist,asourcetoken.posinlist)) ) )
2641                        {
2642                            lct = asourcetoken;
2643                            waitingreturnforfloatdiv = true;
2644                        }
2645                        if ((isvalidplace) && isvalidsqlpluscmdInPostgresql(asourcetoken.astext) )
2646                        {
2647                            asourcetoken.tokencode = TBaseType.sqlpluscmd;
2648                            if (asourcetoken.tokentype != ETokenType.ttslash)
2649                            {asourcetoken.tokentype = ETokenType.ttsqlpluscmd;}
2650                            insqlpluscmd = true;
2651                            flexer.insqlpluscmd = insqlpluscmd;
2652                        }
2653                    }
2654                    isvalidplace = false;
2655
2656                    // the inner keyword tokentext should be converted to TBaseType.ident when
2657                    // next solid tokentext is not join
2658
2659                    if (prevst != null)
2660                    {
2661                        if (prevst.tokencode == TBaseType.rrw_inner)//flexer.getkeywordvalue("INNER"))
2662                        {
2663                            if (asourcetoken.tokencode != flexer.getkeywordvalue("JOIN"))
2664                            {prevst.tokencode = TBaseType.ident;}
2665                        }
2666
2667
2668                        if ((prevst.tokencode == TBaseType.rrw_not)
2669                                && (asourcetoken.tokencode == flexer.getkeywordvalue("DEFERRABLE")))
2670                        {
2671                            prevst.tokencode = flexer.getkeywordvalue("NOT_DEFERRABLE");
2672                        }
2673
2674                    }
2675
2676                    if (asourcetoken.tokencode == TBaseType.rrw_inner)
2677                    {
2678                        prevst = asourcetoken;
2679                    }
2680                    else if (asourcetoken.tokencode == TBaseType.rrw_not)
2681                    {
2682                        prevst = asourcetoken;
2683                    }
2684                    else
2685                    { prevst = null;}
2686
2687                    if ((asourcetoken.tokencode == flexer.getkeywordvalue("DIRECT_LOAD"))
2688                            ||  (asourcetoken.tokencode == flexer.getkeywordvalue("ALL")) )
2689                    {
2690                        // RW_COMPRESS RW_FOR RW_ALL RW_OPERATIONS
2691                        // RW_COMPRESS RW_FOR RW_DIRECT_LOAD RW_OPERATIONS
2692                        // change rw_for to TBaseType.rw_for1, it conflicts with compress for update in create materialized view
2693
2694                        lcprevst = getprevsolidtoken(asourcetoken);
2695                        if (lcprevst != null)
2696                        {
2697                            if (lcprevst.tokencode == TBaseType.rrw_for)
2698                                lcprevst.tokencode = TBaseType.rw_for1;
2699                        }
2700                    }
2701
2702                    if (asourcetoken.tokencode == TBaseType.rrw_dense_rank){
2703                        //keep keyword can be column alias, make keep in keep_denserankclause as a different token code
2704                        TSourceToken stKeep  = asourcetoken.searchToken(TBaseType.rrw_keep,-2);
2705                        if ( stKeep != null){
2706                            stKeep.tokencode = TBaseType.rrw_keep_before_dense_rank;
2707                        }
2708                    }
2709
2710                    if ((asourcetoken.tokencode == TBaseType.rrw_postgresql_rowtype)||(asourcetoken.tokencode == TBaseType.rrw_postgresql_type)) {
2711                        TSourceToken stPercent = asourcetoken.searchToken('%', -1);
2712                        if (stPercent != null) {
2713                            stPercent.tokencode = TBaseType.rowtype_operator;
2714                        }
2715                    }
2716
2717                    if (asourcetoken.tokencode == TBaseType.JSON_EXIST) {
2718                        TSourceToken stPercent = asourcetoken.searchToken('=', -1);
2719                        if (stPercent != null) {    // = ?, ? after = should not be treated as json exist operator
2720                            asourcetoken.tokencode = TBaseType.ident;
2721                        }
2722                    }
2723
2724                    if (asourcetoken.tokencode == TBaseType.rrw_update) { // on conflict do update in insert statement
2725                        TSourceToken stDo = asourcetoken.searchToken(TBaseType.rrw_do, -1);
2726                        if (stDo != null) {
2727                            asourcetoken.tokencode = TBaseType.rrw_postgresql_do_update;
2728                        }
2729                    }
2730
2731
2732                }
2733            }
2734
2735            //flexer.yylexwrap(asourcetoken);
2736            asourcetoken = getanewsourcetoken();
2737            if (asourcetoken != null){
2738                yychar = asourcetoken.tokencode;
2739            }else{
2740                yychar = 0;
2741
2742                if (waitingreturnforfloatdiv)
2743                { // / at the end of line treat as sqlplus command
2744                    //isvalidplace = true;
2745                    lct.tokencode = TBaseType.sqlpluscmd;
2746                    if (lct.tokentype != ETokenType.ttslash){
2747                        lct.tokentype = ETokenType.ttsqlpluscmd;
2748                    }
2749                }
2750
2751            }
2752
2753            if ((yychar == 0) && (prevst != null))
2754            {
2755                if (prevst.tokencode == TBaseType.rrw_inner)// flexer.getkeywordvalue("RW_INNER"))
2756                { prevst.tokencode = TBaseType.ident;}
2757            }
2758
2759
2760        }
2761
2762
2763    }
2764    void dopostgresqltexttotokenlist(){
2765
2766        boolean insqlpluscmd = false;
2767        boolean isvalidplace = true;
2768        boolean waitingreturnforfloatdiv = false;
2769        boolean waitingreturnforsemicolon = false;
2770        boolean continuesqlplusatnewline = false;
2771
2772        TSourceToken lct = null, prevst = null;
2773
2774        TSourceToken asourcetoken,lcprevst;
2775        int yychar;
2776
2777        asourcetoken = getanewsourcetoken();
2778        if ( asourcetoken == null ) return;
2779        yychar = asourcetoken.tokencode;
2780
2781        while (yychar > 0)
2782        {
2783            sourcetokenlist.add(asourcetoken);
2784            switch(yychar){
2785                case TBaseType.cmtdoublehyphen:
2786                case TBaseType.cmtslashstar:
2787                case TBaseType.lexspace:{
2788                    if (insqlpluscmd){
2789                        asourcetoken.insqlpluscmd = true;
2790                    }
2791                    break;
2792                }
2793                case TBaseType.lexnewline:{
2794                    if (insqlpluscmd){
2795                        insqlpluscmd = false;
2796                        isvalidplace = true;
2797
2798                        if (continuesqlplusatnewline) {
2799                            insqlpluscmd = true;
2800                            isvalidplace = false;
2801                            asourcetoken.insqlpluscmd = true ;
2802                        }
2803                    }
2804
2805                    if (waitingreturnforsemicolon){
2806                        isvalidplace = true;
2807                    }
2808                    if (waitingreturnforfloatdiv)
2809                    {
2810                        isvalidplace = true;
2811                        lct.tokencode = TBaseType.sqlpluscmd;
2812                        if (lct.tokentype != ETokenType.ttslash){
2813                            lct.tokentype = ETokenType.ttsqlpluscmd;
2814                        }
2815                    }
2816                    flexer.insqlpluscmd = insqlpluscmd;
2817                    break;
2818                } //case newline
2819                default:{
2820                    //solid tokentext
2821                    continuesqlplusatnewline = false;
2822                    waitingreturnforsemicolon = false;
2823                    waitingreturnforfloatdiv = false;
2824                    if (insqlpluscmd)
2825                    {
2826                        asourcetoken.insqlpluscmd = true ;
2827                        if (asourcetoken.astext.equalsIgnoreCase("-")) { continuesqlplusatnewline = true;}
2828                    }
2829                    else
2830                    {
2831                        if (asourcetoken.tokentype == ETokenType.ttsemicolon)
2832                        {waitingreturnforsemicolon = true;}
2833                        if ( (asourcetoken.tokentype == ETokenType.ttslash)
2834                                // and (isvalidplace or sourcetokenlist.TokenBeforeCurToken(#10,false,false,false)) then
2835                                && (isvalidplace ||  (IsValidPlaceForDivToSqlplusCmd(sourcetokenlist,asourcetoken.posinlist)) ) )
2836                        {
2837                            lct = asourcetoken;
2838                            waitingreturnforfloatdiv = true;
2839                        }
2840                        if ((isvalidplace) && isvalidsqlpluscmdInPostgresql(asourcetoken.astext) )
2841                        {
2842                            asourcetoken.tokencode = TBaseType.sqlpluscmd;
2843                            if (asourcetoken.tokentype != ETokenType.ttslash)
2844                            {asourcetoken.tokentype = ETokenType.ttsqlpluscmd;}
2845                            insqlpluscmd = true;
2846                            flexer.insqlpluscmd = insqlpluscmd;
2847                        }
2848                    }
2849                    isvalidplace = false;
2850
2851                    // the inner keyword tokentext should be convert to TBaseType.ident when
2852                    // next solid tokentext is not join
2853
2854                    if (prevst != null)
2855                    {
2856                        if (prevst.tokencode == TBaseType.rrw_inner)//flexer.getkeywordvalue("INNER"))
2857                        {
2858                            if (asourcetoken.tokencode != flexer.getkeywordvalue("JOIN"))
2859                            {prevst.tokencode = TBaseType.ident;}
2860                        }
2861
2862
2863                        if ((prevst.tokencode == TBaseType.rrw_not)
2864                                && (asourcetoken.tokencode == flexer.getkeywordvalue("DEFERRABLE")))
2865                        {
2866                            prevst.tokencode = flexer.getkeywordvalue("NOT_DEFERRABLE");
2867                        }
2868
2869                    }
2870
2871                    if (asourcetoken.tokencode == TBaseType.rrw_inner)
2872                    {
2873                        prevst = asourcetoken;
2874                    }
2875                    else if (asourcetoken.tokencode == TBaseType.rrw_not)
2876                    {
2877                        prevst = asourcetoken;
2878                    }
2879                    else
2880                    { prevst = null;}
2881
2882                    if ((asourcetoken.tokencode == flexer.getkeywordvalue("DIRECT_LOAD"))
2883                            ||  (asourcetoken.tokencode == flexer.getkeywordvalue("ALL")) )
2884                    {
2885                        // RW_COMPRESS RW_FOR RW_ALL RW_OPERATIONS
2886                        // RW_COMPRESS RW_FOR RW_DIRECT_LOAD RW_OPERATIONS
2887                        // change rw_for to TBaseType.rw_for1, it conflicts with compress for update in create materialized view
2888
2889                        lcprevst = getprevsolidtoken(asourcetoken);
2890                        if (lcprevst != null)
2891                        {
2892                            if (lcprevst.tokencode == TBaseType.rrw_for)
2893                                lcprevst.tokencode = TBaseType.rw_for1;
2894                        }
2895                    }
2896
2897                    if (asourcetoken.tokencode == TBaseType.rrw_dense_rank){
2898                        //keep keyword can be column alias, make keep in keep_denserankclause as a different token code
2899                        TSourceToken stKeep  = asourcetoken.searchToken(TBaseType.rrw_keep,-2);
2900                        if ( stKeep != null){
2901                            stKeep.tokencode = TBaseType.rrw_keep_before_dense_rank;
2902                        }
2903                    }
2904
2905                    if ((asourcetoken.tokencode == TBaseType.rrw_postgresql_rowtype)||(asourcetoken.tokencode == TBaseType.rrw_postgresql_type)) {
2906                        TSourceToken stPercent = asourcetoken.searchToken('%', -1);
2907                        if (stPercent != null) {
2908                            stPercent.tokencode = TBaseType.rowtype_operator;
2909                        }
2910                    }
2911
2912                    if (asourcetoken.tokencode == TBaseType.JSON_EXIST) {
2913                        TSourceToken stPercent = asourcetoken.searchToken('=', -1);
2914                        if (stPercent != null) {    // = ?, ? after = should not be treated as json exist operator
2915                            asourcetoken.tokencode = TBaseType.ident;
2916                        }
2917                    }
2918
2919                    if (asourcetoken.tokencode == TBaseType.rrw_update) { // on conflict do update in insert statement
2920                        TSourceToken stDo = asourcetoken.searchToken(TBaseType.rrw_do, -1);
2921                        if (stDo != null) {
2922                            asourcetoken.tokencode = TBaseType.rrw_postgresql_do_update;
2923                        }
2924                    }
2925
2926
2927                }
2928            }
2929
2930            //flexer.yylexwrap(asourcetoken);
2931            asourcetoken = getanewsourcetoken();
2932            if (asourcetoken != null){
2933                yychar = asourcetoken.tokencode;
2934            }else{
2935                yychar = 0;
2936
2937                if (waitingreturnforfloatdiv)
2938                { // / at the end of line treat as sqlplus command
2939                    //isvalidplace = true;
2940                    lct.tokencode = TBaseType.sqlpluscmd;
2941                    if (lct.tokentype != ETokenType.ttslash){
2942                        lct.tokentype = ETokenType.ttsqlpluscmd;
2943                    }
2944                }
2945
2946            }
2947
2948            if ((yychar == 0) && (prevst != null))
2949            {
2950                if (prevst.tokencode == TBaseType.rrw_inner)// flexer.getkeywordvalue("RW_INNER"))
2951                { prevst.tokencode = TBaseType.ident;}
2952            }
2953
2954
2955        }
2956
2957
2958    }
2959
2960void dosnowflakesqltexttotokenlist(){
2961
2962    boolean insqlpluscmd = false;
2963    boolean isvalidplace = true;
2964    boolean waitingreturnforfloatdiv = false;
2965    boolean waitingreturnforsemicolon = false;
2966    boolean continuesqlplusatnewline = false;
2967
2968    TSourceToken lct = null, prevst = null;
2969
2970    TSourceToken asourcetoken,lcprevst;
2971    int yychar;
2972
2973    asourcetoken = getanewsourcetoken();
2974    if ( asourcetoken == null ) return;
2975    yychar = asourcetoken.tokencode;
2976
2977    while (yychar > 0)
2978      {
2979        sourcetokenlist.add(asourcetoken);
2980        switch(yychar){
2981            case TBaseType.cmtdoublehyphen:
2982            case TBaseType.cmtslashstar:
2983            case TBaseType.lexspace:{
2984               if (insqlpluscmd){
2985                   asourcetoken.insqlpluscmd = true;
2986               }
2987               break;
2988            }
2989            case TBaseType.lexnewline:{
2990                if (insqlpluscmd){
2991                    insqlpluscmd = false;
2992                    isvalidplace = true;
2993
2994                    if (continuesqlplusatnewline) {
2995                        insqlpluscmd = true;
2996                        isvalidplace = false;
2997                        asourcetoken.insqlpluscmd = true ;
2998                    }
2999                }
3000
3001                if (waitingreturnforsemicolon){
3002                  isvalidplace = true;
3003                }
3004                if (waitingreturnforfloatdiv)
3005                {
3006                    isvalidplace = true;
3007                    lct.tokencode = TBaseType.sqlpluscmd;
3008                    if (lct.tokentype != ETokenType.ttslash){
3009                      lct.tokentype = ETokenType.ttsqlpluscmd;
3010                    }
3011                }
3012                flexer.insqlpluscmd = insqlpluscmd;
3013                break;
3014            } //case newline
3015            default:{
3016                //solid tokentext
3017                continuesqlplusatnewline = false;
3018                waitingreturnforsemicolon = false;
3019                waitingreturnforfloatdiv = false;
3020                if (insqlpluscmd)
3021                {
3022                    asourcetoken.insqlpluscmd = true ;
3023                    if (asourcetoken.astext.equalsIgnoreCase("-")) { continuesqlplusatnewline = true;}
3024                }
3025                else
3026                {
3027                    if (asourcetoken.tokentype == ETokenType.ttsemicolon)
3028                    {waitingreturnforsemicolon = true;}
3029                    if ( (asourcetoken.tokentype == ETokenType.ttslash)
3030                      // and (isvalidplace or sourcetokenlist.TokenBeforeCurToken(#10,false,false,false)) then
3031                       && (isvalidplace ||  (IsValidPlaceForDivToSqlplusCmd(sourcetokenlist,asourcetoken.posinlist)) ) )
3032                    {
3033                        lct = asourcetoken;
3034                        waitingreturnforfloatdiv = true;
3035                    }
3036                    if ((isvalidplace) && isvalidsqlpluscmdInPostgresql(asourcetoken.astext) )
3037                    {
3038                        asourcetoken.tokencode = TBaseType.sqlpluscmd;
3039                        if (asourcetoken.tokentype != ETokenType.ttslash)
3040                        {asourcetoken.tokentype = ETokenType.ttsqlpluscmd;}
3041                        insqlpluscmd = true;
3042                        flexer.insqlpluscmd = insqlpluscmd;
3043                    }
3044                }
3045                isvalidplace = false;
3046
3047                // the inner keyword tokentext should be convert to TBaseType.ident when
3048                // next solid tokentext is not join
3049
3050                 if (prevst != null)
3051                 {
3052                    if (prevst.tokencode == TBaseType.rrw_inner)//flexer.getkeywordvalue("INNER"))
3053                    {
3054                        if (asourcetoken.tokencode != flexer.getkeywordvalue("JOIN"))
3055                        {prevst.tokencode = TBaseType.ident;}
3056                    }
3057
3058
3059                    if ((prevst.tokencode == TBaseType.rrw_not)
3060                    && (asourcetoken.tokencode == flexer.getkeywordvalue("DEFERRABLE")))
3061                    {
3062                          prevst.tokencode = flexer.getkeywordvalue("NOT_DEFERRABLE");
3063                    }
3064
3065                 }
3066
3067                if (asourcetoken.tokencode == TBaseType.rrw_inner)
3068                {
3069                    prevst = asourcetoken;
3070                }
3071                else if (asourcetoken.tokencode == TBaseType.rrw_not)
3072                {
3073                     prevst = asourcetoken;
3074                }
3075                else
3076                { prevst = null;}
3077
3078
3079            }
3080        }
3081
3082         //flexer.yylexwrap(asourcetoken);
3083         asourcetoken = getanewsourcetoken();
3084         if (asourcetoken != null){
3085             yychar = asourcetoken.tokencode;
3086         }else{
3087           yychar = 0;
3088
3089             if (waitingreturnforfloatdiv)
3090             { // / at the end of line treat as sqlplus command
3091                 //isvalidplace = true;
3092                 lct.tokencode = TBaseType.sqlpluscmd;
3093                 if (lct.tokentype != ETokenType.ttslash){
3094                   lct.tokentype = ETokenType.ttsqlpluscmd;
3095                 }
3096             }
3097
3098         }
3099
3100          if ((yychar == 0) && (prevst != null))
3101          {
3102              if (prevst.tokencode == TBaseType.rrw_inner)// flexer.getkeywordvalue("RW_INNER"))
3103              { prevst.tokencode = TBaseType.ident;}
3104          }
3105
3106
3107      } // while
3108
3109
3110}
3111
3112    void doverticatexttotokenlist(){
3113        dopostgresqltexttotokenlist();
3114    }
3115
3116    void docouchbasesqltexttotokenlist(){
3117        dopostgresqltexttotokenlist();
3118    }
3119
3120    /**
3121     * Turn one token: `schema.table_name` into 3 tokens: `schema` . `table_name`
3122     * @param asourcetoken
3123     * @return
3124     */
3125    int splitQualifiedNameInBacktick(TSourceToken asourcetoken){
3126        int yychar = 0;
3127
3128        List<String> elephantList = Arrays.asList(TBaseType.getTextWithoutQuoted(asourcetoken.toString()).split("\\."));
3129        int p = 0,offset=0;
3130        for(String s:elephantList){
3131            TSourceToken pst = new TSourceToken("`"+s+"`");
3132            pst.tokencode = asourcetoken.tokencode;
3133            pst.tokentype =  asourcetoken.tokentype;
3134            pst.tokenstatus = asourcetoken.tokenstatus;
3135            pst.lineNo = asourcetoken.lineNo;
3136            pst.columnNo = asourcetoken.columnNo+offset;
3137            if (p==0) offset++;// this count the first ` token
3138            offset = offset+s.length();
3139            pst.container = sourcetokenlist;
3140            if (p>0){// 第一个token使用被拆分前那个token的位置,从第二个开始的token,需要先把列表的位置指针加 1
3141                sourcetokenlist.curpos = sourcetokenlist.curpos+1;
3142            }
3143            pst.posinlist = sourcetokenlist.curpos;
3144
3145            sourcetokenlist.add(pst);
3146            yychar = pst.tokencode;
3147
3148            if (p != elephantList.size()-1){
3149                //`schema.table_name`, add period token in the middle of the backtick included identifier.
3150                TSourceToken periodst = new TSourceToken(".");
3151                periodst.tokencode = '.';
3152                periodst.tokentype =  ETokenType.ttperiod;
3153                periodst.tokenstatus = asourcetoken.tokenstatus;
3154                periodst.lineNo = asourcetoken.lineNo;
3155                periodst.columnNo = asourcetoken.columnNo + offset;
3156                offset++;
3157                periodst.container = sourcetokenlist;
3158                sourcetokenlist.curpos = sourcetokenlist.curpos+1;
3159                periodst.posinlist = sourcetokenlist.curpos;
3160                sourcetokenlist.add(periodst);
3161                yychar = periodst.tokencode;
3162            }
3163
3164            p++;
3165            //System.out.println(s);
3166        }
3167
3168        return yychar;
3169
3170    }
3171
3172    void dobigquerysqltexttotokenlist(){
3173        TSourceToken asourcetoken,lcprevst;
3174        int yychar;
3175
3176
3177        flexer.tmpDelimiter = "";
3178
3179        asourcetoken = getanewsourcetoken();
3180        if ( asourcetoken == null ) return;
3181        yychar = asourcetoken.tokencode;
3182
3183        while (yychar > 0)
3184        {
3185            if (asourcetoken != null){
3186                sourcetokenlist.add(asourcetoken);
3187            }
3188
3189            asourcetoken = getanewsourcetoken();
3190            if ( asourcetoken == null ) break;
3191            yychar = asourcetoken.tokencode;
3192
3193            // `schema.table_name`
3194            if ((asourcetoken.tokencode == TBaseType.ident)
3195                    && (asourcetoken.toString().startsWith("`"))&& (asourcetoken.toString().endsWith("`"))
3196                    && (asourcetoken.toString().indexOf(".")>0)
3197            ){
3198                yychar = splitQualifiedNameInBacktick(asourcetoken);
3199                asourcetoken = null;
3200            }
3201        }
3202    }
3203
3204    void dosoqlsqltexttotokenlist(){
3205        domssqlsqltexttotokenlist();
3206    }
3207
3208void dogreenplumtexttotokenlist(){
3209
3210        boolean insqlpluscmd = false;
3211        boolean isvalidplace = true;
3212        boolean waitingreturnforfloatdiv = false;
3213        boolean waitingreturnforsemicolon = false;
3214        boolean continuesqlplusatnewline = false;
3215
3216        TSourceToken lct = null, prevst = null;
3217
3218        TSourceToken asourcetoken,lcprevst;
3219        int yychar;
3220
3221        asourcetoken = getanewsourcetoken();
3222        if ( asourcetoken == null ) return;
3223        yychar = asourcetoken.tokencode;
3224
3225        while (yychar > 0)
3226          {
3227            sourcetokenlist.add(asourcetoken);
3228            switch(yychar){
3229                case TBaseType.cmtdoublehyphen:
3230                case TBaseType.cmtslashstar:
3231                case TBaseType.lexspace:{
3232                   if (insqlpluscmd){
3233                       asourcetoken.insqlpluscmd = true;
3234                   }
3235                   break;
3236                }
3237                case TBaseType.lexnewline:{
3238                    if (insqlpluscmd){
3239                        insqlpluscmd = false;
3240                        isvalidplace = true;
3241
3242                        if (continuesqlplusatnewline) {
3243                            insqlpluscmd = true;
3244                            isvalidplace = false;
3245                            asourcetoken.insqlpluscmd = true ;
3246                        }
3247                    }
3248
3249                    if (waitingreturnforsemicolon){
3250                      isvalidplace = true;
3251                    }
3252                    if (waitingreturnforfloatdiv)
3253                    {
3254                        isvalidplace = true;
3255                        lct.tokencode = TBaseType.sqlpluscmd;
3256                        if (lct.tokentype != ETokenType.ttslash){
3257                          lct.tokentype = ETokenType.ttsqlpluscmd;
3258                        }
3259                    }
3260                    flexer.insqlpluscmd = insqlpluscmd;
3261                    break;
3262                } //case newline
3263                default:{
3264                    //solid tokentext
3265                    continuesqlplusatnewline = false;
3266                    waitingreturnforsemicolon = false;
3267                    waitingreturnforfloatdiv = false;
3268                    if (insqlpluscmd)
3269                    {
3270                        asourcetoken.insqlpluscmd = true ;
3271                        if (asourcetoken.astext.equalsIgnoreCase("-")) { continuesqlplusatnewline = true;}
3272                    }
3273                    else
3274                    {
3275                        if (asourcetoken.tokentype == ETokenType.ttsemicolon)
3276                        {waitingreturnforsemicolon = true;}
3277                        if ( (asourcetoken.tokentype == ETokenType.ttslash)
3278                          // and (isvalidplace or sourcetokenlist.TokenBeforeCurToken(#10,false,false,false)) then
3279                           && (isvalidplace ||  (IsValidPlaceForDivToSqlplusCmd(sourcetokenlist,asourcetoken.posinlist)) ) )
3280                        {
3281                            lct = asourcetoken;
3282                            waitingreturnforfloatdiv = true;
3283                        }
3284                        if ((isvalidplace) && isvalidsqlpluscmdInPostgresql(asourcetoken.astext) )
3285                        {
3286                            asourcetoken.tokencode = TBaseType.sqlpluscmd;
3287                            if (asourcetoken.tokentype != ETokenType.ttslash)
3288                            {asourcetoken.tokentype = ETokenType.ttsqlpluscmd;}
3289                            insqlpluscmd = true;
3290                            flexer.insqlpluscmd = insqlpluscmd;
3291                        }
3292                    }
3293                    isvalidplace = false;
3294
3295                    // the inner keyword tokentext should be convert to TBaseType.ident when
3296                    // next solid tokentext is not join
3297
3298                     if (prevst != null)
3299                     {
3300                        if (prevst.tokencode == TBaseType.rrw_inner)//flexer.getkeywordvalue("INNER"))
3301                        {
3302                            if (asourcetoken.tokencode != flexer.getkeywordvalue("JOIN"))
3303                            {prevst.tokencode = TBaseType.ident;}
3304                        }
3305
3306
3307                        if ((prevst.tokencode == TBaseType.rrw_not)
3308                        && (asourcetoken.tokencode == flexer.getkeywordvalue("DEFERRABLE")))
3309                        {
3310                              prevst.tokencode = flexer.getkeywordvalue("NOT_DEFERRABLE");
3311                        }
3312
3313                     }
3314
3315                    if (asourcetoken.tokencode == TBaseType.rrw_inner)
3316                    {
3317                        prevst = asourcetoken;
3318                    }
3319                    else if (asourcetoken.tokencode == TBaseType.rrw_not)
3320                    {
3321                         prevst = asourcetoken;
3322                    }
3323                    else
3324                    { prevst = null;}
3325
3326                    if ((asourcetoken.tokencode == flexer.getkeywordvalue("DIRECT_LOAD"))
3327                    ||  (asourcetoken.tokencode == flexer.getkeywordvalue("ALL")) )
3328                    {
3329                        // RW_COMPRESS RW_FOR RW_ALL RW_OPERATIONS
3330                        // RW_COMPRESS RW_FOR RW_DIRECT_LOAD RW_OPERATIONS
3331                        // change rw_for to TBaseType.rw_for1, it conflicts with compress for update in create materialized view
3332
3333                        lcprevst = getprevsolidtoken(asourcetoken);
3334                        if (lcprevst != null)
3335                        {
3336                            if (lcprevst.tokencode == TBaseType.rrw_for)
3337                              lcprevst.tokencode = TBaseType.rw_for1;
3338                        }
3339                    }
3340
3341                    if (asourcetoken.tokencode == TBaseType.rrw_dense_rank){
3342                        //keep keyword can be column alias, make keep in keep_denserankclause as a different token code
3343                        TSourceToken stKeep  = asourcetoken.searchToken(TBaseType.rrw_keep,-2);
3344                        if ( stKeep != null){
3345                            stKeep.tokencode = TBaseType.rrw_keep_before_dense_rank;
3346                        }
3347                    }
3348
3349                    if (asourcetoken.tokencode == TBaseType.rrw_greenplum_rowtype) {
3350                        TSourceToken stPercent = asourcetoken.searchToken('%', -1);
3351                        if (stPercent != null) {
3352                            stPercent.tokencode = TBaseType.rowtype_operator;
3353                        }
3354                    }
3355
3356
3357                }
3358            }
3359
3360             //flexer.yylexwrap(asourcetoken);
3361             asourcetoken = getanewsourcetoken();
3362             if (asourcetoken != null){
3363                 yychar = asourcetoken.tokencode;
3364             }else{
3365               yychar = 0;
3366
3367                 if (waitingreturnforfloatdiv)
3368                 { // / at the end of line treat as sqlplus command
3369                     //isvalidplace = true;
3370                     lct.tokencode = TBaseType.sqlpluscmd;
3371                     if (lct.tokentype != ETokenType.ttslash){
3372                       lct.tokentype = ETokenType.ttsqlpluscmd;
3373                     }
3374                 }
3375
3376             }
3377
3378              if ((yychar == 0) && (prevst != null))
3379              {
3380                  if (prevst.tokencode == TBaseType.rrw_inner)// flexer.getkeywordvalue("RW_INNER"))
3381                  { prevst.tokencode = TBaseType.ident;}
3382              }
3383
3384
3385          }
3386
3387
3388    }
3389
3390void donetezzatexttotokenlist(){
3391
3392    boolean insqlpluscmd = false;
3393    boolean isvalidplace = true;
3394    boolean waitingreturnforfloatdiv = false;
3395    boolean waitingreturnforsemicolon = false;
3396    boolean continuesqlplusatnewline = false;
3397
3398    TSourceToken lct = null, prevst = null;
3399
3400    TSourceToken asourcetoken,lcprevst;
3401    int yychar;
3402
3403    asourcetoken = getanewsourcetoken();
3404    if ( asourcetoken == null ) return;
3405    yychar = asourcetoken.tokencode;
3406
3407    while (yychar > 0)
3408      {
3409        sourcetokenlist.add(asourcetoken);
3410        switch(yychar){
3411            case TBaseType.cmtdoublehyphen:
3412            case TBaseType.cmtslashstar:
3413            case TBaseType.lexspace:{
3414               if (insqlpluscmd){
3415                   asourcetoken.insqlpluscmd = true;
3416               }
3417               break;
3418            }
3419            case TBaseType.lexnewline:{
3420                if (insqlpluscmd){
3421                    insqlpluscmd = false;
3422                    isvalidplace = true;
3423
3424                    if (continuesqlplusatnewline) {
3425                        insqlpluscmd = true;
3426                        isvalidplace = false;
3427                        asourcetoken.insqlpluscmd = true ;
3428                    }
3429                }
3430
3431                if (waitingreturnforsemicolon){
3432                  isvalidplace = true;
3433                }
3434                if (waitingreturnforfloatdiv)
3435                {
3436                    isvalidplace = true;
3437                    lct.tokencode = TBaseType.sqlpluscmd;
3438                    if (lct.tokentype != ETokenType.ttslash){
3439                      lct.tokentype = ETokenType.ttsqlpluscmd;
3440                    }
3441                }
3442                flexer.insqlpluscmd = insqlpluscmd;
3443                break;
3444            } //case newline
3445            default:{
3446                //solid tokentext
3447                continuesqlplusatnewline = false;
3448                waitingreturnforsemicolon = false;
3449                waitingreturnforfloatdiv = false;
3450                if (insqlpluscmd)
3451                {
3452                    asourcetoken.insqlpluscmd = true ;
3453                    if (asourcetoken.astext.equalsIgnoreCase("-")) { continuesqlplusatnewline = true;}
3454                }
3455                else
3456                {
3457                    if (asourcetoken.tokentype == ETokenType.ttsemicolon)
3458                    {waitingreturnforsemicolon = true;}
3459                    if ( (asourcetoken.tokentype == ETokenType.ttslash)
3460                      // and (isvalidplace or sourcetokenlist.TokenBeforeCurToken(#10,false,false,false)) then
3461                       && (isvalidplace ||  (IsValidPlaceForDivToSqlplusCmd(sourcetokenlist,asourcetoken.posinlist)) ) )
3462                    {
3463                        lct = asourcetoken;
3464                        waitingreturnforfloatdiv = true;
3465                    }
3466                    if ((isvalidplace) && isvalidsqlpluscmdInPostgresql(asourcetoken.astext) )
3467                    {
3468                        asourcetoken.tokencode = TBaseType.sqlpluscmd;
3469                        if (asourcetoken.tokentype != ETokenType.ttslash)
3470                        {asourcetoken.tokentype = ETokenType.ttsqlpluscmd;}
3471                        insqlpluscmd = true;
3472                        flexer.insqlpluscmd = insqlpluscmd;
3473                    }
3474                }
3475                isvalidplace = false;
3476
3477                // the inner keyword tokentext should be convert to TBaseType.ident when
3478                // next solid tokentext is not join
3479
3480                 if (prevst != null)
3481                 {
3482                    if (prevst.tokencode == TBaseType.rrw_inner)//flexer.getkeywordvalue("INNER"))
3483                    {
3484                        if (asourcetoken.tokencode != flexer.getkeywordvalue("JOIN"))
3485                        {prevst.tokencode = TBaseType.ident;}
3486                    }
3487
3488
3489                    if ((prevst.tokencode == TBaseType.rrw_not)
3490                    && (asourcetoken.tokencode == flexer.getkeywordvalue("DEFERRABLE")))
3491                    {
3492                          prevst.tokencode = flexer.getkeywordvalue("NOT_DEFERRABLE");
3493                    }
3494
3495                 }
3496
3497                if (asourcetoken.tokencode == TBaseType.rrw_inner)
3498                {
3499                    prevst = asourcetoken;
3500                }
3501                else if (asourcetoken.tokencode == TBaseType.rrw_not)
3502                {
3503                     prevst = asourcetoken;
3504                }
3505                else
3506                { prevst = null;}
3507
3508                if ((asourcetoken.tokencode == flexer.getkeywordvalue("DIRECT_LOAD"))
3509                ||  (asourcetoken.tokencode == flexer.getkeywordvalue("ALL")) )
3510                {
3511                    // RW_COMPRESS RW_FOR RW_ALL RW_OPERATIONS
3512                    // RW_COMPRESS RW_FOR RW_DIRECT_LOAD RW_OPERATIONS
3513                    // change rw_for to TBaseType.rw_for1, it conflicts with compress for update in create materialized view
3514
3515                    lcprevst = getprevsolidtoken(asourcetoken);
3516                    if (lcprevst != null)
3517                    {
3518                        if (lcprevst.tokencode == TBaseType.rrw_for)
3519                          lcprevst.tokencode = TBaseType.rw_for1;
3520                    }
3521                }
3522
3523                if (asourcetoken.tokencode == TBaseType.rrw_dense_rank){
3524                    //keep keyword can be column alias, make keep in keep_denserankclause as a different token code
3525                    TSourceToken stKeep  = asourcetoken.searchToken(TBaseType.rrw_keep,-2);
3526                    if ( stKeep != null){
3527                        stKeep.tokencode = TBaseType.rrw_keep_before_dense_rank;
3528                    }
3529                }
3530
3531
3532            }
3533        }
3534
3535         //flexer.yylexwrap(asourcetoken);
3536         asourcetoken = getanewsourcetoken();
3537         if (asourcetoken != null){
3538             yychar = asourcetoken.tokencode;
3539         }else{
3540           yychar = 0;
3541
3542             if (waitingreturnforfloatdiv)
3543             { // / at the end of line treat as sqlplus command
3544                 //isvalidplace = true;
3545                 lct.tokencode = TBaseType.sqlpluscmd;
3546                 if (lct.tokentype != ETokenType.ttslash){
3547                   lct.tokentype = ETokenType.ttsqlpluscmd;
3548                 }
3549             }
3550
3551         }
3552
3553          if ((yychar == 0) && (prevst != null))
3554          {
3555              if (prevst.tokencode == TBaseType.rrw_inner)// flexer.getkeywordvalue("RW_INNER"))
3556              { prevst.tokencode = TBaseType.ident;}
3557          }
3558
3559
3560      }
3561}
3562
3563private boolean spaceAtTheEndOfReturnToken(String s){
3564    int pos = 0;
3565    if (s == null) return false;
3566    if (s.length() == 0) return false;
3567
3568    return ((s.charAt(s.length() -1 ) == ' ')||(s.charAt(s.length() -1 ) == '\t'));
3569}
3570
3571private int countLines(String s){
3572    int pos = 0, lf = 0, cr = 0;
3573
3574    while (pos < s.length()) {
3575        if (s.charAt(pos) == '\r') {
3576            cr++;
3577            pos++;
3578            continue;
3579        }
3580        if (s.charAt(pos) == '\n') {
3581            lf++;
3582            pos++;
3583            continue;
3584        }
3585
3586        if (s.charAt(pos) == ' ') {
3587            pos++;
3588            continue;
3589        }
3590        break;
3591    }
3592
3593    if (lf >= cr) return lf;
3594    else return  cr;
3595
3596 }
3597
3598void dooraclesqltexttotokenlist(){
3599
3600    boolean insqlpluscmd = false;
3601    boolean isvalidplace = true;
3602    boolean waitingreturnforfloatdiv = false;
3603    boolean waitingreturnforsemicolon = false;
3604    boolean continuesqlplusatnewline = false;
3605
3606    ESqlPlusCmd currentCmdType = ESqlPlusCmd.spcUnknown;
3607
3608    TSourceToken lct = null, prevst = null;
3609
3610    TSourceToken asourcetoken,lcprevst;
3611    int yychar;
3612
3613    asourcetoken = getanewsourcetoken();
3614    if ( asourcetoken == null ) return;
3615    yychar = asourcetoken.tokencode;
3616
3617    while (yychar > 0)
3618      {
3619        sourcetokenlist.add(asourcetoken);
3620        switch(yychar){
3621            case TBaseType.cmtdoublehyphen:
3622            case TBaseType.cmtslashstar:
3623            case TBaseType.lexspace:{
3624               if (insqlpluscmd){
3625                   asourcetoken.insqlpluscmd = true;
3626               }
3627               break;
3628            }
3629            case TBaseType.lexnewline:{
3630                if (insqlpluscmd){
3631                    insqlpluscmd = false;
3632                    isvalidplace = true;
3633
3634                    if (continuesqlplusatnewline) {
3635                        insqlpluscmd = true;
3636                        isvalidplace = false;
3637                        asourcetoken.insqlpluscmd = true ;
3638                    }
3639
3640                    if (!insqlpluscmd){
3641                        currentCmdType = ESqlPlusCmd.spcUnknown;
3642                    }
3643                }
3644
3645                if (waitingreturnforsemicolon){
3646                  isvalidplace = true;
3647                }
3648                if (waitingreturnforfloatdiv)
3649                {
3650                    isvalidplace = true;
3651                    lct.tokencode = TBaseType.sqlpluscmd;
3652                    if (lct.tokentype != ETokenType.ttslash){
3653                      lct.tokentype = ETokenType.ttsqlpluscmd;
3654                    }
3655                }
3656
3657                if (countLines(asourcetoken.toString()) > 1){
3658//                    SELECT *
3659//                            FROM foobar
3660//
3661//                    spool file
3662
3663                    // there is a line after select, so spool is the right place to start a sqlplus command
3664                    isvalidplace = true;
3665                }
3666
3667                flexer.insqlpluscmd = insqlpluscmd;
3668                break;
3669            } //case newline
3670            default:{
3671                //solid tokentext
3672                continuesqlplusatnewline = false;
3673                waitingreturnforsemicolon = false;
3674                waitingreturnforfloatdiv = false;
3675                if (insqlpluscmd)
3676                {
3677                    asourcetoken.insqlpluscmd = true ;
3678                    if (asourcetoken.astext.equalsIgnoreCase("-")) { continuesqlplusatnewline = true;}
3679                }
3680                else
3681                {
3682                    if (asourcetoken.tokentype == ETokenType.ttsemicolon)
3683                        {waitingreturnforsemicolon = true;}
3684                    if ( (asourcetoken.tokentype == ETokenType.ttslash)
3685                      // and (isvalidplace or sourcetokenlist.TokenBeforeCurToken(#10,false,false,false)) then
3686                       && (isvalidplace ||  (IsValidPlaceForDivToSqlplusCmd(sourcetokenlist,asourcetoken.posinlist)) ) )
3687                    {
3688                        lct = asourcetoken;
3689                        waitingreturnforfloatdiv = true;
3690                    }
3691
3692                    currentCmdType =  TSqlplusCmdStatement.searchCmd(asourcetoken.astext,asourcetoken.nextToken());
3693                    // if (isvalidsqlpluscmd(asourcetoken.astext)){
3694                    if ( currentCmdType != ESqlPlusCmd.spcUnknown){
3695                        if (isvalidplace)
3696                        {
3697
3698                            TSourceToken lnbreak = null;
3699                            boolean aRealSqlplusCmd = true;
3700                            if (sourcetokenlist.curpos >0){
3701                                lnbreak = sourcetokenlist.get(sourcetokenlist.curpos - 1);
3702                                aRealSqlplusCmd = !spaceAtTheEndOfReturnToken(lnbreak.toString());
3703                            }
3704
3705
3706//                            if ((countLines(lnbreak.toString()) > 1) && (!spaceAtTheEndOfReturnToken(lnbreak.toString()))) {
3707                            if (aRealSqlplusCmd) {
3708                                asourcetoken.prevTokenCode = asourcetoken.tokencode;
3709                                asourcetoken.tokencode = TBaseType.sqlpluscmd;
3710                                if (asourcetoken.tokentype != ETokenType.ttslash)
3711                                {asourcetoken.tokentype = ETokenType.ttsqlpluscmd;}
3712                                insqlpluscmd = true;
3713                                flexer.insqlpluscmd = insqlpluscmd;
3714                            }
3715
3716                        }else if ((asourcetoken.tokencode == TBaseType.rrw_connect)&&(sourcetokenlist.returnbeforecurtoken(true))){
3717                            asourcetoken.tokencode = TBaseType.sqlpluscmd;
3718                            if (asourcetoken.tokentype != ETokenType.ttslash)
3719                            {asourcetoken.tokentype = ETokenType.ttsqlpluscmd;}
3720                            insqlpluscmd = true;
3721                            flexer.insqlpluscmd = insqlpluscmd;
3722                        }else if(sourcetokenlist.returnbeforecurtoken(true)){
3723                            TSourceToken lnbreak = sourcetokenlist.get(sourcetokenlist.curpos - 1);
3724
3725                            if ((countLines(lnbreak.toString()) > 1) && (!spaceAtTheEndOfReturnToken(lnbreak.toString()))) {
3726                                asourcetoken.tokencode = TBaseType.sqlpluscmd;
3727                                if (asourcetoken.tokentype != ETokenType.ttslash)
3728                                {asourcetoken.tokentype = ETokenType.ttsqlpluscmd;}
3729                                insqlpluscmd = true;
3730                                flexer.insqlpluscmd = insqlpluscmd;
3731                            }
3732                        }
3733                    }
3734
3735                }
3736                isvalidplace = false;
3737
3738                // the inner keyword tokentext should be convert to TBaseType.ident when
3739                // next solid tokentext is not join
3740
3741                 if (prevst != null)
3742                 {
3743                    if (prevst.tokencode == TBaseType.rrw_inner)//flexer.getkeywordvalue("INNER"))
3744                    {
3745                        if (asourcetoken.tokencode != flexer.getkeywordvalue("JOIN"))
3746                        {prevst.tokencode = TBaseType.ident;}
3747                    }else if ((prevst.tokencode == TBaseType.rrw_not)
3748                    && (asourcetoken.tokencode == flexer.getkeywordvalue("DEFERRABLE")))
3749                    {
3750                          prevst.tokencode = flexer.getkeywordvalue("NOT_DEFERRABLE");
3751                    }
3752
3753                 }
3754
3755                if (asourcetoken.tokencode == TBaseType.rrw_inner)
3756                {
3757                    prevst = asourcetoken;
3758                }
3759                else if (asourcetoken.tokencode == TBaseType.rrw_not)
3760                {
3761                     prevst = asourcetoken;
3762                }
3763                else
3764                { prevst = null;}
3765
3766                if ((asourcetoken.tokencode == flexer.getkeywordvalue("DIRECT_LOAD"))
3767                ||  (asourcetoken.tokencode == flexer.getkeywordvalue("ALL")) )
3768                {
3769                    // RW_COMPRESS RW_FOR RW_ALL RW_OPERATIONS
3770                    // RW_COMPRESS RW_FOR RW_DIRECT_LOAD RW_OPERATIONS
3771                    // change rw_for to TBaseType.rw_for1, it conflicts with compress for update in create materialized view
3772
3773                    lcprevst = getprevsolidtoken(asourcetoken);
3774                    if (lcprevst != null)
3775                    {
3776                        if (lcprevst.tokencode == TBaseType.rrw_for)
3777                          lcprevst.tokencode = TBaseType.rw_for1;
3778                    }
3779                }else  if (asourcetoken.tokencode == TBaseType.rrw_dense_rank){
3780                    //keep keyword can be column alias, make keep in keep_denserankclause as a different token code
3781                    TSourceToken stKeep  = asourcetoken.searchToken(TBaseType.rrw_keep,-2);
3782                    if ( stKeep != null){
3783                        stKeep.tokencode = TBaseType.rrw_keep_before_dense_rank;
3784                    }
3785                }else  if (asourcetoken.tokencode == TBaseType.rrw_full){
3786                    TSourceToken stMatch  = asourcetoken.searchToken(TBaseType.rrw_match,-1);
3787                    if (stMatch != null){   //match full
3788                        asourcetoken.tokencode = TBaseType.RW_FULL2;
3789                    }
3790                }else  if (asourcetoken.tokencode == TBaseType.rrw_join){
3791                    TSourceToken stFull  = asourcetoken.searchToken(TBaseType.rrw_full,-1);
3792                    if (stFull != null){ // full join
3793                        stFull.tokencode = TBaseType.RW_FULL2;
3794                    }else{
3795                        TSourceToken stNatural  = asourcetoken.searchToken(TBaseType.rrw_natural,-4);
3796                        if (stNatural != null){
3797                            stNatural.tokencode = TBaseType.RW_NATURAL2;
3798                        }
3799                    }
3800                }else  if (asourcetoken.tokencode == TBaseType.rrw_outer){
3801                    TSourceToken stFull  = asourcetoken.searchToken(TBaseType.rrw_full,-1);
3802                    if (stFull != null){ //full outer join
3803                        stFull.tokencode = TBaseType.RW_FULL2;
3804                    }
3805                }else  if (asourcetoken.tokencode == TBaseType.rrw_is){
3806                    TSourceToken stType  = asourcetoken.searchToken(TBaseType.rrw_type,-2);
3807                    if (stType != null){
3808                        stType.tokencode = TBaseType.rrw_type2;
3809                    }
3810                }else  if (asourcetoken.tokencode == TBaseType.rrw_as){
3811                    TSourceToken stType  = asourcetoken.searchToken(TBaseType.rrw_type,-2);
3812                    if (stType != null){
3813                        stType.tokencode = TBaseType.rrw_type2;
3814                    }
3815                }else  if (asourcetoken.tokencode == TBaseType.rrw_oid){
3816                    TSourceToken stType  = asourcetoken.searchToken(TBaseType.rrw_type,-2);
3817                    if (stType != null){
3818                        stType.tokencode = TBaseType.rrw_type2;
3819                    }
3820                }else  if (asourcetoken.tokencode == TBaseType.rrw_type){
3821                    TSourceToken stPrev;
3822                    stPrev = asourcetoken.searchToken(TBaseType.rrw_drop,-1);
3823                    if (stPrev != null){
3824                        asourcetoken.tokencode = TBaseType.rrw_type2;
3825                    }
3826                    if (asourcetoken.tokencode == TBaseType.rrw_type){
3827                        stPrev  = asourcetoken.searchToken(TBaseType.rrw_of,-1);
3828                        if (stPrev != null){
3829                            asourcetoken.tokencode = TBaseType.rrw_type2;
3830                        }
3831                    }
3832                    if (asourcetoken.tokencode == TBaseType.rrw_type){
3833                        stPrev  = asourcetoken.searchToken(TBaseType.rrw_of,-1);
3834                        if (stPrev != null){
3835                            asourcetoken.tokencode = TBaseType.rrw_type2;
3836                        }
3837                    }
3838                    if (asourcetoken.tokencode == TBaseType.rrw_type){
3839                        stPrev  = asourcetoken.searchToken(TBaseType.rrw_create,-1);
3840                        if (stPrev != null){
3841                            asourcetoken.tokencode = TBaseType.rrw_type2;
3842                        }
3843                    }
3844                    if (asourcetoken.tokencode == TBaseType.rrw_type){
3845                        stPrev  = asourcetoken.searchToken(TBaseType.rrw_replace,-1);
3846                        if (stPrev != null){
3847                            asourcetoken.tokencode = TBaseType.rrw_type2;
3848                        }
3849                    }
3850                    if (asourcetoken.tokencode == TBaseType.rrw_type){
3851                        stPrev  = asourcetoken.searchToken('%',-1);
3852                        if (stPrev != null){
3853                            asourcetoken.tokencode = TBaseType.rrw_type2;
3854                        }
3855                    }
3856                }else  if ((asourcetoken.tokencode == TBaseType.rrw_by)||(asourcetoken.tokencode == TBaseType.rrw_to)){
3857                    lcprevst = getprevsolidtoken(asourcetoken);
3858                    if (lcprevst != null)
3859                    {
3860                        if ((lcprevst.tokencode == TBaseType.sqlpluscmd)&&(lcprevst.toString().equalsIgnoreCase("connect"))){
3861                            lcprevst.tokencode = TBaseType.rrw_connect;
3862                            lcprevst.tokentype = ETokenType.ttkeyword;
3863                            flexer.insqlpluscmd = false;
3864
3865                            continuesqlplusatnewline = false;
3866                            waitingreturnforsemicolon = false;
3867                            waitingreturnforfloatdiv = false;
3868                            isvalidplace = false;
3869                            insqlpluscmd = false;
3870                        }
3871
3872                    }
3873                }else  if (asourcetoken.tokencode == TBaseType.rrw_with){ // rollback start in start with clause
3874                    lcprevst = getprevsolidtoken(asourcetoken);
3875                    if (lcprevst != null)
3876                    {
3877                        if ((lcprevst.tokencode == TBaseType.sqlpluscmd)&&(lcprevst.toString().equalsIgnoreCase("start"))){
3878                            lcprevst.tokencode = TBaseType.rrw_start;
3879                            lcprevst.tokentype = ETokenType.ttkeyword;
3880                            flexer.insqlpluscmd = false;
3881
3882                            continuesqlplusatnewline = false;
3883                            waitingreturnforsemicolon = false;
3884                            waitingreturnforfloatdiv = false;
3885                            isvalidplace = false;
3886                            insqlpluscmd = false;
3887                        }
3888
3889                    }
3890                }else  if (asourcetoken.tokencode == TBaseType.rrw_set){
3891                    lcprevst = getprevsolidtoken(asourcetoken);
3892                    if (lcprevst != null)
3893                    {
3894                        if (lcprevst.astext.equalsIgnoreCase("a")){
3895                            TSourceToken lcpp = getprevsolidtoken(lcprevst);
3896                            if (lcpp != null){
3897                                if ((lcpp.tokencode == TBaseType.rrw_not)||(lcpp.tokencode == TBaseType.rrw_is)){
3898                                    lcprevst.tokencode = TBaseType.rrw_oracle_a_in_aset;
3899                                    asourcetoken.tokencode = TBaseType.rrw_oracle_set_in_aset;
3900                                }
3901                            }
3902                        }
3903                    }
3904
3905                }
3906
3907            }
3908        }
3909
3910         //flexer.yylexwrap(asourcetoken);
3911         asourcetoken = getanewsourcetoken();
3912         if (asourcetoken != null){
3913             yychar = asourcetoken.tokencode;
3914             if ((asourcetoken.tokencode == '.')&&(getprevsolidtoken(asourcetoken) != null)
3915                     &&((currentCmdType == ESqlPlusCmd.spcAppend)
3916                            ||(currentCmdType == ESqlPlusCmd.spcChange)||(currentCmdType == ESqlPlusCmd.spcInput)
3917                            ||(currentCmdType == ESqlPlusCmd.spcList)||(currentCmdType == ESqlPlusCmd.spcRun)
3918                        )){
3919//                 SELECT DISTINCT
3920//                 a.eca_usr_id,
3921//
3922//                         --        run_d,
3923//                         a.ent_rp_usr_id
3924//                 FROM t
3925                 // a.ent_rp_usr_id is not a real sqlplus command
3926
3927                 TSourceToken lcprevst2 = getprevsolidtoken(asourcetoken);
3928                 lcprevst2.insqlpluscmd = false;
3929                 if (lcprevst2.prevTokenCode != 0){
3930                     lcprevst2.tokencode = lcprevst2.prevTokenCode;
3931                 }else{
3932                     lcprevst2.tokencode = TBaseType.ident;
3933                 }
3934
3935                 flexer.insqlpluscmd = false;
3936
3937                 continuesqlplusatnewline = false;
3938                 waitingreturnforsemicolon = false;
3939                 waitingreturnforfloatdiv = false;
3940                 isvalidplace = false;
3941                 insqlpluscmd = false;
3942
3943                // System.out.println("Token before:"+lcprevst2.astext);
3944             }
3945         }else{
3946           yychar = 0;
3947
3948             if (waitingreturnforfloatdiv)
3949             { // / at the end of line treat as sqlplus command
3950                 //isvalidplace = true;
3951                 lct.tokencode = TBaseType.sqlpluscmd;
3952                 if (lct.tokentype != ETokenType.ttslash){
3953                   lct.tokentype = ETokenType.ttsqlpluscmd;
3954                 }
3955             }
3956
3957         }
3958
3959          if ((yychar == 0) && (prevst != null))
3960          {
3961              if (prevst.tokencode == TBaseType.rrw_inner)// flexer.getkeywordvalue("RW_INNER"))
3962              { prevst.tokencode = TBaseType.ident;}
3963          }
3964      }
3965}
3966
3967void dodb2sqltexttotokenlist(){
3968// treat echo, ! of db2 at the begin of each line as
3969// oracle sqlplus command
3970
3971    boolean insqlpluscmd = false;
3972    boolean isvalidplace = true;
3973    int jdbc_escape_nest = 0;
3974//  isSolidTokenStart := false;
3975
3976//  tempsourcetokenlist.clear;
3977
3978    TSourceToken asourcetoken,lcprevst;
3979    int yychar;
3980
3981    asourcetoken = getanewsourcetoken();
3982    
3983    if ( asourcetoken == null ) return;
3984    yychar = asourcetoken.tokencode;
3985
3986
3987    while (yychar > 0)
3988    {
3989
3990        switch (yychar){
3991          case TBaseType.lexnewline:
3992          {
3993              insqlpluscmd = false;
3994              isvalidplace = true;
3995              break;
3996          }
3997          case TBaseType.cmtdoublehyphen:
3998          {
3999              if (asourcetoken.astext.toLowerCase().indexOf("scriptoptions")>=0)
4000              {
4001                  asourcetoken.tokencode = TBaseType.scriptoptions;
4002                  asourcetoken.tokentype = ETokenType.ttidentifier;
4003              }
4004
4005              if (insqlpluscmd)
4006              {
4007                  asourcetoken.insqlpluscmd = true;
4008              }
4009            break;
4010          }
4011          case TBaseType.rrw_jdbc_escape_fn: {
4012              jdbc_escape_nest++;
4013              asourcetoken.tokencode = TBaseType.lexspace;
4014            break;
4015          }
4016          case TBaseType.rrw_jdbc_escape_end: {
4017                jdbc_escape_nest--;
4018                asourcetoken.tokencode = TBaseType.lexspace;
4019                break;
4020          }
4021          default: //solid tokentext
4022          {
4023              if ((asourcetoken.tokencode == TBaseType.rrw_rr)
4024                    || (asourcetoken.tokencode ==  TBaseType.rrw_rs)
4025                    || (asourcetoken.tokencode ==  TBaseType.rrw_cs)
4026                    || (asourcetoken.tokencode ==  TBaseType.rrw_ur)
4027                  )
4028              {
4029                 // change with keyword in isolation clause to rrw_with_isolation
4030                  // so opt_restriction_clause in create view worked correctly
4031                  lcprevst = getprevsolidtoken(asourcetoken);
4032                  if (lcprevst != null)
4033                  {
4034                      if (lcprevst.tokencode == TBaseType.rrw_with)
4035                        lcprevst.tokencode = TBaseType.rrw_with_isolation;
4036                  }
4037              }
4038
4039              if (insqlpluscmd)
4040              {
4041                  //asourcetoken.TokenCode := TBaseType.sqlpluscmd;
4042                  asourcetoken.insqlpluscmd = true;
4043              }
4044              else
4045              {
4046                  if (isvalidplace){
4047                   // System.out.println(asourcetoken.astext);
4048                  if (TBaseType.mycomparetext(asourcetoken.astext.toLowerCase(),"echo") == 0 )
4049                  {
4050                     // System.out.println("finded ");
4051                      asourcetoken.tokencode = TBaseType.sqlpluscmd;
4052                      if (asourcetoken.tokentype != ETokenType.ttslash)
4053                      {asourcetoken.tokentype = ETokenType.ttsqlpluscmd;}
4054                      asourcetoken.insqlpluscmd = true;
4055                      insqlpluscmd = true;
4056                  }
4057                }
4058              }
4059              isvalidplace = false;
4060
4061              break;
4062          } //end of solid tokentext
4063        } //switch
4064
4065//  TBaseType.lexnewline
4066
4067        sourcetokenlist.add(asourcetoken);
4068
4069        asourcetoken = getanewsourcetoken();
4070        if ( asourcetoken == null ) break;
4071        yychar = asourcetoken.tokencode;
4072
4073    } //while
4074
4075}
4076
4077    void doteradatatexttotokenlist(){
4078
4079        TSourceToken asourcetoken,lcprevst;
4080        int yychar;
4081
4082        asourcetoken = getanewsourcetoken();
4083        if ( asourcetoken == null ) return;
4084        yychar = asourcetoken.tokencode;
4085
4086        while (yychar > 0)
4087        {
4088            sourcetokenlist.add(asourcetoken);
4089            asourcetoken = getanewsourcetoken();
4090            if ( asourcetoken == null ) break;
4091
4092            if ((asourcetoken.tokencode == TBaseType.rrw_casespecific)
4093                ||(asourcetoken.tokencode == TBaseType.rrw_teradata_cs))
4094            {
4095                    /* change not to not1 to make "not null column constriants" work correctly */
4096                //      |RW_NOT1 RW_CASESPECIFIC
4097
4098                lcprevst = getprevsolidtoken(asourcetoken);
4099                if (lcprevst != null)
4100                {
4101                    if (lcprevst.tokencode == TBaseType.rrw_not)
4102                      lcprevst.tokencode = TBaseType.rw_not1;
4103                }
4104            } else if (asourcetoken.tokencode == ';'){
4105                lcprevst = getprevsolidtoken(asourcetoken);
4106                if (lcprevst != null)
4107                {
4108                    if (lcprevst.tokencode == ';')
4109                        asourcetoken.tokencode = TBaseType.sqlpluscmd;
4110                }
4111            } else if (asourcetoken.tokencode == TBaseType.variable){ // mantisbt/view.php?id=972
4112                if (asourcetoken.toString().toLowerCase().endsWith("begin")){ //MYPROC :BEGIN
4113                    asourcetoken.tokencode = TBaseType.rrw_begin;
4114                    asourcetoken.tokentype = ETokenType.ttkeyword;
4115
4116                    lcprevst = getprevsolidtoken(asourcetoken);
4117                    if (lcprevst != null)
4118                    {
4119                        lcprevst.tokencode = TBaseType.mslabel;
4120                    }
4121
4122                }
4123            }else if (asourcetoken.tokencode == TCustomLexer.UNICODE_ENCODE_ID){
4124                if (asourcetoken.toString().endsWith("008D")){ // REVERSE LINE FEED, https://codepoints.net/U+008D?lang=en
4125                    asourcetoken.tokencode = TBaseType.lexspace;
4126                }else{
4127                    asourcetoken.tokencode = TBaseType.ident;
4128                }
4129            }
4130
4131
4132            yychar = asourcetoken.tokencode;
4133        }
4134
4135    }
4136
4137void  docommonsqltexttotokenlist(){
4138
4139    TSourceToken asourcetoken,lcprevst;
4140    int yychar;
4141
4142    asourcetoken = getanewsourcetoken();
4143    if ( asourcetoken == null ) return;
4144    yychar = asourcetoken.tokencode;
4145
4146    while (yychar > 0)
4147    {
4148        sourcetokenlist.add(asourcetoken);
4149        asourcetoken = getanewsourcetoken();
4150        if ( asourcetoken == null ) break;
4151        yychar = asourcetoken.tokencode;
4152    }
4153
4154}
4155    void  doodbcsqltexttotokenlist(){
4156        boolean insideODBC = false;
4157        TSourceToken odbcPrefix = null;
4158        domssqlsqltexttotokenlist();
4159        for (int i=0 ; i<sourcetokenlist.size();i++) {
4160            TSourceToken ast = sourcetokenlist.get(i);
4161            if ((ast.tokencode == '{')||(ast.tokencode == TBaseType.odbc_esc_prefix))
4162            {
4163                insideODBC = true;
4164                odbcPrefix = ast;
4165            }
4166            if ((ast.tokencode == '}')||(ast.tokencode == TBaseType.odbc_esc_terminator))
4167            {
4168                insideODBC = false;
4169                odbcPrefix = null;
4170            }
4171            if (((ast.tokencode == TBaseType.rrw_odbc_d)
4172                    ||(ast.tokencode == TBaseType.rrw_odbc_t)
4173                    ||(ast.tokencode == TBaseType.rrw_odbc_ts)
4174                    ||(ast.tokencode == TBaseType.rrw_odbc_fn)
4175                    ||(ast.tokencode == TBaseType.rrw_odbc_oj)
4176                )&&(!insideODBC)) {
4177                ast.tokencode = TBaseType.ident;
4178            }
4179
4180            if ((ast.tokencode == TBaseType.rrw_call)&&(insideODBC)){
4181                odbcPrefix.setLinkToken(ast);
4182            }
4183        }
4184    }
4185
4186void  dodaxsqltexttotokenlist(){
4187
4188    TSourceToken asourcetoken,lcprevst;
4189    int yychar;
4190
4191    asourcetoken = getanewsourcetoken();
4192    if ( asourcetoken == null ) return;
4193    yychar = asourcetoken.tokencode;
4194
4195    while (yychar > 0)
4196    {
4197        sourcetokenlist.add(asourcetoken);
4198        asourcetoken = getanewsourcetoken();
4199        if ( asourcetoken == null ) break;
4200        yychar = asourcetoken.tokencode;
4201    }
4202
4203}
4204
4205
4206void  dohanasqltexttotokenlist(){
4207
4208    TSourceToken asourcetoken,lcprevst;
4209    int yychar;
4210
4211    asourcetoken = getanewsourcetoken();
4212    if ( asourcetoken == null ) return;
4213    yychar = asourcetoken.tokencode;
4214
4215    while (yychar > 0)
4216    {
4217        sourcetokenlist.add(asourcetoken);
4218        asourcetoken = getanewsourcetoken();
4219        if ( asourcetoken == null ) break;
4220        yychar = asourcetoken.tokencode;
4221    }
4222
4223}
4224
4225void  dohivetexttotokenlist(){
4226
4227    TSourceToken asourcetoken,lcprevst;
4228    int yychar;
4229
4230    asourcetoken = getanewsourcetoken();
4231    if ( asourcetoken == null ) return;
4232    yychar = asourcetoken.tokencode;
4233
4234    while (yychar > 0)
4235    {
4236        if (asourcetoken != null){
4237            sourcetokenlist.add(asourcetoken);
4238        }
4239        asourcetoken = getanewsourcetoken();
4240        if ( asourcetoken == null ) break;
4241        if (asourcetoken.tokencode == TBaseType.rrw_map){
4242            TSourceToken token = asourcetoken.searchToken(')',-1);
4243            if (token != null){
4244                asourcetoken.tokencode = TBaseType.ident;
4245            }
4246        }else if (asourcetoken.tokencode == '('){
4247//            TSourceToken token = asourcetoken.searchToken(TBaseType.ident,-1);
4248//            if (token != null){
4249//                token.tokencode = TBaseType.HIVE_FUNC_IDENT;
4250//            }
4251        }
4252        yychar = asourcetoken.tokencode;
4253
4254        // `schema.table_name`
4255        if ((asourcetoken.tokencode == TBaseType.ident)
4256                && (asourcetoken.toString().startsWith("`"))&& (asourcetoken.toString().endsWith("`"))
4257                && (asourcetoken.toString().indexOf(".")>0)
4258        ){
4259            yychar = splitQualifiedNameInBacktick(asourcetoken);
4260            asourcetoken = null;
4261        }
4262
4263    }
4264
4265}
4266
4267void  doimpalatexttotokenlist(){
4268    dohivetexttotokenlist();
4269}
4270
4271void checkMySQLCommentToken(TSourceToken cmtToken){
4272//    if (cmtToken.tokencode == TBaseType.cmtdoublehyphen){
4273//        if ((cmtToken.toString().startsWith("--"))){
4274//            if (cmtToken.toString().length() > 2){
4275//                if (cmtToken.toString().charAt(2) != ' '){
4276//                   this.syntaxErrors.add(new TSyntaxError(cmtToken.toString(),
4277//                           cmtToken.lineNo,
4278//                           cmtToken.columnNo,
4279//                           "requires a space after the initial \"--\" ",EErrorType.sperror,10010
4280//                           ));
4281//                }
4282//            }
4283//            // there should be
4284//        }
4285//    }
4286}
4287    void dosparksqltexttotokenlist(){
4288        TSourceToken asourcetoken,lcprevst;
4289        int yychar;
4290        boolean startDelimiter = false;
4291
4292        flexer.tmpDelimiter = "";
4293
4294        asourcetoken = getanewsourcetoken();
4295        if ( asourcetoken == null ) return;
4296        yychar = asourcetoken.tokencode;
4297
4298
4299
4300
4301        while (yychar > 0)
4302        {
4303            sourcetokenlist.add(asourcetoken);
4304            asourcetoken = getanewsourcetoken();
4305            if ( asourcetoken == null ) break;
4306            checkMySQLCommentToken(asourcetoken);
4307
4308            if ((asourcetoken.tokencode == TBaseType.lexnewline)&&(startDelimiter)){
4309                startDelimiter = false;
4310                flexer.tmpDelimiter  = sourcetokenlist.get(sourcetokenlist.size()-1).astext;
4311            }
4312
4313
4314            if (asourcetoken.tokencode == TBaseType.rrw_rollup)
4315            {
4316                //      with rollup
4317
4318                lcprevst = getprevsolidtoken(asourcetoken);
4319                if (lcprevst != null)
4320                {
4321                    if (lcprevst.tokencode == TBaseType.rrw_with)
4322                        lcprevst.tokencode = TBaseType.with_rollup;
4323                }
4324            }
4325
4326            yychar = asourcetoken.tokencode;
4327        }
4328
4329    }
4330
4331    void doathenatexttotokenlist(){
4332        TSourceToken asourcetoken,lcprevst;
4333        int yychar;
4334        boolean startDelimiter = false;
4335
4336        flexer.tmpDelimiter = "";
4337
4338        asourcetoken = getanewsourcetoken();
4339        if ( asourcetoken == null ) return;
4340        yychar = asourcetoken.tokencode;
4341
4342
4343
4344
4345        while (yychar > 0)
4346        {
4347            sourcetokenlist.add(asourcetoken);
4348            asourcetoken = getanewsourcetoken();
4349            if ( asourcetoken == null ) break;
4350            checkMySQLCommentToken(asourcetoken);
4351
4352            if ((asourcetoken.tokencode == TBaseType.lexnewline)&&(startDelimiter)){
4353                startDelimiter = false;
4354                flexer.tmpDelimiter  = sourcetokenlist.get(sourcetokenlist.size()-1).astext;
4355            }
4356
4357
4358            yychar = asourcetoken.tokencode;
4359        }
4360
4361    }
4362
4363    void dodatabrickstexttotokenlist(){
4364        TSourceToken asourcetoken,lcprevst;
4365        int yychar;
4366        boolean startDelimiter = false;
4367
4368        flexer.tmpDelimiter = "";
4369
4370        asourcetoken = getanewsourcetoken();
4371        if ( asourcetoken == null ) return;
4372        yychar = asourcetoken.tokencode;
4373
4374
4375
4376
4377        while (yychar > 0)
4378        {
4379            sourcetokenlist.add(asourcetoken);
4380            asourcetoken = getanewsourcetoken();
4381            if ( asourcetoken == null ) break;
4382            checkMySQLCommentToken(asourcetoken);
4383
4384            if ((asourcetoken.tokencode == TBaseType.lexnewline)&&(startDelimiter)){
4385                startDelimiter = false;
4386                flexer.tmpDelimiter  = sourcetokenlist.get(sourcetokenlist.size()-1).astext;
4387            }
4388
4389
4390            yychar = asourcetoken.tokencode;
4391        }
4392
4393    }
4394    void doprestotexttotokenlist(){
4395        TSourceToken asourcetoken,lcprevst;
4396        int yychar;
4397        boolean startDelimiter = false;
4398
4399        flexer.tmpDelimiter = "";
4400
4401        asourcetoken = getanewsourcetoken();
4402        if ( asourcetoken == null ) return;
4403        yychar = asourcetoken.tokencode;
4404
4405
4406
4407
4408        while (yychar > 0)
4409        {
4410            sourcetokenlist.add(asourcetoken);
4411            asourcetoken = getanewsourcetoken();
4412            if ( asourcetoken == null ) break;
4413            checkMySQLCommentToken(asourcetoken);
4414
4415            if ((asourcetoken.tokencode == TBaseType.lexnewline)&&(startDelimiter)){
4416                startDelimiter = false;
4417                flexer.tmpDelimiter  = sourcetokenlist.get(sourcetokenlist.size()-1).astext;
4418            }
4419
4420
4421            yychar = asourcetoken.tokencode;
4422        }
4423
4424    }
4425
4426void  domysqltexttotokenlist(){
4427
4428        TSourceToken asourcetoken,lcprevst;
4429        int yychar;
4430        boolean startDelimiter = false;
4431
4432        flexer.tmpDelimiter = "";
4433
4434        asourcetoken = getanewsourcetoken();
4435        if ( asourcetoken == null ) return;
4436        yychar = asourcetoken.tokencode;
4437        checkMySQLCommentToken(asourcetoken);
4438
4439        if ((asourcetoken.tokencode == TBaseType.rrw_mysql_delimiter)){
4440            startDelimiter = true;
4441        }
4442
4443        while (yychar > 0)
4444        {
4445            sourcetokenlist.add(asourcetoken);
4446            asourcetoken = getanewsourcetoken();
4447            if ( asourcetoken == null ) break;
4448            checkMySQLCommentToken(asourcetoken);
4449
4450            if ((asourcetoken.tokencode == TBaseType.lexnewline)&&(startDelimiter)){
4451                startDelimiter = false;
4452                flexer.tmpDelimiter  = sourcetokenlist.get(sourcetokenlist.size()-1).astext;
4453            }
4454
4455            if ((asourcetoken.tokencode == TBaseType.rrw_mysql_delimiter)){
4456                startDelimiter = true;
4457            }
4458
4459            if (asourcetoken.tokencode == TBaseType.rrw_rollup)
4460            {
4461                //      with rollup
4462
4463                lcprevst = getprevsolidtoken(asourcetoken);
4464                if (lcprevst != null)
4465                {
4466                    if (lcprevst.tokencode == TBaseType.rrw_with)
4467                      lcprevst.tokencode = TBaseType.with_rollup;
4468                }
4469            }
4470
4471            if( (asourcetoken.tokencode == TBaseType.rrw_mysql_d)
4472                    ||(asourcetoken.tokencode == TBaseType.rrw_mysql_t)
4473                    ||(asourcetoken.tokencode == TBaseType.rrw_mysql_ts)
4474                    )
4475            {
4476                //      odbc date constant { d 'str' }
4477                lcprevst = getprevsolidtoken(asourcetoken);
4478                if (lcprevst != null)
4479                {
4480                    if (lcprevst.tokencode != '{')
4481                        asourcetoken.tokencode = TBaseType.ident;
4482                }
4483            }
4484
4485
4486            yychar = asourcetoken.tokencode;
4487        }
4488
4489    }
4490
4491void  doMdxtexttotokenlist(){
4492
4493    TSourceToken asourcetoken,lcprevst;
4494    int yychar;
4495
4496    asourcetoken = getanewsourcetoken();
4497    if ( asourcetoken == null ) return;
4498    yychar = asourcetoken.tokencode;
4499
4500    while (yychar > 0)
4501    {
4502        sourcetokenlist.add(asourcetoken);
4503        asourcetoken = getanewsourcetoken();
4504        if ( asourcetoken == null ) break;
4505        yychar = asourcetoken.tokencode;
4506    }
4507
4508}
4509
4510void dosqltexttotokenlist(){
4511    switch(dbVendor){
4512        case dbvmssql:
4513        case dbvazuresql:
4514         {
4515            domssqlsqltexttotokenlist();
4516            break;
4517        }
4518        case dbvinformix:{
4519            doinformixtexttotokenlist();
4520            break;
4521        }
4522        case dbvsybase:{
4523            dosybasesqltexttotokenlist();
4524            break;
4525        }
4526        case dbvoracle:{
4527            dooraclesqltexttotokenlist();
4528            break;
4529        }
4530        case dbvdb2:{
4531            dodb2sqltexttotokenlist();
4532            break;
4533        }
4534        case dbvteradata:{
4535            doteradatatexttotokenlist();
4536            break;
4537        }
4538        case dbvpostgresql:{
4539            dopostgresqltexttotokenlist();
4540            break;
4541        }
4542        case dbvredshift:{
4543            doredshifttexttotokenlist();
4544            break;
4545        }
4546        case dbvgreenplum:{
4547            dogreenplumtexttotokenlist();
4548            break;
4549        }
4550        case dbvmdx: {
4551            doMdxtexttotokenlist();
4552            break;
4553        }
4554        case dbvnetezza:{
4555            donetezzatexttotokenlist();
4556            break;
4557        }
4558        case dbvhive:{
4559            dohivetexttotokenlist();
4560            break;
4561        }
4562        case dbvimpala:{
4563            doimpalatexttotokenlist();
4564            break;
4565        }
4566        case dbvmysql:{
4567            domysqltexttotokenlist();
4568            break;
4569        }
4570        case dbvhana:{
4571            dohanasqltexttotokenlist();
4572            break;
4573        }
4574        case dbvdax:{
4575            dodaxsqltexttotokenlist();
4576            break;
4577        }
4578        case dbvodbc:{
4579            doodbcsqltexttotokenlist();
4580            break;
4581        }
4582        case dbvvertica:{
4583            doverticatexttotokenlist();
4584            break;
4585        }
4586        case dbvopenedge:{
4587            domssqlsqltexttotokenlist();
4588            break;
4589        }
4590        case dbvcouchbase:{
4591            docouchbasesqltexttotokenlist();
4592            break;
4593        }
4594        case dbvsnowflake:{
4595            dosnowflakesqltexttotokenlist();
4596            break;
4597        }
4598        case dbvbigquery:{
4599            dobigquerysqltexttotokenlist();
4600            break;
4601        }
4602        case dbvsoql:{
4603            dosoqlsqltexttotokenlist();
4604            break;
4605        }
4606        case dbvsparksql:{
4607            dosparksqltexttotokenlist();
4608            break;
4609        }
4610        case dbvpresto:{
4611            doprestotexttotokenlist();
4612            break;
4613        }
4614        case dbvathena:{
4615            doathenatexttotokenlist();
4616            break;
4617        }
4618        case dbvdatabricks:{
4619            dodatabrickstexttotokenlist();
4620            break;
4621        }
4622        case dbvgaussdb:{
4623            dogaussdbtexttotokenlist();
4624            break;
4625        }
4626        case dbvansi:{
4627            doansitexttotokenlist();
4628            break;
4629        }
4630        default:{
4631            docommonsqltexttotokenlist();            
4632        }
4633    }
4634
4635    doAfterTokenize();
4636
4637    TBaseType.resetTokenChain(sourcetokenlist,0);
4638
4639    processTokensInTokenTable(dbVendor);
4640    processTokensBeforeParse(dbVendor);
4641
4642    closeFileStream();
4643
4644    if (tokenListHandle != null){
4645        tokenListHandle.processTokenList(sourcetokenlist);
4646    }
4647}
4648
4649void doAfterTokenize(){
4650
4651    int leftParenCount = 0;
4652    int rightParenCount = 0;
4653    int leftIndex = 0;
4654    int rightIndex = sourcetokenlist.size() - 1;
4655
4656    // Count opening parentheses at the beginning
4657    while (leftIndex < sourcetokenlist.size() && sourcetokenlist.get(leftIndex).tokencode == '(') {
4658        leftParenCount++;
4659        leftIndex++;
4660    }
4661
4662    // Count closing parentheses at the end
4663    while (rightIndex >= 0 && sourcetokenlist.get(rightIndex).tokencode == ')') {
4664        rightParenCount++;
4665        rightIndex--;
4666    }
4667
4668    // Set matching parentheses to be ignored
4669    int parensToIgnore = Math.min(leftParenCount, rightParenCount);
4670    // if there is a semicolon before the right parenthesis, set the semicolon to be ignored
4671    // mantisbt/view.php?id=3690
4672
4673    if ((parensToIgnore > 0) && (sourcetokenlist.get(sourcetokenlist.size() - 1 - (parensToIgnore - 1) - 1).tokencode == ';')){
4674        // set to whitespace that this semicolon will be ignored during getting raw sql
4675        sourcetokenlist.get(sourcetokenlist.size() - 1 - (parensToIgnore - 1) - 1).tokentype = ETokenType.ttwhitespace;
4676        // set to ignore by yacc that this semicolon will be ignored during parsing
4677        sourcetokenlist.get(sourcetokenlist.size() - 1 - (parensToIgnore - 1) - 1).tokenstatus = ETokenStatus.tsignorebyyacc;
4678    }
4679//    for (int i = 0; i < parensToIgnore; i++) {
4680//        //sourcetokenlist.get(i).tokenstatus = ETokenStatus.tsignorebyyacc;
4681//        sourcetokenlist.get(i).tokencode = TBaseType.lexspace;
4682//
4683//       // sourcetokenlist.get(sourcetokenlist.size() - 1 - i).tokenstatus = ETokenStatus.tsignorebyyacc;
4684//        sourcetokenlist.get(sourcetokenlist.size() - 1 - i).tokencode = TBaseType.lexspace;
4685//    }
4686
4687}
4688
4689
4690
4691void processTokensBeforeParse(EDbVendor dbVendor){
4692
4693        // 为确保性能,只在snowflake数据库中处理,因为目前只有snowflake数据库中有连续的分号有用户提出这个需求,其他数据库中暂时不处理
4694   if (dbVendor != EDbVendor.dbvsnowflake) return;
4695
4696        // mantisbt/view.php?id=3579
4697        // if there are consecutive semicolon tokens, mark the second semi colon token as deleted token
4698    for(int i=0;i<sourcetokenlist.size();i++){
4699        TSourceToken st = sourcetokenlist.get(i);
4700        if (st.tokencode == ';'){
4701            TSourceToken nextToken = st.nextSolidToken();
4702            if (nextToken != null){
4703                if (nextToken.tokencode == ';'){
4704                    nextToken.tokenstatus = ETokenStatus.tsdeleted;
4705                }
4706            }
4707        }
4708    }
4709
4710}
4711
4712void processTokensInTokenTable(EDbVendor dbVendor){
4713    // 获得所有token后,根据需要对token code进行预处理, token table是 TBaseType.TOKEN_TABLE
4714     long[][] TOKEN_TABLE1 = flexer.TOKEN_TABLE;
4715
4716    switch (dbVendor){
4717        case dbvbigquery:
4718        case dbvsnowflake:
4719            // case 1, DO 关键字如果没有发现对于的 FOR, WHILE 等关键字,把 DO 关键字的token code设置为 TBaseType.ident
4720
4721            if (TOKEN_TABLE1[TBaseType.rrw_do][0] > 0){
4722                if ((TOKEN_TABLE1[TBaseType.rrw_while][0] == 0)&&(TOKEN_TABLE1[TBaseType.rrw_for][0] == 0)){
4723                    for(int i=0;i<sourcetokenlist.size();i++){
4724                        TSourceToken st = sourcetokenlist.get(i);
4725                        if (st.tokencode == TBaseType.rrw_do){
4726                            st.tokencode = TBaseType.ident;
4727                        }
4728                    }
4729                }
4730            }
4731
4732            break;
4733    }
4734
4735}
4736
4737boolean isDollarFunctionDelimiter(int tokencode, EDbVendor dbVendor){
4738        return ((tokencode == TBaseType.rrw_postgresql_function_delimiter)&&(dbVendor == EDbVendor.dbvpostgresql))
4739                ||((tokencode == TBaseType.rrw_greenplum_function_delimiter)&&(dbVendor == EDbVendor.dbvgreenplum))
4740                ||((tokencode == TBaseType.rrw_redshift_function_delimiter)&&(dbVendor == EDbVendor.dbvredshift))
4741                ||((tokencode == TBaseType.rrw_snowflake_function_delimiter)&&(dbVendor == EDbVendor.dbvsnowflake));
4742}
4743void doongetrawsqlstatementevent(TCustomSqlStatement pcsqlstatement){
4744    pcsqlstatement.setGsqlparser(this);
4745    pcsqlstatement.parser = this.fparser;
4746    pcsqlstatement.plsqlparser = this.fplsqlparser;
4747    pcsqlstatement.setStartToken(pcsqlstatement.sourcetokenlist.get(0));
4748    pcsqlstatement.setEndToken(pcsqlstatement.sourcetokenlist.get(pcsqlstatement.sourcetokenlist.size()-1));
4749    sqlstatements.add(pcsqlstatement);
4750
4751    if ((this.dbVendor == EDbVendor.dbvgaussdb) &&
4752            ((pcsqlstatement.sqlstatementtype == sstcreateprocedure)||(pcsqlstatement.sqlstatementtype == sstcreatefunction))){
4753        if (isOracleStyleRoutine){
4754            if (stFunction != null){
4755                stFunction.tokencode = TBaseType.GAUSSDB_FUNCTION_ORA;
4756            }else if (stProcedure != null){
4757                stProcedure.tokencode = TBaseType.GAUSSDB_PROCEDURE_ORA;
4758            }
4759        }
4760        stFunction = null;
4761        stProcedure = null;
4762        isOracleStyleRoutine = true; // 为下一次语句进行重置
4763    }
4764
4765    // if stored procedure body is not written in sql or plsql, then, set the token in body to
4766    if (    ((this.dbVendor == EDbVendor.dbvpostgresql)||(this.dbVendor == EDbVendor.dbvgreenplum) ||(this.dbVendor == EDbVendor.dbvredshift) ||(this.dbVendor == EDbVendor.dbvsnowflake) )
4767             && (pcsqlstatement instanceof TRoutine)
4768       ){
4769         if (!((TRoutine)pcsqlstatement).isBodyInSQL()){
4770             TSourceToken st;
4771             boolean inBody = false;
4772             String routineBodyStr = "";
4773             for(int i=0;i<pcsqlstatement.sourcetokenlist.size();i++){
4774                 st = pcsqlstatement.sourcetokenlist.get(i);
4775                 if (isDollarFunctionDelimiter(st.tokencode,this.dbVendor)
4776//                         ((st.tokencode == TBaseType.rrw_postgresql_function_delimiter)&&(this.dbVendor == EDbVendor.dbvpostgresql))
4777//                        ||((st.tokencode == TBaseType.rrw_greenplum_function_delimiter)&&(this.dbVendor == EDbVendor.dbvgreenplum))
4778//                         ||((st.tokencode == TBaseType.rrw_redshift_function_delimiter)&&(this.dbVendor == EDbVendor.dbvredshift))
4779//                         ||((st.tokencode == TBaseType.rrw_snowflake_function_delimiter)&&(this.dbVendor == EDbVendor.dbvsnowflake))
4780                 ){
4781                     if (!inBody){
4782                         inBody = true;
4783                         routineBodyStr = st.toString();
4784                     }else{
4785                         inBody = false;
4786                         routineBodyStr += st.toString();
4787                         break;
4788                     }
4789                     continue;
4790                 }
4791
4792                 if (inBody){
4793                     st.tokencode = TBaseType.sqlpluscmd;
4794                     routineBodyStr += st.toString();
4795                 }
4796             }
4797
4798             ((TRoutine)pcsqlstatement).setRoutineBody(routineBodyStr);
4799         }
4800    }
4801}
4802
4803    int doredshiftgetrawsqlstatements(){
4804
4805        int waitingEnd = 0;
4806        boolean foundEnd = false, enterDeclare = false;
4807
4808
4809
4810        if ( TBaseType.assigned(sqlstatements) ) sqlstatements.clear();
4811        if ( ! TBaseType.assigned(sourcetokenlist) ) return -1;
4812
4813        gcurrentsqlstatement = null;
4814        EFindSqlStateType gst = EFindSqlStateType.stnormal;
4815        TSourceToken lcprevsolidtoken = null,ast = null;
4816
4817
4818        if (isSinglePLBlock){
4819            gcurrentsqlstatement = new TCommonBlock(EDbVendor.dbvpostgresql);
4820        }
4821
4822        for (int i=0 ; i < sourcetokenlist.size();i++)
4823        {
4824
4825            if ( (ast != null ) && (ast.issolidtoken() ))
4826                lcprevsolidtoken = ast;
4827
4828            ast = sourcetokenlist.get(i);
4829            sourcetokenlist.curpos = i;
4830
4831            if (ast.tokencode == TBaseType.rrw_redshift_filter) {
4832                TSourceToken st1 = ast.nextSolidToken(); //ast.searchToken('(',1);
4833                if (st1 != null) {
4834                    if (st1.tokencode == '(') {
4835
4836                    }else{
4837                        ast.tokencode = TBaseType.ident;
4838                    }
4839                }
4840            }else if (ast.tokencode == TBaseType.rrw_redshift_array){
4841                TSourceToken st1 = ast.searchToken('<',1);
4842                if (st1 != null) { // array<varchar(20)>
4843                    ast.tokencode = TBaseType.rrw_redshift_array_type;
4844                }
4845            }
4846            else if (ast.tokencode == TBaseType.rrw_values) {
4847                TSourceToken stParen =  ast.searchToken('(',1);
4848                if (stParen != null){
4849                    TSourceToken stInsert  = ast.searchToken(TBaseType.rrw_insert,-ast.posinlist);
4850                    if (stInsert != null){
4851                        TSourceToken stSemiColon  = ast.searchToken(';',-ast.posinlist);
4852                        if ((stSemiColon != null)&&(stSemiColon.posinlist > stInsert.posinlist)){
4853//                            INSERT INTO test values (16,1), (8,2), (4,4), (2,0), (97, 16);
4854//                            VALUES (1);
4855                            // don't treat values(1) as insert values
4856
4857                        }else{
4858                            TSourceToken stFrom  = ast.searchToken(TBaseType.rrw_from,-ast.posinlist);
4859                            if ((stFrom != null)&&(stFrom.posinlist > stInsert.posinlist)){
4860                                // don't treat values after from keyword as an insert values
4861
4862                                // insert into inserttest values(10, 20, '40'), (-1, 2, DEFAULT),  ((select 2), (select i from (values(3) ) as foo (i)), 'values are fun!');
4863
4864                            }else{
4865                                ast.tokencode = TBaseType.rrw_postgresql_insert_values;
4866                            }
4867
4868                        }
4869
4870                    }
4871                }
4872            }
4873
4874            switch(gst){
4875                case sterror:{
4876                    if (ast.tokentype ==  ETokenType.ttsemicolon)
4877                    {
4878                        gcurrentsqlstatement.sourcetokenlist.add(ast);
4879                        doongetrawsqlstatementevent(gcurrentsqlstatement);
4880                        gst = EFindSqlStateType.stnormal;
4881                    }
4882                    else
4883                    {
4884                        gcurrentsqlstatement.sourcetokenlist.add(ast);
4885                    }
4886                    break;
4887                } //sterror
4888
4889                case stnormal:{
4890                    if ((ast.tokencode  == TBaseType.cmtdoublehyphen)
4891                            || (ast.tokencode  == TBaseType.cmtslashstar)
4892                            || (ast.tokencode  == TBaseType.lexspace)
4893                            || (ast.tokencode  == TBaseType.lexnewline)
4894                            || (ast.tokentype  == ETokenType.ttsemicolon) )
4895                    {
4896                        if (gcurrentsqlstatement != null)
4897                        {
4898                            gcurrentsqlstatement.addtokentolist(ast);
4899                        }
4900
4901                        if ((lcprevsolidtoken != null) && (ast.tokentype == ETokenType.ttsemicolon))
4902                        {
4903                            if (lcprevsolidtoken.tokentype == ETokenType.ttsemicolon )
4904                            {
4905                                // ;;;; continuous semicolon,treat it as comment
4906                                ast.tokentype = ETokenType.ttsimplecomment;
4907                                ast.tokencode =  TBaseType.cmtdoublehyphen;
4908                            }
4909                        }
4910
4911                        continue;
4912                    }
4913
4914                    if (ast.tokencode == TBaseType.sqlpluscmd )
4915                    {
4916                        gst = EFindSqlStateType.stsqlplus;
4917                        gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
4918                        gcurrentsqlstatement.addtokentolist(ast);
4919                        continue;
4920                    }
4921
4922                    // find a tokentext to start sql or plsql mode
4923                    gcurrentsqlstatement = sqlcmds.issql(ast, dbVendor,gst,gcurrentsqlstatement);
4924
4925                    if (gcurrentsqlstatement != null)
4926                    {
4927                        enterDeclare = false;
4928                        if (gcurrentsqlstatement.ispgplsql())
4929                        {
4930                            gst = EFindSqlStateType.ststoredprocedure;
4931                            gcurrentsqlstatement.addtokentolist(ast);
4932                            foundEnd = false;
4933                            if   ((ast.tokencode == TBaseType.rrw_begin)
4934                                    ||(ast.tokencode == TBaseType.rrw_package)
4935                                    || (ast.searchToken(TBaseType.rrw_package,4) != null)
4936                            )
4937                            {
4938                                waitingEnd = 1;
4939                            }
4940                            else if (ast.tokencode == TBaseType.rrw_declare){
4941                                enterDeclare = true;
4942                            }
4943                        }
4944                        else
4945                        {
4946                            gst = EFindSqlStateType.stsql;
4947                            gcurrentsqlstatement.addtokentolist(ast);
4948                        }
4949                    }else{
4950                        //error tokentext found
4951
4952                        this.syntaxErrors.add( new TSyntaxError(ast.astext,ast.lineNo,(ast.columnNo < 0 ? 0:ast.columnNo)
4953                                ,"Error when tokenlize", EErrorType.spwarning,TBaseType.MSG_WARNING_ERROR_WHEN_TOKENIZE,null,ast.posinlist));
4954
4955                        ast.tokentype = ETokenType.tttokenlizererrortoken;
4956                        gst = EFindSqlStateType.sterror;
4957
4958                        gcurrentsqlstatement = new TUnknownSqlStatement(dbVendor);
4959                        gcurrentsqlstatement.sqlstatementtype = ESqlStatementType.sstinvalid;
4960                        gcurrentsqlstatement.addtokentolist(ast);
4961
4962                    }
4963
4964                    break;
4965                } // stnormal
4966
4967                case stsqlplus:{
4968                    if  (ast.insqlpluscmd)
4969                    {gcurrentsqlstatement.addtokentolist(ast);}
4970                    else
4971                    {
4972                        gst = EFindSqlStateType.stnormal; //this tokentext must be newline,
4973                        gcurrentsqlstatement.addtokentolist(ast); // so add it here
4974                        doongetrawsqlstatementevent(gcurrentsqlstatement);
4975                    }
4976
4977                    break;
4978                }//case stsqlplus
4979
4980                case stsql:{
4981                    if (ast.tokentype == ETokenType.ttsemicolon)
4982                    {
4983                        gst = EFindSqlStateType.stnormal;
4984                        gcurrentsqlstatement.addtokentolist(ast);
4985                        gcurrentsqlstatement.semicolonended = ast;
4986                        doongetrawsqlstatementevent(gcurrentsqlstatement);
4987                        continue;
4988                    }
4989
4990                    if  (sourcetokenlist.sqlplusaftercurtoken() ) //most probaly is / cmd
4991                    {
4992                        gst = EFindSqlStateType.stnormal;
4993                        gcurrentsqlstatement.addtokentolist(ast);
4994                        doongetrawsqlstatementevent(gcurrentsqlstatement);
4995                        continue;
4996                    }
4997
4998                    if (ast.tokencode  == TBaseType.cmtdoublehyphen){
4999                        if (ast.toString().trim().endsWith(TBaseType.sqlflow_stmt_delimiter_str)){ // -- sqlflow-delimiter
5000                            gst = EFindSqlStateType.stnormal;
5001                            doongetrawsqlstatementevent(gcurrentsqlstatement);
5002                            continue;
5003                        }
5004                    }
5005
5006                    gcurrentsqlstatement.addtokentolist(ast);
5007                    break;
5008                }//case stsql
5009
5010                case ststoredprocedure:{
5011                    if (ast.tokencode == TBaseType.rrw_redshift_function_delimiter){
5012                        gcurrentsqlstatement.addtokentolist(ast);
5013                        gst = EFindSqlStateType.ststoredprocedurePgStartBody;
5014
5015                        continue;
5016                    }
5017
5018                    if (ast.tokencode == TBaseType.rrw_redshift_language){
5019                        // check next token which is the language used by this stored procedure
5020                        TSourceToken nextSt = ast.nextSolidToken();
5021                        if (nextSt != null){
5022                            if (gcurrentsqlstatement instanceof TRoutine){  // can be TCreateProcedureStmt or TCreateFunctionStmt
5023                                TRoutine p = (TRoutine) gcurrentsqlstatement;
5024                                p.setRoutineLanguage(nextSt.toString());
5025
5026                            }
5027                        }
5028                    }
5029
5030                    if ((ast.tokentype == ETokenType.ttsemicolon) && (waitingEnd == 0) && (!enterDeclare))
5031                    {
5032                        gst = EFindSqlStateType.stnormal;
5033                        gcurrentsqlstatement.addtokentolist(ast);
5034                        gcurrentsqlstatement.semicolonended = ast;
5035                        doongetrawsqlstatementevent(gcurrentsqlstatement);
5036                        continue;
5037                    }
5038
5039                    if   ((ast.tokencode == TBaseType.rrw_begin)
5040                        //||(ast.tokencode == TBaseType.rrw_between)
5041                    )
5042                    {
5043                        waitingEnd++;
5044                        enterDeclare = false;
5045                    }
5046                    else if   (
5047                            (ast.tokencode == TBaseType.rrw_declare)
5048                    ){
5049                        enterDeclare = true;
5050                    }
5051                    else if   (
5052                            (ast.tokencode == TBaseType.rrw_if)
5053                    ){
5054                        if (ast.searchToken(TBaseType.rrw_end,-1) == null){
5055                            //this is not if after END
5056                            waitingEnd++;
5057                        }
5058                    }
5059                    else if   (
5060                            (ast.tokencode == TBaseType.rrw_case)
5061                    ){
5062                        if (ast.searchToken(TBaseType.rrw_end,-1) == null){
5063                            //this is not case after END
5064                            waitingEnd++;
5065                        }
5066                    }
5067                    else if   (
5068                            (ast.tokencode == TBaseType.rrw_loop)
5069                    ){
5070                        if (ast.searchToken(TBaseType.rrw_end,-1) == null){
5071                            //this is not loop after END
5072                            waitingEnd++;
5073                        }
5074                    }
5075                    else if (ast.tokencode == TBaseType.rrw_end){
5076                        foundEnd = true;
5077                        waitingEnd--;
5078                        if (waitingEnd < 0) { waitingEnd = 0;}
5079                    }
5080
5081                    if ((ast.tokentype == ETokenType.ttslash)  && (ast.tokencode == TBaseType.sqlpluscmd) ) //and (prevst.NewlineIsLastTokenInTailerToken)) then
5082                    {
5083                        // TPlsqlStatementParse(asqlstatement).TerminatorToken := ast;
5084                        ast.tokenstatus = ETokenStatus.tsignorebyyacc;
5085                        gst = EFindSqlStateType.stnormal;
5086                        doongetrawsqlstatementevent(gcurrentsqlstatement);
5087
5088                        //make / a sqlplus cmd
5089                        gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
5090                        gcurrentsqlstatement.addtokentolist(ast);
5091                        doongetrawsqlstatementevent(gcurrentsqlstatement);
5092                    }
5093                    else  if ((ast.tokentype == ETokenType.ttperiod)  && (sourcetokenlist.returnaftercurtoken(false)) && (sourcetokenlist.returnbeforecurtoken(false)))
5094                    {    // single dot at a seperate line
5095                        ast.tokenstatus = ETokenStatus.tsignorebyyacc;
5096                        gst = EFindSqlStateType.stnormal;
5097                        doongetrawsqlstatementevent(gcurrentsqlstatement);
5098
5099                        //make ttperiod a sqlplus cmd
5100                        gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
5101                        gcurrentsqlstatement.addtokentolist(ast);
5102                        doongetrawsqlstatementevent(gcurrentsqlstatement);
5103                    }
5104                    else
5105                    {
5106                        gcurrentsqlstatement.addtokentolist(ast);
5107                        if ((ast.tokentype == ETokenType.ttsemicolon) && (waitingEnd == 0)
5108                                && (foundEnd)
5109                            //        && (gcurrentsqlstatement.OracleStatementCanBeSeparatedByBeginEndPair())
5110                        ){
5111                            gst = EFindSqlStateType.stnormal;
5112                            doongetrawsqlstatementevent(gcurrentsqlstatement);
5113                        }
5114                    }
5115
5116                    if (ast.tokencode == TBaseType.sqlpluscmd)
5117                    {
5118                        //change tokencode back to keyword or TBaseType.ident, because sqlplus cmd
5119                        //in a sql statement(almost is plsql block) is not really a sqlplus cmd
5120                        int m = flexer.getkeywordvalue(ast.astext);
5121                        if (m != 0)
5122                        {ast.tokencode = m;}
5123                        else
5124                        {ast.tokencode = TBaseType.ident;}
5125                    }
5126
5127                    if (( gst == EFindSqlStateType.ststoredprocedure ) && (ast.tokencode  == TBaseType.cmtdoublehyphen)){
5128                        if (ast.toString().trim().endsWith(TBaseType.sqlflow_stmt_delimiter_str)){ // -- sqlflow-delimiter
5129                            gst = EFindSqlStateType.stnormal;
5130                            doongetrawsqlstatementevent(gcurrentsqlstatement);
5131                        }
5132                    }
5133
5134                    break;
5135                } //ststoredprocedure
5136
5137                case ststoredprocedurePgStartBody:{
5138                    gcurrentsqlstatement.addtokentolist(ast);
5139
5140                    if (ast.tokencode == TBaseType.rrw_redshift_function_delimiter){
5141                        gst = EFindSqlStateType.ststoredprocedurePgEndBody;
5142                        continue;
5143                    }
5144
5145                    break;
5146                }
5147
5148                case ststoredprocedurePgEndBody:{
5149
5150                    if (ast.tokentype == ETokenType.ttsemicolon)
5151                    {
5152                        gst = EFindSqlStateType.stnormal;
5153                        gcurrentsqlstatement.addtokentolist(ast);
5154                        gcurrentsqlstatement.semicolonended = ast;
5155                        doongetrawsqlstatementevent(gcurrentsqlstatement);
5156                        continue;
5157                    }
5158                    else if (ast.tokencode  == TBaseType.cmtdoublehyphen){
5159                        if (ast.toString().trim().endsWith(TBaseType.sqlflow_stmt_delimiter_str)){ // -- sqlflow-delimiter
5160                            gst = EFindSqlStateType.stnormal;
5161                            doongetrawsqlstatementevent(gcurrentsqlstatement);
5162                            continue;
5163                        }
5164                    }
5165
5166                    gcurrentsqlstatement.addtokentolist(ast);
5167
5168                    if (ast.tokencode == TBaseType.rrw_redshift_language){
5169                        // check next token which is the language used by this stored procedure
5170                        TSourceToken nextSt = ast.nextSolidToken();
5171                        if (nextSt != null){
5172                            if (gcurrentsqlstatement instanceof TRoutine){  // can be TCreateProcedureStmt or TCreateFunctionStmt
5173                                TRoutine p = (TRoutine) gcurrentsqlstatement;
5174                                p.setRoutineLanguage(nextSt.toString());
5175                            }
5176                        }
5177                    }
5178
5179                    break;
5180                }
5181            } //switch
5182
5183        }//for
5184
5185
5186        //last statement
5187        if ((gcurrentsqlstatement != null) &&
5188                ((gst == EFindSqlStateType.stsqlplus) ||  (gst == EFindSqlStateType.stsql)
5189                        || (gst == EFindSqlStateType.ststoredprocedure)
5190                        || (gst == EFindSqlStateType.ststoredprocedurePgEndBody)
5191                        ||(gst == EFindSqlStateType.sterror)||(isSinglePLBlock)
5192                ))
5193        {
5194            doongetrawsqlstatementevent(gcurrentsqlstatement);
5195        }
5196
5197        return syntaxErrors.size();
5198    }
5199
5200    int doverticagetrawsqlstatements(){
5201        int waitingEnd = 0;
5202        boolean foundEnd = false;
5203
5204        if ( TBaseType.assigned(sqlstatements) ) sqlstatements.clear();
5205        if ( ! TBaseType.assigned(sourcetokenlist) ) return -1;
5206
5207        gcurrentsqlstatement = null;
5208        EFindSqlStateType gst = EFindSqlStateType.stnormal;
5209        TSourceToken lcprevsolidtoken = null,ast = null;
5210
5211        for (int i=0 ; i < sourcetokenlist.size();i++)
5212        {
5213
5214            if ( (ast != null ) && (ast.issolidtoken() ))
5215                lcprevsolidtoken = ast;
5216
5217            ast = sourcetokenlist.get(i);
5218            sourcetokenlist.curpos = i;
5219
5220            if (ast.tokencode == TBaseType.rrw_date){
5221                TSourceToken st1 =  ast.nextSolidToken(); //ast.searchToken('(',1);
5222                if (st1 != null){
5223                    if (st1.tokencode == '('){
5224                        ast.tokencode = TBaseType.rrw_vertica_date_function;
5225                    }
5226                }
5227            }else if ((ast.tokencode == TBaseType.rrw_vertica_greatest)||(ast.tokencode == TBaseType.rrw_vertica_least)){
5228                TSourceToken st1 =  ast.nextSolidToken(); //ast.searchToken('(',1);
5229                if (st1 != null){
5230                    if (st1.tokencode != '('){
5231                        ast.tokencode = TBaseType.ident;
5232                    }
5233                }
5234            }
5235
5236            switch(gst){
5237                case sterror:{
5238                    if (ast.tokentype ==  ETokenType.ttsemicolon)
5239                    {
5240                        gcurrentsqlstatement.sourcetokenlist.add(ast);
5241                        doongetrawsqlstatementevent(gcurrentsqlstatement);
5242                        gst = EFindSqlStateType.stnormal;
5243                    }
5244                    else
5245                    {
5246                        gcurrentsqlstatement.sourcetokenlist.add(ast);
5247                    }
5248                    break;
5249                } //sterror
5250
5251                case stnormal:{
5252                    if ((ast.tokencode  == TBaseType.cmtdoublehyphen)
5253                            || (ast.tokencode  == TBaseType.cmtslashstar)
5254                            || (ast.tokencode  == TBaseType.lexspace)
5255                            || (ast.tokencode  == TBaseType.lexnewline)
5256                            || (ast.tokentype  == ETokenType.ttsemicolon) )
5257                    {
5258                        if (gcurrentsqlstatement != null)
5259                        {
5260                            gcurrentsqlstatement.addtokentolist(ast);
5261                        }
5262
5263                        if ((lcprevsolidtoken != null) && (ast.tokentype == ETokenType.ttsemicolon))
5264                        {
5265                            if (lcprevsolidtoken.tokentype == ETokenType.ttsemicolon )
5266                            {
5267                                // ;;;; continuous semicolon,treat it as comment
5268                                ast.tokentype = ETokenType.ttsimplecomment;
5269                                ast.tokencode =  TBaseType.cmtdoublehyphen;
5270                            }
5271                        }
5272
5273                        continue;
5274                    }
5275
5276                    if (ast.tokencode == TBaseType.sqlpluscmd )
5277                    {
5278                        gst = EFindSqlStateType.stsqlplus;
5279                        gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
5280                        gcurrentsqlstatement.addtokentolist(ast);
5281                        continue;
5282                    }
5283
5284                    // find a token text to start sql or plsql mode
5285                    gcurrentsqlstatement = sqlcmds.issql(ast, dbVendor,gst,gcurrentsqlstatement);
5286
5287                    if (gcurrentsqlstatement != null)
5288                    {
5289                        if (gcurrentsqlstatement.isverticaplsql())
5290                        {
5291                            gst = EFindSqlStateType.ststoredprocedure;
5292                            gcurrentsqlstatement.addtokentolist(ast);
5293                            foundEnd = true;
5294                            if   ((ast.tokencode == TBaseType.rrw_begin)
5295                                    ||(ast.tokencode == TBaseType.rrw_package)
5296                                    || (ast.searchToken(TBaseType.rrw_package,4) != null)
5297                                    )
5298                            { waitingEnd = 1;}
5299                        }
5300                        else
5301                        {
5302                            gst = EFindSqlStateType.stsql;
5303                            gcurrentsqlstatement.addtokentolist(ast);
5304                        }
5305                    }else{
5306                        //error tokentext found
5307
5308                        this.syntaxErrors.add( new TSyntaxError(ast.astext,ast.lineNo,(ast.columnNo < 0 ? 0:ast.columnNo),"Error when tokenlize"
5309                                , EErrorType.spwarning,TBaseType.MSG_WARNING_ERROR_WHEN_TOKENIZE,null,ast.posinlist));
5310
5311                        ast.tokentype = ETokenType.tttokenlizererrortoken;
5312                        gst = EFindSqlStateType.sterror;
5313
5314                        gcurrentsqlstatement = new TUnknownSqlStatement(dbVendor);
5315                        gcurrentsqlstatement.sqlstatementtype = ESqlStatementType.sstinvalid;
5316                        gcurrentsqlstatement.addtokentolist(ast);
5317
5318                    }
5319
5320                    break;
5321                } // stnormal
5322
5323                case stsqlplus:{
5324                    if  (ast.insqlpluscmd)
5325                    {gcurrentsqlstatement.addtokentolist(ast);}
5326                    else
5327                    {
5328                        gst = EFindSqlStateType.stnormal; //this tokentext must be newline,
5329                        gcurrentsqlstatement.addtokentolist(ast); // so add it here
5330                        doongetrawsqlstatementevent(gcurrentsqlstatement);
5331                    }
5332
5333                    break;
5334                }//case stsqlplus
5335
5336                case stsql:{
5337                    if (ast.tokentype == ETokenType.ttsemicolon)
5338                    {
5339                        gst = EFindSqlStateType.stnormal;
5340                        gcurrentsqlstatement.addtokentolist(ast);
5341                        gcurrentsqlstatement.semicolonended = ast;
5342                        doongetrawsqlstatementevent(gcurrentsqlstatement);
5343                        continue;
5344                    }
5345
5346                    if  (sourcetokenlist.sqlplusaftercurtoken() ) //most probaly is / cmd
5347                    {
5348                        gst = EFindSqlStateType.stnormal;
5349                        gcurrentsqlstatement.addtokentolist(ast);
5350                        doongetrawsqlstatementevent(gcurrentsqlstatement);
5351                        continue;
5352                    }
5353                    gcurrentsqlstatement.addtokentolist(ast);
5354                    break;
5355                }//case stsql
5356
5357                case ststoredprocedure:{
5358                    if   ((ast.tokencode == TBaseType.rrw_begin)
5359                        //||(ast.tokencode == TBaseType.rrw_between)
5360                            )
5361                    {
5362                        waitingEnd++;
5363                        foundEnd = false;
5364                    }
5365                    else if   (
5366                            (ast.tokencode == TBaseType.rrw_if)
5367                            ){
5368                        if (ast.searchToken(TBaseType.rrw_end,-1) == null){
5369                            //this is not if after END
5370                            waitingEnd++;
5371                        }
5372                    }
5373                    else if   (
5374                            (ast.tokencode == TBaseType.rrw_case)
5375                            ){
5376                        if (ast.searchToken(TBaseType.rrw_end,-1) == null){
5377                            //this is not case after END
5378                            waitingEnd++;
5379                        }
5380                    }
5381                    else if   (
5382                            (ast.tokencode == TBaseType.rrw_loop)
5383                            ){
5384                        if (ast.searchToken(TBaseType.rrw_end,-1) == null){
5385                            //this is not loop after END
5386                            waitingEnd++;
5387                        }
5388                    }
5389                    else if (ast.tokencode == TBaseType.rrw_end){
5390                        foundEnd = true;
5391                        waitingEnd--;
5392                        if (waitingEnd < 0) { waitingEnd = 0;}
5393                    }
5394
5395                    if ((ast.tokentype == ETokenType.ttslash)  && (ast.tokencode == TBaseType.sqlpluscmd) ) //and (prevst.NewlineIsLastTokenInTailerToken)) then
5396                    {
5397                        // TPlsqlStatementParse(asqlstatement).TerminatorToken := ast;
5398                        ast.tokenstatus = ETokenStatus.tsignorebyyacc;
5399                        gst = EFindSqlStateType.stnormal;
5400                        doongetrawsqlstatementevent(gcurrentsqlstatement);
5401
5402                        //make / a sqlplus cmd
5403                        gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
5404                        gcurrentsqlstatement.addtokentolist(ast);
5405                        doongetrawsqlstatementevent(gcurrentsqlstatement);
5406                    }
5407                    else  if ((ast.tokentype == ETokenType.ttperiod)  && (sourcetokenlist.returnaftercurtoken(false)) && (sourcetokenlist.returnbeforecurtoken(false)))
5408                    {    // single dot at a seperate line
5409                        ast.tokenstatus = ETokenStatus.tsignorebyyacc;
5410                        gst = EFindSqlStateType.stnormal;
5411                        doongetrawsqlstatementevent(gcurrentsqlstatement);
5412
5413                        //make ttperiod a sqlplus cmd
5414                        gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
5415                        gcurrentsqlstatement.addtokentolist(ast);
5416                        doongetrawsqlstatementevent(gcurrentsqlstatement);
5417                    }
5418                    else
5419                    {
5420                        gcurrentsqlstatement.addtokentolist(ast);
5421                        if ((ast.tokentype == ETokenType.ttsemicolon) && (waitingEnd == 0) && (foundEnd) && (gcurrentsqlstatement.VerticaStatementCanBeSeparatedByBeginEndPair())){
5422                            gst = EFindSqlStateType.stnormal;
5423                            doongetrawsqlstatementevent(gcurrentsqlstatement);
5424                        }
5425                    }
5426
5427                    if (ast.tokencode == TBaseType.sqlpluscmd)
5428                    {
5429                        //change tokencode back to keyword or TBaseType.ident, because sqlplus cmd
5430                        //in a sql statement(almost is plsql block) is not really a sqlplus cmd
5431                        int m = flexer.getkeywordvalue(ast.astext);
5432                        if (m != 0)
5433                        {ast.tokencode = m;}
5434                        else
5435                        {ast.tokencode = TBaseType.ident;}
5436                    }
5437
5438                    break;
5439                } //ststoredprocedure
5440            } //switch
5441        }//for
5442
5443        //last statement
5444        if ((gcurrentsqlstatement != null) &&
5445                ((gst == EFindSqlStateType.stsqlplus) ||  (gst == EFindSqlStateType.stsql) || (gst == EFindSqlStateType.ststoredprocedure) ||
5446                        (gst == EFindSqlStateType.sterror)))
5447        {
5448            doongetrawsqlstatementevent(gcurrentsqlstatement);
5449        }
5450
5451        return syntaxErrors.size();
5452    }
5453
5454    boolean checkTokenPairWithEnd(int tokencode){
5455        return    ((tokencode == TBaseType.rrw_if)||(tokencode == TBaseType.rrw_case)
5456                ||(tokencode == TBaseType.rrw_loop)||(tokencode == TBaseType.rrw_repeat)
5457                ||(tokencode == TBaseType.rrw_while)||(tokencode == TBaseType.rrw_for)
5458                ||(tokencode == TBaseType.rrw_case)
5459        );
5460    }
5461
5462    int dobigquerygetrawsqlstatements() {
5463        int errorcount = 0;
5464        gcurrentsqlstatement = null;
5465        EFindSqlStateType gst = EFindSqlStateType.stnormal;
5466        int i,c, beginNested = 0,waitingEnd=0;
5467        TSourceToken ast = null, lcprevsolidtoken = null;
5468        boolean waitingDelimiter = false;
5469
5470        int waitingEnds[] = new int[stored_procedure_nested_level];
5471        stored_procedure_type sptype[] = new stored_procedure_type[stored_procedure_nested_level];
5472        stored_procedure_status procedure_status[] = new stored_procedure_status[stored_procedure_nested_level];
5473        boolean endBySlashOnly = true;
5474        int nestedProcedures = 0, nestedParenthesis = 0;
5475
5476
5477        //reset delimiter
5478        userDelimiterStr = defaultDelimiterStr;
5479
5480        for (i=0;i < sourcetokenlist.size();i++)
5481        {
5482            if ( (ast != null ) && (ast.issolidtoken() ))
5483                lcprevsolidtoken = ast;
5484
5485            ast = sourcetokenlist.get(i);
5486            sourcetokenlist.curpos = i;
5487
5488            if (ast.tokencode == TBaseType.rrw_bigquery_struct){
5489                TSourceToken st1 =  ast.nextSolidToken(); //ast.searchToken('(',1);
5490                if (st1 != null){
5491                    if (st1.tokencode == '('){
5492                        ast.tokencode = TBaseType.rrw_bigquery_struct_constructor;
5493                    }
5494                }
5495            } else if ((ast.tokencode == TBaseType.sconst)
5496            //        ||(ast.tokencode == '+')||(ast.tokencode == '-')
5497            ){
5498            if (TTypeName.searchTypeByName(lcprevsolidtoken.toString()) != null){
5499                // date '2021-2-1', turn date to TBaseType.rrw_bigquery_datatype_used_to_cast
5500                if (lcprevsolidtoken.tokencode != TBaseType.rrw_interval){
5501                        lcprevsolidtoken.tokencode = TBaseType.rrw_bigquery_datatype_used_to_cast;
5502                    }
5503                }
5504//            else if (ast.tokencode == TBaseType.rrw_timestamp){
5505//                TSourceToken st1 =  ast.nextSolidToken();
5506//                if (st1 != null){
5507//                    if (st1.tokencode == TBaseType.sconst){
5508//                        ast.tokencode = TBaseType.rrw_bigquery_timestamp_before_const;
5509//                    }
5510//                }
5511            }else if((ast.tokencode == TBaseType.rrw_time)||(ast.tokencode == TBaseType.rrw_date)) {
5512
5513                TSourceToken st1 = ast.nextSolidToken();
5514                if (st1 != null) {
5515                    if (st1.tokencode == TBaseType.sconst) {
5516                        // ast.tokencode = TBaseType.rrw_bigquery_time_before_const;
5517                    } else if (st1.tokencode == '(') {
5518                        ast.tokencode = TBaseType.ident;
5519                    }
5520                }
5521            }else if (ast.tokencode == TBaseType.rrw_from){
5522                TSourceToken st1 =  ast.prevSolidToken();
5523                if (st1 != null){ // select i.from as `from` from t, treats from in i.from as identifier
5524                    if (st1.tokencode == '.'){
5525                        ast.tokencode = TBaseType.ident;
5526                    }
5527                }
5528            }
5529
5530            switch(gst){
5531                case sterror:
5532                {
5533                    if (ast.tokentype == ETokenType.ttsemicolon)
5534                    {
5535                        gcurrentsqlstatement.sourcetokenlist.add(ast);
5536                        doongetrawsqlstatementevent(gcurrentsqlstatement);
5537                        gst = EFindSqlStateType.stnormal;
5538                    }
5539                    else
5540                    {
5541                        gcurrentsqlstatement.sourcetokenlist.add(ast);
5542                    }
5543                    break;
5544                }
5545                case stnormal :
5546                {
5547                    if ((ast.tokencode  == TBaseType.cmtdoublehyphen)
5548                            || (ast.tokencode  == TBaseType.cmtslashstar)
5549                            || (ast.tokencode  == TBaseType.lexspace)
5550                            || (ast.tokencode  == TBaseType.lexnewline)
5551                            || (ast.tokentype  == ETokenType.ttsemicolon) )
5552                    {
5553                        if (TBaseType.assigned(gcurrentsqlstatement))
5554                        {
5555                            gcurrentsqlstatement.addtokentolist(ast);
5556                        }
5557
5558                        continue;
5559                    }
5560
5561
5562                    // find a tokentext to start sql or plsql mode
5563                    gcurrentsqlstatement = sqlcmds.issql(ast, dbVendor,gst,gcurrentsqlstatement);
5564
5565                    if (TBaseType.assigned(gcurrentsqlstatement))
5566                    {
5567                        if (gcurrentsqlstatement.isBigQueryplsql())
5568                        {
5569                            nestedProcedures = 0;
5570                            gst = EFindSqlStateType.ststoredprocedure;
5571                            gcurrentsqlstatement.addtokentolist(ast);
5572
5573                            switch (gcurrentsqlstatement.sqlstatementtype){
5574                                case sstplsql_createprocedure:
5575                                case sstcreateprocedure:
5576                                    sptype[nestedProcedures] = stored_procedure_type.procedure;
5577                                    break;
5578                                case sstplsql_createfunction:
5579                                    sptype[nestedProcedures] = stored_procedure_type.function;
5580                                    break;
5581                                case sstplsql_createpackage:
5582                                    sptype[nestedProcedures] = stored_procedure_type.package_spec;
5583                                    if (ast.searchToken(TBaseType.rrw_body,5) != null){
5584                                        sptype[nestedProcedures] = stored_procedure_type.package_body;
5585                                    }
5586                                    break;
5587                                case sst_plsql_block:
5588                                    sptype[nestedProcedures] = stored_procedure_type.block_with_declare;
5589                                    if (ast.tokencode == TBaseType.rrw_begin) {
5590                                        sptype[nestedProcedures] = stored_procedure_type.block_with_begin;
5591                                    }
5592                                    break;
5593                                case sstplsql_createtrigger:
5594                                    sptype[nestedProcedures] = stored_procedure_type.create_trigger;
5595                                    break;
5596                                case sstoraclecreatelibrary:
5597                                    sptype[nestedProcedures] = stored_procedure_type.create_library;
5598                                    break;
5599                                case sstplsql_createtype_placeholder:
5600                                    gst = EFindSqlStateType.stsql;
5601                                    break;
5602                                default:
5603                                    sptype[nestedProcedures] = stored_procedure_type.others;
5604                                    break;
5605                            }
5606
5607                            if (sptype[0] == stored_procedure_type.block_with_declare){
5608                                // sd
5609                                endBySlashOnly = false;
5610                                procedure_status[0] = stored_procedure_status.is_as;
5611                            }else if (sptype[0] == stored_procedure_type.block_with_begin){
5612                                // sb
5613                                endBySlashOnly = false;
5614                                procedure_status[0] = stored_procedure_status.body;
5615                            }else if (sptype[0] == stored_procedure_type.procedure){
5616                                // ss
5617                                endBySlashOnly = false;
5618                                procedure_status[0] = stored_procedure_status.start;
5619                            }else if (sptype[0] == stored_procedure_type.function){
5620                                // ss
5621                                endBySlashOnly = false;
5622                                procedure_status[0] = stored_procedure_status.start;
5623                            }else if (sptype[0] == stored_procedure_type.package_spec){
5624                                // ss
5625                                endBySlashOnly = false;
5626                                procedure_status[0] = stored_procedure_status.start;
5627                            }else if (sptype[0] == stored_procedure_type.package_body){
5628                                // ss
5629                                endBySlashOnly = false;
5630                                procedure_status[0] = stored_procedure_status.start;
5631                            }else if (sptype[0] == stored_procedure_type.create_trigger){
5632                                // ss
5633                                endBySlashOnly = false;
5634                                procedure_status[0] = stored_procedure_status.start;
5635                                //procedure_status[0] = stored_procedure_status.body;
5636                            }else if (sptype[0] == stored_procedure_type.create_library){
5637                                // ss
5638                                endBySlashOnly = false;
5639                                procedure_status[0] = stored_procedure_status.bodyend;
5640                            }else {
5641                                // so
5642                                endBySlashOnly = true;
5643                                procedure_status[0] = stored_procedure_status.bodyend;
5644                            }
5645                            //foundEnd = false;
5646                            if   ((ast.tokencode == TBaseType.rrw_begin)
5647                                    ||(ast.tokencode == TBaseType.rrw_package)
5648                                    //||(ast.tokencode == TBaseType.rrw_procedure)
5649                                    || (ast.searchToken(TBaseType.rrw_package,4) != null)
5650                            )
5651                            {
5652                                //waitingEnd = 1;
5653                                waitingEnds[nestedProcedures] = 1;
5654                            }
5655
5656                        }else if ((gcurrentsqlstatement.sqlstatementtype == sst_ifstmt)
5657                            ||(gcurrentsqlstatement.sqlstatementtype == sst_loopstmt)
5658                            ||(gcurrentsqlstatement.sqlstatementtype == sstRepeat)
5659                            ||(gcurrentsqlstatement.sqlstatementtype == sstWhilestmt)
5660                            ||(gcurrentsqlstatement.sqlstatementtype == sstForStmt)
5661                            ||(gcurrentsqlstatement.sqlstatementtype == sst_plsql_block)
5662                                ||(gcurrentsqlstatement.sqlstatementtype == sst_casestmt)
5663
5664                        ){
5665                            gst = EFindSqlStateType.stBigQueryIf;
5666                            waitingEnd = 1;
5667                            gcurrentsqlstatement.addtokentolist(ast);
5668                        }
5669                        else
5670                        {
5671                            gst = EFindSqlStateType.stsql;
5672                            gcurrentsqlstatement.addtokentolist(ast);
5673                        }
5674
5675                    }
5676
5677
5678                    if (!TBaseType.assigned(gcurrentsqlstatement) ) //error tokentext found
5679                    {
5680
5681//                        errormessage = "error when tokenlize:"+ast.astext+"("+ast.lineNo +","+ast.columnNo +")";
5682//                        errorcount = 1;
5683                        this.syntaxErrors.add( new TSyntaxError(ast.astext,ast.lineNo,(ast.columnNo < 0 ? 0:ast.columnNo)
5684                                ,"Error when tokenlize", EErrorType.spwarning,TBaseType.MSG_WARNING_ERROR_WHEN_TOKENIZE,null,ast.posinlist));
5685
5686                        ast.tokentype = ETokenType.tttokenlizererrortoken;
5687                        gst = EFindSqlStateType.sterror;
5688
5689                        gcurrentsqlstatement = new TUnknownSqlStatement(dbVendor);
5690                        gcurrentsqlstatement.sqlstatementtype = ESqlStatementType.sstinvalid;
5691                        gcurrentsqlstatement.addtokentolist(ast);
5692
5693                    }
5694                    break;
5695                }
5696                case stBigQueryIf:{
5697                    gcurrentsqlstatement.addtokentolist(ast);
5698
5699                    if  (checkTokenPairWithEnd(ast.tokencode))
5700                    { // if... end if
5701                        if (ast.searchToken(TBaseType.rrw_end,-1) == null){
5702                            //this is not if after END
5703                            waitingEnd++;
5704                        }
5705                    }
5706                    else if   (ast.tokencode == TBaseType.rrw_end)
5707                    { // if ... end if
5708                        TSourceToken next = ast.nextSolidToken();
5709                        if (next != null){
5710                            if (checkTokenPairWithEnd(next.tokencode)){ // if ... end if;
5711                                waitingEnd--;
5712                            }else if (next.tokencode == ';'){ // begin ... end ;
5713                                waitingEnd--;
5714                            }
5715
5716                        }
5717                    }
5718                    else if   (
5719                            (ast.tokencode == ';')&&(waitingEnd == 0)
5720                    ){
5721                        gst = EFindSqlStateType.stnormal;
5722
5723                        doongetrawsqlstatementevent(gcurrentsqlstatement);
5724                    }
5725                    break;
5726                }
5727                case stsqlplus:{
5728                    if (ast.tokencode  == TBaseType.lexnewline){
5729                        gst = EFindSqlStateType.stnormal;
5730                        gcurrentsqlstatement.addtokentolist(ast); // so add it here
5731                        doongetrawsqlstatementevent(gcurrentsqlstatement);
5732                    }else {
5733                        {gcurrentsqlstatement.addtokentolist(ast);}
5734                    }
5735
5736                    break;
5737                }//case source command or \. command
5738                case stsql :
5739                {
5740                    if ((ast.tokentype == ETokenType.ttsemicolon)&&(gcurrentsqlstatement.sqlstatementtype != ESqlStatementType.sstmysqldelimiter))
5741                    {
5742                        gst = EFindSqlStateType.stnormal;
5743                        gcurrentsqlstatement.addtokentolist(ast);
5744                        gcurrentsqlstatement.semicolonended = ast;
5745                        doongetrawsqlstatementevent(gcurrentsqlstatement);
5746                        continue;
5747                    }
5748                    if (ast.toString().equalsIgnoreCase(userDelimiterStr))
5749                    {
5750                        gst = EFindSqlStateType.stnormal;
5751                        ast.tokencode = ';';// treat it as semicolon
5752                        gcurrentsqlstatement.addtokentolist(ast);
5753                        gcurrentsqlstatement.semicolonended = ast;
5754                        doongetrawsqlstatementevent(gcurrentsqlstatement);
5755                        continue;
5756                    }
5757                    gcurrentsqlstatement.addtokentolist(ast);
5758
5759                    if ((ast.tokencode  == TBaseType.lexnewline)
5760                            &&(gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmysqldelimiter)){
5761                        gst = EFindSqlStateType.stnormal;
5762                        userDelimiterStr = "";
5763                        for(int k=0;k<gcurrentsqlstatement.sourcetokenlist.size();k++){
5764                            TSourceToken st = gcurrentsqlstatement.sourcetokenlist.get(k);
5765                            if ((st.tokencode == TBaseType.rrw_mysql_delimiter)
5766                                    ||(st.tokencode == TBaseType.lexnewline)
5767                                    ||(st.tokencode == TBaseType.lexspace))
5768                            {
5769                                continue;
5770                            }
5771
5772                            userDelimiterStr += st.toString();
5773                            // System.out.println("userDelimiterStr:"+userDelimiterStr);
5774                            // System.out.print(gcurrentsqlstatement.sourcetokenlist.get(k).toString());
5775                        }
5776                        doongetrawsqlstatementevent(gcurrentsqlstatement);
5777
5778                        continue;
5779                    }
5780
5781                    break;
5782                }
5783                case ststoredprocedure :
5784                {
5785                    if (procedure_status[nestedProcedures] != stored_procedure_status.bodyend){
5786                        gcurrentsqlstatement.addtokentolist(ast);
5787                    }
5788
5789                    switch (procedure_status[nestedProcedures]){
5790                        case start:
5791                            if ((ast.tokencode == TBaseType.rrw_as)||(ast.tokencode == TBaseType.rrw_is)){
5792                                // s1
5793                                if (sptype[nestedProcedures] != stored_procedure_type.create_trigger){
5794                                    if ((sptype[0] == stored_procedure_type.package_spec) && (nestedProcedures > 0)){
5795                                        //when it's a package specification, only top level accept as/is
5796                                    }else{
5797                                        procedure_status[nestedProcedures] = stored_procedure_status.is_as;
5798                                        if (ast.searchToken("language",1) != null){
5799                                            // if as language is used in create function, then switch state to stored_procedure_status.body directly.
5800//                                        CREATE OR REPLACE FUNCTION THING.addressparse(p_addressline1 VARCHAR2) RETURN VARCHAR2 AUTHID DEFINER
5801//                                        as Language JAVA NAME 'AddressParser.parse(java.lang.String) return java.lang.String';
5802//                                        /
5803                                            if (nestedProcedures == 0){
5804                                                //  procedure_status[nestedProcedures] = stored_procedure_status.bodyend;
5805                                                gst = EFindSqlStateType.stsql;
5806                                            }else{
5807                                                procedure_status[nestedProcedures] = stored_procedure_status.body;
5808                                                nestedProcedures--;
5809                                                //if (nestedProcedures > 0){ nestedProcedures--;}
5810                                            }
5811
5812                                        }
5813                                    }
5814                                }
5815                            }else if(ast.tokencode == TBaseType.rrw_begin){
5816                                // s4
5817                                if (sptype[nestedProcedures] == stored_procedure_type.create_trigger) waitingEnds[nestedProcedures]++;
5818
5819                                if (nestedProcedures > 0) {nestedProcedures--;}
5820                                procedure_status[nestedProcedures] = stored_procedure_status.body;
5821                                waitingEnds[nestedProcedures] = 1;
5822                            }else if(ast.tokencode == TBaseType.rrw_end){
5823                                //s10
5824                                if((nestedProcedures > 0)&&(waitingEnds[nestedProcedures - 1] == 1)
5825                                        &&((sptype[nestedProcedures - 1] == stored_procedure_type.package_body)
5826                                        ||(sptype[nestedProcedures - 1] == stored_procedure_type.package_spec))){
5827                                    nestedProcedures--;
5828                                    procedure_status[nestedProcedures] = stored_procedure_status.bodyend;
5829                                }
5830                            }else if((ast.tokencode == TBaseType.rrw_procedure)||(ast.tokencode == TBaseType.rrw_function)){
5831                                //s3
5832                                if((nestedProcedures > 0)&&(waitingEnds[nestedProcedures] == 0)
5833                                        &&(procedure_status[nestedProcedures - 1] == stored_procedure_status.is_as)){
5834                                    nestedProcedures--;
5835                                    nestedProcedures++;
5836                                    waitingEnds[nestedProcedures] = 0;
5837                                    procedure_status[nestedProcedures] = stored_procedure_status.start;
5838                                }
5839                            }else if ((sptype[nestedProcedures] == stored_procedure_type.create_trigger) && (ast.tokencode == TBaseType.rrw_declare) )
5840                            {
5841                                procedure_status[nestedProcedures] = stored_procedure_status.is_as;
5842                            }else if ((sptype[nestedProcedures] == stored_procedure_type.create_trigger)&&(ast.tokentype == ETokenType.ttslash)  && (ast.tokencode == TBaseType.sqlpluscmd) )
5843                            {
5844                                // TPlsqlStatementParse(asqlstatement).TerminatorToken := ast;
5845                                ast.tokenstatus = ETokenStatus.tsignorebyyacc;
5846                                gst = EFindSqlStateType.stnormal;
5847                                doongetrawsqlstatementevent(gcurrentsqlstatement);
5848
5849                                //make / a sqlplus cmd
5850                                gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
5851                                gcurrentsqlstatement.addtokentolist(ast);
5852                                doongetrawsqlstatementevent(gcurrentsqlstatement);
5853                            }else if ((sptype[nestedProcedures] == stored_procedure_type.create_trigger) )
5854                            {
5855                                if (ast.tokencode == TBaseType.rrw_trigger){
5856                                    TSourceToken compoundSt =  ast.searchToken(TBaseType.rrw_oracle_compound, -1);
5857                                    if (compoundSt != null){
5858                                        //it's trigger with compound trigger block
5859                                        procedure_status[nestedProcedures] = stored_procedure_status.body;
5860                                        waitingEnds[nestedProcedures]++;
5861                                    }
5862                                }
5863                            }else if ((sptype[nestedProcedures] == stored_procedure_type.function)&&(ast.tokencode == TBaseType.rrw_teradata_using) )
5864                            {
5865                                if ((ast.searchToken("aggregate",-1) != null)||(ast.searchToken("pipelined",-1) != null)){
5866                                    if (nestedProcedures == 0){
5867                                        //  procedure_status[nestedProcedures] = stored_procedure_status.bodyend;
5868                                        gst = EFindSqlStateType.stsql;
5869                                    }else{
5870                                        procedure_status[nestedProcedures] = stored_procedure_status.body;
5871                                        nestedProcedures--;
5872                                    }
5873                                }
5874
5875                            }else{
5876                                //other tokens, do nothing
5877                            }
5878                            break;
5879                        case is_as:
5880                            if((ast.tokencode == TBaseType.rrw_procedure)||(ast.tokencode == TBaseType.rrw_function)){
5881                                // s2
5882                                nestedProcedures++;
5883                                waitingEnds[nestedProcedures] = 0;
5884                                procedure_status[nestedProcedures] = stored_procedure_status.start;
5885
5886                                if (nestedProcedures > stored_procedure_nested_level - 1){
5887                                    gst = EFindSqlStateType.sterror;
5888                                    nestedProcedures--;
5889                                }
5890
5891                            }else if(ast.tokencode == TBaseType.rrw_begin){
5892                                // s5
5893                                if ((nestedProcedures == 0)&&
5894                                        ((sptype[nestedProcedures]==stored_procedure_type.package_body)
5895                                                ||(sptype[nestedProcedures]==stored_procedure_type.package_spec))){
5896                                    //top level package or package body's BEGIN keyword already count,
5897                                    // so don't increase waitingEnds[nestedProcedures] here
5898
5899                                }else {
5900                                    waitingEnds[nestedProcedures]++;
5901                                }
5902                                procedure_status[nestedProcedures] = stored_procedure_status.body;
5903                            }else if(ast.tokencode == TBaseType.rrw_end){
5904                                // s6
5905                                if ((nestedProcedures == 0)&&(waitingEnds[nestedProcedures] == 1)&&
5906                                        ((sptype[nestedProcedures]==stored_procedure_type.package_body)||(sptype[nestedProcedures]==stored_procedure_type.package_spec))){
5907                                    procedure_status[nestedProcedures] = stored_procedure_status.bodyend;
5908                                    waitingEnds[nestedProcedures]--;
5909                                }else{
5910                                    waitingEnds[nestedProcedures]--;
5911                                }
5912                            }else if(ast.tokencode == TBaseType.rrw_case)
5913                            {
5914                                if (ast.searchToken(';',1) == null){
5915                                    //this is not case before ;
5916                                    waitingEnds[nestedProcedures]++;
5917                                }
5918                            }
5919                            else {
5920                                //other tokens, do nothing
5921                            }
5922                            break;
5923                        case body:
5924                            if ((ast.tokencode == TBaseType.rrw_begin))
5925                            {
5926                                waitingEnds[nestedProcedures]++;
5927                            } else if (ast.tokencode == TBaseType.rrw_if)
5928                            {
5929
5930                                if (ast.searchToken(';',2) == null){
5931                                    //this is not if before ;
5932
5933                                    // 2015-02-27, change 1 to 2 make it able to detect label name after case
5934                                    // like this: END CASE l1;
5935                                    waitingEnds[nestedProcedures]++;
5936                                }
5937                            } else if(ast.tokencode == TBaseType.rrw_case)
5938                            {
5939//                            if (ast.searchToken(TBaseType.rrw_end,-1) == null){
5940//                                //this is not case after END
5941//                             waitingEnds[nestedProcedures]++;
5942//                            }
5943                                if (ast.searchToken(';',2) == null){
5944                                    //this is not case before ;
5945                                    if (ast.searchToken(TBaseType.rrw_end,-1) == null){
5946                                        waitingEnds[nestedProcedures]++;
5947                                    }
5948                                }
5949                            } else if((ast.tokencode == TBaseType.rrw_loop)
5950                                        ||(ast.tokencode == TBaseType.rrw_while)||(ast.tokencode == TBaseType.rrw_repeat)
5951                                    ||(ast.tokencode == TBaseType.rrw_for)
5952                            )
5953                            {
5954                                if (!((ast.searchToken(TBaseType.rrw_end,-1) != null)
5955                                        &&(ast.searchToken(';',2) != null))){
5956                                    // exclude loop like this:
5957                                    // end loop [labelname];
5958                                    waitingEnds[nestedProcedures]++;
5959                                }
5960
5961                            }else if (ast.tokencode == TBaseType.rrw_end){
5962                                //foundEnd = true;
5963                                waitingEnds[nestedProcedures]--;
5964                                //if (waitingEnd < 0) { waitingEnd = 0;}
5965                                if (waitingEnds[nestedProcedures] == 0){
5966                                    if (nestedProcedures == 0){
5967                                        // s7
5968                                        procedure_status[nestedProcedures] = stored_procedure_status.bodyend;
5969                                    }else {
5970                                        // s71
5971                                        nestedProcedures--;
5972                                        procedure_status[nestedProcedures] = stored_procedure_status.is_as;
5973                                    }
5974                                }
5975                            }else  if ((waitingEnds[nestedProcedures] == 0)&&(ast.tokentype == ETokenType.ttslash)  && (ast.tokencode == TBaseType.sqlpluscmd) ) //and (prevst.NewlineIsLastTokenInTailerToken)) then
5976                            {
5977                                //sql ref: c:\prg\gsqlparser\Test\TestCases\oracle\createtrigger.sql, line 53
5978                                ast.tokenstatus = ETokenStatus.tsignorebyyacc;
5979                                gst = EFindSqlStateType.stnormal;
5980                                doongetrawsqlstatementevent(gcurrentsqlstatement);
5981
5982                                //make / a sqlplus cmd
5983                                gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
5984                                gcurrentsqlstatement.addtokentolist(ast);
5985                                doongetrawsqlstatementevent(gcurrentsqlstatement);
5986                            }
5987                            break;
5988                        case bodyend:
5989                            if ((ast.tokentype == ETokenType.ttslash)  && (ast.tokencode == TBaseType.sqlpluscmd) ) //and (prevst.NewlineIsLastTokenInTailerToken)) then
5990                            {
5991                                // TPlsqlStatementParse(asqlstatement).TerminatorToken := ast;
5992                                ast.tokenstatus = ETokenStatus.tsignorebyyacc;
5993                                gst = EFindSqlStateType.stnormal;
5994                                doongetrawsqlstatementevent(gcurrentsqlstatement);
5995
5996                                //make / a sqlplus cmd
5997                                gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
5998                                gcurrentsqlstatement.addtokentolist(ast);
5999                                doongetrawsqlstatementevent(gcurrentsqlstatement);
6000                            } else  if ((ast.tokencode == ';') )
6001                            {    // single dot at a seperate line
6002                              //  ast.tokenstatus = ETokenStatus.tsignorebyyacc;
6003                                gst = EFindSqlStateType.stnormal;
6004                                doongetrawsqlstatementevent(gcurrentsqlstatement);
6005
6006                            } else  if ((ast.searchToken(TBaseType.rrw_package,1) != null)&&(!endBySlashOnly))
6007                            {
6008                                gcurrentsqlstatement.addtokentolist(ast);
6009                                gst = EFindSqlStateType.stnormal;
6010                                doongetrawsqlstatementevent(gcurrentsqlstatement);
6011                            } else  if ((ast.searchToken(TBaseType.rrw_procedure,1) != null)&&(!endBySlashOnly))
6012                            {
6013                                gcurrentsqlstatement.addtokentolist(ast);
6014                                gst = EFindSqlStateType.stnormal;
6015                                doongetrawsqlstatementevent(gcurrentsqlstatement);
6016                            } else  if ((ast.searchToken(TBaseType.rrw_function,1) != null)&&(!endBySlashOnly))
6017                            {
6018                                gcurrentsqlstatement.addtokentolist(ast);
6019                                gst = EFindSqlStateType.stnormal;
6020                                doongetrawsqlstatementevent(gcurrentsqlstatement);
6021                            } else  if ((ast.searchToken(TBaseType.rrw_create,1) != null)&&(ast.searchToken(TBaseType.rrw_package,4) != null)&&(!endBySlashOnly))
6022                            {
6023                                gcurrentsqlstatement.addtokentolist(ast);
6024                                gst = EFindSqlStateType.stnormal;
6025                                doongetrawsqlstatementevent(gcurrentsqlstatement);
6026                            } else  if ((ast.searchToken(TBaseType.rrw_create,1) != null)&&(ast.searchToken(TBaseType.rrw_library,4) != null)&&(!endBySlashOnly))
6027                            {
6028                                gcurrentsqlstatement.addtokentolist(ast);
6029                                gst = EFindSqlStateType.stnormal;
6030                                doongetrawsqlstatementevent(gcurrentsqlstatement);
6031                            } else  if ((ast.searchToken(TBaseType.rrw_alter,1) != null)&&(ast.searchToken(TBaseType.rrw_trigger,2) != null)&&(!endBySlashOnly))
6032                            {
6033                                gcurrentsqlstatement.addtokentolist(ast);
6034                                gst = EFindSqlStateType.stnormal;
6035                                doongetrawsqlstatementevent(gcurrentsqlstatement);
6036                            } else  if ((ast.searchToken(TBaseType.rrw_select,1) != null)&&(!endBySlashOnly))
6037                            {
6038                                gcurrentsqlstatement.addtokentolist(ast);
6039                                gst = EFindSqlStateType.stnormal;
6040                                doongetrawsqlstatementevent(gcurrentsqlstatement);
6041                            } else  if ((ast.searchToken(TBaseType.rrw_commit,1) != null)&&(!endBySlashOnly))
6042                            {
6043                                gcurrentsqlstatement.addtokentolist(ast);
6044                                gst = EFindSqlStateType.stnormal;
6045                                doongetrawsqlstatementevent(gcurrentsqlstatement);
6046                            } else  if ((ast.searchToken(TBaseType.rrw_grant,1) != null)&&
6047                                    (ast.searchToken(TBaseType.rrw_execute,2) != null)&&(!endBySlashOnly))
6048                            {
6049                                gcurrentsqlstatement.addtokentolist(ast);
6050                                gst = EFindSqlStateType.stnormal;
6051                                doongetrawsqlstatementevent(gcurrentsqlstatement);
6052                            }else {
6053                                gcurrentsqlstatement.addtokentolist(ast);
6054                            }
6055                            break;
6056                        case end:
6057                            break;
6058                        default:
6059                            break;
6060                    }
6061
6062
6063                    if (ast.tokencode == TBaseType.sqlpluscmd)
6064                    {
6065                        //change tokencode back to keyword or TBaseType.ident, because sqlplus cmd
6066                        //in a sql statement(almost is plsql block) is not really a sqlplus cmd
6067                        int m = flexer.getkeywordvalue(ast.astext);
6068                        if (m != 0)
6069                        {ast.tokencode = m;}
6070                        else if (ast.tokentype == ETokenType.ttslash){
6071                            ast.tokencode = '/';
6072                        }
6073                        else
6074                        {ast.tokencode = TBaseType.ident;}
6075                    }
6076
6077                    final int wrapped_keyword_max_pos = 20;
6078                    if ((ast.tokencode == TBaseType.rrw_wrapped)&&(ast.posinlist - gcurrentsqlstatement.sourcetokenlist.get(0).posinlist  < wrapped_keyword_max_pos)){
6079                        if (gcurrentsqlstatement instanceof TCommonStoredProcedureSqlStatement){
6080                            ((TCommonStoredProcedureSqlStatement)gcurrentsqlstatement).setWrapped(true);
6081                        }
6082
6083                        if (gcurrentsqlstatement instanceof TPlsqlCreatePackage){
6084                            if (ast.prevSolidToken() != null){
6085                                ((TPlsqlCreatePackage) gcurrentsqlstatement).setPackageName(fparser.getNf().createObjectNameWithPart(ast.prevSolidToken()));
6086                            }
6087                        }
6088                    }
6089
6090                    break;
6091                } //ststoredprocedure
6092
6093            } //case
6094        } //for
6095
6096
6097        //last statement
6098        if (TBaseType.assigned(gcurrentsqlstatement) &&
6099                ( (gst == EFindSqlStateType.stsql) || (gst == EFindSqlStateType.ststoredprocedure)
6100                    || (gst == EFindSqlStateType.stBigQueryIf)|| (gst == EFindSqlStateType.sterror)
6101                )
6102        )
6103        {
6104            doongetrawsqlstatementevent(gcurrentsqlstatement);
6105        }
6106
6107        return errorcount;
6108    }
6109
6110
6111    int docouchbasegetrawsqlstatements(){
6112        int waitingEnd = 0;
6113        boolean foundEnd = false;
6114
6115        if ( TBaseType.assigned(sqlstatements) ) sqlstatements.clear();
6116        if ( ! TBaseType.assigned(sourcetokenlist) ) return -1;
6117
6118        gcurrentsqlstatement = null;
6119        EFindSqlStateType gst = EFindSqlStateType.stnormal;
6120        TSourceToken lcprevsolidtoken = null,ast = null;
6121
6122        for (int i=0 ; i < sourcetokenlist.size();i++)
6123        {
6124
6125            if ( (ast != null ) && (ast.issolidtoken() ))
6126                lcprevsolidtoken = ast;
6127
6128            ast = sourcetokenlist.get(i);
6129            sourcetokenlist.curpos = i;
6130
6131//            if (ast.tokencode == ':'){
6132//                TSourceToken st1 = ast.searchToken(TBaseType.ident,-1);
6133//                if (st1 != null){
6134//                    st1.tokencode = TBaseType.IDENT_BEFORE_COLON;
6135//                }
6136//            }
6137
6138            switch(gst){
6139                case sterror:{
6140                    if (ast.tokentype ==  ETokenType.ttsemicolon)
6141                    {
6142                        gcurrentsqlstatement.sourcetokenlist.add(ast);
6143                        doongetrawsqlstatementevent(gcurrentsqlstatement);
6144                        gst = EFindSqlStateType.stnormal;
6145                    }
6146                    else
6147                    {
6148                        gcurrentsqlstatement.sourcetokenlist.add(ast);
6149                    }
6150                    break;
6151                } //sterror
6152
6153                case stnormal:{
6154                    if ((ast.tokencode  == TBaseType.cmtdoublehyphen)
6155                            || (ast.tokencode  == TBaseType.cmtslashstar)
6156                            || (ast.tokencode  == TBaseType.lexspace)
6157                            || (ast.tokencode  == TBaseType.lexnewline)
6158                            || (ast.tokentype  == ETokenType.ttsemicolon) )
6159                    {
6160                        if (gcurrentsqlstatement != null)
6161                        {
6162                            gcurrentsqlstatement.addtokentolist(ast);
6163                        }
6164
6165                        if ((lcprevsolidtoken != null) && (ast.tokentype == ETokenType.ttsemicolon))
6166                        {
6167                            if (lcprevsolidtoken.tokentype == ETokenType.ttsemicolon )
6168                            {
6169                                // ;;;; continuous semicolon,treat it as comment
6170                                ast.tokentype = ETokenType.ttsimplecomment;
6171                                ast.tokencode =  TBaseType.cmtdoublehyphen;
6172                            }
6173                        }
6174
6175                        continue;
6176                    }
6177
6178                    if (ast.tokencode == TBaseType.sqlpluscmd )
6179                    {
6180                        gst = EFindSqlStateType.stsqlplus;
6181                        gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
6182                        gcurrentsqlstatement.addtokentolist(ast);
6183                        continue;
6184                    }
6185
6186                    // find a token text to start sql or plsql mode
6187                    gcurrentsqlstatement = sqlcmds.issql(ast, dbVendor,gst,gcurrentsqlstatement);
6188
6189                    if (gcurrentsqlstatement != null)
6190                    {
6191
6192                            gst = EFindSqlStateType.stsql;
6193                            gcurrentsqlstatement.addtokentolist(ast);
6194                    }else{
6195                        //error tokentext found
6196
6197                        this.syntaxErrors.add( new TSyntaxError(ast.astext,ast.lineNo,(ast.columnNo < 0 ? 0:ast.columnNo)
6198                                ,"Error when tokenlize", EErrorType.spwarning,TBaseType.MSG_WARNING_ERROR_WHEN_TOKENIZE,null,ast.posinlist));
6199
6200                        ast.tokentype = ETokenType.tttokenlizererrortoken;
6201                        gst = EFindSqlStateType.sterror;
6202
6203                        gcurrentsqlstatement = new TUnknownSqlStatement(dbVendor);
6204                        gcurrentsqlstatement.sqlstatementtype = ESqlStatementType.sstinvalid;
6205                        gcurrentsqlstatement.addtokentolist(ast);
6206
6207                    }
6208
6209                    break;
6210                } // stnormal
6211
6212                case stsqlplus:{
6213                    if  (ast.insqlpluscmd)
6214                    {gcurrentsqlstatement.addtokentolist(ast);}
6215                    else
6216                    {
6217                        gst = EFindSqlStateType.stnormal; //this tokentext must be newline,
6218                        gcurrentsqlstatement.addtokentolist(ast); // so add it here
6219                        doongetrawsqlstatementevent(gcurrentsqlstatement);
6220                    }
6221
6222                    break;
6223                }//case stsqlplus
6224
6225                case stsql:{
6226                    if (ast.tokentype == ETokenType.ttsemicolon)
6227                    {
6228                        gst = EFindSqlStateType.stnormal;
6229                        gcurrentsqlstatement.addtokentolist(ast);
6230                        gcurrentsqlstatement.semicolonended = ast;
6231                        doongetrawsqlstatementevent(gcurrentsqlstatement);
6232                        continue;
6233                    }
6234
6235                    if  (sourcetokenlist.sqlplusaftercurtoken() ) //most probaly is / cmd
6236                    {
6237                        gst = EFindSqlStateType.stnormal;
6238                        gcurrentsqlstatement.addtokentolist(ast);
6239                        doongetrawsqlstatementevent(gcurrentsqlstatement);
6240                        continue;
6241                    }
6242                    gcurrentsqlstatement.addtokentolist(ast);
6243                    break;
6244                }//case stsql
6245
6246                case ststoredprocedure:{
6247                    if   ((ast.tokencode == TBaseType.rrw_begin)
6248                        //||(ast.tokencode == TBaseType.rrw_between)
6249                            )
6250                    {
6251                        waitingEnd++;
6252                        foundEnd = false;
6253                    }
6254                    else if   (
6255                            (ast.tokencode == TBaseType.rrw_if)
6256                            ){
6257                        if (ast.searchToken(TBaseType.rrw_end,-1) == null){
6258                            //this is not if after END
6259                            waitingEnd++;
6260                        }
6261                    }
6262                    else if   (
6263                            (ast.tokencode == TBaseType.rrw_case)
6264                            ){
6265                        if (ast.searchToken(TBaseType.rrw_end,-1) == null){
6266                            //this is not case after END
6267                            waitingEnd++;
6268                        }
6269                    }
6270                    else if   (
6271                            (ast.tokencode == TBaseType.rrw_loop)
6272                            ){
6273                        if (ast.searchToken(TBaseType.rrw_end,-1) == null){
6274                            //this is not loop after END
6275                            waitingEnd++;
6276                        }
6277                    }
6278                    else if (ast.tokencode == TBaseType.rrw_end){
6279                        foundEnd = true;
6280                        waitingEnd--;
6281                        if (waitingEnd < 0) { waitingEnd = 0;}
6282                    }
6283
6284                    if ((ast.tokentype == ETokenType.ttslash)  && (ast.tokencode == TBaseType.sqlpluscmd) ) //and (prevst.NewlineIsLastTokenInTailerToken)) then
6285                    {
6286                        // TPlsqlStatementParse(asqlstatement).TerminatorToken := ast;
6287                        ast.tokenstatus = ETokenStatus.tsignorebyyacc;
6288                        gst = EFindSqlStateType.stnormal;
6289                        doongetrawsqlstatementevent(gcurrentsqlstatement);
6290
6291                        //make / a sqlplus cmd
6292                        gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
6293                        gcurrentsqlstatement.addtokentolist(ast);
6294                        doongetrawsqlstatementevent(gcurrentsqlstatement);
6295                    }
6296                    else  if ((ast.tokentype == ETokenType.ttperiod)  && (sourcetokenlist.returnaftercurtoken(false)) && (sourcetokenlist.returnbeforecurtoken(false)))
6297                    {    // single dot at a seperate line
6298                        ast.tokenstatus = ETokenStatus.tsignorebyyacc;
6299                        gst = EFindSqlStateType.stnormal;
6300                        doongetrawsqlstatementevent(gcurrentsqlstatement);
6301
6302                        //make ttperiod a sqlplus cmd
6303                        gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
6304                        gcurrentsqlstatement.addtokentolist(ast);
6305                        doongetrawsqlstatementevent(gcurrentsqlstatement);
6306                    }
6307                    else
6308                    {
6309                        gcurrentsqlstatement.addtokentolist(ast);
6310                        if ((ast.tokentype == ETokenType.ttsemicolon) && (waitingEnd == 0) && (foundEnd) && (gcurrentsqlstatement.VerticaStatementCanBeSeparatedByBeginEndPair())){
6311                            gst = EFindSqlStateType.stnormal;
6312                            doongetrawsqlstatementevent(gcurrentsqlstatement);
6313                        }
6314                    }
6315
6316                    if (ast.tokencode == TBaseType.sqlpluscmd)
6317                    {
6318                        //change tokencode back to keyword or TBaseType.ident, because sqlplus cmd
6319                        //in a sql statement(almost is plsql block) is not really a sqlplus cmd
6320                        int m = flexer.getkeywordvalue(ast.astext);
6321                        if (m != 0)
6322                        {ast.tokencode = m;}
6323                        else
6324                        {ast.tokencode = TBaseType.ident;}
6325                    }
6326
6327                    break;
6328                } //ststoredprocedure
6329            } //switch
6330        }//for
6331
6332        //last statement
6333        if ((gcurrentsqlstatement != null) &&
6334                ((gst == EFindSqlStateType.stsqlplus) ||  (gst == EFindSqlStateType.stsql) || (gst == EFindSqlStateType.ststoredprocedure) ||
6335                        (gst == EFindSqlStateType.sterror)))
6336        {
6337            doongetrawsqlstatementevent(gcurrentsqlstatement);
6338        }
6339
6340        return syntaxErrors.size();
6341    }
6342    int doathenagetrawsqlstatements(){
6343        int waitingEnd = 0;
6344        boolean foundEnd = false;
6345
6346        if ( TBaseType.assigned(sqlstatements) ) sqlstatements.clear();
6347        if ( ! TBaseType.assigned(sourcetokenlist) ) return -1;
6348
6349        gcurrentsqlstatement = null;
6350        EFindSqlStateType gst = EFindSqlStateType.stnormal;
6351        TSourceToken lcprevsolidtoken = null,ast = null;
6352
6353        for (int i=0 ; i < sourcetokenlist.size();i++)
6354        {
6355
6356            if ( (ast != null ) && (ast.issolidtoken() ))
6357                lcprevsolidtoken = ast;
6358
6359            ast = sourcetokenlist.get(i);
6360            sourcetokenlist.curpos = i;
6361
6362
6363            switch(gst){
6364                case sterror:{
6365                    if (ast.tokentype ==  ETokenType.ttsemicolon)
6366                    {
6367                        gcurrentsqlstatement.sourcetokenlist.add(ast);
6368                        doongetrawsqlstatementevent(gcurrentsqlstatement);
6369                        gst = EFindSqlStateType.stnormal;
6370                    }
6371                    else
6372                    {
6373                        gcurrentsqlstatement.sourcetokenlist.add(ast);
6374                    }
6375                    break;
6376                } //sterror
6377
6378                case stnormal:{
6379                    if ((ast.tokencode  == TBaseType.cmtdoublehyphen)
6380                            || (ast.tokencode  == TBaseType.cmtslashstar)
6381                            || (ast.tokencode  == TBaseType.lexspace)
6382                            || (ast.tokencode  == TBaseType.lexnewline)
6383                            || (ast.tokentype  == ETokenType.ttsemicolon) )
6384                    {
6385                        if (gcurrentsqlstatement != null)
6386                        {
6387                            gcurrentsqlstatement.addtokentolist(ast);
6388                        }
6389
6390                        if ((lcprevsolidtoken != null) && (ast.tokentype == ETokenType.ttsemicolon))
6391                        {
6392                            if (lcprevsolidtoken.tokentype == ETokenType.ttsemicolon )
6393                            {
6394                                // ;;;; continuous semicolon,treat it as comment
6395                                ast.tokentype = ETokenType.ttsimplecomment;
6396                                ast.tokencode =  TBaseType.cmtdoublehyphen;
6397                            }
6398                        }
6399
6400                        continue;
6401                    }
6402
6403
6404                    // find a tokentext to start sql or plsql mode
6405                    gcurrentsqlstatement = sqlcmds.issql(ast, dbVendor,gst,gcurrentsqlstatement);
6406
6407                    if (gcurrentsqlstatement != null)
6408                    {
6409                        if (gcurrentsqlstatement.isathenaplsql())
6410                        {
6411                            gst = EFindSqlStateType.ststoredprocedure;
6412                            gcurrentsqlstatement.addtokentolist(ast);
6413                            foundEnd = false;
6414                            if   ((ast.tokencode == TBaseType.rrw_begin)
6415                                    ||(ast.tokencode == TBaseType.rrw_package)
6416                                    || (ast.searchToken(TBaseType.rrw_package,4) != null)
6417                            )
6418                            { waitingEnd = 1;}
6419                        }
6420                        else
6421                        {
6422                            gst = EFindSqlStateType.stsql;
6423                            gcurrentsqlstatement.addtokentolist(ast);
6424                        }
6425                    }else{
6426                        //error tokentext found
6427
6428                        this.syntaxErrors.add( new TSyntaxError(ast.astext,ast.lineNo,(ast.columnNo < 0 ? 0:ast.columnNo)
6429                                ,"Error when tokenlize", EErrorType.spwarning,TBaseType.MSG_WARNING_ERROR_WHEN_TOKENIZE,null,ast.posinlist));
6430
6431                        ast.tokentype = ETokenType.tttokenlizererrortoken;
6432                        gst = EFindSqlStateType.sterror;
6433
6434                        gcurrentsqlstatement = new TUnknownSqlStatement(dbVendor);
6435                        gcurrentsqlstatement.sqlstatementtype = ESqlStatementType.sstinvalid;
6436                        gcurrentsqlstatement.addtokentolist(ast);
6437
6438                    }
6439
6440                    break;
6441                } // stnormal
6442
6443                case stsql:{
6444                    if (ast.tokentype == ETokenType.ttsemicolon)
6445                    {
6446                        gst = EFindSqlStateType.stnormal;
6447                        gcurrentsqlstatement.addtokentolist(ast);
6448                        gcurrentsqlstatement.semicolonended = ast;
6449                        doongetrawsqlstatementevent(gcurrentsqlstatement);
6450                        continue;
6451                    }
6452
6453                    if  (sourcetokenlist.sqlplusaftercurtoken() ) //most probaly is / cmd
6454                    {
6455                        gst = EFindSqlStateType.stnormal;
6456                        gcurrentsqlstatement.addtokentolist(ast);
6457                        doongetrawsqlstatementevent(gcurrentsqlstatement);
6458                        continue;
6459                    }
6460                    gcurrentsqlstatement.addtokentolist(ast);
6461                    break;
6462                }//case stsql
6463
6464                case ststoredprocedure:{
6465                    if   ((ast.tokencode == TBaseType.rrw_begin)
6466                        //||(ast.tokencode == TBaseType.rrw_between)
6467                    )
6468                    {
6469                        waitingEnd++;
6470                    }
6471                    else if   (
6472                            (ast.tokencode == TBaseType.rrw_if)
6473                    ){
6474                        if (ast.searchToken(TBaseType.rrw_end,-1) == null){
6475                            //this is not if after END
6476                            waitingEnd++;
6477                        }
6478                    }
6479                    else if   (
6480                            (ast.tokencode == TBaseType.rrw_case)
6481                    ){
6482                        if (ast.searchToken(TBaseType.rrw_end,-1) == null){
6483                            //this is not case after END
6484                            waitingEnd++;
6485                        }
6486                    }
6487                    else if   (
6488                            (ast.tokencode == TBaseType.rrw_loop)
6489                    ){
6490                        if (ast.searchToken(TBaseType.rrw_end,-1) == null){
6491                            //this is not loop after END
6492                            waitingEnd++;
6493                        }
6494                    }
6495                    else if (ast.tokencode == TBaseType.rrw_end){
6496                        foundEnd = true;
6497                        waitingEnd--;
6498                        if (waitingEnd < 0) { waitingEnd = 0;}
6499                    }
6500
6501                    if ((ast.tokentype == ETokenType.ttslash)  && (ast.tokencode == TBaseType.sqlpluscmd) ) //and (prevst.NewlineIsLastTokenInTailerToken)) then
6502                    {
6503                        // TPlsqlStatementParse(asqlstatement).TerminatorToken := ast;
6504                        ast.tokenstatus = ETokenStatus.tsignorebyyacc;
6505                        gst = EFindSqlStateType.stnormal;
6506                        doongetrawsqlstatementevent(gcurrentsqlstatement);
6507
6508                        //make / a sqlplus cmd
6509                        gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
6510                        gcurrentsqlstatement.addtokentolist(ast);
6511                        doongetrawsqlstatementevent(gcurrentsqlstatement);
6512                    }
6513                    else  if ((ast.tokentype == ETokenType.ttperiod)  && (sourcetokenlist.returnaftercurtoken(false)) && (sourcetokenlist.returnbeforecurtoken(false)))
6514                    {    // single dot at a seperate line
6515                        ast.tokenstatus = ETokenStatus.tsignorebyyacc;
6516                        gst = EFindSqlStateType.stnormal;
6517                        doongetrawsqlstatementevent(gcurrentsqlstatement);
6518
6519                        //make ttperiod a sqlplus cmd
6520                        gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
6521                        gcurrentsqlstatement.addtokentolist(ast);
6522                        doongetrawsqlstatementevent(gcurrentsqlstatement);
6523                    }
6524                    else
6525                    {
6526                        gcurrentsqlstatement.addtokentolist(ast);
6527                        if ((ast.tokentype == ETokenType.ttsemicolon) && (waitingEnd == 0)
6528                                && (foundEnd)
6529                            //        && (gcurrentsqlstatement.OracleStatementCanBeSeparatedByBeginEndPair())
6530                        ){
6531                            gst = EFindSqlStateType.stnormal;
6532                            doongetrawsqlstatementevent(gcurrentsqlstatement);
6533                        }
6534                    }
6535
6536                    if (ast.tokencode == TBaseType.sqlpluscmd)
6537                    {
6538                        //change tokencode back to keyword or TBaseType.ident, because sqlplus cmd
6539                        //in a sql statement(almost is plsql block) is not really a sqlplus cmd
6540                        int m = flexer.getkeywordvalue(ast.astext);
6541                        if (m != 0)
6542                        {ast.tokencode = m;}
6543                        else
6544                        {ast.tokencode = TBaseType.ident;}
6545                    }
6546
6547                    break;
6548                } //ststoredprocedure
6549            } //switch
6550        }//for
6551
6552        //last statement
6553        if ((gcurrentsqlstatement != null) &&
6554                ((gst == EFindSqlStateType.stsqlplus) ||  (gst == EFindSqlStateType.stsql) || (gst == EFindSqlStateType.ststoredprocedure) ||
6555                        (gst == EFindSqlStateType.sterror)))
6556        {
6557            doongetrawsqlstatementevent(gcurrentsqlstatement);
6558        }
6559
6560        return syntaxErrors.size();
6561    }
6562    int dodatabricksgetrawsqlstatements(){
6563        int waitingEnd = 0;
6564        boolean foundEnd = false;
6565        EDataType tmpDatatype = null;
6566
6567        if ( TBaseType.assigned(sqlstatements) ) sqlstatements.clear();
6568        if ( ! TBaseType.assigned(sourcetokenlist) ) return -1;
6569
6570        gcurrentsqlstatement = null;
6571        EFindSqlStateType gst = EFindSqlStateType.stnormal;
6572        TSourceToken lcprevsolidtoken = null,ast = null;
6573
6574        for (int i=0 ; i < sourcetokenlist.size();i++)
6575        {
6576
6577            if ( (ast != null ) && (ast.issolidtoken() ))
6578                lcprevsolidtoken = ast;
6579
6580            ast = sourcetokenlist.get(i);
6581            sourcetokenlist.curpos = i;
6582
6583            if (ast.tokencode == TBaseType.rrw_values) {
6584                TSourceToken stParen =  ast.searchToken('(',1);
6585                if (stParen != null){
6586                    TSourceToken stInsert  = ast.searchToken(TBaseType.rrw_insert,-ast.posinlist,';',true);
6587                    if (stInsert != null){
6588                        TSourceToken stSemiColon  = ast.searchToken(';',-ast.posinlist);
6589                        if ((stSemiColon != null)&&(stSemiColon.posinlist > stInsert.posinlist)){
6590    //                            INSERT INTO test values (16,1), (8,2), (4,4), (2,0), (97, 16);
6591    //                            VALUES (1);
6592                            // don't treat values(1) as insert values
6593
6594                        }else{
6595                            TSourceToken stFrom  = ast.searchToken(TBaseType.rrw_from,-ast.posinlist,';',true);
6596                            if (stFrom != null){
6597                                // don't treat values after from keyword as an insert values
6598
6599                                // insert into inserttest values(10, 20, '40'), (-1, 2, DEFAULT),  ((select 2), (select i from (values(3) ) as foo (i)), 'values are fun!');
6600
6601                                // let check the INSERT keyword is close to VALUES than FROM keyword, if yes, treat it as insert values
6602
6603                                if (stInsert.posinlist > stFrom.posinlist){
6604                                    // https://www.sqlparser.com/bugs/mantisbt/view.php?id=3354
6605                                    ast.tokencode = TBaseType.rrw_databricks_values_insert;
6606                                }
6607
6608                            }else{
6609                                ast.tokencode = TBaseType.rrw_databricks_values_insert;
6610                            }
6611                        }
6612                    }
6613                }
6614           }else if ((ast.tokencode == TBaseType.sconst)||(ast.tokencode == '+')||(ast.tokencode == '-')){
6615                if (TTypeName.searchTypeByName(lcprevsolidtoken.toString()) != null){
6616                    // date '2021-2-1', turn date to TBaseType.rrw_databricks_datatype_used_to_cast
6617                    if (lcprevsolidtoken.tokencode != TBaseType.rrw_interval){
6618                        lcprevsolidtoken.tokencode = TBaseType.rrw_databricks_datatype_used_to_cast;
6619                    }
6620                }
6621            }
6622
6623
6624            switch(gst){
6625                case sterror:{
6626                    if (ast.tokentype ==  ETokenType.ttsemicolon)
6627                    {
6628                        gcurrentsqlstatement.sourcetokenlist.add(ast);
6629                        doongetrawsqlstatementevent(gcurrentsqlstatement);
6630                        gst = EFindSqlStateType.stnormal;
6631                    }
6632                    else
6633                    {
6634                        gcurrentsqlstatement.sourcetokenlist.add(ast);
6635                    }
6636                    break;
6637                } //sterror
6638
6639                case stnormal:{
6640                    if ((ast.tokencode  == TBaseType.cmtdoublehyphen)
6641                            || (ast.tokencode  == TBaseType.cmtslashstar)
6642                            || (ast.tokencode  == TBaseType.lexspace)
6643                            || (ast.tokencode  == TBaseType.lexnewline)
6644                            || (ast.tokentype  == ETokenType.ttsemicolon) )
6645                    {
6646                        if (gcurrentsqlstatement != null)
6647                        {
6648                            gcurrentsqlstatement.addtokentolist(ast);
6649                        }
6650
6651                        if ((lcprevsolidtoken != null) && (ast.tokentype == ETokenType.ttsemicolon))
6652                        {
6653                            if (lcprevsolidtoken.tokentype == ETokenType.ttsemicolon )
6654                            {
6655                                // ;;;; continuous semicolon,treat it as comment
6656                                ast.tokentype = ETokenType.ttsimplecomment;
6657                                ast.tokencode =  TBaseType.cmtdoublehyphen;
6658                            }
6659                        }
6660
6661                        continue;
6662                    }
6663
6664
6665                    // find a tokentext to start sql or plsql mode
6666                    gcurrentsqlstatement = sqlcmds.issql(ast, dbVendor,gst,gcurrentsqlstatement);
6667
6668                    if (gcurrentsqlstatement != null)
6669                    {
6670                        if (gcurrentsqlstatement.isdatabricksplsql())
6671                        {
6672                            gst = EFindSqlStateType.ststoredprocedure;
6673                            gcurrentsqlstatement.addtokentolist(ast);
6674                            foundEnd = false;
6675                            if   ((ast.tokencode == TBaseType.rrw_begin)
6676                                    ||(ast.tokencode == TBaseType.rrw_package)
6677                                    || (ast.searchToken(TBaseType.rrw_package,4) != null)
6678                            )
6679                            { waitingEnd = 1;}
6680                        }
6681                        else
6682                        {
6683                            gst = EFindSqlStateType.stsql;
6684                            gcurrentsqlstatement.addtokentolist(ast);
6685                        }
6686                    }else{
6687                        //error tokentext found
6688
6689                        this.syntaxErrors.add( new TSyntaxError(ast.astext,ast.lineNo,(ast.columnNo < 0 ? 0:ast.columnNo)
6690                                ,"Error when tokenlize", EErrorType.spwarning,TBaseType.MSG_WARNING_ERROR_WHEN_TOKENIZE,null,ast.posinlist));
6691
6692                        ast.tokentype = ETokenType.tttokenlizererrortoken;
6693                        gst = EFindSqlStateType.sterror;
6694
6695                        gcurrentsqlstatement = new TUnknownSqlStatement(dbVendor);
6696                        gcurrentsqlstatement.sqlstatementtype = ESqlStatementType.sstinvalid;
6697                        gcurrentsqlstatement.addtokentolist(ast);
6698
6699                    }
6700
6701                    break;
6702                } // stnormal
6703
6704                case stsql:{
6705                    if (ast.tokentype == ETokenType.ttsemicolon)
6706                    {
6707                        gst = EFindSqlStateType.stnormal;
6708                        gcurrentsqlstatement.addtokentolist(ast);
6709                        gcurrentsqlstatement.semicolonended = ast;
6710                        doongetrawsqlstatementevent(gcurrentsqlstatement);
6711                        continue;
6712                    }
6713
6714                    if  (sourcetokenlist.sqlplusaftercurtoken() ) //most probaly is / cmd
6715                    {
6716                        gst = EFindSqlStateType.stnormal;
6717                        gcurrentsqlstatement.addtokentolist(ast);
6718                        doongetrawsqlstatementevent(gcurrentsqlstatement);
6719                        continue;
6720                    }
6721                    gcurrentsqlstatement.addtokentolist(ast);
6722                    break;
6723                }//case stsql
6724
6725                case ststoredprocedure:{
6726                    if   ((ast.tokencode == TBaseType.rrw_begin)
6727                        //||(ast.tokencode == TBaseType.rrw_between)
6728                    )
6729                    {
6730                        waitingEnd++;
6731                    }
6732                    else if   (
6733                            (ast.tokencode == TBaseType.rrw_if)
6734                    ){
6735                        if (ast.searchToken(TBaseType.rrw_end,-1) == null){
6736                            //this is not if after END
6737                            waitingEnd++;
6738                        }
6739                    }
6740                    else if   (
6741                            (ast.tokencode == TBaseType.rrw_case)
6742                    ){
6743                        if (ast.searchToken(TBaseType.rrw_end,-1) == null){
6744                            //this is not case after END
6745                            waitingEnd++;
6746                        }
6747                    }
6748                    else if   (
6749                            (ast.tokencode == TBaseType.rrw_loop)
6750                    ){
6751                        if (ast.searchToken(TBaseType.rrw_end,-1) == null){
6752                            //this is not loop after END
6753                            waitingEnd++;
6754                        }
6755                    }
6756                    else if (ast.tokencode == TBaseType.rrw_end){
6757                        foundEnd = true;
6758                        waitingEnd--;
6759                        if (waitingEnd < 0) { waitingEnd = 0;}
6760                    }
6761
6762                    if ((ast.tokentype == ETokenType.ttslash)  && (ast.tokencode == TBaseType.sqlpluscmd) ) //and (prevst.NewlineIsLastTokenInTailerToken)) then
6763                    {
6764                        // TPlsqlStatementParse(asqlstatement).TerminatorToken := ast;
6765                        ast.tokenstatus = ETokenStatus.tsignorebyyacc;
6766                        gst = EFindSqlStateType.stnormal;
6767                        doongetrawsqlstatementevent(gcurrentsqlstatement);
6768
6769                        //make / a sqlplus cmd
6770                        gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
6771                        gcurrentsqlstatement.addtokentolist(ast);
6772                        doongetrawsqlstatementevent(gcurrentsqlstatement);
6773                    }
6774                    else  if ((ast.tokentype == ETokenType.ttperiod)  && (sourcetokenlist.returnaftercurtoken(false)) && (sourcetokenlist.returnbeforecurtoken(false)))
6775                    {    // single dot at a seperate line
6776                        ast.tokenstatus = ETokenStatus.tsignorebyyacc;
6777                        gst = EFindSqlStateType.stnormal;
6778                        doongetrawsqlstatementevent(gcurrentsqlstatement);
6779
6780                        //make ttperiod a sqlplus cmd
6781                        gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
6782                        gcurrentsqlstatement.addtokentolist(ast);
6783                        doongetrawsqlstatementevent(gcurrentsqlstatement);
6784                    }
6785                    else
6786                    {
6787                        gcurrentsqlstatement.addtokentolist(ast);
6788                        if ((ast.tokentype == ETokenType.ttsemicolon) && (waitingEnd == 0)
6789                                && (foundEnd)
6790                            //        && (gcurrentsqlstatement.OracleStatementCanBeSeparatedByBeginEndPair())
6791                        ){
6792                            gst = EFindSqlStateType.stnormal;
6793                            doongetrawsqlstatementevent(gcurrentsqlstatement);
6794                        }
6795                    }
6796
6797                    if (ast.tokencode == TBaseType.sqlpluscmd)
6798                    {
6799                        //change tokencode back to keyword or TBaseType.ident, because sqlplus cmd
6800                        //in a sql statement(almost is plsql block) is not really a sqlplus cmd
6801                        int m = flexer.getkeywordvalue(ast.astext);
6802                        if (m != 0)
6803                        {ast.tokencode = m;}
6804                        else
6805                        {ast.tokencode = TBaseType.ident;}
6806                    }
6807
6808                    break;
6809                } //ststoredprocedure
6810            } //switch
6811        }//for
6812
6813        //last statement
6814        if ((gcurrentsqlstatement != null) &&
6815                ((gst == EFindSqlStateType.stsqlplus) ||  (gst == EFindSqlStateType.stsql) || (gst == EFindSqlStateType.ststoredprocedure) ||
6816                        (gst == EFindSqlStateType.sterror)))
6817        {
6818            doongetrawsqlstatementevent(gcurrentsqlstatement);
6819        }
6820
6821        return syntaxErrors.size();
6822    }
6823    int doprestogetrawsqlstatements(){
6824        int waitingEnd = 0;
6825        boolean foundEnd = false;
6826
6827        if ( TBaseType.assigned(sqlstatements) ) sqlstatements.clear();
6828        if ( ! TBaseType.assigned(sourcetokenlist) ) return -1;
6829
6830        gcurrentsqlstatement = null;
6831        EFindSqlStateType gst = EFindSqlStateType.stnormal;
6832        TSourceToken lcprevsolidtoken = null,ast = null;
6833
6834        for (int i=0 ; i < sourcetokenlist.size();i++)
6835        {
6836
6837            if ( (ast != null ) && (ast.issolidtoken() ))
6838                lcprevsolidtoken = ast;
6839
6840            ast = sourcetokenlist.get(i);
6841            sourcetokenlist.curpos = i;
6842
6843
6844            switch(gst){
6845                case sterror:{
6846                    if (ast.tokentype ==  ETokenType.ttsemicolon)
6847                    {
6848                        gcurrentsqlstatement.sourcetokenlist.add(ast);
6849                        doongetrawsqlstatementevent(gcurrentsqlstatement);
6850                        gst = EFindSqlStateType.stnormal;
6851                    }
6852                    else
6853                    {
6854                        gcurrentsqlstatement.sourcetokenlist.add(ast);
6855                    }
6856                    break;
6857                } //sterror
6858
6859                case stnormal:{
6860                    if ((ast.tokencode  == TBaseType.cmtdoublehyphen)
6861                            || (ast.tokencode  == TBaseType.cmtslashstar)
6862                            || (ast.tokencode  == TBaseType.lexspace)
6863                            || (ast.tokencode  == TBaseType.lexnewline)
6864                            || (ast.tokentype  == ETokenType.ttsemicolon) )
6865                    {
6866                        if (gcurrentsqlstatement != null)
6867                        {
6868                            gcurrentsqlstatement.addtokentolist(ast);
6869                        }
6870
6871                        if ((lcprevsolidtoken != null) && (ast.tokentype == ETokenType.ttsemicolon))
6872                        {
6873                            if (lcprevsolidtoken.tokentype == ETokenType.ttsemicolon )
6874                            {
6875                                // ;;;; continuous semicolon,treat it as comment
6876                                ast.tokentype = ETokenType.ttsimplecomment;
6877                                ast.tokencode =  TBaseType.cmtdoublehyphen;
6878                            }
6879                        }
6880
6881                        continue;
6882                    }
6883
6884
6885                    // find a tokentext to start sql or plsql mode
6886                    gcurrentsqlstatement = sqlcmds.issql(ast, dbVendor,gst,gcurrentsqlstatement);
6887
6888                    if (gcurrentsqlstatement != null)
6889                    {
6890                        if (gcurrentsqlstatement.isprestoplsql())
6891                        {
6892                            gst = EFindSqlStateType.ststoredprocedure;
6893                            gcurrentsqlstatement.addtokentolist(ast);
6894                            foundEnd = false;
6895                            if   ((ast.tokencode == TBaseType.rrw_begin)
6896                                    ||(ast.tokencode == TBaseType.rrw_package)
6897                                    || (ast.searchToken(TBaseType.rrw_package,4) != null)
6898                            )
6899                            { waitingEnd = 1;}
6900                        }
6901                        else
6902                        {
6903                            gst = EFindSqlStateType.stsql;
6904                            gcurrentsqlstatement.addtokentolist(ast);
6905                        }
6906                    }else{
6907                        //error tokentext found
6908
6909                        this.syntaxErrors.add( new TSyntaxError(ast.astext,ast.lineNo,(ast.columnNo < 0 ? 0:ast.columnNo)
6910                                ,"Error when tokenlize", EErrorType.spwarning,TBaseType.MSG_WARNING_ERROR_WHEN_TOKENIZE,null,ast.posinlist));
6911
6912                        ast.tokentype = ETokenType.tttokenlizererrortoken;
6913                        gst = EFindSqlStateType.sterror;
6914
6915                        gcurrentsqlstatement = new TUnknownSqlStatement(dbVendor);
6916                        gcurrentsqlstatement.sqlstatementtype = ESqlStatementType.sstinvalid;
6917                        gcurrentsqlstatement.addtokentolist(ast);
6918
6919                    }
6920
6921                    break;
6922                } // stnormal
6923
6924                case stsql:{
6925                    if (ast.tokentype == ETokenType.ttsemicolon)
6926                    {
6927                        gst = EFindSqlStateType.stnormal;
6928                        gcurrentsqlstatement.addtokentolist(ast);
6929                        gcurrentsqlstatement.semicolonended = ast;
6930                        doongetrawsqlstatementevent(gcurrentsqlstatement);
6931                        continue;
6932                    }
6933
6934                    if  (sourcetokenlist.sqlplusaftercurtoken() ) //most probaly is / cmd
6935                    {
6936                        gst = EFindSqlStateType.stnormal;
6937                        gcurrentsqlstatement.addtokentolist(ast);
6938                        doongetrawsqlstatementevent(gcurrentsqlstatement);
6939                        continue;
6940                    }
6941                    gcurrentsqlstatement.addtokentolist(ast);
6942                    break;
6943                }//case stsql
6944
6945                case ststoredprocedure:{
6946                    if   ((ast.tokencode == TBaseType.rrw_begin)
6947                        //||(ast.tokencode == TBaseType.rrw_between)
6948                    )
6949                    {
6950                        waitingEnd++;
6951                    }
6952                    else if   (
6953                            (ast.tokencode == TBaseType.rrw_if)
6954                    ){
6955                        if (ast.searchToken(TBaseType.rrw_end,-1) == null){
6956                            //this is not if after END
6957                            waitingEnd++;
6958                        }
6959                    }
6960                    else if   (
6961                            (ast.tokencode == TBaseType.rrw_case)
6962                    ){
6963                        if (ast.searchToken(TBaseType.rrw_end,-1) == null){
6964                            //this is not case after END
6965                            waitingEnd++;
6966                        }
6967                    }
6968                    else if   (
6969                            (ast.tokencode == TBaseType.rrw_loop)
6970                    ){
6971                        if (ast.searchToken(TBaseType.rrw_end,-1) == null){
6972                            //this is not loop after END
6973                            waitingEnd++;
6974                        }
6975                    }
6976                    else if (ast.tokencode == TBaseType.rrw_end){
6977                        foundEnd = true;
6978                        waitingEnd--;
6979                        if (waitingEnd < 0) { waitingEnd = 0;}
6980                    }
6981
6982                    if ((ast.tokentype == ETokenType.ttslash)  && (ast.tokencode == TBaseType.sqlpluscmd) ) //and (prevst.NewlineIsLastTokenInTailerToken)) then
6983                    {
6984                        // TPlsqlStatementParse(asqlstatement).TerminatorToken := ast;
6985                        ast.tokenstatus = ETokenStatus.tsignorebyyacc;
6986                        gst = EFindSqlStateType.stnormal;
6987                        doongetrawsqlstatementevent(gcurrentsqlstatement);
6988
6989                        //make / a sqlplus cmd
6990                        gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
6991                        gcurrentsqlstatement.addtokentolist(ast);
6992                        doongetrawsqlstatementevent(gcurrentsqlstatement);
6993                    }
6994                    else  if ((ast.tokentype == ETokenType.ttperiod)  && (sourcetokenlist.returnaftercurtoken(false)) && (sourcetokenlist.returnbeforecurtoken(false)))
6995                    {    // single dot at a seperate line
6996                        ast.tokenstatus = ETokenStatus.tsignorebyyacc;
6997                        gst = EFindSqlStateType.stnormal;
6998                        doongetrawsqlstatementevent(gcurrentsqlstatement);
6999
7000                        //make ttperiod a sqlplus cmd
7001                        gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
7002                        gcurrentsqlstatement.addtokentolist(ast);
7003                        doongetrawsqlstatementevent(gcurrentsqlstatement);
7004                    }
7005                    else
7006                    {
7007                        gcurrentsqlstatement.addtokentolist(ast);
7008                        if ((ast.tokentype == ETokenType.ttsemicolon) && (waitingEnd == 0)
7009                                && (foundEnd)
7010                            //        && (gcurrentsqlstatement.OracleStatementCanBeSeparatedByBeginEndPair())
7011                        ){
7012                            gst = EFindSqlStateType.stnormal;
7013                            doongetrawsqlstatementevent(gcurrentsqlstatement);
7014                        }
7015                    }
7016
7017                    if (ast.tokencode == TBaseType.sqlpluscmd)
7018                    {
7019                        //change tokencode back to keyword or TBaseType.ident, because sqlplus cmd
7020                        //in a sql statement(almost is plsql block) is not really a sqlplus cmd
7021                        int m = flexer.getkeywordvalue(ast.astext);
7022                        if (m != 0)
7023                        {ast.tokencode = m;}
7024                        else
7025                        {ast.tokencode = TBaseType.ident;}
7026                    }
7027
7028                    break;
7029                } //ststoredprocedure
7030            } //switch
7031        }//for
7032
7033        //last statement
7034        if ((gcurrentsqlstatement != null) &&
7035                ((gst == EFindSqlStateType.stsqlplus) ||  (gst == EFindSqlStateType.stsql) || (gst == EFindSqlStateType.ststoredprocedure) ||
7036                        (gst == EFindSqlStateType.sterror)))
7037        {
7038            doongetrawsqlstatementevent(gcurrentsqlstatement);
7039        }
7040
7041        return syntaxErrors.size();
7042    }
7043
7044    // isSinglePLBlock = true, 表示 netezza 中的 declear..begen/end blcok 重新在 postgresql 中解析,只需要看做一个整体即可,不需要再逐个语句进行区分。
7045    // TCreateProcedureStmt.java, private void doParseFunctionBody(EDbVendor dbVendor,String inputSQL,boolean isSQLBlock){
7046
7047    private boolean isSinglePLBlock = false;
7048
7049    public void setSinglePLBlock(boolean singlePLBlock) {
7050        isSinglePLBlock = singlePLBlock;
7051    }
7052
7053    // In gaussDB, used to find pkg name during getRawsqlstatement()
7054    // mode = 1, pkg spec, mode = 2, pkg body, mode = 3, pkg name after end and before ;
7055    String findPkgName(TSourceToken st, int mode){
7056
7057        String pkgName="";
7058
7059        boolean inpkgname = false;
7060        if (mode == 3) inpkgname = true;
7061        int MAX_TRY_TOKENS = 20;
7062        int tryTokens = 0;
7063        while (st != null){
7064
7065            if (st.isnonsolidtoken()) {
7066                st = st.getNextTokenInChain();
7067                continue;
7068            }
7069            tryTokens++;
7070
7071            if ((mode == 1 ) && (st.tokencode == TBaseType.rrw_package)){
7072                inpkgname = true;
7073                st = st.getNextTokenInChain();
7074                continue;
7075            }else if ((mode == 2 ) && (st.tokencode == TBaseType.rrw_body)){
7076                inpkgname = true;
7077                st = st.getNextTokenInChain();
7078                continue;
7079            }
7080
7081            if(((mode == 1)||(mode == 2))
7082                && ((st.tokencode == TBaseType.rrw_is)||(st.tokencode == TBaseType.rrw_as))
7083                ){
7084                break;
7085            }else if ((mode == 3) && (st.tokencode == ';')){
7086                break;
7087            }
7088
7089            if (!inpkgname) {
7090                st = st.getNextTokenInChain();
7091                continue;
7092            }
7093            pkgName = pkgName+st.toString();
7094            st = st.getNextTokenInChain();
7095
7096            if (tryTokens > MAX_TRY_TOKENS){
7097                TBaseType.log(String.format("Package name is not found in create package"),TLog.ERROR,st);
7098                break;
7099            }
7100        }
7101
7102        return pkgName;
7103    }
7104
7105    boolean isOracleStyleRoutine = true;
7106    TSourceToken stProcedure = null;
7107    TSourceToken stFunction = null;
7108
7109    int doansigetrawsqlstatements(){
7110        return dodb2getrawsqlstatements();
7111    }
7112
7113    int dogaussdbgetrawsqlstatements(){
7114        int waitingEnd = 0;
7115        boolean foundEnd = false, enterDeclare = false;
7116        isOracleStyleRoutine = true;
7117        stProcedure = null;
7118        stFunction = null;
7119
7120        if ( TBaseType.assigned(sqlstatements) ) sqlstatements.clear();
7121        if ( ! TBaseType.assigned(sourcetokenlist) ) return -1;
7122
7123        gcurrentsqlstatement = null;
7124        EFindSqlStateType gst = EFindSqlStateType.stnormal;
7125        TSourceToken lcprevsolidtoken = null,ast = null;
7126
7127//        if (isSinglePLBlock){
7128//            gcurrentsqlstatement = new TCommonBlock(EDbVendor.dbvgaussdb);
7129//        }
7130
7131        for (int i=0 ; i < sourcetokenlist.size();i++)
7132        {
7133
7134            if ( (ast != null ) && (ast.issolidtoken() ))
7135                lcprevsolidtoken = ast;
7136
7137            ast = sourcetokenlist.get(i);
7138            sourcetokenlist.curpos = i;
7139            if (isSinglePLBlock){
7140                gcurrentsqlstatement.sourcetokenlist.add(ast);
7141                continue;
7142            }
7143
7144            if (ast.tokencode == TBaseType.JSON_EXIST){
7145                TSourceToken stConstant  = ast.searchToken(TBaseType.sconst,1);
7146                if (stConstant == null){
7147                    ast.tokencode = TBaseType.ident;
7148                }
7149            }
7150            else if (ast.tokencode == TBaseType.rrw_postgresql_POSITION) {
7151                TSourceToken st1 = ast.nextSolidToken(); //ast.searchToken('(',1);
7152                if (st1 != null) {
7153                    if (st1.tokencode == '(') {
7154                        ast.tokencode = TBaseType.rrw_postgresql_POSITION_FUNCTION;
7155                    }
7156                }
7157            }else  if (ast.tokencode == TBaseType.rrw_postgresql_ordinality) {
7158                TSourceToken lcprevst = getprevsolidtoken(ast);
7159
7160                if (lcprevst != null) {
7161                    if (lcprevst.tokencode == TBaseType.rrw_with) {
7162                        TSourceToken lcnextst = ast.nextSolidToken();
7163                        if ((lcnextst != null)&&(lcnextst.tokencode == TBaseType.rrw_as)){
7164                            //  with ordinality as (select 1 as x) select * from ordinality;
7165                            // don't change with to rrw_postgresql_with_lookahead
7166                        }else{
7167                            lcprevst.tokencode = TBaseType.rrw_postgresql_with_lookahead;
7168                        }
7169
7170                    }
7171                }
7172            }
7173            else if (ast.tokencode == TBaseType.rrw_postgresql_filter) {
7174                TSourceToken st1 = ast.nextSolidToken(); //ast.searchToken('(',1);
7175                if (st1 != null) {
7176                    if (st1.tokencode == '(') {
7177
7178                    }else{
7179                        ast.tokencode = TBaseType.ident;
7180                    }
7181                }
7182            }
7183            else if (ast.tokencode == TBaseType.rrw_postgresql_jsonb) {
7184                TSourceToken st1 = ast.nextSolidToken(); //ast.searchToken('(',1);
7185                if (st1 != null) {
7186                    if (st1.tokencode == '?') {
7187                        st1.tokencode = TBaseType.OP_JSONB_QUESTION;
7188                    }
7189                }
7190            }
7191            else if (ast.tokencode == TBaseType.GAUSSDB_TO_NUMBER) {
7192                TSourceToken st1 = ast.searchToken('(',1);
7193                if (st1 == null) {
7194                    ast.tokencode = TBaseType.ident;
7195                }
7196            }
7197            else if (ast.tokencode == '?') {
7198                TSourceToken st1 = ast.nextSolidToken(); //ast.searchToken('(',1);
7199                if (st1 != null) {
7200                    if (st1.tokencode == TBaseType.sconst) {
7201                        ast.tokencode = TBaseType.OP_JSONB_QUESTION;
7202                    }
7203                }
7204            }
7205            else if (ast.tokencode == TBaseType.rrw_values) {
7206                TSourceToken stParen =  ast.searchToken('(',1);
7207                if (stParen != null){
7208                    TSourceToken stInsert  = ast.searchToken(TBaseType.rrw_insert,-ast.posinlist);
7209                    if (stInsert != null){
7210                        TSourceToken stSemiColon  = ast.searchToken(';',-ast.posinlist);
7211                        if ((stSemiColon != null)&&(stSemiColon.posinlist > stInsert.posinlist)){
7212//                            INSERT INTO test values (16,1), (8,2), (4,4), (2,0), (97, 16);
7213//                            VALUES (1);
7214                            // don't treat values(1) as insert values
7215
7216                        }else{
7217                            TSourceToken stFrom  = ast.searchToken(TBaseType.rrw_from,-ast.posinlist);
7218                            if ((stFrom != null)&&(stFrom.posinlist > stInsert.posinlist)){
7219                                // 不但要发现 from keywords, 而且该keyword 不能出现在 insert 前
7220                                // 避免这个文件中的 insert values 部分内容被视为 subquery. "C:\prg\gsp_sqlfiles\TestCases\private\java\gaussdb\insert_in_procedure.sql"
7221
7222                                // don't treat values after from keyword as an insert values
7223
7224                                // insert into inserttest values(10, 20, '40'), (-1, 2, DEFAULT),  ((select 2), (select i from (values(3) ) as foo (i)), 'values are fun!');
7225
7226                            }else{
7227                                ast.tokencode = TBaseType.rrw_postgresql_insert_values;
7228                            }
7229
7230                        }
7231
7232                    }
7233                }
7234            }
7235
7236            switch(gst){
7237                case sterror:{
7238                    if (ast.tokentype ==  ETokenType.ttsemicolon)
7239                    {
7240                        gcurrentsqlstatement.sourcetokenlist.add(ast);
7241                        doongetrawsqlstatementevent(gcurrentsqlstatement);
7242                        gst = EFindSqlStateType.stnormal;
7243                    }
7244                    else
7245                    {
7246                        gcurrentsqlstatement.sourcetokenlist.add(ast);
7247                    }
7248                    break;
7249                } //sterror
7250
7251                case stnormal:{
7252                    if ((ast.tokencode  == TBaseType.cmtdoublehyphen)
7253                            || (ast.tokencode  == TBaseType.cmtslashstar)
7254                            || (ast.tokencode  == TBaseType.lexspace)
7255                            || (ast.tokencode  == TBaseType.lexnewline)
7256                            || (ast.tokentype  == ETokenType.ttsemicolon) )
7257                    {
7258                        if (gcurrentsqlstatement != null)
7259                        {
7260                            gcurrentsqlstatement.addtokentolist(ast);
7261                        }
7262
7263                        if ((lcprevsolidtoken != null) && (ast.tokentype == ETokenType.ttsemicolon))
7264                        {
7265                            if (lcprevsolidtoken.tokentype == ETokenType.ttsemicolon )
7266                            {
7267                                // ;;;; continuous semicolon,treat it as comment
7268                                ast.tokentype = ETokenType.ttsimplecomment;
7269                                ast.tokencode =  TBaseType.cmtdoublehyphen;
7270                            }
7271                        }
7272
7273                        continue;
7274                    }
7275
7276                    if (ast.tokencode == TBaseType.sqlpluscmd )
7277                    {
7278                        gst = EFindSqlStateType.stsqlplus;
7279                        gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
7280                        gcurrentsqlstatement.addtokentolist(ast);
7281                        continue;
7282                    }
7283
7284                    // find a tokentext to start sql or plsql mode
7285                    gcurrentsqlstatement = sqlcmds.issql(ast, dbVendor,gst,gcurrentsqlstatement);
7286
7287                    if (gcurrentsqlstatement != null)
7288                    {
7289                        enterDeclare = false;
7290                        if (gcurrentsqlstatement.isGaussDBStoredProcedure())
7291                        {
7292                            gcurrentsqlstatement.addtokentolist(ast);
7293                            if (gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstplsql_createpackage){
7294                                gst = EFindSqlStateType.stGaussDBPkgSpec;
7295                                TPlsqlCreatePackage pkgspec = (TPlsqlCreatePackage) gcurrentsqlstatement;
7296                                pkgspec.setPackageNameStr(findPkgName(ast.getNextTokenInChain(),1));
7297                                //System.out.println("pkg spec name: "+ pkgspec.getPackageNameStr());
7298                            }else if (gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstoraclecreatepackagebody){
7299                                gst = EFindSqlStateType.stGaussDBPkgBody;
7300                                TPlsqlCreatePackage pkgspec = (TPlsqlCreatePackage) gcurrentsqlstatement;
7301                                pkgspec.setPackageNameStr(findPkgName(ast.getNextTokenInChain(),2));
7302                                //System.out.println("pkg body name: "+ pkgspec.getPackageNameStr());
7303                            }else{
7304                                gst = EFindSqlStateType.ststoredprocedure;
7305
7306                                foundEnd = false;
7307                                if   ((ast.tokencode == TBaseType.rrw_begin)
7308                                        ||(ast.tokencode == TBaseType.rrw_package)
7309                                        || (ast.searchToken(TBaseType.rrw_package,4) != null)
7310                                )
7311                                {
7312                                    waitingEnd = 1;
7313                                }
7314                                else if (ast.tokencode == TBaseType.rrw_declare){
7315                                    enterDeclare = true;
7316                                }
7317
7318                                if (gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreateprocedure)
7319                                {
7320                                    // create procedure, create or replace procedure
7321                                    stProcedure = ast.searchToken(TBaseType.rrw_procedure,3);
7322                                }
7323                                else if (gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatefunction){
7324                                    // create function, create or replace function
7325                                    stFunction = ast.searchToken(TBaseType.rrw_function,3);
7326                                }
7327                            }
7328                        }
7329                        else
7330                        {
7331                            gst = EFindSqlStateType.stsql;
7332                            gcurrentsqlstatement.addtokentolist(ast);
7333                        }
7334                    }else{
7335                        //error tokentext found
7336
7337                        this.syntaxErrors.add( new TSyntaxError(ast.astext,ast.lineNo,(ast.columnNo < 0 ? 0:ast.columnNo)
7338                                ,"Error when tokenlize", EErrorType.spwarning,TBaseType.MSG_WARNING_ERROR_WHEN_TOKENIZE,null,ast.posinlist));
7339
7340                        ast.tokentype = ETokenType.tttokenlizererrortoken;
7341                        gst = EFindSqlStateType.sterror;
7342
7343                        gcurrentsqlstatement = new TUnknownSqlStatement(dbVendor);
7344                        gcurrentsqlstatement.sqlstatementtype = ESqlStatementType.sstinvalid;
7345                        gcurrentsqlstatement.addtokentolist(ast);
7346
7347                    }
7348
7349                    break;
7350                } // stnormal
7351
7352                case stsqlplus:{
7353                    if  (ast.insqlpluscmd)
7354                    {gcurrentsqlstatement.addtokentolist(ast);}
7355                    else
7356                    {
7357                        gst = EFindSqlStateType.stnormal; //this tokentext must be newline,
7358                        gcurrentsqlstatement.addtokentolist(ast); // so add it here
7359                        doongetrawsqlstatementevent(gcurrentsqlstatement);
7360                    }
7361
7362                    break;
7363                }//case stsqlplus
7364
7365                case stsql:{
7366                    if (ast.tokentype == ETokenType.ttsemicolon)
7367                    {
7368                        gst = EFindSqlStateType.stnormal;
7369                        gcurrentsqlstatement.addtokentolist(ast);
7370                        gcurrentsqlstatement.semicolonended = ast;
7371                        doongetrawsqlstatementevent(gcurrentsqlstatement);
7372                        continue;
7373                    }
7374
7375                    if  (sourcetokenlist.sqlplusaftercurtoken()) //most probably is / cmd
7376                    {
7377                        // gaussdb 中的普通sql(非存储过程)中如果出现 / ,并且被识别为 sqlplus, 应该是误判,例如下面的sql,需要把 / 复原为普通的字符 /
7378                        //                        select CASE WHEN 1 IS NULL Then -1
7379                        //                        Else
7380                        //                        date_part('day' ,NVL(sysdate, TO_DATE('4712-12-31','YYYY-MM-DD')) - NVL(sysdate, TO_DATE('1900-01-01' ,'YYYY-MM-DD')))
7381                        //                                /
7382                        //                                NVL(NVL(null,1), -1) END AS varCompressionRate
7383                        TSourceToken st = ast.nextSolidToken();
7384                        if (st.tokentype == ETokenType.ttslash){
7385                            st.tokencode = '/';
7386                        }else { // 非 / 的 sqlplus 命令仍然作为sqlplus处理,但 gaussdb 中是否存在类似 oracle的sqlplus,需要进一步验证
7387                            gst = EFindSqlStateType.stnormal;
7388                            gcurrentsqlstatement.addtokentolist(ast);
7389                            doongetrawsqlstatementevent(gcurrentsqlstatement);
7390                            continue;
7391                        }
7392                    }
7393
7394                    if (ast.tokencode  == TBaseType.cmtdoublehyphen){
7395                        if (ast.toString().trim().endsWith(TBaseType.sqlflow_stmt_delimiter_str)){ // -- sqlflow-delimiter
7396                            gst = EFindSqlStateType.stnormal;
7397                            doongetrawsqlstatementevent(gcurrentsqlstatement);
7398                            continue;
7399                        }
7400                    }
7401
7402                    gcurrentsqlstatement.addtokentolist(ast);
7403                    break;
7404                }//case stsql
7405
7406                case ststoredprocedure:{
7407                    if (ast.tokencode == TBaseType.rrw_postgresql_function_delimiter){
7408                        gcurrentsqlstatement.addtokentolist(ast);
7409                        isOracleStyleRoutine = false;
7410                        gst = EFindSqlStateType.ststoredprocedurePgStartBody;
7411                        continue;
7412                    }
7413
7414                    if (ast.tokencode == TBaseType.rrw_postgresql_language){
7415                        // check next token which is the language used by this stored procedure
7416                        TSourceToken nextSt = ast.nextSolidToken();
7417                        if (nextSt != null){
7418                            if (gcurrentsqlstatement instanceof TRoutine){  // can be TCreateProcedureStmt or TCreateFunctionStmt
7419                                TRoutine p = (TRoutine) gcurrentsqlstatement;
7420                                p.setRoutineLanguage(nextSt.toString());
7421                                isOracleStyleRoutine = false;
7422                            }
7423                        }
7424                    }
7425
7426                    if ((ast.tokentype == ETokenType.ttsemicolon) && (waitingEnd == 0) && (!enterDeclare))
7427                    {
7428                        gst = EFindSqlStateType.stnormal;
7429                        gcurrentsqlstatement.addtokentolist(ast);
7430                        gcurrentsqlstatement.semicolonended = ast;
7431
7432                        doongetrawsqlstatementevent(gcurrentsqlstatement);
7433                        continue;
7434                    }
7435
7436                    if   ((ast.tokencode == TBaseType.rrw_begin)
7437                        //||(ast.tokencode == TBaseType.rrw_between)
7438                    )
7439                    {
7440                        waitingEnd++;
7441                        enterDeclare = false;
7442                    }
7443                    else if   (
7444                            (ast.tokencode == TBaseType.rrw_declare)
7445                            ||(ast.tokencode == TBaseType.rrw_as)||(ast.tokencode == TBaseType.rrw_is)
7446                    ){
7447                        TSourceToken next = ast.nextSolidToken();
7448                        if ((next != null) && ((next.tokencode == TBaseType.sconst)||(next.tokencode == TBaseType.GAUSSDB_NULL))){
7449                                // CREATE FUNCTION func_add_sql(integer, integer) RETURNS integer
7450                                //    AS 'select $1 + $2;'
7451                                //    LANGUAGE SQL
7452                                //    IMMUTABLE
7453                                //    RETURNS NULL ON NULL INPUT;
7454                        }else{
7455                            //
7456//                            create or replace function func_001(a in out pkg_type.table_of_index_int, b in out pkg_type.table_of_index_var) --#add in & inout #defult value
7457//                            return pkg_type.table_of_index_int
7458//                            as
7459//                            table_of_index_int_val pkg_type.table_of_index_int;
7460//                            table_of_index_var_val pkg_type.table_of_index_var;
7461//                            begin
7462//                            for i in 1..2 loop
7463                            enterDeclare = true;
7464                        }
7465                    }
7466                    else if   (
7467                            (ast.tokencode == TBaseType.rrw_if)
7468                    ){
7469                        if (ast.searchToken(TBaseType.rrw_end,-1) == null){
7470                            //this is not if after END
7471                            waitingEnd++;
7472                        }
7473                    }
7474                    else if   (
7475                            (ast.tokencode == TBaseType.rrw_case)
7476                    ){
7477                        if (ast.searchToken(TBaseType.rrw_end,-1) == null){
7478                            //this is not case after END
7479                            waitingEnd++;
7480                        }
7481                    }
7482                    else if   (
7483                            (ast.tokencode == TBaseType.rrw_loop)
7484                    ){
7485                        if (ast.searchToken(TBaseType.rrw_end,-1) == null){
7486                            //this is not loop after END
7487                            waitingEnd++;
7488                        }
7489                    }
7490                    else if (ast.tokencode == TBaseType.rrw_end){
7491                        foundEnd = true;
7492                        waitingEnd--;
7493                        if (waitingEnd < 0) { waitingEnd = 0;}
7494                    }
7495
7496                    if ((ast.tokentype == ETokenType.ttslash)  && (ast.tokencode == TBaseType.sqlpluscmd) ) //and (prevst.NewlineIsLastTokenInTailerToken)) then
7497                    {
7498                        // TPlsqlStatementParse(asqlstatement).TerminatorToken := ast;
7499                        ast.tokenstatus = ETokenStatus.tsignorebyyacc;
7500                        gst = EFindSqlStateType.stnormal;
7501
7502                        doongetrawsqlstatementevent(gcurrentsqlstatement);
7503
7504                        //make / a sqlplus cmd
7505                        gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
7506                        gcurrentsqlstatement.addtokentolist(ast);
7507                        doongetrawsqlstatementevent(gcurrentsqlstatement);
7508                    }
7509                    else  if ((ast.tokentype == ETokenType.ttperiod)  && (sourcetokenlist.returnaftercurtoken(false)) && (sourcetokenlist.returnbeforecurtoken(false)))
7510                    {    // single dot at a seperate line
7511                        ast.tokenstatus = ETokenStatus.tsignorebyyacc;
7512                        gst = EFindSqlStateType.stnormal;
7513
7514                        doongetrawsqlstatementevent(gcurrentsqlstatement);
7515
7516                        //make ttperiod a sqlplus cmd
7517                        gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
7518                        gcurrentsqlstatement.addtokentolist(ast);
7519                        doongetrawsqlstatementevent(gcurrentsqlstatement);
7520                    }
7521                    else
7522                    {
7523                        gcurrentsqlstatement.addtokentolist(ast);
7524                        if ((ast.tokentype == ETokenType.ttsemicolon) && (waitingEnd == 0) && (!enterDeclare)
7525                                && (foundEnd)
7526                            //        && (gcurrentsqlstatement.OracleStatementCanBeSeparatedByBeginEndPair())
7527                        ){
7528                            gst = EFindSqlStateType.stnormal;
7529                            doongetrawsqlstatementevent(gcurrentsqlstatement);
7530                        }
7531                    }
7532
7533                    if (ast.tokencode == TBaseType.sqlpluscmd)
7534                    {
7535                        //change tokencode back to keyword or TBaseType.ident, because sqlplus cmd
7536                        //in a sql statement(almost is plsql block) is not really a sqlplus cmd
7537                        int m = flexer.getkeywordvalue(ast.astext);
7538                        if (m != 0)
7539                        {ast.tokencode = m;}
7540                        else
7541                        {ast.tokencode = TBaseType.ident;}
7542                    }
7543
7544                    if (( gst == EFindSqlStateType.ststoredprocedure ) && (ast.tokencode  == TBaseType.cmtdoublehyphen)){
7545                        if (ast.toString().trim().endsWith(TBaseType.sqlflow_stmt_delimiter_str)){ // -- sqlflow-delimiter
7546                            gst = EFindSqlStateType.stnormal;
7547                            doongetrawsqlstatementevent(gcurrentsqlstatement);
7548                        }
7549                    }
7550
7551                    break;
7552                } //ststoredprocedure
7553
7554                case ststoredprocedurePgStartBody:{
7555                    gcurrentsqlstatement.addtokentolist(ast);
7556
7557                    if (ast.tokencode == TBaseType.rrw_postgresql_function_delimiter){
7558                        gst = EFindSqlStateType.ststoredprocedurePgEndBody;
7559                        continue;
7560                    }
7561
7562                    break;
7563                }
7564
7565                case ststoredprocedurePgEndBody:{
7566
7567                    if (ast.tokentype == ETokenType.ttsemicolon)
7568                    {
7569                        gst = EFindSqlStateType.stnormal;
7570                        gcurrentsqlstatement.addtokentolist(ast);
7571                        gcurrentsqlstatement.semicolonended = ast;
7572                        doongetrawsqlstatementevent(gcurrentsqlstatement);
7573                        continue;
7574                    }
7575                    else if (ast.tokencode  == TBaseType.cmtdoublehyphen){
7576                        if (ast.toString().trim().endsWith(TBaseType.sqlflow_stmt_delimiter_str)){ // -- sqlflow-delimiter
7577                            gst = EFindSqlStateType.stnormal;
7578                            doongetrawsqlstatementevent(gcurrentsqlstatement);
7579                            continue;
7580                        }
7581                    }
7582
7583                    gcurrentsqlstatement.addtokentolist(ast);
7584
7585                    if (ast.tokencode == TBaseType.rrw_postgresql_language){
7586                        // check next token which is the language used by this stored procedure
7587                        TSourceToken nextSt = ast.nextSolidToken();
7588                        if (nextSt != null){
7589                            if (gcurrentsqlstatement instanceof TRoutine){  // can be TCreateProcedureStmt or TCreateFunctionStmt
7590                                TRoutine p = (TRoutine) gcurrentsqlstatement;
7591                                p.setRoutineLanguage(nextSt.toString());
7592                            }
7593                        }
7594                    }
7595
7596                    break;
7597                }
7598
7599                case stGaussDBPkgSpec:{
7600                    gcurrentsqlstatement.addtokentolist(ast);
7601
7602                    if (ast.tokencode == TBaseType.rrw_end){
7603                        TPlsqlCreatePackage plsqlCreatePackage = (TPlsqlCreatePackage)gcurrentsqlstatement;
7604
7605                        String pkgName = findPkgName(ast.getNextTokenInChain(),3);
7606                        if ((pkgName != null)&&( pkgName.equalsIgnoreCase(plsqlCreatePackage.getPackageNameStr()))) {
7607                            gst = EFindSqlStateType.stGaussDBPkgSpecEnd;
7608                        }
7609                    }
7610                    break;
7611                }
7612                case stGaussDBPkgSpecEnd:{
7613                    gcurrentsqlstatement.addtokentolist(ast);
7614                    if (ast.tokencode == ';'){
7615                        gst = EFindSqlStateType.stnormal;
7616                        doongetrawsqlstatementevent(gcurrentsqlstatement);
7617                        continue;
7618                    }
7619                    break;
7620                }
7621
7622                case stGaussDBPkgBody:{
7623                    gcurrentsqlstatement.addtokentolist(ast);
7624                    if (ast.tokencode == TBaseType.rrw_end){
7625                        TPlsqlCreatePackage plsqlCreatePackage = (TPlsqlCreatePackage)gcurrentsqlstatement;
7626
7627                        String pkgName = findPkgName(ast.getNextTokenInChain(),3);
7628                        if ((pkgName != null)&&( pkgName.equalsIgnoreCase(plsqlCreatePackage.getPackageNameStr()))) {
7629                            gst = EFindSqlStateType.stGaussDBPkgBodyEnd;
7630                        }
7631                    }
7632                    break;
7633                }
7634                case stGaussDBPkgBodyEnd:{
7635                    gcurrentsqlstatement.addtokentolist(ast);
7636                    if (ast.tokencode == ';'){
7637                        gst = EFindSqlStateType.stnormal;
7638                        doongetrawsqlstatementevent(gcurrentsqlstatement);
7639                        continue;
7640                    }
7641                    break;
7642                }
7643
7644            } //switch
7645        }//for
7646
7647        //last statement
7648        if ((gcurrentsqlstatement != null) &&
7649                ((gst == EFindSqlStateType.stsqlplus) ||  (gst == EFindSqlStateType.stsql)
7650                        || (gst == EFindSqlStateType.ststoredprocedure)
7651                        || (gst == EFindSqlStateType.ststoredprocedurePgEndBody)
7652                        ||(gst == EFindSqlStateType.sterror)||(isSinglePLBlock)
7653                ))
7654        {
7655            doongetrawsqlstatementevent(gcurrentsqlstatement);
7656        }
7657
7658        return syntaxErrors.size();
7659    }
7660
7661    int dopostgresqlgetrawsqlstatements(){
7662        int waitingEnd = 0;
7663        boolean foundEnd = false, enterDeclare = false;
7664
7665
7666
7667        if ( TBaseType.assigned(sqlstatements) ) sqlstatements.clear();
7668        if ( ! TBaseType.assigned(sourcetokenlist) ) return -1;
7669
7670        gcurrentsqlstatement = null;
7671        EFindSqlStateType gst = EFindSqlStateType.stnormal;
7672        TSourceToken lcprevsolidtoken = null,ast = null;
7673
7674        if (isSinglePLBlock){
7675            gcurrentsqlstatement = new TCommonBlock(EDbVendor.dbvpostgresql);
7676        }
7677
7678        for (int i=0 ; i < sourcetokenlist.size();i++)
7679        {
7680
7681            if ( (ast != null ) && (ast.issolidtoken() ))
7682                lcprevsolidtoken = ast;
7683
7684            ast = sourcetokenlist.get(i);
7685            sourcetokenlist.curpos = i;
7686            if (isSinglePLBlock){
7687                gcurrentsqlstatement.sourcetokenlist.add(ast);
7688                continue;
7689            }
7690
7691            if (ast.tokencode == TBaseType.JSON_EXIST){
7692                TSourceToken stConstant  = ast.searchToken(TBaseType.sconst,1);
7693                if (stConstant == null){
7694                    ast.tokencode = TBaseType.ident;
7695                }
7696            }
7697            else if (ast.tokencode == TBaseType.rrw_postgresql_POSITION) {
7698                TSourceToken st1 = ast.nextSolidToken(); //ast.searchToken('(',1);
7699                if (st1 != null) {
7700                    if (st1.tokencode == '(') {
7701                        ast.tokencode = TBaseType.rrw_postgresql_POSITION_FUNCTION;
7702                    }
7703                }
7704            }else  if (ast.tokencode == TBaseType.rrw_postgresql_ordinality) {
7705                TSourceToken lcprevst = getprevsolidtoken(ast);
7706
7707                if (lcprevst != null) {
7708                    if (lcprevst.tokencode == TBaseType.rrw_with) {
7709                        TSourceToken lcnextst = ast.nextSolidToken();
7710                        if ((lcnextst != null)&&(lcnextst.tokencode == TBaseType.rrw_as)){
7711                            //  with ordinality as (select 1 as x) select * from ordinality;
7712                            // don't change with to rrw_postgresql_with_lookahead
7713                        }else{
7714                            lcprevst.tokencode = TBaseType.rrw_postgresql_with_lookahead;
7715                        }
7716
7717                    }
7718                }
7719            }
7720            else if (ast.tokencode == TBaseType.rrw_postgresql_filter) {
7721                TSourceToken st1 = ast.nextSolidToken(); //ast.searchToken('(',1);
7722                if (st1 != null) {
7723                    if (st1.tokencode == '(') {
7724
7725                    }else{
7726                        ast.tokencode = TBaseType.ident;
7727                    }
7728                }
7729            }
7730            else if (ast.tokencode == TBaseType.rrw_postgresql_jsonb) {
7731                TSourceToken st1 = ast.nextSolidToken(); //ast.searchToken('(',1);
7732                if (st1 != null) {
7733                    if (st1.tokencode == '?') {
7734                        st1.tokencode = TBaseType.OP_JSONB_QUESTION;
7735                    }
7736                }
7737            }
7738            else if (ast.tokencode == '?') {
7739                TSourceToken st1 = ast.nextSolidToken(); //ast.searchToken('(',1);
7740                if (st1 != null) {
7741                    if (st1.tokencode == TBaseType.sconst) {
7742                        ast.tokencode = TBaseType.OP_JSONB_QUESTION;
7743                    }
7744                }
7745            }
7746            else if (ast.tokencode == TBaseType.rrw_values) {
7747                TSourceToken stParen =  ast.searchToken('(',1);
7748                if (stParen != null){
7749                    TSourceToken stInsert  = ast.searchToken(TBaseType.rrw_insert,-ast.posinlist);
7750                    if (stInsert != null){
7751                        TSourceToken stSemiColon  = ast.searchToken(';',-ast.posinlist);
7752                        if ((stSemiColon != null)&&(stSemiColon.posinlist > stInsert.posinlist)){
7753//                            INSERT INTO test values (16,1), (8,2), (4,4), (2,0), (97, 16);
7754//                            VALUES (1);
7755                            // don't treat values(1) as insert values
7756
7757                        }else{
7758                            TSourceToken stFrom  = ast.searchToken(TBaseType.rrw_from,-ast.posinlist);
7759                            if ((stFrom != null)&&(stFrom.posinlist > stInsert.posinlist)){
7760                                // don't treat values after from keyword as an insert values
7761
7762                                // insert into inserttest values(10, 20, '40'), (-1, 2, DEFAULT),  ((select 2), (select i from (values(3) ) as foo (i)), 'values are fun!');
7763
7764                            }else{
7765                                ast.tokencode = TBaseType.rrw_postgresql_insert_values;
7766                            }
7767
7768                        }
7769
7770                    }
7771                }
7772            }
7773
7774            switch(gst){
7775                case sterror:{
7776                    if (ast.tokentype ==  ETokenType.ttsemicolon)
7777                    {
7778                        gcurrentsqlstatement.sourcetokenlist.add(ast);
7779                        doongetrawsqlstatementevent(gcurrentsqlstatement);
7780                        gst = EFindSqlStateType.stnormal;
7781                    }
7782                    else
7783                    {
7784                        gcurrentsqlstatement.sourcetokenlist.add(ast);
7785                    }
7786                    break;
7787                } //sterror
7788
7789                case stnormal:{
7790                    if ((ast.tokencode  == TBaseType.cmtdoublehyphen)
7791                            || (ast.tokencode  == TBaseType.cmtslashstar)
7792                            || (ast.tokencode  == TBaseType.lexspace)
7793                            || (ast.tokencode  == TBaseType.lexnewline)
7794                            || (ast.tokentype  == ETokenType.ttsemicolon) )
7795                    {
7796                        if (gcurrentsqlstatement != null)
7797                        {
7798                            gcurrentsqlstatement.addtokentolist(ast);
7799                        }
7800
7801                        if ((lcprevsolidtoken != null) && (ast.tokentype == ETokenType.ttsemicolon))
7802                        {
7803                            if (lcprevsolidtoken.tokentype == ETokenType.ttsemicolon )
7804                            {
7805                                // ;;;; continuous semicolon,treat it as comment
7806                                ast.tokentype = ETokenType.ttsimplecomment;
7807                                ast.tokencode =  TBaseType.cmtdoublehyphen;
7808                            }
7809                        }
7810
7811                        continue;
7812                    }
7813
7814                    if (ast.tokencode == TBaseType.sqlpluscmd )
7815                    {
7816                        gst = EFindSqlStateType.stsqlplus;
7817                        gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
7818                        gcurrentsqlstatement.addtokentolist(ast);
7819                        continue;
7820                    }
7821
7822                    // find a tokentext to start sql or plsql mode
7823                    gcurrentsqlstatement = sqlcmds.issql(ast, dbVendor,gst,gcurrentsqlstatement);
7824
7825                    if (gcurrentsqlstatement != null)
7826                    {
7827                        enterDeclare = false;
7828                        if (gcurrentsqlstatement.ispgplsql())
7829                        {
7830                            gst = EFindSqlStateType.ststoredprocedure;
7831                            gcurrentsqlstatement.addtokentolist(ast);
7832                            foundEnd = false;
7833                            if   ((ast.tokencode == TBaseType.rrw_begin)
7834                                    ||(ast.tokencode == TBaseType.rrw_package)
7835                                    || (ast.searchToken(TBaseType.rrw_package,4) != null)
7836                                    )
7837                            {
7838                                waitingEnd = 1;
7839                            }
7840                            else if (ast.tokencode == TBaseType.rrw_declare){
7841                                enterDeclare = true;
7842                            }
7843                        }
7844                        else
7845                        {
7846                            gst = EFindSqlStateType.stsql;
7847                            gcurrentsqlstatement.addtokentolist(ast);
7848                        }
7849                    }else{
7850                        //error tokentext found
7851
7852                        this.syntaxErrors.add( new TSyntaxError(ast.astext,ast.lineNo,(ast.columnNo < 0 ? 0:ast.columnNo)
7853                                ,"Error when tokenlize", EErrorType.spwarning,TBaseType.MSG_WARNING_ERROR_WHEN_TOKENIZE,null,ast.posinlist));
7854
7855                        ast.tokentype = ETokenType.tttokenlizererrortoken;
7856                        gst = EFindSqlStateType.sterror;
7857
7858                        gcurrentsqlstatement = new TUnknownSqlStatement(dbVendor);
7859                        gcurrentsqlstatement.sqlstatementtype = ESqlStatementType.sstinvalid;
7860                        gcurrentsqlstatement.addtokentolist(ast);
7861
7862                    }
7863
7864                    break;
7865                } // stnormal
7866
7867                case stsqlplus:{
7868                    if  (ast.insqlpluscmd)
7869                    {gcurrentsqlstatement.addtokentolist(ast);}
7870                    else
7871                    {
7872                        gst = EFindSqlStateType.stnormal; //this tokentext must be newline,
7873                        gcurrentsqlstatement.addtokentolist(ast); // so add it here
7874                        doongetrawsqlstatementevent(gcurrentsqlstatement);
7875                    }
7876
7877                    break;
7878                }//case stsqlplus
7879
7880                case stsql:{
7881                    if (ast.tokentype == ETokenType.ttsemicolon)
7882                    {
7883                        gst = EFindSqlStateType.stnormal;
7884                        gcurrentsqlstatement.addtokentolist(ast);
7885                        gcurrentsqlstatement.semicolonended = ast;
7886                        doongetrawsqlstatementevent(gcurrentsqlstatement);
7887                        continue;
7888                    }
7889
7890                    if  (sourcetokenlist.sqlplusaftercurtoken() ) //most probaly is / cmd
7891                    {
7892                        gst = EFindSqlStateType.stnormal;
7893                        gcurrentsqlstatement.addtokentolist(ast);
7894                        doongetrawsqlstatementevent(gcurrentsqlstatement);
7895                        continue;
7896                    }
7897
7898                    if (ast.tokencode  == TBaseType.cmtdoublehyphen){
7899                        if (ast.toString().trim().endsWith(TBaseType.sqlflow_stmt_delimiter_str)){ // -- sqlflow-delimiter
7900                            gst = EFindSqlStateType.stnormal;
7901                            doongetrawsqlstatementevent(gcurrentsqlstatement);
7902                            continue;
7903                        }
7904                    }
7905
7906                    gcurrentsqlstatement.addtokentolist(ast);
7907                    break;
7908                }//case stsql
7909
7910                case ststoredprocedure:{
7911                    if (ast.tokencode == TBaseType.rrw_postgresql_function_delimiter){
7912                        gcurrentsqlstatement.addtokentolist(ast);
7913                        gst = EFindSqlStateType.ststoredprocedurePgStartBody;
7914
7915                        continue;
7916                    }
7917
7918                    if (ast.tokencode == TBaseType.rrw_postgresql_language){
7919                        // check next token which is the language used by this stored procedure
7920                        TSourceToken nextSt = ast.nextSolidToken();
7921                        if (nextSt != null){
7922                            if (gcurrentsqlstatement instanceof TRoutine){  // can be TCreateProcedureStmt or TCreateFunctionStmt
7923                                TRoutine p = (TRoutine) gcurrentsqlstatement;
7924                                p.setRoutineLanguage(nextSt.toString());
7925                            }
7926                        }
7927                    }
7928
7929                    if ((ast.tokentype == ETokenType.ttsemicolon) && (waitingEnd == 0) && (!enterDeclare))
7930                    {
7931                        gst = EFindSqlStateType.stnormal;
7932                        gcurrentsqlstatement.addtokentolist(ast);
7933                        gcurrentsqlstatement.semicolonended = ast;
7934                        doongetrawsqlstatementevent(gcurrentsqlstatement);
7935                        continue;
7936                    }
7937
7938                    if   ((ast.tokencode == TBaseType.rrw_begin)
7939                        //||(ast.tokencode == TBaseType.rrw_between)
7940                            )
7941                    {
7942                        waitingEnd++;
7943                        enterDeclare = false;
7944                    }
7945                    else if   (
7946                            (ast.tokencode == TBaseType.rrw_declare)
7947                    ){
7948                        enterDeclare = true;
7949                    }
7950                    else if   (
7951                            (ast.tokencode == TBaseType.rrw_if)
7952                            ){
7953                        if (ast.searchToken(TBaseType.rrw_end,-1) == null){
7954                            //this is not if after END
7955                            waitingEnd++;
7956                        }
7957                    }
7958                    else if   (
7959                            (ast.tokencode == TBaseType.rrw_case)
7960                            ){
7961                        if (ast.searchToken(TBaseType.rrw_end,-1) == null){
7962                            //this is not case after END
7963                            waitingEnd++;
7964                        }
7965                    }
7966                    else if   (
7967                            (ast.tokencode == TBaseType.rrw_loop)
7968                            ){
7969                        if (ast.searchToken(TBaseType.rrw_end,-1) == null){
7970                            //this is not loop after END
7971                            waitingEnd++;
7972                        }
7973                    }
7974                    else if (ast.tokencode == TBaseType.rrw_end){
7975                        foundEnd = true;
7976                        waitingEnd--;
7977                        if (waitingEnd < 0) { waitingEnd = 0;}
7978                    }
7979
7980                    if ((ast.tokentype == ETokenType.ttslash)  && (ast.tokencode == TBaseType.sqlpluscmd) ) //and (prevst.NewlineIsLastTokenInTailerToken)) then
7981                    {
7982                        // TPlsqlStatementParse(asqlstatement).TerminatorToken := ast;
7983                        ast.tokenstatus = ETokenStatus.tsignorebyyacc;
7984                        gst = EFindSqlStateType.stnormal;
7985                        doongetrawsqlstatementevent(gcurrentsqlstatement);
7986
7987                        //make / a sqlplus cmd
7988                        gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
7989                        gcurrentsqlstatement.addtokentolist(ast);
7990                        doongetrawsqlstatementevent(gcurrentsqlstatement);
7991                    }
7992                    else  if ((ast.tokentype == ETokenType.ttperiod)  && (sourcetokenlist.returnaftercurtoken(false)) && (sourcetokenlist.returnbeforecurtoken(false)))
7993                    {    // single dot at a seperate line
7994                        ast.tokenstatus = ETokenStatus.tsignorebyyacc;
7995                        gst = EFindSqlStateType.stnormal;
7996                        doongetrawsqlstatementevent(gcurrentsqlstatement);
7997
7998                        //make ttperiod a sqlplus cmd
7999                        gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
8000                        gcurrentsqlstatement.addtokentolist(ast);
8001                        doongetrawsqlstatementevent(gcurrentsqlstatement);
8002                    }
8003                    else
8004                    {
8005                        gcurrentsqlstatement.addtokentolist(ast);
8006                        if ((ast.tokentype == ETokenType.ttsemicolon) && (waitingEnd == 0)
8007                                && (foundEnd)
8008                        //        && (gcurrentsqlstatement.OracleStatementCanBeSeparatedByBeginEndPair())
8009                        ){
8010                            gst = EFindSqlStateType.stnormal;
8011                            doongetrawsqlstatementevent(gcurrentsqlstatement);
8012                        }
8013                    }
8014
8015                    if (ast.tokencode == TBaseType.sqlpluscmd)
8016                    {
8017                        //change tokencode back to keyword or TBaseType.ident, because sqlplus cmd
8018                        //in a sql statement(almost is plsql block) is not really a sqlplus cmd
8019                        int m = flexer.getkeywordvalue(ast.astext);
8020                        if (m != 0)
8021                        {ast.tokencode = m;}
8022                        else
8023                        {ast.tokencode = TBaseType.ident;}
8024                    }
8025
8026                    if (( gst == EFindSqlStateType.ststoredprocedure ) && (ast.tokencode  == TBaseType.cmtdoublehyphen)){
8027                        if (ast.toString().trim().endsWith(TBaseType.sqlflow_stmt_delimiter_str)){ // -- sqlflow-delimiter
8028                            gst = EFindSqlStateType.stnormal;
8029                            doongetrawsqlstatementevent(gcurrentsqlstatement);
8030                        }
8031                    }
8032
8033                    break;
8034                } //ststoredprocedure
8035
8036                case ststoredprocedurePgStartBody:{
8037                    gcurrentsqlstatement.addtokentolist(ast);
8038
8039                    if (ast.tokencode == TBaseType.rrw_postgresql_function_delimiter){
8040                        if (gcurrentsqlstatement.sqlstatementtype == sstDoExecuteBlock){
8041                            gst = EFindSqlStateType.stnormal;
8042                            doongetrawsqlstatementevent(gcurrentsqlstatement);
8043                            continue;
8044
8045                        }else{
8046                            gst = EFindSqlStateType.ststoredprocedurePgEndBody;
8047                            continue;
8048                        }
8049                    }
8050
8051                    break;
8052                }
8053
8054                case ststoredprocedurePgEndBody:{
8055
8056                    if (ast.tokentype == ETokenType.ttsemicolon)
8057                    {
8058                        gst = EFindSqlStateType.stnormal;
8059                        gcurrentsqlstatement.addtokentolist(ast);
8060                        gcurrentsqlstatement.semicolonended = ast;
8061                        doongetrawsqlstatementevent(gcurrentsqlstatement);
8062                        continue;
8063                    }
8064                    else if (ast.tokencode  == TBaseType.cmtdoublehyphen){
8065                        if (ast.toString().trim().endsWith(TBaseType.sqlflow_stmt_delimiter_str)){ // -- sqlflow-delimiter
8066                            gst = EFindSqlStateType.stnormal;
8067                            doongetrawsqlstatementevent(gcurrentsqlstatement);
8068                            continue;
8069                        }
8070                    }
8071
8072                    gcurrentsqlstatement.addtokentolist(ast);
8073
8074                    if (ast.tokencode == TBaseType.rrw_postgresql_language){
8075                        // check next token which is the language used by this stored procedure
8076                        TSourceToken nextSt = ast.nextSolidToken();
8077                        if (nextSt != null){
8078                            if (gcurrentsqlstatement instanceof TRoutine){  // can be TCreateProcedureStmt or TCreateFunctionStmt
8079                                TRoutine p = (TRoutine) gcurrentsqlstatement;
8080                                p.setRoutineLanguage(nextSt.toString());
8081                            }
8082                        }
8083                    }
8084
8085                    break;
8086                }
8087            } //switch
8088        }//for
8089
8090        //last statement
8091        if ((gcurrentsqlstatement != null) &&
8092                ((gst == EFindSqlStateType.stsqlplus) ||  (gst == EFindSqlStateType.stsql)
8093                        || (gst == EFindSqlStateType.ststoredprocedure)
8094                        || (gst == EFindSqlStateType.ststoredprocedurePgEndBody)
8095                        ||(gst == EFindSqlStateType.sterror)||(isSinglePLBlock)
8096                ))
8097        {
8098            doongetrawsqlstatementevent(gcurrentsqlstatement);
8099        }
8100
8101        return syntaxErrors.size();
8102    }
8103
8104    /**
8105     * Functionality
8106     * Target Identification:
8107     * Scans for CREATE PROCEDURE and CREATE FUNCTION statements
8108     * Verifies the language is SQL (for procedures)
8109     * Identifies dollar-quoted strings ($$...$$) and single-quoted strings after AS keywords
8110     * Token Expansion:
8111     * For each identified string literal:
8112     * Extracts the content between the quotes
8113     * Tokenizes the extracted SQL code
8114     * Verifies it's a valid code block (starts with DECLARE or BEGIN)
8115     * Replaces the original quoted string with expanded tokens in the source token list
8116     * Special Transformations:
8117     * Converts BEGIN; to BEGIN TRANSACTION;
8118     * Handles BEGIN WORK; similarly
8119     * Special handling for semicolons after END statements
8120     * Token Chain Management:
8121     * Preserves original quotes as space tokens
8122     * Maintains proper token positioning and chaining
8123     * Resets the token chain to ensure correct output during toString() operations
8124     * Implementation Details
8125     * Processes statements in reverse order to maintain correct token positions
8126     * Uses TBaseType.getStringInsideLiteral() to extract content between quotes
8127     * Marks original dollar-quoted tokens as deleted (using tsdeleted)
8128     * Handles multi-line SQL blocks within stored procedure/function bodies
8129     */
8130    void expandDollarString(){
8131        // snowflake, expand dollar string into token list
8132        TSourceToken st;
8133        TCustomSqlStatement sql;
8134        ArrayList<TSourceToken> dollarTokens = new ArrayList<>();
8135        boolean isSQLLanguage = true;
8136
8137        // Iterate all create procedrue and create function, other sql staetment just skipped
8138        for(int i=0;i<sqlstatements.size();i++){
8139            sql = sqlstatements.get(i);
8140            if (!((sql.sqlstatementtype == sstcreateprocedure)||(sql.sqlstatementtype == sstcreatefunction))) continue;
8141            isSQLLanguage = true;
8142            for(int j=0;j<sql.sourcetokenlist.size();j++){
8143                st = sql.sourcetokenlist.get(j);
8144
8145                if (sql.sqlstatementtype == sstcreateprocedure){
8146                    if (st.tokencode == TBaseType.rrw_snowflake_language){
8147                        TSourceToken lang = st.nextSolidToken();
8148                        if ((lang != null)&&(!lang.toString().equalsIgnoreCase("sql"))){
8149                            isSQLLanguage = false;
8150                        }
8151                    }
8152                }
8153
8154                if (!isSQLLanguage) break;
8155
8156                if (st.tokencode == TBaseType.sconst){
8157                    if (st.toString().startsWith("$$")){
8158                        dollarTokens.add(st); // TODO: 可能会有多个 $$ token? 这种情况再哪个场景下会出现?需要找到对应的测试用例和SQL脚本。否则,uncomment next line
8159                        // break; // only one $$ token per sql, if we found one, then just break this sql and continue for next sql
8160                    }else if (st.toString().startsWith("'")){
8161                        // https://docs.snowflake.com/en/sql-reference/sql/create-procedure
8162                        // string literal delimiter can be $ or '
8163                        if (st.prevSolidToken().tokencode == TBaseType.rrw_as){
8164                            dollarTokens.add(st); // TODO: 可能会有多个 $$ token? 这种情况再哪个场景下会出现?需要找到对应的测试用例和SQL脚本。否则,uncomment next line
8165                            // break; // only one single quote token per sql, if we found one, then just break this sql and continue for next sql
8166                        }
8167                    }
8168                }
8169            }//check tokens
8170
8171            for(int m= dollarTokens.size() - 1; m>=0;m--){
8172
8173                // Token Expansion:
8174                // For each identified string literal:
8175                // Extracts the content between the quotes
8176                // Tokenizes the extracted SQL code
8177                // Verifies it's a valid code block (starts with DECLARE or BEGIN)
8178                // Replaces the original quoted string with expanded tokens in the source token list
8179
8180                st = dollarTokens.get(m);
8181
8182                TGSqlParser parser = new TGSqlParser(this.dbVendor);
8183                //parser.sqltext = TBaseType.stringBlock((int)st.lineNo - 1,(int)st.columnNo)+ TBaseType.getStringInsideLiteral(st.toString());
8184                // 如果在前面补充空行,会导致 toString() 重新拼接时多出空行;
8185                // 同时,因为不需要进行解析,所以不需要在前面补充空行以获得准确的错误定位? 这个说法是错误的,因为不加需要的空行,会导致定位不准确 #TODO
8186                parser.sqltext = TBaseType.getStringInsideLiteral(st.toString()); 
8187                TSourceToken startQuote = new TSourceToken(st.toString().substring(0,1));
8188                startQuote.tokencode = TBaseType.lexspace; // 设置为 space,可以在解析时忽略该token,同时在 toString() 时会被原样输出
8189                TSourceToken endQuote = new TSourceToken(st.toString().substring(0,1));
8190                endQuote.tokencode = TBaseType.lexspace;
8191
8192                // use getrawsqlstatements() instead of tokenizeSqltext() to get the source token list because
8193                // some token will be transformed to other token, which will be processed in dosnowflakegetrawsqlstatements()
8194                parser.getrawsqlstatements();
8195                //parser.tokenizeSqltext();
8196
8197                TSourceToken st2;
8198                boolean isValidBlock = false;
8199                for(int k=0;k<parser.sourcetokenlist.size();k++){
8200                    st2 = parser.sourcetokenlist.get(k);
8201                    if (st2.isnonsolidtoken()) continue;
8202                    if ((st2.tokencode == TBaseType.rrw_declare)||(st2.tokencode == TBaseType.rrw_begin)){
8203                        isValidBlock = true;
8204                    }else{
8205                        //
8206                    }
8207                    break;
8208                    //System.out.println(st2.lineNo+","+st2.columnNo+":"+st2.toString());
8209                }
8210
8211                if (isValidBlock){
8212                    TSourceToken semiColon = null;
8213                    st.tokenstatus = ETokenStatus.tsdeleted;
8214                    int startPosOfThisSQl = sql.getStartToken().posinlist;
8215
8216                    sql.sourcetokenlist.add((st.posinlist++) - startPosOfThisSQl,startQuote); // 补上开始引号
8217                    for(int k=0;k<parser.sourcetokenlist.size();k++) {
8218                        st2 = parser.sourcetokenlist.get(k);
8219                        if (st2.tokencode == ';'){
8220                            semiColon = st2;
8221                            TSourceToken prevSolidToken = st2.prevSolidToken();
8222                            if ((prevSolidToken != null) && (prevSolidToken.tokencode == TBaseType.rrw_begin)){
8223                                // begin;  => begin transaction;
8224                                prevSolidToken.tokencode = TBaseType.rrw_snowflake_begin_transaction;
8225                            }
8226                        }
8227                        if ((st2.tokencode == TBaseType.rrw_snowflake_work)||(st2.tokencode == TBaseType.rrw_snowflake_transaction)){
8228                            // begin work;  => begin transaction;
8229                            TSourceToken prevSolidToken = st2.prevSolidToken();
8230                            if ((prevSolidToken != null) && (prevSolidToken.tokencode == TBaseType.rrw_begin)){
8231                                // begin;  => begin transaction;
8232                                prevSolidToken.tokencode = TBaseType.rrw_snowflake_begin_transaction;
8233                            }
8234                        }
8235                        sql.sourcetokenlist.add( (st.posinlist++) - startPosOfThisSQl,st2);
8236                        //st.posinlist++;
8237                    }
8238                    if (semiColon != null){
8239                        if (semiColon.prevSolidToken().tokencode == TBaseType.rrw_end){
8240                            // 设置为 space,可以在解析时忽略该token,同时在 toString() 时会被原样输出
8241                            // semiColon.tokenstatus = ETokenStatus.tsdeleted;
8242                            semiColon.tokencode = TBaseType.lexspace;
8243                        }
8244                    }
8245
8246                    sql.sourcetokenlist.add( (st.posinlist++) - startPosOfThisSQl,endQuote); // 补上结束引号
8247                    TBaseType.resetTokenChain(sql.sourcetokenlist,0); // 重新设置token链,确保新插入的token在 toString() 时能被访问到,从而确保 toString() 输出正确结果
8248                }
8249            }
8250
8251            dollarTokens.clear();
8252        }//statement
8253
8254    }
8255
8256int dosnowflakegetrawsqlstatements(){
8257    int waitingEnd = 0;
8258    boolean foundEnd = false;
8259
8260    int waitingEnds[] = new int[stored_procedure_nested_level];
8261    stored_procedure_type sptype[] = new stored_procedure_type[stored_procedure_nested_level];
8262    stored_procedure_status procedure_status[] = new stored_procedure_status[stored_procedure_nested_level];
8263    boolean endBySlashOnly = true;
8264    int nestedProcedures = 0, nestedParenthesis = 0;
8265    boolean inDollarBody = false;
8266
8267    if ( TBaseType.assigned(sqlstatements) ) sqlstatements.clear();
8268    if ( ! TBaseType.assigned(sourcetokenlist) ) return -1;
8269
8270    gcurrentsqlstatement = null;
8271    EFindSqlStateType gst = EFindSqlStateType.stnormal;
8272    TSourceToken lcprevsolidtoken = null,ast = null;
8273
8274    for (int i=0 ; i < sourcetokenlist.size();i++)
8275      {
8276
8277          if ( (ast != null ) && (ast.issolidtoken() ))
8278            lcprevsolidtoken = ast;
8279
8280        ast = sourcetokenlist.get(i);
8281        sourcetokenlist.curpos = i;
8282
8283        if ((ast.tokencode == TBaseType.rrw_right)||(ast.tokencode == TBaseType.rrw_left)){
8284          TSourceToken stLparen  = ast.searchToken('(',1);
8285          if (stLparen != null){   //match (
8286              ast.tokencode = TBaseType.ident;
8287          }
8288          TSourceToken stNextToken = ast.nextSolidToken();
8289          if ((stNextToken != null) && ((stNextToken.tokencode == TBaseType.rrw_join)||(stNextToken.tokencode == TBaseType.rrw_outer))){
8290            if (ast.tokencode == TBaseType.rrw_left){
8291                ast.tokencode = TBaseType.rrw_snowflake_left_join;
8292            }else{
8293                ast.tokencode = TBaseType.rrw_snowflake_right_join;
8294            }
8295          }
8296        }else if (ast.tokencode == TBaseType.rrw_snowflake_at){
8297            TSourceToken stLparen  = ast.searchToken('(',1);
8298            if (stLparen != null){   //match (
8299                ast.tokencode = TBaseType.rrw_snowflake_at_before_parenthesis;
8300            }
8301        }else if (ast.tokencode == TBaseType.rrw_date){
8302            TSourceToken stLparen  = ast.searchToken('(',1);
8303            if (stLparen != null){   //date (
8304                ast.tokencode = TBaseType.rrw_snowflake_date;
8305            }else {
8306                stLparen  = ast.searchToken('.',1);
8307                if (stLparen != null){   //date (
8308                    ast.tokencode = TBaseType.ident;
8309                }
8310            }
8311        }else if (ast.tokencode == TBaseType.rrw_time){
8312            TSourceToken stLparen  = ast.searchToken('(',1);
8313            if (stLparen != null){   //date (
8314                ast.tokencode = TBaseType.rrw_snowflake_time;
8315            }else {
8316                stLparen  = ast.searchToken('.',1);
8317                if (stLparen != null){   //date (
8318                    ast.tokencode = TBaseType.ident;
8319                }
8320            }
8321        }else if (ast.tokencode == TBaseType.rrw_char){
8322            TSourceToken stLparen  = ast.searchToken('(',1);
8323            if (stLparen != null){   //date (
8324                ast.tokencode = TBaseType.rrw_snowflake_char;
8325            }else {
8326                stLparen  = ast.searchToken('.',1);
8327                if (stLparen != null){   //date (
8328                    ast.tokencode = TBaseType.ident;
8329                }
8330            }
8331        }else if (ast.tokencode == TBaseType.rrw_snowflake_window){
8332            TSourceToken stAs  = ast.searchToken(TBaseType.rrw_as,2);
8333            if (stAs != null){   //date (
8334                ast.tokencode = TBaseType.rrw_snowflake_window_as;
8335            }else {
8336            }
8337        }else if ((ast.tokencode == TBaseType.rrw_snowflake_pivot)||(ast.tokencode == TBaseType.rrw_snowflake_unpivot)){
8338            TSourceToken stLparen  = ast.searchToken('(',1);
8339            if (stLparen != null){   //pivot (, unpivot
8340
8341            }else {
8342                ast.tokencode = TBaseType.ident;
8343            }
8344        }else if (ast.tokencode == TBaseType.rrw_snowflake_flatten){
8345            TSourceToken stLeftParens  = ast.searchToken('(',1);
8346            if (stLeftParens != null){   //flatten (
8347
8348            }else {
8349                ast.tokencode = TBaseType.ident; // change it to an identifier, can be used as db object name.
8350            }
8351        }else if (ast.tokencode == TBaseType.rrw_snowflake_offset){
8352            TSourceToken stFrom  = ast.searchToken(TBaseType.rrw_from,-ast.posinlist,TBaseType.rrw_select,true);
8353            if (stFrom == null){
8354                // FORM keyword before OFFSET is not found, then offset must be a column name,
8355                // just like this: SELECT column1 offset FROM table2
8356                ast.tokencode = TBaseType.ident; // change it to an identifier, can be used as db object name.
8357            }
8358        }else if (ast.tokencode == TBaseType.rrw_replace){
8359            TSourceToken stStar  = ast.prevSolidToken();
8360            if (stStar.tokencode == '*'){
8361                ast.tokencode = TBaseType.rrw_snowflake_replace_after_star;
8362            }
8363        }else if (ast.tokencode == TBaseType.rrw_snowflake_transaction) {
8364            TSourceToken stBegin = ast.prevSolidToken();
8365            if ((stBegin != null) && (stBegin.tokencode == TBaseType.rrw_begin)) {
8366                stBegin.tokencode = TBaseType.rrw_snowflake_begin_transaction;
8367            }
8368        }else if (ast.tokencode == TBaseType.rrw_begin){
8369            TSourceToken stNext  = ast.nextSolidToken();
8370            if ((stNext != null) && ((stNext.tokencode == ';')
8371                        ||(stNext.tokencode == TBaseType.rrw_snowflake_work)||(stNext.tokencode == TBaseType.rrw_snowflake_transaction))
8372            ){
8373                ast.tokencode = TBaseType.rrw_snowflake_begin_transaction;
8374            }
8375        }else if ((ast.tokencode == TBaseType.rrw_snowflake_top)||(ast.tokencode == TBaseType.rrw_text)||(ast.tokencode == TBaseType.rrw_snowflake_default)){
8376            TSourceToken stPeriod  = ast.nextSolidToken();
8377            if ((stPeriod != null) && (stPeriod.tokencode == '.')){
8378                ast.tokencode = TBaseType.ident;
8379            }
8380        }else if (ast.tokencode == TBaseType.rrw_snowflake_limit){
8381            TSourceToken stPrev  = ast.prevSolidToken();
8382            if ((stPrev != null) && (stPrev.tokencode == ',')){
8383                ast.tokencode = TBaseType.ident;
8384            }            
8385        }else if (ast.tokencode == TBaseType.ident){
8386            // check whether it is a snowflake parameter name
8387            // 这个调用可能会有性能问题,因为每个ident都会调用一次
8388            if (TSnowflakeParameterChecker.isSnowflakeParameter(ast.toString())){
8389                ast.tokencode = TBaseType.rrw_snowflake_parameter_name;
8390            }
8391        }
8392
8393
8394        switch(gst){
8395            case sterror:{
8396                if (ast.tokentype ==  ETokenType.ttsemicolon)
8397                {
8398                    gcurrentsqlstatement.sourcetokenlist.add(ast);
8399                    doongetrawsqlstatementevent(gcurrentsqlstatement);
8400                    gst = EFindSqlStateType.stnormal;
8401                }
8402                else
8403                {
8404                    gcurrentsqlstatement.sourcetokenlist.add(ast);
8405                }
8406                break;
8407            } //sterror
8408
8409            case stnormal:{
8410                if ((ast.tokencode  == TBaseType.cmtdoublehyphen)
8411                   || (ast.tokencode  == TBaseType.cmtslashstar)
8412                   || (ast.tokencode  == TBaseType.lexspace)
8413                   || (ast.tokencode  == TBaseType.lexnewline)
8414                   || (ast.tokentype  == ETokenType.ttsemicolon) )
8415                {
8416                   if (gcurrentsqlstatement != null)
8417                   {
8418                       gcurrentsqlstatement.addtokentolist(ast);
8419                   }
8420
8421                   if ((lcprevsolidtoken != null) && (ast.tokentype == ETokenType.ttsemicolon))
8422                   {
8423                       if (lcprevsolidtoken.tokentype == ETokenType.ttsemicolon )
8424                       {
8425                          // ;;;; continuous semicolon,treat it as comment
8426                           ast.tokentype = ETokenType.ttsimplecomment;
8427                           ast.tokencode =  TBaseType.cmtdoublehyphen;
8428                       }
8429                   }
8430
8431                   continue;
8432                }
8433
8434                if (ast.tokencode == TBaseType.sqlpluscmd )
8435                {
8436                    gst = EFindSqlStateType.stsqlplus;
8437                    gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
8438                    gcurrentsqlstatement.addtokentolist(ast);
8439                    continue;
8440                }
8441
8442                // find a tokentext to start sql or plsql mode
8443                gcurrentsqlstatement = sqlcmds.issql(ast, dbVendor,gst,gcurrentsqlstatement);
8444
8445                if (gcurrentsqlstatement != null)
8446                {
8447                    if (gcurrentsqlstatement.issnowflakeplsql())
8448                    {
8449                        nestedProcedures = 0;
8450                        gst = EFindSqlStateType.ststoredprocedure;
8451                        gcurrentsqlstatement.addtokentolist(ast);
8452
8453                        switch (gcurrentsqlstatement.sqlstatementtype){
8454                            case sstplsql_createprocedure:
8455                            case sstcreateprocedure:
8456                                sptype[nestedProcedures] = stored_procedure_type.procedure;
8457                                break;
8458                            case sstplsql_createfunction:
8459                                sptype[nestedProcedures] = stored_procedure_type.function;
8460                                break;
8461                            case sstplsql_createpackage:
8462                                sptype[nestedProcedures] = stored_procedure_type.package_spec;
8463                                if (ast.searchToken(TBaseType.rrw_body,5) != null){
8464                                    sptype[nestedProcedures] = stored_procedure_type.package_body;
8465                                }
8466                                break;
8467                            case sst_plsql_block:
8468                                sptype[nestedProcedures] = stored_procedure_type.block_with_declare;
8469                                if (ast.tokencode == TBaseType.rrw_begin) {
8470                                    sptype[nestedProcedures] = stored_procedure_type.block_with_begin;
8471                                }
8472                                break;
8473                            case sstplsql_createtrigger:
8474                                sptype[nestedProcedures] = stored_procedure_type.create_trigger;
8475                                break;
8476                            case sstoraclecreatelibrary:
8477                                sptype[nestedProcedures] = stored_procedure_type.create_library;
8478                                break;
8479                            case sstplsql_createtype_placeholder:
8480                                gst = EFindSqlStateType.stsql;
8481                                break;
8482                            default:
8483                                sptype[nestedProcedures] = stored_procedure_type.others;
8484                                break;
8485                        }
8486
8487                        if (sptype[0] == stored_procedure_type.block_with_declare){
8488                            // sd
8489                            endBySlashOnly = false;
8490                            procedure_status[0] = stored_procedure_status.is_as;
8491                        }else if (sptype[0] == stored_procedure_type.block_with_begin){
8492                            // sb
8493                            endBySlashOnly = false;
8494                            procedure_status[0] = stored_procedure_status.body;
8495                        }else if (sptype[0] == stored_procedure_type.procedure){
8496                            // ss
8497                            endBySlashOnly = false;
8498                            procedure_status[0] = stored_procedure_status.start;
8499                        }else if (sptype[0] == stored_procedure_type.function){
8500                            // ss
8501                            endBySlashOnly = false;
8502                            procedure_status[0] = stored_procedure_status.start;
8503                        }else if (sptype[0] == stored_procedure_type.package_spec){
8504                            // ss
8505                            endBySlashOnly = false;
8506                            procedure_status[0] = stored_procedure_status.start;
8507                        }else if (sptype[0] == stored_procedure_type.package_body){
8508                            // ss
8509                            endBySlashOnly = false;
8510                            procedure_status[0] = stored_procedure_status.start;
8511                        }else if (sptype[0] == stored_procedure_type.create_trigger){
8512                            // ss
8513                            endBySlashOnly = false;
8514                            procedure_status[0] = stored_procedure_status.start;
8515                            //procedure_status[0] = stored_procedure_status.body;
8516                        }else if (sptype[0] == stored_procedure_type.create_library){
8517                            // ss
8518                            endBySlashOnly = false;
8519                            procedure_status[0] = stored_procedure_status.bodyend;
8520                        }else {
8521                            // so
8522                            endBySlashOnly = true;
8523                            procedure_status[0] = stored_procedure_status.bodyend;
8524                        }
8525                        //foundEnd = false;
8526                        if   ((ast.tokencode == TBaseType.rrw_begin)
8527                                ||(ast.tokencode == TBaseType.rrw_package)
8528                                //||(ast.tokencode == TBaseType.rrw_procedure)
8529                                || (ast.searchToken(TBaseType.rrw_package,4) != null)
8530                        )
8531                        {
8532                            //waitingEnd = 1;
8533                            waitingEnds[nestedProcedures] = 1;
8534                        }
8535
8536                    }
8537                    else
8538                    {
8539                        gst = EFindSqlStateType.stsql;
8540                        gcurrentsqlstatement.addtokentolist(ast);
8541                    }
8542                }else{
8543                    //error tokentext found
8544
8545                    this.syntaxErrors.add( new TSyntaxError(ast.astext,ast.lineNo,(ast.columnNo < 0 ? 0:ast.columnNo)
8546                            ,"Error when tokenlize", EErrorType.spwarning,TBaseType.MSG_WARNING_ERROR_WHEN_TOKENIZE,null,ast.posinlist));
8547
8548                    ast.tokentype = ETokenType.tttokenlizererrortoken;
8549                    gst = EFindSqlStateType.sterror;
8550
8551                    gcurrentsqlstatement = new TUnknownSqlStatement(dbVendor);
8552                    gcurrentsqlstatement.sqlstatementtype = ESqlStatementType.sstinvalid;
8553                    gcurrentsqlstatement.addtokentolist(ast);
8554
8555                }
8556
8557                break;
8558            } // stnormal
8559
8560            case stsqlplus:{
8561                if  (ast.insqlpluscmd)
8562                {gcurrentsqlstatement.addtokentolist(ast);}
8563                else
8564                {
8565                    gst = EFindSqlStateType.stnormal; //this tokentext must be newline,
8566                    gcurrentsqlstatement.addtokentolist(ast); // so add it here
8567                    doongetrawsqlstatementevent(gcurrentsqlstatement);
8568                }
8569
8570                break;
8571            }//case stsqlplus
8572
8573            case stsql:{
8574                if (gcurrentsqlstatement instanceof TRoutine){
8575                    if (isDollarFunctionDelimiter(ast.tokencode,this.dbVendor)){
8576                        if (inDollarBody){
8577                            inDollarBody = false;
8578                        }else{
8579                            inDollarBody = true;
8580                        }
8581                    }
8582
8583                    if (inDollarBody) {
8584                        gcurrentsqlstatement.addtokentolist(ast);
8585                        continue;
8586                    }
8587                }else if (gcurrentsqlstatement instanceof TCreateTaskStmt){
8588                    if (ast.tokencode == TBaseType.rrw_as){
8589                        TSourceToken tmpNext = ast.nextSolidToken();
8590                        if ((tmpNext != null)&&(tmpNext.tokencode == TBaseType.rrw_begin)){
8591                            // begin ... end block in create task statement, mantisbt/view.php?id=3531
8592
8593                            gst = EFindSqlStateType.ststoredprocedure;
8594                            nestedProcedures = 0;
8595                            procedure_status[nestedProcedures] = stored_procedure_status.body;
8596                            waitingEnds[nestedProcedures] = 0;
8597                            gcurrentsqlstatement.addtokentolist(ast);
8598                            continue;
8599                        }
8600                    }
8601                }
8602
8603                if (ast.tokentype == ETokenType.ttsemicolon)
8604                {
8605                    gst = EFindSqlStateType.stnormal;
8606                    gcurrentsqlstatement.addtokentolist(ast);
8607                    gcurrentsqlstatement.semicolonended = ast;
8608                    doongetrawsqlstatementevent(gcurrentsqlstatement);
8609                    continue;
8610                }
8611
8612                if  (sourcetokenlist.sqlplusaftercurtoken() ) //most probaly is / cmd
8613                {
8614                    gst = EFindSqlStateType.stnormal;
8615                    gcurrentsqlstatement.addtokentolist(ast);
8616                    doongetrawsqlstatementevent(gcurrentsqlstatement);
8617                    continue;
8618                }
8619                gcurrentsqlstatement.addtokentolist(ast);
8620                break;
8621            }//case stsql
8622
8623            case ststoredprocedure:
8624            {
8625                if (procedure_status[nestedProcedures] != stored_procedure_status.bodyend){
8626                    gcurrentsqlstatement.addtokentolist(ast);
8627                }
8628
8629                switch (procedure_status[nestedProcedures]){
8630                    case start:
8631                        if ((ast.tokencode == TBaseType.rrw_as)||(ast.tokencode == TBaseType.rrw_is)){
8632                            // s1
8633                            if (sptype[nestedProcedures] != stored_procedure_type.create_trigger){
8634                                if ((sptype[0] == stored_procedure_type.package_spec) && (nestedProcedures > 0)){
8635                                    //when it's a package specification, only top level accept as/is
8636                                }else{
8637                                    procedure_status[nestedProcedures] = stored_procedure_status.is_as;
8638                                    if (ast.searchToken("language",1) != null){
8639                                        // if as language is used in create function, then switch state to stored_procedure_status.body directly.
8640//                                        CREATE OR REPLACE FUNCTION THING.addressparse(p_addressline1 VARCHAR2) RETURN VARCHAR2 AUTHID DEFINER
8641//                                        as Language JAVA NAME 'AddressParser.parse(java.lang.String) return java.lang.String';
8642//                                        /
8643                                        if (nestedProcedures == 0){
8644                                            //  procedure_status[nestedProcedures] = stored_procedure_status.bodyend;
8645                                            gst = EFindSqlStateType.stsql;
8646                                        }else{
8647                                            procedure_status[nestedProcedures] = stored_procedure_status.body;
8648                                            nestedProcedures--;
8649                                            //if (nestedProcedures > 0){ nestedProcedures--;}
8650                                        }
8651
8652                                    }
8653                                }
8654                            }
8655                        }else if(ast.tokencode == TBaseType.rrw_begin){
8656                            // s4
8657                            if (sptype[nestedProcedures] == stored_procedure_type.create_trigger) waitingEnds[nestedProcedures]++;
8658
8659                            if (nestedProcedures > 0) {nestedProcedures--;}
8660                            procedure_status[nestedProcedures] = stored_procedure_status.body;
8661                        }else if(ast.tokencode == TBaseType.rrw_end){
8662                            //s10
8663                            if((nestedProcedures > 0)&&(waitingEnds[nestedProcedures - 1] == 1)
8664                                    &&((sptype[nestedProcedures - 1] == stored_procedure_type.package_body)
8665                                    ||(sptype[nestedProcedures - 1] == stored_procedure_type.package_spec))){
8666                                nestedProcedures--;
8667                                procedure_status[nestedProcedures] = stored_procedure_status.bodyend;
8668                            }
8669                        }else if((ast.tokencode == TBaseType.rrw_procedure)||(ast.tokencode == TBaseType.rrw_function)){
8670                            //s3
8671                            if((nestedProcedures > 0)&&(waitingEnds[nestedProcedures] == 0)
8672                                    &&(procedure_status[nestedProcedures - 1] == stored_procedure_status.is_as)){
8673                                nestedProcedures--;
8674                                nestedProcedures++;
8675                                waitingEnds[nestedProcedures] = 0;
8676                                procedure_status[nestedProcedures] = stored_procedure_status.start;
8677                            }
8678                        }else if ((sptype[nestedProcedures] == stored_procedure_type.create_trigger) && (ast.tokencode == TBaseType.rrw_declare) )
8679                        {
8680                            procedure_status[nestedProcedures] = stored_procedure_status.is_as;
8681                        }else if ((sptype[nestedProcedures] == stored_procedure_type.create_trigger)&&(ast.tokentype == ETokenType.ttslash)  && (ast.tokencode == TBaseType.sqlpluscmd) )
8682                        {
8683                            // TPlsqlStatementParse(asqlstatement).TerminatorToken := ast;
8684                            ast.tokenstatus = ETokenStatus.tsignorebyyacc;
8685                            gst = EFindSqlStateType.stnormal;
8686                            doongetrawsqlstatementevent(gcurrentsqlstatement);
8687
8688                            //make / a sqlplus cmd
8689                            gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
8690                            gcurrentsqlstatement.addtokentolist(ast);
8691                            doongetrawsqlstatementevent(gcurrentsqlstatement);
8692                        }else if ((sptype[nestedProcedures] == stored_procedure_type.create_trigger) )
8693                        {
8694                            if (ast.tokencode == TBaseType.rrw_trigger){
8695                                TSourceToken compoundSt =  ast.searchToken(TBaseType.rrw_oracle_compound, -1);
8696                                if (compoundSt != null){
8697                                    //it's trigger with compound trigger block
8698                                    procedure_status[nestedProcedures] = stored_procedure_status.body;
8699                                    waitingEnds[nestedProcedures]++;
8700                                }
8701                            }
8702                        }else if ((sptype[nestedProcedures] == stored_procedure_type.function)&&(ast.tokencode == TBaseType.rrw_teradata_using) )
8703                        {
8704                            if ((ast.searchToken("aggregate",-1) != null)||(ast.searchToken("pipelined",-1) != null)){
8705                                if (nestedProcedures == 0){
8706                                    //  procedure_status[nestedProcedures] = stored_procedure_status.bodyend;
8707                                    gst = EFindSqlStateType.stsql;
8708                                }else{
8709                                    procedure_status[nestedProcedures] = stored_procedure_status.body;
8710                                    nestedProcedures--;
8711                                }
8712                            }
8713
8714                        }else{
8715                            //other tokens, do nothing
8716                            if (ast.tokencode == TBaseType.rrw_snowflake_language){
8717                                // check next token which is the language used by this stored procedure
8718                                TSourceToken nextSt = ast.nextSolidToken();
8719                                if (nextSt != null){
8720                                    if (gcurrentsqlstatement instanceof TRoutine){  // can be TCreateProcedureStmt or TCreateFunctionStmt
8721                                        TRoutine p = (TRoutine) gcurrentsqlstatement;
8722                                        p.setRoutineLanguage(nextSt.toString());
8723                                        //System.out.println("Find snowflake procedure language: "+p.getRoutineLanguage());
8724                                        if (p.getRoutineLanguage().toString().equalsIgnoreCase("javascript")){
8725                                            // procedure 中出现 javascript, 则碰到 semicolon 可能是整个 procedure 语句解释,因此可以设为 stsql 状态
8726                                            // 但因为 $$body$$ 已经被解析为分离的token,因此需要在 stsql 中忽略这些$$body$$中的token
8727                                             gst = EFindSqlStateType.stsql;
8728                                        }
8729                                    }
8730                                }
8731                            }
8732                        }
8733                        break;
8734                    case is_as:
8735                        if((ast.tokencode == TBaseType.rrw_procedure)||(ast.tokencode == TBaseType.rrw_function)){
8736                            // s2
8737                            nestedProcedures++;
8738                            waitingEnds[nestedProcedures] = 0;
8739                            procedure_status[nestedProcedures] = stored_procedure_status.start;
8740
8741                            if (nestedProcedures > stored_procedure_nested_level - 1){
8742                                gst = EFindSqlStateType.sterror;
8743                                nestedProcedures--;
8744                            }
8745
8746                        }else if(ast.tokencode == TBaseType.rrw_begin){
8747                            // s5
8748                            if ((nestedProcedures == 0)&&
8749                                    ((sptype[nestedProcedures]==stored_procedure_type.package_body)
8750                                            ||(sptype[nestedProcedures]==stored_procedure_type.package_spec))){
8751                                //top level package or package body's BEGIN keyword already count,
8752                                // so don't increase waitingEnds[nestedProcedures] here
8753
8754                            }else {
8755                                waitingEnds[nestedProcedures]++;
8756                            }
8757                            procedure_status[nestedProcedures] = stored_procedure_status.body;
8758                        }else if(ast.tokencode == TBaseType.rrw_end){
8759                            // s6
8760                            if ((nestedProcedures == 0)&&(waitingEnds[nestedProcedures] == 1)&&
8761                                    ((sptype[nestedProcedures]==stored_procedure_type.package_body)||(sptype[nestedProcedures]==stored_procedure_type.package_spec))){
8762                                procedure_status[nestedProcedures] = stored_procedure_status.bodyend;
8763                                waitingEnds[nestedProcedures]--;
8764                            }else{
8765                                waitingEnds[nestedProcedures]--;
8766                            }
8767                        }else if(ast.tokencode == TBaseType.rrw_case)
8768                        {
8769//                            if (ast.searchToken(TBaseType.rrw_end,-1) == null){
8770//                                //this is not case after END
8771//                             waitingEnds[nestedProcedures]++;
8772//                            }
8773                            if (ast.searchToken(';',1) == null){
8774                                //this is not case before ;
8775                                waitingEnds[nestedProcedures]++;
8776                            }
8777                        }
8778                        else {
8779                            //other tokens, do nothing
8780                        }
8781                        break;
8782                    case body:
8783                        if ((ast.tokencode == TBaseType.rrw_begin))
8784                        {
8785                            waitingEnds[nestedProcedures]++;
8786                        }
8787                        else if (ast.tokencode == TBaseType.rrw_if)
8788                        {
8789                             if (ast.searchToken(TBaseType.rrw_snowflake_exists,1) != null){
8790                                 //drop table if exists SANDBOX.ANALYSIS_CONTENT.TABLEAU_DATES;
8791                                 // don't need END for the above if exists clause
8792                            }
8793                            else if (ast.searchToken(';',2) == null){
8794                                //this is not if before ;
8795
8796                                // 2015-02-27, change 1 to 2 make it able to detect label name after case
8797                                // like this: END CASE l1;
8798                                waitingEnds[nestedProcedures]++;
8799                            }
8800                        }
8801                        else if (ast.tokencode == TBaseType.rrw_for)
8802                        {
8803                            if (ast.searchToken(';',2) == null){
8804                                //this is not for before ;
8805
8806                                // 2015-02-27, change 1 to 2 make it able to detect label name after case
8807                                // like this: END CASE l1;
8808                                waitingEnds[nestedProcedures]++;
8809                            }
8810                        }
8811                        else if(ast.tokencode == TBaseType.rrw_case)
8812                        {
8813//                            if (ast.searchToken(TBaseType.rrw_end,-1) == null){
8814//                                //this is not case after END
8815//                             waitingEnds[nestedProcedures]++;
8816//                            }
8817                            if (ast.searchToken(';',2) == null){
8818                                //this is not case before ;
8819                                if (ast.searchToken(TBaseType.rrw_end,-1) == null){
8820                                    waitingEnds[nestedProcedures]++;
8821                                }
8822                            }
8823                        } else if(ast.tokencode == TBaseType.rrw_loop)
8824                        {
8825                            if (!((ast.searchToken(TBaseType.rrw_end,-1) != null)
8826                                    &&(ast.searchToken(';',2) != null))){
8827                                // exclude loop like this:
8828                                // end loop [labelname];
8829                                waitingEnds[nestedProcedures]++;
8830                            }
8831
8832//                            if (ast.searchToken(TBaseType.rrw_end,-1) == null){
8833//                                //this is not loop after END
8834//                             waitingEnds[nestedProcedures]++;
8835////                            }
8836////                            if (ast.searchToken(';',2) == null){
8837////                                //this is no loop before ;
8838////                             waitingEnds[nestedProcedures]++;
8839//                            } else if (ast.searchToken(TBaseType.rrw_null,1) != null){
8840//                                // mantis bug tracking system:   #65
8841//                                waitingEnds[nestedProcedures]++;
8842//                            }
8843                        }else if (ast.tokencode == TBaseType.rrw_end){
8844                            //foundEnd = true;
8845                            waitingEnds[nestedProcedures]--;
8846                            //if (waitingEnd < 0) { waitingEnd = 0;}
8847                            if (waitingEnds[nestedProcedures] == 0){
8848                                if (nestedProcedures == 0){
8849                                    // s7
8850                                    procedure_status[nestedProcedures] = stored_procedure_status.bodyend;
8851                                }else {
8852                                    // s71
8853                                    nestedProcedures--;
8854                                    procedure_status[nestedProcedures] = stored_procedure_status.is_as;
8855                                }
8856                            }
8857                        }else  if ((waitingEnds[nestedProcedures] == 0)&&(ast.tokentype == ETokenType.ttslash)  && (ast.tokencode == TBaseType.sqlpluscmd) ) //and (prevst.NewlineIsLastTokenInTailerToken)) then
8858                        {
8859                            //sql ref: c:\prg\gsqlparser\Test\TestCases\oracle\createtrigger.sql, line 53
8860                            ast.tokenstatus = ETokenStatus.tsignorebyyacc;
8861                            gst = EFindSqlStateType.stnormal;
8862                            doongetrawsqlstatementevent(gcurrentsqlstatement);
8863
8864                            //make / a sqlplus cmd
8865                            gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
8866                            gcurrentsqlstatement.addtokentolist(ast);
8867                            doongetrawsqlstatementevent(gcurrentsqlstatement);
8868                        }
8869                        break;
8870                    case bodyend:
8871                        if ((ast.tokentype == ETokenType.ttslash)  && (ast.tokencode == TBaseType.sqlpluscmd) ) //and (prevst.NewlineIsLastTokenInTailerToken)) then
8872                        {
8873                            // TPlsqlStatementParse(asqlstatement).TerminatorToken := ast;
8874                            ast.tokenstatus = ETokenStatus.tsignorebyyacc;
8875                            gst = EFindSqlStateType.stnormal;
8876                            doongetrawsqlstatementevent(gcurrentsqlstatement);
8877
8878                            //make / a sqlplus cmd
8879                            gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
8880                            gcurrentsqlstatement.addtokentolist(ast);
8881                            doongetrawsqlstatementevent(gcurrentsqlstatement);
8882                        } else  if ((ast.tokentype == ETokenType.ttperiod)  && (sourcetokenlist.returnaftercurtoken(false)) && (sourcetokenlist.returnbeforecurtoken(false)))
8883                        {    // single dot at a seperate line
8884                            ast.tokenstatus = ETokenStatus.tsignorebyyacc;
8885                            gst = EFindSqlStateType.stnormal;
8886                            doongetrawsqlstatementevent(gcurrentsqlstatement);
8887
8888                            //make ttperiod a sqlplus cmd
8889                            gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
8890                            gcurrentsqlstatement.addtokentolist(ast);
8891                            doongetrawsqlstatementevent(gcurrentsqlstatement);
8892                        } else  if ((ast.searchToken(TBaseType.rrw_package,1) != null)&&(!endBySlashOnly))
8893                        {
8894                            gcurrentsqlstatement.addtokentolist(ast);
8895                            gst = EFindSqlStateType.stnormal;
8896                            doongetrawsqlstatementevent(gcurrentsqlstatement);
8897                        } else  if ((ast.searchToken(TBaseType.rrw_procedure,1) != null)&&(!endBySlashOnly))
8898                        {
8899                            gcurrentsqlstatement.addtokentolist(ast);
8900                            gst = EFindSqlStateType.stnormal;
8901                            doongetrawsqlstatementevent(gcurrentsqlstatement);
8902                        } else  if ((ast.searchToken(TBaseType.rrw_function,1) != null)&&(!endBySlashOnly))
8903                        {
8904                            gcurrentsqlstatement.addtokentolist(ast);
8905                            gst = EFindSqlStateType.stnormal;
8906                            doongetrawsqlstatementevent(gcurrentsqlstatement);
8907                        } else  if ((ast.searchToken(TBaseType.rrw_create,1) != null)&&(ast.searchToken(TBaseType.rrw_package,4) != null)&&(!endBySlashOnly))
8908                        {
8909                            gcurrentsqlstatement.addtokentolist(ast);
8910                            gst = EFindSqlStateType.stnormal;
8911                            doongetrawsqlstatementevent(gcurrentsqlstatement);
8912                        } else  if ((ast.searchToken(TBaseType.rrw_create,1) != null)&&(ast.searchToken(TBaseType.rrw_library,4) != null)&&(!endBySlashOnly))
8913                        {
8914                            gcurrentsqlstatement.addtokentolist(ast);
8915                            gst = EFindSqlStateType.stnormal;
8916                            doongetrawsqlstatementevent(gcurrentsqlstatement);
8917                        } else  if ((ast.searchToken(TBaseType.rrw_alter,1) != null)&&(ast.searchToken(TBaseType.rrw_trigger,2) != null)&&(!endBySlashOnly))
8918                        {
8919                            gcurrentsqlstatement.addtokentolist(ast);
8920                            gst = EFindSqlStateType.stnormal;
8921                            doongetrawsqlstatementevent(gcurrentsqlstatement);
8922                        } else  if ((ast.searchToken(TBaseType.rrw_select,1) != null)&&(!endBySlashOnly))
8923                        {
8924                            gcurrentsqlstatement.addtokentolist(ast);
8925                            gst = EFindSqlStateType.stnormal;
8926                            doongetrawsqlstatementevent(gcurrentsqlstatement);
8927                        } else  if ((ast.searchToken(TBaseType.rrw_commit,1) != null)&&(!endBySlashOnly))
8928                        {
8929                            gcurrentsqlstatement.addtokentolist(ast);
8930                            gst = EFindSqlStateType.stnormal;
8931                            doongetrawsqlstatementevent(gcurrentsqlstatement);
8932                        } else  if ((ast.searchToken(TBaseType.rrw_grant,1) != null)&&
8933                                (ast.searchToken(TBaseType.rrw_execute,2) != null)&&(!endBySlashOnly))
8934                        {
8935                            gcurrentsqlstatement.addtokentolist(ast);
8936                            gst = EFindSqlStateType.stnormal;
8937                            doongetrawsqlstatementevent(gcurrentsqlstatement);
8938                        } else if ((gcurrentsqlstatement instanceof TCreateTaskStmt)&&(ast.tokencode == ';')){
8939                            gcurrentsqlstatement.addtokentolist(ast);
8940                            gst = EFindSqlStateType.stnormal;
8941                            doongetrawsqlstatementevent(gcurrentsqlstatement);
8942                        }
8943                        else {
8944                            gcurrentsqlstatement.addtokentolist(ast);
8945                        }
8946                        break;
8947                    case end:
8948                        break;
8949                    default:
8950                        break;
8951                }
8952
8953
8954                if (ast.tokencode == TBaseType.sqlpluscmd)
8955                {
8956                    //change tokencode back to keyword or TBaseType.ident, because sqlplus cmd
8957                    //in a sql statement(almost is plsql block) is not really a sqlplus cmd
8958                    int m = flexer.getkeywordvalue(ast.astext);
8959                    if (m != 0)
8960                    {ast.tokencode = m;}
8961                    else if (ast.tokentype == ETokenType.ttslash){
8962                        ast.tokencode = '/';
8963                    }
8964                    else
8965                    {ast.tokencode = TBaseType.ident;}
8966                }
8967
8968                final int wrapped_keyword_max_pos = 20;
8969                if ((ast.tokencode == TBaseType.rrw_wrapped)&&(ast.posinlist - gcurrentsqlstatement.sourcetokenlist.get(0).posinlist  < wrapped_keyword_max_pos)){
8970                    if (gcurrentsqlstatement instanceof TCommonStoredProcedureSqlStatement){
8971                        ((TCommonStoredProcedureSqlStatement)gcurrentsqlstatement).setWrapped(true);
8972                    }
8973
8974                    if (gcurrentsqlstatement instanceof TPlsqlCreatePackage){
8975                        if (ast.prevSolidToken() != null){
8976                            ((TPlsqlCreatePackage) gcurrentsqlstatement).setPackageName(fparser.getNf().createObjectNameWithPart(ast.prevSolidToken()));
8977                        }
8978                    }
8979                }
8980
8981                break;
8982            } //ststoredprocedure
8983        } //switch
8984      }//for
8985
8986    //last statement
8987    if ((gcurrentsqlstatement != null) &&
8988        ((gst == EFindSqlStateType.stsqlplus) ||  (gst == EFindSqlStateType.stsql) || (gst == EFindSqlStateType.ststoredprocedure) ||
8989                    (gst == EFindSqlStateType.sterror)))
8990    {
8991        doongetrawsqlstatementevent(gcurrentsqlstatement);
8992    }
8993
8994  return syntaxErrors.size();
8995}
8996
8997int dogreenplumgetrawsqlstatements(){
8998        int waitingEnd = 0;
8999        boolean foundEnd = false,enterDeclare=false;
9000
9001        if ( TBaseType.assigned(sqlstatements) ) sqlstatements.clear();
9002        if ( ! TBaseType.assigned(sourcetokenlist) ) return -1;
9003
9004        gcurrentsqlstatement = null;
9005        EFindSqlStateType gst = EFindSqlStateType.stnormal;
9006        TSourceToken lcprevsolidtoken = null,ast = null;
9007        TSourceToken dollarStringToken = null;
9008
9009        for (int i=0 ; i < sourcetokenlist.size();i++)
9010          {
9011
9012              if ( (ast != null ) && (ast.issolidtoken() ))
9013                lcprevsolidtoken = ast;
9014
9015            ast = sourcetokenlist.get(i);
9016            sourcetokenlist.curpos = i;
9017
9018              if (ast.tokencode == TBaseType.rrw_date) {
9019                  TSourceToken st1 = ast.nextSolidToken(); //ast.searchToken('(',1);
9020                  if (st1 != null) {
9021                      if (st1.tokencode == '(') {
9022                          ast.tokencode = TBaseType.rrw_greenplum_DATE_FUNCTION;
9023                      }
9024                  }
9025              }
9026              else if (ast.tokencode == TBaseType.rrw_greenplum_POSITION) {
9027                  TSourceToken st1 = ast.nextSolidToken(); //ast.searchToken('(',1);
9028                  if (st1 != null) {
9029                      if (st1.tokencode == '(') {
9030                          ast.tokencode = TBaseType.rrw_greenplum_POSITION_FUNCTION;
9031                      }
9032                  }
9033              }
9034              else if (ast.tokencode == TBaseType.rrw_greenplum_filter) {
9035                  TSourceToken st1 = ast.nextSolidToken(); //ast.searchToken('(',1);
9036                  if (st1 != null) {
9037                      if (st1.tokencode == '(') {
9038
9039                      }else{
9040                          ast.tokencode = TBaseType.ident;
9041                      }
9042                  }
9043              }
9044              else if (ast.tokencode == TBaseType.rrw_values) {
9045                  TSourceToken stParen =  ast.searchToken('(',1);
9046                  if (stParen != null){
9047                      TSourceToken stInsert  = ast.searchToken(TBaseType.rrw_insert,-ast.posinlist);
9048                      if (stInsert != null){
9049                          TSourceToken stSemiColon  = ast.searchToken(';',-ast.posinlist);
9050                          if ((stSemiColon != null)&&(stSemiColon.posinlist > stInsert.posinlist)){
9051//                            INSERT INTO test values (16,1), (8,2), (4,4), (2,0), (97, 16);
9052//                            VALUES (1);
9053                              // don't treat values(1) as insert values
9054
9055                          }else{
9056                              TSourceToken stFrom  = ast.searchToken(TBaseType.rrw_from,-ast.posinlist);
9057                              if (stFrom != null){
9058                                  // don't treat values after from keyword as a insert values
9059
9060                                  // insert into inserttest values(10, 20, '40'), (-1, 2, DEFAULT),  ((select 2), (select i from (values(3) ) as foo (i)), 'values are fun!');
9061
9062                              }else{
9063                                  ast.tokencode = TBaseType.rrw_greenplum_values_insert;
9064                              }
9065
9066                          }
9067
9068                      }
9069                  }
9070              }
9071
9072              switch(gst){
9073                case sterror:{
9074                    if (ast.tokentype ==  ETokenType.ttsemicolon)
9075                    {
9076                        gcurrentsqlstatement.sourcetokenlist.add(ast);
9077                        doongetrawsqlstatementevent(gcurrentsqlstatement);
9078                        gst = EFindSqlStateType.stnormal;
9079                    }
9080                    else
9081                    {
9082                        gcurrentsqlstatement.sourcetokenlist.add(ast);
9083                    }
9084                    break;
9085                } //sterror
9086
9087                case stnormal:{
9088                    if ((ast.tokencode  == TBaseType.cmtdoublehyphen)
9089                       || (ast.tokencode  == TBaseType.cmtslashstar)
9090                       || (ast.tokencode  == TBaseType.lexspace)
9091                       || (ast.tokencode  == TBaseType.lexnewline)
9092                       || (ast.tokentype  == ETokenType.ttsemicolon) )
9093                    {
9094                       if (gcurrentsqlstatement != null)
9095                       {
9096                           gcurrentsqlstatement.addtokentolist(ast);
9097                       }
9098
9099                       if ((lcprevsolidtoken != null) && (ast.tokentype == ETokenType.ttsemicolon))
9100                       {
9101                           if (lcprevsolidtoken.tokentype == ETokenType.ttsemicolon )
9102                           {
9103                              // ;;;; continuous semicolon,treat it as comment
9104                               ast.tokentype = ETokenType.ttsimplecomment;
9105                               ast.tokencode =  TBaseType.cmtdoublehyphen;
9106                           }
9107                       }
9108
9109                       continue;
9110                    }
9111
9112                    if (ast.tokencode == '\\' )
9113                    {
9114                        gst = EFindSqlStateType.stsqlplus;
9115                        gcurrentsqlstatement = new TSlashCommand(dbVendor);
9116                        gcurrentsqlstatement.addtokentolist(ast);
9117                        continue;
9118                    }
9119
9120                    // find a tokentext to start sql or plsql mode
9121                    gcurrentsqlstatement = sqlcmds.issql(ast, dbVendor,gst,gcurrentsqlstatement);
9122
9123                    if (gcurrentsqlstatement != null)
9124                    {
9125                        if (gcurrentsqlstatement.isgreeplumplsql())
9126                        {
9127                              gst = EFindSqlStateType.ststoredprocedure;
9128                              gcurrentsqlstatement.addtokentolist(ast);
9129                              foundEnd = false;
9130                              if   ((ast.tokencode == TBaseType.rrw_begin)
9131                                ||(ast.tokencode == TBaseType.rrw_package)
9132                                || (ast.searchToken(TBaseType.rrw_package,4) != null)
9133                                      )
9134                              {
9135                                  waitingEnd = 1;
9136                              }else if (ast.tokencode == TBaseType.rrw_declare){
9137                                  enterDeclare = true;
9138                              }
9139                        }
9140                        else
9141                        {
9142                            gst = EFindSqlStateType.stsql;
9143                            gcurrentsqlstatement.addtokentolist(ast);
9144                        }
9145                    }else{
9146                        //error tokentext found
9147
9148                        this.syntaxErrors.add( new TSyntaxError(ast.astext,ast.lineNo,(ast.columnNo < 0 ? 0:ast.columnNo)
9149                                ,"Error when tokenlize", EErrorType.spwarning,TBaseType.MSG_WARNING_ERROR_WHEN_TOKENIZE,null,ast.posinlist));
9150
9151                        ast.tokentype = ETokenType.tttokenlizererrortoken;
9152                        gst = EFindSqlStateType.sterror;
9153
9154                        gcurrentsqlstatement = new TUnknownSqlStatement(dbVendor);
9155                        gcurrentsqlstatement.sqlstatementtype = ESqlStatementType.sstinvalid;
9156                        gcurrentsqlstatement.addtokentolist(ast);
9157
9158                    }
9159
9160                    break;
9161                } // stnormal
9162
9163                case stsqlplus:{
9164                    if (ast.tokencode  == TBaseType.lexnewline){
9165                        gst = EFindSqlStateType.stnormal; //this tokentext must be newline,
9166                        gcurrentsqlstatement.addtokentolist(ast); // so add it here
9167                        doongetrawsqlstatementevent(gcurrentsqlstatement);
9168                    }if (ast.tokencode  == '\\'){
9169                        TSourceToken nextst = ast.searchToken('\\',1);
9170                        if (nextst!=null){
9171                            gst = EFindSqlStateType.stnormal;
9172                            gcurrentsqlstatement.addtokentolist(ast);
9173                            doongetrawsqlstatementevent(gcurrentsqlstatement);
9174                        }else {
9175                            gst = EFindSqlStateType.stsqlplus;
9176                            gcurrentsqlstatement = new TSlashCommand(dbVendor);
9177                            gcurrentsqlstatement.addtokentolist(ast);
9178                            continue;
9179                        }
9180                    }else {
9181                        {gcurrentsqlstatement.addtokentolist(ast);}
9182                    }
9183
9184
9185                    break;
9186                }//case greenplum meta command
9187
9188                case stsql:{
9189                    if (ast.tokentype == ETokenType.ttsemicolon)
9190                    {
9191                        gst = EFindSqlStateType.stnormal;
9192                        gcurrentsqlstatement.addtokentolist(ast);
9193                        gcurrentsqlstatement.semicolonended = ast;
9194                        doongetrawsqlstatementevent(gcurrentsqlstatement);
9195                        continue;
9196                    }
9197
9198                    if  (sourcetokenlist.sqlplusaftercurtoken() ) //most probaly is / cmd
9199                    {
9200                        gst = EFindSqlStateType.stnormal;
9201                        gcurrentsqlstatement.addtokentolist(ast);
9202                        doongetrawsqlstatementevent(gcurrentsqlstatement);
9203                        continue;
9204                    }
9205                    gcurrentsqlstatement.addtokentolist(ast);
9206                    break;
9207                }//case stsql
9208
9209                case ststoredprocedure:{
9210                    if (ast.tokencode == TBaseType.rrw_greenplum_function_delimiter){
9211                        gcurrentsqlstatement.addtokentolist(ast);
9212                        gst = EFindSqlStateType.ststoredprocedurePgStartBody;
9213                        dollarStringToken = ast;
9214                        continue;
9215                    }
9216
9217                    if (ast.tokencode == TBaseType.rrw_greenplum_language){
9218                        // check next token which is the language used by this stored procedure
9219                        TSourceToken nextSt = ast.nextSolidToken();
9220                        if (nextSt != null){
9221                            if (gcurrentsqlstatement instanceof TRoutine){  // can be TCreateProcedureStmt or TCreateFunctionStmt
9222                                TRoutine p = (TRoutine) gcurrentsqlstatement;
9223                                p.setRoutineLanguage(nextSt.toString());
9224                            }
9225                        }
9226                    }
9227
9228                    if ((ast.tokentype == ETokenType.ttsemicolon) && (waitingEnd == 0) && (!enterDeclare))
9229                    {
9230                        gst = EFindSqlStateType.stnormal;
9231                        gcurrentsqlstatement.addtokentolist(ast);
9232                        gcurrentsqlstatement.semicolonended = ast;
9233                        doongetrawsqlstatementevent(gcurrentsqlstatement);
9234                        continue;
9235                    }
9236
9237
9238                    if   ((ast.tokencode == TBaseType.rrw_begin)
9239                            //||(ast.tokencode == TBaseType.rrw_between)
9240                            )
9241                    {
9242                        waitingEnd++;
9243                        enterDeclare = false;
9244                    }
9245                    else if   (
9246                            (ast.tokencode == TBaseType.rrw_declare)
9247                    ){
9248                        enterDeclare = true;
9249                    }
9250                    else if   (
9251                            (ast.tokencode == TBaseType.rrw_if)
9252                            ){
9253                         if (ast.searchToken(TBaseType.rrw_end,-1) == null){
9254                             //this is not if after END
9255                             if(!( (ast.searchToken(TBaseType.rrw_greenplum_exits,1) != null)
9256                                 ||(ast.searchToken(TBaseType.rrw_greenplum_exits,2) != null)
9257                             )) // if not exists, if exists is not a real if statement, so skip those
9258                             {
9259                                 waitingEnd++;
9260                             }
9261                         }
9262                    }
9263                    else if   (
9264                            (ast.tokencode == TBaseType.rrw_case)
9265                            ){
9266                        if (ast.searchToken(TBaseType.rrw_end,-1) == null){
9267                            //this is not case after END
9268                         waitingEnd++;
9269                        }
9270                    }
9271                    else if   (
9272                            (ast.tokencode == TBaseType.rrw_loop)
9273                            ){
9274                        if (ast.searchToken(TBaseType.rrw_end,-1) == null){
9275                            //this is not loop after END
9276                         waitingEnd++;
9277                        }
9278                    }
9279                    else if (ast.tokencode == TBaseType.rrw_end){
9280                        foundEnd = true;
9281                        waitingEnd--;
9282                        if (waitingEnd < 0) { waitingEnd = 0;}
9283                    }
9284
9285                    if ((ast.tokentype == ETokenType.ttslash)  && (ast.tokencode == TBaseType.sqlpluscmd) ) //and (prevst.NewlineIsLastTokenInTailerToken)) then
9286                    {
9287                      // TPlsqlStatementParse(asqlstatement).TerminatorToken := ast;
9288                       ast.tokenstatus = ETokenStatus.tsignorebyyacc;
9289                       gst = EFindSqlStateType.stnormal;
9290                       doongetrawsqlstatementevent(gcurrentsqlstatement);
9291
9292                       //make / a sqlplus cmd
9293                       gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
9294                       gcurrentsqlstatement.addtokentolist(ast);
9295                       doongetrawsqlstatementevent(gcurrentsqlstatement);
9296                    }
9297                    else  if ((ast.tokentype == ETokenType.ttperiod)  && (sourcetokenlist.returnaftercurtoken(false)) && (sourcetokenlist.returnbeforecurtoken(false)))
9298                    {    // single dot at a seperate line
9299                       ast.tokenstatus = ETokenStatus.tsignorebyyacc;
9300                       gst = EFindSqlStateType.stnormal;
9301                       doongetrawsqlstatementevent(gcurrentsqlstatement);
9302
9303                       //make ttperiod a sqlplus cmd
9304                       gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
9305                       gcurrentsqlstatement.addtokentolist(ast);
9306                       doongetrawsqlstatementevent(gcurrentsqlstatement);
9307                    }else  if ((ast.tokencode == TBaseType.rrw_declare)&&(waitingEnd == 0)){
9308                        i--;
9309                        doongetrawsqlstatementevent(gcurrentsqlstatement);
9310                        gst = EFindSqlStateType.stnormal;
9311                    }
9312                     else
9313                    {
9314                        gcurrentsqlstatement.addtokentolist(ast);
9315                        if ((ast.tokentype == ETokenType.ttsemicolon) && (waitingEnd == 0) && (foundEnd) && (gcurrentsqlstatement.OracleStatementCanBeSeparatedByBeginEndPair())){
9316                            gst = EFindSqlStateType.stnormal;
9317                            doongetrawsqlstatementevent(gcurrentsqlstatement);
9318                        }
9319                    }
9320
9321                     if (ast.tokencode == TBaseType.sqlpluscmd)
9322                     {
9323                         //change tokencode back to keyword or TBaseType.ident, because sqlplus cmd
9324                         //in a sql statement(almost is plsql block) is not really a sqlplus cmd
9325                         int m = flexer.getkeywordvalue(ast.astext);
9326                         if (m != 0)
9327                         {ast.tokencode = m;}
9328                         else
9329                         {ast.tokencode = TBaseType.ident;}
9330                     }
9331
9332                    break;
9333                } //ststoredprocedure
9334
9335                  case ststoredprocedurePgStartBody:{
9336                      gcurrentsqlstatement.addtokentolist(ast);
9337
9338                      if (ast.tokencode == TBaseType.rrw_greenplum_function_delimiter){
9339                          if (dollarStringToken.toString().equalsIgnoreCase(ast.toString())){
9340                              // must match the $$ token
9341                              gst = EFindSqlStateType.ststoredprocedurePgEndBody;
9342                              continue;
9343                          }
9344                      }
9345
9346                      break;
9347                  }
9348
9349                  case ststoredprocedurePgEndBody:{
9350
9351                      if (ast.tokentype == ETokenType.ttsemicolon)
9352                      {
9353                          gst = EFindSqlStateType.stnormal;
9354                          gcurrentsqlstatement.addtokentolist(ast);
9355                          gcurrentsqlstatement.semicolonended = ast;
9356                          doongetrawsqlstatementevent(gcurrentsqlstatement);
9357                          continue;
9358                      }
9359                      else if (ast.tokencode  == TBaseType.cmtdoublehyphen){
9360                          if (ast.toString().trim().endsWith(TBaseType.sqlflow_stmt_delimiter_str)){ // -- sqlflow-delimiter
9361                              gst = EFindSqlStateType.stnormal;
9362                              doongetrawsqlstatementevent(gcurrentsqlstatement);
9363                              continue;
9364                          }
9365                      }
9366
9367                      gcurrentsqlstatement.addtokentolist(ast);
9368
9369                      if (ast.tokencode == TBaseType.rrw_greenplum_language){
9370                          // check next token which is the language used by this stored procedure
9371                          TSourceToken nextSt = ast.nextSolidToken();
9372                          if (nextSt != null){
9373                              if (gcurrentsqlstatement instanceof TRoutine){  // can be TCreateProcedureStmt or TCreateFunctionStmt
9374                                  TRoutine p = (TRoutine) gcurrentsqlstatement;
9375                                  p.setRoutineLanguage(nextSt.toString());
9376                              }
9377                          }
9378                      }
9379
9380                      break;
9381                  }
9382
9383            } //switch
9384          }//for
9385
9386        //last statement
9387        if ((gcurrentsqlstatement != null) &&
9388            ((gst == EFindSqlStateType.stsqlplus) ||  (gst == EFindSqlStateType.stsql)
9389                    || (gst == EFindSqlStateType.ststoredprocedure)|| (gst == EFindSqlStateType.ststoredprocedurePgEndBody)
9390                    ||(gst == EFindSqlStateType.sterror)))
9391        {
9392            doongetrawsqlstatementevent(gcurrentsqlstatement);
9393        }
9394
9395      return syntaxErrors.size();
9396    }
9397
9398private boolean isTypeCastToken(TSourceToken ast){
9399    boolean istypecasetoken = false;
9400    TSourceToken st = ast.searchToken('(',1);
9401    if (st != null){
9402       TSourceToken  nst = st.searchToken(TBaseType.iconst,1);
9403        istypecasetoken = (nst == null);
9404    }
9405
9406    return istypecasetoken;
9407}
9408
9409int donetezzagetrawsqlstatements(){
9410    int waitingEnd = 0;
9411    boolean foundEnd = false;
9412
9413    if ( TBaseType.assigned(sqlstatements) ) sqlstatements.clear();
9414    if ( ! TBaseType.assigned(sourcetokenlist) ) return -1;
9415
9416    gcurrentsqlstatement = null;
9417    EFindSqlStateType gst = EFindSqlStateType.stnormal;
9418    TSourceToken lcprevsolidtoken = null,ast = null;
9419
9420    for (int i=0 ; i < sourcetokenlist.size();i++)
9421      {
9422
9423          if ( (ast != null ) && (ast.issolidtoken() ))
9424            lcprevsolidtoken = ast;
9425
9426        ast = sourcetokenlist.get(i);
9427        sourcetokenlist.curpos = i;
9428
9429        // change token code if necessary
9430        if (ast.tokencode == TBaseType.rrw_int){
9431            if (isTypeCastToken(ast)) ast.tokencode = TBaseType.rrw_int_cast;
9432        }else  if (ast.tokencode == TBaseType.rrw_integer){
9433            if (isTypeCastToken(ast)) ast.tokencode = TBaseType.rrw_integer_cast;
9434        }else  if (ast.tokencode == TBaseType.rrw_smallint){
9435            if (isTypeCastToken(ast)) ast.tokencode = TBaseType.rrw_smallint_cast;
9436        }else  if (ast.tokencode == TBaseType.rrw_bigint){
9437            if (isTypeCastToken(ast)) ast.tokencode = TBaseType.rrw_bigint_cast;
9438        }else  if (ast.tokencode == TBaseType.rrw_real){
9439            if (isTypeCastToken(ast)) ast.tokencode = TBaseType.rrw_real_cast;
9440        }else  if (ast.tokencode == TBaseType.rrw_float){
9441            if (isTypeCastToken(ast)) ast.tokencode = TBaseType.rrw_float_cast;
9442        }else  if (ast.tokencode == TBaseType.rrw_numeric){
9443            if (isTypeCastToken(ast)) ast.tokencode = TBaseType.rrw_numeric_cast;
9444//        }else  if (ast.tokencode == TBaseType.rrw_boolean){
9445//            if (isTypeCastToken(ast)) ast.tokencode = TBaseType.rrw_boolean_cast;
9446        }else  if (ast.tokencode == TBaseType.rrw_bit){
9447            if (isTypeCastToken(ast)) ast.tokencode = TBaseType.rrw_bit_cast;
9448        }else  if (ast.tokencode == TBaseType.rrw_char){
9449            if (isTypeCastToken(ast)) ast.tokencode = TBaseType.rrw_char_cast;
9450        }else  if (ast.tokencode == TBaseType.rrw_nchar){
9451            if (isTypeCastToken(ast)) ast.tokencode = TBaseType.rrw_nchar_cast;
9452        }else  if (ast.tokencode == TBaseType.rrw_varchar){
9453            if (isTypeCastToken(ast)) ast.tokencode = TBaseType.rrw_varchar_cast;
9454        }else  if (ast.tokencode == TBaseType.rrw_character){
9455            if (isTypeCastToken(ast)) ast.tokencode = TBaseType.rrw_character_cast;
9456        }else  if (ast.tokencode == TBaseType.rrw_date){
9457            if (isTypeCastToken(ast)) ast.tokencode = TBaseType.rrw_date_cast;
9458        }else  if (ast.tokencode == TBaseType.rrw_time){
9459            if (isTypeCastToken(ast)) ast.tokencode = TBaseType.rrw_time_cast;
9460        }else  if (ast.tokencode == TBaseType.rrw_timestamp){
9461            if (isTypeCastToken(ast)) ast.tokencode = TBaseType.rrw_timestamp_cast;
9462        }else  if (ast.tokencode == TBaseType.rrw_interval){
9463            if (isTypeCastToken(ast)) ast.tokencode = TBaseType.rrw_interval_cast;
9464        }else  if (ast.tokencode == TBaseType.rrw_decimal){
9465            if (isTypeCastToken(ast)) ast.tokencode = TBaseType.rrw_decimal_cast;
9466        }
9467
9468        switch(gst){
9469            case sterror:{
9470                if (ast.tokentype ==  ETokenType.ttsemicolon)
9471                {
9472                    gcurrentsqlstatement.sourcetokenlist.add(ast);
9473                    doongetrawsqlstatementevent(gcurrentsqlstatement);
9474                    gst = EFindSqlStateType.stnormal;
9475                }
9476                else
9477                {
9478                    gcurrentsqlstatement.sourcetokenlist.add(ast);
9479                }
9480                break;
9481            } //sterror
9482
9483            case stnormal:{
9484                if ((ast.tokencode  == TBaseType.cmtdoublehyphen)
9485                   || (ast.tokencode  == TBaseType.cmtslashstar)
9486                   || (ast.tokencode  == TBaseType.lexspace)
9487                   || (ast.tokencode  == TBaseType.lexnewline)
9488                   || (ast.tokentype  == ETokenType.ttsemicolon) )
9489                {
9490                   if (gcurrentsqlstatement != null)
9491                   {
9492                       gcurrentsqlstatement.addtokentolist(ast);
9493                   }
9494
9495                   if ((lcprevsolidtoken != null) && (ast.tokentype == ETokenType.ttsemicolon))
9496                   {
9497                       if (lcprevsolidtoken.tokentype == ETokenType.ttsemicolon )
9498                       {
9499                          // ;;;; continuous semicolon,treat it as comment
9500                           ast.tokentype = ETokenType.ttsimplecomment;
9501                           ast.tokencode =  TBaseType.cmtdoublehyphen;
9502                       }
9503                   }
9504
9505                   continue;
9506                }
9507
9508                if (ast.tokencode == TBaseType.sqlpluscmd )
9509                {
9510                    gst = EFindSqlStateType.stsqlplus;
9511                    gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
9512                    gcurrentsqlstatement.addtokentolist(ast);
9513                    continue;
9514                }
9515
9516                // find a tokentext to start sql or plsql mode
9517                gcurrentsqlstatement = sqlcmds.issql(ast, dbVendor,gst,gcurrentsqlstatement);
9518
9519                if (gcurrentsqlstatement != null)
9520                {
9521                    if (gcurrentsqlstatement.isnzplsql())
9522                    {
9523                          gst = EFindSqlStateType.ststoredprocedure;
9524                          gcurrentsqlstatement.addtokentolist(ast);
9525                          foundEnd = false;
9526                          if   ((ast.tokencode == TBaseType.rrw_begin)
9527                            ||(ast.tokencode == TBaseType.rrw_package)
9528                            || (ast.searchToken(TBaseType.rrw_package,4) != null)
9529                                  )
9530                          { waitingEnd = 1;}
9531                    }
9532                    else
9533                    {
9534                        gst = EFindSqlStateType.stsql;
9535                        gcurrentsqlstatement.addtokentolist(ast);
9536                    }
9537                }else{
9538                    //error tokentext found
9539
9540                    this.syntaxErrors.add( new TSyntaxError(ast.astext,ast.lineNo,(ast.columnNo < 0 ? 0:ast.columnNo)
9541                            ,"Error when tokenlize", EErrorType.spwarning,TBaseType.MSG_WARNING_ERROR_WHEN_TOKENIZE,null,ast.posinlist));
9542
9543                    ast.tokentype = ETokenType.tttokenlizererrortoken;
9544                    gst = EFindSqlStateType.sterror;
9545
9546                    gcurrentsqlstatement = new TUnknownSqlStatement(dbVendor);
9547                    gcurrentsqlstatement.sqlstatementtype = ESqlStatementType.sstinvalid;
9548                    gcurrentsqlstatement.addtokentolist(ast);
9549
9550                }
9551
9552                break;
9553            } // stnormal
9554
9555            case stsqlplus:{
9556                if  (ast.insqlpluscmd)
9557                {gcurrentsqlstatement.addtokentolist(ast);}
9558                else
9559                {
9560                    gst = EFindSqlStateType.stnormal; //this tokentext must be newline,
9561                    gcurrentsqlstatement.addtokentolist(ast); // so add it here
9562                    doongetrawsqlstatementevent(gcurrentsqlstatement);
9563                }
9564
9565                break;
9566            }//case stsqlplus
9567
9568            case stsql:{
9569                if (ast.tokentype == ETokenType.ttsemicolon)
9570                {
9571                    gst = EFindSqlStateType.stnormal;
9572                    gcurrentsqlstatement.addtokentolist(ast);
9573                    gcurrentsqlstatement.semicolonended = ast;
9574                    doongetrawsqlstatementevent(gcurrentsqlstatement);
9575                    continue;
9576                }
9577
9578                if  (sourcetokenlist.sqlplusaftercurtoken() ) //most probaly is / cmd
9579                {
9580                    gst = EFindSqlStateType.stnormal;
9581                    gcurrentsqlstatement.addtokentolist(ast);
9582                    doongetrawsqlstatementevent(gcurrentsqlstatement);
9583                    continue;
9584                }
9585                gcurrentsqlstatement.addtokentolist(ast);
9586                break;
9587            }//case stsql
9588
9589            case ststoredprocedure:{
9590                if   ((ast.tokencode == TBaseType.rrw_begin)
9591                        //||(ast.tokencode == TBaseType.rrw_between)
9592                        )
9593                {
9594                    waitingEnd++;
9595                }
9596                else if   (
9597                        (ast.tokencode == TBaseType.rrw_if)
9598                        ){
9599                     if (ast.searchToken(TBaseType.rrw_end,-1) == null){
9600                         //this is not if after END
9601                      waitingEnd++;
9602                     }
9603                }
9604                else if   (
9605                        (ast.tokencode == TBaseType.rrw_case)
9606                        ){
9607                    if (ast.searchToken(TBaseType.rrw_end,-1) == null){
9608                        //this is not case after END
9609                     waitingEnd++;
9610                    }
9611                }
9612                else if   (
9613                        (ast.tokencode == TBaseType.rrw_loop)
9614                        ){
9615                    if (ast.searchToken(TBaseType.rrw_end,-1) == null){
9616                        //this is not loop after END
9617                     waitingEnd++;
9618                    }
9619                }
9620                else if (ast.tokencode == TBaseType.rrw_end){
9621                    foundEnd = true;
9622                    waitingEnd--;
9623                    if (waitingEnd < 0) { waitingEnd = 0;}
9624                }
9625
9626                if ((ast.tokentype == ETokenType.ttslash)  && (ast.tokencode == TBaseType.sqlpluscmd) ) //and (prevst.NewlineIsLastTokenInTailerToken)) then
9627                {
9628                  // TPlsqlStatementParse(asqlstatement).TerminatorToken := ast;
9629                   ast.tokenstatus = ETokenStatus.tsignorebyyacc;
9630                   gst = EFindSqlStateType.stnormal;
9631                   doongetrawsqlstatementevent(gcurrentsqlstatement);
9632
9633                   //make / a sqlplus cmd
9634                   gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
9635                   gcurrentsqlstatement.addtokentolist(ast);
9636                   doongetrawsqlstatementevent(gcurrentsqlstatement);
9637                }
9638                else  if ((ast.tokentype == ETokenType.ttperiod)  && (sourcetokenlist.returnaftercurtoken(false)) && (sourcetokenlist.returnbeforecurtoken(false)))
9639                {    // single dot at a seperate line
9640                   ast.tokenstatus = ETokenStatus.tsignorebyyacc;
9641                   gst = EFindSqlStateType.stnormal;
9642                   doongetrawsqlstatementevent(gcurrentsqlstatement);
9643
9644                   //make ttperiod a sqlplus cmd
9645                   gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
9646                   gcurrentsqlstatement.addtokentolist(ast);
9647                   doongetrawsqlstatementevent(gcurrentsqlstatement);
9648                }
9649                 else
9650                {
9651                    gcurrentsqlstatement.addtokentolist(ast);
9652                    if ((ast.tokentype == ETokenType.ttsemicolon) && (waitingEnd == 0) && (foundEnd) && (gcurrentsqlstatement.OracleStatementCanBeSeparatedByBeginEndPair())){
9653                        gst = EFindSqlStateType.stnormal;
9654                        doongetrawsqlstatementevent(gcurrentsqlstatement);
9655                    }else if ((ast.searchToken(TBaseType.rrw_create,1) != null)&&(ast.searchToken(TBaseType.rrw_procedure,4) != null)&&(waitingEnd == 0)){
9656                        gst = EFindSqlStateType.stnormal;
9657                        doongetrawsqlstatementevent(gcurrentsqlstatement);
9658                    }
9659
9660            }
9661
9662                break;
9663            } //ststoredprocedure
9664        } //switch
9665      }//for
9666
9667    //last statement
9668    if ((gcurrentsqlstatement != null) &&
9669        ((gst == EFindSqlStateType.stsqlplus) ||  (gst == EFindSqlStateType.stsql) || (gst == EFindSqlStateType.ststoredprocedure) ||
9670                    (gst == EFindSqlStateType.sterror)))
9671    {
9672        doongetrawsqlstatementevent(gcurrentsqlstatement);
9673    }
9674
9675  return syntaxErrors.size();
9676}
9677
9678int dooraclegetrawsqlstatements(){
9679    int waitingEnds[] = new int[stored_procedure_nested_level];
9680    stored_procedure_type sptype[] = new stored_procedure_type[stored_procedure_nested_level];
9681    stored_procedure_status procedure_status[] = new stored_procedure_status[stored_procedure_nested_level];
9682    boolean endBySlashOnly = true;
9683    int nestedProcedures = 0, nestedParenthesis = 0;
9684
9685
9686
9687    if ( TBaseType.assigned(sqlstatements) ) sqlstatements.clear();
9688    if ( ! TBaseType.assigned(sourcetokenlist) ) return -1;
9689
9690    gcurrentsqlstatement = null;
9691    EFindSqlStateType gst = EFindSqlStateType.stnormal;
9692    TSourceToken lcprevsolidtoken = null,ast = null;
9693
9694    for (int i=0 ; i < sourcetokenlist.size();i++)
9695      {
9696
9697          if ( (ast != null ) && (ast.issolidtoken() ))
9698            lcprevsolidtoken = ast;
9699
9700        ast = sourcetokenlist.get(i);
9701        sourcetokenlist.curpos = i;
9702
9703        if (ast.tokencode == TBaseType.rrw_return){
9704                    TSourceToken stMatch  = ast.searchToken(TBaseType.rrw_where,1);
9705                    if (stMatch != null){   //match full
9706                        ast.tokencode = TBaseType.ident;
9707                    }
9708        }else if (ast.tokencode == TBaseType.rrw_value_oracle){
9709          TSourceToken stBy  = ast.searchToken(TBaseType.rrw_by,-1);
9710          if (stBy == null){
9711             // keep value as keyword, but it is in rule: unreserved_keyword_can_be_function
9712              // so value can be used as column ,table name.
9713
9714          }else{
9715              ast.tokencode = TBaseType.rrw_value_after_by;
9716          }
9717        }else if (ast.tokencode == TBaseType.rrw_new_oracle){
9718            TSourceToken stRightParen  = ast.searchToken(')',-1);
9719            if (stRightParen != null){
9720                ast.tokencode = TBaseType.ident;
9721            }
9722            TSourceToken stDot  = ast.searchToken('.',1);
9723            if (stDot != null){
9724                ast.tokencode = TBaseType.ident;
9725            }
9726//            TSourceToken stNext= ast.searchToken("(",3);
9727//            if (stNext != null){
9728//                ast.tokencode = TBaseType.rrw_oracle_new_constructor;
9729//            }
9730
9731            TSourceToken stNext= ast.searchTokenAfterObjectName();
9732            stDot  = ast.searchToken('.',1);
9733            if ((stDot == null)&&(stNext != null) && (stNext.tokencode == '(')){
9734                ast.tokencode = TBaseType.rrw_oracle_new_constructor;
9735            }
9736
9737        }else if (ast.tokencode == TBaseType.rrw_chr_oracle){
9738            TSourceToken stLeftParen= ast.searchToken('(',1);
9739            if (stLeftParen == null){
9740                ast.tokencode = TBaseType.ident;
9741            }
9742        }else if (ast.tokencode == TBaseType.rrw_log_oracle){
9743            TSourceToken stNext= ast.searchToken(TBaseType.rrw_errors_oracle,1);
9744            TSourceToken stPrev= ast.searchToken(TBaseType.rrw_view,-1);
9745            if (stPrev == null){
9746                stPrev= ast.searchToken(TBaseType.rrw_oracle_supplemental,-1);
9747            }
9748            if ((stNext == null)&&(stPrev == null)){
9749                ast.tokencode = TBaseType.ident;
9750            }
9751        }else if (ast.tokencode == TBaseType.rrw_delete){
9752            TSourceToken stPrev= ast.searchToken('.',-1);
9753            if (stPrev != null){
9754                ast.tokencode = TBaseType.ident;
9755            }
9756        }else if (ast.tokencode == TBaseType.rrw_partition){
9757            TSourceToken stPrev= ast.searchToken(TBaseType.rrw_add,-1);
9758            if (stPrev != null){
9759                stPrev.tokencode = TBaseType.rrw_add_p;
9760            }
9761        }else if (ast.tokencode == TBaseType.rrw_oracle_column){
9762            TSourceToken stPrev= ast.searchToken(TBaseType.rrw_oracle_modify,-1);
9763            if (stPrev != null){
9764                ast.tokencode = TBaseType.rrw_oracle_column_after_modify;
9765            }
9766        }else if (ast.tokencode == TBaseType.rrw_oracle_apply){
9767            TSourceToken stPrev= ast.searchToken(TBaseType.rrw_outer,-1);
9768            if (stPrev != null){
9769                stPrev.tokencode = TBaseType.ORACLE_OUTER2;
9770            }
9771        }else if (ast.tokencode == TBaseType.rrw_oracle_subpartition){
9772            TSourceToken stNext= ast.searchToken("(",2);
9773            if (stNext != null){
9774
9775                TSourceToken st1 = ast.nextSolidToken();
9776                if (st1.toString().equalsIgnoreCase("template")){
9777                    // RW_SUBPARTITION RW_TEMPLATE '(' dummy_node ')'
9778                    // don't change, keep as RW_SUBPARTITION
9779                }else{
9780                    ast.tokencode = TBaseType.rrw_oracle_subpartition_tablesample;
9781                }
9782
9783            }
9784        }else if (ast.tokencode == TBaseType.rrw_primary){
9785            TSourceToken stNext= ast.searchToken("key",1);
9786            if (stNext == null){ // if this is not primary key, then, treat "primary" as an identifier.
9787                ast.tokencode = TBaseType.ident;
9788            }
9789        }else if (ast.tokencode == TBaseType.rrw_oracle_offset){
9790            TSourceToken stNext= ast.searchToken(TBaseType.rrw_oracle_row,2);
9791            if (stNext == null){
9792                stNext= ast.searchToken(TBaseType.rrw_oracle_rows,2);
9793            }
9794            if (stNext != null){
9795                ast.tokencode = TBaseType.rrw_oracle_offset_row;
9796            }
9797        }else if (ast.tokencode == TBaseType.rrw_translate){
9798            TSourceToken stNext= ast.searchToken("(",2);
9799            if (stNext == null){
9800                ast.tokencode = TBaseType.ident;
9801            }
9802        }else if (ast.tokencode == TBaseType.rrw_constraint){
9803            TSourceToken stNext= ast.nextSolidToken();
9804            if (stNext == null){
9805                ast.tokencode = TBaseType.ident;
9806            }else{
9807                if (stNext.tokencode != TBaseType.ident){
9808                    // constraint name, there must be a name after keyword constraint, otherwise, constraint is an identifier
9809                    ast.tokencode = TBaseType.ident;
9810                }
9811            }
9812        }else if (ast.tokencode == TBaseType.rrw_oracle_without) {
9813            TSourceToken stNext = ast.searchToken(TBaseType.rrw_oracle_count, 1);
9814            if (stNext != null) {
9815                ast.tokencode = TBaseType.rrw_oracle_without_before_count;
9816            }
9817        }else if (ast.tokencode == TBaseType.rrw_bulk) {
9818            TSourceToken stNext = ast.searchToken(TBaseType.rrw_oracle_collect, 1);
9819            if (stNext == null) {
9820                // treat all bulk keywords as identifier if not followed by collect.
9821                // bulk collect
9822                ast.tokencode = TBaseType.ident;
9823            }
9824        }else if (ast.tokencode == TBaseType.rrw_oracle_model){
9825            TSourceToken stNext = ast.nextSolidToken();
9826            if (stNext != null){
9827                switch (stNext.toString().toUpperCase()) {
9828                    case "RETURN":      // RETURN [UPDATED|ALL] ROWS
9829                    case "REFERENCE":   // REFERENCE model_name...
9830                    case "IGNORE":      // IGNORE NAV
9831                    case "KEEP":        // KEEP NAV
9832                    case "UNIQUE":      // UNIQUE [DIMENSION|SINGLE REFERENCE]
9833                    case "PARTITION":   // PARTITION BY
9834                    case "DIMENSION":   // DIMENSION BY
9835                    case "MEASURES":    // MEASURES (cols)
9836                    case "RULES":       // RULES...
9837                        ast.tokencode = TBaseType.rrw_oracle_model_in_model_clause;
9838                        break;
9839                    default:
9840                       ;
9841                }
9842            }
9843        }
9844
9845        switch(gst){
9846            case sterror:{
9847                if (ast.tokentype ==  ETokenType.ttsemicolon)
9848                {
9849                    gcurrentsqlstatement.sourcetokenlist.add(ast);
9850                    doongetrawsqlstatementevent(gcurrentsqlstatement);
9851                    gst = EFindSqlStateType.stnormal;
9852                }
9853                else
9854                {
9855                    gcurrentsqlstatement.sourcetokenlist.add(ast);
9856                }
9857                break;
9858            } //sterror
9859
9860            case stnormal:{
9861                if ((ast.tokencode  == TBaseType.cmtdoublehyphen)
9862                   || (ast.tokencode  == TBaseType.cmtslashstar)
9863                   || (ast.tokencode  == TBaseType.lexspace)
9864                   || (ast.tokencode  == TBaseType.lexnewline)
9865                   || (ast.tokentype  == ETokenType.ttsemicolon) )
9866                {
9867                   if (gcurrentsqlstatement != null)
9868                   {
9869                       gcurrentsqlstatement.addtokentolist(ast);
9870                   }
9871
9872                   if ((lcprevsolidtoken != null) && (ast.tokentype == ETokenType.ttsemicolon))
9873                   {
9874                       if (lcprevsolidtoken.tokentype == ETokenType.ttsemicolon )
9875                       {
9876                          // ;;;; continuous semicolon,treat it as comment
9877                           ast.tokentype = ETokenType.ttsimplecomment;
9878                           ast.tokencode =  TBaseType.cmtdoublehyphen;
9879                       }
9880                   }
9881
9882                   continue;
9883                }
9884
9885                if (ast.tokencode == TBaseType.sqlpluscmd )
9886                {
9887
9888                    gst = EFindSqlStateType.stsqlplus;
9889                    gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
9890                    gcurrentsqlstatement.addtokentolist(ast);
9891                    continue;
9892                }
9893
9894                // find a tokentext to start sql or plsql mode
9895                gcurrentsqlstatement = sqlcmds.issql(ast, dbVendor,gst,gcurrentsqlstatement);
9896
9897                if (gcurrentsqlstatement != null)
9898                {
9899                    if (gcurrentsqlstatement.isoracleplsql())
9900                    {
9901                          nestedProcedures = 0;
9902                          gst = EFindSqlStateType.ststoredprocedure;
9903                          gcurrentsqlstatement.addtokentolist(ast);
9904
9905                          switch (gcurrentsqlstatement.sqlstatementtype){
9906                              case sstplsql_createprocedure:
9907                                  sptype[nestedProcedures] = stored_procedure_type.procedure;
9908                                  break;
9909                              case sstplsql_createfunction:
9910                                  sptype[nestedProcedures] = stored_procedure_type.function;
9911                                  break;
9912                              case sstplsql_createpackage:
9913                                  sptype[nestedProcedures] = stored_procedure_type.package_spec;
9914                                  if (ast.searchToken(TBaseType.rrw_body,5) != null){
9915                                      sptype[nestedProcedures] = stored_procedure_type.package_body;
9916                                  }
9917                                  break;
9918                              case sst_plsql_block:
9919                                  sptype[nestedProcedures] = stored_procedure_type.block_with_declare;
9920                                  if (ast.tokencode == TBaseType.rrw_begin) {
9921                                      sptype[nestedProcedures] = stored_procedure_type.block_with_begin;
9922                                  }
9923                                  break;
9924                              case sstplsql_createtrigger:
9925                                  sptype[nestedProcedures] = stored_procedure_type.create_trigger;
9926                                  break;
9927                              case sstoraclecreatelibrary:
9928                                  sptype[nestedProcedures] = stored_procedure_type.create_library;
9929                                  break;
9930                              case sstplsql_createtype_placeholder:
9931                                  gst = EFindSqlStateType.stsql;
9932                                  break;
9933                              default:
9934                                  sptype[nestedProcedures] = stored_procedure_type.others;
9935                                  break;
9936                          }
9937
9938                          if (sptype[0] == stored_procedure_type.block_with_declare){
9939                              // sd
9940                             endBySlashOnly = false;
9941                             procedure_status[0] = stored_procedure_status.is_as;
9942                          }else if (sptype[0] == stored_procedure_type.block_with_begin){
9943                              // sb
9944                              endBySlashOnly = false;
9945                              procedure_status[0] = stored_procedure_status.body;
9946                          }else if (sptype[0] == stored_procedure_type.procedure){
9947                              // ss
9948                              endBySlashOnly = false;
9949                              procedure_status[0] = stored_procedure_status.start;
9950                          }else if (sptype[0] == stored_procedure_type.function){
9951                              // ss
9952                              endBySlashOnly = false;
9953                              procedure_status[0] = stored_procedure_status.start;
9954                          }else if (sptype[0] == stored_procedure_type.package_spec){
9955                              // ss
9956                              endBySlashOnly = false;
9957                              procedure_status[0] = stored_procedure_status.start;
9958                          }else if (sptype[0] == stored_procedure_type.package_body){
9959                              // ss
9960                              endBySlashOnly = false;
9961                              procedure_status[0] = stored_procedure_status.start;
9962                          }else if (sptype[0] == stored_procedure_type.create_trigger){
9963                              // ss
9964                              endBySlashOnly = false;
9965                              procedure_status[0] = stored_procedure_status.start;
9966                              //procedure_status[0] = stored_procedure_status.body;
9967                          }else if (sptype[0] == stored_procedure_type.create_library){
9968                              // ss
9969                              endBySlashOnly = false;
9970                              procedure_status[0] = stored_procedure_status.bodyend;
9971                          }else {
9972                              // so
9973                              endBySlashOnly = true;
9974                              procedure_status[0] = stored_procedure_status.bodyend;
9975                          }
9976                          //foundEnd = false;
9977                          if   ((ast.tokencode == TBaseType.rrw_begin)
9978                            ||(ast.tokencode == TBaseType.rrw_package)
9979                            //||(ast.tokencode == TBaseType.rrw_procedure)
9980                            || (ast.searchToken(TBaseType.rrw_package,4) != null)
9981                                  )
9982                          {
9983                              //waitingEnd = 1;
9984                              waitingEnds[nestedProcedures] = 1;
9985                          }
9986                    }
9987                    else
9988                    {
9989                        gst = EFindSqlStateType.stsql;
9990                        gcurrentsqlstatement.addtokentolist(ast);
9991                        nestedParenthesis = 0;
9992                    }
9993                }else{
9994                    //error tokentext found
9995
9996                    this.syntaxErrors.add( new TSyntaxError(ast.astext,ast.lineNo,(ast.columnNo < 0 ? 0:ast.columnNo)
9997                            ,"Error when tokenlize", EErrorType.spwarning,TBaseType.MSG_WARNING_ERROR_WHEN_TOKENIZE,null,ast.posinlist));
9998
9999                    ast.tokentype = ETokenType.tttokenlizererrortoken;
10000                    gst = EFindSqlStateType.sterror;
10001
10002                    gcurrentsqlstatement = new TUnknownSqlStatement(dbVendor);
10003                    gcurrentsqlstatement.sqlstatementtype = ESqlStatementType.sstinvalid;
10004                    gcurrentsqlstatement.addtokentolist(ast);
10005
10006                }
10007
10008                break;
10009            } // stnormal
10010
10011            case stsqlplus:{
10012                if  (ast.insqlpluscmd)
10013                {gcurrentsqlstatement.addtokentolist(ast);}
10014                else
10015                {
10016                    gst = EFindSqlStateType.stnormal; //this tokentext must be newline,
10017                    gcurrentsqlstatement.addtokentolist(ast); // so add it here
10018                    doongetrawsqlstatementevent(gcurrentsqlstatement);
10019                }
10020
10021                break;
10022            }//case stsqlplus
10023
10024            case stsql:{
10025                if (ast.tokentype == ETokenType.ttsemicolon)
10026                {
10027                    gst = EFindSqlStateType.stnormal;
10028                    gcurrentsqlstatement.addtokentolist(ast);
10029                    gcurrentsqlstatement.semicolonended = ast;
10030                    doongetrawsqlstatementevent(gcurrentsqlstatement);
10031                    continue;
10032                }
10033
10034                if  (sourcetokenlist.sqlplusaftercurtoken() ) //most probably is / cmd
10035                {
10036                    gst = EFindSqlStateType.stnormal;
10037                    gcurrentsqlstatement.addtokentolist(ast);
10038                    doongetrawsqlstatementevent(gcurrentsqlstatement);
10039                    continue;
10040                }
10041
10042                if (ast.tokencode == '(') nestedParenthesis++;
10043                if (ast.tokencode == ')')
10044                {
10045                    nestedParenthesis--;
10046                    if (nestedParenthesis < 0) nestedParenthesis = 0;
10047                }
10048                Boolean findNewStmt = false;
10049                TCustomSqlStatement lcStmt = null;
10050                if ((nestedParenthesis == 0) && (gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatetable))
10051                {
10052                    lcStmt = sqlcmds.issql(ast, dbVendor, gst, gcurrentsqlstatement);
10053                    if (lcStmt != null)
10054                    {
10055                        findNewStmt = true;
10056                        if (lcStmt.sqlstatementtype == ESqlStatementType.sstselect)
10057                        {
10058                            TSourceToken prevst = ast.prevSolidToken();
10059                            if ((prevst.tokencode == TBaseType.rrw_as) || (prevst.tokencode == '(')|| (prevst.tokencode == ')'))
10060                            {
10061                                findNewStmt = false;
10062                            }
10063                        }
10064                    }
10065                }
10066                if (findNewStmt)
10067                {
10068                    doongetrawsqlstatementevent(gcurrentsqlstatement);
10069                    gcurrentsqlstatement = lcStmt;
10070                    gcurrentsqlstatement.addtokentolist(ast);
10071                    continue;
10072                }
10073                else
10074                    gcurrentsqlstatement.addtokentolist(ast);
10075
10076                break;
10077            }//case stsql
10078
10079            case ststoredprocedure:{
10080
10081                if (procedure_status[nestedProcedures] != stored_procedure_status.bodyend){
10082                    gcurrentsqlstatement.addtokentolist(ast);
10083                }
10084
10085                switch (procedure_status[nestedProcedures]){
10086                    case cursor_declare:
10087                        if (ast.tokencode == ';'){
10088                            nestedProcedures--;
10089                            if (nestedProcedures < 0) nestedProcedures = 0;
10090                        }
10091                        break;
10092                    case start:
10093                        if ((ast.tokencode == TBaseType.rrw_as)||(ast.tokencode == TBaseType.rrw_is)){
10094                            // s1
10095                            if (sptype[nestedProcedures] != stored_procedure_type.create_trigger){
10096                                if ((sptype[0] == stored_procedure_type.package_spec) && (nestedProcedures > 0)){
10097                                 //when it's a package specification, only top level accept as/is
10098                                }else{
10099                                    procedure_status[nestedProcedures] = stored_procedure_status.is_as;
10100                                    if (ast.searchToken("language",1) != null){
10101                                        // if as language is used in create function, then switch state to stored_procedure_status.body directly.
10102//                                        CREATE OR REPLACE FUNCTION THING.addressparse(p_addressline1 VARCHAR2) RETURN VARCHAR2 AUTHID DEFINER
10103//                                        as Language JAVA NAME 'AddressParser.parse(java.lang.String) return java.lang.String';
10104//                                        /
10105                                        if (nestedProcedures == 0){
10106                                          //  procedure_status[nestedProcedures] = stored_procedure_status.bodyend;
10107                                            gst = EFindSqlStateType.stsql;
10108                                        }else{
10109                                            procedure_status[nestedProcedures] = stored_procedure_status.body;
10110                                            nestedProcedures--;
10111                                            //if (nestedProcedures > 0){ nestedProcedures--;}
10112                                        }
10113
10114                                    }
10115                                }
10116                            }
10117                        }else if(ast.tokencode == TBaseType.rrw_begin){
10118                            // s4
10119                            if (sptype[nestedProcedures] == stored_procedure_type.create_trigger) waitingEnds[nestedProcedures]++;
10120
10121                            if (nestedProcedures > 0) {nestedProcedures--;}
10122                            procedure_status[nestedProcedures] = stored_procedure_status.body;
10123                        }else if(ast.tokencode == TBaseType.rrw_end){
10124                            //s10
10125                            if((nestedProcedures > 0)&&(waitingEnds[nestedProcedures - 1] == 1)
10126                                    &&((sptype[nestedProcedures - 1] == stored_procedure_type.package_body)
10127                                        ||(sptype[nestedProcedures - 1] == stored_procedure_type.package_spec))){
10128                                nestedProcedures--;
10129                                procedure_status[nestedProcedures] = stored_procedure_status.bodyend;
10130                            }
10131                        }else if((ast.tokencode == TBaseType.rrw_procedure)||(ast.tokencode == TBaseType.rrw_function)){
10132                            //s3
10133                            if((nestedProcedures > 0)&&(waitingEnds[nestedProcedures] == 0)
10134                                    &&(procedure_status[nestedProcedures - 1] == stored_procedure_status.is_as)){
10135                                nestedProcedures--;
10136                                nestedProcedures++;
10137                                waitingEnds[nestedProcedures] = 0;
10138                                procedure_status[nestedProcedures] = stored_procedure_status.start;
10139                            }
10140                        }else if(ast.tokencode == TBaseType.rrw_oracle_cursor){
10141                            //s3, cursor in package specification
10142                            // PROCEDURE SM_23567_secondary_match;
10143                            // CURSOR active_lessors_cursor IS
10144                            if((nestedProcedures > 0)&&(waitingEnds[nestedProcedures] == 0)
10145                                    &&(procedure_status[nestedProcedures - 1] == stored_procedure_status.is_as)){
10146                                nestedProcedures--;
10147                                nestedProcedures++;
10148                                waitingEnds[nestedProcedures] = 0;
10149                                procedure_status[nestedProcedures] = stored_procedure_status.cursor_declare;
10150                            }
10151                        }else if ((sptype[nestedProcedures] == stored_procedure_type.create_trigger) && (ast.tokencode == TBaseType.rrw_declare) )
10152                        {
10153                            procedure_status[nestedProcedures] = stored_procedure_status.is_as;
10154                        }else if ((sptype[nestedProcedures] == stored_procedure_type.create_trigger)&&(ast.tokentype == ETokenType.ttslash)  && (ast.tokencode == TBaseType.sqlpluscmd) )
10155                        {
10156                          // TPlsqlStatementParse(asqlstatement).TerminatorToken := ast;
10157                           ast.tokenstatus = ETokenStatus.tsignorebyyacc;
10158                           gst = EFindSqlStateType.stnormal;
10159                           doongetrawsqlstatementevent(gcurrentsqlstatement);
10160
10161                           //make / a sqlplus cmd
10162                           gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
10163                           gcurrentsqlstatement.addtokentolist(ast);
10164                           doongetrawsqlstatementevent(gcurrentsqlstatement);
10165                        }else if ((sptype[nestedProcedures] == stored_procedure_type.create_trigger) )
10166                        {
10167                            if (ast.tokencode == TBaseType.rrw_trigger){
10168                                TSourceToken compoundSt =  ast.searchToken(TBaseType.rrw_oracle_compound, -1);
10169                                if (compoundSt != null){
10170                                    //it's trigger with compound trigger block
10171                                    procedure_status[nestedProcedures] = stored_procedure_status.body;
10172                                    waitingEnds[nestedProcedures]++;
10173                                }
10174                            }
10175                        }else if ((sptype[nestedProcedures] == stored_procedure_type.function)&&(ast.tokencode == TBaseType.rrw_teradata_using) )
10176                        {
10177                            if ((ast.searchToken("aggregate",-1) != null)||(ast.searchToken("pipelined",-1) != null)){
10178                                if (nestedProcedures == 0){
10179                                    //  procedure_status[nestedProcedures] = stored_procedure_status.bodyend;
10180                                    gst = EFindSqlStateType.stsql;
10181                                }else{
10182                                    procedure_status[nestedProcedures] = stored_procedure_status.body;
10183                                    nestedProcedures--;
10184                                }
10185                            }
10186
10187                        }else{
10188                            //other tokens, do nothing
10189                        }
10190                        break;
10191                    case is_as:
10192                        if((ast.tokencode == TBaseType.rrw_procedure)||(ast.tokencode == TBaseType.rrw_function)){
10193                          // s2
10194                          nestedProcedures++;
10195                          waitingEnds[nestedProcedures] = 0;
10196                          procedure_status[nestedProcedures] = stored_procedure_status.start;
10197
10198                          if (nestedProcedures > stored_procedure_nested_level - 1){
10199                              gst = EFindSqlStateType.sterror;
10200                              nestedProcedures--;
10201                          }
10202
10203                        }else if(ast.tokencode == TBaseType.rrw_begin){
10204                            // s5
10205                            if ((nestedProcedures == 0)&&
10206                                    ((sptype[nestedProcedures]==stored_procedure_type.package_body)
10207                                    ||(sptype[nestedProcedures]==stored_procedure_type.package_spec))){
10208                                //top level package or package body's BEGIN keyword already count,
10209                                // so don't increase waitingEnds[nestedProcedures] here
10210
10211                            }else {
10212                                waitingEnds[nestedProcedures]++;
10213                            }
10214                            procedure_status[nestedProcedures] = stored_procedure_status.body;
10215                        }else if(ast.tokencode == TBaseType.rrw_end){
10216                            // s6
10217                            if ((nestedProcedures == 0)&&(waitingEnds[nestedProcedures] == 1)&&
10218                                    ((sptype[nestedProcedures]==stored_procedure_type.package_body)||(sptype[nestedProcedures]==stored_procedure_type.package_spec))){
10219                              procedure_status[nestedProcedures] = stored_procedure_status.bodyend;
10220                              waitingEnds[nestedProcedures]--;
10221                            }else{
10222                                waitingEnds[nestedProcedures]--;
10223                            }
10224                        }else if(ast.tokencode == TBaseType.rrw_case)
10225                        {
10226//                            if (ast.searchToken(TBaseType.rrw_end,-1) == null){
10227//                                //this is not case after END
10228//                             waitingEnds[nestedProcedures]++;
10229//                            }
10230                            if (ast.searchToken(';',1) == null){
10231                                //this is not case before ;
10232                             waitingEnds[nestedProcedures]++;
10233                            }
10234                        }
10235                        else {
10236                            //other tokens, do nothing
10237                        }
10238                        break;
10239                    case body:
10240                        if ((ast.tokencode == TBaseType.rrw_begin))
10241                        {
10242                            waitingEnds[nestedProcedures]++;
10243                        } else if (ast.tokencode == TBaseType.rrw_if)
10244                        {
10245//                             if (ast.searchToken(TBaseType.rrw_end,-1) == null){
10246//                                 //this is not if after END
10247//                              waitingEnds[nestedProcedures]++;
10248//                            }
10249                            if (ast.searchToken(';',2) == null){
10250                                //this is not if before ;
10251
10252                                // 2015-02-27, change 1 to 2 make it able to detect label name after case
10253                                // like this: END CASE l1;
10254                             waitingEnds[nestedProcedures]++;
10255                            }
10256                        } else if(ast.tokencode == TBaseType.rrw_case)
10257                        {
10258//                            if (ast.searchToken(TBaseType.rrw_end,-1) == null){
10259//                                //this is not case after END
10260//                             waitingEnds[nestedProcedures]++;
10261//                            }
10262                            if (ast.searchToken(';',2) == null){
10263                                //this is not case before ;
10264                                if (ast.searchToken(TBaseType.rrw_end,-1) == null){
10265                                    waitingEnds[nestedProcedures]++;
10266                                }
10267                            }
10268                        } else if(ast.tokencode == TBaseType.rrw_loop)
10269                        {
10270                            if (!((ast.searchToken(TBaseType.rrw_end,-1) != null)
10271                                &&(ast.searchToken(';',2) != null))){
10272                                // exclude loop like this:
10273                                // end loop [labelname];
10274                             waitingEnds[nestedProcedures]++;
10275                            }
10276
10277//                            if (ast.searchToken(TBaseType.rrw_end,-1) == null){
10278//                                //this is not loop after END
10279//                             waitingEnds[nestedProcedures]++;
10280////                            }
10281////                            if (ast.searchToken(';',2) == null){
10282////                                //this is no loop before ;
10283////                             waitingEnds[nestedProcedures]++;
10284//                            } else if (ast.searchToken(TBaseType.rrw_null,1) != null){
10285//                                // mantis bug tracking system:   #65
10286//                                waitingEnds[nestedProcedures]++;
10287//                            }
10288                        }else if (ast.tokencode == TBaseType.rrw_end){
10289                            //foundEnd = true;
10290                            waitingEnds[nestedProcedures]--;
10291                            //if (waitingEnd < 0) { waitingEnd = 0;}
10292                            if (waitingEnds[nestedProcedures] == 0){
10293                                if (nestedProcedures == 0){
10294                                    // s7
10295                                    procedure_status[nestedProcedures] = stored_procedure_status.bodyend;
10296                                }else {
10297                                    // s71
10298                                    nestedProcedures--;
10299                                    procedure_status[nestedProcedures] = stored_procedure_status.is_as;
10300                                }
10301                            }
10302                        }else  if ((waitingEnds[nestedProcedures] == 0)&&(ast.tokentype == ETokenType.ttslash)  && (ast.tokencode == TBaseType.sqlpluscmd) ) //and (prevst.NewlineIsLastTokenInTailerToken)) then
10303                        {
10304                          //sql ref: c:\prg\gsqlparser\Test\TestCases\oracle\createtrigger.sql, line 53
10305                           ast.tokenstatus = ETokenStatus.tsignorebyyacc;
10306                           gst = EFindSqlStateType.stnormal;
10307                           doongetrawsqlstatementevent(gcurrentsqlstatement);
10308
10309                           //make / a sqlplus cmd
10310                           gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
10311                           gcurrentsqlstatement.addtokentolist(ast);
10312                           doongetrawsqlstatementevent(gcurrentsqlstatement);
10313                        }
10314                        break;
10315                    case bodyend:
10316                        if ((ast.tokentype == ETokenType.ttslash)  && (ast.tokencode == TBaseType.sqlpluscmd) ) //and (prevst.NewlineIsLastTokenInTailerToken)) then
10317                        {
10318                          // TPlsqlStatementParse(asqlstatement).TerminatorToken := ast;
10319                           ast.tokenstatus = ETokenStatus.tsignorebyyacc;
10320                           gst = EFindSqlStateType.stnormal;
10321                           doongetrawsqlstatementevent(gcurrentsqlstatement);
10322
10323                           //make / a sqlplus cmd
10324                           gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
10325                           gcurrentsqlstatement.addtokentolist(ast);
10326                           doongetrawsqlstatementevent(gcurrentsqlstatement);
10327                        } else  if ((ast.tokentype == ETokenType.ttperiod)  && (sourcetokenlist.returnaftercurtoken(false)) && (sourcetokenlist.returnbeforecurtoken(false)))
10328                        {    // single dot at a seperate line
10329                           ast.tokenstatus = ETokenStatus.tsignorebyyacc;
10330                           gst = EFindSqlStateType.stnormal;
10331                           doongetrawsqlstatementevent(gcurrentsqlstatement);
10332
10333                           //make ttperiod a sqlplus cmd
10334                           gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
10335                           gcurrentsqlstatement.addtokentolist(ast);
10336                           doongetrawsqlstatementevent(gcurrentsqlstatement);
10337                        } else  if ((ast.searchToken(TBaseType.rrw_package,1) != null)&&(!endBySlashOnly))
10338                        {
10339                            gcurrentsqlstatement.addtokentolist(ast);
10340                            gst = EFindSqlStateType.stnormal;
10341                            doongetrawsqlstatementevent(gcurrentsqlstatement);
10342                        } else  if ((ast.searchToken(TBaseType.rrw_procedure,1) != null)&&(!endBySlashOnly))
10343                        {
10344                            gcurrentsqlstatement.addtokentolist(ast);
10345                            gst = EFindSqlStateType.stnormal;
10346                            doongetrawsqlstatementevent(gcurrentsqlstatement);
10347                        } else  if ((ast.searchToken(TBaseType.rrw_function,1) != null)&&(!endBySlashOnly))
10348                        {
10349                            gcurrentsqlstatement.addtokentolist(ast);
10350                            gst = EFindSqlStateType.stnormal;
10351                            doongetrawsqlstatementevent(gcurrentsqlstatement);
10352                        } else  if ((ast.searchToken(TBaseType.rrw_create,1) != null)
10353                                &&((ast.searchToken(TBaseType.rrw_package,4) != null)||(ast.searchToken(TBaseType.rrw_package,5) != null))
10354                                &&(!endBySlashOnly))
10355                        {
10356                            gcurrentsqlstatement.addtokentolist(ast);
10357                            gst = EFindSqlStateType.stnormal;
10358                            doongetrawsqlstatementevent(gcurrentsqlstatement);
10359                        } else  if ((ast.searchToken(TBaseType.rrw_create,1) != null)
10360                                &&((ast.searchToken(TBaseType.rrw_procedure,4) != null)
10361                                    ||(ast.searchToken(TBaseType.rrw_function,4) != null)
10362                                    ||(ast.searchToken(TBaseType.rrw_view,4) != null)
10363                                    ||(ast.searchToken(TBaseType.rrw_oracle_synonym,4) != null)
10364                                ||(ast.searchToken(TBaseType.rrw_trigger,4) != null)
10365                                    )
10366                                &&(!endBySlashOnly))
10367                        {
10368                            gcurrentsqlstatement.addtokentolist(ast);
10369                            gst = EFindSqlStateType.stnormal;
10370                            doongetrawsqlstatementevent(gcurrentsqlstatement);
10371                        } else  if ((ast.searchToken(TBaseType.rrw_create,1) != null)&&(ast.searchToken(TBaseType.rrw_library,4) != null)&&(!endBySlashOnly))
10372                        {
10373                            gcurrentsqlstatement.addtokentolist(ast);
10374                            gst = EFindSqlStateType.stnormal;
10375                            doongetrawsqlstatementevent(gcurrentsqlstatement);
10376                        } else  if ((ast.searchToken(TBaseType.rrw_alter,1) != null)&&(ast.searchToken(TBaseType.rrw_trigger,2) != null)&&(!endBySlashOnly))
10377                        {
10378                            gcurrentsqlstatement.addtokentolist(ast);
10379                            gst = EFindSqlStateType.stnormal;
10380                            doongetrawsqlstatementevent(gcurrentsqlstatement);
10381                        } else  if ((ast.searchToken(TBaseType.rrw_select,1) != null)&&(!endBySlashOnly))
10382                        {
10383                            gcurrentsqlstatement.addtokentolist(ast);
10384                            gst = EFindSqlStateType.stnormal;
10385                            doongetrawsqlstatementevent(gcurrentsqlstatement);
10386                        } else  if ((ast.searchToken(TBaseType.rrw_call,1) != null)&&(!endBySlashOnly))
10387                        {
10388                            gcurrentsqlstatement.addtokentolist(ast);
10389                            gst = EFindSqlStateType.stnormal;
10390                            doongetrawsqlstatementevent(gcurrentsqlstatement);
10391                        } else  if ((ast.searchToken(TBaseType.rrw_commit,1) != null)&&(!endBySlashOnly))
10392                        {
10393                            gcurrentsqlstatement.addtokentolist(ast);
10394                            gst = EFindSqlStateType.stnormal;
10395                            doongetrawsqlstatementevent(gcurrentsqlstatement);
10396                        } else  if ((ast.searchToken(TBaseType.rrw_declare,1) != null)&&(!endBySlashOnly))
10397                        {
10398                            gcurrentsqlstatement.addtokentolist(ast);
10399                            gst = EFindSqlStateType.stnormal;
10400                            doongetrawsqlstatementevent(gcurrentsqlstatement);
10401                        } else  if ((ast.searchToken(TBaseType.rrw_grant,1) != null)&&
10402                                    (ast.searchToken(TBaseType.rrw_execute,2) != null)&&(!endBySlashOnly))
10403                        {
10404                            gcurrentsqlstatement.addtokentolist(ast);
10405                            gst = EFindSqlStateType.stnormal;
10406                            doongetrawsqlstatementevent(gcurrentsqlstatement);
10407                        } else  if ((ast.searchToken(TBaseType.rrw_alter,1) != null)&&
10408                                (ast.searchToken(TBaseType.rrw_table,2) != null)&&(!endBySlashOnly))
10409                        {
10410                            gcurrentsqlstatement.addtokentolist(ast);
10411                            gst = EFindSqlStateType.stnormal;
10412                            doongetrawsqlstatementevent(gcurrentsqlstatement);
10413                        }else {
10414                            gcurrentsqlstatement.addtokentolist(ast);
10415                        }
10416                        break;
10417                    case end:
10418                        break;
10419                    default:
10420                        break;
10421                }
10422
10423
10424                 if (ast.tokencode == TBaseType.sqlpluscmd)
10425                 {
10426                     //change tokencode back to keyword or TBaseType.ident, because sqlplus cmd
10427                     //in a sql statement(almost is plsql block) is not really a sqlplus cmd
10428                     int m = flexer.getkeywordvalue(ast.astext);
10429                     if (m != 0)
10430                     {ast.tokencode = m;}
10431                     else if (ast.tokentype == ETokenType.ttslash){
10432                         ast.tokencode = '/';
10433                     }
10434                     else
10435                     {ast.tokencode = TBaseType.ident;}
10436                 }
10437
10438                final int wrapped_keyword_max_pos = 20;
10439                if ((ast.tokencode == TBaseType.rrw_wrapped)&&(ast.posinlist - gcurrentsqlstatement.sourcetokenlist.get(0).posinlist  < wrapped_keyword_max_pos)){
10440                    if (gcurrentsqlstatement instanceof TCommonStoredProcedureSqlStatement){
10441                       ((TCommonStoredProcedureSqlStatement)gcurrentsqlstatement).setWrapped(true);
10442                    }
10443
10444                    if (gcurrentsqlstatement instanceof TPlsqlCreatePackage){
10445                        if (ast.prevSolidToken() != null){
10446                            ((TPlsqlCreatePackage) gcurrentsqlstatement).setPackageName(fparser.getNf().createObjectNameWithPart(ast.prevSolidToken()));
10447                        }
10448                    }
10449                }
10450
10451                break;
10452            } //ststoredprocedure
10453
10454        } //switch
10455      }//for
10456
10457    //last statement
10458    if ((gcurrentsqlstatement != null) &&
10459        ((gst == EFindSqlStateType.stsqlplus) ||  (gst == EFindSqlStateType.stsql) || (gst == EFindSqlStateType.ststoredprocedure) ||
10460                    (gst == EFindSqlStateType.sterror)))
10461    {
10462        doongetrawsqlstatementevent(gcurrentsqlstatement);
10463    }
10464
10465  return syntaxErrors.size();
10466}
10467
10468int domdxgetrawsqlstatements(){
10469    int waitingEnd = 0;
10470    boolean foundEnd = false;
10471
10472    if ( TBaseType.assigned(sqlstatements) ) sqlstatements.clear();
10473    if ( ! TBaseType.assigned(sourcetokenlist) ) return -1;
10474
10475    gcurrentsqlstatement = null;
10476    EFindSqlStateType gst = EFindSqlStateType.stnormal;
10477    TSourceToken lcprevsolidtoken = null,ast = null;
10478
10479    for (int i=0 ; i < sourcetokenlist.size();i++)
10480      {
10481
10482          if ( (ast != null ) && (ast.issolidtoken() ))
10483            lcprevsolidtoken = ast;
10484
10485            ast = sourcetokenlist.get(i);
10486            sourcetokenlist.curpos = i;
10487
10488        switch(gst){
10489            case sterror:{
10490                if (ast.tokentype ==  ETokenType.ttsemicolon)
10491                {
10492                    gcurrentsqlstatement.sourcetokenlist.add(ast);
10493                    doongetrawsqlstatementevent(gcurrentsqlstatement);
10494                    gst = EFindSqlStateType.stnormal;
10495                }
10496                else
10497                {
10498                    gcurrentsqlstatement.sourcetokenlist.add(ast);
10499                }
10500                break;
10501            } //sterror
10502
10503            case stnormal:{
10504                if ((ast.tokencode  == TBaseType.cmtdoublehyphen)
10505                   || (ast.tokencode  == TBaseType.cmtslashstar)
10506                   || (ast.tokencode  == TBaseType.lexspace)
10507                   || (ast.tokencode  == TBaseType.lexnewline)
10508                   || (ast.tokentype  == ETokenType.ttsemicolon) )
10509                {
10510                   if (gcurrentsqlstatement != null)
10511                   {
10512                       gcurrentsqlstatement.addtokentolist(ast);
10513                   }
10514
10515                   if ((lcprevsolidtoken != null) && (ast.tokentype == ETokenType.ttsemicolon))
10516                   {
10517                       if (lcprevsolidtoken.tokentype == ETokenType.ttsemicolon )
10518                       {
10519                          // ;;;; continuous semicolon,treat it as comment
10520                           ast.tokentype = ETokenType.ttsimplecomment;
10521                           ast.tokencode =  TBaseType.cmtdoublehyphen;
10522                       }
10523                   }
10524
10525                   continue;
10526                }
10527
10528
10529                // find a tokentext to start sql or plsql mode
10530                gcurrentsqlstatement = sqlcmds.issql(ast, dbVendor,gst,gcurrentsqlstatement);
10531
10532                if (gcurrentsqlstatement != null)
10533                {
10534                    if (gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmdxscope)
10535                    {
10536                          gst = EFindSqlStateType.ststoredprocedure;
10537                          gcurrentsqlstatement.addtokentolist(ast);
10538                          foundEnd = false;
10539                          waitingEnd = 1;
10540                    }
10541                    else
10542                    {
10543                        gst = EFindSqlStateType.stsql;
10544                        gcurrentsqlstatement.addtokentolist(ast);
10545                    }
10546                }else{
10547                    //error tokentext found
10548
10549                    this.syntaxErrors.add( new TSyntaxError(ast.astext,ast.lineNo,(ast.columnNo < 0 ? 0:ast.columnNo)
10550                            ,"Error when tokenlize", EErrorType.spwarning,TBaseType.MSG_WARNING_ERROR_WHEN_TOKENIZE,null,ast.posinlist));
10551
10552                    ast.tokentype = ETokenType.tttokenlizererrortoken;
10553                    gst = EFindSqlStateType.sterror;
10554
10555                    gcurrentsqlstatement = new TUnknownSqlStatement(dbVendor);
10556                    gcurrentsqlstatement.sqlstatementtype = ESqlStatementType.sstinvalid;
10557                    gcurrentsqlstatement.addtokentolist(ast);
10558
10559                }
10560
10561                break;
10562            } // stnormal
10563
10564            case stsql:{
10565                if (ast.tokentype == ETokenType.ttsemicolon)
10566                {
10567                    gst = EFindSqlStateType.stnormal;
10568                    gcurrentsqlstatement.addtokentolist(ast);
10569                    gcurrentsqlstatement.semicolonended = ast;
10570                    doongetrawsqlstatementevent(gcurrentsqlstatement);
10571                    continue;
10572                }
10573
10574                gcurrentsqlstatement.addtokentolist(ast);
10575                break;
10576            }//case stsql
10577
10578            case ststoredprocedure:{
10579               if (ast.tokencode == TBaseType.rrw_if)
10580                {
10581                   waitingEnd++;
10582                }else if (ast.tokencode == TBaseType.rrw_case)
10583                {
10584                   waitingEnd++;
10585                }else if (ast.tokencode == TBaseType.rrw_scope)
10586                {
10587                    // ignore scrope after end keyword like this:
10588                    // end scope
10589                    if (lcprevsolidtoken.tokencode != TBaseType.rrw_end){
10590                        waitingEnd++;
10591                    }
10592                }else if (ast.tokencode == TBaseType.rrw_end){
10593                    foundEnd = true;
10594                    waitingEnd--;
10595                    if (waitingEnd < 0) { waitingEnd = 0;}
10596                }
10597
10598                gcurrentsqlstatement.addtokentolist(ast);
10599                if ((ast.tokentype == ETokenType.ttsemicolon) && (waitingEnd == 0) && (foundEnd)){
10600                    gst = EFindSqlStateType.stnormal;
10601                    doongetrawsqlstatementevent(gcurrentsqlstatement);
10602                }
10603
10604                break;
10605            } //ststoredprocedure
10606        } //switch
10607      }//for
10608
10609    //last statement
10610    if ((gcurrentsqlstatement != null) &&
10611        ((gst == EFindSqlStateType.stsql) || (gst == EFindSqlStateType.ststoredprocedure) ||
10612                    (gst == EFindSqlStateType.sterror)))
10613    {
10614        doongetrawsqlstatementevent(gcurrentsqlstatement);
10615    }
10616
10617  return syntaxErrors.size();
10618}
10619
10620int doimpalagetrawsqlstatements(){
10621   return dohivegetrawsqlstatements();
10622}
10623
10624int dohivegetrawsqlstatements(){
10625
10626        if ( TBaseType.assigned(sqlstatements) ) sqlstatements.clear();
10627        if ( ! TBaseType.assigned(sourcetokenlist) ) return -1;
10628
10629        gcurrentsqlstatement = null;
10630        EFindSqlStateType gst = EFindSqlStateType.stnormal;
10631        TSourceToken lcprevsolidtoken = null,ast = null;
10632
10633        for (int i=0 ; i < sourcetokenlist.size();i++)
10634          {
10635
10636              if ( (ast != null ) && (ast.issolidtoken() ))
10637                lcprevsolidtoken = ast;
10638
10639                ast = sourcetokenlist.get(i);
10640                sourcetokenlist.curpos = i;
10641
10642              if (ast.tokencode == TBaseType.hive_CharSetName){
10643                  TSourceToken st1 = ast.searchToken(TBaseType.hive_CharSetLiteral,1);
10644                  if (st1 == null){
10645                      ast.tokencode = TBaseType.ident;
10646                  }
10647              }else  if (ast.tokencode == TBaseType.rrw_date) {
10648                  TSourceToken st1 = ast.nextSolidToken(); //ast.searchToken('(',1);
10649                  if (st1 != null) {
10650                      if (st1.tokencode == '(') {
10651                          ast.tokencode = TBaseType.rrw_hive_DATE_FUNCTION;
10652                      }
10653                    }
10654              }else  if (ast.tokencode == TBaseType.rrw_sort) {
10655                  TSourceToken st1 = ast.searchToken(TBaseType.rrw_by,1);
10656                  if (st1 == null) {
10657                      ast.tokencode = TBaseType.ident;
10658                  }
10659              }
10660
10661            switch(gst){
10662                case sterror:{
10663                    if (ast.tokentype ==  ETokenType.ttsemicolon)
10664                    {
10665                        gcurrentsqlstatement.sourcetokenlist.add(ast);
10666                        doongetrawsqlstatementevent(gcurrentsqlstatement);
10667                        gst = EFindSqlStateType.stnormal;
10668                    }
10669                    else
10670                    {
10671                        gcurrentsqlstatement.sourcetokenlist.add(ast);
10672                    }
10673                    break;
10674                } //sterror
10675
10676                case stnormal:{
10677                    if ((ast.tokencode  == TBaseType.cmtdoublehyphen)
10678                       || (ast.tokencode  == TBaseType.cmtslashstar)
10679                       || (ast.tokencode  == TBaseType.lexspace)
10680                       || (ast.tokencode  == TBaseType.lexnewline)
10681                       || (ast.tokentype  == ETokenType.ttsemicolon) )
10682                    {
10683                       if (gcurrentsqlstatement != null)
10684                       {
10685                           gcurrentsqlstatement.addtokentolist(ast);
10686                       }
10687
10688                       if ((lcprevsolidtoken != null) && (ast.tokentype == ETokenType.ttsemicolon))
10689                       {
10690                           if (lcprevsolidtoken.tokentype == ETokenType.ttsemicolon )
10691                           {
10692                              // ;;;; continuous semicolon,treat it as comment
10693                               ast.tokentype = ETokenType.ttsimplecomment;
10694                               ast.tokencode =  TBaseType.cmtdoublehyphen;
10695                           }
10696                       }
10697
10698                       continue;
10699                    }
10700
10701
10702
10703                    gcurrentsqlstatement = sqlcmds.issql(ast, dbVendor,gst,gcurrentsqlstatement);
10704
10705                    if (gcurrentsqlstatement != null)
10706                    {
10707                            gst = EFindSqlStateType.stsql;
10708                            gcurrentsqlstatement.addtokentolist(ast);
10709                    }else{
10710                        //error tokentext found
10711
10712                        this.syntaxErrors.add( new TSyntaxError(ast.astext,ast.lineNo,(ast.columnNo < 0 ? 0:ast.columnNo)
10713                                ,"Error when tokenlize", EErrorType.spwarning,TBaseType.MSG_WARNING_ERROR_WHEN_TOKENIZE,null,ast.posinlist));
10714
10715                        ast.tokentype = ETokenType.tttokenlizererrortoken;
10716                        gst = EFindSqlStateType.sterror;
10717
10718                        gcurrentsqlstatement = new TUnknownSqlStatement(dbVendor);
10719                        gcurrentsqlstatement.sqlstatementtype = ESqlStatementType.sstinvalid;
10720                        gcurrentsqlstatement.addtokentolist(ast);
10721
10722                    }
10723
10724                    break;
10725                } // stnormal
10726
10727                case stsql:{
10728                    if (ast.tokentype == ETokenType.ttsemicolon)
10729                    {
10730                        gst = EFindSqlStateType.stnormal;
10731                        gcurrentsqlstatement.addtokentolist(ast);
10732                        gcurrentsqlstatement.semicolonended = ast;
10733                        doongetrawsqlstatementevent(gcurrentsqlstatement);
10734                        continue;
10735                    }
10736
10737                    gcurrentsqlstatement.addtokentolist(ast);
10738                    break;
10739                }//case stsql
10740
10741            } //switch
10742          }//for
10743
10744        //last statement
10745        if ((gcurrentsqlstatement != null) &&
10746            ((gst == EFindSqlStateType.stsql) ||(gst == EFindSqlStateType.sterror)))
10747        {
10748            doongetrawsqlstatementevent(gcurrentsqlstatement);
10749        }
10750
10751      return syntaxErrors.size();
10752    }
10753
10754 int dosybasegetrawsqlstatements(){
10755    int errorcount = 0;
10756    int case_end_nest = 0;
10757
10758    if ( TBaseType.assigned(sqlstatements) ) sqlstatements.clear();
10759    if ( ! TBaseType.assigned(sourcetokenlist) ) return -1;
10760
10761    gcurrentsqlstatement = null;
10762    EFindSqlStateType gst = EFindSqlStateType.stnormal;
10763    int lcblocklevel = 0;
10764    int lctrycatchlevel = 0;
10765    TSourceToken lcprevsolidtoken = null,lcnextsolidtoken,lcnnextsolidtoken;
10766    TSourceToken ast = null;
10767    int i;
10768    boolean lcisendconversation, lcstillinsql;
10769
10770    for (i=0 ; i < sourcetokenlist.size();i++)
10771      {
10772
10773          if ( (ast != null ) && (ast.issolidtoken() ))
10774            lcprevsolidtoken = ast;
10775
10776        ast = sourcetokenlist.get(i);
10777        sourcetokenlist.curpos = i;
10778        if ( ast.tokenstatus == ETokenStatus.tsignoredbygetrawstatement )
10779          {
10780            //tsignoredbygetrawstatement is set when cte is found in dbcmds.findcte function
10781            gcurrentsqlstatement.sourcetokenlist.add(ast);
10782            continue;
10783          }
10784
10785        if ( gst == EFindSqlStateType.ststoredprocedurebody )
10786          {
10787            if ( !(
10788                (ast.tokencode == TBaseType.rrw_go)
10789                || (ast.tokencode == TBaseType.rrw_create)
10790                || (ast.tokencode == TBaseType.rrw_alter) )
10791              )
10792              {
10793                gcurrentsqlstatement.sourcetokenlist.add(ast);
10794                continue;
10795              }
10796          }
10797
10798        TCustomSqlStatement lcnextsqlstatement =  sqlcmds.issql(ast, dbVendor,gst,gcurrentsqlstatement);
10799
10800        switch(gst){
10801          case sterror:
10802            {
10803              if ( TBaseType.assigned(lcnextsqlstatement) )
10804                {
10805                  doongetrawsqlstatementevent(gcurrentsqlstatement);
10806                  gcurrentsqlstatement = lcnextsqlstatement;
10807                  gcurrentsqlstatement.sourcetokenlist.add(ast);
10808                  gst = EFindSqlStateType.stsql;
10809                }
10810              else if ( (ast.tokentype == ETokenType.ttsemicolon) )
10811                {
10812                  gcurrentsqlstatement.sourcetokenlist.add(ast);
10813                  doongetrawsqlstatementevent(gcurrentsqlstatement);
10814                  gst = EFindSqlStateType.stnormal;
10815                }
10816              else
10817                {
10818                  gcurrentsqlstatement.sourcetokenlist.add(ast);
10819                }
10820                break;
10821            }
10822          case stnormal :
10823            {
10824              if ( (ast.tokencode  == TBaseType.cmtdoublehyphen)
10825                 || (ast.tokencode  == TBaseType.cmtslashstar)
10826                 || (ast.tokencode  == TBaseType.lexspace)
10827                 || (ast.tokencode  == TBaseType.lexnewline)
10828                 || (ast.tokentype  == ETokenType.ttsemicolon) )
10829                {
10830                 if ( TBaseType.assigned(gcurrentsqlstatement) )
10831                   {
10832                     gcurrentsqlstatement.addtokentolist(ast);
10833                   }
10834
10835                 if ( TBaseType.assigned(lcprevsolidtoken) && (ast.tokentype == ETokenType.ttsemicolon) )
10836                   {
10837                     if ( lcprevsolidtoken.tokentype == ETokenType.ttsemicolon )
10838                       {
10839                        // ;;;; continuous semicolon,treat it as comment
10840                         ast.tokentype = ETokenType.ttsimplecomment;
10841                         ast.tokencode =  TBaseType.cmtdoublehyphen;
10842                       }
10843                     else
10844                       {
10845                       }
10846
10847                   }
10848
10849                 continue;
10850                }
10851
10852              gcurrentsqlstatement = lcnextsqlstatement; //isstoredprocedure(ast,dbvendor,gst,sqlstatements);
10853
10854              if ( TBaseType.assigned(gcurrentsqlstatement) )
10855                {
10856                  switch(gcurrentsqlstatement.sqlstatementtype){    //
10857                    case sstmssqlcreateprocedure:
10858                    case sstmssqlcreatefunction:
10859                    case sstcreatetrigger:
10860                    case sstmssqlalterprocedure:
10861                    case   sstmssqlalterfunction:
10862                    case sstmssqlaltertrigger:
10863                      {
10864                        gcurrentsqlstatement.addtokentolist(ast);
10865                        gst = EFindSqlStateType.ststoredprocedure;
10866                        break;
10867                      }
10868                    case sstmssqlbegintry:
10869                    case sstmssqlbegincatch:
10870                      {
10871                        gcurrentsqlstatement.addtokentolist(ast);
10872                        gst = EFindSqlStateType.sttrycatch;
10873                        lctrycatchlevel = 0;
10874                          break;
10875                      }
10876                    case sstmssqlgo:
10877                      {
10878                        gcurrentsqlstatement.addtokentolist(ast);
10879                        doongetrawsqlstatementevent(gcurrentsqlstatement);
10880                        gst = EFindSqlStateType.stnormal;
10881                          break;
10882                      }
10883                    default:
10884                      {
10885                        gcurrentsqlstatement.addtokentolist(ast);
10886                        if (gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqllabel){
10887                            doongetrawsqlstatementevent(gcurrentsqlstatement);
10888                            gst = EFindSqlStateType.stnormal;
10889                        }else{
10890                            gst = EFindSqlStateType.stsql;
10891                        }
10892                          break;
10893                      }
10894                  }    // case
10895                }
10896              else
10897                {
10898                  if ( ast.tokencode == TBaseType.rrw_begin )
10899                    {
10900                      gcurrentsqlstatement = new TMssqlBlock(dbVendor);
10901                      gcurrentsqlstatement.sqlstatementtype = ESqlStatementType.sstmssqlblock;
10902                      gcurrentsqlstatement.addtokentolist(ast);
10903                      gst = EFindSqlStateType.stblock;
10904                    }
10905                  else
10906                    {
10907                      if ( sqlstatements.size() == 0 )
10908                        {
10909                          //first statement of mssql batch, treat it as exec sp
10910                          gst = EFindSqlStateType.stsql;
10911                          gcurrentsqlstatement = new TMssqlExecute(dbVendor);
10912                            ast.tokencode = TBaseType.rrw_sybase_exce_proc_name;
10913                          //tmssqlexecute(gcurrentsqlstatement).exectype = metnoexeckeyword;
10914// todo need previous line need to be implemented
10915                          gcurrentsqlstatement.addtokentolist(ast);
10916                        }
10917                      else if ( sqlstatements.get(sqlstatements.size() -1).sqlstatementtype == ESqlStatementType.sstmssqlgo )
10918                        {
10919                          // prev sql is go, treat it as exec sp
10920                          gst = EFindSqlStateType.stsql;
10921                          gcurrentsqlstatement = new TMssqlExecute(dbVendor);
10922                            ast.tokencode = TBaseType.rrw_sybase_exce_proc_name;
10923                          //todo need to be implemented: tmssqlexecute(gcurrentsqlstatement).exectype = metnoexeckeyword;
10924                          gcurrentsqlstatement.addtokentolist(ast);
10925                        }
10926                      else
10927                        {
10928                        }
10929                    }
10930                }
10931
10932
10933              if (  !TBaseType.assigned(gcurrentsqlstatement)  ) //error tokentext found
10934                {
10935
10936//                  if ( TBaseType.assigned(ontokenlizertokenerror) )
10937//                    ontokenlizertokenerror(self,ast);
10938//                  incerrorcount;
10939//                  fsyntaxerrors[ferrorcount].hint = 'error when tokenlize';
10940//                  fsyntaxerrors[ferrorcount].errortype = spwarning;
10941//                  fsyntaxerrors[ferrorcount].tokentext = ast.sourcecode;
10942//                  fsyntaxerrors[ferrorcount].lines = ast.lines;
10943//                  fsyntaxerrors[ferrorcount].columns = ast.columns;// - length(fsyntaxerrors[ferrorcount].tokentext);
10944
10945//                  errormessage = "error when tokenlize:"+ast.astext+"("+ast.lineNo +","+ast.columnNo +")";
10946//                  errorcount = 1;
10947                    this.syntaxErrors.add( new TSyntaxError(ast.astext,ast.lineNo,(ast.columnNo < 0 ? 0:ast.columnNo)
10948                            ,"Error when tokenlize", EErrorType.spwarning,TBaseType.MSG_WARNING_ERROR_WHEN_TOKENIZE,null,ast.posinlist));
10949
10950                  ast.tokentype = ETokenType.tttokenlizererrortoken;
10951                  gst = EFindSqlStateType.sterror;
10952
10953                  gcurrentsqlstatement = new TUnknownSqlStatement(dbVendor);
10954                  gcurrentsqlstatement.sqlstatementtype = ESqlStatementType.sstinvalid;
10955                  gcurrentsqlstatement.addtokentolist(ast);
10956                }
10957                break;
10958            }
10959          case stblock:
10960            {
10961              if ( TBaseType.assigned(lcnextsqlstatement) )
10962                {
10963                  if ( lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlgo )
10964                    {
10965                        doongetrawsqlstatementevent(gcurrentsqlstatement);
10966                        gcurrentsqlstatement = lcnextsqlstatement;
10967                        gcurrentsqlstatement.addtokentolist(ast);
10968                        doongetrawsqlstatementevent(gcurrentsqlstatement);
10969                        gst = EFindSqlStateType.stnormal;
10970                    }
10971                  else
10972                    {
10973                      lcnextsqlstatement = null;
10974                    }
10975                }
10976
10977              if ( gst == EFindSqlStateType.stblock )
10978                {
10979                  gcurrentsqlstatement.addtokentolist(ast);
10980                  if ( ast.tokencode == TBaseType.rrw_begin )
10981                    {
10982                      // { [distributed] transaxtion/trans statement
10983                      // { dialog [ conversation ]
10984                      // { conversation timer
10985                      //  doesn't start block ({ .. })
10986                      lcnextsolidtoken = sourcetokenlist.nextsolidtoken(i,1,false);
10987                      if ( TBaseType.assigned(lcnextsolidtoken) )
10988                        {
10989                          if ( ! (TBaseType.mysametext(lcnextsolidtoken.astext,"tran")
10990                                  || TBaseType.mysametext(lcnextsolidtoken.astext,"transaction")
10991                                  || TBaseType.mysametext(lcnextsolidtoken.astext,"distributed")
10992                                  || TBaseType.mysametext(lcnextsolidtoken.astext,"dialog")
10993                                  || TBaseType.mysametext(lcnextsolidtoken.astext,"conversation")
10994                                  ) )
10995                           lcblocklevel++;
10996                        }
10997                      else
10998                        lcblocklevel++;
10999
11000                    }
11001                  else if ( ast.tokencode == TBaseType.rrw_case )  // case ... }
11002                    lcblocklevel++;
11003                  else if ( ast.tokencode == TBaseType.rrw_end )
11004                    {
11005
11006                      lcisendconversation = false;
11007
11008
11009                      lcnextsolidtoken = sourcetokenlist.nextsolidtoken(i,1,false);
11010                      if ( TBaseType.assigned(lcnextsolidtoken) )
11011                        {
11012                          if ( lcnextsolidtoken.tokencode == flexer.getkeywordvalue("conversation".toUpperCase()))
11013                            lcisendconversation = true; // } conversation statement
11014                        }
11015
11016
11017                      if ( ! lcisendconversation )
11018                        {
11019
11020                          if ( lcblocklevel == 0 )
11021                            {
11022                              if ( gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlif )
11023                                {
11024                                  if ( TBaseType.assigned(lcnextsolidtoken) )
11025                                    {
11026                                      if ( lcnextsolidtoken.tokencode == TBaseType.rrw_else )
11027                                        {
11028                                          // { .. } else
11029                                          gst = EFindSqlStateType.stsql;
11030                                        }
11031                                      else if ( lcnextsolidtoken.tokentype == ETokenType.ttsemicolon )
11032                                        {
11033                                          lcnnextsolidtoken = sourcetokenlist.nextsolidtoken(lcnextsolidtoken.posinlist,1,false);
11034                                          if ( TBaseType.assigned(lcnnextsolidtoken) )
11035                                            {
11036                                              if ( lcnnextsolidtoken.tokencode == TBaseType.rrw_else )
11037                                                {
11038                                                  // { .. } else
11039                                                  gst = EFindSqlStateType.stsql;
11040                                                }
11041                                            }
11042                                        }
11043                                    }
11044                                }
11045
11046                              if ( gst != EFindSqlStateType.stsql )
11047                                {
11048                                  doongetrawsqlstatementevent(gcurrentsqlstatement);
11049                                  gst = EFindSqlStateType.stnormal;
11050                                }
11051
11052                            }
11053                          else
11054                            {
11055                              lcblocklevel--;
11056                            }
11057
11058                        }
11059                    }
11060                }
11061                break;
11062            }
11063          case sttrycatch:
11064            {
11065
11066              if ( TBaseType.assigned(lcnextsqlstatement) )
11067                {
11068                  if ( lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlgo )
11069                    {
11070                        doongetrawsqlstatementevent(gcurrentsqlstatement);
11071                        gcurrentsqlstatement = lcnextsqlstatement;
11072                        gcurrentsqlstatement.addtokentolist(ast);
11073                        doongetrawsqlstatementevent(gcurrentsqlstatement);
11074                        gst = EFindSqlStateType.stnormal;
11075                    }
11076                  else
11077                    {
11078                      if (
11079                              (lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlbegintry)
11080                              ||(lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlbegincatch)
11081                        )
11082                         lctrycatchlevel++;
11083                      lcnextsqlstatement = null;
11084                    }
11085                }
11086
11087              if ( gst == EFindSqlStateType.sttrycatch )
11088                {
11089                  gcurrentsqlstatement.addtokentolist(ast);
11090                  if ( (ast.tokencode == TBaseType.rrw_try) ||
11091                    (ast.tokencode == TBaseType.rrw_catch) )
11092                    {
11093                     // lcprevsolidtoken = sourcetokenlist.solidtokenbefore(i);
11094                      if ( TBaseType.assigned(lcprevsolidtoken) )
11095                        {
11096                          if ( lcprevsolidtoken.tokencode == TBaseType.rrw_end )
11097                            {
11098                              if ( lctrycatchlevel == 0 )
11099                                {
11100                                  doongetrawsqlstatementevent(gcurrentsqlstatement);
11101                                  gst = EFindSqlStateType.stnormal;
11102                                }
11103                              else
11104                                lctrycatchlevel--;
11105                            }
11106                        }
11107                    }
11108                }
11109            break;
11110            }
11111          case stsql :
11112            {
11113              if ( (ast.tokentype == ETokenType.ttsemicolon)   )
11114                {
11115                  lcstillinsql = false;
11116                  if ( gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlif )
11117                    {
11118                      lcnextsolidtoken = sourcetokenlist.nextsolidtoken(i,1,false);
11119                      if ( TBaseType.assigned(lcnextsolidtoken) )
11120                        {
11121                          if ( lcnextsolidtoken.tokencode == TBaseType.rrw_else )
11122                            {
11123                              // if ( expr stmt; else
11124                              gcurrentsqlstatement.addtokentolist(ast);
11125                              lcstillinsql = true;
11126                            }
11127
11128                        }
11129                    }
11130
11131                  if (  !lcstillinsql )
11132                    {
11133                      gst = EFindSqlStateType.stnormal;
11134                      gcurrentsqlstatement.addtokentolist(ast);
11135                      gcurrentsqlstatement.semicolonended = ast;
11136                      doongetrawsqlstatementevent(gcurrentsqlstatement);
11137                    }
11138
11139                }
11140              else if ( TBaseType.assigned(lcnextsqlstatement) )
11141                {
11142
11143                  if ( lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlgo )
11144                    {
11145                        doongetrawsqlstatementevent(gcurrentsqlstatement);
11146                        gcurrentsqlstatement = lcnextsqlstatement;
11147                        gcurrentsqlstatement.addtokentolist(ast);
11148                        doongetrawsqlstatementevent(gcurrentsqlstatement);
11149                        gst = EFindSqlStateType.stnormal;
11150                        continue;
11151                    }
11152
11153                  switch(gcurrentsqlstatement.sqlstatementtype){    //
11154                    case sstmssqlif:
11155                    case sstmssqlwhile:
11156                      {
11157                        if ((lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlbegincatch)
11158                                ||(lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlbegintry))
11159                            {
11160                                gcurrentsqlstatement.addtokentolist(ast);
11161                                gst = EFindSqlStateType.stblock;
11162                                lcblocklevel = 1;
11163                                lcnextsqlstatement = null;
11164                                continue;
11165
11166                        }
11167                        // if ( || while only contain one sql(not closed by {/} pair)
11168                        // so will still in if ( || while statement
11169                        else if ( gcurrentsqlstatement.dummytag == 1 )
11170                          {
11171                            // if ( cond ^stmt nextstmt (^ stands for current pos)
11172                            gcurrentsqlstatement.addtokentolist(ast);
11173
11174                            if ( (lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlif)
11175                            || (lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlwhile)
11176                              )
11177                                gcurrentsqlstatement.dummytag = 1;
11178                              else
11179                                gcurrentsqlstatement.dummytag = 0;
11180
11181
11182                            lcnextsqlstatement = null;
11183                            continue;
11184                          }
11185                      break;
11186                      }//
11187                    case sstmssqlalterqueue:
11188                      {
11189                       if ( lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlexec )
11190                        {
11191                            // execute can't be used to delimite alter queue
11192                            gcurrentsqlstatement.addtokentolist(ast);
11193
11194
11195                            lcnextsqlstatement = null;
11196                            continue;
11197
11198                        }
11199                      break;
11200                      }
11201                    case sstmssqlcreateschema:
11202                      {
11203                            gcurrentsqlstatement.addtokentolist(ast);
11204                            lcnextsqlstatement = null;
11205                            continue;
11206                      }
11207                  }//case
11208
11209                  doongetrawsqlstatementevent(gcurrentsqlstatement);
11210                  gcurrentsqlstatement = lcnextsqlstatement;
11211                  gcurrentsqlstatement.addtokentolist(ast);
11212
11213                  switch(gcurrentsqlstatement.sqlstatementtype){    //
11214                    case sstmssqlcreateprocedure:
11215                    case sstmssqlcreatefunction:
11216                    case sstcreatetrigger:
11217                    case sstmssqlalterprocedure:
11218                    case sstmssqlalterfunction:
11219                    case sstmssqlaltertrigger:
11220                      {
11221                        gst = EFindSqlStateType.ststoredprocedure;
11222                        break;
11223                      }
11224                    case sstmssqlbegintry:
11225                    case sstmssqlbegincatch:
11226                      {
11227                        gst = EFindSqlStateType.sttrycatch;
11228                        lctrycatchlevel = 0;
11229                        break;
11230                      }
11231                    case sstmssqlgo:
11232                      {
11233                        gst = EFindSqlStateType.stnormal;
11234                        break;
11235                      }
11236                    default:
11237                      {
11238                        gst = EFindSqlStateType.stsql;
11239                        break;
11240                      }
11241                  }    // case
11242
11243                }//TBaseType.assigned(lcnextsqlstatement)
11244              else if ( (ast.tokencode == TBaseType.rrw_begin) )
11245                {
11246                  if ( (gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlif)
11247                  || (gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlwhile)
11248                  )
11249                    {
11250                      // start block of if ( || while statement
11251                      gst = EFindSqlStateType.stblock;
11252                      lcblocklevel = 0;
11253                      gcurrentsqlstatement.addtokentolist(ast);
11254                    }
11255                   else if ( gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqldeclare )
11256                      {
11257                        doongetrawsqlstatementevent(gcurrentsqlstatement);
11258                        gcurrentsqlstatement = new TMssqlBlock(dbVendor);
11259                        gcurrentsqlstatement.sqlstatementtype = ESqlStatementType.sstmssqlblock;
11260                        gcurrentsqlstatement.addtokentolist(ast);
11261                        gst = EFindSqlStateType.stblock;
11262                      }
11263                  else
11264                    {
11265                      gcurrentsqlstatement.addtokentolist(ast);
11266                    }
11267                }
11268              else if ( (ast.tokencode == TBaseType.rrw_case) ){
11269                  case_end_nest++;
11270                  gcurrentsqlstatement.addtokentolist(ast);
11271              }
11272              else if ( (ast.tokencode == TBaseType.rrw_end) ){
11273                  if (case_end_nest > 0){
11274                      case_end_nest--;
11275                  }
11276                  gcurrentsqlstatement.addtokentolist(ast);
11277              }
11278              else if ( (ast.tokencode == TBaseType.rrw_else) )
11279                {
11280                  gcurrentsqlstatement.addtokentolist(ast);
11281                  // if ( cond stmt ^else stmt
11282                  if (( (gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlif)
11283                  || (gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlwhile)
11284                  ) && (case_end_nest == 0))
11285                    gcurrentsqlstatement.dummytag = 1; // reduce to 1 while stmt after else is found: if ( cond stmt ^else stmt
11286                }
11287              else
11288                {
11289                  gcurrentsqlstatement.addtokentolist(ast);
11290                  if (gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlset){
11291                        if (ast.tokencode == TBaseType.rrw_on){
11292                            gst = EFindSqlStateType.stnormal;
11293                            doongetrawsqlstatementevent(gcurrentsqlstatement);
11294                        }
11295                  }
11296                }
11297             break;
11298            }
11299          case ststoredprocedure:
11300            {
11301              if ( TBaseType.assigned(lcnextsqlstatement) )
11302                {
11303                  if ( lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlgo )
11304                    {
11305                        doongetrawsqlstatementevent(gcurrentsqlstatement);
11306                        gcurrentsqlstatement = lcnextsqlstatement;
11307                        gcurrentsqlstatement.addtokentolist(ast);
11308                        doongetrawsqlstatementevent(gcurrentsqlstatement);
11309                        gst = EFindSqlStateType.stnormal;
11310                    }
11311                  else
11312                    {
11313                      gst = EFindSqlStateType.ststoredprocedurebody;
11314                      gcurrentsqlstatement.addtokentolist(ast);
11315
11316                      lcnextsqlstatement = null;
11317                    }
11318                }
11319
11320              if ( gst == EFindSqlStateType.ststoredprocedure )
11321                {
11322                  gcurrentsqlstatement.addtokentolist(ast);
11323                  if ( ast.tokencode == TBaseType.rrw_begin )
11324                    {
11325                      gst = EFindSqlStateType.stblock;
11326                    }
11327                }
11328             break;
11329            } //stplsql
11330          case ststoredprocedurebody:
11331            {
11332              if ( TBaseType.assigned(lcnextsqlstatement) )
11333                {
11334                  switch(lcnextsqlstatement.sqlstatementtype){    //
11335                    case sstmssqlgo:
11336                      {
11337                          doongetrawsqlstatementevent(gcurrentsqlstatement);
11338                          gcurrentsqlstatement = lcnextsqlstatement;
11339                          gcurrentsqlstatement.addtokentolist(ast);
11340                          doongetrawsqlstatementevent(gcurrentsqlstatement);
11341                          gst = EFindSqlStateType.stnormal;
11342                          break;
11343                      }
11344                    case sstmssqlcreateprocedure:
11345                    case sstmssqlcreatefunction:
11346                    case sstcreatetrigger:
11347                    case sstmssqlalterprocedure:
11348                    case sstmssqlalterfunction:
11349                    case sstmssqlaltertrigger:
11350                      {
11351                        doongetrawsqlstatementevent(gcurrentsqlstatement);
11352                        gcurrentsqlstatement = lcnextsqlstatement;
11353                        gcurrentsqlstatement.addtokentolist(ast);
11354                        gst = EFindSqlStateType.ststoredprocedure;
11355                          break;
11356                      }
11357                    default:
11358                      {
11359                        lcnextsqlstatement = null;
11360                          break;
11361                      }
11362                  }//case
11363                }
11364
11365              if ( gst == EFindSqlStateType.ststoredprocedurebody )
11366                gcurrentsqlstatement.addtokentolist(ast);
11367            }
11368          break;
11369        } //case
11370      } //for
11371
11372
11373    //last statement
11374    if ( TBaseType.assigned(gcurrentsqlstatement) &&  (gst != EFindSqlStateType.stnormal))
11375      {
11376        doongetrawsqlstatementevent(gcurrentsqlstatement);
11377      }
11378
11379
11380
11381    return errorcount;
11382
11383}
11384
11385int doinformixgetrawsqlstatements(){
11386    int errorcount = 0;
11387    int case_end_nest = 0;
11388
11389    if ( TBaseType.assigned(sqlstatements) ) sqlstatements.clear();
11390    if ( ! TBaseType.assigned(sourcetokenlist) ) return -1;
11391
11392    gcurrentsqlstatement = null;
11393    EFindSqlStateType gst = EFindSqlStateType.stnormal;
11394    int lcblocklevel = 0;
11395    int lctrycatchlevel = 0;
11396    TSourceToken lcprevsolidtoken = null,lcnextsolidtoken,lcnnextsolidtoken;
11397    TSourceToken ast = null;
11398    int i;
11399    boolean lcisendconversation, lcstillinsql;
11400
11401    for (i=0 ; i < sourcetokenlist.size();i++)
11402      {
11403
11404          if ( (ast != null ) && (ast.issolidtoken() ))
11405            lcprevsolidtoken = ast;
11406
11407        ast = sourcetokenlist.get(i);
11408        sourcetokenlist.curpos = i;
11409        if ( ast.tokenstatus == ETokenStatus.tsignoredbygetrawstatement )
11410          {
11411            //tsignoredbygetrawstatement is set when cte is found in dbcmds.findcte function
11412            gcurrentsqlstatement.sourcetokenlist.add(ast);
11413            continue;
11414          }
11415
11416        if ( gst == EFindSqlStateType.ststoredprocedurebody )
11417          {
11418            if ( !(
11419                (ast.tokencode == TBaseType.rrw_go)
11420                || (ast.tokencode == TBaseType.rrw_create)
11421                || (ast.tokencode == TBaseType.rrw_alter) )
11422              )
11423              {
11424                gcurrentsqlstatement.sourcetokenlist.add(ast);
11425                continue;
11426              }
11427          }
11428
11429        TCustomSqlStatement lcnextsqlstatement =  sqlcmds.issql(ast, dbVendor,gst,gcurrentsqlstatement);
11430
11431        switch(gst){
11432          case sterror:
11433            {
11434              if ( TBaseType.assigned(lcnextsqlstatement) )
11435                {
11436                  doongetrawsqlstatementevent(gcurrentsqlstatement);
11437                  gcurrentsqlstatement = lcnextsqlstatement;
11438                  gcurrentsqlstatement.sourcetokenlist.add(ast);
11439                  gst = EFindSqlStateType.stsql;
11440                }
11441              else if ( (ast.tokentype == ETokenType.ttsemicolon) )
11442                {
11443                  gcurrentsqlstatement.sourcetokenlist.add(ast);
11444                  doongetrawsqlstatementevent(gcurrentsqlstatement);
11445                  gst = EFindSqlStateType.stnormal;
11446                }
11447              else
11448                {
11449                  gcurrentsqlstatement.sourcetokenlist.add(ast);
11450                }
11451                break;
11452            }
11453          case stnormal :
11454            {
11455              if ( (ast.tokencode  == TBaseType.cmtdoublehyphen)
11456                 || (ast.tokencode  == TBaseType.cmtslashstar)
11457                 || (ast.tokencode  == TBaseType.lexspace)
11458                 || (ast.tokencode  == TBaseType.lexnewline)
11459                 || (ast.tokentype  == ETokenType.ttsemicolon) )
11460                {
11461                 if ( TBaseType.assigned(gcurrentsqlstatement) )
11462                   {
11463                     gcurrentsqlstatement.addtokentolist(ast);
11464                   }
11465
11466                 if ( TBaseType.assigned(lcprevsolidtoken) && (ast.tokentype == ETokenType.ttsemicolon) )
11467                   {
11468                     if ( lcprevsolidtoken.tokentype == ETokenType.ttsemicolon )
11469                       {
11470                        // ;;;; continuous semicolon,treat it as comment
11471                         ast.tokentype = ETokenType.ttsimplecomment;
11472                         ast.tokencode =  TBaseType.cmtdoublehyphen;
11473                       }
11474                     else
11475                       {
11476                       }
11477
11478                   }
11479
11480                 continue;
11481                }
11482
11483              gcurrentsqlstatement = lcnextsqlstatement; //isstoredprocedure(ast,dbvendor,gst,sqlstatements);
11484
11485              if ( TBaseType.assigned(gcurrentsqlstatement) )
11486                {
11487                  switch(gcurrentsqlstatement.sqlstatementtype){    //
11488                    case sstinformixCreateProcedure:
11489                    case sstinformixCreateFunction:
11490                    case sstcreatetrigger:
11491                    case sstinformixAlterProcedure:
11492                    case sstinformixAlterFunction:
11493                      {
11494                        gcurrentsqlstatement.addtokentolist(ast);
11495                        gst = EFindSqlStateType.ststoredprocedure;
11496                        break;
11497                      }
11498                    case sstmssqlbegintry:
11499                    case sstmssqlbegincatch:
11500                      {
11501                        gcurrentsqlstatement.addtokentolist(ast);
11502                        gst = EFindSqlStateType.sttrycatch;
11503                        lctrycatchlevel = 0;
11504                          break;
11505                      }
11506                    case sstmssqlgo:
11507                      {
11508                        gcurrentsqlstatement.addtokentolist(ast);
11509                        doongetrawsqlstatementevent(gcurrentsqlstatement);
11510                        gst = EFindSqlStateType.stnormal;
11511                          break;
11512                      }
11513                    case sstinformixExecute:
11514                    {
11515                        gst = EFindSqlStateType.stExec;
11516                        break;
11517                    }
11518                    default:
11519                      {
11520                        gcurrentsqlstatement.addtokentolist(ast);
11521                        gst = EFindSqlStateType.stsql;
11522                          break;
11523                      }
11524                  }    // case
11525                }
11526              else
11527                {
11528                  if ( ast.tokencode == TBaseType.rrw_begin )
11529                    {
11530                      gcurrentsqlstatement = new TMssqlBlock(dbVendor);
11531                      gcurrentsqlstatement.sqlstatementtype = ESqlStatementType.sstmssqlblock;
11532                      gcurrentsqlstatement.addtokentolist(ast);
11533                      gst = EFindSqlStateType.stblock;
11534                    }
11535                  else
11536                    {
11537                      if ( sqlstatements.size() == 0 )
11538                        {
11539                          //first statement of mssql batch, treat it as exec sp
11540                          gst = EFindSqlStateType.stsql;
11541                          gcurrentsqlstatement = new TMssqlExecute(dbVendor);
11542                          //tmssqlexecute(gcurrentsqlstatement).exectype = metnoexeckeyword;
11543// todo need previous line need to be implemented
11544                          gcurrentsqlstatement.addtokentolist(ast);
11545                        }
11546                      else if ( sqlstatements.get(sqlstatements.size() -1).sqlstatementtype == ESqlStatementType.sstmssqlgo )
11547                        {
11548                          // prev sql is go, treat it as exec sp
11549                          gst = EFindSqlStateType.stsql;
11550                          gcurrentsqlstatement = new TMssqlExecute(dbVendor);
11551                          //todo need to be implemented: tmssqlexecute(gcurrentsqlstatement).exectype = metnoexeckeyword;
11552                          gcurrentsqlstatement.addtokentolist(ast);
11553                        }
11554                      else
11555                        {
11556                        }
11557                    }
11558                }
11559
11560
11561              if (  !TBaseType.assigned(gcurrentsqlstatement)  ) //error tokentext found
11562                {
11563
11564//                  if ( TBaseType.assigned(ontokenlizertokenerror) )
11565//                    ontokenlizertokenerror(self,ast);
11566//                  incerrorcount;
11567//                  fsyntaxerrors[ferrorcount].hint = 'error when tokenlize';
11568//                  fsyntaxerrors[ferrorcount].errortype = spwarning;
11569//                  fsyntaxerrors[ferrorcount].tokentext = ast.sourcecode;
11570//                  fsyntaxerrors[ferrorcount].lines = ast.lines;
11571//                  fsyntaxerrors[ferrorcount].columns = ast.columns;// - length(fsyntaxerrors[ferrorcount].tokentext);
11572
11573//                  errormessage = "error when tokenlize:"+ast.astext+"("+ast.lineNo +","+ast.columnNo +")";
11574//                  errorcount = 1;
11575                    this.syntaxErrors.add( new TSyntaxError(ast.astext,ast.lineNo,(ast.columnNo < 0 ? 0:ast.columnNo)
11576                            ,"Error when tokenlize", EErrorType.spwarning,TBaseType.MSG_WARNING_ERROR_WHEN_TOKENIZE,null,ast.posinlist));
11577
11578                  ast.tokentype = ETokenType.tttokenlizererrortoken;
11579                  gst = EFindSqlStateType.sterror;
11580
11581                  gcurrentsqlstatement = new TUnknownSqlStatement(dbVendor);
11582                  gcurrentsqlstatement.sqlstatementtype = ESqlStatementType.sstinvalid;
11583                  gcurrentsqlstatement.addtokentolist(ast);
11584                }
11585                break;
11586            }
11587          case stExec:
11588          {
11589              gcurrentsqlstatement.sourcetokenlist.add(ast);
11590              if  (ast.tokentype == ETokenType.ttsemicolon){
11591                  gst = EFindSqlStateType.stnormal;
11592                  doongetrawsqlstatementevent(gcurrentsqlstatement);
11593              }
11594              break;
11595          }
11596          case stblock:
11597            {
11598              if ( TBaseType.assigned(lcnextsqlstatement) )
11599                {
11600                  if ( lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlgo )
11601                    {
11602                        doongetrawsqlstatementevent(gcurrentsqlstatement);
11603                        gcurrentsqlstatement = lcnextsqlstatement;
11604                        gcurrentsqlstatement.addtokentolist(ast);
11605                        doongetrawsqlstatementevent(gcurrentsqlstatement);
11606                        gst = EFindSqlStateType.stnormal;
11607                    }
11608                  else
11609                    {
11610                      lcnextsqlstatement = null;
11611                    }
11612                }
11613
11614              if ( gst == EFindSqlStateType.stblock )
11615                {
11616                  gcurrentsqlstatement.addtokentolist(ast);
11617                  if ( ast.tokencode == TBaseType.rrw_begin )
11618                    {
11619                      // { [distributed] transaxtion/trans statement
11620                      // { dialog [ conversation ]
11621                      // { conversation timer
11622                      //  doesn't start block ({ .. })
11623                      lcnextsolidtoken = sourcetokenlist.nextsolidtoken(i,1,false);
11624                      if ( TBaseType.assigned(lcnextsolidtoken) )
11625                        {
11626                          if ( ! (TBaseType.mysametext(lcnextsolidtoken.astext,"tran")
11627                                  || TBaseType.mysametext(lcnextsolidtoken.astext,"transaction")
11628                                  || TBaseType.mysametext(lcnextsolidtoken.astext,"distributed")
11629                                  || TBaseType.mysametext(lcnextsolidtoken.astext,"dialog")
11630                                  || TBaseType.mysametext(lcnextsolidtoken.astext,"conversation")
11631                                  ) )
11632                           lcblocklevel++;
11633                        }
11634                      else
11635                        lcblocklevel++;
11636
11637                    }
11638                  else if ( ast.tokencode == TBaseType.rrw_case )  // case ... }
11639                    lcblocklevel++;
11640                  else if ( ast.tokencode == TBaseType.rrw_end )
11641                    {
11642
11643                      lcisendconversation = false;
11644
11645
11646                      lcnextsolidtoken = sourcetokenlist.nextsolidtoken(i,1,false);
11647                      if ( TBaseType.assigned(lcnextsolidtoken) )
11648                        {
11649                          if ( lcnextsolidtoken.tokencode == flexer.getkeywordvalue("conversation".toUpperCase()))
11650                            lcisendconversation = true; // } conversation statement
11651                        }
11652
11653
11654                      if ( ! lcisendconversation )
11655                        {
11656
11657                          if ( lcblocklevel == 0 )
11658                            {
11659                              if ( gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlif )
11660                                {
11661                                  if ( TBaseType.assigned(lcnextsolidtoken) )
11662                                    {
11663                                      if ( lcnextsolidtoken.tokencode == TBaseType.rrw_else )
11664                                        {
11665                                          // { .. } else
11666                                          gst = EFindSqlStateType.stsql;
11667                                        }
11668                                      else if ( lcnextsolidtoken.tokentype == ETokenType.ttsemicolon )
11669                                        {
11670                                          lcnnextsolidtoken = sourcetokenlist.nextsolidtoken(lcnextsolidtoken.posinlist,1,false);
11671                                          if ( TBaseType.assigned(lcnnextsolidtoken) )
11672                                            {
11673                                              if ( lcnnextsolidtoken.tokencode == TBaseType.rrw_else )
11674                                                {
11675                                                  // { .. } else
11676                                                  gst = EFindSqlStateType.stsql;
11677                                                }
11678                                            }
11679                                        }
11680                                    }
11681                                }
11682
11683                              if ( gst != EFindSqlStateType.stsql )
11684                                {
11685                                  doongetrawsqlstatementevent(gcurrentsqlstatement);
11686                                  gst = EFindSqlStateType.stnormal;
11687                                }
11688
11689                            }
11690                          else
11691                            {
11692                              lcblocklevel--;
11693                            }
11694
11695                        }
11696                    }
11697                }
11698                break;
11699            }
11700          case sttrycatch:
11701            {
11702
11703              if ( TBaseType.assigned(lcnextsqlstatement) )
11704                {
11705                  if ( lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlgo )
11706                    {
11707                        doongetrawsqlstatementevent(gcurrentsqlstatement);
11708                        gcurrentsqlstatement = lcnextsqlstatement;
11709                        gcurrentsqlstatement.addtokentolist(ast);
11710                        doongetrawsqlstatementevent(gcurrentsqlstatement);
11711                        gst = EFindSqlStateType.stnormal;
11712                    }
11713                  else
11714                    {
11715                      if (
11716                              (lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlbegintry)
11717                              ||(lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlbegincatch)
11718                        )
11719                         lctrycatchlevel++;
11720                      lcnextsqlstatement = null;
11721                    }
11722                }
11723
11724              if ( gst == EFindSqlStateType.sttrycatch )
11725                {
11726                  gcurrentsqlstatement.addtokentolist(ast);
11727                  if ( (ast.tokencode == TBaseType.rrw_try) ||
11728                    (ast.tokencode == TBaseType.rrw_catch) )
11729                    {
11730                     // lcprevsolidtoken = sourcetokenlist.solidtokenbefore(i);
11731                      if ( TBaseType.assigned(lcprevsolidtoken) )
11732                        {
11733                          if ( lcprevsolidtoken.tokencode == TBaseType.rrw_end )
11734                            {
11735                              if ( lctrycatchlevel == 0 )
11736                                {
11737                                  doongetrawsqlstatementevent(gcurrentsqlstatement);
11738                                  gst = EFindSqlStateType.stnormal;
11739                                }
11740                              else
11741                                lctrycatchlevel--;
11742                            }
11743                        }
11744                    }
11745                }
11746            break;
11747            }
11748          case stsql :
11749            {
11750              if ( (ast.tokentype == ETokenType.ttsemicolon)   )
11751                {
11752                  lcstillinsql = false;
11753                  if ( gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlif )
11754                    {
11755                      lcnextsolidtoken = sourcetokenlist.nextsolidtoken(i,1,false);
11756                      if ( TBaseType.assigned(lcnextsolidtoken) )
11757                        {
11758                          if ( lcnextsolidtoken.tokencode == TBaseType.rrw_else )
11759                            {
11760                              // if ( expr stmt; else
11761                              gcurrentsqlstatement.addtokentolist(ast);
11762                              lcstillinsql = true;
11763                            }
11764
11765                        }
11766                    }
11767
11768                  if (  !lcstillinsql )
11769                    {
11770                      gst = EFindSqlStateType.stnormal;
11771                      gcurrentsqlstatement.addtokentolist(ast);
11772                      gcurrentsqlstatement.semicolonended = ast;
11773                      doongetrawsqlstatementevent(gcurrentsqlstatement);
11774                    }
11775
11776                }
11777              else if ( TBaseType.assigned(lcnextsqlstatement) )
11778                {
11779
11780                  if ( lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlgo )
11781                    {
11782                        doongetrawsqlstatementevent(gcurrentsqlstatement);
11783                        gcurrentsqlstatement = lcnextsqlstatement;
11784                        gcurrentsqlstatement.addtokentolist(ast);
11785                        doongetrawsqlstatementevent(gcurrentsqlstatement);
11786                        gst = EFindSqlStateType.stnormal;
11787                        continue;
11788                    }
11789
11790                  switch(gcurrentsqlstatement.sqlstatementtype){    //
11791                    case sstmssqlif:
11792                    case sstmssqlwhile:
11793                      {
11794                        if ((lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlbegincatch)
11795                                ||(lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlbegintry))
11796                            {
11797                                gcurrentsqlstatement.addtokentolist(ast);
11798                                gst = EFindSqlStateType.stblock;
11799                                lcblocklevel = 1;
11800                                lcnextsqlstatement = null;
11801                                continue;
11802
11803                        }
11804                        // if ( || while only contain one sql(not closed by {/} pair)
11805                        // so will still in if ( || while statement
11806                        else if ( gcurrentsqlstatement.dummytag == 1 )
11807                          {
11808                            // if ( cond ^stmt nextstmt (^ stands for current pos)
11809                            gcurrentsqlstatement.addtokentolist(ast);
11810
11811                            if ( (lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlif)
11812                            || (lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlwhile)
11813                              )
11814                                gcurrentsqlstatement.dummytag = 1;
11815                              else
11816                                gcurrentsqlstatement.dummytag = 0;
11817
11818
11819                            lcnextsqlstatement = null;
11820                            continue;
11821                          }
11822                      break;
11823                      }//
11824                    case sstmssqlalterqueue:
11825                      {
11826                       if ( lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlexec )
11827                        {
11828                            // execute can't be used to delimite alter queue
11829                            gcurrentsqlstatement.addtokentolist(ast);
11830
11831
11832                            lcnextsqlstatement = null;
11833                            continue;
11834
11835                        }
11836                      break;
11837                      }
11838                    case sstmssqlcreateschema:
11839                      {
11840                            gcurrentsqlstatement.addtokentolist(ast);
11841                            lcnextsqlstatement = null;
11842                            continue;
11843                      }
11844                  }//case
11845
11846                  doongetrawsqlstatementevent(gcurrentsqlstatement);
11847                  gcurrentsqlstatement = lcnextsqlstatement;
11848                  gcurrentsqlstatement.addtokentolist(ast);
11849
11850                  switch(gcurrentsqlstatement.sqlstatementtype){    //
11851                    case sstinformixCreateProcedure:
11852                    case sstinformixCreateFunction:
11853                    case sstcreatetrigger:
11854                    case sstinformixAlterProcedure:
11855                    case sstinformixAlterFunction:
11856                      {
11857                        gst = EFindSqlStateType.ststoredprocedure;
11858                        break;
11859                      }
11860                    case sstmssqlbegintry:
11861                    case sstmssqlbegincatch:
11862                      {
11863                        gst = EFindSqlStateType.sttrycatch;
11864                        lctrycatchlevel = 0;
11865                        break;
11866                      }
11867                    case sstmssqlgo:
11868                      {
11869                        gst = EFindSqlStateType.stnormal;
11870                        break;
11871                      }
11872                    default:
11873                      {
11874                        gst = EFindSqlStateType.stsql;
11875                        break;
11876                      }
11877                  }    // case
11878
11879                }//TBaseType.assigned(lcnextsqlstatement)
11880              else if ( (ast.tokencode == TBaseType.rrw_begin) )
11881                {
11882                  if ( (gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlif)
11883                  || (gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlwhile)
11884                  )
11885                    {
11886                      // start block of if ( || while statement
11887                      gst = EFindSqlStateType.stblock;
11888                      lcblocklevel = 0;
11889                      gcurrentsqlstatement.addtokentolist(ast);
11890                    }
11891                   else if ( gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqldeclare )
11892                      {
11893                        doongetrawsqlstatementevent(gcurrentsqlstatement);
11894                        gcurrentsqlstatement = new TMssqlBlock(dbVendor);
11895                        gcurrentsqlstatement.sqlstatementtype = ESqlStatementType.sstmssqlblock;
11896                        gcurrentsqlstatement.addtokentolist(ast);
11897                        gst = EFindSqlStateType.stblock;
11898                      }
11899                  else
11900                    {
11901                      gcurrentsqlstatement.addtokentolist(ast);
11902                    }
11903                }
11904              else if ( (ast.tokencode == TBaseType.rrw_case) ){
11905                  case_end_nest++;
11906                  gcurrentsqlstatement.addtokentolist(ast);
11907              }
11908              else if ( (ast.tokencode == TBaseType.rrw_end) ){
11909                  if (case_end_nest > 0){
11910                      case_end_nest--;
11911                  }
11912                  gcurrentsqlstatement.addtokentolist(ast);
11913              }
11914              else if ( (ast.tokencode == TBaseType.rrw_else) )
11915                {
11916                  gcurrentsqlstatement.addtokentolist(ast);
11917                  // if ( cond stmt ^else stmt
11918                  if (( (gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlif)
11919                  || (gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlwhile)
11920                  ) && (case_end_nest == 0))
11921                    gcurrentsqlstatement.dummytag = 1; // reduce to 1 while stmt after else is found: if ( cond stmt ^else stmt
11922                }
11923              else
11924                {
11925                  gcurrentsqlstatement.addtokentolist(ast);
11926                }
11927             break;
11928            }
11929          case ststoredprocedure:
11930            {
11931              if ( TBaseType.assigned(lcnextsqlstatement) )
11932                {
11933                  if ( lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlgo )
11934                    {
11935                        doongetrawsqlstatementevent(gcurrentsqlstatement);
11936                        gcurrentsqlstatement = lcnextsqlstatement;
11937                        gcurrentsqlstatement.addtokentolist(ast);
11938                        doongetrawsqlstatementevent(gcurrentsqlstatement);
11939                        gst = EFindSqlStateType.stnormal;
11940                    }
11941                  else
11942                    {
11943                      gst = EFindSqlStateType.ststoredprocedurebody;
11944                      gcurrentsqlstatement.addtokentolist(ast);
11945
11946                      lcnextsqlstatement = null;
11947                    }
11948                }
11949
11950              if ( gst == EFindSqlStateType.ststoredprocedure )
11951                {
11952                  gcurrentsqlstatement.addtokentolist(ast);
11953                  if (( ast.tokencode == TBaseType.rrw_procedure )
11954                      ||( ast.tokencode == TBaseType.rrw_function ))
11955                    {
11956                        if (ast.searchToken(TBaseType.rrw_end,-1) != null)
11957                            gst = EFindSqlStateType.stsql;
11958                    }
11959                }
11960             break;
11961            } //stplsql
11962          case ststoredprocedurebody:
11963            {
11964              if ( TBaseType.assigned(lcnextsqlstatement) )
11965                {
11966                  switch(lcnextsqlstatement.sqlstatementtype){    //
11967                    case sstmssqlgo:
11968                      {
11969                          doongetrawsqlstatementevent(gcurrentsqlstatement);
11970                          gcurrentsqlstatement = lcnextsqlstatement;
11971                          gcurrentsqlstatement.addtokentolist(ast);
11972                          doongetrawsqlstatementevent(gcurrentsqlstatement);
11973                          gst = EFindSqlStateType.stnormal;
11974                          break;
11975                      }
11976                    case sstinformixCreateProcedure:
11977                    case sstinformixCreateFunction:
11978                    case sstcreatetrigger:
11979                    case sstinformixAlterProcedure:
11980                    case sstinformixAlterFunction:
11981                      {
11982                        doongetrawsqlstatementevent(gcurrentsqlstatement);
11983                        gcurrentsqlstatement = lcnextsqlstatement;
11984                        gcurrentsqlstatement.addtokentolist(ast);
11985                        gst = EFindSqlStateType.ststoredprocedure;
11986                          break;
11987                      }
11988                    default:
11989                      {
11990                        lcnextsqlstatement = null;
11991                          break;
11992                      }
11993                  }//case
11994                }
11995
11996              if ( gst == EFindSqlStateType.ststoredprocedurebody )
11997                gcurrentsqlstatement.addtokentolist(ast);
11998            }
11999          break;
12000        } //case
12001      } //for
12002
12003
12004    //last statement
12005    if ( TBaseType.assigned(gcurrentsqlstatement) &&  (gst != EFindSqlStateType.stnormal))
12006      {
12007        doongetrawsqlstatementevent(gcurrentsqlstatement);
12008      }
12009
12010
12011
12012    return errorcount;
12013
12014}
12015
12016    int dosoqlgetrawsqlstatements(){
12017        int errorcount = 0;
12018        int case_end_nest = 0;
12019
12020        if ( TBaseType.assigned(sqlstatements) ) sqlstatements.clear();
12021        if ( ! TBaseType.assigned(sourcetokenlist) ) return -1;
12022
12023        gcurrentsqlstatement = null;
12024        EFindSqlStateType gst = EFindSqlStateType.stnormal;
12025        int lcblocklevel = 0;
12026        int lctrycatchlevel = 0;
12027        TSourceToken lcprevsolidtoken = null,lcnextsolidtoken,lcnnextsolidtoken;
12028        TSourceToken ast = null;
12029        int i,lcMergeInSelectNested = 0;
12030        boolean lcisendconversation, lcstillinsql,lcMergeInSelect = false;
12031
12032        for (i=0 ; i < sourcetokenlist.size();i++)
12033        {
12034
12035            if ( (ast != null ) && (ast.issolidtoken() ))
12036                lcprevsolidtoken = ast;
12037
12038            ast = sourcetokenlist.get(i);
12039            sourcetokenlist.curpos = i;
12040
12041            if (lcMergeInSelect){
12042                if (ast.tokencode == '(') lcMergeInSelectNested++;
12043                if (ast.tokencode == ')'){
12044                    lcMergeInSelectNested--;
12045                    if (lcMergeInSelectNested == 0){
12046                        lcMergeInSelect = false;
12047                    }
12048                }
12049                gcurrentsqlstatement.sourcetokenlist.add(ast);
12050                continue;
12051            }
12052            if ( ast.tokenstatus == ETokenStatus.tsignoredbygetrawstatement )
12053            {
12054                //tsignoredbygetrawstatement is set when cte is found in dbcmds.findcte function
12055                gcurrentsqlstatement.sourcetokenlist.add(ast);
12056                continue;
12057            }
12058
12059            if (ast.tokencode == TBaseType.rrw_update) {
12060                TSourceToken st1 = ast.nextSolidToken();
12061                if (st1 != null) {
12062                    if (st1.toString().equalsIgnoreCase("tracking")
12063                    ||st1.toString().equalsIgnoreCase("viewstat")){ //UPDATE TRACKING|VIEWSTAT
12064                        ast.tokencode  = TBaseType.rrw_soql_update_tracking;
12065                    }
12066                }
12067            }
12068
12069            if (dbVendor == EDbVendor.dbvopenedge){
12070                if (ast.tokencode == TBaseType.rrw_order){
12071                    TSourceToken st1 = ast.searchToken(TBaseType.rrw_by,1);
12072                    if (st1 == null) {
12073                        ast.tokencode = TBaseType.ident;
12074                    }
12075                }else if (ast.tokencode == TBaseType.rrw_with){
12076                    TSourceToken st1 = ast.searchToken(TBaseType.rrw_check,1);
12077                    if (st1 != null) {
12078                        ast.tokencode = TBaseType.rrw_openedge_with_check;
12079                    }
12080                }
12081            }
12082
12083            if ( gst == EFindSqlStateType.ststoredprocedurebody )
12084            {
12085                if ( !(
12086                        (ast.tokencode == TBaseType.rrw_go)
12087                                || (ast.tokencode == TBaseType.rrw_create)
12088                                || (ast.tokencode == TBaseType.rrw_alter) )
12089                )
12090                {
12091                    gcurrentsqlstatement.sourcetokenlist.add(ast);
12092                    continue;
12093                }
12094            }
12095
12096            TCustomSqlStatement lcnextsqlstatement =  sqlcmds.issql(ast, dbVendor,gst,gcurrentsqlstatement);
12097
12098            switch(gst){
12099                case sterror:
12100                {
12101                    if ( TBaseType.assigned(lcnextsqlstatement) )
12102                    {
12103                        doongetrawsqlstatementevent(gcurrentsqlstatement);
12104                        gcurrentsqlstatement = lcnextsqlstatement;
12105                        gcurrentsqlstatement.sourcetokenlist.add(ast);
12106                        gst = EFindSqlStateType.stsql;
12107                    }
12108                    else if ( (ast.tokentype == ETokenType.ttsemicolon) )
12109                    {
12110                        gcurrentsqlstatement.sourcetokenlist.add(ast);
12111                        doongetrawsqlstatementevent(gcurrentsqlstatement);
12112                        gst = EFindSqlStateType.stnormal;
12113                    }
12114                    else
12115                    {
12116                        gcurrentsqlstatement.sourcetokenlist.add(ast);
12117                    }
12118                    break;
12119                }
12120                case stnormal :
12121                {
12122                    if ( (ast.tokencode  == TBaseType.cmtdoublehyphen)
12123                            || (ast.tokencode  == TBaseType.cmtslashstar)
12124                            || (ast.tokencode  == TBaseType.lexspace)
12125                            || (ast.tokencode  == TBaseType.lexnewline)
12126                            || (ast.tokentype  == ETokenType.ttsemicolon) )
12127                    {
12128                        if ( TBaseType.assigned(gcurrentsqlstatement) )
12129                        {
12130                            gcurrentsqlstatement.addtokentolist(ast);
12131                        }
12132
12133                        if ( TBaseType.assigned(lcprevsolidtoken) && (ast.tokentype == ETokenType.ttsemicolon) )
12134                        {
12135                            if ( lcprevsolidtoken.tokentype == ETokenType.ttsemicolon )
12136                            {
12137                                // ;;;; continuous semicolon,treat it as comment
12138                                ast.tokentype = ETokenType.ttsimplecomment;
12139                                ast.tokencode =  TBaseType.cmtdoublehyphen;
12140                            }
12141                            else
12142                            {
12143                            }
12144
12145                        }
12146
12147                        continue;
12148                    }
12149
12150                    gcurrentsqlstatement = lcnextsqlstatement; //isstoredprocedure(ast,dbvendor,gst,sqlstatements);
12151
12152                    if ( TBaseType.assigned(gcurrentsqlstatement) )
12153                    {
12154                        switch(gcurrentsqlstatement.sqlstatementtype){    //
12155                            case sstmssqlcreateprocedure:
12156                            case sstmssqlcreatefunction:
12157                                //case sstmssqlcreatetrigger:
12158                            case sstcreatetrigger:
12159                            case sstmssqlalterprocedure:
12160                            case   sstmssqlalterfunction:
12161                            case sstmssqlaltertrigger:
12162                            {
12163                                gcurrentsqlstatement.addtokentolist(ast);
12164                                gst = EFindSqlStateType.ststoredprocedure;
12165                                break;
12166                            }
12167                            case sstmssqlbegintry:
12168                            case sstmssqlbegincatch:
12169                            {
12170                                gcurrentsqlstatement.addtokentolist(ast);
12171                                gst = EFindSqlStateType.sttrycatch;
12172                                lctrycatchlevel = 0;
12173                                break;
12174                            }
12175                            case sstmssqlgo:
12176                            {
12177                                gcurrentsqlstatement.addtokentolist(ast);
12178                                doongetrawsqlstatementevent(gcurrentsqlstatement);
12179                                gst = EFindSqlStateType.stnormal;
12180                                break;
12181                            }
12182                            default:
12183                            {
12184                                gcurrentsqlstatement.addtokentolist(ast);
12185                                gst = EFindSqlStateType.stsql;
12186                                break;
12187                            }
12188                        }    // case
12189                    }
12190                    else
12191                    {
12192                        if ( ast.tokencode == TBaseType.rrw_begin )
12193                        {
12194                            gcurrentsqlstatement = new TMssqlBlock(dbVendor);
12195                            gcurrentsqlstatement.sqlstatementtype = ESqlStatementType.sstmssqlblock;
12196                            gcurrentsqlstatement.addtokentolist(ast);
12197                            gst = EFindSqlStateType.stblock;
12198                        }
12199                        else
12200                        {
12201                            if ( sqlstatements.size() == 0 )
12202                            {
12203                                //first statement of mssql batch, treat it as exec sp
12204                                gst = EFindSqlStateType.stsql;
12205                                gcurrentsqlstatement = new TMssqlExecute(dbVendor);
12206                                //tmssqlexecute(gcurrentsqlstatement).exectype = metnoexeckeyword;
12207// todo need previous line need to be implemented
12208                                gcurrentsqlstatement.addtokentolist(ast);
12209                            }
12210                            else if ( sqlstatements.get(sqlstatements.size() -1).sqlstatementtype == ESqlStatementType.sstmssqlgo )
12211                            {
12212                                // prev sql is go, treat it as exec sp
12213                                gst = EFindSqlStateType.stsql;
12214                                gcurrentsqlstatement = new TMssqlExecute(dbVendor);
12215                                //todo need to be implemented: tmssqlexecute(gcurrentsqlstatement).exectype = metnoexeckeyword;
12216                                gcurrentsqlstatement.addtokentolist(ast);
12217                            }
12218                            else
12219                            {
12220                            }
12221                        }
12222                    }
12223
12224
12225                    if (  !TBaseType.assigned(gcurrentsqlstatement)  ) //error tokentext found
12226                    {
12227
12228//                        errormessage = "error when tokenlize:"+ast.astext+"("+ast.lineNo +","+ast.columnNo +")";
12229//                        errorcount = 1;
12230                        this.syntaxErrors.add( new TSyntaxError(ast.astext,ast.lineNo,(ast.columnNo < 0 ? 0:ast.columnNo)
12231                                ,"Error when tokenlize", EErrorType.spwarning,TBaseType.MSG_WARNING_ERROR_WHEN_TOKENIZE,null,ast.posinlist));
12232
12233                        ast.tokentype = ETokenType.tttokenlizererrortoken;
12234                        gst = EFindSqlStateType.sterror;
12235
12236                        gcurrentsqlstatement = new TUnknownSqlStatement(dbVendor);
12237                        gcurrentsqlstatement.sqlstatementtype = ESqlStatementType.sstinvalid;
12238                        gcurrentsqlstatement.addtokentolist(ast);
12239                    }
12240                    break;
12241                }
12242                case stblock:
12243                {
12244                    if ( TBaseType.assigned(lcnextsqlstatement) )
12245                    {
12246                        if ( lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlgo )
12247                        {
12248                            doongetrawsqlstatementevent(gcurrentsqlstatement);
12249                            gcurrentsqlstatement = lcnextsqlstatement;
12250                            gcurrentsqlstatement.addtokentolist(ast);
12251                            doongetrawsqlstatementevent(gcurrentsqlstatement);
12252                            gst = EFindSqlStateType.stnormal;
12253                        }
12254                        else
12255                        {
12256                            lcnextsqlstatement = null;
12257                        }
12258                    }
12259
12260                    if ( gst == EFindSqlStateType.stblock )
12261                    {
12262                        gcurrentsqlstatement.addtokentolist(ast);
12263                        if ( ast.tokencode == TBaseType.rrw_begin )
12264                        {
12265                            // { [distributed] transaxtion/trans statement
12266                            // { dialog [ conversation ]
12267                            // { conversation timer
12268                            //  doesn't start block ({ .. })
12269                            lcnextsolidtoken = sourcetokenlist.nextsolidtoken(i,1,false);
12270                            if ( TBaseType.assigned(lcnextsolidtoken) )
12271                            {
12272                                if ( ! (TBaseType.mysametext(lcnextsolidtoken.astext,"tran")
12273                                        || TBaseType.mysametext(lcnextsolidtoken.astext,"transaction")
12274                                        || TBaseType.mysametext(lcnextsolidtoken.astext,"distributed")
12275                                        || TBaseType.mysametext(lcnextsolidtoken.astext,"dialog")
12276                                        || TBaseType.mysametext(lcnextsolidtoken.astext,"conversation")
12277                                ) )
12278                                    lcblocklevel++;
12279                            }
12280                            else
12281                                lcblocklevel++;
12282
12283                        }
12284                        else if ( ast.tokencode == TBaseType.rrw_case )  // case ... }
12285                            lcblocklevel++;
12286                        else if ( ast.tokencode == TBaseType.rrw_end )
12287                        {
12288
12289                            lcisendconversation = false;
12290
12291
12292                            lcnextsolidtoken = sourcetokenlist.nextsolidtoken(i,1,false);
12293                            if ( TBaseType.assigned(lcnextsolidtoken) )
12294                            {
12295                                if ( lcnextsolidtoken.tokencode == flexer.getkeywordvalue("conversation".toUpperCase()))
12296                                    lcisendconversation = true; // } conversation statement
12297                            }
12298
12299
12300                            if ( ! lcisendconversation )
12301                            {
12302
12303                                if ( lcblocklevel == 0 )
12304                                {
12305                                    if ( gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlif )
12306                                    {
12307                                        if ( TBaseType.assigned(lcnextsolidtoken) )
12308                                        {
12309                                            if ( lcnextsolidtoken.tokencode == TBaseType.rrw_else )
12310                                            {
12311                                                // { .. } else
12312                                                gst = EFindSqlStateType.stsql;
12313                                            }
12314                                            else if ( lcnextsolidtoken.tokentype == ETokenType.ttsemicolon )
12315                                            {
12316                                                lcnnextsolidtoken = sourcetokenlist.nextsolidtoken(lcnextsolidtoken.posinlist,1,false);
12317                                                if ( TBaseType.assigned(lcnnextsolidtoken) )
12318                                                {
12319                                                    if ( lcnnextsolidtoken.tokencode == TBaseType.rrw_else )
12320                                                    {
12321                                                        // { .. } else
12322                                                        gst = EFindSqlStateType.stsql;
12323                                                    }
12324                                                }
12325                                            }
12326                                        }
12327                                    }
12328
12329                                    if ( gst != EFindSqlStateType.stsql )
12330                                    {
12331                                        doongetrawsqlstatementevent(gcurrentsqlstatement);
12332                                        gst = EFindSqlStateType.stnormal;
12333                                    }
12334
12335                                }
12336                                else
12337                                {
12338                                    lcblocklevel--;
12339                                }
12340
12341                            }
12342                        }
12343                    }
12344                    break;
12345                }
12346                case sttrycatch:
12347                {
12348
12349                    if ( TBaseType.assigned(lcnextsqlstatement) )
12350                    {
12351                        if ( lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlgo )
12352                        {
12353                            doongetrawsqlstatementevent(gcurrentsqlstatement);
12354                            gcurrentsqlstatement = lcnextsqlstatement;
12355                            gcurrentsqlstatement.addtokentolist(ast);
12356                            doongetrawsqlstatementevent(gcurrentsqlstatement);
12357                            gst = EFindSqlStateType.stnormal;
12358                        }
12359                        else
12360                        {
12361                            if (
12362                                    (lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlbegintry)
12363                                            ||(lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlbegincatch)
12364                            )
12365                                lctrycatchlevel++;
12366                            lcnextsqlstatement = null;
12367                        }
12368                    }
12369
12370                    if ( gst == EFindSqlStateType.sttrycatch )
12371                    {
12372                        gcurrentsqlstatement.addtokentolist(ast);
12373                        if ( (ast.tokencode == TBaseType.rrw_try) ||
12374                                (ast.tokencode == TBaseType.rrw_catch) )
12375                        {
12376                            // lcprevsolidtoken = sourcetokenlist.solidtokenbefore(i);
12377                            if ( TBaseType.assigned(lcprevsolidtoken) )
12378                            {
12379                                if ( lcprevsolidtoken.tokencode == TBaseType.rrw_end )
12380                                {
12381                                    if ( lctrycatchlevel == 0 )
12382                                    {
12383                                        doongetrawsqlstatementevent(gcurrentsqlstatement);
12384                                        gst = EFindSqlStateType.stnormal;
12385                                    }
12386                                    else
12387                                        lctrycatchlevel--;
12388                                }
12389                            }
12390                        }
12391                    }
12392                    break;
12393                }
12394                case stsql :
12395                {
12396                    if ( (ast.tokentype == ETokenType.ttsemicolon)   )
12397                    {
12398                        lcstillinsql = false;
12399                        if ( gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlif )
12400                        {
12401                            lcnextsolidtoken = sourcetokenlist.nextsolidtoken(i,1,false);
12402                            if ( TBaseType.assigned(lcnextsolidtoken) )
12403                            {
12404                                if ( lcnextsolidtoken.tokencode == TBaseType.rrw_else )
12405                                {
12406                                    // if ( expr stmt; else
12407                                    gcurrentsqlstatement.addtokentolist(ast);
12408                                    lcstillinsql = true;
12409                                }
12410
12411                            }
12412                        }
12413
12414                        if (  !lcstillinsql )
12415                        {
12416                            gst = EFindSqlStateType.stnormal;
12417                            gcurrentsqlstatement.addtokentolist(ast);
12418                            gcurrentsqlstatement.semicolonended = ast;
12419                            doongetrawsqlstatementevent(gcurrentsqlstatement);
12420                        }
12421
12422                    }
12423                    else if ( TBaseType.assigned(lcnextsqlstatement) )
12424                    {
12425
12426                        if ( lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlgo )
12427                        {
12428                            doongetrawsqlstatementevent(gcurrentsqlstatement);
12429                            gcurrentsqlstatement = lcnextsqlstatement;
12430                            gcurrentsqlstatement.addtokentolist(ast);
12431                            doongetrawsqlstatementevent(gcurrentsqlstatement);
12432                            gst = EFindSqlStateType.stnormal;
12433                            continue;
12434                        }
12435
12436                        switch(gcurrentsqlstatement.sqlstatementtype){    //
12437                            case sstmssqlif:
12438                            case sstmssqlwhile:
12439                            {
12440                                if ((lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlbegincatch)
12441                                        ||(lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlbegintry))
12442                                {
12443                                    gcurrentsqlstatement.addtokentolist(ast);
12444                                    gst = EFindSqlStateType.stblock;
12445                                    lcblocklevel = 1;
12446                                    lcnextsqlstatement = null;
12447                                    continue;
12448
12449                                }
12450                                // if ( || while only contain one sql(not closed by {/} pair)
12451                                // so will still in if ( || while statement
12452                                else if ( gcurrentsqlstatement.dummytag == 1 )
12453                                {
12454                                    // if ( cond ^stmt nextstmt (^ stands for current pos)
12455                                    gcurrentsqlstatement.addtokentolist(ast);
12456
12457                                    if ( (lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlif)
12458                                            || (lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlwhile)
12459                                    )
12460                                        gcurrentsqlstatement.dummytag = 1;
12461                                    else
12462                                        gcurrentsqlstatement.dummytag = 0;
12463
12464
12465                                    lcnextsqlstatement = null;
12466                                    continue;
12467                                }
12468                                break;
12469                            }//
12470                            case sstmssqlalterqueue:
12471                            {
12472                                if ( lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlexec )
12473                                {
12474                                    // execute can't be used to delimite alter queue
12475                                    gcurrentsqlstatement.addtokentolist(ast);
12476
12477
12478                                    lcnextsqlstatement = null;
12479                                    continue;
12480
12481                                }
12482                                break;
12483                            }
12484                            case sstmssqlcreateschema:
12485                            {
12486                                gcurrentsqlstatement.addtokentolist(ast);
12487                                lcnextsqlstatement = null;
12488                                continue;
12489                            }
12490                        }//case
12491
12492                        doongetrawsqlstatementevent(gcurrentsqlstatement);
12493                        gcurrentsqlstatement = lcnextsqlstatement;
12494                        gcurrentsqlstatement.addtokentolist(ast);
12495
12496                        switch(gcurrentsqlstatement.sqlstatementtype){    //
12497                            case sstmssqlcreateprocedure:
12498                            case sstmssqlcreatefunction:
12499                                //case sstmssqlcreatetrigger:
12500                            case sstcreatetrigger:
12501                            case sstmssqlalterprocedure:
12502                            case sstmssqlalterfunction:
12503                            case sstmssqlaltertrigger:
12504                            {
12505                                gst = EFindSqlStateType.ststoredprocedure;
12506                                break;
12507                            }
12508                            case sstmssqlbegintry:
12509                            case sstmssqlbegincatch:
12510                            {
12511                                gst = EFindSqlStateType.sttrycatch;
12512                                lctrycatchlevel = 0;
12513                                break;
12514                            }
12515                            case sstmssqlgo:
12516                            {
12517                                gst = EFindSqlStateType.stnormal;
12518                                break;
12519                            }
12520                            default:
12521                            {
12522                                gst = EFindSqlStateType.stsql;
12523                                break;
12524                            }
12525                        }    // case
12526
12527                    }//TBaseType.assigned(lcnextsqlstatement)
12528                    else if ( (ast.tokencode == TBaseType.rrw_begin) )
12529                    {
12530                        if ( (gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlif)
12531                                || (gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlwhile)
12532                        )
12533                        {
12534                            // start block of if ( || while statement
12535                            gst = EFindSqlStateType.stblock;
12536                            lcblocklevel = 0;
12537                            gcurrentsqlstatement.addtokentolist(ast);
12538                        }
12539                        else if ( gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqldeclare )
12540                        {
12541                            doongetrawsqlstatementevent(gcurrentsqlstatement);
12542                            gcurrentsqlstatement = new TMssqlBlock(dbVendor);
12543                            gcurrentsqlstatement.sqlstatementtype = ESqlStatementType.sstmssqlblock;
12544                            gcurrentsqlstatement.addtokentolist(ast);
12545                            gst = EFindSqlStateType.stblock;
12546                        }
12547                        else
12548                        {
12549                            gcurrentsqlstatement.addtokentolist(ast);
12550                        }
12551                    }
12552                    else if ( (ast.tokencode == TBaseType.rrw_case) ){
12553                        case_end_nest++;
12554                        gcurrentsqlstatement.addtokentolist(ast);
12555                    }
12556                    else if ( (ast.tokencode == TBaseType.rrw_end) ){
12557                        if (case_end_nest > 0){
12558                            case_end_nest--;
12559                        }
12560                        gcurrentsqlstatement.addtokentolist(ast);
12561                    }
12562                    else if ( (ast.tokencode == TBaseType.rrw_else) )
12563                    {
12564                        gcurrentsqlstatement.addtokentolist(ast);
12565                        // if ( cond stmt ^else stmt
12566                        if (( (gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlif)
12567                                || (gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlwhile)
12568                        ) && (case_end_nest == 0))
12569                            gcurrentsqlstatement.dummytag = 1; // reduce to 1 while stmt after else is found: if ( cond stmt ^else stmt
12570                    }
12571                    else
12572                    {
12573                        gcurrentsqlstatement.addtokentolist(ast);
12574                    }
12575                    break;
12576                }
12577                case ststoredprocedure:
12578                {
12579                    if ( TBaseType.assigned(lcnextsqlstatement) )
12580                    {
12581                        if ( lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlgo )
12582                        {
12583                            doongetrawsqlstatementevent(gcurrentsqlstatement);
12584                            gcurrentsqlstatement = lcnextsqlstatement;
12585                            gcurrentsqlstatement.addtokentolist(ast);
12586                            doongetrawsqlstatementevent(gcurrentsqlstatement);
12587                            gst = EFindSqlStateType.stnormal;
12588                        }
12589                        else
12590                        {
12591                            gst = EFindSqlStateType.ststoredprocedurebody;
12592                            gcurrentsqlstatement.addtokentolist(ast);
12593
12594                            lcnextsqlstatement = null;
12595                        }
12596                    }
12597
12598                    if ( gst == EFindSqlStateType.ststoredprocedure )
12599                    {
12600                        gcurrentsqlstatement.addtokentolist(ast);
12601                        if ( ast.tokencode == TBaseType.rrw_begin )
12602                        {
12603                            gst = EFindSqlStateType.stblock;
12604                        }
12605                    }
12606                    break;
12607                } //stplsql
12608                case ststoredprocedurebody:
12609                {
12610                    if ( TBaseType.assigned(lcnextsqlstatement) )
12611                    {
12612                        switch(lcnextsqlstatement.sqlstatementtype){    //
12613                            case sstmssqlgo:
12614                            {
12615                                doongetrawsqlstatementevent(gcurrentsqlstatement);
12616                                gcurrentsqlstatement = lcnextsqlstatement;
12617                                gcurrentsqlstatement.addtokentolist(ast);
12618                                doongetrawsqlstatementevent(gcurrentsqlstatement);
12619                                gst = EFindSqlStateType.stnormal;
12620                                break;
12621                            }
12622                            case sstmssqlcreateprocedure:
12623                            case sstmssqlcreatefunction:
12624                                //case sstmssqlcreatetrigger:
12625                            case sstcreatetrigger:
12626                            case sstmssqlalterprocedure:
12627                            case sstmssqlalterfunction:
12628                            case sstmssqlaltertrigger:
12629                            {
12630                                doongetrawsqlstatementevent(gcurrentsqlstatement);
12631                                gcurrentsqlstatement = lcnextsqlstatement;
12632                                gcurrentsqlstatement.addtokentolist(ast);
12633                                gst = EFindSqlStateType.ststoredprocedure;
12634                                break;
12635                            }
12636                            case sstcreateview:
12637                            case sstcreatetable:
12638                            {
12639
12640                                boolean readForNewStmt = false;
12641                                TSourceToken st1 = ast.searchToken(';',-1);
12642                                if (st1 != null) {
12643                                    TSourceToken st2 = ast.searchToken(TBaseType.rrw_end,-2);
12644                                    if (st2 != null){
12645                                        readForNewStmt = true;
12646                                    }
12647                                }
12648
12649                                if (readForNewStmt){
12650                                    doongetrawsqlstatementevent(gcurrentsqlstatement);
12651                                    gcurrentsqlstatement = lcnextsqlstatement;
12652                                    gcurrentsqlstatement.addtokentolist(ast);
12653                                    gst = EFindSqlStateType.stsql;
12654                                }else{
12655                                    lcnextsqlstatement = null;
12656                                }
12657                                break;
12658                            }
12659                            default:
12660                            {
12661                                lcnextsqlstatement = null;
12662                                break;
12663                            }
12664                        }//case
12665                    }
12666
12667                    if ( gst == EFindSqlStateType.ststoredprocedurebody )
12668                        gcurrentsqlstatement.addtokentolist(ast);
12669                }
12670                break;
12671            } //case
12672        } //for
12673
12674
12675        //last statement
12676        if ( TBaseType.assigned(gcurrentsqlstatement) &&  (gst != EFindSqlStateType.stnormal))
12677        {
12678            doongetrawsqlstatementevent(gcurrentsqlstatement);
12679        }
12680
12681
12682
12683        return errorcount;
12684
12685    }
12686
12687    int domssqlgetrawsqlstatements(){
12688        int errorcount = 0;
12689        int case_end_nest = 0;
12690
12691        if ( TBaseType.assigned(sqlstatements) ) sqlstatements.clear();
12692        if ( ! TBaseType.assigned(sourcetokenlist) ) return -1;
12693
12694        gcurrentsqlstatement = null;
12695        EFindSqlStateType gst = EFindSqlStateType.stnormal;
12696        int lcblocklevel = 0;
12697        int lctrycatchlevel = 0;
12698        TSourceToken lcprevsolidtoken = null,lcnextsolidtoken,lcnnextsolidtoken;
12699        TSourceToken ast = null;
12700        int i,lcMergeInSelectNested = 0;
12701        boolean lcisendconversation, lcstillinsql,lcMergeInSelect = false;
12702
12703        for (i=0 ; i < sourcetokenlist.size();i++)
12704        {
12705
12706            if ( (ast != null ) && (ast.issolidtoken() ))
12707                lcprevsolidtoken = ast;
12708
12709            ast = sourcetokenlist.get(i);
12710            sourcetokenlist.curpos = i;
12711
12712            if (ast.tokencode == TBaseType.rrw_for){
12713                TSourceToken st1 = ast.nextSolidToken();
12714                if ((st1 != null) && (st1.tokencode == TBaseType.rrw_system_time)){
12715                    ast.tokencode = TBaseType.rw_for_system_time;
12716                }
12717            }
12718
12719            if (lcMergeInSelect){
12720                if (ast.tokencode == '(') lcMergeInSelectNested++;
12721                if (ast.tokencode == ')'){
12722                    lcMergeInSelectNested--;
12723                    if (lcMergeInSelectNested == 0){
12724                        lcMergeInSelect = false;
12725                    }
12726                }
12727                gcurrentsqlstatement.sourcetokenlist.add(ast);
12728                continue;
12729            }
12730            if ( ast.tokenstatus == ETokenStatus.tsignoredbygetrawstatement )
12731            {
12732                //tsignoredbygetrawstatement is set when cte is found in dbcmds.findcte function
12733                gcurrentsqlstatement.sourcetokenlist.add(ast);
12734                continue;
12735            }
12736
12737            if (ast.tokencode == TBaseType.rrw_minus){
12738                TSourceToken st1 = ast.searchToken('(',1);
12739                if (st1 == null){
12740                    st1 = ast.searchToken(TBaseType.rrw_select,1);
12741                    if (st1 == null){
12742                        ast.tokencode = TBaseType.ident;
12743                    }
12744                }
12745            }else if (ast.tokencode == TBaseType.rrw_merge){
12746                TSourceToken st1 = ast.nextSolidToken();
12747                if (st1.tokencode == TBaseType.rrw_join){
12748                    ast.tokencode = TBaseType.rrw_merge2_sqlserver;
12749                }
12750                if ((lcprevsolidtoken != null)&&(lcprevsolidtoken.tokencode == '(')){
12751                    lcMergeInSelect = true;
12752                    lcMergeInSelectNested++;
12753                    gcurrentsqlstatement.addtokentolist(ast);
12754                    continue;
12755                }
12756            }else if (ast.tokencode == TBaseType.rrw_sqlserver_value){
12757                if ((lcprevsolidtoken != null)&&(lcprevsolidtoken.tokencode == '.')){
12758                    TSourceToken st1 = ast.searchToken('(',1);
12759                    if (st1 != null) {
12760                        ast.tokencode = TBaseType.rrw_xml_value;
12761                    }
12762                }
12763            }else if (ast.tokencode == TBaseType.rrw_sqlserver_modify){
12764                if ((lcprevsolidtoken != null)&&(lcprevsolidtoken.tokencode == '.')){
12765                    TSourceToken st1 = ast.searchToken('(',1);
12766                    if (st1 != null) {
12767                        ast.tokencode = TBaseType.rrw_xml_modify;
12768                    }
12769                }
12770            }else if (ast.tokencode == TBaseType.rrw_sqlserver_query){
12771                if ((lcprevsolidtoken != null)&&(lcprevsolidtoken.tokencode == '.')){
12772                    TSourceToken st1 = ast.searchToken('(',1);
12773                    if (st1 != null) {
12774                        ast.tokencode = TBaseType.rrw_xml_query;
12775                    }
12776                }
12777            }else if (ast.tokencode == TBaseType.rrw_sqlserver_exist){
12778                if ((lcprevsolidtoken != null)&&(lcprevsolidtoken.tokencode == '.')){
12779                    TSourceToken st1 = ast.searchToken('(',1);
12780                    if (st1 != null) {
12781                        ast.tokencode = TBaseType.rrw_xml_exist;
12782                    }
12783                }
12784            }else if (ast.tokencode == TBaseType.rrw_sqlserver_nodes){
12785                if ((lcprevsolidtoken != null)&&(lcprevsolidtoken.tokencode == '.')){
12786                    TSourceToken st1 = ast.searchToken('(',1);
12787                    if (st1 != null) {
12788                        ast.tokencode = TBaseType.rrw_xml_nodes;
12789                    }
12790                }
12791            }else if (ast.tokencode == TBaseType.rrw_check){
12792                if ((lcprevsolidtoken != null)&&(lcprevsolidtoken.tokencode == TBaseType.rrw_with)){
12793                    lcprevsolidtoken.tokencode = TBaseType.rrw_sqlserver_check_with;
12794                }
12795//            }else if (ast.tokencode == TBaseType.rrw_for){
12796//                TSourceToken st1 = ast.nextSolidToken();
12797//                if ((st1 != null) && (st1.tokencode == TBaseType.rrw_system_time)){
12798//                    ast.tokencode = TBaseType.rw_for_system_time;
12799//                }
12800            }else if (ast.tokencode == TBaseType.rrw_sqlserver_next){
12801                TSourceToken st1 = ast.nextSolidToken();
12802                if ((st1 != null) && (st1.tokencode == '.')){
12803                    ast.tokencode = TBaseType.ident;
12804                }
12805            }else if (ast.tokencode == TBaseType.rrw_fetch){
12806                if ((lcprevsolidtoken != null)&&((lcprevsolidtoken.tokencode == TBaseType.rrw_sqlserver_row)||(lcprevsolidtoken.tokencode == TBaseType.rrw_sqlserver_rows))){
12807                      TSourceToken prev2 = lcprevsolidtoken.searchToken(TBaseType.rrw_open,-1);
12808                      if (prev2 == null){
12809                          ast.tokencode = TBaseType.rrw_sqlserver_offset_fetch;
12810                      }else{
12811                          // don't turn fetch to TBaseType.rrw_sqlserver_offset_fetch
12812                          //open row
12813                          //fetch row into @msg
12814                      }
12815
12816                }
12817            }else if((ast.tokencode == TBaseType.rrw_exec)||(ast.tokencode == TBaseType.rrw_execute)){
12818                // search ;2 after execute
12819                // EXECUTE ApxSQL_Test_Triggers_Add;2  @TableName, @AddFlag
12820                int searchRange = 4;
12821                TSourceToken endTokenInSameLine = ast.searchTokenAtTheEndOfSameLine();
12822                if (endTokenInSameLine != null){
12823                    searchRange = endTokenInSameLine.posinlist - ast.posinlist;
12824                }
12825                TSourceToken st1 = ast.searchToken(';',searchRange);
12826                if (st1 != null){
12827                    TSourceToken numSt = st1.nextSolidToken();
12828                    if ((numSt != null)&&(numSt.tokentype == ETokenType.ttnumber)){
12829                        st1.tokencode = TBaseType.rrw_sqlserver_semicolon_module_number;
12830                        st1.tokentype = ETokenType.ttidentifier;
12831                    }
12832                }
12833            }
12834            else if (ast.tokencode == TBaseType.rrw_sqlserver_trim){
12835                TSourceToken st1 =  ast.nextSolidToken();
12836                if (st1 != null){
12837                    if (st1.tokencode == '('){
12838
12839                    }else{
12840                        ast.tokencode = TBaseType.ident; // change trim keyword to identifier if not followed by (), trim()
12841                    }
12842                }
12843            }
12844
12845            if (dbVendor == EDbVendor.dbvopenedge){
12846                if (ast.tokencode == TBaseType.rrw_order){
12847                        TSourceToken st1 = ast.searchToken(TBaseType.rrw_by,1);
12848                        if (st1 == null) {
12849                            ast.tokencode = TBaseType.ident;
12850                        }
12851                }else if (ast.tokencode == TBaseType.rrw_with){
12852                        TSourceToken st1 = ast.searchToken(TBaseType.rrw_check,1);
12853                        if (st1 != null) {
12854                            ast.tokencode = TBaseType.rrw_openedge_with_check;
12855                        }
12856                }
12857            }
12858
12859            if ( gst == EFindSqlStateType.ststoredprocedurebody )
12860            {
12861                if ( !(
12862                        (ast.tokencode == TBaseType.rrw_go)
12863                                || (ast.tokencode == TBaseType.rrw_create)
12864                                || (ast.tokencode == TBaseType.rrw_alter) )
12865                        )
12866                {
12867                    gcurrentsqlstatement.sourcetokenlist.add(ast);
12868                    continue;
12869                }
12870            }
12871
12872            TCustomSqlStatement lcnextsqlstatement =  sqlcmds.issql(ast, dbVendor,gst,gcurrentsqlstatement);
12873
12874            switch(gst){
12875                case sterror:
12876                {
12877                    if ( TBaseType.assigned(lcnextsqlstatement) )
12878                    {
12879                        doongetrawsqlstatementevent(gcurrentsqlstatement);
12880                        gcurrentsqlstatement = lcnextsqlstatement;
12881                        gcurrentsqlstatement.sourcetokenlist.add(ast);
12882                        gst = EFindSqlStateType.stsql;
12883                    }
12884                    else if ( (ast.tokentype == ETokenType.ttsemicolon) )
12885                    {
12886                        gcurrentsqlstatement.sourcetokenlist.add(ast);
12887                        doongetrawsqlstatementevent(gcurrentsqlstatement);
12888                        gst = EFindSqlStateType.stnormal;
12889                    }
12890                    else
12891                    {
12892                        gcurrentsqlstatement.sourcetokenlist.add(ast);
12893                    }
12894                    break;
12895                }
12896                case stnormal :
12897                {
12898                    if ( (ast.tokencode  == TBaseType.cmtdoublehyphen)
12899                            || (ast.tokencode  == TBaseType.cmtslashstar)
12900                            || (ast.tokencode  == TBaseType.lexspace)
12901                            || (ast.tokencode  == TBaseType.lexnewline)
12902                            || (ast.tokentype  == ETokenType.ttsemicolon) )
12903                    {
12904                        if ( TBaseType.assigned(gcurrentsqlstatement) )
12905                        {
12906                            gcurrentsqlstatement.addtokentolist(ast);
12907                        }
12908
12909                        if ( TBaseType.assigned(lcprevsolidtoken) && (ast.tokentype == ETokenType.ttsemicolon) )
12910                        {
12911                            if ( lcprevsolidtoken.tokentype == ETokenType.ttsemicolon )
12912                            {
12913                                // ;;;; continuous semicolon,treat it as comment
12914                                ast.tokentype = ETokenType.ttsimplecomment;
12915                                ast.tokencode =  TBaseType.cmtdoublehyphen;
12916                            }
12917                            else
12918                            {
12919                            }
12920
12921                        }
12922
12923                        continue;
12924                    }
12925
12926                    gcurrentsqlstatement = lcnextsqlstatement; //isstoredprocedure(ast,dbvendor,gst,sqlstatements);
12927
12928                    if ( TBaseType.assigned(gcurrentsqlstatement) )
12929                    {
12930                        switch(gcurrentsqlstatement.sqlstatementtype){    //
12931                            case sstmssqlcreateprocedure:
12932                            case sstmssqlcreatefunction:
12933                            //case sstmssqlcreatetrigger:
12934                            case sstcreatetrigger:
12935                            case sstmssqlalterprocedure:
12936                            case   sstmssqlalterfunction:
12937                            case sstmssqlaltertrigger:
12938                            {
12939                                gcurrentsqlstatement.addtokentolist(ast);
12940                                gst = EFindSqlStateType.ststoredprocedure;
12941                                break;
12942                            }
12943                            case sstmssqlbegintry:
12944                            case sstmssqlbegincatch:
12945                            {
12946                                gcurrentsqlstatement.addtokentolist(ast);
12947                                gst = EFindSqlStateType.sttrycatch;
12948                                lctrycatchlevel = 0;
12949                                break;
12950                            }
12951                            case sstmssqlgo:
12952                            {
12953                                gcurrentsqlstatement.addtokentolist(ast);
12954                                doongetrawsqlstatementevent(gcurrentsqlstatement);
12955                                gst = EFindSqlStateType.stnormal;
12956                                break;
12957                            }
12958                            default:
12959                            {
12960                                gcurrentsqlstatement.addtokentolist(ast);
12961                                gst = EFindSqlStateType.stsql;
12962                                break;
12963                            }
12964                        }    // case
12965                    }
12966                    else
12967                    {
12968                        if ( ast.tokencode == TBaseType.rrw_begin )
12969                        {
12970                            gcurrentsqlstatement = new TMssqlBlock(dbVendor);
12971                            gcurrentsqlstatement.sqlstatementtype = ESqlStatementType.sstmssqlblock;
12972                            gcurrentsqlstatement.addtokentolist(ast);
12973                            gst = EFindSqlStateType.stblock;
12974                        }
12975                        else
12976                        {
12977                            if ( sqlstatements.size() == 0 )
12978                            {
12979                                //first statement of mssql batch, treat it as exec sp
12980                                gst = EFindSqlStateType.stsql;
12981                                gcurrentsqlstatement = new TMssqlExecute(dbVendor);
12982                                //tmssqlexecute(gcurrentsqlstatement).exectype = metnoexeckeyword;
12983// todo need previous line need to be implemented
12984                                gcurrentsqlstatement.addtokentolist(ast);
12985                            }
12986                            else if ( sqlstatements.get(sqlstatements.size() -1).sqlstatementtype == ESqlStatementType.sstmssqlgo )
12987                            {
12988                                // prev sql is go, treat it as exec sp
12989                                gst = EFindSqlStateType.stsql;
12990                                gcurrentsqlstatement = new TMssqlExecute(dbVendor);
12991                                //todo need to be implemented: tmssqlexecute(gcurrentsqlstatement).exectype = metnoexeckeyword;
12992                                gcurrentsqlstatement.addtokentolist(ast);
12993                            }
12994                            else
12995                            {
12996                            }
12997                        }
12998                    }
12999
13000
13001                    if (  !TBaseType.assigned(gcurrentsqlstatement)  ) //error tokentext found
13002                    {
13003
13004
13005                        this.syntaxErrors.add( new TSyntaxError(ast.astext,ast.lineNo,(ast.columnNo < 0 ? 0:ast.columnNo)
13006                                ,"Error when tokenlize", EErrorType.spwarning,TBaseType.MSG_WARNING_ERROR_WHEN_TOKENIZE,null,ast.posinlist));
13007
13008
13009                        ast.tokentype = ETokenType.tttokenlizererrortoken;
13010                        gst = EFindSqlStateType.sterror;
13011
13012                        gcurrentsqlstatement = new TUnknownSqlStatement(dbVendor);
13013                        gcurrentsqlstatement.sqlstatementtype = ESqlStatementType.sstinvalid;
13014                        gcurrentsqlstatement.addtokentolist(ast);
13015                    }
13016                    break;
13017                }
13018                case stblock:
13019                {
13020                    if ( TBaseType.assigned(lcnextsqlstatement) )
13021                    {
13022                        if ( lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlgo )
13023                        {
13024                            doongetrawsqlstatementevent(gcurrentsqlstatement);
13025                            gcurrentsqlstatement = lcnextsqlstatement;
13026                            gcurrentsqlstatement.addtokentolist(ast);
13027                            doongetrawsqlstatementevent(gcurrentsqlstatement);
13028                            gst = EFindSqlStateType.stnormal;
13029                        }
13030                        else
13031                        {
13032                            lcnextsqlstatement = null;
13033                        }
13034                    }
13035
13036                    if ( gst == EFindSqlStateType.stblock )
13037                    {
13038                        gcurrentsqlstatement.addtokentolist(ast);
13039                        if ( ast.tokencode == TBaseType.rrw_begin )
13040                        {
13041                            // { [distributed] transaxtion/trans statement
13042                            // { dialog [ conversation ]
13043                            // { conversation timer
13044                            //  doesn't start block ({ .. })
13045                            lcnextsolidtoken = sourcetokenlist.nextsolidtoken(i,1,false);
13046                            if ( TBaseType.assigned(lcnextsolidtoken) )
13047                            {
13048                                if ( ! (TBaseType.mysametext(lcnextsolidtoken.astext,"tran")
13049                                        || TBaseType.mysametext(lcnextsolidtoken.astext,"transaction")
13050                                        || TBaseType.mysametext(lcnextsolidtoken.astext,"distributed")
13051                                        || TBaseType.mysametext(lcnextsolidtoken.astext,"dialog")
13052                                        || TBaseType.mysametext(lcnextsolidtoken.astext,"conversation")
13053                                ) )
13054                                    lcblocklevel++;
13055                            }
13056                            else
13057                                lcblocklevel++;
13058
13059                        }
13060                        else if ( ast.tokencode == TBaseType.rrw_case )  // case ... }
13061                            lcblocklevel++;
13062                        else if ( ast.tokencode == TBaseType.rrw_end )
13063                        {
13064
13065                            lcisendconversation = false;
13066
13067
13068                            lcnextsolidtoken = sourcetokenlist.nextsolidtoken(i,1,false);
13069                            if ( TBaseType.assigned(lcnextsolidtoken) )
13070                            {
13071                                if ( lcnextsolidtoken.tokencode == flexer.getkeywordvalue("conversation".toUpperCase()))
13072                                    lcisendconversation = true; // } conversation statement
13073                            }
13074
13075
13076                            if ( ! lcisendconversation )
13077                            {
13078
13079                                if ( lcblocklevel == 0 )
13080                                {
13081                                    if ( gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlif )
13082                                    {
13083                                        if ( TBaseType.assigned(lcnextsolidtoken) )
13084                                        {
13085                                            if ( lcnextsolidtoken.tokencode == TBaseType.rrw_else )
13086                                            {
13087                                                // { .. } else
13088                                                gst = EFindSqlStateType.stsql;
13089                                            }
13090                                            else if ( lcnextsolidtoken.tokentype == ETokenType.ttsemicolon )
13091                                            {
13092                                                lcnnextsolidtoken = sourcetokenlist.nextsolidtoken(lcnextsolidtoken.posinlist,1,false);
13093                                                if ( TBaseType.assigned(lcnnextsolidtoken) )
13094                                                {
13095                                                    if ( lcnnextsolidtoken.tokencode == TBaseType.rrw_else )
13096                                                    {
13097                                                        // { .. } else
13098                                                        gst = EFindSqlStateType.stsql;
13099                                                    }
13100                                                }
13101                                            }
13102                                        }
13103                                    }
13104
13105                                    if ( gst != EFindSqlStateType.stsql )
13106                                    {
13107                                        doongetrawsqlstatementevent(gcurrentsqlstatement);
13108                                        gst = EFindSqlStateType.stnormal;
13109                                    }
13110
13111                                }
13112                                else
13113                                {
13114                                    lcblocklevel--;
13115                                }
13116
13117                            }
13118                        }
13119                    }
13120                    break;
13121                }
13122                case sttrycatch:
13123                {
13124
13125                    if ( TBaseType.assigned(lcnextsqlstatement) )
13126                    {
13127                        if ( lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlgo )
13128                        {
13129                            doongetrawsqlstatementevent(gcurrentsqlstatement);
13130                            gcurrentsqlstatement = lcnextsqlstatement;
13131                            gcurrentsqlstatement.addtokentolist(ast);
13132                            doongetrawsqlstatementevent(gcurrentsqlstatement);
13133                            gst = EFindSqlStateType.stnormal;
13134                        }
13135                        else
13136                        {
13137                            if (
13138                                    (lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlbegintry)
13139                                            ||(lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlbegincatch)
13140                                    )
13141                                lctrycatchlevel++;
13142                            lcnextsqlstatement = null;
13143                        }
13144                    }
13145
13146                    if ( gst == EFindSqlStateType.sttrycatch )
13147                    {
13148                        gcurrentsqlstatement.addtokentolist(ast);
13149                        if ( (ast.tokencode == TBaseType.rrw_try) ||
13150                                (ast.tokencode == TBaseType.rrw_catch) )
13151                        {
13152                            // lcprevsolidtoken = sourcetokenlist.solidtokenbefore(i);
13153                            if ( TBaseType.assigned(lcprevsolidtoken) )
13154                            {
13155                                if ( lcprevsolidtoken.tokencode == TBaseType.rrw_end )
13156                                {
13157                                    if ( lctrycatchlevel == 0 )
13158                                    {
13159                                        doongetrawsqlstatementevent(gcurrentsqlstatement);
13160                                        gst = EFindSqlStateType.stnormal;
13161                                    }
13162                                    else
13163                                        lctrycatchlevel--;
13164                                }
13165                            }
13166                        }
13167                    }
13168                    break;
13169                }
13170                case stprocedureWithReturn:
13171                {
13172                    // found return statement in create procedure/function, which means can be ended with a semicolon
13173
13174                    if ( TBaseType.assigned(lcnextsqlstatement) ) {
13175                        if (lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlgo) {
13176                            doongetrawsqlstatementevent(gcurrentsqlstatement);
13177                            gcurrentsqlstatement = lcnextsqlstatement;
13178                            gcurrentsqlstatement.addtokentolist(ast);
13179                            doongetrawsqlstatementevent(gcurrentsqlstatement);
13180                            gst = EFindSqlStateType.stnormal;
13181                            break;
13182                        }
13183                    }
13184
13185                    gcurrentsqlstatement.addtokentolist(ast);
13186                    if ((gst == EFindSqlStateType.stprocedureWithReturn) && (ast.tokentype == ETokenType.ttsemicolon)){
13187
13188                        doongetrawsqlstatementevent(gcurrentsqlstatement);
13189                        gst = EFindSqlStateType.stnormal;
13190                    }
13191                    break;
13192                }
13193                case stsql :
13194                {
13195                    if ( (ast.tokentype == ETokenType.ttsemicolon)   )
13196                    {
13197                        lcstillinsql = false;
13198                        if ( gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlif )
13199                        {
13200                            lcnextsolidtoken = sourcetokenlist.nextsolidtoken(i,1,false);
13201                            if ( TBaseType.assigned(lcnextsolidtoken) )
13202                            {
13203                                if ( lcnextsolidtoken.tokencode == TBaseType.rrw_else )
13204                                {
13205                                    // if ( expr stmt; else
13206                                    gcurrentsqlstatement.addtokentolist(ast);
13207                                    lcstillinsql = true;
13208                                }
13209
13210                            }
13211                        }
13212
13213                        if (  !lcstillinsql )
13214                        {
13215                            gst = EFindSqlStateType.stnormal;
13216                            gcurrentsqlstatement.addtokentolist(ast);
13217                            gcurrentsqlstatement.semicolonended = ast;
13218                            doongetrawsqlstatementevent(gcurrentsqlstatement);
13219                        }
13220
13221                    }
13222                    else if ( TBaseType.assigned(lcnextsqlstatement) )
13223                    {
13224
13225                        if ( lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlgo )
13226                        {
13227                            doongetrawsqlstatementevent(gcurrentsqlstatement);
13228                            gcurrentsqlstatement = lcnextsqlstatement;
13229                            gcurrentsqlstatement.addtokentolist(ast);
13230                            doongetrawsqlstatementevent(gcurrentsqlstatement);
13231                            gst = EFindSqlStateType.stnormal;
13232                            continue;
13233                        }
13234
13235                        switch(gcurrentsqlstatement.sqlstatementtype){    //
13236                            case sstmssqlif:
13237                            case sstmssqlwhile:
13238                            {
13239                                if ((lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlbegincatch)
13240                                        ||(lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlbegintry))
13241                                {
13242                                    gcurrentsqlstatement.addtokentolist(ast);
13243                                    gst = EFindSqlStateType.stblock;
13244                                    lcblocklevel = 1;
13245                                    lcnextsqlstatement = null;
13246                                    continue;
13247
13248                                }
13249                                // if ( || while only contain one sql(not closed by {/} pair)
13250                                // so will still in if ( || while statement
13251                                else if ( gcurrentsqlstatement.dummytag == 1 )
13252                                {
13253                                    // if ( cond ^stmt nextstmt (^ stands for current pos)
13254                                    gcurrentsqlstatement.addtokentolist(ast);
13255
13256                                    if ( (lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlif)
13257                                            || (lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlwhile)
13258                                            )
13259                                        gcurrentsqlstatement.dummytag = 1;
13260                                    else
13261                                        gcurrentsqlstatement.dummytag = 0;
13262
13263
13264                                    lcnextsqlstatement = null;
13265                                    continue;
13266                                }else{
13267                                    // 在 if statement 中,已经遇见过第一个sql语句,现在是碰到第二个,正常情况下这个第二个
13268                                    //IF EXISTS (SELECT * FROM sysobjects WHERE id = OBJECT_ID(N'[DF_TEST]') AND type = 'D')
13269                                    //ALTER TABLE test DROP CONSTRAINT IF EXISTS DF_TEST;
13270
13271                                    if (lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlif){
13272                                        // 上例中的第二个 IF EXISTS 不是真正的 sql, 忽略它
13273                                        if ((ast.nextSolidToken() != null)&&(ast.nextSolidToken().tokencode == TBaseType.rrw_sqlserver_exists)){
13274                                            gcurrentsqlstatement.addtokentolist(ast);
13275                                            lcnextsqlstatement = null;
13276                                            continue;
13277                                        }
13278                                    }
13279                                }
13280                                break;
13281                            }//
13282                            case sstmssqlalterqueue:
13283                            {
13284                                if ( lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlexec )
13285                                {
13286                                    // execute can't be used to delimite alter queue
13287                                    gcurrentsqlstatement.addtokentolist(ast);
13288                                    lcnextsqlstatement = null;
13289                                    continue;
13290
13291                                }
13292                                break;
13293                            }
13294                            case sstmssqlcreateschema:
13295                            {
13296                                gcurrentsqlstatement.addtokentolist(ast);
13297                                lcnextsqlstatement = null;
13298                                continue;
13299                            }
13300                        }//case
13301
13302                        doongetrawsqlstatementevent(gcurrentsqlstatement);
13303                        gcurrentsqlstatement = lcnextsqlstatement;
13304                        gcurrentsqlstatement.addtokentolist(ast);
13305
13306                        switch(gcurrentsqlstatement.sqlstatementtype){    //
13307                            case sstmssqlcreateprocedure:
13308                            case sstmssqlcreatefunction:
13309                            //case sstmssqlcreatetrigger:
13310                            case sstcreatetrigger:
13311                            case sstmssqlalterprocedure:
13312                            case sstmssqlalterfunction:
13313                            case sstmssqlaltertrigger:
13314                            {
13315                                gst = EFindSqlStateType.ststoredprocedure;
13316                                break;
13317                            }
13318                            case sstmssqlbegintry:
13319                            case sstmssqlbegincatch:
13320                            {
13321                                gst = EFindSqlStateType.sttrycatch;
13322                                lctrycatchlevel = 0;
13323                                break;
13324                            }
13325                            case sstmssqlgo:
13326                            {
13327                                gst = EFindSqlStateType.stnormal;
13328                                break;
13329                            }
13330                            default:
13331                            {
13332                                gst = EFindSqlStateType.stsql;
13333                                break;
13334                            }
13335                        }    // case
13336
13337                    }//TBaseType.assigned(lcnextsqlstatement)
13338                    else if ( (ast.tokencode == TBaseType.rrw_begin) )
13339                    {
13340                        if ( (gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlif)
13341                                || (gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlwhile)
13342                                )
13343                        {
13344                            // start block of if ( || while statement
13345                            gst = EFindSqlStateType.stblock;
13346                            lcblocklevel = 0;
13347                            gcurrentsqlstatement.addtokentolist(ast);
13348                        }
13349                        else if ( gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqldeclare )
13350                        {
13351                            doongetrawsqlstatementevent(gcurrentsqlstatement);
13352                            gcurrentsqlstatement = new TMssqlBlock(dbVendor);
13353                            gcurrentsqlstatement.sqlstatementtype = ESqlStatementType.sstmssqlblock;
13354                            gcurrentsqlstatement.addtokentolist(ast);
13355                            gst = EFindSqlStateType.stblock;
13356                        }
13357                        else
13358                        {
13359                            gcurrentsqlstatement.addtokentolist(ast);
13360                        }
13361                    }
13362                    else if ( (ast.tokencode == TBaseType.rrw_case) ){
13363                        case_end_nest++;
13364                        gcurrentsqlstatement.addtokentolist(ast);
13365                    }
13366                    else if ( (ast.tokencode == TBaseType.rrw_end) ){
13367                        if (case_end_nest > 0){
13368                            case_end_nest--;
13369                        }
13370                        gcurrentsqlstatement.addtokentolist(ast);
13371                    }
13372                    else if ( (ast.tokencode == TBaseType.rrw_else) )
13373                    {
13374                        gcurrentsqlstatement.addtokentolist(ast);
13375                        // if ( cond stmt ^else stmt
13376                        if (( (gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlif)
13377                                || (gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlwhile)
13378                        ) && (case_end_nest == 0))
13379                            gcurrentsqlstatement.dummytag = 1; // reduce to 1 while stmt after else is found: if ( cond stmt ^else stmt
13380                    }
13381                    else
13382                    {
13383                        gcurrentsqlstatement.addtokentolist(ast);
13384                    }
13385                    break;
13386                }
13387                case ststoredprocedure:
13388                {
13389                    if ( TBaseType.assigned(lcnextsqlstatement) )
13390                    {
13391                        if ( lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlgo )
13392                        {
13393                            doongetrawsqlstatementevent(gcurrentsqlstatement);
13394                            gcurrentsqlstatement = lcnextsqlstatement;
13395                            gcurrentsqlstatement.addtokentolist(ast);
13396                            doongetrawsqlstatementevent(gcurrentsqlstatement);
13397                            gst = EFindSqlStateType.stnormal;
13398                        }
13399                        else if (lcnextsqlstatement.sqlstatementtype == sstmssqlreturn)
13400                        {
13401                            gst = EFindSqlStateType.stprocedureWithReturn;
13402                            gcurrentsqlstatement.addtokentolist(ast);
13403                            lcnextsqlstatement = null;
13404                        }
13405                        else
13406                        {
13407                            gst = EFindSqlStateType.ststoredprocedurebody;
13408                            gcurrentsqlstatement.addtokentolist(ast);
13409
13410                            lcnextsqlstatement = null;
13411                        }
13412                    }
13413
13414                    if ( gst == EFindSqlStateType.ststoredprocedure )
13415                    {
13416                        gcurrentsqlstatement.addtokentolist(ast);
13417                        if ( ast.tokencode == TBaseType.rrw_begin )
13418                        {
13419                            gst = EFindSqlStateType.stblock;
13420                        }
13421                    }
13422                    break;
13423                } //stplsql
13424                case ststoredprocedurebody:
13425                {
13426                    if ( TBaseType.assigned(lcnextsqlstatement) )
13427                    {
13428                        switch(lcnextsqlstatement.sqlstatementtype){    //
13429                            case sstmssqlgo:
13430                            {
13431                                doongetrawsqlstatementevent(gcurrentsqlstatement);
13432                                gcurrentsqlstatement = lcnextsqlstatement;
13433                                gcurrentsqlstatement.addtokentolist(ast);
13434                                doongetrawsqlstatementevent(gcurrentsqlstatement);
13435                                gst = EFindSqlStateType.stnormal;
13436                                break;
13437                            }
13438                            case sstmssqlcreateprocedure:
13439                            case sstmssqlcreatefunction:
13440                            //case sstmssqlcreatetrigger:
13441                            case sstcreatetrigger:
13442                            case sstmssqlalterprocedure:
13443                            case sstmssqlalterfunction:
13444                            case sstmssqlaltertrigger:
13445                            {
13446                                doongetrawsqlstatementevent(gcurrentsqlstatement);
13447                                gcurrentsqlstatement = lcnextsqlstatement;
13448                                gcurrentsqlstatement.addtokentolist(ast);
13449                                gst = EFindSqlStateType.ststoredprocedure;
13450                                break;
13451                            }
13452                            case sstcreateview:
13453                            case sstcreatetable:
13454                            {
13455
13456                                boolean readForNewStmt = false;
13457                                TSourceToken st1 = ast.searchToken(';',-1);
13458                                if (st1 != null) {
13459                                    TSourceToken st2 = ast.searchToken(TBaseType.rrw_end,-2);
13460                                    if (st2 != null){
13461                                        readForNewStmt = true;
13462                                    }
13463                                }
13464
13465                                if (readForNewStmt){
13466                                    doongetrawsqlstatementevent(gcurrentsqlstatement);
13467                                    gcurrentsqlstatement = lcnextsqlstatement;
13468                                    gcurrentsqlstatement.addtokentolist(ast);
13469                                    gst = EFindSqlStateType.stsql;
13470                                }else{
13471                                    lcnextsqlstatement = null;
13472                                }
13473                                break;
13474                            }
13475                            case sstmssqlDropSecurityPolicy:
13476                            case sstmssqlAlterSecurityPolicy:
13477                            case sstmssqlCreateSecurityPolicy:
13478                                doongetrawsqlstatementevent(gcurrentsqlstatement);
13479                                gcurrentsqlstatement = lcnextsqlstatement;
13480                                gcurrentsqlstatement.addtokentolist(ast);
13481                                gst = EFindSqlStateType.stsql;
13482
13483                                    break;
13484                            default:
13485                            {
13486                                lcnextsqlstatement = null;
13487                                break;
13488                            }
13489                        }//case
13490                    }
13491
13492                    if ( gst == EFindSqlStateType.ststoredprocedurebody )
13493                        gcurrentsqlstatement.addtokentolist(ast);
13494                }
13495                break;
13496            } //case
13497        } //for
13498
13499
13500        //last statement
13501        if ( TBaseType.assigned(gcurrentsqlstatement) &&  (gst != EFindSqlStateType.stnormal))
13502        {
13503            doongetrawsqlstatementevent(gcurrentsqlstatement);
13504        }
13505
13506
13507
13508        return errorcount;
13509
13510    }
13511
13512
13513    private TCustomSqlStatement startDaxStmt(TSourceToken currToken,TCustomSqlStatement currStmt){
13514        TCustomSqlStatement newStmt = null;
13515        if (currToken == null) return null;
13516        if ((currToken.tokencode == '=')&&(currToken.isFirstTokenOfLine())){
13517            currToken.tokencode = TBaseType.equal_start_expr;
13518            newStmt = new TDaxExprStmt(EDbVendor.dbvdax);
13519        }else if ((currToken.tokencode == TBaseType.rrw_dax_define)&&(currToken.isFirstTokenOfLine())){
13520            newStmt = new TDaxEvaluateStmt(EDbVendor.dbvdax);
13521            ((TDaxEvaluateStmt)newStmt).setStartWithDefine(true);
13522        }else if ((currToken.tokencode == TBaseType.rrw_dax_evaluate)&&(currToken.isFirstTokenOfLine())){
13523            if ((currStmt != null)&&(currStmt instanceof TDaxEvaluateStmt)){
13524                TDaxEvaluateStmt tmp = (TDaxEvaluateStmt)currStmt;
13525                if (tmp.isStartWithDefine()) return  null;
13526            }
13527            newStmt = new TDaxEvaluateStmt(EDbVendor.dbvdax);
13528        }
13529
13530        if (newStmt == null){
13531            // let's check is this the first token of query
13532            boolean isFirst = currToken.isFirstTokenOfLine();
13533            TSourceToken prevToken = currToken.prevSolidToken();
13534            if ((isFirst)&&(prevToken == null)){
13535                newStmt = new TDaxExprStmt(EDbVendor.dbvdax);
13536            }
13537        }
13538        return newStmt;
13539    }
13540
13541    int doodbcgetrawsqlstatements(){
13542        return domssqlgetrawsqlstatements();
13543    }
13544
13545    int dodaxgetrawsqlstatements(){
13546        gcurrentsqlstatement = null;
13547        TCustomSqlStatement tmpStmt = null;
13548        EFindSqlStateType gst = EFindSqlStateType.stnormal;
13549        int i;
13550        TSourceToken ast;
13551        int errorcount = 0;
13552        int nestedParens = 0;
13553
13554        for (i=0 ; i<sourcetokenlist.size();i++)
13555        {
13556            ast = sourcetokenlist.get(i);
13557            //System.out.println(ast);
13558            sourcetokenlist.curpos = i;
13559
13560            if ((ast.tokencode == TBaseType.rrw_dax_product)
13561                    ||(ast.tokencode == TBaseType.rrw_dax_true)
13562                    ||(ast.tokencode == TBaseType.rrw_dax_false)
13563                    ||(ast.tokencode == TBaseType.rrw_dax_calendar)
13564                    ||(ast.tokencode == TBaseType.rrw_dax_second)
13565                    ){
13566                TSourceToken st1 = ast.searchToken("(",1);
13567                if (st1 == null){
13568                    ast.tokencode = TBaseType.ident;
13569                }
13570            }
13571
13572            if (ast.tokencode == '(') nestedParens++;
13573            if (ast.tokencode == ')') nestedParens--;
13574            if (nestedParens > 0){
13575                if (gcurrentsqlstatement != null){
13576                    gcurrentsqlstatement.sourcetokenlist.add(ast);
13577                }
13578                continue;
13579            }
13580
13581            switch(gst){
13582                case sterror:
13583                {
13584                    tmpStmt = startDaxStmt(ast,gcurrentsqlstatement);
13585                    if (tmpStmt != null){
13586                        doongetrawsqlstatementevent(gcurrentsqlstatement);
13587
13588                        gcurrentsqlstatement =  tmpStmt;
13589                        gcurrentsqlstatement.sourcetokenlist.add(ast);
13590                        gst = EFindSqlStateType.stsql;
13591                    }
13592                    else
13593                    {
13594                        gcurrentsqlstatement.sourcetokenlist.add(ast);
13595                    }
13596                    break;
13597                }
13598                case stnormal :
13599                {
13600                    if ((ast.tokencode  == TBaseType.cmtdoublehyphen)
13601                            || (ast.tokencode  == TBaseType.cmtslashstar)
13602                            || (ast.tokencode  == TBaseType.lexspace)
13603                            || (ast.tokencode  == TBaseType.lexnewline)
13604                            || (ast.tokentype  == ETokenType.ttsemicolon))
13605                    {
13606                        if (TBaseType.assigned(gcurrentsqlstatement))
13607                        {
13608                            gcurrentsqlstatement.addtokentolist(ast);
13609                        }
13610                        continue;
13611                    }
13612
13613                    gcurrentsqlstatement = startDaxStmt(ast,gcurrentsqlstatement);
13614
13615                    if (TBaseType.assigned(gcurrentsqlstatement))
13616                    {
13617                            gst = EFindSqlStateType.stsql;
13618                            gcurrentsqlstatement.addtokentolist(ast);
13619                    }else
13620                    {
13621
13622//                        errormessage = "error when tokenlize:"+ast.astext+"("+ast.lineNo +","+ast.columnNo +")";
13623//                        errorcount = 1;
13624                        this.syntaxErrors.add( new TSyntaxError(ast.astext,ast.lineNo,(ast.columnNo < 0 ? 0:ast.columnNo)
13625                                ,"Error when tokenlize", EErrorType.spwarning,TBaseType.MSG_WARNING_ERROR_WHEN_TOKENIZE,null,ast.posinlist));
13626
13627                        ast.tokentype = ETokenType.tttokenlizererrortoken;
13628                        gst = EFindSqlStateType.sterror;
13629
13630                        gcurrentsqlstatement = new TUnknownSqlStatement(dbVendor);
13631                        gcurrentsqlstatement.sqlstatementtype = ESqlStatementType.sstinvalid;
13632                        gcurrentsqlstatement.addtokentolist(ast);
13633
13634                    }
13635                    break;
13636                }
13637                case stsql :
13638                {
13639                    tmpStmt = startDaxStmt(ast,gcurrentsqlstatement);
13640                    if (tmpStmt != null){
13641                        gst = EFindSqlStateType.stsql;
13642                        doongetrawsqlstatementevent(gcurrentsqlstatement);
13643
13644                        gcurrentsqlstatement = tmpStmt;
13645                        gcurrentsqlstatement.addtokentolist(ast);
13646                        continue;
13647                    }
13648
13649                    gcurrentsqlstatement.addtokentolist(ast);
13650
13651                    break;
13652                }
13653
13654            } //case
13655        } //for
13656
13657
13658        //last statement
13659        if (TBaseType.assigned(gcurrentsqlstatement) && ((gst == EFindSqlStateType.stsql) || (gst == EFindSqlStateType.sterror)) )
13660        {
13661            doongetrawsqlstatementevent(gcurrentsqlstatement);
13662        }
13663
13664        return errorcount;//FSqlStatements.Count;
13665
13666    }
13667
13668
13669 int dohanagetrawsqlstatements(){
13670    int errorcount = 0;
13671    int case_end_nest = 0;
13672
13673    if ( TBaseType.assigned(sqlstatements) ) sqlstatements.clear();
13674    if ( ! TBaseType.assigned(sourcetokenlist) ) return -1;
13675
13676    gcurrentsqlstatement = null;
13677    EFindSqlStateType gst = EFindSqlStateType.stnormal;
13678    int lcblocklevel = 0;
13679    int lctrycatchlevel = 0;
13680    TSourceToken lcprevsolidtoken = null,lcnextsolidtoken,lcnnextsolidtoken;
13681    TSourceToken ast = null;
13682    int i,lcMergeInSelectNested = 0;
13683    boolean lcisendconversation, lcstillinsql,lcMergeInSelect = false;
13684
13685    for (i=0 ; i < sourcetokenlist.size();i++)
13686      {
13687
13688          if ( (ast != null ) && (ast.issolidtoken() ))
13689            lcprevsolidtoken = ast;
13690
13691        ast = sourcetokenlist.get(i);
13692        sourcetokenlist.curpos = i;
13693
13694        if (lcMergeInSelect){
13695            if (ast.tokencode == '(') lcMergeInSelectNested++;
13696            if (ast.tokencode == ')'){
13697                lcMergeInSelectNested--;
13698                if (lcMergeInSelectNested == 0){
13699                    lcMergeInSelect = false;
13700                }
13701            }
13702            gcurrentsqlstatement.sourcetokenlist.add(ast);
13703            continue;
13704        }
13705        if ( ast.tokenstatus == ETokenStatus.tsignoredbygetrawstatement )
13706          {
13707            //tsignoredbygetrawstatement is set when cte is found in dbcmds.findcte function
13708            gcurrentsqlstatement.sourcetokenlist.add(ast);
13709            continue;
13710          }
13711
13712        if (ast.tokencode == TBaseType.rrw_minus){
13713            TSourceToken st1 = ast.searchToken('(',1);
13714            if (st1 == null){
13715                st1 = ast.searchToken(TBaseType.rrw_select,1);
13716                if (st1 == null){
13717                    ast.tokencode = TBaseType.ident;
13718                }
13719            }
13720        }else if (ast.tokencode == TBaseType.rrw_merge){
13721            TSourceToken st1 = ast.nextSolidToken();
13722            if (st1.tokencode == TBaseType.rrw_join){
13723                ast.tokencode = TBaseType.rrw_merge2_sqlserver;
13724            }
13725            if ((lcprevsolidtoken != null)&&(lcprevsolidtoken.tokencode == '(')){
13726                lcMergeInSelect = true;
13727                lcMergeInSelectNested++;
13728                gcurrentsqlstatement.addtokentolist(ast);
13729                continue;
13730            }
13731        }else if (ast.tokencode == TBaseType.rrw_as){
13732            TSourceToken st1 = ast.nextSolidToken();
13733            if (st1.tokencode == TBaseType.rrw_hana_of){
13734                ast.tokencode = TBaseType.rrw_as_before_of;
13735            }
13736        }else if (ast.tokencode == TBaseType.rrw_date){
13737            TSourceToken st1 = ast.nextSolidToken();
13738            if (st1.tokencode == TBaseType.sconst){
13739                ast.tokencode = TBaseType.rrw_hana_date_const;
13740            }
13741        }else if (ast.tokencode == TBaseType.rrw_time){
13742            TSourceToken st1 = ast.nextSolidToken();
13743            if (st1.tokencode == TBaseType.sconst){
13744                ast.tokencode = TBaseType.rrw_hana_time_const;
13745            }
13746        }else if (ast.tokencode == TBaseType.rrw_timestamp){
13747            TSourceToken st1 = ast.nextSolidToken();
13748            if (st1.tokencode == TBaseType.sconst){
13749                ast.tokencode = TBaseType.rrw_hana_timestamp_const;
13750            }
13751        }else if (ast.tokencode == TBaseType.rrw_with){
13752            TSourceToken st1 = ast.nextSolidToken();
13753            if (st1.toString().equalsIgnoreCase("structured")){
13754                ast.tokencode = TBaseType.rrw_hana_with_structured;
13755            }else if (st1.toString().equalsIgnoreCase("cache")){
13756                ast.tokencode = TBaseType.rrw_hana_with_cache;
13757            }else if (st1.toString().equalsIgnoreCase("static")){
13758                ast.tokencode = TBaseType.rrw_hana_with_cache;
13759            }else if (st1.toString().equalsIgnoreCase("dynamic")){
13760                ast.tokencode = TBaseType.rrw_hana_with_cache;
13761            }else if (st1.toString().equalsIgnoreCase("check")){
13762                ast.tokencode = TBaseType.rrw_hana_with_check;
13763            }else if (st1.toString().equalsIgnoreCase("mask")){
13764                ast.tokencode = TBaseType.rrw_hana_with_mask;
13765            }else if (st1.toString().equalsIgnoreCase("expression")){
13766                ast.tokencode = TBaseType.rrw_hana_with_expression;
13767            }else if (st1.toString().equalsIgnoreCase("anonymization")){
13768                ast.tokencode = TBaseType.rrw_hana_with_anonymization;
13769            }else if (st1.toString().equalsIgnoreCase("hint")){
13770                ast.tokencode = TBaseType.rrw_hana_with_hint;
13771            }
13772        }else if (ast.tokencode == TBaseType.rrw_hana_unload){
13773            TSourceToken st1 = ast.nextSolidToken();
13774            if (st1.toString().equalsIgnoreCase("priority")){
13775                ast.tokencode = TBaseType.rrw_hana_unload2;
13776            }
13777        }
13778
13779        if ( gst == EFindSqlStateType.ststoredprocedurebody )
13780          {
13781            if ( !(
13782                (ast.tokencode == TBaseType.rrw_go)
13783                || (ast.tokencode == TBaseType.rrw_create)
13784                || (ast.tokencode == TBaseType.rrw_alter) )
13785              )
13786              {
13787                gcurrentsqlstatement.sourcetokenlist.add(ast);
13788                continue;
13789              }
13790          }
13791
13792        TCustomSqlStatement lcnextsqlstatement =  sqlcmds.issql(ast, dbVendor,gst,gcurrentsqlstatement);
13793
13794        switch(gst){
13795          case sterror:
13796            {
13797              if ( TBaseType.assigned(lcnextsqlstatement) )
13798                {
13799                  doongetrawsqlstatementevent(gcurrentsqlstatement);
13800                  gcurrentsqlstatement = lcnextsqlstatement;
13801                  gcurrentsqlstatement.sourcetokenlist.add(ast);
13802                  gst = EFindSqlStateType.stsql;
13803                }
13804              else if ( (ast.tokentype == ETokenType.ttsemicolon) )
13805                {
13806                  gcurrentsqlstatement.sourcetokenlist.add(ast);
13807                  doongetrawsqlstatementevent(gcurrentsqlstatement);
13808                  gst = EFindSqlStateType.stnormal;
13809                }
13810              else
13811                {
13812                  gcurrentsqlstatement.sourcetokenlist.add(ast);
13813                }
13814                break;
13815            }
13816          case stnormal :
13817            {
13818              if ( (ast.tokencode  == TBaseType.cmtdoublehyphen)
13819                 || (ast.tokencode  == TBaseType.cmtslashstar)
13820                 || (ast.tokencode  == TBaseType.lexspace)
13821                 || (ast.tokencode  == TBaseType.lexnewline)
13822                 || (ast.tokentype  == ETokenType.ttsemicolon) )
13823                {
13824                 if ( TBaseType.assigned(gcurrentsqlstatement) )
13825                   {
13826                     gcurrentsqlstatement.addtokentolist(ast);
13827                   }
13828
13829                 if ( TBaseType.assigned(lcprevsolidtoken) && (ast.tokentype == ETokenType.ttsemicolon) )
13830                   {
13831                     if ( lcprevsolidtoken.tokentype == ETokenType.ttsemicolon )
13832                       {
13833                        // ;;;; continuous semicolon,treat it as comment
13834                         ast.tokentype = ETokenType.ttsimplecomment;
13835                         ast.tokencode =  TBaseType.cmtdoublehyphen;
13836                       }
13837                     else
13838                       {
13839                       }
13840
13841                   }
13842
13843                 continue;
13844                }
13845
13846              gcurrentsqlstatement = lcnextsqlstatement; //isstoredprocedure(ast,dbvendor,gst,sqlstatements);
13847
13848              if ( TBaseType.assigned(gcurrentsqlstatement) )
13849                {
13850                  switch(gcurrentsqlstatement.sqlstatementtype){    //
13851                    case sstcreateprocedure:
13852                    case sstcreatefunction:
13853                    case sstcreatetrigger:
13854                   // case sstalterprocedure:
13855                   // case sstalterfunction:
13856                    case sstaltertrigger:
13857                      {
13858                        gcurrentsqlstatement.addtokentolist(ast);
13859                        gst = EFindSqlStateType.ststoredprocedure;
13860                        break;
13861                      }
13862                    case sstmssqlgo:
13863                      {
13864                        gcurrentsqlstatement.addtokentolist(ast);
13865                        doongetrawsqlstatementevent(gcurrentsqlstatement);
13866                        gst = EFindSqlStateType.stnormal;
13867                          break;
13868                      }
13869                    default:
13870                      {
13871                        gcurrentsqlstatement.addtokentolist(ast);
13872                        gst = EFindSqlStateType.stsql;
13873                          break;
13874                      }
13875                  }    // case
13876                }
13877              else
13878                {
13879                  if ( ast.tokencode == TBaseType.rrw_begin )
13880                    {
13881                      gcurrentsqlstatement = new TMssqlBlock(dbVendor);
13882                      gcurrentsqlstatement.sqlstatementtype = ESqlStatementType.sstmssqlblock;
13883                      gcurrentsqlstatement.addtokentolist(ast);
13884                      gst = EFindSqlStateType.stblock;
13885                    }
13886                  else
13887                    {
13888                      if ( sqlstatements.size() == 0 )
13889                        {
13890                          //first statement of mssql batch, treat it as exec sp
13891                          gst = EFindSqlStateType.stsql;
13892                          gcurrentsqlstatement = new TMssqlExecute(dbVendor);
13893                          //tmssqlexecute(gcurrentsqlstatement).exectype = metnoexeckeyword;
13894// todo need previous line need to be implemented
13895                          gcurrentsqlstatement.addtokentolist(ast);
13896                        }
13897                      else if ( sqlstatements.get(sqlstatements.size() -1).sqlstatementtype == ESqlStatementType.sstmssqlgo )
13898                        {
13899                          // prev sql is go, treat it as exec sp
13900                          gst = EFindSqlStateType.stsql;
13901                          gcurrentsqlstatement = new TMssqlExecute(dbVendor);
13902                          //todo need to be implemented: tmssqlexecute(gcurrentsqlstatement).exectype = metnoexeckeyword;
13903                          gcurrentsqlstatement.addtokentolist(ast);
13904                        }
13905                      else
13906                        {
13907                        }
13908                    }
13909                }
13910
13911
13912              if (  !TBaseType.assigned(gcurrentsqlstatement)  ) //error tokentext found
13913                {
13914
13915//                  errormessage = "error when tokenlize:"+ast.astext+"("+ast.lineNo +","+ast.columnNo +")";
13916//                  errorcount = 1;
13917                    this.syntaxErrors.add( new TSyntaxError(ast.astext,ast.lineNo,(ast.columnNo < 0 ? 0:ast.columnNo)
13918                            ,"Error when tokenlize", EErrorType.spwarning,TBaseType.MSG_WARNING_ERROR_WHEN_TOKENIZE,null,ast.posinlist));
13919
13920                  ast.tokentype = ETokenType.tttokenlizererrortoken;
13921                  gst = EFindSqlStateType.sterror;
13922
13923                  gcurrentsqlstatement = new TUnknownSqlStatement(dbVendor);
13924                  gcurrentsqlstatement.sqlstatementtype = ESqlStatementType.sstinvalid;
13925                  gcurrentsqlstatement.addtokentolist(ast);
13926                }
13927                break;
13928            }
13929          case stblock:
13930            {
13931              if ( TBaseType.assigned(lcnextsqlstatement) )
13932                {
13933                  if ( lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlgo )
13934                    {
13935                        doongetrawsqlstatementevent(gcurrentsqlstatement);
13936                        gcurrentsqlstatement = lcnextsqlstatement;
13937                        gcurrentsqlstatement.addtokentolist(ast);
13938                        doongetrawsqlstatementevent(gcurrentsqlstatement);
13939                        gst = EFindSqlStateType.stnormal;
13940                    }
13941                  else
13942                    {
13943                      lcnextsqlstatement = null;
13944                    }
13945                }
13946
13947                if (( lcblocklevel == -1 )&&(ast.tokencode==';'))
13948                {
13949                    doongetrawsqlstatementevent(gcurrentsqlstatement);
13950                    gst = EFindSqlStateType.stnormal;
13951                    break;
13952                }
13953
13954              if ( gst == EFindSqlStateType.stblock )
13955                {
13956                  gcurrentsqlstatement.addtokentolist(ast);
13957                  if ( ast.tokencode == TBaseType.rrw_begin )
13958                    {
13959                      // { [distributed] transaxtion/trans statement
13960                      // { dialog [ conversation ]
13961                      // { conversation timer
13962                      //  doesn't start block ({ .. })
13963                      lcnextsolidtoken = sourcetokenlist.nextsolidtoken(i,1,false);
13964                      if ( TBaseType.assigned(lcnextsolidtoken) )
13965                        {
13966                          if ( ! (TBaseType.mysametext(lcnextsolidtoken.astext,"tran")
13967                                  || TBaseType.mysametext(lcnextsolidtoken.astext,"transaction")
13968                                  ) )
13969                           lcblocklevel++;
13970                        }
13971                      else
13972                        lcblocklevel++;
13973
13974                    }
13975                  else if ( ast.tokencode == TBaseType.rrw_case )  // case ... }
13976                    lcblocklevel++;
13977                  else if ( ast.tokencode == TBaseType.rrw_end )
13978                    {
13979
13980                      lcisendconversation = false;
13981
13982
13983                      lcnextsolidtoken = sourcetokenlist.nextsolidtoken(i,1,false);
13984
13985                      if ( ! lcisendconversation )
13986                        {
13987
13988                          if ( lcblocklevel == 0 )
13989                            {
13990                              if ( gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlif )
13991                                {
13992                                  if ( TBaseType.assigned(lcnextsolidtoken) )
13993                                    {
13994                                      if ( lcnextsolidtoken.tokencode == TBaseType.rrw_else )
13995                                        {
13996                                          // { .. } else
13997                                          gst = EFindSqlStateType.stsql;
13998                                        }
13999                                      else if ( lcnextsolidtoken.tokentype == ETokenType.ttsemicolon )
14000                                        {
14001                                          lcnnextsolidtoken = sourcetokenlist.nextsolidtoken(lcnextsolidtoken.posinlist,1,false);
14002                                          if ( TBaseType.assigned(lcnnextsolidtoken) )
14003                                            {
14004                                              if ( lcnnextsolidtoken.tokencode == TBaseType.rrw_else )
14005                                                {
14006                                                  // { .. } else
14007                                                  gst = EFindSqlStateType.stsql;
14008                                                }
14009                                            }
14010                                        }
14011                                    }
14012                                }
14013
14014//                              if ( gst != EFindSqlStateType.stsql )
14015//                                {
14016//                                  doongetrawsqlstatementevent(gcurrentsqlstatement);
14017//                                  gst = EFindSqlStateType.stnormal;
14018//                                }
14019
14020                            }
14021                          else
14022                            {
14023                              lcblocklevel--;
14024                            }
14025
14026                        }
14027                    }
14028                }
14029                break;
14030            }
14031          case stsql :
14032            {
14033              if ( (ast.tokentype == ETokenType.ttsemicolon)   )
14034                {
14035                  lcstillinsql = false;
14036                  if ( gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlif )
14037                    {
14038                      lcnextsolidtoken = sourcetokenlist.nextsolidtoken(i,1,false);
14039                      if ( TBaseType.assigned(lcnextsolidtoken) )
14040                        {
14041                          if ( lcnextsolidtoken.tokencode == TBaseType.rrw_else )
14042                            {
14043                              // if ( expr stmt; else
14044                              gcurrentsqlstatement.addtokentolist(ast);
14045                              lcstillinsql = true;
14046                            }
14047
14048                        }
14049                    }
14050
14051                  if (  !lcstillinsql )
14052                    {
14053                      gst = EFindSqlStateType.stnormal;
14054                      gcurrentsqlstatement.addtokentolist(ast);
14055                      gcurrentsqlstatement.semicolonended = ast;
14056                      doongetrawsqlstatementevent(gcurrentsqlstatement);
14057                    }
14058
14059                }
14060              else if ( TBaseType.assigned(lcnextsqlstatement) )
14061                {
14062
14063                  if ( lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlgo )
14064                    {
14065                        doongetrawsqlstatementevent(gcurrentsqlstatement);
14066                        gcurrentsqlstatement = lcnextsqlstatement;
14067                        gcurrentsqlstatement.addtokentolist(ast);
14068                        doongetrawsqlstatementevent(gcurrentsqlstatement);
14069                        gst = EFindSqlStateType.stnormal;
14070                        continue;
14071                    }
14072
14073                  switch(gcurrentsqlstatement.sqlstatementtype){    //
14074                    case sstmssqlif:
14075                    case sstmssqlwhile:
14076                      {
14077                        // if ( || while only contain one sql(not closed by {/} pair)
14078                        // so will still in if ( || while statement
14079                        if ( gcurrentsqlstatement.dummytag == 1 )
14080                          {
14081                            // if ( cond ^stmt nextstmt (^ stands for current pos)
14082                            gcurrentsqlstatement.addtokentolist(ast);
14083
14084                            if ( (lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlif)
14085                            || (lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlwhile)
14086                              )
14087                                gcurrentsqlstatement.dummytag = 1;
14088                              else
14089                                gcurrentsqlstatement.dummytag = 0;
14090
14091
14092                            lcnextsqlstatement = null;
14093                            continue;
14094                          }
14095                      break;
14096                      }//
14097                    case sstcreateschema:
14098                      {
14099                            gcurrentsqlstatement.addtokentolist(ast);
14100                            lcnextsqlstatement = null;
14101                            continue;                          
14102                      }
14103                  }//case
14104
14105                  doongetrawsqlstatementevent(gcurrentsqlstatement);
14106                  gcurrentsqlstatement = lcnextsqlstatement;
14107                  gcurrentsqlstatement.addtokentolist(ast);
14108
14109                  switch(gcurrentsqlstatement.sqlstatementtype){    //
14110                    case sstcreateprocedure:
14111                    case sstcreatefunction:
14112                    case sstcreatetrigger:
14113                    case sstalterprocedure:
14114                    case sstalterfunction:
14115                    case sstaltertrigger:
14116                      {
14117                        gst = EFindSqlStateType.ststoredprocedure;
14118                        break;
14119                      }
14120                    default:
14121                      {
14122                        gst = EFindSqlStateType.stsql;
14123                        break;
14124                      }
14125                  }    // case
14126
14127                }//TBaseType.assigned(lcnextsqlstatement)
14128              else if ( (ast.tokencode == TBaseType.rrw_begin) )
14129                {
14130                  if ( (gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlif)
14131                  || (gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlwhile)
14132                  )
14133                    {
14134                      // start block of if ( || while statement
14135                      gst = EFindSqlStateType.stblock;
14136                      lcblocklevel = 0;
14137                      gcurrentsqlstatement.addtokentolist(ast);
14138                    }
14139                  else
14140                    {
14141                      gcurrentsqlstatement.addtokentolist(ast);
14142                    }
14143                }
14144              else if ( (ast.tokencode == TBaseType.rrw_case) ){
14145                  case_end_nest++;
14146                  gcurrentsqlstatement.addtokentolist(ast);
14147              }
14148              else if ( (ast.tokencode == TBaseType.rrw_end) ){
14149                  if (case_end_nest > 0){
14150                      case_end_nest--;
14151                  }
14152                  gcurrentsqlstatement.addtokentolist(ast);
14153              }
14154              else if ( (ast.tokencode == TBaseType.rrw_else) )
14155                {
14156                  gcurrentsqlstatement.addtokentolist(ast);
14157                  // if ( cond stmt ^else stmt
14158                  if (( (gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlif)
14159                  || (gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmssqlwhile)
14160                  ) && (case_end_nest == 0))
14161                    gcurrentsqlstatement.dummytag = 1; // reduce to 1 while stmt after else is found: if ( cond stmt ^else stmt
14162                }
14163              else
14164                {
14165                  gcurrentsqlstatement.addtokentolist(ast);
14166                }
14167             break;
14168            }
14169          case ststoredprocedure:
14170            {
14171              if ( TBaseType.assigned(lcnextsqlstatement) )
14172                {
14173
14174
14175                  if (( lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstalterfunction )
14176                          ||( lcnextsqlstatement.sqlstatementtype == sstcreateprocedure )
14177                          ||( lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatefunction )
14178                          ||( lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatetrigger )
14179                          ||( lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstalterprocedure )
14180                          ||( lcnextsqlstatement.sqlstatementtype == ESqlStatementType.sstaltertrigger )
14181                          )
14182                    {
14183                        doongetrawsqlstatementevent(gcurrentsqlstatement);
14184                        gcurrentsqlstatement = lcnextsqlstatement;
14185                        gcurrentsqlstatement.addtokentolist(ast);
14186                        gst = EFindSqlStateType.ststoredprocedure;
14187                        break;
14188                    }
14189                  else
14190                    {
14191                      gst = EFindSqlStateType.ststoredprocedurebody;
14192                      gcurrentsqlstatement.addtokentolist(ast);
14193
14194                      lcnextsqlstatement = null;
14195                    }
14196                }
14197
14198              if ( gst == EFindSqlStateType.ststoredprocedure )
14199                {
14200                  gcurrentsqlstatement.addtokentolist(ast);
14201                  if ( ast.tokencode == TBaseType.rrw_begin )
14202                    {
14203                      gst = EFindSqlStateType.ststoredprocedurebody;
14204                    }
14205                    else if ( ast.tokencode == TBaseType.rrw_hana_header )
14206                    {
14207                        gst = EFindSqlStateType.ststoredprocedurebody;
14208                    }
14209                }
14210             break;
14211            } //stplsql
14212          case ststoredprocedurebody:
14213            {
14214              if ( TBaseType.assigned(lcnextsqlstatement) )
14215                {
14216                  switch(lcnextsqlstatement.sqlstatementtype){    //
14217                    case sstmssqlgo:
14218                      {
14219                          doongetrawsqlstatementevent(gcurrentsqlstatement);
14220                          gcurrentsqlstatement = lcnextsqlstatement;
14221                          gcurrentsqlstatement.addtokentolist(ast);
14222                          doongetrawsqlstatementevent(gcurrentsqlstatement);
14223                          gst = EFindSqlStateType.stnormal;
14224                          break;
14225                      }
14226                    case sstcreateprocedure:
14227                    case sstcreatefunction:
14228                    case sstcreatetrigger:
14229                    case sstalterprocedure:
14230                    case sstalterfunction:
14231                    case sstaltertrigger:
14232                      {
14233                        doongetrawsqlstatementevent(gcurrentsqlstatement);
14234                        gcurrentsqlstatement = lcnextsqlstatement;
14235                        gcurrentsqlstatement.addtokentolist(ast);
14236                        gst = EFindSqlStateType.ststoredprocedure;
14237                        break;
14238                      }
14239                    default:
14240                      {
14241                        lcnextsqlstatement = null;
14242                          break;
14243                      }
14244                  }//case
14245                }
14246
14247              if ( gst == EFindSqlStateType.ststoredprocedurebody )
14248                gcurrentsqlstatement.addtokentolist(ast);
14249            }
14250          break;
14251        } //case
14252      } //for
14253
14254
14255    //last statement
14256    if ( TBaseType.assigned(gcurrentsqlstatement) &&  (gst != EFindSqlStateType.stnormal))
14257      {
14258        doongetrawsqlstatementevent(gcurrentsqlstatement);
14259      }
14260
14261    return errorcount;
14262
14263}
14264
14265int dosparksqlgetrawsqlstatements(){
14266
14267
14268        int errorcount = 0;
14269        gcurrentsqlstatement = null;
14270        EFindSqlStateType gst = EFindSqlStateType.stnormal;
14271        int i,c;
14272        TSourceToken ast;
14273        //char ch;
14274        // String lcstr,delimterTokenStr;
14275        boolean waitingDelimiter = false;
14276
14277        //reset delimiter
14278        userDelimiterStr = defaultDelimiterStr;
14279
14280        for (i=0;i < sourcetokenlist.size();i++)
14281        {
14282            ast = sourcetokenlist.get(i);
14283            sourcetokenlist.curpos = i;
14284
14285            if (ast.tokencode == TBaseType.rrw_date){
14286                TSourceToken st1 =  ast.nextSolidToken(); //ast.searchToken('(',1);
14287                if (st1 != null){
14288                    if (st1.tokencode == '('){
14289                        ast.tokencode = TBaseType.rrw_spark_date_function;
14290                    }else if (st1.tokencode == TBaseType.sconst){
14291                        ast.tokencode = TBaseType.rrw_spark_date_const;
14292                    }
14293                }
14294            }
14295            else if (ast.tokencode == TBaseType.rrw_time){
14296                TSourceToken st1 =  ast.nextSolidToken();
14297                if (st1 != null){
14298                    if (st1.tokencode == TBaseType.sconst){
14299                        ast.tokencode = TBaseType.rrw_spark_time_const;
14300                    }
14301                }
14302            }
14303            else if (ast.tokencode == TBaseType.rrw_timestamp){
14304                TSourceToken st1 =  ast.nextSolidToken();
14305                if (st1 != null){
14306                    if (st1.tokencode == TBaseType.sconst){
14307                        ast.tokencode = TBaseType.rrw_spark_timestamp_constant;
14308                    }else if (st1.tokencode == TBaseType.ident){
14309                        if (st1.toString().startsWith("\"")){
14310                            ast.tokencode = TBaseType.rrw_spark_timestamp_constant;
14311                            st1.tokencode = TBaseType.sconst;
14312                        }
14313                    }
14314                }
14315            }
14316            else if (ast.tokencode == TBaseType.rrw_interval){
14317                TSourceToken leftParen = ast.searchToken('(',1);
14318                if ( leftParen != null){
14319                    int k = leftParen.posinlist + 1;
14320                    boolean commaToken = false;
14321                    while (k<ast.container.size()){
14322                        if (ast.container.get(k).tokencode == ')') break;
14323                        if (ast.container.get(k).tokencode == ','){
14324                            commaToken = true;
14325                            break;
14326                        }
14327                        k++;
14328                    }
14329                    if (commaToken){
14330                        ast.tokencode = TBaseType.rrw_mysql_interval_func;
14331                    }
14332                }
14333            }
14334
14335            switch(gst){
14336                case sterror:
14337                {
14338                    if (ast.tokentype == ETokenType.ttsemicolon)
14339                    {
14340                        gcurrentsqlstatement.sourcetokenlist.add(ast);
14341                        doongetrawsqlstatementevent(gcurrentsqlstatement);
14342                        gst = EFindSqlStateType.stnormal;
14343                    }
14344                    else
14345                    {
14346                        gcurrentsqlstatement.sourcetokenlist.add(ast);
14347                    }
14348                    break;
14349                }
14350                case stnormal :
14351                {
14352                    if ((ast.tokencode  == TBaseType.cmtdoublehyphen)
14353                            || (ast.tokencode  == TBaseType.cmtslashstar)
14354                            || (ast.tokencode  == TBaseType.lexspace)
14355                            || (ast.tokencode  == TBaseType.lexnewline)
14356                            || (ast.tokentype  == ETokenType.ttsemicolon) )
14357                    {
14358                        if (TBaseType.assigned(gcurrentsqlstatement))
14359                        {
14360                            gcurrentsqlstatement.addtokentolist(ast);
14361                        }
14362
14363                        continue;
14364                    }
14365
14366                    if ((ast.isFirstTokenOfLine())&&((ast.tokencode == TBaseType.rrw_mysql_source ) || (ast.tokencode == TBaseType.slash_dot)))
14367                    {
14368                        gst = EFindSqlStateType.stsqlplus;
14369                        gcurrentsqlstatement = new TMySQLSource(dbVendor);
14370                        gcurrentsqlstatement.addtokentolist(ast);
14371                        continue;
14372                    }
14373
14374                    // find a tokentext to start sql or plsql mode
14375                    gcurrentsqlstatement = sqlcmds.issql(ast, dbVendor,gst,gcurrentsqlstatement);
14376
14377                    if (TBaseType.assigned(gcurrentsqlstatement))
14378                    {
14379                        ESqlStatementType[] ses = {ESqlStatementType.sstmysqlcreateprocedure, ESqlStatementType.sstmysqlcreatefunction
14380                                , sstcreateprocedure, ESqlStatementType.sstcreatefunction
14381                                , ESqlStatementType.sstcreatetrigger};
14382                        if(includesqlstatementtype(gcurrentsqlstatement.sqlstatementtype, ses) )
14383                        {
14384                            gst = EFindSqlStateType.ststoredprocedure;
14385                            waitingDelimiter = false;
14386                            gcurrentsqlstatement.addtokentolist(ast);
14387                            curdelimiterchar = ';';
14388//                        if (userDelimiterStr == ""){
14389//                            userDelimiterStr = defaultDelimiterStr;
14390//                        }
14391                        }
14392                        else
14393                        {
14394                            gst = EFindSqlStateType.stsql;
14395                            gcurrentsqlstatement.addtokentolist(ast);
14396                        }
14397
14398                    }
14399
14400
14401                    if (!TBaseType.assigned(gcurrentsqlstatement) ) //error tokentext found
14402                    {
14403
14404//                  errormessage = "error when tokenlize:"+ast.astext+"("+ast.lineNo +","+ast.columnNo +")";
14405//                  errorcount = 1;
14406                        this.syntaxErrors.add( new TSyntaxError(ast.astext,ast.lineNo,(ast.columnNo < 0 ? 0:ast.columnNo)
14407                                ,"Error when tokenlize", EErrorType.spwarning,TBaseType.MSG_WARNING_ERROR_WHEN_TOKENIZE,null,ast.posinlist));
14408
14409                        ast.tokentype = ETokenType.tttokenlizererrortoken;
14410                        gst = EFindSqlStateType.sterror;
14411
14412                        gcurrentsqlstatement = new TUnknownSqlStatement(dbVendor);
14413                        gcurrentsqlstatement.sqlstatementtype = ESqlStatementType.sstinvalid;
14414                        gcurrentsqlstatement.addtokentolist(ast);
14415
14416                    }
14417                    break;
14418                }
14419                case stsqlplus:{
14420                    if (ast.tokencode  == TBaseType.lexnewline){
14421                        gst = EFindSqlStateType.stnormal;
14422                        gcurrentsqlstatement.addtokentolist(ast); // so add it here
14423                        doongetrawsqlstatementevent(gcurrentsqlstatement);
14424                    }else {
14425                        {gcurrentsqlstatement.addtokentolist(ast);}
14426                    }
14427
14428                    break;
14429                }//case source command or \. command
14430                case stsql :
14431                {
14432                    if ((ast.tokentype == ETokenType.ttsemicolon)&&(gcurrentsqlstatement.sqlstatementtype != ESqlStatementType.sstmysqldelimiter))
14433                    {
14434                        gst = EFindSqlStateType.stnormal;
14435                        gcurrentsqlstatement.addtokentolist(ast);
14436                        gcurrentsqlstatement.semicolonended = ast;
14437                        doongetrawsqlstatementevent(gcurrentsqlstatement);
14438                        continue;
14439                    }
14440                    if (ast.toString().equalsIgnoreCase(userDelimiterStr))
14441                    {
14442                        gst = EFindSqlStateType.stnormal;
14443                        ast.tokencode = ';';// treat it as semicolon
14444                        gcurrentsqlstatement.addtokentolist(ast);
14445                        gcurrentsqlstatement.semicolonended = ast;
14446                        doongetrawsqlstatementevent(gcurrentsqlstatement);
14447                        continue;
14448                    }
14449                    gcurrentsqlstatement.addtokentolist(ast);
14450
14451                    if ((ast.tokencode  == TBaseType.lexnewline)
14452                            &&(gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmysqldelimiter)){
14453                        gst = EFindSqlStateType.stnormal;
14454                        userDelimiterStr = "";
14455                        for(int k=0;k<gcurrentsqlstatement.sourcetokenlist.size();k++){
14456                            TSourceToken st = gcurrentsqlstatement.sourcetokenlist.get(k);
14457                            if ((st.tokencode == TBaseType.rrw_mysql_delimiter)
14458                                    ||(st.tokencode == TBaseType.lexnewline)
14459                                    ||(st.tokencode == TBaseType.lexspace)
14460                                    ||(st.tokencode == TBaseType.rrw_set) // set delimiter //
14461                            )
14462                            {
14463                                continue;
14464                            }
14465
14466                            userDelimiterStr += st.toString();
14467                            // System.out.println("userDelimiterStr:"+userDelimiterStr);
14468                            // System.out.print(gcurrentsqlstatement.sourcetokenlist.get(k).toString());
14469                        }
14470                        doongetrawsqlstatementevent(gcurrentsqlstatement);
14471
14472                        continue;
14473                    }
14474
14475                    break;
14476                }
14477                case ststoredprocedure :
14478                {
14479                    // single stmt in function/procedure/trigger may use ; as terminate char
14480                    // so default terminate char is ;, if begin is found
14481                    // then set terminate char to DelimiterChar
14482//                    if (!userDelimiterStr.equals(defaultDelimiterStr) )
14483//                      if (ast.tokencode == TBaseType.rrw_begin)
14484//                        userDelimiterStr = defaultDelimiterStr;
14485                    if (waitingDelimiter){
14486                        if (userDelimiterStr.equalsIgnoreCase(ast.toString())){
14487                            gst = EFindSqlStateType.stnormal;
14488                            gcurrentsqlstatement.semicolonended = ast;
14489                            doongetrawsqlstatementevent(gcurrentsqlstatement);
14490                            continue;
14491                        }else if (userDelimiterStr.startsWith(ast.toString())){
14492                            String lcstr = ast.toString();
14493                            for (int k=ast.posinlist+1;k<ast.container.size();k++) {
14494                                TSourceToken st = ast.container.get(k);
14495                                if ((st.tokencode == TBaseType.rrw_mysql_delimiter) || (st.tokencode == TBaseType.lexnewline) || (st.tokencode == TBaseType.lexspace)) {
14496                                    break;
14497                                }
14498                                lcstr = lcstr + st.toString();
14499                            }
14500
14501                            if (userDelimiterStr.equalsIgnoreCase(lcstr)){
14502                                for (int k=ast.posinlist;k<ast.container.size();k++) {
14503                                    TSourceToken st = ast.container.get(k);
14504                                    if ((st.tokencode == TBaseType.rrw_mysql_delimiter) || (st.tokencode == TBaseType.lexnewline) || (st.tokencode == TBaseType.lexspace)) {
14505                                        break;
14506                                    }
14507                                    ast.tokenstatus = ETokenStatus.tsignorebyyacc;
14508                                }
14509                                gst = EFindSqlStateType.stnormal;
14510                                gcurrentsqlstatement.semicolonended = ast;
14511                                doongetrawsqlstatementevent(gcurrentsqlstatement);
14512                                continue;
14513                            }
14514
14515                        }
14516                    }
14517                    if (ast.tokencode == TBaseType.rrw_begin)
14518                        waitingDelimiter = true;
14519
14520                    if (userDelimiterStr.equals(";")||(waitingDelimiter == false))
14521                    {
14522                        gcurrentsqlstatement.addtokentolist(ast);
14523                        if (ast.tokentype == ETokenType.ttsemicolon)
14524                        {
14525                            gst = EFindSqlStateType.stnormal;
14526                            gcurrentsqlstatement.semicolonended = ast;
14527                            // asqlstatement._semicolon := ast;
14528                            doongetrawsqlstatementevent(gcurrentsqlstatement);
14529                            continue;
14530                        }
14531                    }
14532                    else
14533                    {
14534                        if (ast.toString().equals(userDelimiterStr) )
14535                        {
14536                            ast.tokenstatus = ETokenStatus.tsignorebyyacc;
14537                            gcurrentsqlstatement.addtokentolist(ast);
14538                            gst = EFindSqlStateType.stnormal;
14539                            doongetrawsqlstatementevent(gcurrentsqlstatement);
14540                        }
14541                        else{
14542                            if ((ast.tokentype == ETokenType.ttsemicolon)&&(userDelimiterStr.equals(";")))
14543                            {
14544                                TSourceToken lcprevtoken = ast.container.nextsolidtoken(ast,-1,false);
14545                                if (lcprevtoken != null)
14546                                {
14547                                    if (lcprevtoken.tokencode == TBaseType.rrw_end)
14548                                    {
14549                                        gst = EFindSqlStateType.stnormal;
14550                                        gcurrentsqlstatement.semicolonended = ast;
14551                                        gcurrentsqlstatement.addtokentolist(ast);
14552                                        doongetrawsqlstatementevent(gcurrentsqlstatement);
14553                                        continue;
14554                                    }
14555                                }
14556                            }
14557
14558                            gcurrentsqlstatement.addtokentolist(ast);
14559                        }
14560                    } // end of DelimiterChar
14561                    break;
14562                } //mysql sp
14563            } //case
14564        } //for
14565
14566
14567        //last statement
14568        if (TBaseType.assigned(gcurrentsqlstatement) && ( (gst == EFindSqlStateType.stsql) || (gst == EFindSqlStateType.ststoredprocedure) || (gst == EFindSqlStateType.sterror))
14569        )
14570        {
14571            doongetrawsqlstatementevent(gcurrentsqlstatement);
14572        }
14573
14574        return errorcount;
14575
14576}
14577
14578int domysqlgetrawsqlstatements(){
14579    int errorcount = 0;
14580    gcurrentsqlstatement = null;
14581    EFindSqlStateType gst = EFindSqlStateType.stnormal;
14582    int i,c;
14583    TSourceToken ast;
14584    //char ch;
14585   // String lcstr,delimterTokenStr;
14586    boolean waitingDelimiter = false;
14587
14588    //reset delimiter
14589    userDelimiterStr = defaultDelimiterStr;
14590
14591    for (i=0;i < sourcetokenlist.size();i++)
14592    {
14593        ast = sourcetokenlist.get(i);
14594        sourcetokenlist.curpos = i;
14595
14596        if (ast.tokencode == TBaseType.rrw_date){
14597            TSourceToken st1 =  ast.nextSolidToken(); //ast.searchToken('(',1);
14598            if (st1 != null){
14599                if (st1.tokencode == '('){
14600                    ast.tokencode = TBaseType.rrw_mysql_date_function;
14601                }else if (st1.tokencode == TBaseType.sconst){
14602                    ast.tokencode = TBaseType.rrw_mysql_date_const;
14603                }
14604            }
14605        }
14606        else if (ast.tokencode == TBaseType.rrw_time){
14607            TSourceToken st1 =  ast.nextSolidToken();
14608            if (st1 != null){
14609                if (st1.tokencode == TBaseType.sconst){
14610                    ast.tokencode = TBaseType.rrw_mysql_time_const;
14611                }
14612            }
14613        }
14614        else if (ast.tokencode == TBaseType.rrw_timestamp){
14615            TSourceToken st1 =  ast.nextSolidToken();
14616            if (st1 != null){
14617                if (st1.tokencode == TBaseType.sconst){
14618                    ast.tokencode = TBaseType.rrw_mysql_timestamp_constant;
14619                }else if (st1.tokencode == TBaseType.ident){
14620                    if (st1.toString().startsWith("\"")){
14621                        ast.tokencode = TBaseType.rrw_mysql_timestamp_constant;
14622                        st1.tokencode = TBaseType.sconst;
14623                    }
14624                }
14625            }
14626        }
14627        else if (ast.tokencode == TBaseType.rrw_mysql_position){
14628            TSourceToken st1 =  ast.nextSolidToken();
14629            if (st1 != null){
14630                if (st1.tokencode == '('){
14631
14632                }else{
14633                    ast.tokencode = TBaseType.ident; // change position keyword to identifier if not followed by (), position()
14634                }
14635            }
14636        }
14637        else if (ast.tokencode == TBaseType.rrw_mysql_row){
14638            boolean isIdent = true;
14639            TSourceToken st1 =  ast.nextSolidToken();
14640            if (st1 != null){
14641                if (st1.tokencode == '('){
14642                    isIdent = false;
14643                }
14644            }
14645            st1 =  ast.prevSolidToken();
14646            if (st1 != null){
14647                if ((st1.tokencode == TBaseType.rrw_mysql_each)||(st1.tokencode == TBaseType.rrw_mysql_current)){
14648                    isIdent = false;
14649                }
14650            }
14651            if (isIdent) ast.tokencode = TBaseType.ident;
14652        }else if (ast.tokencode == TBaseType.rrw_interval){
14653            TSourceToken leftParen = ast.searchToken('(',1);
14654            if ( leftParen != null){
14655                int k = leftParen.posinlist + 1;
14656                int nested = 1;
14657                boolean commaToken = false;
14658                while (k<ast.container.size()){
14659                    if (ast.container.get(k).tokencode == '(') {
14660                        nested++;
14661                    }
14662                    if (ast.container.get(k).tokencode == ')') {
14663                        nested--;
14664                        if (nested == 0) break;
14665                    }
14666                    if ((ast.container.get(k).tokencode == ',')&&(nested == 1)){
14667                        // only calculate the comma in the first level which is belong to interval
14668                        // don't count comma in the nested () liek this: INTERVAL (SELECT IF(1=1,2,3))
14669                        commaToken = true;
14670                        break;
14671                    }
14672                    k++;
14673                }
14674                if (commaToken){
14675                    ast.tokencode = TBaseType.rrw_mysql_interval_func;
14676                }
14677            }
14678        }
14679
14680        switch(gst){
14681          case sterror:
14682          {
14683              if (ast.tokentype == ETokenType.ttsemicolon)
14684              {
14685                  gcurrentsqlstatement.sourcetokenlist.add(ast);
14686                  doongetrawsqlstatementevent(gcurrentsqlstatement);
14687                  gst = EFindSqlStateType.stnormal;
14688              }
14689              else
14690              {
14691                  gcurrentsqlstatement.sourcetokenlist.add(ast);
14692              }
14693            break;
14694          }
14695          case stnormal :
14696          {
14697              if ((ast.tokencode  == TBaseType.cmtdoublehyphen)
14698                 || (ast.tokencode  == TBaseType.cmtslashstar)
14699                 || (ast.tokencode  == TBaseType.lexspace)
14700                 || (ast.tokencode  == TBaseType.lexnewline)
14701                 || (ast.tokentype  == ETokenType.ttsemicolon) )
14702              {
14703                 if (TBaseType.assigned(gcurrentsqlstatement))
14704                  {
14705                     gcurrentsqlstatement.addtokentolist(ast);
14706                  }
14707
14708                 continue;
14709              }
14710
14711              if (ast.isFirstTokenOfLine() && (ast.toString().equalsIgnoreCase(userDelimiterStr)))
14712              {
14713                  ast.tokencode = ';';// treat it as semicolon
14714                  continue;
14715              }
14716
14717              if ((ast.isFirstTokenOfLine())&&((ast.tokencode == TBaseType.rrw_mysql_source ) || (ast.tokencode == TBaseType.slash_dot)))
14718              {
14719                  gst = EFindSqlStateType.stsqlplus;
14720                  gcurrentsqlstatement = new TMySQLSource(dbVendor);
14721                  gcurrentsqlstatement.addtokentolist(ast);
14722                  continue;
14723              }
14724
14725              // find a tokentext to start sql or plsql mode
14726              gcurrentsqlstatement = sqlcmds.issql(ast, dbVendor,gst,gcurrentsqlstatement);
14727
14728              if (TBaseType.assigned(gcurrentsqlstatement))
14729              {
14730                  ESqlStatementType[] ses = {ESqlStatementType.sstmysqlcreateprocedure, ESqlStatementType.sstmysqlcreatefunction
14731                          , sstcreateprocedure, ESqlStatementType.sstcreatefunction
14732                          , ESqlStatementType.sstcreatetrigger};
14733                  if(includesqlstatementtype(gcurrentsqlstatement.sqlstatementtype, ses) )
14734                  {
14735                        gst = EFindSqlStateType.ststoredprocedure;
14736                        waitingDelimiter = false;
14737                        gcurrentsqlstatement.addtokentolist(ast);
14738                        curdelimiterchar = ';';
14739//                        if (userDelimiterStr == ""){
14740//                            userDelimiterStr = defaultDelimiterStr;
14741//                        }
14742                  }
14743                  else
14744                  {
14745                      gst = EFindSqlStateType.stsql;
14746                      gcurrentsqlstatement.addtokentolist(ast);
14747                  }
14748
14749              }
14750
14751
14752              if (!TBaseType.assigned(gcurrentsqlstatement) ) //error tokentext found
14753              {
14754
14755//                  errormessage = "error when tokenlize:"+ast.astext+"("+ast.lineNo +","+ast.columnNo +")";
14756//                  errorcount = 1;
14757                  this.syntaxErrors.add( new TSyntaxError(ast.astext,ast.lineNo,(ast.columnNo < 0 ? 0:ast.columnNo)
14758                          ,"Error when tokenlize", EErrorType.spwarning,TBaseType.MSG_WARNING_ERROR_WHEN_TOKENIZE,null,ast.posinlist));
14759
14760                  ast.tokentype = ETokenType.tttokenlizererrortoken;
14761                  gst = EFindSqlStateType.sterror;
14762
14763                  gcurrentsqlstatement = new TUnknownSqlStatement(dbVendor);
14764                  gcurrentsqlstatement.sqlstatementtype = ESqlStatementType.sstinvalid;
14765                  gcurrentsqlstatement.addtokentolist(ast);
14766
14767              }
14768                break;
14769            }
14770            case stsqlplus:{
14771                if (ast.tokencode  == TBaseType.lexnewline){
14772                    gst = EFindSqlStateType.stnormal;
14773                    gcurrentsqlstatement.addtokentolist(ast); // so add it here
14774                    doongetrawsqlstatementevent(gcurrentsqlstatement);
14775                }else {
14776                    {gcurrentsqlstatement.addtokentolist(ast);}
14777                }
14778
14779                break;
14780            }//case source command or \. command
14781          case stsql :
14782          {
14783              if ((ast.tokentype == ETokenType.ttsemicolon)&&(gcurrentsqlstatement.sqlstatementtype != ESqlStatementType.sstmysqldelimiter))
14784              {
14785                  gst = EFindSqlStateType.stnormal;
14786                  gcurrentsqlstatement.addtokentolist(ast);
14787                  gcurrentsqlstatement.semicolonended = ast;
14788                  doongetrawsqlstatementevent(gcurrentsqlstatement);
14789                  continue;
14790              }
14791              if (ast.toString().equalsIgnoreCase(userDelimiterStr))
14792              {
14793                  gst = EFindSqlStateType.stnormal;
14794                  ast.tokencode = ';';// treat it as semicolon
14795                  gcurrentsqlstatement.addtokentolist(ast);
14796                  gcurrentsqlstatement.semicolonended = ast;
14797                  doongetrawsqlstatementevent(gcurrentsqlstatement);
14798                  continue;
14799              }
14800
14801              if (ast.tokencode  == TBaseType.cmtdoublehyphen){
14802                  if (ast.toString().trim().endsWith(TBaseType.sqlflow_stmt_delimiter_str)){ // -- sqlflow-delimiter
14803                      gst = EFindSqlStateType.stnormal;
14804                      doongetrawsqlstatementevent(gcurrentsqlstatement);
14805                      continue;
14806                  }
14807              }
14808
14809              gcurrentsqlstatement.addtokentolist(ast);
14810
14811              if ((ast.tokencode  == TBaseType.lexnewline)
14812                      &&(gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstmysqldelimiter)){
14813                  gst = EFindSqlStateType.stnormal;
14814                  userDelimiterStr = "";
14815                  for(int k=0;k<gcurrentsqlstatement.sourcetokenlist.size();k++){
14816                      TSourceToken st = gcurrentsqlstatement.sourcetokenlist.get(k);
14817                      if ((st.tokencode == TBaseType.rrw_mysql_delimiter)
14818                          ||(st.tokencode == TBaseType.lexnewline)
14819                          ||(st.tokencode == TBaseType.lexspace)
14820                          ||(st.tokencode == TBaseType.rrw_set) // set delimiter //
14821                      )
14822                      {
14823                          continue;
14824                      }
14825
14826                      userDelimiterStr += st.toString();
14827                      // System.out.println("userDelimiterStr:"+userDelimiterStr);
14828                     // System.out.print(gcurrentsqlstatement.sourcetokenlist.get(k).toString());
14829                  }
14830                  doongetrawsqlstatementevent(gcurrentsqlstatement);
14831
14832                  continue;
14833              }
14834
14835              break;
14836          }
14837          case ststoredprocedure :
14838          {
14839
14840              if (( gst == EFindSqlStateType.ststoredprocedure ) && (ast.tokencode  == TBaseType.cmtdoublehyphen)){
14841                  if (ast.toString().trim().endsWith(TBaseType.sqlflow_stmt_delimiter_str)){ // -- sqlflow-delimiter
14842                      gst = EFindSqlStateType.stnormal;
14843                      doongetrawsqlstatementevent(gcurrentsqlstatement);
14844                      continue;
14845                  }
14846              }
14847                  // single stmt in function/procedure/trigger may use ; as terminate char
14848                  // so default terminate char is ;, if begin is found
14849                  // then set terminate char to DelimiterChar
14850//                    if (!userDelimiterStr.equals(defaultDelimiterStr) )
14851//                      if (ast.tokencode == TBaseType.rrw_begin)
14852//                        userDelimiterStr = defaultDelimiterStr;
14853              if (waitingDelimiter){
14854                  if (userDelimiterStr.equalsIgnoreCase(ast.toString())){
14855                      gst = EFindSqlStateType.stnormal;
14856                      gcurrentsqlstatement.semicolonended = ast;
14857                      doongetrawsqlstatementevent(gcurrentsqlstatement);
14858                      continue;
14859                  }else if (userDelimiterStr.startsWith(ast.toString())){
14860                      String lcstr = ast.toString();
14861                      for (int k=ast.posinlist+1;k<ast.container.size();k++) {
14862                          TSourceToken st = ast.container.get(k);
14863                          if ((st.tokencode == TBaseType.rrw_mysql_delimiter) || (st.tokencode == TBaseType.lexnewline) || (st.tokencode == TBaseType.lexspace)) {
14864                              break;
14865                          }
14866                          lcstr = lcstr + st.toString();
14867                      }
14868
14869                      if (userDelimiterStr.equalsIgnoreCase(lcstr)){
14870                          for (int k=ast.posinlist;k<ast.container.size();k++) {
14871                              TSourceToken st = ast.container.get(k);
14872                              if ((st.tokencode == TBaseType.rrw_mysql_delimiter) || (st.tokencode == TBaseType.lexnewline) || (st.tokencode == TBaseType.lexspace)) {
14873                                  break;
14874                              }
14875                              ast.tokenstatus = ETokenStatus.tsignorebyyacc;
14876                          }
14877                          gst = EFindSqlStateType.stnormal;
14878                          gcurrentsqlstatement.semicolonended = ast;
14879                          doongetrawsqlstatementevent(gcurrentsqlstatement);
14880                          continue;
14881                      }
14882
14883                  }
14884              }
14885                      if (ast.tokencode == TBaseType.rrw_begin)
14886                          waitingDelimiter = true;
14887
14888                    if (userDelimiterStr.equals(";")||(waitingDelimiter == false))
14889                    {
14890                        gcurrentsqlstatement.addtokentolist(ast);
14891                        if (ast.tokentype == ETokenType.ttsemicolon)
14892                        {
14893                            gst = EFindSqlStateType.stnormal;
14894                            gcurrentsqlstatement.semicolonended = ast;
14895                            // asqlstatement._semicolon := ast;
14896                            doongetrawsqlstatementevent(gcurrentsqlstatement);
14897                            continue;
14898                        }
14899                    }
14900                    else
14901                    {
14902                          if (ast.toString().equals(userDelimiterStr) )
14903                          {
14904                              ast.tokenstatus = ETokenStatus.tsignorebyyacc;
14905                              gcurrentsqlstatement.addtokentolist(ast);
14906                              gst = EFindSqlStateType.stnormal;
14907                              doongetrawsqlstatementevent(gcurrentsqlstatement);
14908                          }
14909                          else{
14910                              if ((ast.tokentype == ETokenType.ttsemicolon)&&(userDelimiterStr.equals(";")))
14911                              {
14912                                  TSourceToken lcprevtoken = ast.container.nextsolidtoken(ast,-1,false);
14913                                  if (lcprevtoken != null)
14914                                  {
14915                                      if (lcprevtoken.tokencode == TBaseType.rrw_end)
14916                                      {
14917                                          gst = EFindSqlStateType.stnormal;
14918                                          gcurrentsqlstatement.semicolonended = ast;
14919                                          gcurrentsqlstatement.addtokentolist(ast);
14920                                          doongetrawsqlstatementevent(gcurrentsqlstatement);
14921                                          continue;
14922                                      }
14923                                  }
14924                              }
14925
14926                            gcurrentsqlstatement.addtokentolist(ast);
14927                          }
14928                    } // end of DelimiterChar
14929          break;
14930          } //mysql sp
14931    } //case
14932} //for
14933
14934
14935    //last statement
14936    if (TBaseType.assigned(gcurrentsqlstatement) && ( (gst == EFindSqlStateType.stsql) || (gst == EFindSqlStateType.ststoredprocedure) || (gst == EFindSqlStateType.sterror))
14937            ) 
14938    {
14939        doongetrawsqlstatementevent(gcurrentsqlstatement);
14940    }
14941
14942    return errorcount;
14943}
14944
14945int dodb2getrawsqlstatements(){
14946    gcurrentsqlstatement = null;
14947    EFindSqlStateType gst = EFindSqlStateType.stnormal;
14948    int i,c;
14949    TSourceToken ast;
14950    int errorcount = 0;
14951    char ch;
14952    String lcstr;
14953    int waitingEnds = 0;
14954    boolean waitingForFirstBegin = false;
14955
14956    for (i=0 ; i<sourcetokenlist.size();i++)
14957    {
14958        ast = sourcetokenlist.get(i);
14959        //System.out.println(ast);
14960        sourcetokenlist.curpos = i;
14961
14962        if (ast.tokencode == TBaseType.rrw_declare){
14963            TSourceToken st1 = ast.searchToken("global",1);
14964            if (st1 != null){
14965              ast.tokencode = TBaseType.rrw_declare_global;
14966            }
14967        }else if ((ast.tokencode == TBaseType.rrw_year)||(ast.tokencode == TBaseType.rrw_db2_second)
14968                ||(ast.tokencode == TBaseType.rrw_db2_current)){
14969            TSourceToken st1 = ast.searchToken('.',1);
14970            if (st1 != null){
14971                // year.columnA, year is a table alias
14972                ast.tokencode = TBaseType.ident;
14973            }
14974        }else if ((ast.tokencode == TBaseType.rrw_db2_trim_l)||(ast.tokencode == TBaseType.rrw_db2_trim_r)){
14975            TSourceToken st1 = ast.searchToken(TBaseType.rrw_db2_trim,-2);
14976            if (st1 == null){
14977                // not L,R in TRIM (R 'Mr.' FROM name)
14978                ast.tokencode = TBaseType.ident;
14979            }
14980        }
14981
14982        switch(gst){
14983          case sterror:
14984          {
14985              if (ast.tokentype == ETokenType.ttsemicolon)
14986              {
14987                  gcurrentsqlstatement.sourcetokenlist.add(ast);
14988                  doongetrawsqlstatementevent(gcurrentsqlstatement);
14989                  gst = EFindSqlStateType.stnormal;
14990              }
14991              else
14992              {
14993                  gcurrentsqlstatement.sourcetokenlist.add(ast);
14994              }
14995              break;
14996          }
14997          case stnormal :
14998          {
14999              if ((ast.tokencode  == TBaseType.cmtdoublehyphen)
15000                 || (ast.tokencode  == TBaseType.cmtslashstar)
15001                 || (ast.tokencode  == TBaseType.lexspace)
15002                 || (ast.tokencode  == TBaseType.lexnewline)
15003                 || (ast.tokentype  == ETokenType.ttsemicolon))
15004                 {
15005                 if (TBaseType.assigned(gcurrentsqlstatement))
15006                     {
15007                     gcurrentsqlstatement.addtokentolist(ast);
15008                     }
15009                 continue;
15010                 }
15011
15012              if (ast.tokencode == TBaseType.sqlpluscmd )
15013              { // echo in db2 is treated as sqlplus cmd
15014                  gst = EFindSqlStateType.stsqlplus;
15015                  gcurrentsqlstatement = new TSqlplusCmdStatement(dbVendor);
15016                  gcurrentsqlstatement.addtokentolist(ast);
15017                  continue;
15018              }
15019
15020              // find a tokentext to start sql or plsql mode
15021              gcurrentsqlstatement = sqlcmds.issql(ast, dbVendor,gst,gcurrentsqlstatement);
15022
15023              if (TBaseType.assigned(gcurrentsqlstatement))
15024              {
15025                  ESqlStatementType[] ses = {ESqlStatementType.sstdb2declarecursor, sstcreateprocedure,
15026                          ESqlStatementType.sstcreatefunction, ESqlStatementType.sstcreatetrigger,ESqlStatementType.sst_plsql_block};
15027                  if(includesqlstatementtype(gcurrentsqlstatement.sqlstatementtype, ses) )
15028                       {
15029                        gst = EFindSqlStateType.ststoredprocedure;
15030                        waitingEnds = 1; //need a END keyword to end this procedure
15031                        waitingForFirstBegin = true;
15032                        gcurrentsqlstatement.addtokentolist(ast);
15033                        if ((gcurrentsqlstatement.sqlstatementtype == sstcreateprocedure)
15034                        || (gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatefunction)
15035                        || (gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatetrigger))
15036                           {
15037                            curdelimiterchar = ';';
15038                           }
15039                        }
15040                  else if (gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstdb2scriptOption){
15041                      gst = EFindSqlStateType.stnormal;
15042                      gcurrentsqlstatement.addtokentolist(ast);
15043                      doongetrawsqlstatementevent(gcurrentsqlstatement);
15044                  }
15045                  else  {
15046                      gst = EFindSqlStateType.stsql;
15047                      gcurrentsqlstatement.addtokentolist(ast);
15048                    }
15049
15050              }
15051
15052
15053              if (!TBaseType.assigned(gcurrentsqlstatement) ) //error tokentext found
15054              {
15055
15056//                  errormessage = "error when tokenlize:"+ast.astext+"("+ast.lineNo +","+ast.columnNo +")";
15057//                  errorcount = 1;
15058                  this.syntaxErrors.add( new TSyntaxError(ast.astext,ast.lineNo,(ast.columnNo < 0 ? 0:ast.columnNo)
15059                          ,"Error when tokenlize", EErrorType.spwarning,TBaseType.MSG_WARNING_ERROR_WHEN_TOKENIZE,null,ast.posinlist));
15060
15061                  ast.tokentype = ETokenType.tttokenlizererrortoken;
15062                  gst = EFindSqlStateType.sterror;
15063
15064                  gcurrentsqlstatement = new TUnknownSqlStatement(dbVendor);
15065                  gcurrentsqlstatement.sqlstatementtype = ESqlStatementType.sstinvalid;
15066                  gcurrentsqlstatement.addtokentolist(ast);
15067
15068              }
15069              break;
15070          }
15071          case stsqlplus : //// treat echo, ! of db2 at the begin of each line as oracle sqlplus command
15072          {
15073              if (ast.insqlpluscmd)
15074              { gcurrentsqlstatement.addtokentolist(ast);}
15075              else
15076              {
15077                  gst = EFindSqlStateType.stnormal; //this tokentext must be newline,
15078                  gcurrentsqlstatement.addtokentolist(ast); // so add it here
15079                  doongetrawsqlstatementevent(gcurrentsqlstatement);
15080              }
15081              break;
15082          }
15083          case stsql :
15084          {
15085              if (ast.tokentype == ETokenType.ttsemicolon)
15086              {
15087                  gst = EFindSqlStateType.stnormal;
15088                  gcurrentsqlstatement.addtokentolist(ast);
15089                  gcurrentsqlstatement.semicolonended = ast;
15090                  doongetrawsqlstatementevent(gcurrentsqlstatement);
15091                  continue;
15092              }
15093              gcurrentsqlstatement.addtokentolist(ast);
15094
15095              break;
15096          }
15097          case ststoredprocedure :
15098          {
15099              nextStmt = sqlcmds.issql(ast, dbVendor,gst,gcurrentsqlstatement);
15100              if ((nextStmt != null)
15101                      &&((nextStmt.sqlstatementtype == sstcreateprocedure)
15102                      || (nextStmt.sqlstatementtype == ESqlStatementType.sstcreatefunction)
15103                      || (nextStmt.sqlstatementtype == ESqlStatementType.sstcreatetrigger))
15104                      )
15105              {
15106                  doongetrawsqlstatementevent(gcurrentsqlstatement);
15107                  gcurrentsqlstatement = nextStmt;
15108                  gst = EFindSqlStateType.ststoredprocedure;
15109                  waitingEnds = 1; //need a END keyword to end this procedure
15110                  waitingForFirstBegin = true;
15111                  gcurrentsqlstatement.addtokentolist(ast);
15112                  curdelimiterchar = ';';
15113                  continue;
15114              }
15115
15116                  // single stmt in function/procedure/trigger may use ; as terminate char
15117                  // so default terminate char is ;, if begin is found ,then
15118                  //set terminate char to DelimiterChar
15119                    if (curdelimiterchar !=  delimiterchar)
15120//                    if TBaseType.mycomparetext(lzWideLowerCase(ast.astext),'begin') = 0 then
15121                      if((ast.tokencode == TBaseType.rrw_begin )||(ast.tokencode == TBaseType.rrw_declare ))
15122                      {
15123                          curdelimiterchar = delimiterchar;
15124                      }
15125
15126
15127                    if (curdelimiterchar == ';')
15128                    {
15129                        gcurrentsqlstatement.addtokentolist(ast);
15130                        if (ast.tokentype == ETokenType.ttsemicolon)
15131                        {
15132                            gst = EFindSqlStateType.stnormal;
15133                            //asqlstatement.SemiColonEnded := ast;
15134                             gcurrentsqlstatement._semicolon = ast;
15135                            doongetrawsqlstatementevent(gcurrentsqlstatement);
15136                            continue;
15137                        }
15138                    }
15139                    else
15140                    {
15141                          if (ast.astext.length() == 1 )
15142                          { ch = ast.astext.charAt(0);}
15143                          else if ((ast.astext.length() > 1)&&(ast.issolidtoken()))
15144                           { ch = ast.astext.charAt(ast.astext.length()-1); }
15145                          else
15146                          { ch = ' ';}
15147
15148
15149                          if (ch == curdelimiterchar )
15150                          {
15151                              if (ast.astext.length() > 1)
15152                              {
15153                                  lcstr = ast.astext.substring(0,ast.astext.length()-1);
15154                                  if ((c=flexer.getkeywordvalue(lcstr))>0 )
15155                                    ast.tokencode = c;
15156                              }
15157                              else
15158                              {
15159                                 // ast.TokenStatus := tsIgnoreByyacc;
15160                                 // ast.Tokentype :=   ttDoublehyphenComment; //make this tokentext available like a comment
15161                                  gcurrentsqlstatement._semicolon = ast;
15162                              }
15163                              gcurrentsqlstatement.addtokentolist(ast);
15164                              gst = EFindSqlStateType.stnormal;
15165                              doongetrawsqlstatementevent(gcurrentsqlstatement);
15166                          }
15167                          else
15168                          {
15169                              gcurrentsqlstatement.addtokentolist(ast);
15170
15171                              if((ast.tokencode == TBaseType.rrw_case)
15172                                      ||(ast.tokencode == TBaseType.rrw_for)
15173                                      ||(ast.tokencode == TBaseType.rrw_if)
15174                                      ||(ast.tokencode == TBaseType.rrw_while)
15175                                      ||(ast.tokencode == TBaseType.rrw_repeat)
15176                                      ||(ast.tokencode == TBaseType.rrw_loop)
15177                              ){
15178                                  TSourceToken nextst = ast.nextSolidToken();
15179                                  if (nextst != null){
15180                                      if (nextst.tokencode != ';'){
15181                                          waitingEnds++;
15182                                      }
15183                                  }
15184
15185                              } else if(ast.tokencode == TBaseType.rrw_begin){
15186                                  if (waitingForFirstBegin){
15187                                      waitingForFirstBegin = false;
15188                                  }else{
15189                                      waitingEnds++;
15190                                  }
15191                              } else if(ast.tokencode == TBaseType.rrw_end){
15192                                  waitingEnds--;
15193                              }
15194
15195                              if ((ast.tokentype == ETokenType.ttsemicolon)&&(waitingEnds == 0))
15196                              {
15197                                  gst = EFindSqlStateType.stnormal;
15198                                  //asqlstatement.SemiColonEnded := ast;
15199                                   gcurrentsqlstatement._semicolon = ast;
15200                                  doongetrawsqlstatementevent(gcurrentsqlstatement);
15201                                  continue;
15202                              }
15203
15204                          }
15205                    } // end of DelimiterChar
15206
15207              break;
15208          } //db2 sp
15209        } //case
15210    } //for
15211
15212
15213    //last statement
15214    if (TBaseType.assigned(gcurrentsqlstatement) && ((gst == EFindSqlStateType.stsqlplus) ||  (gst == EFindSqlStateType.stsql) || (gst == EFindSqlStateType.ststoredprocedure) || (gst == EFindSqlStateType.sterror)) )
15215    {
15216        doongetrawsqlstatementevent(gcurrentsqlstatement);
15217    }
15218
15219    return errorcount;//FSqlStatements.Count;
15220
15221}
15222
15223int doteradatagetrawsqlstatements(){
15224    gcurrentsqlstatement = null;
15225    EFindSqlStateType gst = EFindSqlStateType.stnormal;
15226    int i,c,lcNestedParens = 0, lcNestedBeginEnd = 0, lcNestedCase = 0, lcNestedSample = 0;
15227    TSourceToken lcprevst = null,lcnextst=null,lcnextst2= null, lcnextst3 = null,
15228            lcprevsolidtoken = null,ast = null,lcprevst2 = null;
15229    int errorcount = 0;
15230    char ch;
15231    String lcstr;
15232    boolean inBTEQComment = false, isContinueBTEQCmd = false;
15233
15234    for (i=0 ; i<sourcetokenlist.size();i++)
15235    {
15236        if ( (ast != null ) && (ast.issolidtoken() ))
15237          lcprevsolidtoken = ast;
15238
15239        ast = sourcetokenlist.get(i);
15240        //System.out.println(ast);
15241        sourcetokenlist.curpos = i;
15242
15243        if ((ast.tokencode == TBaseType.rrw_time)
15244                ||(ast.tokencode == TBaseType.rrw_date)
15245                ||(ast.tokencode == TBaseType.rrw_timestamp)
15246           )
15247            {
15248            }else if (ast.tokencode == '('){
15249                    lcnextst = sourcetokenlist.nextsolidtoken(i,1,false);
15250                    lcprevst =  getprevsolidtoken(ast);
15251                    if ((lcprevst != null)&&(
15252                                (lcprevst.tokencode == TBaseType.rrw_teradata_cast)
15253                                    ||(lcprevst.tokencode == TBaseType.rrw_year) // sample sql: select year(date) - 1 mantisbt/view.php?id=3049
15254                            )
15255                        ){
15256                        lcnextst = null; // don't check next token if prev token is cast. sample: cast(DATETIME as BIGINT)
15257                    }
15258                    if ((lcprevst!=null)&&(TFunctionCall.isBuiltIn(lcprevst.toString(),EDbVendor.dbvteradata))){
15259                        if (((lcprevst.tokencode == TBaseType.rrw_end)
15260                                ||(lcprevst.tokencode == TBaseType.rrw_time)
15261                                ||(lcprevst.tokencode == TBaseType.rrw_date)
15262                                ||(lcprevst.tokencode == TBaseType.rrw_timestamp)
15263                                ||(lcprevst.tokencode == TBaseType.rrw_teradata_type)
15264                                ||(lcprevst.toString().equalsIgnoreCase("current_date"))
15265                                ||(lcprevst.toString().equalsIgnoreCase("current_time"))
15266                                ||(lcprevst.toString().equalsIgnoreCase("current_timestamp"))
15267                                ||(lcprevst.toString().equalsIgnoreCase("user"))
15268                                ||(lcprevst.toString().equalsIgnoreCase("current_user"))
15269                                ))
15270                        {
15271
15272                        }else{
15273                            lcnextst = null;
15274                        }
15275                    }
15276
15277                    if (lcnextst != null){
15278                        EDataType dataType = TTypeName.searchTeradataTypeByName(lcnextst.toString());
15279                        if (( dataType != null)&&(lcprevst!=null)&&(lcprevst.tokencode != TBaseType.rrw_teradata_period)){
15280                            ast.tokencode = TBaseType.rrw_teradata_start_data_conversion;
15281                            // lcnextst2 is the token 2 steps after (
15282                            lcnextst2 = sourcetokenlist.nextsolidtoken(i,2,false);
15283
15284                            // lcnextst3 is the token 3 steps after (
15285                            lcnextst3 = sourcetokenlist.nextsolidtoken(i,3,false);
15286
15287                            if (lcnextst2.tokencode == ',') {
15288                                // this is data conversion: (date,format '$xxx'),
15289                                // this is not data conversion: trunc(date,'yy')
15290                                TSourceToken st1 = lcnextst3;
15291                                TSourceToken st2 = sourcetokenlist.nextsolidtoken(i, 4, false);
15292                                if (TDatatypeAttribute.searchDataTypeAttributeByName(st1, st2) != null) {
15293                                    // this is data conversion, such as (date,format '$xxx'),
15294                                } else {
15295                                    // this is not data conversion, such as :trunc(date,'yy')
15296                                    ast.tokencode = '(';
15297                                }
15298                            }else if ((lcnextst2 != null)&&(lcnextst3 != null)){
15299                                switch (dataType){
15300                                    case date_t:
15301                                    case time_t:
15302                                        // next token is: ) or comma or data attribute token
15303                                        if ((lcnextst2.tokencode == ')')
15304                                                    ||((lcnextst2.tokencode == '(')&&(lcnextst3.tokencode == 263)) // hire_date (time(6))
15305                                        ) {
15306                                            //  (date)
15307                                            // select (date) from t, here (date) is a function, not a data conversion,
15308                                            //
15309
15310                                        }else {
15311                                            ast.tokencode = '(';
15312                                        }
15313                                        break;
15314                                    case timestamp_t:
15315                                    case interval_t:
15316                                        if (lcnextst2.tokencode == TBaseType.sconst){ // INSERT t1 (TIME '10:44:25.123-08:00',TIMESTAMP '2000-09-20 10:44:25.1234')
15317                                            ast.tokencode = '(';
15318                                        }
15319                                            break;
15320                                    case period_t:
15321
15322                                        if (lcnextst2.tokencode == '('){
15323                                            // 只有 period() 才确保这里 period 是datatype,否则period不是datatype
15324                                        }else{
15325                                            ast.tokencode = '(';
15326                                        }
15327                                        break;
15328                                    case char_t:
15329                                        if (lcnextst2.tokencode == ')'){
15330                                            //  NULL (CHAR) AS B
15331
15332                                        }
15333                                        else if (lcnextst3.tokencode != TBaseType.iconst){ // INSERT t1 (TIME '10:44:25.123-08:00',TIMESTAMP '2000-09-20 10:44:25.1234')
15334                                            ast.tokencode = '(';
15335                                        }
15336                                        break;
15337                                    default:
15338                                        break;
15339                                }
15340                            }
15341                        }else{
15342//                            lcstr = lcnextst.toString();
15343//                            if ((lcnextst.tokencode == TBaseType.rrw_not)||(lcnextst.tokencode == TBaseType.rw_not1) // not null, not casespecific
15344//                                ||(lcnextst.tokencode == TBaseType.rrw_with) // with default, with time zone
15345//                            ){
15346//                                // data attribute include more than one keyword, concate the first 2 keywords
15347//                                lcnextst = sourcetokenlist.nextsolidtoken(i, 2, false);
15348//                                if (lcnextst != null){
15349//                                    lcstr = lcstr+"_"+lcnextst.toString();
15350//                                }else{
15351//                                    lcstr = lcstr+"_";
15352//                                }
15353//                            }
15354
15355                            TSourceToken st1 = lcnextst;
15356                            TSourceToken st2 = sourcetokenlist.nextsolidtoken(i, 2, false);
15357                            if (TDatatypeAttribute.searchDataTypeAttributeByName(st1,st2) != null){
15358                                ast.tokencode = TBaseType.rrw_teradata_start_data_conversion;
15359                            }
15360                        }
15361                    }
15362        }else if (ast.tokencode == TBaseType.rrw_for){
15363            TSourceToken nextToken = ast.searchTokenAfterObjectName();
15364            if (nextToken != null){
15365                if (nextToken.tokencode == TBaseType.rrw_as){
15366                    ast.tokencode = TBaseType.rrw_teradata_for_loop;
15367                }
15368            }
15369        }else if (ast.tokencode == TBaseType.rrw_teradata_last){
15370            TSourceToken nextToken = ast.searchToken('(',1);
15371            if (nextToken != null){
15372               ast.tokencode = TBaseType.rrw_last_function;
15373            }
15374        }else if (ast.tokencode == TBaseType.rrw_teradata_pivot){
15375            TSourceToken nextToken = ast.searchToken('(',1);
15376            if (nextToken == null){
15377                ast.tokencode = TBaseType.ident;
15378            }
15379        }else if (ast.tokencode == TBaseType.rrw_teradata_period){
15380            TSourceToken nextToken =  ast.nextSolidToken(); // ast.searchToken('(',1);
15381            if (nextToken == null){
15382                ast.tokencode = TBaseType.ident;
15383            }else if (nextToken.tokencode == '('){
15384                // keep it as keyword
15385            }else if (nextToken.tokencode == TBaseType.rrw_for){
15386                // keep it as keyword
15387            }else if (nextToken.tokencode == TBaseType.sconst){
15388                // sample: DEFAULT PERIOD '(2005-02-03, 2006-02-03)'
15389                // keep it as keyword
15390            }else {
15391                if (ast.prevSolidToken() == null){
15392                    ast.tokencode = TBaseType.ident;
15393                }else{
15394                    if (!ast.prevSolidToken().toString().equalsIgnoreCase("anchor")){
15395                        ast.tokencode = TBaseType.ident;
15396                    }
15397                }
15398            }
15399        }else if (ast.tokencode == TBaseType.rrw_teradata_transaction) {
15400            lcprevst =  getprevsolidtoken(ast);
15401            if (lcprevst != null) {
15402                if (lcprevst.tokencode == TBaseType.rrw_end){
15403                    lcprevst.tokencode = TBaseType.rrw_teradata_end_t;
15404                }
15405            }
15406        }else if (ast.tokencode == TBaseType.rrw_replace) {
15407            TSourceToken nextToken = ast.searchToken('(',1);
15408            if (nextToken != null){
15409               ast.tokencode = TBaseType.ident;
15410            }
15411        }else if (ast.tokencode == TBaseType.rrw_between) {
15412            TSourceToken nextToken = ast.nextSolidToken();
15413            if (nextToken != null){
15414                if ((nextToken.tokencode == TBaseType.rrw_begin)||(nextToken.tokencode == TBaseType.rrw_end)){
15415                    // BETWEEN begin(DODD_EFF_PERI)
15416                    nextToken.tokencode = TBaseType.ident;
15417                }
15418            }
15419        }else if (ast.tokencode == TBaseType.rrw_declare) {
15420            TSourceToken nextToken = ast.nextSolidToken();
15421            if (nextToken != null){
15422                TSourceToken nextnextToken = nextToken.nextSolidToken();
15423                if (nextnextToken != null){
15424                    if ((nextnextToken.toString().equalsIgnoreCase("cursor"))
15425                    ||(nextnextToken.toString().equalsIgnoreCase("insensitive"))
15426                            ||(nextnextToken.toString().equalsIgnoreCase("scroll"))
15427                            ||(nextnextToken.toString().equalsIgnoreCase("no"))
15428                    ){
15429                        nextToken.tokencode = TBaseType.rrw_teradata_cursor_name;
15430                    }else if ((nextnextToken.toString().equalsIgnoreCase("condition"))){
15431                        nextToken.tokencode = TBaseType.rrw_teradata_condition_name;
15432                    }
15433                }
15434            }
15435        }else if ((ast.tokencode == TBaseType.rrw_case)&&(ast.tag == 0)&&(ast.posinlist + 1 < sourcetokenlist.size())) {
15436            int lcNest = 1;
15437            for(int m=ast.posinlist+1;m< sourcetokenlist.size()-1;m++){
15438                TSourceToken st = sourcetokenlist.get(m);
15439                if (st.tokencode == TBaseType.rrw_case) {
15440                    st.tag = 1;// this is nested case keyword, don't check this token later
15441                    lcNest++;
15442                }
15443                if (st.tokencode == TBaseType.rrw_end) {
15444                    lcNest--;
15445                    if (lcNest == 0){
15446                        TSourceToken caseToken = st.nextSolidToken();
15447                        if (caseToken != null){
15448                            if (caseToken.tokencode == TBaseType.rrw_case){
15449                                ast.tokencode = TBaseType.rrw_teradata_case_stmt;
15450                                caseToken.tag = 1; // this is case after end, don't check this token later
15451                                break;
15452                            }
15453                        }
15454                    }
15455                }
15456            }
15457        } else if (ast.tokencode == TBaseType.rrw_grant) {
15458            TSourceToken prevSolidToken = ast.prevSolidToken();
15459            if (prevSolidToken != null) {
15460                if (prevSolidToken.tokencode == TBaseType.rrw_with){
15461                    prevSolidToken.tokencode = TBaseType.rrw_teradata_with_grant;
15462                }
15463            }
15464        } else if (ast.tokencode == TBaseType.variable) {
15465            // USING ( _spVV8 VARCHAR(1024) CHARACTER SET UNICODE ) SELECT INTO :_spVV8 ;
15466            // variable after into keyword treat as identifier
15467
15468            TSourceToken prevSolidToken = ast.prevSolidToken();
15469            if (prevSolidToken != null) {
15470                if (prevSolidToken.tokencode == TBaseType.rrw_into){
15471                    ast.tokencode = TBaseType.ident;
15472                }
15473            }
15474        }else if ((ast.tokencode == TBaseType.rrw_teradata_sequenced)||(ast.tokencode == TBaseType.rrw_teradata_nonsequenced)) {
15475            TSourceToken nextSolidToken = ast.nextSolidToken();
15476            if (nextSolidToken != null) {
15477                if ((nextSolidToken.tokencode == TBaseType.rrw_teradata_validtime)){
15478
15479                    TSourceToken nextToken2 = nextSolidToken.nextSolidToken();
15480                    if (nextToken2 != null) {
15481                        if ((nextToken2.tokencode == TBaseType.rrw_select)
15482                                ||(nextToken2.tokencode == TBaseType.rrw_insert)
15483                                ||(nextToken2.tokencode == TBaseType.rrw_update)
15484                                ||(nextToken2.tokencode == TBaseType.rrw_delete)
15485                                ||(nextToken2.tokencode == TBaseType.rrw_merge)){
15486                            // SEQUENCED VALIDTIME select/insert/update/delete/merge
15487                            ast.tokencode = TBaseType.lexspace;
15488                            nextSolidToken.tokencode = TBaseType.lexspace;
15489                        }
15490                    }
15491                }
15492            }
15493        }
15494
15495
15496        switch(gst){
15497          case sterror:
15498          {
15499              if (ast.tokentype == ETokenType.ttsemicolon)
15500              {
15501                  gcurrentsqlstatement.sourcetokenlist.add(ast);
15502                  doongetrawsqlstatementevent(gcurrentsqlstatement);
15503                  gst = EFindSqlStateType.stnormal;
15504              }
15505              else
15506              {
15507                  gcurrentsqlstatement.sourcetokenlist.add(ast);
15508              }
15509              break;
15510          }
15511          case stMultiLoadCmd: {
15512              gcurrentsqlstatement.addtokentolist(ast);
15513             if ((ast.tokencode == ';')&&(ast.isLastTokenOfLine())) {
15514                 TSourceToken nextToken = ast.nextSolidToken();
15515                 TSourceToken nextToken2 = nextToken != null ? nextToken.nextSolidToken() : null;
15516                 if (nextToken != null && nextToken2 != null && 
15517                     nextToken.tokencode == '.' && 
15518                     nextToken2.toString().equalsIgnoreCase("FIELD") &&
15519                     nextToken.isFirstTokenOfLine()) {
15520                     // Remain in stMultiLoadCmd state
15521                 } else {
15522                     doongetrawsqlstatementevent(gcurrentsqlstatement);
15523                     gst = EFindSqlStateType.stnormal;
15524                 }
15525             }else if (ast.isLastTokenOfLine()){
15526                 //.IF ERRORCODE <> 0 THEN
15527                 //INSERT INTO Sou_EMP_Tab
15528                   //      (1, 'bala');
15529                 String cmdstr = gcurrentsqlstatement.sourcetokenlist.get(0).toString();
15530                 if (gcurrentsqlstatement.sourcetokenlist.size() > 1){
15531                     cmdstr = cmdstr+gcurrentsqlstatement.sourcetokenlist.get(1).toString();
15532                 }
15533                 if ((cmdstr.toLowerCase().startsWith(".if"))||(cmdstr.toLowerCase().startsWith(".set"))||(cmdstr.toLowerCase().startsWith("set"))){
15534                     doongetrawsqlstatementevent(gcurrentsqlstatement);
15535                     gst = EFindSqlStateType.stnormal;
15536                 }
15537             }
15538              //System.out.println("find stMultiLoadCmd");
15539              break;
15540          }
15541          case stFastExportCmd: {
15542              gcurrentsqlstatement.addtokentolist(ast);
15543              if ((ast.tokencode == ';')&&(ast.isLastTokenOfLine())) {
15544                  doongetrawsqlstatementevent(gcurrentsqlstatement);
15545                  gst = EFindSqlStateType.stnormal;
15546              }else{
15547                  boolean findSQL = false;
15548                  TSourceToken nextst = ast.nextToken();
15549                  if (nextst != null){
15550                      if (nextst.tokentype == ETokenType.ttreturn){
15551                          findSQL = (sqlcmds.issql(ast.nextSolidToken(), dbVendor,gst,gcurrentsqlstatement) != null);
15552                          if (findSQL){
15553                              doongetrawsqlstatementevent(gcurrentsqlstatement);
15554                              gst = EFindSqlStateType.stnormal;
15555                          }
15556                      }
15557                  }
15558              }
15559              //System.out.println("find stFastExportCmd");
15560              break;
15561          }
15562          case stFastLoadCmd: {
15563              gcurrentsqlstatement.addtokentolist(ast);
15564              if ((ast.tokencode == ';')&&(ast.isLastTokenOfLine())) {
15565                  doongetrawsqlstatementevent(gcurrentsqlstatement);
15566                  gst = EFindSqlStateType.stnormal;
15567              }else if (ast.tokencode == TBaseType.lexnewline){
15568                  TSourceToken nextst = ast.nextSolidToken();
15569                  if (nextst != null){
15570                      if (nextst.tokencode == TBaseType.BTEQCMD){
15571                          doongetrawsqlstatementevent(gcurrentsqlstatement);
15572                          gst = EFindSqlStateType.stFastLoadCmd;
15573                      }else if (nextst.tokencode == '.'){
15574                          doongetrawsqlstatementevent(gcurrentsqlstatement);
15575                          gst = EFindSqlStateType.stFastLoadCmd;
15576                      }else if (sqlcmds.issql(nextst, dbVendor,gst,gcurrentsqlstatement) != null){
15577                          doongetrawsqlstatementevent(gcurrentsqlstatement);
15578                          gst = EFindSqlStateType.stnormal;
15579                      }
15580                  }
15581              }
15582              //System.out.println("find stFastLoadCmd");
15583              break;
15584          }
15585          case stBTEQCmd:
15586          {
15587              gcurrentsqlstatement.addtokentolist(ast);
15588
15589              if (ast.tokencode == TBaseType.lexnewline){
15590                  if (isContinueBTEQCmd){
15591                      isContinueBTEQCmd = false;
15592                  }else{
15593                     // System.out.println(((TTeradataBTEQCmd)gcurrentsqlstatement).getBteqCmdType());
15594                      if (((TTeradataBTEQCmd)gcurrentsqlstatement).getBteqCmdType() == BteqCmdType.LOGON){
15595                          //TSourceToken nextSolidToken = ast.nextSolidToken()
15596                          boolean findSQL = false;
15597                           findSQL = (sqlcmds.issql(ast.nextSolidToken(), dbVendor,gst,gcurrentsqlstatement) != null);
15598                          if (findSQL){
15599                              doongetrawsqlstatementevent(gcurrentsqlstatement);
15600                              gst = EFindSqlStateType.stnormal;
15601                          }
15602                      }else{
15603                          doongetrawsqlstatementevent(gcurrentsqlstatement);
15604                          gst = EFindSqlStateType.stnormal;
15605                      }
15606                  }
15607              }else if ((ast.tokencode == '-')&&(ast.isLastTokenOfLine())){
15608                  if (!inBTEQComment)
15609                    isContinueBTEQCmd = true;
15610              }else if (ast.tokencode  == TBaseType.lexspace){
15611
15612              }else if (ast.tokencode  == ';'){
15613
15614                  doongetrawsqlstatementevent(gcurrentsqlstatement);
15615                  boolean findNewCmdInSameLine = false;
15616                  if (!ast.isLastTokenOfLine()){
15617                      // check if next cmd like below:
15618                      // .SET SIDETITLES ON; .SET FOLDLINE ON ALL
15619                      TSourceToken nextst  = ast.nextSolidToken();
15620                      if ((nextst != null)&&(nextst.tokencode == '.')){
15621                          TSourceToken nextst2  = nextst.nextSolidToken();
15622                          TSourceToken searchToken = null;
15623                          if (nextst2 != null){
15624
15625                              String searchStr = null;
15626                              if (nextst2.tokencode == TBaseType.rrw_set){
15627                                  TSourceToken nextst3 = nextst2.nextSolidToken();
15628                                  if (nextst3 != null){
15629                                      searchStr = nextst3.astext;
15630                                      searchToken = nextst3;
15631                                  }
15632
15633                              }else{
15634                                  searchStr = nextst2.astext;
15635                                    searchToken = nextst2;
15636                              }
15637
15638                              //EBTEQCmdType ebteqCmdType = TTeradataHelper.searchBTEQTypeByName(searchStr);
15639                              BteqCmdType bteqCmdType = BteqCmdType.searchBteqCmd(searchToken);
15640                              if (bteqCmdType != null){
15641                                  gcurrentsqlstatement = new TTeradataBTEQCmd(dbVendor);
15642                                  ((TTeradataBTEQCmd)gcurrentsqlstatement).setBteqCmdType(bteqCmdType);
15643                                  gcurrentsqlstatement.addtokentolist(ast);
15644                                  findNewCmdInSameLine = true;
15645                              }
15646                          }
15647                      }
15648                  }
15649
15650                  if (findNewCmdInSameLine){
15651                      gst = EFindSqlStateType.stBTEQCmd;
15652                  }else{
15653                      gst = EFindSqlStateType.stnormal;
15654                  }
15655
15656              }else if (ast.tokencode  == '*'){
15657//                  if (inBTEQComment){
15658//                      inBTEQComment = false;
15659//                      doongetrawsqlstatementevent(gcurrentsqlstatement);
15660//                      gst = EFindSqlStateType.stnormal;
15661//                  }
15662                  isContinueBTEQCmd = false;
15663              }else{ //solid token
15664                  isContinueBTEQCmd = false;
15665              }
15666              //System.out.println("find stBTEQCmd");
15667              break;
15668          }
15669          case stnormal :
15670          {
15671              if ((ast.tokencode  == TBaseType.cmtdoublehyphen)
15672                 || (ast.tokencode  == TBaseType.cmtslashstar)
15673                 || (ast.tokencode  == TBaseType.lexspace)
15674                 || (ast.tokencode  == TBaseType.lexnewline)
15675                 || (ast.tokentype  == ETokenType.ttsemicolon))
15676                 {
15677                 if (TBaseType.assigned(gcurrentsqlstatement))
15678                     {
15679                     gcurrentsqlstatement.addtokentolist(ast);
15680                     }
15681
15682                     if ((lcprevsolidtoken != null) && (ast.tokentype == ETokenType.ttsemicolon))
15683                     {
15684                         if (lcprevsolidtoken.tokentype == ETokenType.ttsemicolon )
15685                         {
15686                            // ;;;; continuous semicolon,treat it as comment
15687                             ast.tokentype = ETokenType.ttsimplecomment;
15688                             ast.tokencode =  TBaseType.cmtdoublehyphen;
15689                         }
15690                     }
15691
15692                 continue;
15693                 }
15694
15695
15696              if ((ast.tokencode == '.')&&(ast.isFirstTokenOfLine())){
15697                  TSourceToken nextst  = ast.nextSolidToken();
15698                  TSourceToken cmdToken = null;
15699                  if (nextst != null){
15700
15701                    //   String searchStr = null;
15702                    //   if (nextst.tokencode == TBaseType.rrw_set){
15703                    //       TSourceToken nextst2 = nextst.nextSolidToken();
15704                    //       if (nextst2 != null){
15705                    //           searchStr = nextst2.astext;
15706                    //           cmdToken = nextst2;
15707                    //       }
15708
15709                    //   }else{
15710                    //       searchStr = nextst.astext;
15711                    //       cmdToken = nextst;
15712                    //   }
15713
15714                    //   EBTEQCmdType ebteqCmdType = TTeradataHelper.searchBTEQTypeByName(searchStr);
15715                    //   if (ebteqCmdType != null){
15716                    //       //check is this a bteq command
15717                    //       //if (ebteqCmdType == EBTEQCmdType.EXPORT)
15718                    //       TSourceToken nextst2;
15719                    //       switch (ebteqCmdType){
15720                    //           case EXPORT:
15721                    //               nextst2 = cmdToken.nextSolidToken();
15722                    //               if (nextst2 != null){
15723                    //                   if ((nextst2.astext.equalsIgnoreCase("data"))
15724                    //                       ||(nextst2.astext.equalsIgnoreCase("indicdata"))
15725                    //                           ||(nextst2.astext.equalsIgnoreCase("report"))
15726                    //                           ||(nextst2.astext.equalsIgnoreCase("dif"))
15727                    //                           ||(nextst2.astext.equalsIgnoreCase("reset"))
15728                    //                   ){
15729
15730                    //                   }else{
15731                    //                       ebteqCmdType = null;
15732                    //                   }
15733
15734                    //               }
15735                    //             break;
15736                    //           case IMPORT:
15737                    //               nextst2 = cmdToken.nextSolidToken();
15738                    //               if (nextst2 != null){
15739                    //                   if ((nextst2.astext.equalsIgnoreCase("data"))
15740                    //                           ||(nextst2.astext.equalsIgnoreCase("indicdata"))
15741                    //                           ||(nextst2.astext.equalsIgnoreCase("vartext"))
15742                    //                           ||(nextst2.astext.equalsIgnoreCase("reset"))
15743                    //                           ||(nextst2.astext.equalsIgnoreCase("ddname"))
15744                    //                   ){
15745
15746                    //                   }else{
15747                    //                       ebteqCmdType = null;
15748                    //                   }
15749                    //               }
15750                    //               break;
15751                    //           case SET_SESSION:
15752                    //               nextst2 = cmdToken.nextSolidToken();
15753                    //               if (nextst2 != null){
15754                    //                   if (nextst2.astext.equalsIgnoreCase("charset")) {
15755                    //                       ebteqCmdType = EBTEQCmdType.SESSION_CHARSET;
15756                    //                   }else if (nextst2.astext.equalsIgnoreCase("RESPBUFLEN")){
15757                    //                       ebteqCmdType = EBTEQCmdType.SESSION_RESPBUFLEN;
15758                    //                   }else if (nextst2.astext.equalsIgnoreCase("SQLFLAG")){
15759                    //                       ebteqCmdType = EBTEQCmdType.SESSION_SQLFLAG;
15760                    //                   }else if (nextst2.astext.equalsIgnoreCase("TRANSACTION")){
15761                    //                       ebteqCmdType = EBTEQCmdType.SESSION_TRANSACTION;
15762                    //                   }else if (nextst2.astext.equalsIgnoreCase("TRANS")){
15763                    //                       ebteqCmdType = EBTEQCmdType.SESSION_TRANSACTION;
15764                    //                   }else if (nextst2.astext.equalsIgnoreCase("TWORESPBUFS")){
15765                    //                       ebteqCmdType = EBTEQCmdType.SESSION_TWORESPBUFS;
15766                    //                   }else{
15767                    //                       ebteqCmdType = null;
15768                    //                   }
15769                    //               }
15770                    //               break;
15771                    //           case SHOW:
15772                    //               nextst2 = cmdToken.nextSolidToken();
15773                    //               if (nextst2 != null){
15774                    //                   if (nextst2.astext.equalsIgnoreCase("CONTROLS")) {
15775                    //                       ebteqCmdType = EBTEQCmdType.SHOW_CONTROLS;
15776                    //                   }else if (nextst2.astext.equalsIgnoreCase("CONTROL")){
15777                    //                       ebteqCmdType = EBTEQCmdType.SHOW_CONTROLS;
15778                    //                   }else if (nextst2.astext.equalsIgnoreCase("ERRORMAP")){
15779                    //                       ebteqCmdType = EBTEQCmdType.SHOW_ERRORMAP;
15780                    //                   }else if (nextst2.astext.equalsIgnoreCase("VERSION")){
15781                    //                       ebteqCmdType = EBTEQCmdType.SHOW_VERSIONS;
15782                    //                   }else if (nextst2.astext.equalsIgnoreCase("VERSIONS")){
15783                    //                       ebteqCmdType = EBTEQCmdType.SHOW_VERSIONS;
15784                    //                   }
15785                    //               }
15786                    //               break;
15787                    //       }
15788
15789                    //       if (ebteqCmdType != null){
15790                    //           gcurrentsqlstatement = new TTeradataBTEQCmd(dbVendor);
15791                    //           ((TTeradataBTEQCmd)gcurrentsqlstatement).setBteqCmdType(ebteqCmdType);
15792                    //           gcurrentsqlstatement.addtokentolist(ast);
15793                    //           gst = EFindSqlStateType.stBTEQCmd;
15794                    //           continue;
15795                    //       }
15796                    //   }
15797
15798                      gst = ((TLexerTeradata)getFlexer()).cmdType(nextst);
15799                      boolean foundCmd = false;
15800                      switch (gst){
15801                          case stMultiLoadCmd:
15802                              gcurrentsqlstatement = new TTeradataMultiLoadCmd(dbVendor);
15803                              gst = EFindSqlStateType.stMultiLoadCmd;
15804                              ((TTeradataMultiLoadCmd)gcurrentsqlstatement).setCmdType(TTeradataHelper.searchMultiLoadTypeByName(nextst.astext));
15805                              foundCmd = true;
15806                              break;
15807                          case stFastExportCmd:
15808                              gcurrentsqlstatement = new TTeradataFastExportCmd(dbVendor);
15809                              gst = EFindSqlStateType.stFastExportCmd;
15810                              foundCmd = true;
15811                              break;
15812                          case stFastLoadCmd:
15813                              gcurrentsqlstatement = new TTeradataFastLoadCmd(dbVendor);
15814                              gst = EFindSqlStateType.stFastLoadCmd;
15815                              foundCmd = true;
15816                              break;
15817                          case stBTEQCmd:
15818                              gcurrentsqlstatement = new TTeradataBTEQCmd(dbVendor);
15819                              ((TTeradataBTEQCmd)gcurrentsqlstatement).setBteqCmdType(BteqCmdType.searchBteqCmd(nextst));
15820                              gst = EFindSqlStateType.stBTEQCmd;
15821                              foundCmd = true;
15822                              break;
15823                      }
15824                      if (foundCmd) {
15825                          gcurrentsqlstatement.addtokentolist(ast);
15826                          continue;
15827                      }
15828
15829                  } // next solid token
15830              }
15831              else if ((ast.tokencode == '*')&&(ast.isFirstTokenOfLine())){
15832                  gst = EFindSqlStateType.stBTEQCmd;
15833                  inBTEQComment = true;
15834                  gcurrentsqlstatement = new TTeradataBTEQCmd(dbVendor);
15835                  ((TTeradataBTEQCmd)gcurrentsqlstatement).setBteqCmdType(BteqCmdType.COMMENT);
15836                  //((TTeradataBTEQCmd)gcurrentsqlstatement).setFindSqlStateType(gst);
15837                  gcurrentsqlstatement.addtokentolist(ast);
15838                  continue;
15839              }
15840              else if ((ast.tokencode == '=')&&(ast.isFirstTokenOfLine())){
15841                  TSourceToken st1 = ast.prevSolidToken();
15842                  if (st1 != null){
15843                      if (st1.tokencode == ';'){
15844                          gst = EFindSqlStateType.stBTEQCmd;
15845                          gcurrentsqlstatement = new TTeradataBTEQCmd(dbVendor);
15846                          ((TTeradataBTEQCmd)gcurrentsqlstatement).setFindSqlStateType(gst);
15847                          gcurrentsqlstatement.addtokentolist(ast);
15848                          continue;
15849                      }
15850                  }
15851              }
15852              else if (ast.isFirstTokenOfLine() && (BteqCmdType.searchBteqCmd(ast) != null)){
15853                  TSourceToken st1 = ast.prevSolidToken();
15854                  if (st1 != null){
15855                      if (st1.tokencode == ';'){
15856                          gst = EFindSqlStateType.stBTEQCmd;
15857                          gcurrentsqlstatement = new TTeradataBTEQCmd(dbVendor);
15858                          ((TTeradataBTEQCmd)gcurrentsqlstatement).setFindSqlStateType(gst);
15859                          gcurrentsqlstatement.addtokentolist(ast);
15860                          continue;
15861                      }
15862                  }
15863              }
15864
15865
15866              // find a tokentext to start sql or stored procedure mode
15867              gcurrentsqlstatement = sqlcmds.issql(ast, dbVendor,gst,gcurrentsqlstatement);
15868
15869              if (TBaseType.assigned(gcurrentsqlstatement))
15870              {
15871                  ESqlStatementType[] ses = { sstcreateprocedure
15872                          ,ESqlStatementType.sstteradatacreatefunction,ESqlStatementType.sstcreatetrigger};
15873                  if(includesqlstatementtype(gcurrentsqlstatement.sqlstatementtype, ses) )
15874                       {
15875                        gst = EFindSqlStateType.ststoredprocedure;
15876                        gcurrentsqlstatement.addtokentolist(ast);
15877                        if ((gcurrentsqlstatement.sqlstatementtype == sstcreateprocedure)
15878                        || (gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstteradatacreatefunction)
15879                        || (gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatetrigger)
15880                        )
15881                           {
15882                            curdelimiterchar = ';';
15883                           }
15884                        }
15885                  else
15886                    {
15887                      gst = EFindSqlStateType.stsql;
15888                      gcurrentsqlstatement.addtokentolist(ast);
15889                    }
15890
15891                  lcNestedParens = 0;
15892
15893              }
15894
15895              if ((!TBaseType.assigned(gcurrentsqlstatement) ) && (ast.isFirstTokenOfLine())){
15896                  gst = ((TLexerTeradata)getFlexer()).cmdType(ast);
15897                  if ((gst == EFindSqlStateType.stMultiLoadCmd)||(gst == EFindSqlStateType.stFastLoadCmd)||(gst == EFindSqlStateType.stFastExportCmd)){
15898                      gcurrentsqlstatement = new TTeradataBTEQCmd(dbVendor);
15899                      ((TTeradataBTEQCmd)gcurrentsqlstatement).setFindSqlStateType(gst);
15900                      gcurrentsqlstatement.addtokentolist(ast);
15901                      continue;
15902                  }else gst = EFindSqlStateType.stnormal;
15903              }
15904
15905              if (!TBaseType.assigned(gcurrentsqlstatement) ) //error tokentext found
15906              {
15907
15908//                  errormessage = "error when tokenlize:"+ast.astext+"("+ast.lineNo +","+ast.columnNo +")";
15909//                  errorcount = 1;
15910                  this.syntaxErrors.add( new TSyntaxError(ast.astext,ast.lineNo,(ast.columnNo < 0 ? 0:ast.columnNo)
15911                          ,"Error when tokenlize", EErrorType.spwarning,TBaseType.MSG_WARNING_ERROR_WHEN_TOKENIZE,null,ast.posinlist));
15912
15913                  ast.tokentype = ETokenType.tttokenlizererrortoken;
15914                  gst = EFindSqlStateType.sterror;
15915
15916                  gcurrentsqlstatement = new TUnknownSqlStatement(dbVendor);
15917                  gcurrentsqlstatement.sqlstatementtype = ESqlStatementType.sstinvalid;
15918                  gcurrentsqlstatement.addtokentolist(ast);
15919
15920              }
15921              break;
15922          }
15923          case stsql :
15924          {
15925              boolean readyToEnd = true;
15926              if (gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstteradatacreatemacro){
15927                  if ((ast.tokencode == '(')||(ast.tokencode == TBaseType.left_parenthesis_2)) lcNestedParens++;
15928                  if (ast.tokencode == ')') {
15929                      lcNestedParens--;
15930                      if (lcNestedParens < 0) lcNestedParens = 0;
15931                  }
15932
15933                  readyToEnd = (lcNestedParens == 0);
15934              }
15935
15936              if ((ast.tokentype == ETokenType.ttsemicolon) && (readyToEnd))
15937              {
15938                  gst = EFindSqlStateType.stnormal;
15939                  gcurrentsqlstatement.addtokentolist(ast);
15940                  gcurrentsqlstatement.semicolonended = ast;
15941                  doongetrawsqlstatementevent(gcurrentsqlstatement);
15942                  continue;
15943              }
15944
15945              if (ast.tokencode  == TBaseType.cmtdoublehyphen){
15946                  if (ast.toString().trim().endsWith(TBaseType.sqlflow_stmt_delimiter_str)){ // -- sqlflow-delimiter
15947                      gst = EFindSqlStateType.stnormal;
15948                      doongetrawsqlstatementevent(gcurrentsqlstatement);
15949                      continue;
15950                  }
15951              }
15952
15953              gcurrentsqlstatement.addtokentolist(ast);
15954
15955              break;
15956          }
15957          case ststoredprocedure :
15958          {
15959
15960              boolean readyToEnd = true;
15961              if (ast.tokencode == ';'){
15962                  // don't count case..end, sample ... end after ;
15963                  lcNestedSample = 0;
15964                  lcNestedCase = 0;
15965              }else if (ast.tokencode == TBaseType.rrw_case){ // case ... end
15966                  lcNestedCase++;
15967
15968                  TSourceToken prevst = ast.prevSolidToken();
15969                  if (prevst != null){
15970                    if (prevst.tokencode == TBaseType.rrw_end){
15971                        // don't count:  end case
15972                        lcNestedCase--;
15973                    }
15974                  }
15975
15976              }else if (ast.tokencode == TBaseType.rrw_teradata_sample){ // sample ... end
15977                  lcNestedSample++;
15978              }
15979
15980              if ((gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatetrigger)
15981                  ||(gcurrentsqlstatement.sqlstatementtype == sstcreateprocedure)
15982                      ||(gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatefunction)
15983              )
15984              {
15985                  if ((ast.tokencode == '(')||(ast.tokencode == TBaseType.left_parenthesis_2)) lcNestedParens++;
15986                  if (ast.tokencode == ')') {
15987                      lcNestedParens--;
15988                      if (lcNestedParens < 0) lcNestedParens = 0;
15989                  }
15990
15991                  if (ast.tokencode == TBaseType.rrw_begin) lcNestedBeginEnd++;
15992                  if (ast.tokencode == TBaseType.rrw_end) {
15993
15994
15995                      boolean countThisEnd = true;
15996                      if (lcNestedSample>0){
15997                          // don't count sample...end
15998                          lcNestedSample--;
15999                          countThisEnd = false;
16000                      }else if (lcNestedCase>0){
16001                          // don't count case...end
16002                          lcNestedCase--;
16003                          countThisEnd = false;
16004                      }
16005
16006                      if (countThisEnd){
16007                          // don't count end while/if/case/loop/for/repeat
16008                          TSourceToken nt = ast.nextSolidToken();
16009                          if (nt != null){
16010                              countThisEnd = ((nt.tokencode != TBaseType.rrw_while)
16011                                      &&(nt.tokencode != TBaseType.rrw_if)&&(nt.tokencode != TBaseType.rrw_case)
16012                                      &&(nt.tokencode != TBaseType.rrw_loop)&&(nt.tokencode != TBaseType.rrw_for)
16013                                      &&(nt.tokencode != TBaseType.rrw_repeat)
16014                              );
16015                          }
16016                      }
16017
16018                      if (countThisEnd){
16019                          lcNestedBeginEnd--;
16020                          if (lcNestedBeginEnd < 0 ) lcNestedBeginEnd = 0;
16021                      }
16022                  }
16023
16024                  readyToEnd = ((lcNestedParens == 0)&&(lcNestedBeginEnd == 0));
16025              }
16026              // single stmt in function/procedure/trigger may use ; as terminate char
16027              // so default terminate char is ;, if begin is found ,then
16028              //set terminate char to DelimiterChar
16029                if (curdelimiterchar !=  delimiterchar){
16030                  if (ast.tokencode == TBaseType.rrw_begin )
16031                    {curdelimiterchar = delimiterchar;}
16032                  else if (ast.tokencode == TBaseType.mslabel ){
16033                      if (ast.container.nextsolidtoken(ast,1,false).tokencode == TBaseType.rrw_begin ){
16034//                          if (ast.container.solidtokenafterpos(ast.posinlist,TBaseType.rrw_begin,1,"") == 1) {
16035                          curdelimiterchar = delimiterchar;
16036                      }
16037                  }
16038                }
16039
16040                    if (curdelimiterchar == ';')
16041                    {
16042                        gcurrentsqlstatement.addtokentolist(ast);
16043                        if ((ast.tokentype == ETokenType.ttsemicolon)&(gcurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatetrigger)&(readyToEnd))
16044                        {
16045                            gst = EFindSqlStateType.stnormal;
16046                            //asqlstatement.SemiColonEnded := ast;
16047                             gcurrentsqlstatement._semicolon = ast;
16048                            doongetrawsqlstatementevent(gcurrentsqlstatement);
16049                            continue;
16050                        }
16051                    }else
16052                    {
16053                          if (ast.astext.length() == 1 )
16054                          { ch = ast.astext.charAt(0);}
16055                          else if (ast.astext.length() > 1)
16056                           { ch = ast.astext.charAt(ast.astext.length()-1); }
16057                          else
16058                          { ch = ' ';}
16059
16060
16061                          if (((ast.tokencode != TBaseType.cmtslashstar)&&(ast.tokencode != TBaseType.cmtdoublehyphen))
16062                                  && ((ch == curdelimiterchar )&&(ast.isFirstTokenOfLine())&&(readyToEnd)))
16063                          {
16064                              if (ast.astext.length() > 1)
16065                              {
16066                                  lcstr = ast.astext.substring(0,ast.astext.length()-1);
16067                                  if ((c=flexer.getkeywordvalue(lcstr))>0 )
16068                                    ast.tokencode = c;
16069                              }
16070                              else
16071                              {
16072                                 // ast.TokenStatus := tsIgnoreByyacc;
16073                                 // ast.Tokentype :=   ttDoublehyphenComment; //make this tokentext available like a comment
16074                                  gcurrentsqlstatement._semicolon = ast;
16075                              }
16076                              gcurrentsqlstatement.addtokentolist(ast);
16077                              gst = EFindSqlStateType.stnormal;
16078                              doongetrawsqlstatementevent(gcurrentsqlstatement);
16079                          }else if ((ast.searchToken(TBaseType.rrw_create,1) != null)&&(ast.searchToken(TBaseType.rrw_procedure,4) != null)&&(readyToEnd))
16080                          {
16081                              // gcurrentsqlstatement.addtokentolist(ast);
16082                              gst = EFindSqlStateType.stnormal;
16083                              doongetrawsqlstatementevent(gcurrentsqlstatement);
16084
16085                          }else if (ast.tokencode == ';'){
16086                              gcurrentsqlstatement.addtokentolist(ast);
16087
16088                              boolean startNewStatement = false;
16089                              if (readyToEnd){
16090                                  startNewStatement  = (sqlcmds.issql(ast.nextSolidToken(), dbVendor,gst,gcurrentsqlstatement) != null);
16091                              }
16092                              if (startNewStatement){
16093                                  gst = EFindSqlStateType.stnormal;
16094                                  doongetrawsqlstatementevent(gcurrentsqlstatement);
16095                              }
16096                          }
16097                          else{
16098                              gcurrentsqlstatement.addtokentolist(ast);
16099                          }
16100                    } // end of DelimiterChar
16101
16102                if (( gst == EFindSqlStateType.ststoredprocedure ) && (ast.tokencode  == TBaseType.cmtdoublehyphen)){
16103                  if (ast.toString().trim().endsWith(TBaseType.sqlflow_stmt_delimiter_str)){ // -- sqlflow-delimiter
16104                      gst = EFindSqlStateType.stnormal;
16105                      doongetrawsqlstatementevent(gcurrentsqlstatement);
16106                  }
16107                }
16108
16109              break;
16110          } //teradata sp
16111
16112        } //case
16113    } //for
16114
16115
16116    //last statement
16117    if (TBaseType.assigned(gcurrentsqlstatement) && ( (gst == EFindSqlStateType.stsql) ||(gst == EFindSqlStateType.stBTEQCmd) || (gst == EFindSqlStateType.ststoredprocedure) || (gst == EFindSqlStateType.sterror)) )
16118    {
16119        doongetrawsqlstatementevent(gcurrentsqlstatement);
16120    }
16121
16122    return errorcount;//FSqlStatements.Count;
16123
16124}
16125
16126int dogetrawsqlstatements(){
16127
16128    sqlstatements.clear();
16129    if (sourcetokenlist.size() == 0) return -1;
16130
16131    switch(dbVendor){
16132        case dbvmssql:
16133        case dbvazuresql: {
16134            return domssqlgetrawsqlstatements();
16135        }
16136        case dbvsybase:{
16137            return dosybasegetrawsqlstatements();
16138        }
16139        case dbvinformix:{
16140            return doinformixgetrawsqlstatements();
16141        }
16142        case dbvoracle:{
16143            return dooraclegetrawsqlstatements();
16144        }
16145        case dbvdb2:{
16146            return dodb2getrawsqlstatements();
16147        }
16148        case dbvmysql:{
16149            return domysqlgetrawsqlstatements();
16150        }
16151        case dbvteradata:{
16152            return doteradatagetrawsqlstatements();
16153        }
16154        case dbvpostgresql:{
16155            return dopostgresqlgetrawsqlstatements();
16156        }
16157        case dbvredshift:{
16158            return doredshiftgetrawsqlstatements();
16159        }
16160        case dbvgreenplum:{
16161            return dogreenplumgetrawsqlstatements();
16162        }
16163        case dbvmdx:{
16164            return domdxgetrawsqlstatements();
16165        }
16166        case dbvnetezza:{
16167            return donetezzagetrawsqlstatements();
16168        }
16169        case dbvhive:{
16170            return dohivegetrawsqlstatements();
16171        }
16172        case dbvimpala:{
16173            return doimpalagetrawsqlstatements();
16174        }
16175        case dbvhana:{
16176            return dohanagetrawsqlstatements();
16177        }
16178        case dbvdax:{
16179            return dodaxgetrawsqlstatements();
16180        }
16181        case dbvodbc:{
16182            return doodbcgetrawsqlstatements();
16183        }
16184        case dbvvertica:{
16185            return doverticagetrawsqlstatements();
16186        }
16187        case dbvopenedge:{
16188            return domssqlgetrawsqlstatements();
16189        }
16190        case dbvcouchbase:{
16191            return docouchbasegetrawsqlstatements();
16192        }
16193        case dbvsnowflake:{
16194            int i = dosnowflakegetrawsqlstatements();
16195            // expland $$ string into token list
16196            expandDollarString();
16197            return i;
16198        }
16199        case dbvbigquery:{
16200            return dobigquerygetrawsqlstatements();
16201        }
16202        case dbvsoql:{
16203            return dosoqlgetrawsqlstatements();
16204        }
16205        case dbvsparksql:{
16206            return dosparksqlgetrawsqlstatements();
16207        }
16208        case dbvpresto:{
16209            return doprestogetrawsqlstatements();
16210        }
16211        case dbvathena:{
16212            return doprestogetrawsqlstatements();
16213        }
16214        case dbvdatabricks:{
16215            return dodatabricksgetrawsqlstatements();
16216        }
16217        case dbvgaussdb:{
16218            return dogaussdbgetrawsqlstatements();
16219        }
16220        case dbvansi:{
16221            return doansigetrawsqlstatements();
16222        }
16223        default:{
16224            return domssqlgetrawsqlstatements();
16225        }
16226    }
16227
16228}
16229
16230    /**
16231     *  separates the SQL statements in the input SQL script without doing syntax check.
16232     *  <p></p>
16233     *  Use the {@link #getSqlstatements()} method to get the list of SQL statements.
16234     *  The SQL statement object is the instance of the sub-class of {@link TCustomSqlStatement}, get SQL statement type
16235     *  via the {@link TCustomSqlStatement#sqlstatementtype} field, get string representation of
16236     *  each SQL statement via the {@link TCustomSqlStatement#toString} method.
16237     *  <p></p>
16238     *  All source tokens in this SQL statement
16239     *  is available by using {@link TCustomSqlStatement#sourcetokenlist} filed.
16240     *  Since no parse tree is built by calling this method, no further detailed information about the SQL statement is available.
16241     *
16242      * @return 0 if get SQL statements successfully
16243     */
16244public int getrawsqlstatements(){
16245    
16246    int ret = readsql();
16247    if (ret != 0) return ret;
16248    dosqltexttotokenlist();
16249
16250    return dogetrawsqlstatements();
16251}
16252
16253    /**
16254     *  turns the input SQL into a sequence of token which is the
16255     *  basic lexis element of SQL syntax. Token is categorized as keyword, identifier,
16256     *  number, operator, whitespace and other types. All source tokens can be fetched
16257     *  via the {@link #getSourcetokenlist()} method.
16258     *
16259     */
16260public void tokenizeSqltext(){
16261    readsql();
16262    dosqltexttotokenlist();
16263}
16264
16265
16266
16267void findAllSyntaxErrorsInPlsql(TCustomSqlStatement psql){
16268    if (psql.getErrorCount() > 0){
16269        copyerrormsg(psql);
16270    }
16271
16272    for (int k=0;k<psql.getStatements().size();k++){
16273        findAllSyntaxErrorsInPlsql(psql.getStatements().get(k));
16274    }
16275
16276}
16277
16278private TSQLEnv sqlEnv = null;
16279
16280    /**
16281     * SQL environment includes the database metadata such as procedure, function, trigger, table and etc.
16282     *
16283     * In order to link column to table correctly without connecting to database,
16284     * we need to provide a class which implements {@link TSQLEnv} to TGSqlParser.
16285     * this class tells TGSqlParser the relationship between column and table.
16286     *
16287     * <p>Take this SQL for example:
16288     * <pre>
16289     * SELECT Quantity,b.Time,c.Description
16290     * FROM
16291     * (SELECT ID2,Time FROM bTab) b
16292     * INNER JOIN aTab a on a.ID=b.ID
16293     * INNER JOIN cTab c on a.ID=c.ID
16294     * </pre>
16295     *
16296     * <p>General SQL Parser can build relationship between column: ID2 and table: bTable
16297     * correctly without metadata information from database because there is only one table
16298     * in from clause. But it can't judge column: Quantity belong to table: aTab or cTab,
16299     * since no table alias was prefixed to column: Quantity. If no metadata provided,
16300     * General SQL Parser will link column: Quantity to the first valid table (here it is aTab)
16301     *
16302     * <p>If we create a class  TRealDatabaseSQLEnv implements {@link TSQLEnv},then
16303     *  {@link #setSqlEnv(TSQLEnv)}, General SQL Parser can take this advantage to create
16304     *  a correct relationship between column and tables.
16305     *
16306     *<pre>
16307     * class TSQLServerEnv extends TSQLEnv{
16308     *
16309     *  public TSQLServerEnv(){
16310     *          super(EDbVendor.dbvmssql);
16311     *          initSQLEnv();
16312     *        }
16313     *
16314     *    &#64;Override
16315     *    public void initSQLEnv() {
16316     *
16317     *          // add a new database: master
16318     *          TSQLCatalog sqlCatalog = createSQLCatalog("master");
16319     *          // add a new schema: dbo
16320     *          TSQLSchema sqlSchema = sqlCatalog.createSchema("dbo");
16321     *          //add a new table: aTab
16322     *          TSQLTable aTab = sqlSchema.createTable("aTab");
16323     *          aTab.addColumn("Quantity1");
16324     *
16325     *          //add a new table: bTab
16326     *          TSQLTable bTab = sqlSchema.createTable("bTab");
16327     *          bTab.addColumn("Quantity2");
16328     *
16329     *          //add a new table: cTab
16330     *          TSQLTable cTab = sqlSchema.createTable("cTab");
16331     *          cTab.addColumn("Quantity");
16332     *
16333     *    }
16334     * }
16335     * </pre>
16336     *
16337     * @return SQL environment
16338     */
16339    public TSQLEnv getSqlEnv() {
16340        return sqlEnv;
16341    }
16342
16343    private boolean onlyNeedRawParseTree = false;
16344
16345    public void setOnlyNeedRawParseTree(boolean onlyNeedRawParseTree) {
16346        this.onlyNeedRawParseTree = onlyNeedRawParseTree;
16347    }
16348
16349    public void setSqlEnv(TSQLEnv sqlEnv) {
16350        this.sqlEnv = sqlEnv;
16351    }
16352
16353
16354     // Time tracking variables
16355     private boolean enableTimeLogging = false;
16356     private long rawSqlStatementsTime = 0;
16357     private long parsingTime = 0;
16358     private long semanticAnalysisTime = 0;
16359     private long interpreterTime = 0;
16360     
16361     /**
16362      * Enable or disable time logging for parser steps
16363      * @param enable true to enable time logging, false to disable
16364      */
16365     public void setEnableTimeLogging(boolean enable) {
16366         this.enableTimeLogging = enable;
16367     }
16368     
16369     /**
16370      * Check if time logging is enabled
16371      * @return true if time logging is enabled, false otherwise
16372      */
16373     public boolean isTimeLoggingEnabled() {
16374         return this.enableTimeLogging;
16375     }
16376     
16377     /**
16378      * Reset all accumulated time counters to zero
16379      */
16380     public void resetTimeCounters() {
16381         rawSqlStatementsTime = 0;
16382         parsingTime = 0;
16383         semanticAnalysisTime = 0;
16384         interpreterTime = 0;
16385     }
16386     
16387     /**
16388      * Get accumulated time spent getting raw SQL statements in milliseconds
16389      * @return time in milliseconds
16390      */
16391     public long getRawSqlStatementsTime() {
16392         return rawSqlStatementsTime;
16393     }
16394     
16395     /**
16396      * Get accumulated time spent parsing in milliseconds
16397      * @return time in milliseconds
16398      */
16399     public long getParsingTime() {
16400         return parsingTime;
16401     }
16402     
16403     /**
16404      * Get accumulated time spent on semantic analysis in milliseconds
16405      * @return time in milliseconds
16406      */
16407     public long getSemanticAnalysisTime() {
16408         return semanticAnalysisTime;
16409     }
16410     
16411     /**
16412      * Get accumulated time spent in interpreter in milliseconds
16413      * @return time in milliseconds
16414      */
16415     public long getInterpreterTime() {
16416         return interpreterTime;
16417     }
16418     
16419     /**
16420      * Get total accumulated time spent in all steps
16421      * @return total time in milliseconds
16422      */
16423     public long getTotalTime() {
16424         return rawSqlStatementsTime + parsingTime + semanticAnalysisTime + interpreterTime;
16425     }
16426     
16427     /**
16428      * Returns time statistics as a formatted string
16429      * @return formatted string with time statistics
16430      */
16431     public String getTimeStatistics() {
16432         if (!enableTimeLogging) {
16433             return "Time logging is disabled";
16434         }
16435         
16436         StringBuilder sb = new StringBuilder();
16437         sb.append(String.format("Time statistics for TGSqlParser, dbvendor: %s:\n",this.dbVendor));
16438         sb.append(String.format("1. Raw SQL statements: %d ms (%.2f%%)\n", 
16439                 rawSqlStatementsTime,
16440                 getTotalTime() > 0 ? 100.0 * rawSqlStatementsTime / getTotalTime() : 0));
16441         sb.append(String.format("2. Parsing: %d ms (%.2f%%)\n", 
16442                 parsingTime,
16443                 getTotalTime() > 0 ? 100.0 * parsingTime / getTotalTime() : 0));
16444         sb.append(String.format("3. Semantic analysis: %d ms (%.2f%%)\n", 
16445                 semanticAnalysisTime,
16446                 getTotalTime() > 0 ? 100.0 * semanticAnalysisTime / getTotalTime() : 0));
16447         sb.append(String.format("4. Interpreter: %d ms (%.2f%%)\n", 
16448                 interpreterTime,
16449                 getTotalTime() > 0 ? 100.0 * interpreterTime / getTotalTime() : 0));
16450         sb.append(String.format("Total: %d ms", getTotalTime()));
16451         return sb.toString();
16452     }
16453     
16454     int doparse() {
16455         int j;
16456         long startTime, endTime;
16457 
16458         // 1. start get raw sql statements
16459         startTime = enableTimeLogging ? System.currentTimeMillis() : 0;
16460         
16461         int ret = getrawsqlstatements();
16462         
16463         if (enableTimeLogging) {
16464             endTime = System.currentTimeMillis();
16465             rawSqlStatementsTime += (endTime - startTime);
16466         }
16467 
16468         boolean isPushGloablStack = false;
16469         //if (ret != 0) return ret;
16470         TFrame firstFrame = null;
16471 
16472         globalContext = new TContext();
16473 
16474         if (this.sqlEnv == null) {
16475             this.sqlEnv = new TSQLEnv(this.dbVendor) {
16476                 @Override
16477                 public void initSQLEnv() {
16478                 }
16479             };
16480             // this.sqlEnv.setEnableGetMetadataFromDDL(false);
16481         }
16482         globalContext.setSqlEnv(this.sqlEnv, this.sqlstatements);
16483 
16484         //TStackFrame stackFrame = new TStackFrame(new TGlobalScope());
16485         if (getFrameStack().size() == 0) { // stack passed from outside gsqlparser will contain frames
16486             //getFrameStack().push(new TStackFrame(new TGlobalScope()));
16487             TGlobalScope globalScope = new TGlobalScope();
16488 
16489             globalScope.setSqlEnv(this.sqlEnv);
16490             firstFrame = new TFrame(globalScope);
16491             firstFrame.pushMeToStack(getFrameStack());
16492             isPushGloablStack = true;
16493         }
16494 
16495         // 2. start parsing
16496         startTime = enableTimeLogging ? System.currentTimeMillis() : 0;
16497         
16498         for (int i = 0; i < sqlstatements.size(); i++) {
16499             sqlstatements.getRawSql(i).setFrameStack(frameStack);
16500             j = sqlstatements.getRawSql(i).parsestatement(null, false, onlyNeedRawParseTree);
16501 
16502             TCustomSqlStatement sql0 = null;
16503             if (sqlstatements.get(i).isoracleplsql()) {
16504                 // check syntax error in select/insert statement inside plsql
16505                 sql0 = sqlstatements.get(i);
16506                 findAllSyntaxErrorsInPlsql(sql0);
16507             }
16508 
16509             boolean doRecover = TBaseType.ENABLE_ERROR_RECOVER_IN_CREATE_TABLE;
16510 
16511             if (doRecover && ((j != 0) || (sqlstatements.get(i).getErrorCount() > 0))) {
16512                 if (((sqlstatements.get(i).sqlstatementtype == ESqlStatementType.sstcreatetable)
16513                         || ((sqlstatements.get(i).sqlstatementtype == ESqlStatementType.sstcreateindex) && (dbVendor != EDbVendor.dbvcouchbase))
16514                         ) && (!TBaseType.c_createTableStrictParsing)
16515                 ) {
16516                     // only parse main body of create table,
16517                     TCustomSqlStatement errorSqlStatement = (TCustomSqlStatement) sqlstatements.get(i);
16518 
16519                     int nested = 0;
16520                     boolean isIgnore = false, isFoundIgnoreToken = false;
16521                     TSourceToken firstIgnoreToken = null;
16522                     for (int k = 0; k < errorSqlStatement.sourcetokenlist.size(); k++) {
16523                         TSourceToken st = errorSqlStatement.sourcetokenlist.get(k);
16524                         if (isIgnore) {
16525                             if (st.issolidtoken() && (st.tokencode != ';')) {
16526                                 isFoundIgnoreToken = true;
16527                                 if (firstIgnoreToken == null) {
16528                                     firstIgnoreToken = st;
16529                                 }
16530                             }
16531                             if (st.tokencode != ';') {
16532                                 st.tokencode = TBaseType.sqlpluscmd;
16533                             }
16534                             continue;
16535                         }
16536                         if (st.tokencode == (int) ')') {
16537                             nested--;
16538                             if (nested == 0) {
16539                                 //let's check is next token is
16540                                 // as ( select
16541                                 boolean isSelect = false;
16542                                 TSourceToken st1 = st.searchToken(TBaseType.rrw_as, 1);
16543                                 if (st1 != null) {
16544                                     TSourceToken st2 = st.searchToken((int) '(', 2);
16545                                     if (st2 != null) {
16546                                         TSourceToken st3 = st.searchToken(TBaseType.rrw_select, 3);
16547                                         isSelect = (st3 != null);
16548                                     }
16549                                 }
16550                                 if (!isSelect) isIgnore = true;
16551                             }
16552                         }
16553                         if ((st.tokencode == (int) '(') || (st.tokencode == TBaseType.left_parenthesis_2)) {
16554                             nested++;
16555                         }
16556                     }
16557 
16558                     if ((dbVendor == EDbVendor.dbvoracle) && ((firstIgnoreToken != null) && (!TBaseType.searchOracleTablePros(firstIgnoreToken.toString())))) {
16559                         // if it is not the valid Oracle table properties option, let raise the error.
16560                         isFoundIgnoreToken = false;
16561                     }
16562                     if (isFoundIgnoreToken) {
16563                         errorSqlStatement.clearError();
16564                         j = sqlstatements.get(i).parsestatement(null, false);
16565                     }
16566                 }
16567 
16568                 if (((sqlstatements.get(i).sqlstatementtype == ESqlStatementType.sstcreatetrigger)
16569                         || (sqlstatements.get(i).sqlstatementtype == ESqlStatementType.sstcreatefunction)
16570                         || (sqlstatements.get(i).sqlstatementtype == sstcreateprocedure)
16571                         ) && (dbVendor == EDbVendor.dbvdb2)) { 
16572                     // db2 can handle Oracle pl/sql code, so we give it a try here
16573                     TCustomSqlStatement stmt = sqlstatements.get(i);
16574                     StringBuffer stmtStr = new StringBuffer(1024);
16575                     for (int k = 0; k < stmt.sourcetokenlist.size(); k++) {
16576                         stmtStr.append(stmt.sourcetokenlist.get(k).astext);
16577                     }
16578 
16579                     TGSqlParser lc_sqlparser = new TGSqlParser(EDbVendor.dbvoracle);
16580                     lc_sqlparser.sqltext = stmtStr.toString();
16581                     int iRet = lc_sqlparser.parse();
16582                     if (iRet == 0) {
16583                         sqlstatements.remove(i);
16584                         sqlstatements.add(i, lc_sqlparser.sqlstatements.get(0));
16585                         continue;
16586                     }
16587                 }
16588             }
16589 
16590             if ((j != 0) || (sqlstatements.get(i).getErrorCount() > 0)) {
16591                 copyerrormsg(sqlstatements.get(i));
16592 
16593                 if ((isEnablePartialParsing()) && (dbVendor == EDbVendor.dbvsybase) && (sqlstatements.get(i).sqlstatementtype == ESqlStatementType.sstmssqlcreateprocedure)) {
16594                     TMssqlCreateProcedure createProcedure = (TMssqlCreateProcedure) sqlstatements.get(i);
16595 
16596                     StringBuffer storedProcedure = new StringBuffer(1024);
16597                     boolean ASKeyword = false;
16598                     for (int k = 0; k < createProcedure.sourcetokenlist.size(); k++) {
16599                         if ((!ASKeyword) && (createProcedure.sourcetokenlist.get(k).tokencode == TBaseType.rrw_as)) {
16600                             ASKeyword = true;
16601                             continue;
16602                         }
16603                         if (ASKeyword) {
16604                             storedProcedure.append(createProcedure.sourcetokenlist.get(k).astext);
16605                         }
16606                     }
16607 
16608                     TGSqlParser lc_sqlparser = new TGSqlParser(dbVendor);
16609                     lc_sqlparser.sqltext = storedProcedure.toString();
16610                     lc_sqlparser.parse();
16611                     for (int k = 0; k < lc_sqlparser.sqlstatements.size(); k++) {
16612                         createProcedure.getBodyStatements().add(lc_sqlparser.sqlstatements.get(k));
16613                     }
16614                 }
16615             }
16616 
16617             // fire SQL Statement handle event if set, if return true, stop parsing
16618             if (sqlStatementHandle != null) {
16619                 if (sqlStatementHandle.processSQLStatement(sqlstatements.get(i), this)) break;
16620             }
16621         }
16622         
16623         if (enableTimeLogging) {
16624             endTime = System.currentTimeMillis();
16625             parsingTime += (endTime - startTime);
16626         }
16627 
16628         if (isPushGloablStack) {
16629             firstFrame.popMeFromStack(getFrameStack());
16630         }
16631 
16632         // 3. start semantic analysis
16633         startTime = enableTimeLogging ? System.currentTimeMillis() : 0;
16634         
16635         if ((TBaseType.ENABLE_RESOLVER) && (getErrorCount() == 0)) {
16636             TSQLResolver resolver = new TSQLResolver(globalContext, sqlstatements);
16637             if (!resolver.resolve()) {
16638                 // Handle resolution errors
16639                 // addErrors(resolver.getLog().getErrors());
16640             }
16641         }
16642         
16643         if (enableTimeLogging) {
16644             endTime = System.currentTimeMillis();
16645             semanticAnalysisTime += (endTime - startTime);
16646         }
16647 
16648         // 4. start interpreter
16649         startTime = enableTimeLogging ? System.currentTimeMillis() : 0;
16650         
16651         if ((TBaseType.ENABLE_INTERPRETER) && (getErrorCount() == 0)) {
16652             TLog.clearLogs();
16653             TGlobalScope globalScope = new TGlobalScope(sqlEnv);
16654             TLog.enableInterpreterLogOnly();
16655 
16656             TASTEvaluator astEvaluator = new TASTEvaluator(this.sqlstatements, globalScope);
16657             astEvaluator.eval();
16658         }
16659         
16660         if (enableTimeLogging) {
16661             endTime = System.currentTimeMillis();
16662             interpreterTime += (endTime - startTime);
16663         }
16664 
16665         return getErrorCount();
16666     }
16667
16668     
16669void copyerrormsg(TCustomSqlStatement sql){
16670    for (int i = 0; i<sql.getSyntaxErrors().size(); i++){
16671            this.syntaxErrors.add(new TSyntaxError( (TSyntaxError)sql.getSyntaxErrors().get(i) ));
16672    }
16673//    for (int i = 0; i<sql.getSyntaxHints().size(); i++){
16674//            this.syntaxHints.add(new TSyntaxError( (TSyntaxError)sql.getSyntaxHints().get(i) ));
16675//    }
16676}
16677
16678private static String calculateLicenseKey(boolean ignoreMachineId){
16679
16680    if (userName == null) return null;
16681    if (machineId == null) return null;
16682
16683    byte[] bytesOfMessage=null;
16684    String licenseStr = "I love sql pretty printer, yeah!"+userName.toLowerCase();
16685    if (!ignoreMachineId){
16686        licenseStr += machineId.toLowerCase();
16687    }
16688    try {
16689        bytesOfMessage = licenseStr.getBytes("UTF-8");
16690    } catch (UnsupportedEncodingException e) {
16691        e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
16692    }
16693
16694    MessageDigest md = null;
16695    try {
16696        md = MessageDigest.getInstance("MD5");
16697    } catch (NoSuchAlgorithmException e) {
16698        e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
16699    }
16700    byte[] digest = md.digest(bytesOfMessage);
16701
16702    return null;//HardwareBinder.getHex(digest);
16703}
16704
16705private static boolean validateLicense(){
16706
16707    int ret = 0;
16708//    String line;
16709//
16710//    try{
16711//        BufferedReader br = new BufferedReader(new InputStreamReader(TLexerTeradata.class.getResourceAsStream(TBaseType.license_file_name)));
16712//        line = br.readLine().trim();
16713//        String[] ss = line.split("[|]");
16714//        if (ss.length != 3){
16715//            licenseMessage = TBaseType.license_file_invalid;
16716//            ret = -2;
16717//        }else {
16718//            licenseType = ss[0].trim();
16719//            userName = ss[1].trim();
16720//            licenseKey = ss[2].trim();
16721//        }
16722//    }catch (NullPointerException n){
16723//        licenseMessage = TBaseType.license_file_missing;
16724//        ret = -1;
16725//    }catch(IOException e){
16726//        licenseMessage = TBaseType.license_file_missing;
16727//        ret = -1;
16728//    }
16729//
16730//    machineId = new HardwareBinder().getMachineIdString();
16731//
16732//    if (ret == 0 ){
16733//        boolean ignoreMachineId = licenseType.equalsIgnoreCase(TBaseType.license_type_dist);
16734//        if (!calculateLicenseKey(ignoreMachineId).equalsIgnoreCase(licenseKey)){
16735//            licenseMessage = TBaseType.license_illegal_key;
16736//            ret = -3;
16737//        }
16738//    }else {
16739//        licenseMessage += ", please contact "+TBaseType.vendorEmail +" to get a license file by providing this number[UUID]"+TBaseType.newline+machineId;
16740//    }
16741
16742    return ret == 0;
16743
16744}
16745
16746private static boolean check_license_time(){
16747
16748    boolean  ret = false;
16749
16750    String toDate = TBaseType.license_expired_date;
16751
16752    DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT);
16753    Calendar currDtCal = Calendar.getInstance();
16754
16755    // Zero out the hour, minute, second, and millisecond
16756    currDtCal.set(Calendar.HOUR_OF_DAY, 0);
16757    currDtCal.set(Calendar.MINUTE, 0);
16758    currDtCal.set(Calendar.SECOND, 0);
16759    currDtCal.set(Calendar.MILLISECOND, 0);
16760
16761    Date currDt = currDtCal.getTime();
16762
16763    Date toDt;
16764    try {
16765        toDt = df.parse(toDate);
16766    } catch (ParseException e) {
16767        toDt = null;
16768        // Print some error message back to the user
16769    }
16770
16771    if (toDt != null){
16772        int results = toDt.compareTo(currDt);
16773        ret = results > 0;
16774    }
16775
16776    return ret;
16777}
16778
16779    public void setTeradataUtilityType(TeradataUtilityType teradataUtilityType) {
16780        if ((this.getFlexer() != null) && (this.getFlexer() instanceof TLexerTeradata)){
16781            ((TLexerTeradata)this.getFlexer()).setTeradataUtilityType(teradataUtilityType);
16782        }
16783    }
16784
16785}