001package gudusoft.gsqlparser.sqlcmds;
002
003import gudusoft.gsqlparser.*;
004import gudusoft.gsqlparser.stmt.*;
005import gudusoft.gsqlparser.stmt.databricks.*;
006import gudusoft.gsqlparser.stmt.presto.TResetSessionStmt;
007
008/**
009 * Databricks SQL command resolver.
010 * Contains all Databricks-specific SQL command recognition logic.
011 *
012 * @since 3.1.0.9
013 */
014public class TSqlCmdsDatabricks extends AbstractSqlCmds {
015
016    // Temporary field for statement type during issql processing
017    private ESqlStatementType gnewsqlstatementtype = ESqlStatementType.sstinvalid;
018
019    public TSqlCmdsDatabricks() {
020        super(EDbVendor.dbvdatabricks);
021    }
022
023    /**
024     * Databricks/Spark allow the {@code AS} keyword to be omitted in a CTE:
025     * <pre>WITH cte_name [ ( col_list ) ] ( query ) ...</pre>
026     * The shared {@link AbstractSqlCmds#findcte(TSourceToken)} only recognizes
027     * the {@code AS} form; this override adds the no-{@code AS} form.
028     *
029     * <p>The no-{@code AS} detection runs FIRST: the shared logic keys off the
030     * first {@code AS} token, which for a no-{@code AS} CTE could be an unrelated
031     * later {@code AS} (e.g. an {@code INSERT INTO t AS a} target alias) and lead
032     * to the wrong statement class. {@link #findCteWithoutAs} returns {@code null}
033     * for a genuine {@code AS} CTE, so those still fall through to the shared
034     * logic.
035     */
036    @Override
037    protected TCustomSqlStatement findcte(TSourceToken ptoken) {
038        TCustomSqlStatement ret = findCteWithoutAs(ptoken);
039        if (ret != null) {
040            return ret;
041        }
042        return super.findcte(ptoken);
043    }
044
045    /**
046     * Recognize a CTE whose {@code AS} keyword is omitted. Paren tracking starts
047     * at the first parenthesis after the CTE name so that both the optional
048     * column-list parens and the query-body parens are skipped, landing on the
049     * top-level keyword of the main statement (mirroring the {@code AS} path in
050     * {@link AbstractSqlCmds#findcte(TSourceToken)}).
051     *
052     * @param withToken the {@code WITH} token
053     * @return a select statement flagged as a CTE query, or {@code null} if the
054     *         no-{@code AS} CTE pattern is not present
055     */
056    private TCustomSqlStatement findCteWithoutAs(TSourceToken withToken) {
057        TSourceTokenList list = withToken.container;
058
059        int startPos = -1;
060        for (int i = withToken.posinlist + 1; i < list.size(); i++) {
061            TSourceToken t = list.get(i);
062            if (t.isnonsolidtoken()) {
063                continue;
064            }
065            if (t.tokencode == TBaseType.rrw_as) {
066                return null; // AS form -> already handled by super.findcte()
067            }
068            if (t.tokentype == ETokenType.ttleftparenthesis) {
069                startPos = i; // first paren after the CTE name
070                break;
071            }
072            if ((t.tokentype == ETokenType.ttsemicolon)
073                    || (t.tokencode == TBaseType.rrw_select)) {
074                return null; // reached a query/end before any CTE header parens
075            }
076        }
077        if (startPos < 0) {
078            return null;
079        }
080
081        int nested = 0;
082        for (int j = startPos; j < list.size(); j++) {
083            TSourceToken t = list.get(j);
084            if (t.isnonsolidtoken()) {
085                continue;
086            }
087            if (t.tokentype == ETokenType.ttleftparenthesis) {
088                nested++;
089                continue;
090            }
091            if (t.tokentype == ETokenType.ttrightparenthesis) {
092                nested--;
093                continue;
094            }
095            if (nested != 0) {
096                continue;
097            }
098
099            // The first top-level keyword after the CTE definitions is the main
100            // statement. Mirror the AS path in AbstractSqlCmds#findcte so a no-AS
101            // CTE can precede SELECT / INSERT / DELETE / UPDATE / MERGE.
102            TCustomSqlStatement ret = null;
103            if (t.tokencode == TBaseType.rrw_select) {
104                ret = new TSelectSqlStatement(vendor);
105                gnewsqlstatementtype = ESqlStatementType.sstselect;
106            } else if ((t.tokencode == TBaseType.rrw_insert) || (t.tokencode == TBaseType.rrw_replace)) {
107                ret = new TInsertSqlStatement(vendor);
108                gnewsqlstatementtype = (t.tokencode == TBaseType.rrw_replace)
109                        ? ESqlStatementType.sstmysqlreplace : ESqlStatementType.sstinsert;
110                ret.sqlstatementtype = gnewsqlstatementtype;
111                ret.dummytag = 1; // select stmt in insert is permitted
112                // Ignore the INSERT header up to its VALUES/SELECT so the raw
113                // splitter does not treat the INSERT's SELECT as a new statement.
114                int k = t.posinlist + 1;
115                for (; k < list.size(); k++) {
116                    if (list.get(k).isnonsolidtoken()) continue;
117                    if ((list.get(k).tokencode == TBaseType.rrw_values)
118                            || (list.get(k).tokencode == TBaseType.rrw_go)
119                            || (list.get(k).tokentype == ETokenType.ttsemicolon)
120                            || (list.get(k).tokencode == TBaseType.rrw_select)) {
121                        break;
122                    }
123                }
124                if (k > list.size() - 1) {
125                    k = list.size() - 1;
126                }
127                for (int m = t.posinlist + 1; m <= k; m++) {
128                    list.get(m).tokenstatus = ETokenStatus.tsignoredbygetrawstatement;
129                }
130            } else if (t.tokencode == TBaseType.rrw_delete) {
131                ret = new TDeleteSqlStatement(vendor);
132                gnewsqlstatementtype = ESqlStatementType.sstdelete;
133            } else if (t.tokencode == TBaseType.rrw_update) {
134                ret = new TUpdateSqlStatement(vendor);
135                ret.dummytag = 1; // set clause in update is not found yet
136                gnewsqlstatementtype = ESqlStatementType.sstupdate;
137            } else if (t.tokencode == TBaseType.rrw_merge) {
138                ret = new TMergeSqlStatement(vendor);
139                gnewsqlstatementtype = ESqlStatementType.sstmerge;
140            }
141
142            if (ret != null) {
143                ret.isctequery = true;
144                for (int k = withToken.posinlist + 1; k <= j; k++) {
145                    list.get(k).tokenstatus = ETokenStatus.tsignoredbygetrawstatement;
146                }
147                return ret;
148            }
149
150            if (t.tokentype == ETokenType.ttsemicolon) {
151                return null;
152            }
153        }
154        return null;
155    }
156
157    @Override
158    protected String getToken1Str(int token1) {
159        switch (token1) {
160            case TBaseType.rrw_databricks_convert:
161                return "convert";
162            case TBaseType.rrw_databricks_copy:
163                return "copy";
164            case TBaseType.rrw_databricks_desc:
165                return "desc";
166            case TBaseType.rrw_databricks_fsck:
167                return "fsck";
168            case TBaseType.rrw_databricks_list:
169                return "list";
170            case TBaseType.rrw_databricks_msck:
171                return "msck";
172            case TBaseType.rrw_databricks_reorg:
173                return "reorg";
174            case TBaseType.rrw_databricks_sync:
175                return "sync";
176            case TBaseType.rrw_databricks_uncache:
177                return "uncache";
178            case TBaseType.rrw_databricks_vacuum:
179                return "vacuum";
180            default:
181                return null;
182        }
183    }
184
185    @Override
186    protected void initializeCommands() {
187        // Databricks commands extracted from TSqlCmds.initdatabrickscmds()
188        // Note: Longer patterns must come BEFORE shorter patterns with the same prefix
189
190        addCmd(TBaseType.rrw_add, "archive", ESqlStatementType.sstaddAchieve);
191        addCmd(TBaseType.rrw_add, "archives", ESqlStatementType.sstaddAchieve);
192
193        addCmd(TBaseType.rrw_alter, "catalog", ESqlStatementType.sstaltercatalog);
194        addCmd(TBaseType.rrw_alter, "database", ESqlStatementType.sstalterdatabase);
195        addCmd(TBaseType.rrw_alter, "external", "location", ESqlStatementType.sstalterlocation);
196        addCmd(TBaseType.rrw_alter, "group", ESqlStatementType.sstAlterGroup);
197        addCmd(TBaseType.rrw_alter, "provider", ESqlStatementType.sstalterprovider);
198        addCmd(TBaseType.rrw_alter, "recipient", ESqlStatementType.sstalterrecipient);
199        addCmd(TBaseType.rrw_alter, "schema", ESqlStatementType.sstAlterSchema);
200        addCmd(TBaseType.rrw_alter, "share", ESqlStatementType.sstAltershare);
201        addCmd(TBaseType.rrw_alter, "storage", "credential", ESqlStatementType.sstaltercredental);
202        addCmd(TBaseType.rrw_alter, "table", ESqlStatementType.sstaltertable);
203        addCmd(TBaseType.rrw_alter, "view", ESqlStatementType.sstalterview);
204
205        addCmd(TBaseType.rrw_analyze, "table", ESqlStatementType.sstAnalyzeTable);
206        addCmd(TBaseType.rrw_analyze, "tables", ESqlStatementType.sstAnalyzeTable);
207
208        addCmd(TBaseType.rrw_cache, "select", ESqlStatementType.sstCacheSelect);
209        addCmd(TBaseType.rrw_clear, "cache", ESqlStatementType.sstClearCache);
210        addCmd(TBaseType.rrw_comment, "on", ESqlStatementType.sstCommentOn);
211
212        addCmd(TBaseType.rrw_databricks_convert, "to", "delta", ESqlStatementType.sstConvertToDelta);
213        addCmd(TBaseType.rrw_databricks_copy, "into", ESqlStatementType.sstCopyInto);
214
215        // CREATE commands - longer patterns first
216        addCmd(TBaseType.rrw_create, "bloomfilter", "index", ESqlStatementType.sstcreateindex);
217        addCmd(TBaseType.rrw_create, "catalog", ESqlStatementType.sstcreatecatalog);
218        addCmd(TBaseType.rrw_create, "database", ESqlStatementType.sstcreatedatabase);
219        addCmd(TBaseType.rrw_create, "external", "location", ESqlStatementType.sstCreateExternallocation);
220        addCmd(TBaseType.rrw_create, "group", ESqlStatementType.sstCreategroup);
221        addCmd(TBaseType.rrw_create, "materialized", "view", ESqlStatementType.sstcreatematerializedview);
222        addCmd(TBaseType.rrw_create, "or", "replace", "function", ESqlStatementType.sstcreatefunction);
223        addCmd(TBaseType.rrw_create, "or", "replace", "materialized", "view", ESqlStatementType.sstcreatematerializedview);
224        addCmd(TBaseType.rrw_create, "or", "replace", "table", ESqlStatementType.sstcreatetable);
225        addCmd(TBaseType.rrw_create, "or", "replace", "temp", "function", ESqlStatementType.sstcreatefunction);
226        addCmd(TBaseType.rrw_create, "or", "replace", "temp", "view", ESqlStatementType.sstcreateview);
227        addCmd(TBaseType.rrw_create, "or", "replace", "temporary", "function", ESqlStatementType.sstcreatefunction);
228        addCmd(TBaseType.rrw_create, "or", "replace", "temporary", "view", ESqlStatementType.sstcreateview);
229        addCmd(TBaseType.rrw_create, "or", "replace", "view", ESqlStatementType.sstcreateview);
230        addCmd(TBaseType.rrw_create, "recipient", ESqlStatementType.sstcreaterecipient);
231        addCmd(TBaseType.rrw_create, "schema", ESqlStatementType.sstcreateschema);
232        addCmd(TBaseType.rrw_create, "share", ESqlStatementType.sstcreateshare);
233        addCmd(TBaseType.rrw_create, "temp", "function", ESqlStatementType.sstcreatefunction);
234        addCmd(TBaseType.rrw_create, "temporary", "function", ESqlStatementType.sstcreatefunction);
235        addCmd(TBaseType.rrw_create, "function", ESqlStatementType.sstcreatefunction);
236        addCmd(TBaseType.rrw_create, "role", ESqlStatementType.sstcreaterole);
237        addCmd(TBaseType.rrw_create, "table", ESqlStatementType.sstcreatetable);
238        addCmd(TBaseType.rrw_create, "view", ESqlStatementType.sstcreateview);
239
240        // Databricks REPLACE TABLE (atomic replacement); same statement as CREATE OR REPLACE TABLE
241        addCmd(TBaseType.rrw_replace, "table", ESqlStatementType.sstcreatetable);
242
243        // DECLARE [OR REPLACE] [VARIABLE | VAR] name [type] [DEFAULT expr | = expr]
244        // (session variable, Mantis 4896). Same registration as TSqlCmdsSparksql:
245        // the default branch of issql returns a typed TUnknownSqlStatement, so the
246        // statement is recognized and ends at its own semicolon.
247        addCmd(TBaseType.rrw_declare, ESqlStatementType.sstmysqldeclare);
248
249        addCmd(TBaseType.rrw_delete, "from", ESqlStatementType.sstdelete);
250        addCmd(TBaseType.rrw_deny, ESqlStatementType.sstDeny);
251
252        // DESCRIBE commands - longer patterns first
253        addCmd(TBaseType.rrw_databricks_desc, "catalog", ESqlStatementType.sstdescribeCatalog);
254        addCmd(TBaseType.rrw_databricks_desc, "function", ESqlStatementType.sstdescribeFunction);
255        addCmd(TBaseType.rrw_databricks_desc, "provider", ESqlStatementType.sstdescribeProvider);
256        addCmd(TBaseType.rrw_databricks_desc, "query", ESqlStatementType.sstdescribeQuery);
257        addCmd(TBaseType.rrw_databricks_desc, "recipient", ESqlStatementType.sstdescribeRecipient);
258        addCmd(TBaseType.rrw_databricks_desc, "schema", ESqlStatementType.sstdescribeSchema);
259        addCmd(TBaseType.rrw_databricks_desc, "share", ESqlStatementType.sstdescribeShare);
260        addCmd(TBaseType.rrw_databricks_desc, "table", ESqlStatementType.sstdescribeTable);
261        addCmd(TBaseType.rrw_databricks_desc, ESqlStatementType.sstdescribe);
262
263        addCmd(TBaseType.rrw_describe, "catalog", ESqlStatementType.sstdescribeCatalog);
264        addCmd(TBaseType.rrw_describe, "database", ESqlStatementType.sstdescribeDatabase);
265        addCmd(TBaseType.rrw_describe, "external", "location", ESqlStatementType.sstdescribeLocation);
266        addCmd(TBaseType.rrw_describe, "function", ESqlStatementType.sstdescribeFunction);
267        addCmd(TBaseType.rrw_describe, "provider", ESqlStatementType.sstdescribeProvider);
268        addCmd(TBaseType.rrw_describe, "query", ESqlStatementType.sstdescribeQuery);
269        addCmd(TBaseType.rrw_describe, "recipient", ESqlStatementType.sstdescribeRecipient);
270        addCmd(TBaseType.rrw_describe, "schema", ESqlStatementType.sstdescribeSchema);
271        addCmd(TBaseType.rrw_describe, "share", ESqlStatementType.sstdescribeShare);
272        addCmd(TBaseType.rrw_describe, "storage", "credential", ESqlStatementType.sstdescribeCredential);
273        addCmd(TBaseType.rrw_describe, "table", ESqlStatementType.sstdescribeTable);
274        addCmd(TBaseType.rrw_describe, ESqlStatementType.sstdescribe);
275
276        // DROP commands - longer patterns first
277        addCmd(TBaseType.rrw_drop, "bloomfilter", "index", ESqlStatementType.sstdropindex);
278        addCmd(TBaseType.rrw_drop, "catalog", ESqlStatementType.sstdropcatalog);
279        addCmd(TBaseType.rrw_drop, "database", ESqlStatementType.sstdropdatabase);
280        addCmd(TBaseType.rrw_drop, "external", "location", ESqlStatementType.sstdroplocation);
281        addCmd(TBaseType.rrw_drop, "group", ESqlStatementType.sstDropGroup);
282        addCmd(TBaseType.rrw_drop, "provider", ESqlStatementType.sstdropprovider);
283        addCmd(TBaseType.rrw_drop, "recipient", ESqlStatementType.sstdroprecipient);
284        addCmd(TBaseType.rrw_drop, "schema", ESqlStatementType.sstdropschema);
285        addCmd(TBaseType.rrw_drop, "share", ESqlStatementType.sstdropshare);
286        addCmd(TBaseType.rrw_drop, "storage", "credential", ESqlStatementType.sstdropcredential);
287        addCmd(TBaseType.rrw_drop, "temp", "function", ESqlStatementType.sstdropfunction);
288        addCmd(TBaseType.rrw_drop, "temporary", "function", ESqlStatementType.sstdropfunction);
289        addCmd(TBaseType.rrw_drop, "function", ESqlStatementType.sstdropfunction);
290        addCmd(TBaseType.rrw_drop, "table", ESqlStatementType.sstdroptable);
291        addCmd(TBaseType.rrw_drop, "view", ESqlStatementType.sstdropview);
292
293        addCmd(TBaseType.rrw_explain, ESqlStatementType.sstExplain);
294
295        addCmd(TBaseType.rrw_databricks_fsck, "repair", ESqlStatementType.sstmsckrepairtable);
296
297        // GRANT commands - longer patterns first
298        addCmd(TBaseType.rrw_grant, "select", "on", "share", ESqlStatementType.sstGrant);
299        addCmd(TBaseType.rrw_grant, ESqlStatementType.sstGrant);
300
301        addCmd(TBaseType.rrw_insert, ESqlStatementType.sstinsert);
302        addCmd(TBaseType.rrw_databricks_list, ESqlStatementType.sstList);
303        addCmd(TBaseType.rrw_load, "data", ESqlStatementType.sstLoadData);
304        addCmd(TBaseType.rrw_merge, "into", ESqlStatementType.sstmerge);
305        // Delta Lake automatic schema evolution on MERGE (Mantis 4645)
306        addCmd(TBaseType.rrw_merge, "with", "schema", "evolution", "into", ESqlStatementType.sstmerge);
307
308        // MSCK commands - longer patterns first
309        addCmd(TBaseType.rrw_databricks_msck, "repair", "table", ESqlStatementType.sstmsckrepairtable);
310        addCmd(TBaseType.rrw_databricks_msck, "repair", ESqlStatementType.sstmsckrepairtable);
311
312        addCmd(TBaseType.rrw_optimize, ESqlStatementType.sstOptimize);
313
314        addCmd(TBaseType.rrw_refresh, "function", ESqlStatementType.sstRefreshFunction);
315        addCmd(TBaseType.rrw_refresh, "table", ESqlStatementType.sstRefreshTable);
316        addCmd(TBaseType.rrw_refresh, ESqlStatementType.sstRefresh);
317
318        addCmd(TBaseType.rrw_databricks_reorg, "table", ESqlStatementType.sstReorgTable);
319        addCmd(TBaseType.rrw_replace, "table", ESqlStatementType.sstcreatetable);
320        addCmd(TBaseType.rrw_reset, "session", ESqlStatementType.sstResetSession);
321        addCmd(TBaseType.rrw_reset, ESqlStatementType.sstReset);
322        addCmd(TBaseType.rrw_restore, ESqlStatementType.sstRestoreTable);
323
324        // REVOKE commands - longer patterns first
325        addCmd(TBaseType.rrw_revoke, "select", "on", "share", ESqlStatementType.sstRevoke);
326        addCmd(TBaseType.rrw_revoke, ESqlStatementType.sstRevoke);
327
328        addCmd(TBaseType.rrw_rollback, ESqlStatementType.sstrollback);
329        addCmd(TBaseType.rrw_select, ESqlStatementType.sstselect);
330        addCmd(TBaseType.rrw_table, ESqlStatementType.sstselect);  // TABLE t = SELECT * FROM t
331
332        // SET commands - longer patterns first
333        addCmd(TBaseType.rrw_set, "catalog", ESqlStatementType.sstUseCatalog);
334        addCmd(TBaseType.rrw_set, "role", ESqlStatementType.sstset);
335        addCmd(TBaseType.rrw_set, "session", ESqlStatementType.sstset);
336        addCmd(TBaseType.rrw_set, "time", "zone", ESqlStatementType.sstset);
337        addCmd(TBaseType.rrw_set, ESqlStatementType.sstset);
338
339        // SHOW commands - longer patterns first
340        addCmd(TBaseType.rrw_show, "all", "functions", ESqlStatementType.sstShow);
341        addCmd(TBaseType.rrw_show, "all", "in", "share", ESqlStatementType.sstShow);
342        addCmd(TBaseType.rrw_show, "catalogs", ESqlStatementType.sstShow);
343        addCmd(TBaseType.rrw_show, "columns", ESqlStatementType.sstShow);
344        addCmd(TBaseType.rrw_show, "create", "table", ESqlStatementType.sstShow);
345        addCmd(TBaseType.rrw_show, "external", "locations", ESqlStatementType.sstShow);
346        addCmd(TBaseType.rrw_show, "functions", ESqlStatementType.sstShow);
347        addCmd(TBaseType.rrw_show, "grants", "on", "share", ESqlStatementType.sstShow);
348        addCmd(TBaseType.rrw_show, "grants", "to", "recipient", ESqlStatementType.sstShow);
349        addCmd(TBaseType.rrw_show, "grants", ESqlStatementType.sstShow);
350        addCmd(TBaseType.rrw_show, "groups", ESqlStatementType.sstShow);
351        addCmd(TBaseType.rrw_show, "partitions", ESqlStatementType.sstShow);
352        addCmd(TBaseType.rrw_show, "providers", ESqlStatementType.sstShow);
353        addCmd(TBaseType.rrw_show, "recipients", ESqlStatementType.sstShow);
354        addCmd(TBaseType.rrw_show, "schemas", ESqlStatementType.sstShow);
355        addCmd(TBaseType.rrw_show, "shares", ESqlStatementType.sstShow);
356        addCmd(TBaseType.rrw_show, "storage", "credentials", ESqlStatementType.sstShow);
357        addCmd(TBaseType.rrw_show, "system", "functions", ESqlStatementType.sstShow);
358        addCmd(TBaseType.rrw_show, "table", "extended", ESqlStatementType.sstShow);
359        addCmd(TBaseType.rrw_show, "tables", ESqlStatementType.sstShow);
360        addCmd(TBaseType.rrw_show, "tblproperties", ESqlStatementType.sstShow);
361        addCmd(TBaseType.rrw_show, "user", "functions", ESqlStatementType.sstShow);
362        addCmd(TBaseType.rrw_show, "users", ESqlStatementType.sstShow);
363        addCmd(TBaseType.rrw_show, "views", ESqlStatementType.sstShow);
364
365        addCmd(TBaseType.rrw_databricks_sync, "schema", ESqlStatementType.sstsync);
366        addCmd(TBaseType.rrw_databricks_sync, "table", ESqlStatementType.sstsync);
367
368        addCmd(TBaseType.rrw_start, "transaction", ESqlStatementType.sstStartTransaction);
369        addCmd(TBaseType.rrw_truncate, "table", ESqlStatementType.ssttruncatetable);
370        addCmd(TBaseType.rrw_databricks_uncache, "table", ESqlStatementType.sstUnCacheTable);
371        addCmd(TBaseType.rrw_update, ESqlStatementType.sstupdate);
372
373        // USE commands - longer patterns first
374        addCmd(TBaseType.rrw_use, "catalog", ESqlStatementType.sstUseCatalog);
375        addCmd(TBaseType.rrw_use, "database", ESqlStatementType.sstUseSchema);
376        addCmd(TBaseType.rrw_use, "schema", ESqlStatementType.sstUseSchema);
377        addCmd(TBaseType.rrw_use, ESqlStatementType.sstUseSchema);
378
379        addCmd(TBaseType.rrw_databricks_vacuum, ESqlStatementType.sstVacuum);
380        addCmd(TBaseType.rrw_values, ESqlStatementType.sstValues);
381        addCmd(TBaseType.rrw_prepare, ESqlStatementType.sstprepare);
382    }
383
384    @Override
385    public TCustomSqlStatement issql(TSourceToken token, EFindSqlStateType state, TCustomSqlStatement currentStatement) {
386        TCustomSqlStatement ret = null;
387        int k;
388        boolean lcisnewsql;
389        TSourceToken lcpprevsolidtoken, lcnextsolidtoken;
390
391        gnewsqlstatementtype = ESqlStatementType.sstinvalid;
392
393        if ((token.tokencode == TBaseType.cmtdoublehyphen)
394                || (token.tokencode == TBaseType.cmtslashstar)
395                || (token.tokencode == TBaseType.lexspace)
396                || (token.tokencode == TBaseType.lexnewline)
397                || (token.tokentype == ETokenType.ttsemicolon)) {
398            return ret;
399        }
400
401        int lcpos = token.posinlist;
402        TSourceTokenList lcsourcetokenlist = token.container;
403        TCustomSqlStatement lccurrentsqlstatement = currentStatement;
404
405        // Subquery after semicolon || at first line
406        if ((state == EFindSqlStateType.stnormal) && (token.tokentype == ETokenType.ttleftparenthesis)) {
407            k = lcsourcetokenlist.solidtokenafterpos(lcpos, TBaseType.rrw_select, 1, "(");
408            if (k > 0) {
409                ret = new TSelectSqlStatement(vendor);
410            }
411            return ret;
412        }
413
414        // CTE
415        if ((state == EFindSqlStateType.stnormal) && (token.tokencode == TBaseType.rrw_with)) {
416            ret = findcte(token);
417            if ((ret != null)) return ret;
418        }
419
420        gnewsqlstatementtype = getStatementTypeForToken(token);
421
422        TSourceToken lcprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcpos);
423
424        if ((gnewsqlstatementtype == ESqlStatementType.sstinvalid) && (token.tokencode == TBaseType.rrw_create)) {
425            TSourceToken viewToken = token.container.searchToken(TBaseType.rrw_view, "", token, 15);
426            if (viewToken != null) {
427                gnewsqlstatementtype = ESqlStatementType.sstcreateview;
428            }
429        }
430
431        switch (gnewsqlstatementtype) {
432            case sstinvalid: {
433                ret = null;
434                break;
435            }
436            case sstselect: {
437                lcisnewsql = true;
438
439                if (state != EFindSqlStateType.stnormal) {
440                    if (TBaseType.assigned(lcprevsolidtoken)) {
441                        if (lcprevsolidtoken.tokentype == ETokenType.ttleftparenthesis)
442                            lcisnewsql = false; // subquery
443                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_union)
444                            lcisnewsql = false;
445                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_intersect)
446                            lcisnewsql = false;
447                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_minus)
448                            lcisnewsql = false;
449                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_except)
450                            lcisnewsql = false;
451                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_return)
452                            lcisnewsql = false;
453                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_as) {
454                            if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatetable)
455                                lcisnewsql = false;
456                            if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreateview)
457                                lcisnewsql = false;
458                        }
459
460                        if (lcisnewsql && (lcprevsolidtoken.tokencode == TBaseType.rrw_all)) {
461                            lcpprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcprevsolidtoken.posinlist);
462                            if (TBaseType.assigned(lcpprevsolidtoken)) {
463                                if (lcpprevsolidtoken.tokencode == TBaseType.rrw_union)
464                                    lcisnewsql = false;
465                            }
466                        }
467                    }
468
469                    if (TBaseType.assigned(lccurrentsqlstatement)) {
470                        if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstinsert)
471                            lcisnewsql = false;
472                    }
473                }
474
475                if (lcisnewsql)
476                    ret = new TSelectSqlStatement(vendor);
477                break;
478            }
479            case sstinsert: {
480                lcisnewsql = true;
481                if (state != EFindSqlStateType.stnormal) {
482                    if (TBaseType.assigned(lccurrentsqlstatement)) {
483                    }
484                }
485
486                if (lcisnewsql)
487                    ret = new TInsertSqlStatement(vendor);
488                ret.sqlstatementtype = gnewsqlstatementtype;
489                break;
490            }
491            case sstdelete: {
492                lcisnewsql = true;
493
494                if (state != EFindSqlStateType.stnormal) {
495                    lcprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcpos);
496                    if (TBaseType.assigned(lcprevsolidtoken)) {
497                        if (lcprevsolidtoken.tokencode == TBaseType.rrw_on)
498                            lcisnewsql = false;
499                    }
500
501                    if (TBaseType.assigned(lccurrentsqlstatement)) {
502                    }
503                }
504
505                if (lcisnewsql)
506                    ret = new TDeleteSqlStatement(vendor);
507                break;
508            }
509            case sstaltertable: {
510                ret = new TAlterTableStatement(vendor);
511                break;
512            }
513            case sstalterfunction: {
514                ret = new TAlterFunctionStmt(vendor);
515                break;
516            }
517            case sstAlterSchema: {
518                ret = new TAlterSchemaStmt(vendor);
519                break;
520            }
521            case sstanalyzeTable: {
522                ret = new TAnalyzeStmt(vendor);
523                break;
524            }
525            case sstcall: {
526                ret = new TCallStatement(vendor);
527                break;
528            }
529            case sstcommit: {
530                ret = new TCommitStmt(vendor);
531                break;
532            }
533            case sstcreatefunction: {
534                ret = new TCreateFunctionStmt(vendor);
535                break;
536            }
537            case sstcreaterole: {
538                ret = new TCreateRoleStmt(vendor);
539                break;
540            }
541            case sstcreateschema: {
542                ret = new TCreateSchemaSqlStatement(vendor);
543                break;
544            }
545            case sstcreatetable: {
546                ret = new TCreateTableSqlStatement(vendor);
547                break;
548            }
549            case sstcreateview: {
550                ret = new TCreateViewSqlStatement(vendor);
551                break;
552            }
553            case sstpostgresqlDeallocate: {
554                ret = new TUnknownSqlStatement(vendor);
555                ret.sqlstatementtype = gnewsqlstatementtype;
556                break;
557            }
558            case sstdropfunction: {
559                ret = new TDropFunctionStmt(vendor);
560                break;
561            }
562            case sstdroprole: {
563                ret = new TDropRoleStmt(vendor);
564                break;
565            }
566            case sstdropschema: {
567                ret = new TDropSchemaSqlStatement(vendor);
568                break;
569            }
570            case sstdroptable: {
571                ret = new TDropTableSqlStatement(vendor);
572                break;
573            }
574            case sstdropview: {
575                ret = new TDropViewSqlStatement(vendor);
576                break;
577            }
578            case sstExecute: {
579                ret = new TExecuteSqlStatement(vendor);
580                break;
581            }
582            case sstExplain: {
583                ret = new TExplainPlan(vendor);
584                break;
585            }
586            case sstGrant: {
587                ret = new TGrantStmt(vendor);
588                break;
589            }
590            case sstprepare: {
591                ret = new TPrepareStmt(vendor);
592                break;
593            }
594            case sstset:
595            case sstReset: {
596                lcisnewsql = true;
597                if (state != EFindSqlStateType.stnormal) {
598                    if (TBaseType.assigned(lccurrentsqlstatement)) {
599                        lcisnewsql = false;
600                    }
601                }
602
603                if (lcisnewsql) {
604                    ret = new TSetStmt(vendor);
605                }
606                break;
607            }
608            case sstShow: {
609                ret = new TShowStmt(vendor);
610                ret.sqlstatementtype = gnewsqlstatementtype;
611                break;
612            }
613            case sstStartTransaction: {
614                ret = new TStartTransactionStmt(vendor);
615                break;
616            }
617            case sstValues: {
618                ret = new TSelectSqlStatement(vendor);
619                break;
620            }
621            case sstResetSession: {
622                ret = new TResetSessionStmt(vendor);
623                break;
624            }
625            case sstCreateExternallocation:
626                ret = new TCreateExternalLocationStmt(vendor);
627                break;
628            case sstList: {
629                ret = new TListStmt(vendor);
630                break;
631            }
632            case sstRevoke:
633                ret = new TRevokeStmt(vendor);
634                break;
635            case sstaltercredental:
636                ret = new TAlterCredentialStmt(vendor);
637                break;
638            case sstdescribeCatalog:
639            case sstdescribeFunction:
640            case sstdescribeProvider:
641            case sstdescribeQuery:
642            case sstdescribeRecipient:
643            case sstdescribeSchema:
644            case sstdescribeShare:
645            case sstdescribeTable:
646            case sstdescribeDatabase:
647            case sstdescribeLocation:
648            case sstdescribeCredential:
649            case sstdescribe:
650                ret = new TDescribeStmt(vendor);
651                break;
652            case sstUseCatalog:
653            case sstUseSchema:
654            case sstUseDatabase:
655            case sstUse:
656                ret = new TUseDatabase(vendor);
657                break;
658            case sstAnalyzeTable:
659                ret = new TAnalyzeStmt(vendor);
660                break;
661            case sstCreategroup:
662                ret = new TCreateGroup(vendor);
663                break;
664            case sstAlterGroup:
665                ret = new TAlterGroup(vendor);
666                break;
667            case sstDeny:
668                ret = new TDenyStmt(vendor);
669                break;
670            case sstDropGroup:
671                ret = new TDropGroup(vendor);
672                break;
673            case sstmsckrepairtable:
674                ret = new TMSCKStmt(vendor);
675                break;
676            case sstcreatecatalog:
677                ret = new TCreateCatalogStmt(vendor);
678                break;
679            case sstConvertToDelta:
680                ret = new TConvertToDeltaStmt(vendor);
681                break;
682            case sstOptimize:
683                ret = new TOptimizeStmt(vendor);
684                break;
685            case sstRestoreTable:
686                ret = new TRestoreTableStmt(vendor);
687                break;
688            case sstReorgTable:
689                ret = new TReorgTableStmt(vendor);
690                break;
691            case sstVacuum:
692                ret = new TVacuumStmt(vendor);
693                break;
694            case sstmerge:
695                ret = new TMergeSqlStatement(vendor);
696                break;
697            case sstcreatematerializedview:
698                ret = new TCreateMaterializedSqlStatement(vendor);
699                break;
700            default: {
701                ret = new TUnknownSqlStatement(vendor);
702                ret.sqlstatementtype = gnewsqlstatementtype;
703                break;
704            }
705        }
706
707        return ret;
708    }
709}