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        addCmd(TBaseType.rrw_delete, "from", ESqlStatementType.sstdelete);
244        addCmd(TBaseType.rrw_deny, ESqlStatementType.sstDeny);
245
246        // DESCRIBE commands - longer patterns first
247        addCmd(TBaseType.rrw_databricks_desc, "catalog", ESqlStatementType.sstdescribeCatalog);
248        addCmd(TBaseType.rrw_databricks_desc, "function", ESqlStatementType.sstdescribeFunction);
249        addCmd(TBaseType.rrw_databricks_desc, "provider", ESqlStatementType.sstdescribeProvider);
250        addCmd(TBaseType.rrw_databricks_desc, "query", ESqlStatementType.sstdescribeQuery);
251        addCmd(TBaseType.rrw_databricks_desc, "recipient", ESqlStatementType.sstdescribeRecipient);
252        addCmd(TBaseType.rrw_databricks_desc, "schema", ESqlStatementType.sstdescribeSchema);
253        addCmd(TBaseType.rrw_databricks_desc, "share", ESqlStatementType.sstdescribeShare);
254        addCmd(TBaseType.rrw_databricks_desc, "table", ESqlStatementType.sstdescribeTable);
255        addCmd(TBaseType.rrw_databricks_desc, ESqlStatementType.sstdescribe);
256
257        addCmd(TBaseType.rrw_describe, "catalog", ESqlStatementType.sstdescribeCatalog);
258        addCmd(TBaseType.rrw_describe, "database", ESqlStatementType.sstdescribeDatabase);
259        addCmd(TBaseType.rrw_describe, "external", "location", ESqlStatementType.sstdescribeLocation);
260        addCmd(TBaseType.rrw_describe, "function", ESqlStatementType.sstdescribeFunction);
261        addCmd(TBaseType.rrw_describe, "provider", ESqlStatementType.sstdescribeProvider);
262        addCmd(TBaseType.rrw_describe, "query", ESqlStatementType.sstdescribeQuery);
263        addCmd(TBaseType.rrw_describe, "recipient", ESqlStatementType.sstdescribeRecipient);
264        addCmd(TBaseType.rrw_describe, "schema", ESqlStatementType.sstdescribeSchema);
265        addCmd(TBaseType.rrw_describe, "share", ESqlStatementType.sstdescribeShare);
266        addCmd(TBaseType.rrw_describe, "storage", "credential", ESqlStatementType.sstdescribeCredential);
267        addCmd(TBaseType.rrw_describe, "table", ESqlStatementType.sstdescribeTable);
268        addCmd(TBaseType.rrw_describe, ESqlStatementType.sstdescribe);
269
270        // DROP commands - longer patterns first
271        addCmd(TBaseType.rrw_drop, "bloomfilter", "index", ESqlStatementType.sstdropindex);
272        addCmd(TBaseType.rrw_drop, "catalog", ESqlStatementType.sstdropcatalog);
273        addCmd(TBaseType.rrw_drop, "database", ESqlStatementType.sstdropdatabase);
274        addCmd(TBaseType.rrw_drop, "external", "location", ESqlStatementType.sstdroplocation);
275        addCmd(TBaseType.rrw_drop, "group", ESqlStatementType.sstDropGroup);
276        addCmd(TBaseType.rrw_drop, "provider", ESqlStatementType.sstdropprovider);
277        addCmd(TBaseType.rrw_drop, "recipient", ESqlStatementType.sstdroprecipient);
278        addCmd(TBaseType.rrw_drop, "schema", ESqlStatementType.sstdropschema);
279        addCmd(TBaseType.rrw_drop, "share", ESqlStatementType.sstdropshare);
280        addCmd(TBaseType.rrw_drop, "storage", "credential", ESqlStatementType.sstdropcredential);
281        addCmd(TBaseType.rrw_drop, "temp", "function", ESqlStatementType.sstdropfunction);
282        addCmd(TBaseType.rrw_drop, "temporary", "function", ESqlStatementType.sstdropfunction);
283        addCmd(TBaseType.rrw_drop, "function", ESqlStatementType.sstdropfunction);
284        addCmd(TBaseType.rrw_drop, "table", ESqlStatementType.sstdroptable);
285        addCmd(TBaseType.rrw_drop, "view", ESqlStatementType.sstdropview);
286
287        addCmd(TBaseType.rrw_explain, ESqlStatementType.sstExplain);
288
289        addCmd(TBaseType.rrw_databricks_fsck, "repair", ESqlStatementType.sstmsckrepairtable);
290
291        // GRANT commands - longer patterns first
292        addCmd(TBaseType.rrw_grant, "select", "on", "share", ESqlStatementType.sstGrant);
293        addCmd(TBaseType.rrw_grant, ESqlStatementType.sstGrant);
294
295        addCmd(TBaseType.rrw_insert, ESqlStatementType.sstinsert);
296        addCmd(TBaseType.rrw_databricks_list, ESqlStatementType.sstList);
297        addCmd(TBaseType.rrw_load, "data", ESqlStatementType.sstLoadData);
298        addCmd(TBaseType.rrw_merge, "into", ESqlStatementType.sstmerge);
299        // Delta Lake automatic schema evolution on MERGE (Mantis 4645)
300        addCmd(TBaseType.rrw_merge, "with", "schema", "evolution", "into", ESqlStatementType.sstmerge);
301
302        // MSCK commands - longer patterns first
303        addCmd(TBaseType.rrw_databricks_msck, "repair", "table", ESqlStatementType.sstmsckrepairtable);
304        addCmd(TBaseType.rrw_databricks_msck, "repair", ESqlStatementType.sstmsckrepairtable);
305
306        addCmd(TBaseType.rrw_optimize, ESqlStatementType.sstOptimize);
307
308        addCmd(TBaseType.rrw_refresh, "function", ESqlStatementType.sstRefreshFunction);
309        addCmd(TBaseType.rrw_refresh, "table", ESqlStatementType.sstRefreshTable);
310        addCmd(TBaseType.rrw_refresh, ESqlStatementType.sstRefresh);
311
312        addCmd(TBaseType.rrw_databricks_reorg, "table", ESqlStatementType.sstReorgTable);
313        addCmd(TBaseType.rrw_replace, "table", ESqlStatementType.sstcreatetable);
314        addCmd(TBaseType.rrw_reset, "session", ESqlStatementType.sstResetSession);
315        addCmd(TBaseType.rrw_reset, ESqlStatementType.sstReset);
316        addCmd(TBaseType.rrw_restore, ESqlStatementType.sstRestoreTable);
317
318        // REVOKE commands - longer patterns first
319        addCmd(TBaseType.rrw_revoke, "select", "on", "share", ESqlStatementType.sstRevoke);
320        addCmd(TBaseType.rrw_revoke, ESqlStatementType.sstRevoke);
321
322        addCmd(TBaseType.rrw_rollback, ESqlStatementType.sstrollback);
323        addCmd(TBaseType.rrw_select, ESqlStatementType.sstselect);
324
325        // SET commands - longer patterns first
326        addCmd(TBaseType.rrw_set, "catalog", ESqlStatementType.sstUseCatalog);
327        addCmd(TBaseType.rrw_set, "role", ESqlStatementType.sstset);
328        addCmd(TBaseType.rrw_set, "session", ESqlStatementType.sstset);
329        addCmd(TBaseType.rrw_set, "time", "zone", ESqlStatementType.sstset);
330        addCmd(TBaseType.rrw_set, ESqlStatementType.sstset);
331
332        // SHOW commands - longer patterns first
333        addCmd(TBaseType.rrw_show, "all", "functions", ESqlStatementType.sstShow);
334        addCmd(TBaseType.rrw_show, "all", "in", "share", ESqlStatementType.sstShow);
335        addCmd(TBaseType.rrw_show, "catalogs", ESqlStatementType.sstShow);
336        addCmd(TBaseType.rrw_show, "columns", ESqlStatementType.sstShow);
337        addCmd(TBaseType.rrw_show, "create", "table", ESqlStatementType.sstShow);
338        addCmd(TBaseType.rrw_show, "external", "locations", ESqlStatementType.sstShow);
339        addCmd(TBaseType.rrw_show, "functions", ESqlStatementType.sstShow);
340        addCmd(TBaseType.rrw_show, "grants", "on", "share", ESqlStatementType.sstShow);
341        addCmd(TBaseType.rrw_show, "grants", "to", "recipient", ESqlStatementType.sstShow);
342        addCmd(TBaseType.rrw_show, "grants", ESqlStatementType.sstShow);
343        addCmd(TBaseType.rrw_show, "groups", ESqlStatementType.sstShow);
344        addCmd(TBaseType.rrw_show, "partitions", ESqlStatementType.sstShow);
345        addCmd(TBaseType.rrw_show, "providers", ESqlStatementType.sstShow);
346        addCmd(TBaseType.rrw_show, "recipients", ESqlStatementType.sstShow);
347        addCmd(TBaseType.rrw_show, "schemas", ESqlStatementType.sstShow);
348        addCmd(TBaseType.rrw_show, "shares", ESqlStatementType.sstShow);
349        addCmd(TBaseType.rrw_show, "storage", "credentials", ESqlStatementType.sstShow);
350        addCmd(TBaseType.rrw_show, "system", "functions", ESqlStatementType.sstShow);
351        addCmd(TBaseType.rrw_show, "table", "extended", ESqlStatementType.sstShow);
352        addCmd(TBaseType.rrw_show, "tables", ESqlStatementType.sstShow);
353        addCmd(TBaseType.rrw_show, "tblproperties", ESqlStatementType.sstShow);
354        addCmd(TBaseType.rrw_show, "user", "functions", ESqlStatementType.sstShow);
355        addCmd(TBaseType.rrw_show, "users", ESqlStatementType.sstShow);
356        addCmd(TBaseType.rrw_show, "views", ESqlStatementType.sstShow);
357
358        addCmd(TBaseType.rrw_databricks_sync, "schema", ESqlStatementType.sstsync);
359        addCmd(TBaseType.rrw_databricks_sync, "table", ESqlStatementType.sstsync);
360
361        addCmd(TBaseType.rrw_start, "transaction", ESqlStatementType.sstStartTransaction);
362        addCmd(TBaseType.rrw_truncate, "table", ESqlStatementType.ssttruncatetable);
363        addCmd(TBaseType.rrw_databricks_uncache, "table", ESqlStatementType.sstUnCacheTable);
364        addCmd(TBaseType.rrw_update, ESqlStatementType.sstupdate);
365
366        // USE commands - longer patterns first
367        addCmd(TBaseType.rrw_use, "catalog", ESqlStatementType.sstUseCatalog);
368        addCmd(TBaseType.rrw_use, "database", ESqlStatementType.sstUseSchema);
369        addCmd(TBaseType.rrw_use, "schema", ESqlStatementType.sstUseSchema);
370        addCmd(TBaseType.rrw_use, ESqlStatementType.sstUseSchema);
371
372        addCmd(TBaseType.rrw_databricks_vacuum, ESqlStatementType.sstVacuum);
373        addCmd(TBaseType.rrw_values, ESqlStatementType.sstValues);
374        addCmd(TBaseType.rrw_prepare, ESqlStatementType.sstprepare);
375    }
376
377    @Override
378    public TCustomSqlStatement issql(TSourceToken token, EFindSqlStateType state, TCustomSqlStatement currentStatement) {
379        TCustomSqlStatement ret = null;
380        int k;
381        boolean lcisnewsql;
382        TSourceToken lcpprevsolidtoken, lcnextsolidtoken;
383
384        gnewsqlstatementtype = ESqlStatementType.sstinvalid;
385
386        if ((token.tokencode == TBaseType.cmtdoublehyphen)
387                || (token.tokencode == TBaseType.cmtslashstar)
388                || (token.tokencode == TBaseType.lexspace)
389                || (token.tokencode == TBaseType.lexnewline)
390                || (token.tokentype == ETokenType.ttsemicolon)) {
391            return ret;
392        }
393
394        int lcpos = token.posinlist;
395        TSourceTokenList lcsourcetokenlist = token.container;
396        TCustomSqlStatement lccurrentsqlstatement = currentStatement;
397
398        // Subquery after semicolon || at first line
399        if ((state == EFindSqlStateType.stnormal) && (token.tokentype == ETokenType.ttleftparenthesis)) {
400            k = lcsourcetokenlist.solidtokenafterpos(lcpos, TBaseType.rrw_select, 1, "(");
401            if (k > 0) {
402                ret = new TSelectSqlStatement(vendor);
403            }
404            return ret;
405        }
406
407        // CTE
408        if ((state == EFindSqlStateType.stnormal) && (token.tokencode == TBaseType.rrw_with)) {
409            ret = findcte(token);
410            if ((ret != null)) return ret;
411        }
412
413        gnewsqlstatementtype = getStatementTypeForToken(token);
414
415        TSourceToken lcprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcpos);
416
417        if ((gnewsqlstatementtype == ESqlStatementType.sstinvalid) && (token.tokencode == TBaseType.rrw_create)) {
418            TSourceToken viewToken = token.container.searchToken(TBaseType.rrw_view, "", token, 15);
419            if (viewToken != null) {
420                gnewsqlstatementtype = ESqlStatementType.sstcreateview;
421            }
422        }
423
424        switch (gnewsqlstatementtype) {
425            case sstinvalid: {
426                ret = null;
427                break;
428            }
429            case sstselect: {
430                lcisnewsql = true;
431
432                if (state != EFindSqlStateType.stnormal) {
433                    if (TBaseType.assigned(lcprevsolidtoken)) {
434                        if (lcprevsolidtoken.tokentype == ETokenType.ttleftparenthesis)
435                            lcisnewsql = false; // subquery
436                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_union)
437                            lcisnewsql = false;
438                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_intersect)
439                            lcisnewsql = false;
440                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_minus)
441                            lcisnewsql = false;
442                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_except)
443                            lcisnewsql = false;
444                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_return)
445                            lcisnewsql = false;
446                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_as) {
447                            if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatetable)
448                                lcisnewsql = false;
449                            if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreateview)
450                                lcisnewsql = false;
451                        }
452
453                        if (lcisnewsql && (lcprevsolidtoken.tokencode == TBaseType.rrw_all)) {
454                            lcpprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcprevsolidtoken.posinlist);
455                            if (TBaseType.assigned(lcpprevsolidtoken)) {
456                                if (lcpprevsolidtoken.tokencode == TBaseType.rrw_union)
457                                    lcisnewsql = false;
458                            }
459                        }
460                    }
461
462                    if (TBaseType.assigned(lccurrentsqlstatement)) {
463                        if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstinsert)
464                            lcisnewsql = false;
465                    }
466                }
467
468                if (lcisnewsql)
469                    ret = new TSelectSqlStatement(vendor);
470                break;
471            }
472            case sstinsert: {
473                lcisnewsql = true;
474                if (state != EFindSqlStateType.stnormal) {
475                    if (TBaseType.assigned(lccurrentsqlstatement)) {
476                    }
477                }
478
479                if (lcisnewsql)
480                    ret = new TInsertSqlStatement(vendor);
481                ret.sqlstatementtype = gnewsqlstatementtype;
482                break;
483            }
484            case sstdelete: {
485                lcisnewsql = true;
486
487                if (state != EFindSqlStateType.stnormal) {
488                    lcprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcpos);
489                    if (TBaseType.assigned(lcprevsolidtoken)) {
490                        if (lcprevsolidtoken.tokencode == TBaseType.rrw_on)
491                            lcisnewsql = false;
492                    }
493
494                    if (TBaseType.assigned(lccurrentsqlstatement)) {
495                    }
496                }
497
498                if (lcisnewsql)
499                    ret = new TDeleteSqlStatement(vendor);
500                break;
501            }
502            case sstaltertable: {
503                ret = new TAlterTableStatement(vendor);
504                break;
505            }
506            case sstalterfunction: {
507                ret = new TAlterFunctionStmt(vendor);
508                break;
509            }
510            case sstAlterSchema: {
511                ret = new TAlterSchemaStmt(vendor);
512                break;
513            }
514            case sstanalyzeTable: {
515                ret = new TAnalyzeStmt(vendor);
516                break;
517            }
518            case sstcall: {
519                ret = new TCallStatement(vendor);
520                break;
521            }
522            case sstcommit: {
523                ret = new TCommitStmt(vendor);
524                break;
525            }
526            case sstcreatefunction: {
527                ret = new TCreateFunctionStmt(vendor);
528                break;
529            }
530            case sstcreaterole: {
531                ret = new TCreateRoleStmt(vendor);
532                break;
533            }
534            case sstcreateschema: {
535                ret = new TCreateSchemaSqlStatement(vendor);
536                break;
537            }
538            case sstcreatetable: {
539                ret = new TCreateTableSqlStatement(vendor);
540                break;
541            }
542            case sstcreateview: {
543                ret = new TCreateViewSqlStatement(vendor);
544                break;
545            }
546            case sstpostgresqlDeallocate: {
547                ret = new TUnknownSqlStatement(vendor);
548                ret.sqlstatementtype = gnewsqlstatementtype;
549                break;
550            }
551            case sstdropfunction: {
552                ret = new TDropFunctionStmt(vendor);
553                break;
554            }
555            case sstdroprole: {
556                ret = new TDropRoleStmt(vendor);
557                break;
558            }
559            case sstdropschema: {
560                ret = new TDropSchemaSqlStatement(vendor);
561                break;
562            }
563            case sstdroptable: {
564                ret = new TDropTableSqlStatement(vendor);
565                break;
566            }
567            case sstdropview: {
568                ret = new TDropViewSqlStatement(vendor);
569                break;
570            }
571            case sstExecute: {
572                ret = new TExecuteSqlStatement(vendor);
573                break;
574            }
575            case sstExplain: {
576                ret = new TExplainPlan(vendor);
577                break;
578            }
579            case sstGrant: {
580                ret = new TGrantStmt(vendor);
581                break;
582            }
583            case sstprepare: {
584                ret = new TPrepareStmt(vendor);
585                break;
586            }
587            case sstset:
588            case sstReset: {
589                lcisnewsql = true;
590                if (state != EFindSqlStateType.stnormal) {
591                    if (TBaseType.assigned(lccurrentsqlstatement)) {
592                        lcisnewsql = false;
593                    }
594                }
595
596                if (lcisnewsql) {
597                    ret = new TSetStmt(vendor);
598                }
599                break;
600            }
601            case sstShow: {
602                ret = new TShowStmt(vendor);
603                ret.sqlstatementtype = gnewsqlstatementtype;
604                break;
605            }
606            case sstStartTransaction: {
607                ret = new TStartTransactionStmt(vendor);
608                break;
609            }
610            case sstValues: {
611                ret = new TSelectSqlStatement(vendor);
612                break;
613            }
614            case sstResetSession: {
615                ret = new TResetSessionStmt(vendor);
616                break;
617            }
618            case sstCreateExternallocation:
619                ret = new TCreateExternalLocationStmt(vendor);
620                break;
621            case sstList: {
622                ret = new TListStmt(vendor);
623                break;
624            }
625            case sstRevoke:
626                ret = new TRevokeStmt(vendor);
627                break;
628            case sstaltercredental:
629                ret = new TAlterCredentialStmt(vendor);
630                break;
631            case sstdescribeCatalog:
632            case sstdescribeFunction:
633            case sstdescribeProvider:
634            case sstdescribeQuery:
635            case sstdescribeRecipient:
636            case sstdescribeSchema:
637            case sstdescribeShare:
638            case sstdescribeTable:
639            case sstdescribeDatabase:
640            case sstdescribeLocation:
641            case sstdescribeCredential:
642            case sstdescribe:
643                ret = new TDescribeStmt(vendor);
644                break;
645            case sstUseCatalog:
646            case sstUseSchema:
647            case sstUseDatabase:
648            case sstUse:
649                ret = new TUseDatabase(vendor);
650                break;
651            case sstAnalyzeTable:
652                ret = new TAnalyzeStmt(vendor);
653                break;
654            case sstCreategroup:
655                ret = new TCreateGroup(vendor);
656                break;
657            case sstAlterGroup:
658                ret = new TAlterGroup(vendor);
659                break;
660            case sstDeny:
661                ret = new TDenyStmt(vendor);
662                break;
663            case sstDropGroup:
664                ret = new TDropGroup(vendor);
665                break;
666            case sstmsckrepairtable:
667                ret = new TMSCKStmt(vendor);
668                break;
669            case sstcreatecatalog:
670                ret = new TCreateCatalogStmt(vendor);
671                break;
672            case sstConvertToDelta:
673                ret = new TConvertToDeltaStmt(vendor);
674                break;
675            case sstOptimize:
676                ret = new TOptimizeStmt(vendor);
677                break;
678            case sstRestoreTable:
679                ret = new TRestoreTableStmt(vendor);
680                break;
681            case sstReorgTable:
682                ret = new TReorgTableStmt(vendor);
683                break;
684            case sstVacuum:
685                ret = new TVacuumStmt(vendor);
686                break;
687            case sstmerge:
688                ret = new TMergeSqlStatement(vendor);
689                break;
690            case sstcreatematerializedview:
691                ret = new TCreateMaterializedSqlStatement(vendor);
692                break;
693            default: {
694                ret = new TUnknownSqlStatement(vendor);
695                ret.sqlstatementtype = gnewsqlstatementtype;
696                break;
697            }
698        }
699
700        return ret;
701    }
702}