001package gudusoft.gsqlparser;
002
003
004import gudusoft.gsqlparser.nodes.TExpression;
005import gudusoft.gsqlparser.nodes.TParseTreeNode;
006
007
008import java.io.*;
009import java.math.BigInteger;
010import java.nio.charset.Charset;
011import java.nio.file.Files;
012import java.nio.file.Path;
013import java.nio.file.Paths;
014import java.nio.file.StandardOpenOption;
015import java.sql.Timestamp;
016import java.util.*;
017import java.util.concurrent.atomic.AtomicLong;
018import java.util.stream.Stream;
019import java.nio.charset.StandardCharsets; // Added import
020import java.nio.ByteBuffer;
021import java.nio.channels.FileChannel;
022
023/**
024 * Constants and functions used by parser internally.
025 */
026
027public class TBaseType {    
028
029    public static String  versionid = "4.2.19";
030    public static String  releaseDate = "2026-10-23";
031    public static final boolean full_edition = true;
032    static final boolean enterprise_edition = true;
033    private static final String  licenseType = "developer license";
034    public static String  version = "General SQL Parser Java Version "+versionid;
035
036   // public static final  boolean HIVE_TEST = true;
037
038    public static final String vendorEmail = "info@sqlparser.com";
039
040    public static double db_version_num = 11.0;
041
042   // public static TeradataUtilityType teradataUtilityType = TeradataUtilityType.BTEQ;
043
044    public static boolean DEBUG = false;
045    public static boolean DEBUG_PARSE_TABLE = false;
046
047    public static boolean ENABLE_ERROR_RECOVER_IN_CREATE_TABLE = true;
048
049    public static boolean ENABLE_INTERPRETER = false;
050
051    // Thread-local variable to ensure thread-safe resolver state
052    private static final ThreadLocal<Boolean> ENABLE_RESOLVER_THREADLOCAL = ThreadLocal.withInitial(() -> false);
053
054    // Getter method for ENABLE_RESOLVER
055    public static boolean isEnableResolver() {
056        return ENABLE_RESOLVER_THREADLOCAL.get();
057    }
058
059    // Setter method for ENABLE_RESOLVER
060    public static void setEnableResolver(boolean value) {
061        if (value && isEnableResolver2()) {
062            throw new IllegalStateException("Cannot enable both ENABLE_RESOLVER and ENABLE_RESOLVER2 at the same time. " +
063                "Please disable ENABLE_RESOLVER2 first by calling setEnableResolver2(false).");
064        }
065        ENABLE_RESOLVER_THREADLOCAL.set(value);
066    }
067
068    // Thread-local variable to ensure thread-safe resolver2 state
069    private static final ThreadLocal<Boolean> ENABLE_RESOLVER2_THREADLOCAL = ThreadLocal.withInitial(() -> true);
070
071    // Getter method for ENABLE_RESOLVER2
072    public static boolean isEnableResolver2() {
073        return ENABLE_RESOLVER2_THREADLOCAL.get();
074    }
075
076    // Setter method for ENABLE_RESOLVER2
077    public static void setEnableResolver2(boolean value) {
078        if (value && isEnableResolver()) {
079            throw new IllegalStateException("Cannot enable both ENABLE_RESOLVER and ENABLE_RESOLVER2 at the same time. " +
080                "Please disable ENABLE_RESOLVER first by calling setEnableResolver(false).");
081        }
082        ENABLE_RESOLVER2_THREADLOCAL.set(value);
083    }
084
085    public static boolean DUMP_RESOLVER_LOG_TO_CONSOLE = false;
086
087    // Name matching feature flags (Phase 1: Name Matching)
088    // Default: false (disabled until stabilized)
089    public static boolean USE_EXT_NAME_MATCHER = false;         // Use SqlNameMatcher for name comparisons
090
091    // Phase 3.5: CatalogStoreProvider is now always used
092
093    // Catalog optimization feature flags (Phase 2: Hierarchical Index, Phase 3: Bucketed Index)
094    // Shadow introduction strategy: gradual rollout with fallback
095    public static boolean USE_HIERARCHICAL_INDEX = true;      // Enable hierarchical index (LinkedHashMap per layer)
096    public static boolean USE_BUCKETED_INDEX = true;          // Enable bucketed index for SQL Server COLLATION_BASED (25x faster)
097    public static boolean USE_COMPOSITE_KEY_OPT = false;       // Enable composite key optimization (Couchbase only)
098    public static boolean LOG_INDEX_HIT_RATE = false;          // Log index hit rate for performance validation
099    public static boolean ENFORCE_CATALOG_SEAL = false;        // Enforce catalog seal() - throw exception on modification after seal (Phase 6)
100    public static boolean ALLOW_MULTI_SEGMENT_IN_KEY = true;   // Allow multi-segment identifiers in keyForMap (Phase 0: enabled for gradual migration)
101    public static boolean LOG_KEY_COMPARISON = false;          // Phase 1: Log new vs old key comparisons for debugging
102
103    // Phase 3: Migration complete - CatalogStoreProvider is now the default implementation
104    // (Feature flags removed as migration is complete)
105
106    // System property support for catalog optimization flags (gradual rollout)
107    static {
108        String hierarchicalFlag = System.getProperty("gsp.use_hierarchical_index");
109        if (hierarchicalFlag != null) {
110            USE_HIERARCHICAL_INDEX = Boolean.parseBoolean(hierarchicalFlag);
111        }
112
113        String compositeKeyFlag = System.getProperty("gsp.use_composite_key");
114        if (compositeKeyFlag != null) {
115            USE_COMPOSITE_KEY_OPT = Boolean.parseBoolean(compositeKeyFlag);
116        }
117
118        String bucketedIndexFlag = System.getProperty("gsp.use_bucketed_index");
119        if (bucketedIndexFlag != null) {
120            USE_BUCKETED_INDEX = Boolean.parseBoolean(bucketedIndexFlag);
121        }
122
123        String logHitRateFlag = System.getProperty("gsp.log_index_hit_rate");
124        if (logHitRateFlag != null) {
125            LOG_INDEX_HIT_RATE = Boolean.parseBoolean(logHitRateFlag);
126        }
127
128        String enforceSealFlag = System.getProperty("gsp.enforce_catalog_seal");
129        if (enforceSealFlag != null) {
130            ENFORCE_CATALOG_SEAL = Boolean.parseBoolean(enforceSealFlag);
131        }
132
133        // Phase 3: Migration flags removed - migration complete
134    }
135
136    public static boolean USE_JOINEXPR_INSTEAD_OF_JOIN = true; // introduce since 2.7.3.0
137
138    public static String sqlflow_stmt_delimiter_str = "sqlflow-delimiter";
139
140    /**
141     * Buffer size for lexer input BufferedReader.
142     * Larger buffer reduces I/O overhead when lexer performs character-by-character reads.
143     * Default: 64KB (8x the JDK default of 8KB).
144     */
145    public static int LEXER_INPUT_BUFFER_SIZE = 64 * 1024;
146
147    public static final int tag_token_value_changed_in_on_canonical = 999;
148    public static  boolean as_canonical_f_decrypt_replace_password = false;
149
150
151    public static  boolean REDSHIFT_ENABLE_BRACKET_NAME = false;
152
153    public static final int BOOL_VALUE_FALSE = 0;
154    public static final int BOOL_VALUE_TRUE = 1;
155    public static final int BOOL_VALUE_NOT_SET = 2;
156
157    public static final int MATCH_COLUMN_RESULT_NOT_MATCH = -1;
158    public static final int MATCH_COLUMN_RESULT_MATCHED = 0;
159    public static final int MATCH_COLUMN_RESULT_MATCHED_COLUMN_PROPERTY = 1;
160    public static final int MATCH_COLUMN_RESULT_MAYBE_MATCH_P1 = 10; // Highest priority for possible match
161    public static final int MATCH_COLUMN_RESULT_MAYBE_MATCH_P3 = 30;
162    public static final int MATCH_COLUMN_RESULT_MAYBE_MATCH_P4 = 40;
163    public static final int MATCH_COLUMN_RESULT_MAYBE_MATCH_P5 = 50;
164    public static final int MATCH_COLUMN_RESULT_MAYBE_MATCH_P9 = 90;
165
166    public static final int CAN_BE_COLUMN_NOT_VALIDATE_YET = 0;
167    public static final int VALIDATED_CAN_BE_A_COLUMN_NAME = 1;
168    public static final int VALIDATED_CAN_NOT_BE_A_COLUMN_NAME = 2;
169    public static final int MARKED_NOT_A_COLUMN_IN_COLUMN_RESOLVER = 3;
170
171    public static final int COLUMN_LINKED_TO_COLUMN_ALIAS_IN_OLD_ALGORITHM = 4;
172
173    // 在老算法中关联 column 和 table时,谨慎把 column 的 状态设为该值,这会导致 column resolver 不再 resolve 该值
174    // 从而导致 column push 动作没有执行。 除非在非常明确的情况,在老算法中即便关联了 column 和 table,也不要设置该值
175
176    // SELECT * FROM (
177    //    WITH
178    //      Combined1 AS (
179    //        SELECT * FROM actor
180    //        UNION ALL
181    //        SELECT * FROM actor2
182    //        UNION ALL
183    //        SELECT * FROM actor3
184    //      )
185    //       , Combined2 AS (
186    //        SELECT * FROM  Combined1
187    //      )
188    //    SELECT
189    //      actor_id,
190    //      first_name
191    //    FROM Combined2
192    //) outer_select_wrapper
193    public static final int COLUMN_LINKED_TO_TABLE_IN_OLD_ALGORITHM = 5;
194
195    public static final int NOT_RESOLVED_YET = 1;
196    public static final int RESOLVED_BUT_NOT_FOUND = 2;
197    public static final int RESOLVED_AND_FOUND = 3;
198    public static final int RESOLVED_BUT_AMBIGUOUS = 4;
199
200    // 不在  TCustomSqlStatement.linkColumnToTable() 进行关联,延迟到 column resolver 中进行
201    // 目的是避免产生假性的 orphan column
202    public static final int RESOLVE_DELAY_TO_COLUMN_RESOLVER = 5;
203
204    public static final int GUESS_COLUMN_STRATEGY_NEAREST = 0;
205    public static final int GUESS_COLUMN_STRATEGY_FARTHEST = 1;
206    public static final int GUESS_COLUMN_STRATEGY_NOT_PICKUP = 2;
207    public static final String[] GUESS_COLUMN_STRATEGY_MSG = {"GUESS_COLUMN_STRATEGY_NEAREST","GUESS_COLUMN_STRATEGY_FARTHEST","GUESS_COLUMN_STRATEGY_NOT_PICKUP"};
208
209    public static  int GUESS_COLUMN_STRATEGY = GUESS_COLUMN_STRATEGY_NOT_PICKUP;
210
211    public static final int COLUMN_IN_TABEL_FUNCTION_YES = 1;
212    public static final int COLUMN_IN_TABEL_FUNCTION_NO = 2;
213    public static final int COLUMN_IN_TABEL_FUNCTION_NOTSURE = 3;
214
215    // Error, warning, hint Code
216    public static final int MSG_WARNING_ERROR_WHEN_TOKENIZE = 10200;
217    public static final int MSG_HINT_FIND_ORPHAN_COLUMN = 10500;
218    public static final int MSG_ERROR_NO_ROOT_NODE = -1000;
219    public static final int MSG_ERROR_AND_KEYWORD_CANT_USED_AS_TABLE_ALIAS = 10600;
220    public static final int MSG_ERROR_RESERVED_KEYWORD_CANT_USED_AS_COLUMN_NAME = 10601;
221    public static final int MSG_ERROR_FUNCTION_IN_SET_CLAUSE = 10700;
222    public static final int MSG_ERROR_DUPLICATED_COLUMN_NAME = 10800;
223    public static final int MSG_ERROR_SYNTAX_ERROR = 10111;
224    public static final int MSG_ERROR_INSERT_VALUE_COLUMN_NUMBER_NOT_MATCH = 10900;
225    public static final int MSG_ERROR_COLUMN_NOT_FOUND = 10950;
226
227    static final String license_file_missing = "license file is missing";
228    static final String license_file_invalid = "invalid license file";
229    static final String license_file_name = "/gsp_license.txt";
230    static final String license_trail_username = "trial_user";
231//    static final String license_trail_machineid = "trial_machine";
232    static final String license_illegal_key = "Illegal license key";
233    static final String license_type_developer = "developer";
234    static final String license_type_dist = "dist";
235    static final String license_type_trial = "trial";
236
237    static  final boolean license_expired_check = false;
238    static  final String license_expired_date = "2022-10-19";
239
240    static final boolean need_license_file = false;
241
242    static final boolean bigquery_edition = false;
243    static final boolean couchbase_edition = false;
244    static final boolean dax_edition = false;
245    static final boolean powerquery_edition = false;
246    static final boolean db2_edition = false;
247    static final boolean greenplum_edition = false;
248    static final boolean hana_edition = false;
249    static final boolean hive_edition = false;
250    static final boolean impala_edition = false;
251    static final boolean informix_edition = false;
252    static final boolean mdx_edition = false;
253    static final boolean mysql_edition = false;
254    static final boolean doris_edition = false;
255    static final boolean netezza_edition = false;
256    static final boolean odbc_edition = false;
257    static final boolean openedge_edition = false;
258    static final boolean oracle_edition = false;
259    static final boolean postgresql_edition = false;
260    static final boolean duckdb_edition = false;
261    static final boolean redshift_edition = false;
262    static final boolean snowflake_edition = false;
263    static final boolean sqlserver_edition = false;
264    static final boolean sybase_edition = false;
265    static final boolean teradata_edition = false;
266    static final boolean vertica_edition = false;
267    static final boolean soql_edition = false;
268    static final boolean azuresql_edition = false;
269    static final boolean sparksql_edition = false;
270    static final boolean exasol_edition = false;
271    static final boolean starrocks_edition = false;
272    static final boolean flink_edition = false;
273    static final boolean athena_edition = false;
274    static final boolean presto_edition = false;
275    static final boolean trino_edition = false;
276    static final boolean generic_edition = true;
277    static final boolean databricks_edition = false;
278    static final boolean gaussdb_edition = false;
279    static final boolean edb_edition = false;
280    static final boolean dameng_edition = false;
281    static final boolean ansi_edition = false;
282    static final boolean sqlite_edition = false;
283    static final boolean clickhouse_edition = false;
284
285    static final int query_size_limitation = 10000;
286    static final String time_limited_msg = "expired after 90 days after first usage.";
287    /**
288     * ONE trial-cap message with ONE limit, applied once, where the SQL is
289     * read (owner decision 2026-07-28): a byte-backed source (file/stream) is
290     * measured in raw bytes, a String in characters ignoring leading
291     * whitespace. See {@link TrialInputGuard} for why the character rule makes
292     * every internal re-parse of already-ingested text pass without any
293     * exemption machinery.
294     */
295    static final String trail_version_size_message = "trial version can only process query with size of at most "+query_size_limitation+" bytes"+", and "+time_limited_msg;
296    static final String trail_version_file_message = trail_version_size_message;
297    static final String trail_version_query_message = trail_version_size_message;
298
299    /**
300     * Canonical trial-build size-cap message. Public because enforcement points
301     * live outside this package (the lexer byte counter, the pp2 formatter, the
302     * dlineage analyzers).
303     *
304     * <p>Callers deciding whether a failure IS the trial rejection must use
305     * {@link #isTrialSizeMessage(String)} rather than comparing with equals:
306     * some adapters prefix downstream messages ("Parsing failed: ...").
307     */
308    public static String trialSizeMessage() {
309        return trail_version_size_message;
310    }
311
312    /**
313     * True when {@code message} reports the trial size cap, including when an
314     * adapter has prefixed it.
315     */
316    public static boolean isTrialSizeMessage(String message) {
317        return !full_edition && message != null && message.contains(trail_version_size_message);
318    }
319
320    /**
321     * True when running a trial build AND the given BYTE count exceeds the trial
322     * cap. Always false in full builds (compile-time constant). Public for entry
323     * points outside this package that must refuse oversized input instead of
324     * degrading (e.g., the fault-tolerant pp2 formatter, which would otherwise
325     * echo the input back with a success status).
326     */
327    public static boolean trialSizeExceeded(long byteCount) {
328        return !full_edition && byteCount > query_size_limitation;
329    }
330
331    /** The trial cap: bytes for a byte-backed source, characters for a String. */
332    public static int trialSizeLimitBytes() {
333        return query_size_limitation;
334    }
335
336
337
338
339//Following const must be keep the same value in  .y file
340public static final String linebreak = System.getProperty("line.separator");
341public static final String windowsLinebreak = "\r\n";
342public static final String windowsLinebreakEscape = "\\r\\n";
343
344    public static  boolean bigquery_legacysql_compatible = false;
345
346/**
347 * Token code value for block comment: /* comment inside  *&#47;
348 */
349public final static int cmtslashstar = 257;
350
351    /**
352     *  single line comment
353      */
354public final static int cmtdoublehyphen = 258;
355
356    /**
357     * whitespace including space and tab
358     */
359public final static int lexspace = 259;
360
361    /**
362     * linebreak
363     */
364public final static int lexnewline = 260;
365
366    /**
367     * float and real constant
368     */
369public final static int fconst  = 261;
370
371    /**
372     * string constant
373     */
374public final static int sconst = 262;
375
376    /**
377     * integer constant
378     */
379public final static int iconst = 263;
380
381    /**
382     * identifier token id
383     */
384public final static int ident = 264;
385public final static int op = 265;
386public final static int cmpop = 266;
387public final static int bind_v = 267;
388public final static int assign_sign = 268;
389public final static int double_dot = 269;
390public final static int label_begin = 270;
391public final static int hive_CharSetName = 270;     //hive
392public final static int label_end = 271;
393public final static int hive_div = 271;      //hive
394public final static int substitution_v = 272;
395public final static int filepath_sign = 272; //snowflake
396public final static int hive_number = 272;
397public final static int sqlpluscmd = 273;
398public final static int atversion = 273; //databricks, @V
399public final static int left_parenthesis_3 = 273;
400
401
402public final static int error = 274;
403public final static int variable = 275;
404public final static int hive_DecimalLiteral = 273;
405public final static int hive_StringLiteral = 275;
406public final static int hive_CharSetLiteral = 276;
407public final static int hive_ByteLengthLiteral = 277;
408public final static int hive_BigintLiteral = 278;
409public final static int hive_SmallintLiteral = 279;
410public final static int hive_TinyintLiteral = 280;
411public final static int mslabel = 276;
412public final static int RW_NATURAL2 = 276;
413//public final static int RW_CONNECT_TO = 276;
414public final static int bconst = 276; //postgresql
415public final static int equal_start_expr = 276;
416public final static int leftjoin_op = 277;
417public final static int logic_and_op = 277;
418public final static int odbc_esc_prefix = 277;
419public final static int rightjoin_op = 278;
420public final static int logic_or_op = 278;
421public final static int odbc_esc_terminator = 278;
422public final static int dax_column_token = 279;
423public final static int with_rollup = 279;  //MYSQL WITH ROLLUP
424public final static int RW_FULL2 = 279;   //used to replace full keyword in oracle
425public final static int db2label = 279;
426public final static int xconst = 279; //postgresql
427public final static int teradata_unicode_sconst = 279;
428// public final static int ref_arrow = 280;
429public final static int scriptoptions = 281;
430    public final static int     JSON_GET_TEXT = 281;
431    public final static int     ORACLE_OUTER2 = 281;
432
433public final static int mysqllabel = 282;
434    public final static int     JSON_GET_TEXT_AT_PATH = 282;
435public final static int BTEQCMD = 282;
436public final static int concatenationop = 283;
437public final static int pipe_greater = 283; // StarRocks pipe operator |>
438public final static int rw_not_deferrable = 284;
439    public final static int     JSON_GET_OBJECT = 284;
440
441public final static int rw_for1 = 285;
442public final static int     JSON_GET_OBJECT_AT_PATH = 285;
443public final static int rw_not1 = 285;
444    public final static int rw_for_system_time = 285; //MSSQL
445    public final static int rw_for_path = 672; //MSSQL - compound token for graph FOR PATH
446
447public final static int stmt_delimiter = 286;
448
449public final static int m_clause = 287;
450    public final static int rw_sybase_at1 = 287;
451public final static int typecast = 287; //postgresql,netezza,db2
452public final static int rrw_time2_teradata = 287;
453    public final static int rrw_merge2_sqlserver = 287;
454
455public final static int k_clause = 288;
456public final static int rw_sybase_update1 = 288;
457public final static int     JSON_LEFT_CONTAIN = 288;
458public final static int safe_equal = 288;//HIVE equal_ns, gaussdb
459public final static int rrw_date2_teradata = 288;
460public final static int measure_equal = 288; //dax measure equal :=
461public final static int slash_dot = 288; //mysql \. sqlfile,  execute an SQL script file
462public final static int postgresql_arary_operator = 288;
463
464
465public final static int outer_join = 289;
466public final static int hive_equal = 289;
467public final static int rrw_timestamp2_teradata = 289;
468
469public final static int not_equal = 290;
470public final static int not_great = 291;
471public final static int not_less = 292;
472public final static int great_equal = 293;
473public final static int less_equal = 294;
474// Oracle 26c vector distance operators (IDs from lzyaccoraclesql.pas)
475public final static int vector_cosine_distance = 1235;      // <=>
476public final static int vector_euclidean_distance = 1236;   // <->
477public final static int vector_dot_product = 1237;          // <#>
478public final static int exponentiate = 295;
479public final static int boolean_and = 296;
480public final static int rowtype_operator = 296;
481public final static int boolean_or = 297;
482public final static int     JSON_RIGHT_CONTAIN = 297;
483public final static int     square_root = 297;
484public final static int     cube_root = 298;
485public final static int     bitwise_shift_left = 299;
486public final static int     bitwise_shift_right = 300;
487
488public final static int rw_locktable = 296;
489public final static int rw_foreign2 = 297;
490public final static int rw_constraint2 = 298;
491public final static int     JSON_EXIST = 298;
492public final static int     HIVE_FUNC_IDENT = 298;
493public final static int rw_primary2 = 299;
494public final static int     JSON_ANY_EXIST = 299;
495public final static int rw_unique2 = 300;
496public final static int     JSON_ALL_EXIST = 300;
497
498public final static int     IDENT_BEFORE_COLON = 297;
499public final static int     NEXT_PARAM = 298;
500public final static int     POSITIONAL_PARAM = 299;
501public final static int     NAMED_PARAM = 300;
502
503
504// common sql keywords used in all databases
505public final static int rrw_select = 301;
506public final static int rrw_insert = 302;
507public final static int rrw_delete = 303;
508public final static int rrw_update = 304;
509public final static int rrw_if = 305;
510public final static int rrw_for  = 306;
511public final static int rrw_create  = 307;
512public final static int rrw_table  = 308;
513public final static int rrw_index   = 309;
514public final static int rrw_view   = 310;
515public final static int rrw_with   = 311;
516public final static int rrw_start  = 312;
517public final static int rrw_end     = 313;
518public final static int rrw_drop    = 314;
519public final static int rrw_declare   = 315;
520public final static int rrw_case      = 316;
521public final static int rrw_where      = 317;
522public final static int rrw_having      = 318;
523public final static int rrw_and      = 319;
524public final static int rrw_or      = 320;
525public final static int rrw_not      = 321;
526public final static int rrw_when      = 322;
527public final static int rrw_on      = 323;
528public final static int rrw_join      = 324;
529public final static int rrw_set      = 325;
530public final static int rrw_values      = 326;
531public final static int rrw_object      = 327;
532public final static int rrw_record      = 328;
533public final static int rrw_from      = 329;
534public final static int rrw_group      = 330;
535public final static int rrw_sort      = 331;
536public final static int rrw_into      = 332;
537public final static int rrw_order      = 333;
538public final static int rrw_fetch      = 334;
539public final static int rrw_decode      = 335;
540public final static int rrw_over      = 336;
541public final static int rrw_extract     = 337;
542public final static int rrw_distinct    = 338;
543public final static int rrw_all    = 339;
544public final static int rrw_by    = 340;
545public final static int rrw_as    = 341;
546public final static int rrw_union  = 342;
547public final static int rrw_left  = 343;
548public final static int rrw_right  = 344;
549public final static int rrw_inner  = 345;
550public final static int rrw_full  = 346;
551public final static int rrw_outer  = 347;
552public final static int rrw_then  = 348;
553public final static int rrw_else  = 349;
554public final static int rrw_between  = 350;
555public final static int rrw_begin   = 351;
556public final static int rrw_except   = 352;
557public final static int rrw_minus   = 353;
558public final static int rrw_intersect   = 354;
559
560public final static int rrw_bit  = 355;
561
562public final static int rrw_tinyint = 356; //mysql
563public final static int rrw_smallint = 357;
564public final static int rrw_mediumint = 358; //mysql
565public final static int rrw_middleint = 359; //mysql
566public final static int rrw_int = 360;
567public final static int rrw_integer = 361;
568public final static int rrw_int1 = 362; //mysql
569public final static int rrw_int2 = 363; //mysql
570public final static int rrw_int3 = 364; //mysql
571public final static int rrw_int4 = 365; //mysql
572public final static int rrw_int8 = 366; //mysql
573public final static int rrw_bigint  = 367;
574
575public final static int rrw_float = 368;
576public final static int rrw_float4 = 369;
577public final static int rrw_float8 = 370;
578public final static int rrw_num = 371;
579public final static int rrw_numeric = 372;
580public final static int rrw_number = 373;
581public final static int rrw_real = 374;
582public final static int rrw_decimal = 375;
583public final static int rrw_dec = 376;
584
585public final static int rrw_double = 377;
586public final static int rrw_precision = 378;
587public final static int rrw_char = 379;
588public final static int rrw_nchar = 380;
589public final static int rrw_character = 381;
590public final static int rrw_varchar = 382;
591public final static int rrw_varchar2 = 383; //oracle
592public final static int rrw_national = 384; //mysql national char
593public final static int rrw_nvarchar = 385;
594public final static int rrw_nvarchar2 = 386; //oracle
595public final static int rrw_varbinary = 387;
596public final static int rrw_varying = 388;
597public final static int rrw_tinytext = 389;//mysql
598public final static int rrw_text = 390;
599public final static int rrw_mediumtext = 391;//mysql
600public final static int rrw_longtext = 392;//mysql
601public final static int rrw_time = 393;
602public final static int rrw_date = 394;
603public final static int rrw_timestamp = 395;
604public final static int rrw_year = 396;//mysql
605public final static int rrw_local = 397;
606public final static int rrw_zone = 398;
607public final static int rrw_long = 399;
608public final static int rrw_raw = 400;
609public final static int rrw_blob  = 401;
610public final static int rrw_tinyblob = 402; //mysql
611public final static int rrw_mediumblob = 403; //mysql
612public final static int rrw_longblob = 404; //mysql
613public final static int rrw_clob = 405;
614public final static int rrw_nclob = 406;
615public final static int rrw_dbclob = 407;
616public final static int rrw_bfile = 408;
617public final static int rrw_large = 409;
618public final static int rrw_data = 410; //db2 for bit data
619public final static int rrw_binary = 411; //db2 binary large object
620
621public final static int rrw_graphic = 412;  //db2
622public final static int rrw_vargraphic = 413; //db2
623public final static int rrw_datalink = 414; //db2
624public final static int rrw_enum = 415; //mysql
625public final static int rrw_interval = 416; //oracle interval year to month
626public final static int rrw_urowid = 417; //oracle
627public final static int rrw_merge = 418;
628public final static int rrw_commit = 419;
629public final static int rrw_rollback = 420;
630public final static int rrw_savepoint = 421;
631public final static int rrw_revoke = 422;
632public final static int rrw_grant = 423;
633public final static int rrw_truncate = 424;
634public final static int rrw_database = 425;
635public final static int rrw_alter = 426;
636public final static int rrw_return = 427;
637public final static int rrw_add = 428;
638public final static int rrw_close = 429;
639public final static int rrw_continue = 430;
640public final static int rrw_backup = 431;
641public final static int rrw_break = 432;
642public final static int rrw_bulk = 433;
643public final static int rrw_dbcc = 434;
644public final static int rrw_deallocate = 435;
645public final static int rrw_deny = 436;
646public final static int rrw_disable = 437;
647public final static int rrw_enable = 438;
648public final static int rrw_exec = 439;
649public final static int rrw_execute = 440;
650public final static int rrw_goto = 441;
651public final static int rrw_kill = 442;
652public final static int rrw_open = 443;
653public final static int rrw_save = 444;
654public final static int rrw_move = 445;
655public final static int rrw_print = 446;
656public final static int rrw_raiserror = 447;
657public final static int rrw_readtext = 448;
658public final static int rrw_receive = 449;
659public final static int rrw_reconfigure = 450;
660public final static int rrw_restore = 451;
661public final static int rrw_send = 452;
662public final static int rrw_setuser = 453;
663public final static int rrw_shutdown = 454;
664public final static int rrw_sign = 455;
665public final static int rrw_try = 456;
666public final static int rrw_updatetext = 457;
667public final static int rrw_use = 458;
668public final static int rrw_waitfor = 459;
669public final static int rrw_while = 460;
670public final static int rrw_writetext = 461;
671public final static int rrw_catch = 462;
672public final static int rrw_go = 463;
673public final static int rrw_openrowset = 464;
674public final static int rrw_analyze = 465;
675public final static int rrw_associate = 466;
676public final static int rrw_audit = 467;
677public final static int rrw_call = 468;
678public final static int rrw_comment = 469;
679public final static int rrw_disassociate = 470;
680public final static int rrw_explain = 471;
681public final static int rrw_flashback = 472;
682public final static int rrw_lock = 473;
683public final static int rrw_noaudit = 474;
684public final static int rrw_purge = 475;
685public final static int rrw_rename = 476;
686public final static int rrw_procedure = 477;
687public final static int rrw_function = 478;
688public final static int rrw_package = 479;
689public final static int rrw_allocate = 480;
690public final static int rrw_connect = 481;
691public final static int rrw_describe = 482;
692public final static int rrw_disconnect = 483;
693public final static int rrw_flush = 484;
694public final static int rrw_free = 485;
695public final static int rrw_get = 486;
696public final static int rrw_include = 487;
697public final static int rrw_iterate = 488;
698public final static int rrw_leave = 489;
699public final static int rrw_loop = 490;
700public final static int rrw_prepare = 491;
701public final static int rrw_refresh = 492;
702public final static int rrw_release = 493;
703public final static int rrw_repeat = 494;
704public final static int rrw_resignal = 495;
705public final static int rrw_signal = 496;
706public final static int rrw_cache = 497;
707public final static int rrw_change = 498;
708public final static int rrw_check = 499;
709public final static int rrw_checksum = 500;
710public final static int rrw_do = 501;
711public final static int rrw_handler = 502;
712public final static int rrw_load = 503;
713public final static int rrw_optimize = 504;
714public final static int rrw_replace = 505;
715public final static int rrw_repair = 506;
716public final static int rrw_reset = 507;
717public final static int rrw_show = 508;
718public final static int rrw_stop = 509;
719public final static int rrw_unlock = 510;
720public final static int rrw_terminate = 511;
721public final static int rrw_to = 512;
722
723// ClickHouse token values, read from the generated parser constants after
724// regeneration. They are stable only because new ClickHouse tokens are
725// appended at the END of the %token block; an insertion mid-list shifts every
726// later value and must be reflected here (symptom: "token code:0" errors).
727public final static int rrw_clickhouse_partition = 658;
728public final static int rrw_clickhouse_in = 699;
729public final static int rrw_clickhouse_format = 1169;
730public final static int rrw_clickhouse_in_before_partition = 1211;
731public final static int rrw_clickhouse_tuple_dot = 1213;
732public final static int rrw_clickhouse_exists = 696;
733public final static int rrw_clickhouse_exchange = 798;
734public final static int rrw_clickhouse_undrop = 1214;
735public final static int rrw_clickhouse_time = 393;
736public final static int rrw_clickhouse_local = 397;
737public final static int rrw_clickhouse_zone = 398;
738public final static int rrw_clickhouse_at = 622;
739public final static int rrw_snowflake_desc_short = 534; // DESC (short form), from the generated snowflake parser constants
740public final static int rrw_primary = 513;
741public final static int rrw_unique = 514;
742public final static int rrw_constraint = 515;
743public final static int rrw_foreign = 516;
744public final static int rrw_revert = 517;
745public final static int rrw_checkpoint = 518;
746public final static int rrw_calculate = 519;
747public final static int rrw_clear = 520;
748public final static int rrw_drillthrough = 521;
749public final static int rrw_freeze = 522;
750public final static int rrw_existing = 523;
751public final static int rrw_scope = 524;
752public final static int rrw_is = 525;
753public final static int rrw_body = 526;
754public final static int rrw_abort = 527;
755public final static int rrw_using = 528;
756public final static int rrw_pause = 511;
757public final static int rrw_resume = 512;
758public final static int rrw_submit = 670;
759public final static int rrw_task = 752;
760public final static int rrw_cancel = 820;
761public final static int rrw_export = 873;
762public final static int rrw_locations = 774;
763public final static int rrw_location = 773;
764public final static int rrw_volume = 1061;
765public final static int rrw_volumes = 1062;
766public final static int rrw_repository = 1063;
767public final static int rrw_views = 755;
768public final static int rrw_functions = 756;
769public final static int rrw_builtin = 1261;
770public final static int rrw_dictionary = 858;
771
772// Oracle conditional compilation tokens (from lzyaccoracleplsql.pas)
773public final static int cc_if = 1248;
774public final static int cc_then = 1249;
775public final static int cc_else = 1250;
776public final static int cc_elsif = 1251;
777public final static int cc_end = 1252;
778public final static int cc_error = 1253;
779
780// end of common sql keywords used in all databases
781
782//databricks
783    // public final static int param  = rrw_abort + 2; keep the same value as postgresql
784    public final static int rrw_databricks_msck = rrw_abort + 3;
785    public final static int rrw_databricks_sync = rrw_abort + 4;
786    public final static int rrw_databricks_copy = rrw_abort + 5;
787    public final static int rrw_databricks_uncache = rrw_abort + 6;
788    public final static int rrw_databricks_desc = rrw_abort + 7;
789    public final static int rrw_databricks_list = rrw_abort + 8;
790    public final static int rrw_databricks_values_insert = rrw_abort + 9;
791    public final static int rrw_databricks_datatype_used_to_cast = rrw_abort + 10;
792    public final static int rrw_databricks_convert = rrw_abort + 11;
793    public final static int rrw_databricks_fsck = rrw_abort + 12;
794    public final static int rrw_databricks_reorg = rrw_abort + 13;
795    public final static int rrw_databricks_vacuum = rrw_abort + 14;
796    // POSITION function token codes: MUST match the YACC token values in
797    // lzyaccdatabricks.y (RW_POSITION_FUNCTION=564, RW_POSITION=565). Used by
798    // DatabricksSqlParser to route the POSITION(substr IN str) form to the
799    // dedicated position grammar rule (RW_POSITION_FUNCTION '(' opt_position_list ')').
800    public final static int rrw_databricks_POSITION_FUNCTION = rrw_abort + 37;
801    public final static int rrw_databricks_POSITION = rrw_abort + 38;
802    // MUST match the YACC token values in lzyaccdatabricks.y (declared at the
803    // END of the %token list). RW_IDENTIFIER_FUNC routes IDENTIFIER(expr) used
804    // as a write-target table name (Mantis 4638); RW_WITH_SCHEMA_OPTION routes
805    // the WITH of "WITH SCHEMA ..." / "WITH METRICS LANGUAGE ..." clauses
806    // (Mantis 4643/4644/4645). Both are assigned by DatabricksSqlParser's
807    // token pre-pass, never by the lexer.
808    public final static int rrw_databricks_identifier_func = 1201;
809    public final static int rrw_databricks_with_schema_option = 1202;
810//end of databricks
811
812//INFORMIX
813    public final static int castoperator = rrw_abort + 2;
814    //public final static int compoundAssignmentOperator = rrw_abort + 3;
815    //public final static int SEMI_COLON_AFTER_BEGIN = rrw_abort + 4;
816
817    public final static int rrw_informix_unload = rrw_abort + 5;
818    public final static int rrw_informix_whenever = rrw_abort + 6;
819    public final static int rrw_informix_put = rrw_abort +7;
820    public final static int rrw_informix_output = rrw_abort + 8;
821    public final static int rrw_informix_info = rrw_abort + 9;
822    public final static int rrw_informix_connect_to = rrw_abort + 10;
823
824    //DB2
825    public final static int rrw_rr = rrw_abort + 3;
826    public final static int rrw_rs = rrw_abort + 4;
827    public final static int rrw_cs = rrw_abort + 5;
828    public final static int rrw_ur = rrw_abort + 6;
829    public final static int rrw_with_isolation = rrw_abort + 7;
830    public final static int rrw_declare_global = rrw_abort + 8;
831    public final static int rrw_db2_second = rrw_abort + 9;
832    public final static int rrw_db2_label = rrw_abort + 10;
833    public final static int rrw_db2_tablespace = rrw_abort + 11;
834    public final static int rrw_db2_runstats = rrw_abort + 12;
835    public final static int rrw_db2_current = rrw_abort + 13;
836    public final static int rrw_jdbc_escape_fn = rrw_abort + 14;
837    public final static int rrw_jdbc_escape_end = rrw_abort + 15;
838    public final static int rrw_db2_trim_l = rrw_abort + 16;
839    public final static int rrw_db2_trim_r = rrw_abort + 17;
840    public final static int rrw_db2_trim = rrw_abort + 18;
841
842    //postgresql, guassdb, redshift share the following constant
843    public final static int param  = rrw_abort + 2;
844    public final static int rrw_postgresql_cluster = rrw_abort + 3;
845    public final static int rrw_postgresql_copy = rrw_abort + 4;
846    public final static int rrw_postgresql_discard = rrw_abort + 5;
847    public final static int rrw_postgresql_listen = rrw_abort + 6;
848    public final static int rrw_postgresql_notify = rrw_abort + 7;
849    public final static int rrw_postgresql_reassign = rrw_abort + 8;
850    public final static int rrw_postgresql_reindex = rrw_abort + 9;
851    public final static int rrw_postgresql_security = rrw_abort + 10;
852    public final static int rrw_postgresql_unlisten = rrw_abort + 11;
853
854    public final static int rrw_cascade  = rrw_abort + 12;
855    public final static int rrw_restrict  = rrw_abort + 13;
856    public final static int rrw_perform  = rrw_abort + 14;
857    public final static int rrw_debug  = rrw_abort + 15;
858    public final static int rrw_exception  = rrw_abort + 16;
859    public final static int rrw_notice  = rrw_abort + 17;
860    public final static int rrw_postgresql_info  = rrw_abort + 18;
861    public final static int rrw_warning  = rrw_abort + 19;
862    public final static int rrw_log  = rrw_abort + 20;
863    public final static int rrw_postgresql_rowtype  = rrw_abort + 21;
864
865    // In TCreateFunctionStmt.postgresqlFunctionDefinition(), 手工加上 plpgsql_function_delimiter 字符串,标记一个pgsql block的开始
866    public final static int rrw_plpgsql_function_delimiter = rrw_abort + 22;
867
868    public final static int rrw_postgresql_vacuum = rrw_abort + 23;
869    public final static int rrw_postgresql_do_update = rrw_abort + 24;
870    public final static int rrw_postgresql_POSITION_FUNCTION  = rrw_abort + 25;
871    public final static int rrw_postgresql_POSITION  = rrw_abort + 26;
872    public final static int rrw_postgresql_insert_values  = rrw_abort + 27;
873    public final static int rrw_postgresql_conflict = rrw_abort + 28;
874    public final static int rrw_postgresql_nothing = rrw_abort + 29;
875    public final static int rrw_postgresql_import = rrw_abort + 30;
876    public final static int rrw_postgresql_with_lookahead = rrw_abort + 31;
877    public final static int rrw_postgresql_ordinality = rrw_abort + 32;
878    public final static int rrw_postgresql_filter  = rrw_abort + 33;
879
880    // SQLite constants (same grammar base as PostgreSQL, shared values)
881    public final static int rrw_sqlite_insert_values = rrw_postgresql_insert_values;
882    public final static int rrw_sqlite_pragma = 1194;  // RW_PRAGMA token value from lzyaccsqlite.pas
883    public final static int rrw_sqlite_attach = 734;   // RW_ATTACH token value from lzyaccsqlite.pas
884    public final static int rrw_sqlite_detach = 735;   // RW_DETACH token value from lzyaccsqlite.pas
885
886    public final static int OP_STAR_EQUAL  = rrw_abort + 34;
887    public final static int OP_STAR_LESS  = rrw_abort + 35;
888    public final static int OP_STAR_GREAT  = rrw_abort + 36;
889    public final static int OP_SQUARE_ROOT  = rrw_abort + 37;
890    public final static int OP_LESS_LESS  = rrw_abort + 38;
891    public final static int OP_GREAT_GREAT  = rrw_abort + 39;
892    public final static int OP_EXCLAMATION_EXCLAMATION  = rrw_abort + 40;
893    public final static int OP_TILDE_TILDE  = rrw_abort + 41;
894    public final static int OP_TILDE_STAR  = rrw_abort + 42;
895    public final static int OP_EXCLAMATION_TILDE  = rrw_abort + 43;
896    public final static int OP_AT_AT  = rrw_abort + 44;
897    public final static int OP_POUND_POUND  = rrw_abort + 45;
898    public final static int OP_AT_GREAT  = rrw_abort + 46;
899    public final static int OP_LESS_AT  = rrw_abort + 47;
900    public final static int OP_PUNCTUATION_PUNCTUATION  = rrw_abort + 48;
901    public final static int OP_PUNCTUATION_LESS  = rrw_abort + 49;
902    public final static int OP_PUNCTUATION_GREAT  = rrw_abort + 50;
903    public final static int OP_LESS_CARET  = rrw_abort + 51;
904    public final static int OP_GREAT_CARET  = rrw_abort + 52;
905    public final static int OP_QUESTION_POUND  = rrw_abort + 53;
906    public final static int OP_QUESTION_MINUS  = rrw_abort + 54;
907    public final static int OP_QUESTION_BAR  = rrw_abort + 55;
908    public final static int OP_TILDE_EQUAL  = rrw_abort + 56;
909    public final static int OP_MINUS_GREAT  = rrw_abort + 57;
910    public final static int OP_POUND_GREAT  = rrw_abort + 58;
911    public final static int OP_QUESTION_PUNCTUATION  = rrw_abort + 59;
912    public final static int OP_POUND_MINUS  = rrw_abort + 60;
913    public final static int OP_AT_QUESTION  = rrw_abort + 61;
914    public final static int OP_STAR_LESS_GREAT  = rrw_abort + 62;
915    public final static int OP_STAR_LESS_EQUAL  = rrw_abort + 63;
916    public final static int OP_STAR_GREAT_EQUAL  = rrw_abort + 64;
917    public final static int OP_CUBE_ROOT  = rrw_abort + 65;
918    public final static int OP_TILDE_TILDE_STAR  = rrw_abort + 66;
919    public final static int OP_EXCLAMATION_TIDLE_TIDLE  = rrw_abort + 67;
920    public final static int OP_EXCLAMATION_TIDLE_TIDLE_STAR  = rrw_abort + 68;
921    public final static int OP_EXCLAMATION_TIDLE_STAR  = rrw_abort + 69;
922    public final static int OP_AT_MINUS_AT  = rrw_abort + 70;
923    public final static int OP_LESS_MINUS_GREAT  = rrw_abort + 71;
924    public final static int OP_LESS_LESS_BAR  = rrw_abort + 72;
925    public final static int OP_BAR_GREAT_GREAT  = rrw_abort + 73;
926    public final static int OP_PUNCTUATION_LESS_BAR  = rrw_abort + 74;
927    public final static int OP_BAR_PUNCTUATION_GREAT  = rrw_abort + 75;
928    public final static int OP_QUESTION_MINUS_BAR  = rrw_abort + 76;
929    public final static int OP_QUESTION_BAR_BAR  = rrw_abort + 77;
930    public final static int OP_LESS_LESS_EQUAL  = rrw_abort + 78;
931    public final static int OP_GREAT_GREAT_EQUAL  = rrw_abort + 79;
932    public final static int OP_AT_AT_AT  = rrw_abort + 80;
933    public final static int OP_MINUS_GREAT_GREAT  = rrw_abort + 81;
934    public final static int OP_POUND_GREAT_GREAT  = rrw_abort + 82;
935    public final static int OP_MINUS_BAR_MINUS  = rrw_abort + 83;
936    public final static int OP_JSONB_QUESTION  = rrw_abort + 84;
937    public final static int rrw_postgresql_json  = rrw_abort + 85;
938    public final static int rrw_postgresql_jsonb  = rrw_abort + 86;
939    public final static int OP_TILDE_GREAT_TILDE  = rrw_abort + 87;
940    public final static int OP_TILDE_LESS_TILDE  = rrw_abort + 88;
941    public final static int OP_TILDE_GREAT_EQUAL_TILDE  = rrw_abort + 89;
942    public final static int OP_TILDE_LESS_EQUAL_TILDE  = rrw_abort + 90;
943    public final static int OP_LESS_LESS_LESS  = rrw_abort + 91;
944    public final static int OP_GREAT_GREAT_GREAT  = rrw_abort + 92;
945    public final static int OP_LESS_PERCENT  = rrw_abort + 93;
946    public final static int OP_GREAT_PERCENT  = rrw_abort + 94;
947    public final static int rrw_postgresql_recursive  = rrw_abort + 95;
948    public final static int rrw_postgresql_function_delimiter  = rrw_abort + 96;
949    public final static int rrw_postgresql_language  = rrw_abort + 97;
950    public final static int rrw_postgresql_type  = rrw_abort + 98;
951    // Value MUST match yacc-assigned value in lzyaccpostgresql.pas
952    public final static int rrw_postgresql_declare_cursor_stmt  = 1217;
953
954    // PGvector distance operators - values MUST match yacc-assigned values in lzyaccpostgresql.pas
955    public final static int OP_LESS_HASH_GREAT  = 1263;    // <#> (negative) inner product
956    public final static int OP_LESS_EQUAL_GREAT  = 1264;   // <=> cosine distance
957    public final static int OP_LESS_PLUS_GREAT  = 1265;    // <+> L1 distance
958    public final static int OP_LESS_TILDE_GREAT  = 1266;   // <~> Hamming distance
959    public final static int OP_LESS_PERCENT_GREAT  = 1267; // <%> Jaccard distance
960    public final static int OP_STAR_STAR  = 1300;           // ** power/exponentiation (DuckDB), matches yacc value
961    public final static int OP_SLASH_SLASH  = 1301;        // // integer division (DuckDB), matches yacc value
962
963    // end of postgres, guassdb, redshift
964
965    // gaussDB
966    public final static int OP_SAFE_EQUAL  = rrw_abort + 99;
967    public final static int GAUSSDB_CURSOR  = rrw_abort + 100;
968    public final static int GAUSSDB_DECLARE_SINGLE_STMT  = rrw_abort + 101;
969    public final static int GAUSSDB_BEGIN_TRANSACTION  = rrw_abort + 102;
970    public final static int GAUSSDB_PROCEDURE_ORA  = rrw_abort + 103;
971    public final static int GAUSSDB_FUNCTION_ORA  = rrw_abort + 104;
972    public final static int GAUSSDB_NULL  = rrw_abort + 105;
973
974    public final static int GAUSSDB_TO_BINARY_DOUBLE  = rrw_abort + 106;
975    public final static int GAUSSDB_TO_NUMBER  = rrw_abort + 107;
976    public final static int GAUSSDB_TO_BINARY_FLOAT  = rrw_abort + 108;
977    public final static int GAUSSDB_TO_DATE  = rrw_abort + 109;
978    public final static int GAUSSDB_TO_TIMESTAMP  = rrw_abort + 110;
979    public final static int GAUSSDB_TO_TIMESTAMP_TZ  = rrw_abort + 111;
980
981    
982
983    //greenplum
984    // public final static int param  = rrw_abort + 2; keep the same value as postgresql
985
986    public final static int rrw_greenplum_cluster = rrw_abort + 3;
987    public final static int rrw_greenplum_copy = rrw_abort + 4;
988    public final static int rrw_greenplum_reassign = rrw_abort + 8;
989    public final static int rrw_greenplum_reindex = rrw_abort + 9;
990    public final static int rrw_greenplum_vacuum = rrw_abort + 21;
991    public final static int rrw_greenplum_language = rrw_abort + 22;
992    public final static int rrw_greenplum_rowtype  = rrw_abort + 23;
993    public final static int rrw_greenplum_analyse  = rrw_abort + 24;
994    public final static int rrw_greenplum_DATE_FUNCTION  = rrw_abort + 25;
995    public final static int rrw_greenplum_POSITION_FUNCTION  = rrw_abort + 26;
996    public final static int rrw_greenplum_POSITION  = rrw_abort + 27;
997    public final static int rrw_greenplum_CURSOR  = rrw_abort + 28;
998    public final static int rrw_greenplum_exits  = rrw_abort + 29;
999    public final static int rrw_greenplum_filter  = rrw_abort + 30;
1000    public final static int rrw_greenplum_values_insert  = rrw_abort + 31;
1001    public final static int rrw_greenplum_function_delimiter  = rrw_abort + 32;
1002
1003
1004    //MYSQL
1005    public final static int logical_and = rrw_abort + 2;
1006    public final static int logical_or = rrw_abort + 3;
1007    public final static int rrw_left_shift = rrw_abort + 4;
1008    public final static int rrw_right_shift = rrw_abort + 5;
1009    public final static int rrw_mysql_desc = rrw_abort + 8;
1010    public final static int rrw_mysql_delimiter = rrw_abort + 9;
1011    public final static int rrw_rollup = rrw_abort + 10;
1012    public final static int rrw_mysql_date_function = rrw_abort + 11;
1013    public final static int rrw_mysql_date_const = rrw_abort + 12;
1014    public final static int rrw_mysql_time_const = rrw_abort + 13;
1015    public final static int rrw_mysql_row = rrw_abort + 14;
1016    public final static int rrw_mysql_each = rrw_abort + 15;
1017    public final static int rrw_mysql_source = rrw_abort + 16;
1018    public final static int rrw_mysql_interval_func = rrw_abort + 17;
1019    public final static int rrw_mysql_true = rrw_abort + 18;
1020    public final static int rrw_mysql_false = rrw_abort + 19;
1021    public final static int rrw_mysql_default = rrw_abort + 20;
1022    public final static int rrw_mysql_d = rrw_abort + 21;
1023    public final static int rrw_mysql_t = rrw_abort + 22;
1024    public final static int rrw_mysql_ts = rrw_abort + 23;
1025    public final static int rrw_mysql_null = rrw_abort + 24;
1026    public final static int rrw_mysql_current = rrw_abort + 25;
1027    public final static int rrw_mysql_timestamp_constant = rrw_abort + 26;
1028    public final static int rrw_mysql_position = rrw_abort + 27;
1029
1030    //oracle specific keyword
1031    public final static int rrw_custom = rrw_abort + 2;
1032    public final static int rrw_translate = rrw_abort + 4;
1033    public final static int rrw_keep = rrw_abort + 5;
1034    public final static int rrw_keep_before_dense_rank = rrw_abort + 6;
1035    public final static int rrw_dense_rank = rrw_abort + 7;
1036    public final static int rrw_wrapped = rrw_abort + 8;
1037    public final static int rrw_level = rrw_abort + 10;
1038    public final static int rrw_match = rrw_abort + 11;
1039    public final static int rrw_natural = rrw_abort + 12;
1040    public final static int rrw_type2 = rrw_abort + 13;
1041    public final static int rrw_type = rrw_abort + 14;
1042    public final static int rrw_of = rrw_abort + 15;
1043    public final static int rrw_oid = rrw_abort + 16;
1044    public final static int rrw_null = rrw_abort + 17;
1045    public final static int rrw_trigger = rrw_abort + 18;
1046    public final static int rrw_library = rrw_abort + 19;
1047    public final static int rrw_value_after_by = rrw_abort + 20;
1048    public final static int rrw_value_oracle = rrw_abort + 21;
1049    public final static int rrw_new_oracle = rrw_abort + 22;
1050    public final static int rrw_chr_oracle = rrw_abort + 23;
1051    public final static int rrw_errors_oracle = rrw_abort + 24;
1052    public final static int rrw_log_oracle = rrw_abort + 25;
1053    public final static int rrw_add_p = rrw_abort + 26; //add partition
1054    public final static int rrw_partition = rrw_abort + 27; //add partition
1055    public final static int rrw_oracle_apply = rrw_abort + 28;
1056    public final static int rrw_oracle_subpartition = rrw_abort + 29;
1057    public final static int rrw_oracle_subpartition_tablesample = rrw_abort + 30;
1058    public final static int rrw_oracle_new_constructor = rrw_abort + 31;
1059    public final static int rrw_oracle_supplemental = rrw_abort + 32;
1060    public final static int rrw_oracle_compound = rrw_abort + 33;
1061    public final static int rrw_oracle_offset = rrw_abort + 34;
1062    public final static int rrw_oracle_row = rrw_abort + 35;
1063    public final static int rrw_oracle_rows = rrw_abort + 36;
1064    public final static int rrw_oracle_offset_row = rrw_abort + 37;
1065    public final static int rrw_oracle_a_in_aset = rrw_abort + 38;
1066    public final static int rrw_oracle_set_in_aset = rrw_abort + 39;
1067    public final static int rrw_oracle_modify = rrw_abort + 40;
1068    public final static int rrw_oracle_column = rrw_abort + 41;
1069    public final static int rrw_oracle_column_after_modify = rrw_abort + 42;
1070    public final static int rrw_oracle_without = rrw_abort + 43;
1071    public final static int rrw_oracle_count = rrw_abort + 44;
1072    public final static int rrw_oracle_without_before_count = rrw_abort + 45;
1073    public final static int rrw_oracle_cursor = rrw_abort + 46;
1074    public final static int rrw_oracle_collect = rrw_abort + 47;
1075    public final static int rrw_oracle_synonym = rrw_abort + 48;
1076    public final static int rrw_oracle_model = rrw_abort + 49;
1077    public final static int rrw_oracle_model_in_model_clause = rrw_abort + 50;
1078    
1079    
1080    // sql server keywords
1081    public final static int twocolons = rrw_abort + 2;
1082    public final static int compoundAssignmentOperator = rrw_abort + 3;
1083    public final static int SEMI_COLON_AFTER_BEGIN = rrw_abort + 4;
1084
1085    public final static int rrw_starea   = rrw_abort + 5;
1086    public final static int rrw_stasbinary   = rrw_abort + 6;
1087    public final static int rrw_stastext = rrw_abort + 7;
1088    public final static int rrw_stbuffer = rrw_abort + 8;
1089    public final static int rrw_stdimension = rrw_abort + 9;
1090    public final static int rrw_stdisjoint = rrw_abort + 10;
1091    public final static int rrw_stdistance = rrw_abort + 11;
1092    public final static int rrw_stendpoint = rrw_abort + 12;
1093    public final static int rrw_stgeometryn = rrw_abort + 13;
1094    public final static int rrw_stgeometrytype = rrw_abort + 14;
1095    public final static int rrw_stintersection = rrw_abort + 15;
1096    public final static int rrw_stintersects = rrw_abort + 16;
1097    public final static int rrw_stisclosed = rrw_abort + 17;
1098    public final static int rrw_stisempty = rrw_abort + 18;
1099    public final static int rrw_stlength = rrw_abort + 19;
1100    public final static int rrw_stnumgeometries = rrw_abort + 20;
1101    public final static int rrw_stnumpoints = rrw_abort + 21;
1102    public final static int rrw_stpointn = rrw_abort + 22;
1103    public final static int rrw_stsrid = rrw_abort + 23;
1104    public final static int rrw_ststartpoint = rrw_abort + 24;
1105    public final static int rrw_stunion = rrw_abort + 25;
1106
1107    //sql server, functions on xml column
1108    public final static int rrw_xml_value = rrw_abort + 26;
1109    public final static int rrw_xml_modify = rrw_abort + 27;
1110    public final static int rrw_xml_query = rrw_abort + 28;
1111    public final static int rrw_xml_exist = rrw_abort + 29;
1112    public final static int rrw_xml_nodes = rrw_abort + 30;
1113    public final static int rrw_sqlserver_value = rrw_abort + 31;
1114    public final static int rrw_sqlserver_modify = rrw_abort + 32;
1115    public final static int rrw_sqlserver_query = rrw_abort + 33;
1116    public final static int rrw_sqlserver_exist = rrw_abort + 34;
1117    public final static int rrw_sqlserver_nodes = rrw_abort + 35;
1118
1119    public final static int rrw_sqlserver_throw = rrw_abort + 36;
1120    public final static int rrw_system_time = rrw_abort + 37;
1121    public final static int rrw_xmlnamespaces = rrw_abort + 38;
1122    public final static int rrw_sqlserver_next = rrw_abort + 39;
1123    public final static int rrw_sqlserver_row = rrw_abort + 40;
1124    public final static int rrw_sqlserver_rows = rrw_abort + 41;
1125    public final static int rrw_sqlserver_offset_fetch = rrw_abort + 42;
1126    public final static int rrw_sqlserver_odbc_escape = rrw_abort + 43;
1127    public final static int rrw_sqlserver_exists = rrw_abort + 44;
1128    public final static int rrw_sqlserver_copy = rrw_abort + 45;
1129    public final static int rrw_sqlserver_copyinto = rrw_abort + 46;
1130    public final static int rrw_sqlserver_column = rrw_abort + 47;
1131    public final static int rrw_sqlserver_drop_column = rrw_abort + 48;
1132    public final static int rrw_sqlserver_check_with = rrw_abort + 49;
1133    public final static int rrw_sqlserver_semicolon_module_number = rrw_abort + 50;
1134    public final static int rrw_sqlserver_trim = rrw_abort + 51;
1135    public final static int rrw_sqlserver_synonym = rrw_abort + 52;
1136    public final static int rrw_sqlserver_sequence = rrw_abort + 53;
1137    public final static int rrw_sqlserver_tran = rrw_abort + 54;
1138    public final static int rrw_sqlserver_transaction = rrw_abort + 55;
1139    public final static int rrw_sqlserver_distributed = rrw_abort + 56;
1140    public final static int rrw_sqlserver_dialog = rrw_abort + 57;
1141    public final static int rrw_sqlserver_conversation = rrw_abort + 58;
1142    public final static int rrw_sqlserver_DELETED = rrw_abort + 59;
1143    public final static int rrw_sqlserver_INSERTED = rrw_abort + 60;
1144
1145     // end of sql server keywords
1146
1147    //SOQL
1148
1149    public final static int rrw_soql_update_tracking = rrw_abort + 45;
1150
1151    //sybase
1152    public final static int rrw_sybase_dump = rrw_abort + 31;
1153    public final static int rrw_sybase_at = rrw_abort + 32;
1154    public final static int rrw_sybase_isolation = rrw_abort + 33;
1155    public final static int rrw_sybase_off = rrw_abort + 34;
1156    public final static int rrw_sybase_partition = rrw_abort + 38;
1157    public final static int rrw_sybase_exce_proc_name = rrw_abort + 39;
1158    // Sybase IQ / SQL Anywhere statement-level command keywords. Values are
1159    // the token codes assigned by yacc for the sybase grammar (lzyaccsybase.y);
1160    // verify against `const RW_*` in the regenerated lzyaccsybase.pas after
1161    // any token addition (new tokens must be appended at the END of the
1162    // %token declarations so these offsets stay stable).
1163    public final static int rrw_sybase_trigger = rrw_abort + 179;      // RW_TRIGGER = 706
1164    public final static int rrw_sybase_message = rrw_abort + 194;      // RW_MESSAGE = 721
1165    public final static int rrw_sybase_read = rrw_abort + 402;         // RW_READ = 929
1166    public final static int rrw_sybase_output = rrw_abort + 521;       // RW_OUTPUT = 1048
1167    public final static int rrw_sybase_forward = rrw_abort + 618;      // RW_FORWARD = 1145
1168    public final static int rrw_sybase_install = rrw_abort + 619;      // RW_INSTALL = 1146
1169    public final static int rrw_sybase_remove = rrw_abort + 620;       // RW_REMOVE = 1147
1170    public final static int rrw_sybase_put = rrw_abort + 621;          // RW_PUT = 1148
1171    public final static int rrw_sybase_synchronize = rrw_abort + 622;  // RW_SYNCHRONIZE = 1149
1172    public final static int rrw_sybase_iq = rrw_abort + 623;           // RW_IQ = 1150
1173
1174    // Exasol (shares the MSSQL grammar). Values are token codes assigned by
1175    // yacc for lzyaccmssqlsql.y — verify against `const RW_*` in the
1176    // regenerated lzyaccmssqlsql.pas after any token addition (new tokens
1177    // must be appended at the END of the %token declarations so these stay
1178    // stable). The RW_EXASOL_* tokens are synthetic: the lexer never emits
1179    // them; MssqlSqlParser's Exasol pre-pass rewrites plain words to these
1180    // codes when the input dialect is dbvexasol.
1181    public final static int rrw_mssql_access = rrw_abort + 236;        // RW_ACCESS = 763
1182    public final static int rrw_mssql_admin = rrw_abort + 309;         // RW_ADMIN = 836
1183    public final static int rrw_mssql_limit = rrw_abort + 414;         // RW_LIMIT = 941
1184    public final static int rrw_mssql_prior = rrw_abort + 265;         // RW_PRIOR = 792
1185    public final static int rrw_mssql_partition = rrw_abort + 293;     // RW_PARTITION = 820
1186    public final static int rrw_exasol_qualify = rrw_abort + 829;      // RW_EXASOL_QUALIFY = 1356
1187    public final static int rrw_exasol_invalid = rrw_abort + 830;      // RW_EXASOL_INVALID = 1357
1188    public final static int rrw_exasol_referencing = rrw_abort + 831;  // RW_EXASOL_REFERENCING = 1358
1189    public final static int rrw_exasol_distribute = rrw_abort + 832;   // RW_EXASOL_DISTRIBUTE = 1359
1190    public final static int rrw_exasol_including = rrw_abort + 833;    // RW_EXASOL_INCLUDING = 1360
1191    public final static int rrw_exasol_partition = rrw_abort + 834;    // RW_EXASOL_PARTITION = 1361
1192    public final static int rrw_exasol_prior = rrw_abort + 835;        // RW_EXASOL_PRIOR = 1362
1193    public final static int rrw_exasol_disable = rrw_abort + 836;      // RW_EXASOL_DISABLE = 1363
1194
1195
1196// teradata specifc keyword
1197    public final static int rrw_teradata_using = rrw_abort + 1;
1198    public final static int rrw_bt = rrw_abort + 2;
1199    public final static int rrw_teradata_collect = rrw_abort + 3;
1200    public final static int rrw_teradata_cm = rrw_abort + 4;
1201    public final static int rrw_ct = rrw_abort + 5;
1202    public final static int rrw_teradata_del = rrw_abort + 6;
1203    public final static int rrw_teradata_diagnostic = rrw_abort + 7;
1204    public final static int rrw_teradata_dump = rrw_abort + 8;
1205    public final static int rrw_teradata_echo = rrw_abort + 9;
1206    public final static int rrw_et = rrw_abort + 10;
1207    public final static int rrw_teradata_give = rrw_abort + 11;
1208    public final static int rrw_teradata_help = rrw_abort + 12;
1209    public final static int rrw_teradata_ins = rrw_abort + 13;
1210    public final static int rrw_logoff = rrw_abort + 14;
1211    public final static int rrw_teradata_logon = rrw_abort + 15;
1212    public final static int rrw_teradata_modify = rrw_abort + 16;
1213    public final static int rrw_teradata_position = rrw_abort + 17;
1214    public final static int rrw_teradata_restart = rrw_abort + 18;
1215    public final static int rrw_rewind = rrw_abort + 19;
1216    public final static int rrw_teradata_sel = rrw_abort + 20;
1217    public final static int rrw_ss = rrw_abort + 21;
1218    public final static int rrw_teradata_upd = rrw_abort + 22;
1219    public final static int rrw_teradata_wait = rrw_abort + 23;
1220    public final static int rrw_teradata_locking = rrw_abort + 24;
1221    public final static int rrw_casespecific = rrw_abort + 25;
1222    public final static int rrw_teradata_cs = rrw_abort + 26;
1223    public final static int rrw_teradata_add_months = rrw_abort + 27;
1224    public final static int rrw_teradata_format = rrw_abort + 28;
1225    public final static int rrw_teradata_title = rrw_abort + 29;
1226    public final static int rrw_teradata_named = rrw_abort + 30;
1227    public final static int left_parenthesis_2 = rrw_abort + 31;
1228    public final static int rrw_teradata_start_data_conversion = rrw_abort + 31;
1229    public final static int rrw_teradata_period = rrw_abort + 32;
1230    public final static int rrw_teradata_cast = rrw_abort + 33;
1231  //  public final static int rrw_teradata_null = rrw_abort + 34;
1232    public final static int rrw_teradata_cv = rrw_abort + 35;
1233    public final static int rrw_teradata_for_loop = rrw_abort + 36;
1234    public final static int rrw_teradata_last = rrw_abort + 37;
1235    public final static int rrw_last_function = rrw_abort + 38;
1236    public final static int rrw_teradata_transaction = rrw_abort + 39;
1237    public final static int rrw_teradata_end_t = rrw_abort + 40;
1238    public final static int rrw_teradata_exit = rrw_abort + 41;
1239    public final static int rrw_teradata_label = rrw_abort + 42;
1240    public final static int rrw_teradata_pivot = rrw_abort + 43;
1241    public final static int rrw_teradata_cursor_name = rrw_abort + 44;
1242    public final static int rrw_teradata_condition_name = rrw_abort + 45;
1243    public final static int rrw_teradata_case_stmt = rrw_abort + 46;
1244    public final static int rrw_teradata_with_grant = rrw_abort + 47;
1245    public final static int rrw_teradata_external = rrw_abort + 48;
1246    public final static int rrw_teradata_type = rrw_abort + 53;
1247    public final static int rrw_teradata_sample = rrw_abort + 54;
1248    public final static int rrw_teradata_validtime = rrw_abort + 55;
1249    public final static int rrw_teradata_sequenced = rrw_abort + 56;
1250    public final static int rrw_teradata_nonsequenced = rrw_abort + 57;
1251
1252
1253    //hive
1254public final static int rrw_hive_desc = rrw_abort + 2;
1255public final static int rrw_hive_msck = rrw_abort + 3;
1256public final static int rrw_hive_export = rrw_abort + 4;
1257public final static int rrw_hive_import = rrw_abort + 5;
1258public final static int rrw_hive_recover = rrw_abort + 6;
1259public final static int rrw_map                             = rrw_abort + 7;
1260public final static int rrw_formatted                       = rrw_abort + 8;
1261public final static int rrw_extended                        = rrw_abort + 9;
1262public final static int rrw_pretty                          = rrw_abort + 10;
1263public final static int rrw_shared                          = rrw_abort + 11;
1264public final static int rrw_exclusive                       = rrw_abort + 12;
1265public final static int rrw_show_database                           = rrw_abort + 13;
1266public final static int  rrw_hive_DATE_FUNCTION = rrw_abort + 14;
1267public final static int  rrw_hive_rollup = rrw_abort + 15;
1268public final static int  rrw_hive_cube = rrw_abort + 16;
1269    public final static int  rrw_hive_upsert = rrw_abort + 17; // shared by hive and impala
1270    public final static int  rrw_hive_reload = rrw_abort + 18;
1271    public final static int  rrw_hive_list = rrw_abort + 19;
1272
1273// flink
1274    public final static int rrw_watermark = 693;
1275    // Flink EXPLAIN statement option keywords
1276    public final static int rrw_estimated_cost = 1300;
1277    public final static int rrw_changelog_mode = 1301;
1278    public final static int rrw_plan_advice = 1302;
1279    public final static int rrw_json_execution_plan = 1303;
1280    // Flink catalog operation keywords
1281    public final static int rrw_catalog = 1304;
1282    // Flink-specific function keywords
1283    public final static int rrw_try_cast = 1305;
1284    public final static int rrw_ifnull = 1306;
1285    public final static int rrw_nullif = 1307;
1286    public final static int rrw_coalesce = 1308;
1287    public final static int rrw_proctime = 1309;
1288    public final static int rrw_rowtime = 1310;
1289    public final static int rrw_current_watermark = 1311;
1290    public final static int rrw_current_row_timestamp = 1312;
1291    public final static int rrw_localtime = 1313;
1292    public final static int rrw_localtimestamp = 1314;
1293    // Flink-specific LOCALTIME/LOCALTIMESTAMP lexer token codes (match YACC grammar positions)
1294    public final static int flink_rw_localtime = 707;
1295    public final static int flink_rw_localtimestamp = 708;
1296    public final static int rrw_tumble = 1315;
1297    public final static int rrw_hop = 1316;
1298    public final static int rrw_cumulate = 1317;
1299    public final static int rrw_descriptor = 1318;
1300    public final static int rrw_to_timestamp = 1319;
1301    public final static int rrw_to_timestamp_ltz = 1320;
1302    public final static int rrw_to_date = 1321;
1303    public final static int rrw_date_format = 1322;
1304    // Flink PRIMARY KEY NOT ENFORCED support
1305    public final static int rrw_enforced = 1323;
1306    // Flink interval unit token codes
1307    public final static int flink_interval_year = 396;
1308    public final static int flink_interval_years = 692;
1309    public final static int flink_interval_second = 1077;
1310    public final static int flink_interval_seconds = 1078;
1311    public final static int flink_interval_minute = 1079;
1312    public final static int flink_interval_minutes = 1080;
1313    public final static int flink_interval_hour = 1081;
1314    public final static int flink_interval_hours = 1082;
1315    public final static int flink_interval_day = 1083;
1316    public final static int flink_interval_days = 1084;
1317    public final static int flink_interval_month = 1085;
1318    public final static int flink_interval_microsecond = 1159;
1319    public final static int flink_interval_microseconds = 1160;
1320    public final static int flink_interval_millisecond = 1217;
1321    public final static int flink_interval_milliseconds = 1218;
1322    public final static int flink_interval_months = 1247;
1323
1324// netezza
1325    public final static int rrw_netezza_groom = rrw_abort + 2;
1326    public final static int rrw_netezza_copy       = rrw_abort + 3;
1327    public final static int rrw_netezza_generate = rrw_abort + 4;
1328
1329    public final static int rrw_int_cast                        = rrw_abort + 5;
1330    public final static int rrw_integer_cast                    = rrw_abort + 6;
1331    public final static int rrw_smallint_cast                   = rrw_abort + 7;
1332    public final static int rrw_bigint_cast                     = rrw_abort + 8;
1333    public final static int rrw_real_cast                       = rrw_abort + 9;
1334    public final static int rrw_float_cast                      = rrw_abort + 10;
1335    public final static int rrw_numeric_cast                    = rrw_abort + 11;
1336    public final static int rrw_boolean_cast                    = rrw_abort + 12;
1337    public final static int rrw_bit_cast                        = rrw_abort + 13;
1338    public final static int rrw_char_cast                       = rrw_abort + 14;
1339    public final static int rrw_nchar_cast                      = rrw_abort + 15;
1340    public final static int rrw_varchar_cast                    = rrw_abort + 16;
1341    public final static int rrw_character_cast                  = rrw_abort + 17;
1342    public final static int rrw_date_cast                       = rrw_abort + 18;
1343    public final static int rrw_time_cast                       = rrw_abort + 19;
1344    public final static int rrw_timestamp_cast                  = rrw_abort + 20;
1345    public final static int rrw_interval_cast                   = rrw_abort + 21;
1346    public final static int rrw_decimal_cast                    = rrw_abort + 22;
1347    public final static int rrw_begin_proc                      = rrw_abort + 23;
1348    public final static int rrw_end_proc                        = rrw_abort + 24;
1349    public final static int rrw_netezza_op_less_less                    = rrw_abort + 25;
1350    public final static int rrw_netezza_op_great_great                  = rrw_abort + 26;
1351
1352public final static int hive_DOT                            = rrw_abort + 2;
1353public final static int hive_COLON                  = rrw_abort + 3;
1354public final static int hive_COMMA                  = rrw_abort + 4;
1355public final static int hive_SEMICOLON    = rrw_abort + 5;
1356public final static int hive_LPAREN               = rrw_abort + 6;
1357public final static int hive_RPAREN               = rrw_abort + 7;
1358public final static int hive_LSQUARE              = rrw_abort + 8;
1359public final static int hive_RSQUARE              = rrw_abort + 9;
1360public final static int hive_LCURLY               = rrw_abort + 10;
1361public final static int hive_RCURLY               = rrw_abort + 11;
1362public final static int hive_LESSTHAN     = rrw_abort + 12;
1363public final static int hive_GREATERTHAN  = rrw_abort + 13;
1364public final static int hive_DIVIDE         = rrw_abort + 14;
1365public final static int hive_PLUS                   = rrw_abort + 15;
1366public final static int hive_MINUS            = rrw_abort + 16;
1367public final static int hive_STAR             = rrw_abort + 17;
1368public final static int hive_MOD                      = rrw_abort + 18;
1369public final static int hive_AMPERSAND    = rrw_abort + 19;
1370public final static int hive_TILDE                        = rrw_abort + 20;
1371public final static int hive_BITWISEOR    = rrw_abort + 21;
1372public final static int hive_BITWISEXOR         = rrw_abort + 22;
1373public final static int hive_QUESTION           = rrw_abort + 23;
1374public final static int hive_DOLLAR                     = rrw_abort + 24;
1375
1376
1377    // redshift
1378    // public final static int param  = rrw_abort + 2; keep the same value as postgresql
1379    public final static int rrw_redshift_binary_as_type = rrw_abort + 792; // = 1319, for BINARY as data type (not identifier)
1380
1381    public final static int rrw_redshift_cancel = rrw_postgresql_type + 1;
1382    public final static int rrw_redshift_unload = rrw_postgresql_type + 2 ;
1383    public final static int rrw_redshift_verbose  = rrw_postgresql_type + 3;
1384    public final static int rrw_redshift_struct  = rrw_postgresql_type + 4;
1385    public final static int rrw_redshift_array  = rrw_postgresql_type + 5;
1386    public final static int rrw_redshift_array_type  = rrw_postgresql_type + 6;
1387
1388    public final static int rrw_redshift_vacuum  = rrw_postgresql_vacuum;
1389    public final static int rrw_redshift_copy  = rrw_postgresql_copy;
1390    public final static int rrw_redshift_rowtype  = rrw_postgresql_rowtype;
1391    public final static int rrw_redshift_filter  = rrw_postgresql_filter;
1392    public final static int rrw_redshift_function_delimiter  = rrw_postgresql_function_delimiter;
1393    public final static int rrw_redshift_language  = rrw_postgresql_language;
1394    public final static int rrw_redshift_desc = rrw_abort + 434; // = 961, matches RW_DESC in Redshift grammar
1395    public final static int rrw_redshift_attach = rrw_abort + 819; // = 1346, matches RW_ATTACH in Redshift grammar
1396    public final static int rrw_redshift_detach = rrw_abort + 820; // = 1347, matches RW_DETACH in Redshift grammar
1397    public final static int rrw_redshift_library = rrw_abort + 826; // = 1353, matches RW_LIBRARY in Redshift grammar
1398    public final static int rrw_redshift_prior = rrw_abort + 452; // = 979, matches RW_PRIOR in Redshift grammar
1399
1400    // HANA
1401    public final static int rrw_hana_unset = rrw_abort + 2;
1402    public final static int rrw_hana_upsert = rrw_abort + 3 ;
1403    public final static int rrw_as_before_of                = rrw_abort + 4 ;
1404    public final static int rrw_hana_import                 = rrw_abort + 5 ;
1405    public final static int rrw_hana_export                 = rrw_abort + 6 ;
1406    public final static int rrw_hana_of             = rrw_abort + 7 ;
1407    public final static int rrw_hana_date_const             = rrw_abort + 8 ;
1408    public final static int rrw_hana_time_const             = rrw_abort + 9 ;
1409    public final static int rrw_hana_timestamp_const                = rrw_abort + 10 ;
1410    public final static int rrw_hana_with_structured                = rrw_abort + 11 ;
1411    public final static int rrw_hana_with_cache             = rrw_abort + 12 ;
1412    public final static int rrw_hana_with_check             = rrw_abort + 13 ;
1413    public final static int rrw_hana_recover                = rrw_abort + 14 ;
1414    public final static int rrw_hana_unload                 = rrw_abort + 15 ;
1415    public final static int rrw_hana_unload2                = rrw_abort + 16 ;
1416    public final static int rrw_hana_validate               = rrw_abort + 17;
1417    public final static int rrw_hana_header                 = rrw_abort + 18;
1418    public final static int rrw_hana_with_mask              = rrw_abort + 19;
1419    public final static int rrw_hana_with_expression                = rrw_abort + 20;
1420    public final static int rrw_hana_with_anonymization             = rrw_abort + 21;
1421    public final static int rrw_hana_with_hint              = rrw_abort + 22;
1422    public final static int rrw_hana_with_range_restriction         = rrw_abort + 23;
1423
1424
1425    //dax
1426    public final static int rrw_dax_define                          = rrw_abort + 2;
1427    public final static int rrw_dax_evaluate                        = rrw_abort + 3 ;
1428    public final static int rrw_dax_product                         = rrw_abort + 4 ;
1429    public final static int rrw_dax_true                            = rrw_abort + 5;
1430    public final static int rrw_dax_false                           = rrw_abort + 6 ;
1431    public final static int rrw_dax_calendar                        = rrw_abort + 7 ;
1432    public final static int rrw_dax_second                          = rrw_abort + 8 ;
1433
1434    // ODBC
1435    public final static int rrw_odbc_d                      = rrw_abort + 4;
1436    public final static int rrw_odbc_t                      = rrw_abort + 5;
1437    public final static int rrw_odbc_ts                             = rrw_abort + 6;
1438    public final static int rrw_odbc_oj                             = rrw_abort + 7;
1439    public final static int rrw_odbc_fn                             = rrw_abort + 8;
1440    public final static int rrw_odbc_escape                         = rrw_abort + 9;
1441
1442    //vertica
1443    // public final static int param  = rrw_abort + 2; keep the same value as postgresql
1444    public final static int rrw_vertica_activate = rrw_abort + 3;
1445    public final static int rrw_vertica_deactivate= rrw_abort + 4;
1446    public final static int rrw_vertica_profile= rrw_abort + 5;
1447    public final static int rrw_vertica_date_function= rrw_abort + 6;
1448    public final static int rrw_vertica_greatest= rrw_abort + 7;
1449    public final static int rrw_vertica_least= rrw_abort + 8;
1450    public final static int rrw_vertica_copy = rrw_abort + 9;
1451    public final static int rrw_vertica_export = rrw_abort + 10;
1452
1453   // openedge
1454    public final static int rrw_openedge_with_check = rrw_abort + 2;
1455
1456    public final static int howtoSetValue_none = 0;
1457    public final static int howtoSetValue_assign = 1;
1458    public final static int howtoSetValue_default = 2;    
1459
1460    public final static int     kind_create = 1;
1461    public final static int     kind_declare = 2;
1462    public final static int     kind_define = 3;
1463    public final static int     kind_create_body = 4;
1464
1465    // couchbase
1466    public final static int rrw_couchbase_build = rrw_abort + 2;
1467    public final static int rrw_couchbase_infer = rrw_abort + 3;
1468    public final static int rrw_couchbase_upsert = rrw_abort + 4;
1469
1470    //snowflake
1471    // public final static int param  = rrw_abort + 2; keep the same value as postgresql
1472    public final static int rrw_snowflake_list = rrw_abort + 3;
1473    public final static int rrw_snowflake_remove = rrw_abort + 4;
1474    public final static int rrw_snowflake_undrop = rrw_abort + 5;
1475    public final static int rrw_snowflake_copy = rrw_abort + 6;
1476    public final static int rrw_snowflake_desc = rrw_abort + 7;
1477    public final static int rrw_snowflake_ls = rrw_abort + 8;
1478    public final static int rrw_snowflake_put = rrw_abort + 9;
1479    public final static int rrw_snowflake_rm = rrw_abort + 10;
1480    public final static int rrw_snowflake_unset = rrw_abort + 11;
1481    public final static int rrw_snowflake_at = rrw_abort + 12;
1482    public final static int rrw_snowflake_at_before_parenthesis = rrw_abort + 13;
1483    public final static int rrw_snowflake_pseudo_stmt_sign = rrw_abort + 14;
1484    public final static int rrw_snowflake_date = rrw_abort + 15;
1485    public final static int rrw_snowflake_time = rrw_abort + 16;
1486    public final static int rrw_snowflake_char = rrw_abort + 17;
1487    public final static int rrw_snowflake_begin_transaction = rrw_abort + 18;
1488    public final static int rrw_snowflake_language = rrw_abort + 19;
1489    public final static int rrw_snowflake_plpgsql_function_delimiter = rrw_abort + 20;
1490    public final static int rrw_snowflake_datetime = rrw_abort + 21;
1491    public final static int rrw_snowflake_window = rrw_abort + 22;
1492    public final static int rrw_snowflake_window_as = rrw_abort + 23;
1493    public final static int rrw_snowflake_pivot = rrw_abort + 24;
1494    public final static int rrw_snowflake_unpivot = rrw_abort + 25;
1495    public final static int rrw_snowflake_default = rrw_abort + 26;
1496    public final static int rrw_snowflake_flatten = rrw_abort + 27;
1497    public final static int rrw_snowflake_offset = rrw_abort + 28;
1498    public final static int rrw_snowflake_replace_after_star = rrw_abort + 29;
1499    public final static int rrw_snowflake_function_delimiter = rrw_abort + 30;
1500    public final static int rrw_snowflake_parameter_name = rrw_abort + 31;
1501    public final static int rrw_snowflake_exists = rrw_abort + 32;
1502    public final static int rrw_snowflake_transaction = rrw_abort + 33;
1503    public final static int rrw_snowflake_javascript = rrw_abort + 34;
1504    public final static int rrw_snowflake_top = rrw_abort + 35;
1505    public final static int rrw_snowflake_limit = rrw_abort + 36;
1506    public final static int rrw_snowflake_work = rrw_abort + 37;
1507    public final static int rrw_snowflake_left_join = rrw_abort + 38;
1508    public final static int rrw_snowflake_right_join = rrw_abort + 39;
1509    public final static int rrw_snowflake_changes = rrw_abort + 40;
1510    public final static int rrw_snowflake_changes_parenthesis = rrw_abort + 41;
1511
1512    //Doris
1513    public final static int rrw_doris_export = 667;  // Token code from Doris lexer
1514    public final static int rrw_doris_switch = 1011; // Token code from Doris lexer
1515    public final static int rrw_doris_admin = 788;   // Token code from Doris lexer for ADMIN commands
1516    public final static int rrw_doris_recover = 663; // Token code from Doris lexer for RECOVER commands
1517    public final static int rrw_doris_cancel = 800;  // Token code from Doris lexer for CANCEL commands
1518    public final static int rrw_doris_pause = 668;   // Token code from Doris lexer for PAUSE commands
1519    public final static int rrw_doris_resume = 669;  // Token code from Doris lexer for RESUME commands
1520    // RIGHT_SHIFT in lzyaccdorissql.y / lzyaccstarrockssql.y: the lexer gives >> this code so that it can
1521    // close two nested column types at once, as in ARRAY<ARRAY<INT>>. Pinned by TestComplexColumnTypes.
1522    public final static int rrw_doris_right_shift = 532;
1523    public final static int rrw_starrocks_right_shift = 534;
1524
1525    //OCEANBASE MySQL mode (XA transaction entry token)
1526    // Absolute value from parsetable output for RW_XA in lzyaccoceanbasemysql.pas
1527    // (appended at end of %token block per FORK_DIVERGENCE rule #1).
1528    public final static int rrw_oceanbase_xa = 1204;
1529    // RW_ROLE from lzyaccoceanbasemysql.pas; used by the OceanBaseMysqlSqlParser
1530    // pre-pass to retokenize "SET role = ..." as a variable assignment (parity
1531    // with base MySQL) instead of the SET ROLE statement.
1532    public final static int rrw_oceanbase_role = 935;
1533
1534    //BIGQUERY
1535    public final static int rrw_bigquery_struct = rrw_abort + 2;
1536    public final static int rrw_bigquery_struct_constructor = rrw_abort + 3;
1537    public final static int rrw_bigquery_datatype_used_to_cast = rrw_abort + 4;
1538    public final static int rrw_bigquery_export = rrw_abort + 5;
1539    public final static int rrw_bigquery_begin_transaction = rrw_abort + 6;
1540    public final static int rrw_bigquery_timestamp_as_type = rrw_abort + 7;
1541    // LEFT/INNER/FULL prefixing a set operation (LEFT [OUTER] UNION ...), rewritten
1542    // by the BigQuerySqlParser pre-pass; values must match lzyaccbigquery.pas
1543    public final static int rrw_bigquery_left_set_op = rrw_abort + 682;   // = 1209
1544    public final static int rrw_bigquery_inner_set_op = rrw_abort + 683;  // = 1210
1545    public final static int rrw_bigquery_full_set_op = rrw_abort + 684;   // = 1211
1546
1547//    public final static int rrw_bigquery_timestamp_before_const = rrw_abort + 4;
1548//    public final static int rrw_bigquery_date_before_const = rrw_abort + 5;
1549
1550
1551    //sparksql
1552    public final static int rrw_spark_uncache = rrw_abort + 2;
1553    public final static int rrw_spark_desc = rrw_abort + 3;
1554    public final static int rrw_spark_list = rrw_abort + 4;
1555    public final static int rrw_spark_date_const = rrw_abort + 5;
1556    public final static int rrw_spark_date_function = rrw_abort + 6;
1557    public final static int rrw_spark_time_const = rrw_abort + 7;
1558    public final static int rrw_spark_timestamp_constant = rrw_abort + 8;
1559    public final static int rrw_spark_msck = rrw_abort + 9;
1560    public final static int rrw_spark_position = rrw_abort + 10;
1561    public final static int sparksql_pipe_arrow = 753; // |> pipe operator, must match PIPE_ARROW in lzyaccsparksql.y
1562
1563    //flink
1564    // Context-sensitive tokens for LOCALTIME and LOCALTIMESTAMP
1565    // These keywords can be both builtin functions and identifiers.
1566    // When used as functions (standalone without period prefix), use these tokens.
1567    // Token codes must match YACC positions in lzyaccflink.y (709, 710)
1568    public final static int rrw_flink_localtime_as_func = rrw_abort + 182;      // = 709
1569    public final static int rrw_flink_localtimestamp_as_func = rrw_abort + 183; // = 710
1570    // Named-argument assignment "=>" in Flink window TVF calls, e.g. TUMBLE(DATA => TABLE t, ...).
1571    // The lexer emits a generic multi-char operator; FlinkSqlParser rewrites it to this token.
1572    // Token code must match RW_FLINK_NAMED_ARG in the generated lzyaccflink.pas (1245)
1573    public final static int rrw_flink_named_arg = rrw_abort + 718;              // = 1245
1574
1575    //presto
1576    // public final static int param  = rrw_abort + 2; keep the same value as postgresql
1577    public final static int rrw_presto_verbose = rrw_abort + 3;
1578
1579    //athena
1580    // public final static int param  = rrw_abort + 2; keep the same value as postgresql
1581    public final static int rrw_athena_unload = rrw_abort + 3;
1582    public final static int rrw_athena_msck = rrw_abort + 4;
1583
1584    //duckdb
1585    public final static int rrw_duckdb_export = 1270;
1586    public final static int rrw_duckdb_summarize = 1271;
1587    public final static int rrw_duckdb_install = 1272;
1588    public final static int rrw_duckdb_import = 557;   // RW_IMPORT in duckdb .pas
1589public final static int rrw_mysql_import = 613;    // raw keyword code of IMPORT as seen by the statement splitter
1590    public final static int rrw_duckdb_force = 927;    // RW_FORCE in duckdb .pas
1591    public final static int rrw_duckdb_secret = 1274;  // RW_SECRET in duckdb .pas
1592    public final static int rrw_duckdb_pivot = 1275;   // RW_PIVOT in duckdb .pas
1593    public final static int rrw_duckdb_unpivot = 1276;  // RW_UNPIVOT in duckdb .pas
1594    public final static int rrw_duckdb_lbrace = 1277;  // RW_LBRACE in duckdb .pas
1595    public final static int rrw_duckdb_rbrace = 1278;  // RW_RBRACE in duckdb .pas
1596    public final static int rrw_duckdb_variable = 1282; // RW_VARIABLE in duckdb .pas
1597    public final static int rrw_duckdb_pragma = 1299;  // RW_PRAGMA in duckdb .pas
1598
1599    /**
1600     * @deprecated since 1.7.2.7, replaced by {@link gudusoft.gsqlparser.EOracleCreateType#octIncomplete}
1601     */
1602    public final static int     kind_create_incomplete = 5;
1603
1604    /**
1605     * @deprecated since 1.7.2.7, replaced by {@link gudusoft.gsqlparser.EOracleCreateType#octVarray}
1606     */
1607    public final static int     kind_create_varray = 6;
1608
1609    /**
1610     * @deprecated since 1.7.2.7, replaced by {@link gudusoft.gsqlparser.EOracleCreateType#octNestedTable}
1611     */
1612    public final static int     kind_create_nested_table = 7;
1613
1614    public final static int     kind_create_type_placeholder = 8;
1615
1616    /**
1617     * Trigger fire mode
1618     */
1619
1620    public final static int fireMode_before = 1;
1621    public final static int fireMode_after = 2;
1622    public final static int fireMode_insteadOf = 3;
1623    public final static int fireMode_for = 4;
1624
1625
1626
1627    // source of join
1628    public final static int join_source_fake = 1;
1629    public final static int join_source_table = 2;
1630    public final static int join_source_join = 3;
1631
1632    /**
1633     * value types of insert statement
1634     */
1635    public final static int     vt_values = 1;
1636    public final static int     vt_query = 2;
1637    public final static int     vt_default_values = 3;
1638    public final static int     vt_execute = 4;
1639    public final static int     vt_values_function = 5; // oracle
1640    public final static int     vt_values_empty = 6; //mysql, values()
1641    public final static int vt_set_column_value = 7; //mysql, values()
1642    public final static int     vt_values_oracle_record = 8; // oracle plsql record
1643    public final static int     vt_values_multi_table = 9; // oracle multitable insert
1644    public final static int     vt_hive = 10;
1645    public final static int     vt_hive_query = 11;
1646    public final static int     vt_table = 12;
1647
1648
1649    // variable type in declare statement
1650    public final static int declare_varaible_normal = 1;
1651    public final static int declare_varaible_cursor = 2;
1652    public final static int declare_varaible_table = 3;
1653
1654    // type of declare statement
1655     /*
1656      *  @deprecated As of v1.4.7.8, replaced by {@link EDeclareType#variable    }
1657      */
1658    public final static int declare_statement_variable = 1;
1659     /*
1660      *  @deprecated As of v1.4.7.8, replaced by {@link EDeclareType#cursor    }
1661      */
1662    public final static int declare_statement_cursor = 2;
1663     /*
1664      *  @deprecated As of v1.4.7.8, replaced by {@link EDeclareType#conditions    }
1665      */
1666    public final static int declare_statement_conditions = 3; //mysql
1667     /*
1668      *  @deprecated As of v1.4.7.8, replaced by {@link EDeclareType#handlers    }
1669      */
1670    public final static int declare_statement_handlers = 4; //mysql,db2
1671     /*
1672      *  @deprecated As of v1.4.7.8, replaced by {@link EDeclareType#statement    }
1673      */
1674    public final static int declare_statement_statement = 5; //db2
1675     /*
1676      *  @deprecated As of v1.4.7.8, replaced by {@link EDeclareType#returnCode    }
1677      */
1678    public final static int declare_statement_returnCode = 6; //db2
1679
1680    // conditional statement type
1681    public final static int condition_statement_if = 1;
1682    public final static int condition_statement_while = 2;
1683
1684    // parameters in-out mode
1685    public final static int parameter_mode_default = 0;
1686    public final static int parameter_mode_in = 1;
1687    public final static int parameter_mode_out = 2;
1688    public final static int parameter_mode_inout = 3;
1689    public final static int parameter_mode_output = 4;
1690    public final static int parameter_mode_readonly = 5;
1691    public final static int parameter_mode_aslocator = 6; //as locator
1692    public final static int parameter_mode_variadic = 7; //as locator
1693
1694    // create function return type
1695    public final static int function_return_datatype = 1;
1696    public final static int function_return_table = 2; // sql server
1697    public final static int function_return_table_variable = 3; // sql server
1698
1699
1700    // constraint level
1701
1702    public final static int constraint_level_column = 1;
1703    public final static int constraint_level_table = 2;
1704
1705    public final static int TOKEN_ALREADY_PROCESSED = 123;
1706
1707    // select distinct type
1708
1709    /**
1710     * @deprecated As of 1.7.3.3, replaced by {@link EUniqueRowFilterType#urfNone}
1711     */
1712    public final static int dtNone = 0;
1713
1714    /**
1715     * @deprecated As of 1.7.3.3, replaced by {@link EUniqueRowFilterType#urfDistinct}
1716     */
1717    public final static int dtDistinct = 1;
1718
1719    /**
1720     * @deprecated As of 1.7.3.3, replaced by {@link EUniqueRowFilterType#urfDistinctOn}
1721     */
1722    public final static int dtDistinctOn = 2;
1723
1724    /**
1725     * @deprecated As of 1.7.3.3, replaced by {@link EUniqueRowFilterType#urfAll}
1726     */
1727    public final static int dtAll = 3;
1728
1729    /**
1730     * @deprecated As of 1.7.3.3, replaced by {@link EUniqueRowFilterType#urfUnique}
1731     */
1732    public final static int dtUnique = 4;
1733
1734    /**
1735     * @deprecated As of 1.7.3.3, replaced by {@link EUniqueRowFilterType#urfDistinctRow}
1736     */
1737    public final static int dtDistinctRow = 5;
1738
1739    // TLzMssqlSetType
1740    public final static int mstUnknown = 0;
1741    public final static int mstLocalVar = 1;
1742    public final static int mstLocalVarCursor = 2;
1743    public final static int mstSetCmd = 3;
1744    public final static int mstXmlMethod = 4;
1745    public final static int mstSybaseLocalVar = 5;
1746
1747    // trigger firemode
1748    public final static int tfmFor = 0;
1749    public final static int tfmAfter = 1;
1750    public final static int tfmInsteadOf = 2;
1751    public final static int tfmBefore = 3;
1752    public final static int tfmNoCascadeBefore = 4;
1753    public final static int tReferencing = 5;
1754
1755    // TLzMssqlExecType = (metExecSp,metExecStringCmd,metExecStringCmdLinkServer,metNoExecKeyword);
1756    public final static int metExecSp = 0;
1757    public final static int metExecStringCmd = 1;
1758    public final static int metExecStringCmdLinkServer = 2;
1759    public final static int metNoExecKeyword = 3;
1760    public final static int metExecMload = 4;
1761
1762    // sql server execute type
1763     // public final static int execute_procedure_function = 1;
1764     // public final static int execute_character_string = 2;
1765
1766    //TLzUDFType = (
1767    public final static int uftUnknown = 0;
1768    public final static int uftScalar = 1;
1769    public final static int uftInlineTableValued = 2;
1770    public final static int uftMultiStatementTableValued = 3;
1771
1772    //TLzSortType = (srtNone,srtAsc,srtDesc);
1773    /**
1774     *  @deprecated As of v1.6.4.9, replaced by {@link ESortType}
1775     */
1776    public final static int srtNone = 0;
1777    /**
1778     *  @deprecated As of v1.6.4.9, replaced by {@link ESortType}
1779     */
1780    public final static int srtAsc = 1;
1781    /**
1782     *  @deprecated As of v1.6.4.9, replaced by {@link ESortType}
1783     */
1784    public final static int srtDesc = 2;
1785
1786    //TLzSortNulls = (srnNone,srnNullsFirst,srnNullsLast);
1787    public final static int srnNone = 0;
1788    public final static int srnNullsFirst = 1;
1789    public final static int srnNullsLast = 2;
1790
1791    public static int  LEXER_INIT_MAX_MATCHES = 1024*20*10*2;
1792
1793
1794
1795    
1796public static String newline = System.getProperty("line.separator");
1797
1798public static int mycomparetext(String p1,String p2){
1799        return p1.compareToIgnoreCase(p2);
1800    }
1801
1802public static boolean mysametext(String p1,String p2)
1803    {
1804        return (mycomparetext(p1,p2)==0);
1805    }
1806
1807    
1808public static boolean assigned(Object st){
1809    return (st != null);
1810}
1811
1812static void setTokenToIdentifier(TExpression expr){
1813    if (expr.getExpressionType() == EExpressionType.simple_object_name_t){
1814        if (expr.getObjectOperand().getEndToken() != null){
1815            expr.getObjectOperand().getEndToken().tokencode = ident;
1816            expr.getObjectOperand().getEndToken().tokentype = ETokenType.ttidentifier;
1817        }
1818    }else if (expr.getExpressionType() == EExpressionType.simple_source_token_t){
1819        expr.getSourcetokenOperand().tokencode = ident;
1820        expr.getSourcetokenOperand().tokentype = ETokenType.ttidentifier;
1821    }
1822}
1823
1824public  static void resetTokenChain(TSourceTokenList pSourceTokenList, int startPos){
1825        if(pSourceTokenList == null) return;
1826        if ((startPos < 0)||(startPos>=pSourceTokenList.size())) return;
1827
1828        if (pSourceTokenList.size() <= 0) return;
1829
1830
1831        TSourceToken lcPrevToken = null;
1832        if (startPos > 0){
1833            lcPrevToken = pSourceTokenList.get(startPos-1);
1834        }
1835        for (int i=startPos ; i<pSourceTokenList.size();i++) {
1836            pSourceTokenList.get(i).setPrevTokenInChain(lcPrevToken);
1837            if (i != pSourceTokenList.size() - 1){
1838                pSourceTokenList.get(i).setNextTokenInChain(pSourceTokenList.get(i+1));
1839            }
1840            lcPrevToken = pSourceTokenList.get(i);
1841        }
1842    }
1843
1844
1845/**
1846 * Extracts the string content from inside a SQL literal value.
1847 * 
1848 * Handles different types of SQL string literals:
1849 * - Standard quoted strings ('abc')
1850 * - Empty strings ('')
1851 * - Q-quoted strings (Q'[abc]')
1852 * - N-quoted strings (N'abc') 
1853 * - Dollar quoted strings ($$abc$$)
1854 *
1855 * For quoted strings, it removes the outer quotes and handles escaped quotes
1856 * by replacing '' and \' with single quotes.
1857 *
1858 * @param literalStr The SQL string literal to process
1859 * @return The string content without quotes and with escaped quotes converted to single quotes.
1860 *         Returns empty string for '', original string for non-literals or strings < 3 chars.
1861 */
1862public static String getStringInsideLiteral(String literalStr){
1863    if (literalStr.equalsIgnoreCase("''")) return "";
1864    if (literalStr.length() <3) return literalStr;
1865
1866    boolean isLiteral = false, isDollarStr = false;
1867  //  System.out.println(literalStr);
1868    int startindex = 1,endindex = 2;
1869    if (literalStr.startsWith("'")){
1870      startindex = 1;
1871      endindex = literalStr.length() - 1;
1872      isLiteral = true;
1873    }else if ((literalStr.length() >= 5)
1874            && ((literalStr.charAt(0) == 'q') || (literalStr.charAt(0) == 'Q'))
1875            && (literalStr.charAt(1) == '\'')
1876            && literalStr.endsWith("'")){
1877      startindex = 3;
1878      endindex = literalStr.length() - 2;
1879        isLiteral = true;
1880    }else if ((literalStr.length() >= 3)
1881            && ((literalStr.charAt(0) == 'n') || (literalStr.charAt(0) == 'N'))
1882            && (literalStr.charAt(1) == '\'')
1883            && literalStr.endsWith("'")){
1884        startindex = 2;
1885        endindex = literalStr.length() - 1;
1886        isLiteral = true;
1887    }else if (literalStr.toLowerCase(Locale.ROOT).startsWith("$$")){
1888        startindex = 3;
1889        endindex = literalStr.length() - 2;
1890        isLiteral = true;
1891        isDollarStr = true;
1892    }
1893
1894    if (isLiteral){
1895        if (isDollarStr) return  literalStr.substring(startindex,endindex);
1896        else
1897            return  literalStr.substring(startindex,endindex).replace("''","'").replace("\\'","'");
1898    }else{
1899        return literalStr;
1900    }
1901
1902}
1903
1904    public static String toHex(String arg, String charset) {
1905        String resultStr =arg;
1906        try {
1907            resultStr =  String.format("%040x", new BigInteger(1, arg.getBytes(charset)));
1908        }
1909        catch(UnsupportedEncodingException ex){
1910            System.out.println("Unsupported character set"+ex);
1911        }
1912
1913        return resultStr;
1914    }
1915
1916    public static String removeQuoteChar(String str){
1917      return getTextWithoutQuoted(str);
1918    }
1919    public static String getTextWithoutQuoted(String str){
1920        if ((str.length() > 1) && ((str.startsWith("`"))||(str.startsWith("'"))||(str.startsWith("["))||(str.startsWith("\"")))){
1921            return  str.substring(1, str.length() - 1);
1922        }else
1923            return  str;
1924    }
1925
1926    public static String removePrefixOrSuffixQuoteChar(String str){
1927        if ((str.length() > 1) && ((str.startsWith("`"))||(str.startsWith("'"))||(str.startsWith("["))||(str.startsWith("\"")))){
1928            return  str.substring(1, str.length());
1929        }else if ((str.length() > 1) && ((str.endsWith("`"))||(str.endsWith("'"))||(str.endsWith("["))||(str.endsWith("\"")))){
1930            return  str.substring(0, str.length()-1);
1931        }
1932            return  str;
1933    }
1934
1935
1936    public static String getLastPartOfQualifiedName(String str){
1937      if (str.length() == 0) return str;
1938      int  index = -1;
1939      for(int i = str.length() - 1; i>=0;i--){
1940          if (str.charAt(i) == '.'){
1941              index = i;
1942              break;
1943          }
1944      }
1945      if (index>=0){
1946          return str.substring(index+1,str.length());
1947      }else{
1948          return str;
1949      }
1950
1951    }
1952
1953    public static String getTextByTokenCode(int tokenCode){
1954        String retStr = "";
1955        switch (tokenCode){
1956            case TBaseType.rrw_select:
1957                retStr = "select";
1958                break;
1959            case TBaseType.rrw_delete:
1960                retStr = "delete";
1961                break;
1962            case TBaseType.rrw_insert:
1963                retStr = "insert";
1964                break;
1965            case TBaseType.rrw_update:
1966                retStr = "update";
1967                break;
1968            case TBaseType.rrw_create:
1969                retStr = "create";
1970                break;
1971            case TBaseType.rrw_drop:
1972                retStr = "drop";
1973                break;
1974            case TBaseType.rrw_alter:
1975                retStr = "alter";
1976                break;
1977            case TBaseType.rrw_merge:
1978                retStr = "merge";
1979                break;
1980            case TBaseType.rrw_grant:
1981                retStr = "grant";
1982                break;
1983            case TBaseType.rrw_revoke:
1984                retStr = "revoke";
1985                break;
1986            case TBaseType.rrw_commit:
1987                retStr = "commit";
1988                break;
1989            case TBaseType.rrw_rollback:
1990                retStr = "rollback";
1991                break;
1992            case TBaseType.rrw_execute:
1993                retStr = "execute";
1994                break;
1995            case TBaseType.rrw_explain:
1996                retStr = "explain";
1997                break;
1998            case TBaseType.rrw_prepare:
1999                retStr = "prepare";
2000                break;
2001            case TBaseType.rrw_couchbase_upsert:
2002                retStr = "upsert";
2003                break;
2004            case TBaseType.rrw_analyze:
2005                retStr = "analyze";
2006                break;
2007            case TBaseType.rrw_associate:
2008                retStr = "associate";
2009                break;
2010            case TBaseType.rrw_audit:
2011                retStr = "audit";
2012                break;
2013            case TBaseType.rrw_call:
2014                retStr = "call";
2015                break;
2016            case TBaseType.rrw_disassociate:
2017                retStr = "disassociate";
2018                break;
2019            case TBaseType.rrw_flashback:
2020                retStr = "flashback";
2021                break;
2022            case TBaseType.rrw_lock:
2023                retStr = "lock";
2024                break;
2025            case TBaseType.rrw_noaudit:
2026                retStr = "noaudit";
2027                break;
2028            case TBaseType.rrw_purge:
2029                retStr = "purge";
2030                break;
2031            case TBaseType.rrw_rename:
2032                retStr = "rename";
2033                break;
2034            case TBaseType.rrw_savepoint:
2035                retStr = "savepoint";
2036                break;
2037            case TBaseType.rrw_set:
2038                retStr = "set";
2039                break;
2040            case TBaseType.rrw_comment:
2041                retStr = "comment";
2042                break;
2043            case TBaseType.rrw_truncate:
2044                retStr = "truncate";
2045                break;
2046            case TBaseType.rrw_add:
2047                retStr = "add";
2048                break;
2049            case TBaseType.rrw_backup:
2050                retStr = "backup";
2051                break;
2052            case TBaseType.rrw_begin:
2053                retStr = "begin";
2054                break;
2055            case TBaseType.rrw_break:
2056                retStr = "break";
2057                break;
2058            case TBaseType.rrw_bulk:
2059                retStr = "bulk";
2060                break;
2061            case TBaseType.rrw_checkpoint:
2062                retStr = "checkpoint";
2063                break;
2064            case TBaseType.rrw_close:
2065                retStr = "close";
2066                break;
2067            case TBaseType.rrw_continue:
2068                retStr = "continue";
2069                break;
2070            case TBaseType.rrw_dbcc:
2071                retStr = "dbcc";
2072                break;
2073            case TBaseType.rrw_deallocate:
2074                retStr = "deallocate";
2075                break;
2076            case TBaseType.rrw_declare:
2077                retStr = "declare";
2078                break;
2079            case TBaseType.rrw_deny:
2080                retStr = "deny";
2081                break;
2082            case TBaseType.rrw_disable:
2083                retStr = "disable";
2084                break;
2085            case TBaseType.rrw_enable:
2086                retStr = "enable";
2087                break;
2088            case TBaseType.rrw_end:
2089                retStr = "end";
2090                break;
2091            case TBaseType.rrw_exec:
2092                retStr = "exec";
2093                break;
2094            case TBaseType.rrw_fetch:
2095                retStr = "fetch";
2096                break;
2097            case TBaseType.rrw_go:
2098                retStr = "go";
2099                break;
2100            case TBaseType.rrw_goto:
2101                retStr = "goto";
2102                break;
2103            case TBaseType.rrw_if:
2104                retStr = "if";
2105                break;
2106            case TBaseType.rrw_kill:
2107                retStr = "kill";
2108                break;
2109            case TBaseType.rw_locktable:
2110                retStr = "locktable";
2111                break;
2112            case TBaseType.rrw_open:
2113                retStr = "open";
2114                break;
2115            case TBaseType.rrw_print:
2116                retStr = "print";
2117                break;
2118            case TBaseType.rrw_raiserror:
2119                retStr = "raiserror";
2120                break;
2121            case TBaseType.rrw_readtext:
2122                retStr = "readtext";
2123                break;
2124            case TBaseType.rrw_receive:
2125                retStr = "receive";
2126                break;
2127            case TBaseType.rrw_reconfigure:
2128                retStr = "reconfigure";
2129                break;
2130            case TBaseType.rrw_restore:
2131                retStr = "restore";
2132                break;
2133            case TBaseType.rrw_return:
2134                retStr = "return";
2135                break;
2136            case TBaseType.rrw_revert:
2137                retStr = "revert";
2138                break;
2139            case TBaseType.rrw_save:
2140                retStr = "save";
2141                break;
2142            case TBaseType.rrw_setuser:
2143                retStr = "setuser";
2144                break;
2145            case TBaseType.rrw_shutdown:
2146                retStr = "shutdown";
2147                break;
2148            case TBaseType.rrw_sqlserver_throw:
2149                retStr = "throw";
2150                break;
2151            case TBaseType.rrw_updatetext:
2152                retStr = "updatetext";
2153                break;
2154            case TBaseType.rrw_use:
2155                retStr = "use";
2156                break;
2157            case TBaseType.rrw_waitfor:
2158                retStr = "waitfor";
2159                break;
2160            case TBaseType.rrw_while:
2161                retStr = "while";
2162                break;
2163            case TBaseType.rrw_with:
2164                retStr = "with";
2165                break;
2166            case TBaseType.rrw_writetext:
2167                retStr = "writetext";
2168                break;
2169            case TBaseType.rrw_move:
2170                retStr = "move";
2171                break;
2172            case TBaseType.rrw_send:
2173                retStr = "send";
2174                break;
2175            case TBaseType.rrw_allocate:
2176                retStr = "allocate";
2177                break;
2178            case TBaseType.rrw_case:
2179                retStr = "case";
2180                break;
2181            case TBaseType.rrw_connect:
2182                retStr = "connect";
2183                break;
2184            case TBaseType.rrw_describe:
2185                retStr = "describe";
2186                break;
2187            case TBaseType.rrw_disconnect:
2188                retStr = "disconnect";
2189                break;
2190            case TBaseType.rrw_flush:
2191                retStr = "flush";
2192                break;
2193            case TBaseType.rrw_for:
2194                retStr = "for";
2195                break;
2196            case TBaseType.rrw_free:
2197                retStr = "free";
2198                break;
2199            case TBaseType.rrw_get:
2200                retStr = "get";
2201                break;
2202            case TBaseType.rrw_include:
2203                retStr = "include";
2204                break;
2205            case TBaseType.rrw_iterate:
2206                retStr = "iterate";
2207                break;
2208            case TBaseType.rrw_leave:
2209                retStr = "leave";
2210                break;
2211            case TBaseType.rrw_loop:
2212                retStr = "loop";
2213                break;
2214            case TBaseType.rrw_refresh:
2215                retStr = "refresh";
2216                break;
2217            case TBaseType.rrw_release:
2218                retStr = "release";
2219                break;
2220            case TBaseType.rrw_repeat:
2221                retStr = "repeat";
2222                break;
2223            case TBaseType.rrw_resignal:
2224                retStr = "resignal";
2225                break;
2226            case TBaseType.rrw_signal:
2227                retStr = "signal";
2228                break;
2229            case TBaseType.rrw_terminate:
2230                retStr = "terminate";
2231                break;
2232            case TBaseType.rrw_abort:
2233                retStr = "abort";
2234                break;
2235            case TBaseType.rrw_greenplum_analyse:
2236                retStr = "analyse";
2237                break;
2238            case TBaseType.rrw_load:
2239                retStr = "load";
2240                break;
2241            case TBaseType.rrw_postgresql_reassign:
2242                retStr = "reassign";
2243                break;
2244            case TBaseType.rrw_postgresql_reindex:
2245                retStr = "reindex";
2246                break;
2247            case TBaseType.rrw_reset:
2248                retStr = "reset";
2249                break;
2250            case TBaseType.rrw_show:
2251                retStr = "show";
2252                break;
2253            case TBaseType.rrw_start:
2254                retStr = "start";
2255                break;
2256            case TBaseType.rrw_greenplum_vacuum:
2257                retStr = "vacuum";
2258                break;
2259            case TBaseType.rrw_values:
2260                retStr = "values";
2261                break;
2262            case TBaseType.rrw_do:
2263                retStr = "do";
2264                break;
2265            case TBaseType.rrw_replace:
2266                retStr = "replace";
2267                break;
2268            case TBaseType.rrw_hana_export:
2269                retStr = "rrw_hana_export";
2270                break;
2271            case TBaseType.rrw_hana_import:
2272                retStr = "rrw_hana_import";
2273                break;
2274            case TBaseType.rrw_hana_recover:
2275                retStr = "rrw_recover";
2276                break;
2277            case TBaseType.rrw_hana_unload:
2278                retStr = "rrw_unload";
2279                break;
2280            case TBaseType.rrw_unlock:
2281                retStr = "unlock";
2282                break;
2283            case TBaseType.rrw_database:
2284                retStr = "database";
2285                break;
2286            case TBaseType.rrw_stop:
2287                retStr = "stop";
2288                break;
2289            case TBaseType.rrw_optimize:
2290                retStr = "optimize";
2291                break;
2292            case TBaseType.rrw_handler:
2293                retStr = "handler";
2294                break;
2295            case TBaseType.rrw_checksum:
2296                retStr = "checksum";
2297                break;
2298            case TBaseType.rrw_check:
2299                retStr = "check";
2300                break;
2301            case TBaseType.rrw_change:
2302                retStr = "change";
2303                break;
2304            case TBaseType.rrw_cache:
2305                retStr = "cache";
2306                break;
2307            case TBaseType.rrw_repair:
2308                retStr = "repair";
2309                break;
2310
2311//            case TBaseType.rrw_hana_unset:
2312//                retStr = "rrw_unset";
2313//                break;
2314//            case TBaseType.rrw_hana_upsert:
2315//                retStr = "rrw_upsert";
2316//                break;
2317//            case TBaseType.rrw_couchbase_build:
2318//                retStr = "build";
2319//                break;
2320//            case TBaseType.rrw_couchbase_infer:
2321//                retStr = "infer";
2322//                break;
2323            default:
2324                retStr = "**";
2325                break;
2326        }
2327
2328        return  retStr;
2329
2330    }
2331
2332    public static String stringBlock(int line, int column) {
2333        if (line >1000){
2334            // 在前面增加空行是为了准确定位 sql 在原来文件中的位置。
2335            // 为避免大文件中 sql block 出现在非常后面的位置,导致前面填充非常多的空行,从而引起 TSourcetoken 占用太多的内容,进而引起 out of memory
2336            // 限定最多在前面加 1000 个空行,这可能会导致地位不准确,但避免了 out of memory 的问题
2337            // https://e.gitee.com/gudusoft/projects/151613/tasks/list?issue_type_category=task&issue=I6RLR0
2338            line = 1000;
2339        }
2340        StringBuilder stringBuilder = new StringBuilder();
2341        if (line > 0) {
2342            for (int n = 1; n <= line; n++) {
2343                stringBuilder.append("\n");
2344            }
2345        }
2346        if (column > 0) {
2347            for (int n = 1; n <= column; n++) {
2348                stringBuilder.append(" ");
2349            }
2350        }
2351        return stringBuilder.toString();
2352    }
2353
2354    public static String stringBlock(int lineNo, int columnNo, int quotedSymbolLength, String quotedStr){
2355        // Windows: \r\n, Mac: \r, Linux: \n
2356        // CR(0D) -> \r, LF(0A) -> \n
2357
2358        String lineStr = "";
2359        char c;
2360        boolean prevCharIsCR = false;
2361        int x=lineNo,y=columnNo - 1 +quotedSymbolLength;
2362        for ( int i=quotedSymbolLength; i<quotedStr.length();i++){
2363            c = quotedStr.charAt(i);
2364            if (c=='\r'){
2365                x++;
2366                y = 0;
2367                prevCharIsCR = true;
2368            }else if (c=='\n'){
2369                if (!prevCharIsCR){
2370                    x++;
2371                    y=0;
2372                }
2373                prevCharIsCR = false;
2374            }else if (c==' '){
2375                y++;
2376                prevCharIsCR = false;
2377            }else if (c=='\t'){
2378                y = y + TABSIZE;
2379                prevCharIsCR = false;
2380            }else{
2381                break;
2382            }
2383        }
2384        return stringBlock(x-1,y);
2385    }
2386
2387    private static final Map<String,Integer> cryptFunctions = new java.util.concurrent.ConcurrentHashMap<String,Integer>( );
2388
2389    public static void clearCryptFunctions(){
2390        cryptFunctions.clear();
2391    }
2392
2393    /**
2394     * In order to replace key argument used in some user defined functions when generate sql text from TCustomSqlStatement.asCanonical()
2395     * <br> We use this function to set the functions the need to be process.
2396     * <br>
2397     * <br> For example, if we want to replace 'abcdefg' argument in the following f_decrypt function when calling TCustomSqlStatement.asCanonical()
2398     * <br> select f_decrypt(name,'abcdefg') from t
2399     * <br> we call {@link #addToCryptFunctions(String, Integer)} with 'f_decrypt' refer to the function name and 2 refer to
2400     * the second argument that need to be replaced.
2401     *
2402     * <br> This function can be call multi-times to set multi-functions.
2403     *
2404     * @param functionName
2405     * @param keyPosition
2406     */
2407    public static void addToCryptFunctions(String functionName, Integer keyPosition){
2408        cryptFunctions.put(functionName.toUpperCase(Locale.ROOT),keyPosition);
2409    }
2410
2411    public static Integer searchCryptFunction(String functionName){
2412        Integer i = cryptFunctions.get(getLastPartOfQualifiedName(functionName.toUpperCase(Locale.ROOT)));
2413        if (i == null) return 0;
2414        return i;
2415    }
2416
2417
2418    private static final Map<String,Integer> oracleTableProps;
2419
2420    static {
2421        Map<String,Integer> props = new java.util.HashMap<String,Integer>();
2422        props.put("CACHE",10);
2423        props.put("CLUSTER",11);
2424        props.put("COMPRESS",12);
2425        props.put("FILESYSTEM_LIKE_LOGGING",20);
2426        props.put("INITRANS",30);
2427        props.put("LOB",35);
2428        props.put("LOGGING",36);
2429        props.put("MAXTRANS",40);
2430        props.put("NOCACHE",45);
2431        props.put("NOCOMPRESS",46);
2432        props.put("NOLOGGING",47);
2433        props.put("NOPARALLEL",48);
2434        props.put("ON",56);
2435        props.put("ORGANIZATION",55);
2436        props.put("PARALLEL",60);
2437        props.put("PARTITION",61);
2438        props.put("PCTFREE",64);
2439        props.put("PCTUSED",66);
2440        props.put("SEGMENT",70);
2441        props.put("STORAGE",73);
2442        props.put("TABLESPACE",80);
2443        oracleTableProps = java.util.Collections.unmodifiableMap(props);
2444    }
2445
2446    public static boolean searchOracleTablePros(String str){
2447        Integer i = oracleTableProps.get(str.toUpperCase(Locale.ROOT));
2448        if (i == null) return false;
2449        return i>0;
2450    }
2451
2452    public static boolean isSupportLateralColumn(EDbVendor pDbvendor){
2453        return (pDbvendor != EDbVendor.dbvmssql);
2454//        return ((pDbvendor == EDbVendor.dbvsnowflake)||(pDbvendor == EDbVendor.dbvteradata)||(pDbvendor == EDbVendor.dbvredshift)
2455//                ||(pDbvendor == EDbVendor.dbvsparksql));
2456    }
2457    // configuration
2458    public static boolean c_createTableStrictParsing = false;
2459    public static int TABSIZE = 2;
2460
2461    public static boolean comparyStringArray(String[] actualText, String[] requiredText){
2462        boolean ret = true;
2463        if (actualText.length != requiredText.length){
2464            System.out.println("Total lines in not equal, required text: "+ requiredText.length+", Actual SQL: "+actualText.length);
2465            return false;
2466        }
2467
2468        for(int i=0;i<requiredText.length;i++){
2469            if (requiredText[i].equalsIgnoreCase(actualText[i])){
2470                continue;
2471            }else{
2472                System.out.println("Text of Line:"+(i+1)+" is not equal");
2473                System.out.println("Actual   Text:"+actualText[i]);
2474                System.out.println("Required Text:"+requiredText[i]);
2475                ret = false;
2476                break;
2477            }
2478        }
2479        return ret;
2480    }
2481
2482    public static boolean compareStringBuilderToFile(StringBuilder actual, String requiredSourceFileName){
2483        String outStr = "";
2484        String[] requiredSource = null,actualString=null;
2485
2486        try {
2487            outStr = TBaseType.readFile(requiredSourceFileName, Charset.defaultCharset());
2488            requiredSource = outStr.trim().split("\r?\n");
2489
2490        } catch (IOException e) {
2491            e.printStackTrace();
2492        }
2493
2494        actualString = actual.toString().trim().split("\r?\n");
2495
2496        return TBaseType.comparyStringArray(actualString,requiredSource);
2497    }
2498
2499    public static  String readFromTextfile( File file )
2500    {
2501        try
2502        {
2503            ByteArrayOutputStream out = new ByteArrayOutputStream( 4096 );
2504            byte[] tmp = new byte[4096];
2505            InputStream is = new BufferedInputStream( new FileInputStream( file ) );
2506            while ( true )
2507            {
2508                int r = is.read( tmp );
2509                if ( r == -1 )
2510                    break;
2511                out.write( tmp, 0, r );
2512            }
2513            byte[] bytes = out.toByteArray( );
2514            is.close( );
2515            out.close( );
2516            String content = new String( bytes );
2517            return content.trim( );
2518        }
2519        catch ( IOException e )
2520        {
2521            e.printStackTrace( );
2522        }
2523        return null;
2524    }
2525
2526    /**
2527     * Normalizes dataflow XML output for comparison by removing volatile fields
2528     * that change between runs or grammar updates but don't affect functionality.
2529     *
2530     * Normalized fields:
2531     * - id, processId, processIds, procedureId: Auto-generated IDs
2532     * - coordinate: Position info that may vary
2533     * - state:\d+: Parser state numbers that shift when grammar changes
2534     *
2535     * @param dataflowXml The dataflow XML string to normalize
2536     * @return Normalized XML string for comparison
2537     */
2538    public static String normalizeDataflowForComparison(String dataflowXml) {
2539        return dataflowXml
2540                .replaceAll("id=\".+?\"", "id=\"\"")
2541                .replaceAll("processId=\".+?\"", "processId=\"\"")
2542                .replaceAll("processIds=\".+?\"", "processIds=\"\"")
2543                .replaceAll("procedureId=\".+?\"", "procedureId=\"\"")
2544                .replaceAll("coordinate=\".+?\"", "coordinate=\"\"")
2545                .replaceAll("state:\\d+", "state:NNN");  // Parser state numbers change with grammar updates
2546    }
2547
2548    public static boolean compareStringsLineByLine(String str1, String str2) {
2549        // Split the strings into lines
2550        String[] lines1 = str1.split("\\r?\\n");
2551        String[] lines2 = str2.split("\\r?\\n");
2552
2553        // Compare the lines
2554        int numLines = Math.min(lines1.length, lines2.length);
2555        for (int i = 0; i < numLines; i++) {
2556            if (!lines1[i].equalsIgnoreCase(lines2[i])) {
2557                System.out.println("Mismatch at line " + (i + 1)+"\n"+lines1[i]+"\n"+lines2[i]);
2558                return false;
2559            }
2560        }
2561
2562        // Check if any lines are remaining
2563        if (lines1.length != lines2.length) {
2564            System.out.println("Lines mismatch");
2565            return false;
2566        }
2567
2568        return true;
2569    }
2570
2571    public static String readFile(String path, Charset encoding)
2572            throws IOException
2573    {
2574        byte[] encoded = Files.readAllBytes(Paths.get(path));
2575        return new String(encoded, encoding);
2576    }
2577
2578    /**
2579     * return an array list in text between ( and ), which is start token and end token, like this: ( option1=value1, option2=value2, option3=values )
2580     * the result is an array like this:
2581     * <br>
2582     * <br>option1=value1
2583     * <br>option2=value2
2584     * <br>option3=value3
2585     *
2586     * @param startToken
2587     * @param endToken
2588     * @param includeNonSolidToken
2589     * @return
2590     */
2591    public static List<String> getArrayListBetweenTokens(TSourceToken startToken, TSourceToken endToken, boolean includeNonSolidToken){
2592        if ((startToken == null) || (endToken == null)) return null;
2593        if (startToken.container == null) return null;
2594        String textBetweenTokens = "";
2595        int nested=0;
2596
2597        // get text between 2 tokens, doesn't include the start and end token
2598        for(int i=startToken.posinlist+1;i<endToken.posinlist;i++){
2599            TSourceToken st = startToken.container.get(i);
2600            if ((!includeNonSolidToken)&&(st.isnonsolidtoken())) continue;
2601            if (st.tokencode == '(') nested++;
2602            if (st.tokencode == ')') nested--;
2603            if (nested > 0){
2604                // , and = inside () is not the separator to separate the options
2605                if (st.tokencode == ','){
2606                    st.setAstext(";");
2607                }else if (st.tokencode == '='){
2608                    st.setAstext("?");
2609                }
2610            }
2611            if (st.tokencode == TBaseType.sconst) {
2612                if (st.toString().indexOf(",") > 0) {
2613                    st.setAstext(st.getAstext().replace(',', ';'));
2614                } else if (st.toString().indexOf("=") > 0) {
2615                    st.setAstext(st.getAstext().replace('=', '?'));
2616                }
2617            }
2618
2619            textBetweenTokens = textBetweenTokens + st.toString();
2620        }
2621
2622            if (textBetweenTokens != ""){
2623                return Arrays.asList(textBetweenTokens.split(","));
2624            }else
2625                return null;
2626    }
2627
2628    /**
2629     * The input optionList is in format like this:
2630     *
2631     *       <br>
2632     *       <br>option1=value1
2633     *       <br>option2=value2
2634     *       <br>option3=value3
2635     *
2636     *  when optionName is option1, value1 should be returned.
2637     *
2638     * @param optionList
2639     * @param optionName
2640     * @return
2641     */
2642    public static String getOption(List<String> optionList,String optionName){
2643        if (optionList == null)  return null;
2644        String optionValue = "";
2645        List<String> nameValues = null;
2646        for(int i=0;i<optionList.size();i++){
2647            String str = optionList.get(i).trim();
2648            nameValues = Arrays.asList(str.split("="));
2649            if ((nameValues != null)&&(nameValues.size() == 2)){
2650                if (nameValues.get(0).trim().equalsIgnoreCase(optionName)){
2651                    optionValue = nameValues.get(1);
2652                    break;
2653                }
2654            }
2655        }
2656
2657        return optionValue;
2658    }
2659
2660    public static List<String> getOptionNames(List<String> optionList){
2661        if (optionList == null)  return null;
2662        String optionNameStr = "";
2663        List<String> optionNames = null;
2664        for(int i=0;i<optionList.size();i++){
2665            String str = optionList.get(i).trim();
2666            optionNames = Arrays.asList(str.split("="));
2667            if ((optionNames != null)&&(optionNames.size() == 2)){
2668                optionNameStr = optionNameStr+optionNames.get(0)+',';
2669            }
2670        }
2671
2672        return Arrays.asList(optionNameStr.split(","));
2673    }
2674
2675    public static String numberOfSpace(int pNum,char space){
2676        String ret="";
2677        for(int i=0;i<pNum;i++){
2678            ret = ret+space;
2679        }
2680        return ret;
2681    }
2682
2683
2684    protected static List<TLog> logs = new LinkedList<TLog>();
2685
2686    public static int logSize(){
2687        return logs.size();
2688    }
2689
2690
2691    public static void log(String message, int type){
2692        TBaseType.log(message,type,-1,-1);
2693    }
2694    public static void log(String message, int type, TParseTreeNode node){
2695        TBaseType.log(message,type,node.getStartToken().lineNo,node.getStartToken().columnNo);
2696    }
2697    public static void log(String message, int type, TSourceToken token){
2698        TBaseType.log(message,type,token.lineNo,token.columnNo);
2699    }
2700    public static void log(String message, int type, long line, long column){
2701        if (!TLog.isEnabled(type)) return;
2702
2703        String fullMessage = message;
2704
2705        if (DUMP_RESOLVER_LOG_TO_CONSOLE){
2706            // 获取调用栈
2707            StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
2708            // // // 索引3是调用log方法的类(索引0是getStackTrace,1是log方法本身,2是直接调用log的方法)
2709            StackTraceElement caller = stackTrace[3];
2710
2711            String location = String.format("%s:%d", caller.getFileName(), caller.getLineNumber());
2712
2713            fullMessage = String.format("[%s] %s", location, message);
2714        }
2715
2716        TLog log = new TLog();
2717        log.message = fullMessage;
2718        log.type = type;
2719        log.line = line;
2720        log.column = column;
2721        Timestamp timestamp = new Timestamp(System.currentTimeMillis());
2722        log.timestamp = TLog.sdf3.format(timestamp);
2723
2724        logs.add(log);
2725    }
2726
2727     public static void dumpLogs(boolean force){
2728        if ((!DUMP_RESOLVER_LOG_TO_CONSOLE)&&(!force)) return;
2729
2730        System.out.print("\nDump logs...\n");
2731         for (TLog log : logs){
2732             System.out.println(log);
2733         }
2734         System.out.print("\nEnd of dump logs\n\n");
2735     }
2736
2737     public static void dumpLogsToFile(String fileName){
2738         FileWriter fw = null;
2739         try {
2740             fw = new FileWriter(fileName, true);
2741             BufferedWriter bw = new BufferedWriter(fw);
2742             for (TLog log : logs){
2743                 bw.write(log.toString());
2744                 bw.newLine();
2745             }
2746             bw.close();
2747         } catch (IOException e) {
2748             e.printStackTrace();
2749         }
2750     }
2751
2752    public static String dumpLogsToString(){
2753        StringBuilder sb = new StringBuilder();
2754        for (TLog log : logs){
2755            sb.append (log.toString()+TBaseType.newline);
2756        }
2757        return sb.toString();
2758    }
2759
2760    /**
2761     * Calculates statistics for SQL files within a given directory.
2762     *
2763     * @param directoryPaths A list of paths to directories to scan recursively.
2764     * @param timeInMillis The time taken to process the files in milliseconds. If 0, speed calculation is skipped.
2765     */
2766    public static void calculateSqlLinesStats(List<String> directoryPaths, long timeInMillis) {
2767        AtomicLong totalLines = new AtomicLong(0);
2768        AtomicLong totalChars = new AtomicLong(0);
2769        AtomicLong totalFiles = new AtomicLong(0);
2770        AtomicLong errorFiles = new AtomicLong(0);
2771
2772        for (String dirPath : directoryPaths) {
2773            Path startPath = Paths.get(dirPath);
2774            if (!Files.isDirectory(startPath)) {
2775                System.err.println("Warning: Path is not a directory, skipping: " + dirPath);
2776                continue;
2777            }
2778            try (Stream<Path> stream = Files.walk(startPath)) {
2779                stream.filter(path -> path.toString().toLowerCase(Locale.ROOT).endsWith(".sql"))
2780                      .filter(Files::isRegularFile)
2781                      .forEach(filePath -> {
2782                          totalFiles.incrementAndGet();
2783                          try {
2784                              // Use our safe reading method
2785                              List<String> lines = safelyReadLines(filePath);
2786                              if (lines.isEmpty()) {
2787                                  System.out.println("Note: Empty file: " + filePath);
2788                              } else {
2789                                  totalLines.addAndGet(lines.size());
2790                                  lines.forEach(line -> totalChars.addAndGet(line.length()));
2791                              }
2792                          } catch (Exception e) {
2793                              errorFiles.incrementAndGet();
2794                              System.err.println("Error processing file " + filePath + ": " + e.getMessage());
2795                          }
2796                      });
2797            } catch (IOException e) {
2798                System.err.println("Error walking the directory " + dirPath + ": " + e.getMessage());
2799            }
2800        }
2801
2802        long finalTotalLines = totalLines.get();
2803        long finalTotalChars = totalChars.get();
2804
2805        System.out.println("Total SQL files found: " + totalFiles.get());
2806        System.out.println("Files with processing errors: " + errorFiles.get());
2807
2808        if (finalTotalLines == 0) {
2809            System.out.println("No .sql files found or files are empty in the specified directories.");
2810            return;
2811        }
2812
2813        double averageLineLength = (double) finalTotalChars / finalTotalLines;
2814
2815        System.out.printf("Total lines of code in .sql files: %d%n", finalTotalLines);
2816        System.out.printf("Average line length: %.2f characters%n", averageLineLength);
2817
2818        if (timeInMillis > 0) {
2819            // Normalize total lines based on an 80-character average line length
2820            if (averageLineLength > 0) { // Avoid division by zero if averageLineLength is somehow 0
2821                 double normalizedTotalLines = (double) finalTotalChars / 80.0;
2822                 double timeInSeconds = timeInMillis / 1000.0;
2823                 double linesPerSecond = normalizedTotalLines / timeInSeconds;
2824                 System.out.printf("Processing speed (normalized to 80 chars/line): %.2f lines/second%n", linesPerSecond);
2825            } else {
2826                System.out.println("Cannot calculate processing speed: Average line length is zero.");
2827            }
2828        }
2829    }
2830
2831    /**
2832     * Attempts to detect the encoding of a file by checking for BOMs and content patterns.
2833     * 
2834     * @param filePath The path to the file
2835     * @return The detected Charset, or ISO_8859_1 as a fallback
2836     */
2837    private static Charset detectFileEncoding(Path filePath) {
2838        try {
2839            // Try to determine encoding from BOM or content
2840            byte[] bytes = Files.readAllBytes(filePath);
2841            
2842            // Empty file check
2843            if (bytes.length == 0) {
2844                return StandardCharsets.UTF_8; // Default for empty files
2845            }
2846            
2847            // Check for BOM markers
2848            if (bytes.length >= 3 && 
2849                (bytes[0] & 0xFF) == 0xEF && 
2850                (bytes[1] & 0xFF) == 0xBB && 
2851                (bytes[2] & 0xFF) == 0xBF) {
2852                return StandardCharsets.UTF_8; // UTF-8 with BOM
2853            }
2854            
2855            if (bytes.length >= 2 && 
2856                (bytes[0] & 0xFF) == 0xFE && 
2857                (bytes[1] & 0xFF) == 0xFF) {
2858                return StandardCharsets.UTF_16BE; // UTF-16 Big Endian
2859            }
2860            
2861            if (bytes.length >= 2 && 
2862                (bytes[0] & 0xFF) == 0xFF && 
2863                (bytes[1] & 0xFF) == 0xFE) {
2864                if (bytes.length >= 4 && bytes[2] == 0 && bytes[3] == 0) {
2865                    return Charset.forName("UTF-32LE"); // UTF-32 Little Endian
2866                }
2867                return StandardCharsets.UTF_16LE; // UTF-16 Little Endian
2868            }
2869            
2870            if (bytes.length >= 4 && 
2871                (bytes[0] & 0xFF) == 0x00 && 
2872                (bytes[1] & 0xFF) == 0x00 && 
2873                (bytes[2] & 0xFF) == 0xFE && 
2874                (bytes[3] & 0xFF) == 0xFF) {
2875                return Charset.forName("UTF-32BE"); // UTF-32 Big Endian
2876            }
2877            
2878            // No BOM found, try to guess based on content
2879            // This is a very simplified approach - for real detection you'd want
2880            // a dedicated library like juniversalchardet
2881            
2882            // Check if file appears to be valid UTF-8
2883            if (isLikelyUtf8(bytes)) {
2884                return StandardCharsets.UTF_8;
2885            }
2886            
2887            // If the file is very small and contains only ASCII chars, use UTF-8
2888            if (bytes.length < 10 && isAscii(bytes)) {
2889                return StandardCharsets.UTF_8;
2890            }
2891            
2892            // Default to ISO-8859-1 as it can read any byte sequence without errors
2893            return StandardCharsets.ISO_8859_1;
2894            
2895        } catch (IOException e) {
2896            // If we can't read the file to detect encoding, use ISO-8859-1 as fallback
2897            return StandardCharsets.ISO_8859_1;
2898        }
2899    }
2900    
2901    /**
2902     * Checks if a byte array contains only ASCII characters (0-127)
2903     */
2904    private static boolean isAscii(byte[] bytes) {
2905        for (byte b : bytes) {
2906            if ((b & 0xFF) > 127) {
2907                return false;
2908            }
2909        }
2910        return true;
2911    }
2912    
2913    /**
2914     * Simple check if content appears to be valid UTF-8
2915     * This doesn't guarantee it's UTF-8, but helps identify obvious UTF-8 content
2916     */
2917    private static boolean isLikelyUtf8(byte[] bytes) {
2918        int i = 0;
2919        while (i < bytes.length) {
2920            if ((bytes[i] & 0x80) == 0) { // 0xxxxxxx - ASCII character
2921                i++;
2922            } else if ((bytes[i] & 0xE0) == 0xC0) { // 110xxxxx - 2 byte sequence
2923                if (i + 1 >= bytes.length || (bytes[i + 1] & 0xC0) != 0x80) {
2924                    return false;
2925                }
2926                i += 2;
2927            } else if ((bytes[i] & 0xF0) == 0xE0) { // 1110xxxx - 3 byte sequence
2928                if (i + 2 >= bytes.length || (bytes[i + 1] & 0xC0) != 0x80 || (bytes[i + 2] & 0xC0) != 0x80) {
2929                    return false;
2930                }
2931                i += 3;
2932            } else if ((bytes[i] & 0xF8) == 0xF0) { // 11110xxx - 4 byte sequence
2933                if (i + 3 >= bytes.length || (bytes[i + 1] & 0xC0) != 0x80 || (bytes[i + 2] & 0xC0) != 0x80 || (bytes[i + 3] & 0xC0) != 0x80) {
2934                    return false;
2935                }
2936                i += 4;
2937            } else {
2938                return false; // Invalid UTF-8 byte sequence
2939            }
2940        }
2941        return true;
2942    }
2943    
2944    /**
2945     * Reads lines from a file safely, handling different encodings
2946     * 
2947     * @param filePath The path to the file
2948     * @return List of lines or empty list if file cannot be read
2949     */
2950    private static List<String> safelyReadLines(Path filePath) {
2951        try {
2952            Charset detectedCharset = detectFileEncoding(filePath);
2953            
2954            // First attempt - use detected charset
2955            try {
2956                return Files.readAllLines(filePath, detectedCharset);
2957            } catch (IOException firstAttemptError) {
2958                // If that fails, try again with a more forgiving approach for small files
2959                if (Files.size(filePath) <= 4) { // Very small file
2960                    try (FileChannel channel = FileChannel.open(filePath, StandardOpenOption.READ)) {
2961                        ByteBuffer buffer = ByteBuffer.allocate((int)channel.size());
2962                        channel.read(buffer);
2963                        buffer.flip();
2964                        
2965                        // We won't try to interpret - just count as a single line if not empty
2966                        if (buffer.hasRemaining()) {
2967                            return Collections.singletonList("");
2968                        } else {
2969                            return Collections.emptyList();
2970                        }
2971                    } catch (IOException e) {
2972                        return Collections.emptyList();
2973                    }
2974                }
2975                
2976                // Try with ISO-8859-1 as last resort
2977                try {
2978                    return Files.readAllLines(filePath, StandardCharsets.ISO_8859_1);
2979                } catch (IOException lastAttemptError) {
2980                    System.err.println("Failed to read file (all encoding attempts failed): " + filePath);
2981                    return Collections.emptyList();
2982                }
2983            }
2984        } catch (IOException e) {
2985            System.err.println("Error accessing file: " + filePath + " - " + e.getMessage());
2986            return Collections.emptyList();
2987        }
2988    }
2989
2990    /**
2991     * Efficiently removes delimiters from SQL identifiers without unnecessary string allocations.
2992     * @param str The input string
2993     * @param leftDelim Left delimiter character
2994     * @param rightDelim Right delimiter character
2995     * @param doublequote Whether to remove double quotes
2996     * @return The string with delimiters removed, or the original string if no delimiters present
2997     */
2998    public static String removeDelimiters(String str, char leftDelim, char rightDelim, boolean doublequote) {
2999        if (str == null || str.isEmpty()) {
3000            return str;
3001        }
3002
3003        // Quick check if delimiters exist to avoid unnecessary processing
3004        boolean hasLeftDelim = str.indexOf(leftDelim) >= 0;
3005        boolean hasRightDelim = str.indexOf(rightDelim) >= 0;
3006        boolean hasDoubleQuote = doublequote && str.indexOf('"') >= 0;
3007
3008        if (!hasLeftDelim && !hasRightDelim && !hasDoubleQuote) {
3009            return str; // No delimiters found, return original string
3010        }
3011
3012        // We have at least one delimiter to remove
3013        StringBuilder sb = new StringBuilder(str.length());
3014        for (int i = 0; i < str.length(); i++) {
3015            char c = str.charAt(i);
3016            if (c == leftDelim || c == rightDelim || (doublequote && c == '"')) {
3017                // Skip this character
3018                continue;
3019            }
3020            sb.append(c);
3021        }
3022
3023        return sb.toString();
3024    }
3025
3026
3027    static public boolean verifyScript(EDbVendor dbVendor, String src, String target, boolean removeTrailingSemicolon){
3028        if (src == null || target == null) return false;
3029        String normalizedSrc = gudusoft.gsqlparser.util.RegexEquivalents.removeWhitespace(src).toLowerCase(Locale.ROOT);
3030        String normalizedTarget = gudusoft.gsqlparser.util.RegexEquivalents.removeWhitespace(target).toLowerCase(Locale.ROOT);
3031        if (removeTrailingSemicolon){
3032            normalizedSrc = gudusoft.gsqlparser.util.RegexEquivalents.stripTrailingSemicolons(normalizedSrc);
3033            normalizedTarget = gudusoft.gsqlparser.util.RegexEquivalents.stripTrailingSemicolons(normalizedTarget);
3034        }
3035        if (!normalizedSrc.equals(normalizedTarget)) {
3036            // Find first differing character
3037            int i = 0;
3038            while (i < normalizedSrc.length() && i < normalizedTarget.length() &&
3039                    normalizedSrc.charAt(i) == normalizedTarget.charAt(i)) {
3040                i++;
3041            }
3042
3043            // Extract up to 20 chars from difference point
3044//            String srcDiff = normalizedSrc.substring(i, Math.min(i + 20, normalizedSrc.length()));
3045//            String targetDiff = normalizedTarget.substring(i, Math.min(i + 20, normalizedTarget.length()));
3046
3047            System.out.println("Scripts differ at position " + i + ":");
3048            System.out.println("Source: " + normalizedSrc);
3049            System.out.println("Target: " + normalizedTarget);
3050            return false;
3051        }
3052        return true;
3053    }
3054
3055}