001package gudusoft.gsqlparser.sqlcmds;
002
003import gudusoft.gsqlparser.*;
004import gudusoft.gsqlparser.stmt.*;
005import gudusoft.gsqlparser.stmt.mysql.*;
006
007/**
008 * ClickHouse SQL command resolver.
009 * Handles ClickHouse-specific statement detection and command resolution.
010 * Based on MySQL command resolver since ClickHouse grammar is derived from MySQL.
011 *
012 * @since 3.2.0.0
013 */
014public class TSqlCmdsClickhouse extends AbstractSqlCmds {
015
016    public TSqlCmdsClickhouse() {
017        super(EDbVendor.dbvclickhouse);
018    }
019
020    @Override
021    protected void initializeCommands() {
022        // ClickHouse commands - based on MySQL with ClickHouse-specific adaptations
023
024        // ALTER commands
025        addCmd(TBaseType.rrw_alter, "database", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlalterdatabase);
026        addCmd(TBaseType.rrw_alter, "table", " ", " ", " ", " ", " ", ESqlStatementType.sstaltertable);
027        addCmd(TBaseType.rrw_alter, "view", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlalterview);
028
029        // CREATE commands
030        addCmd(TBaseType.rrw_create, "database", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlcreatedatabase);
031        addCmd(TBaseType.rrw_create, "function", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlcreatefunction);
032        addCmd(TBaseType.rrw_create, "index", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlcreateindex);
033        addCmd(TBaseType.rrw_create, "or", "replace", "function", " ", " ", " ", ESqlStatementType.sstmysqlcreatefunction);
034        addCmd(TBaseType.rrw_create, "or", "replace", "table", " ", " ", " ", ESqlStatementType.sstcreatetable);
035        addCmd(TBaseType.rrw_create, "or", "replace", "*", "*", "*", "view", ESqlStatementType.sstcreateview);
036        addCmd(TBaseType.rrw_create, "or", "replace", "view", " ", " ", " ", ESqlStatementType.sstcreateview);
037        addCmd(TBaseType.rrw_create, "materialized", "view", " ", " ", " ", " ", ESqlStatementType.sstcreatematerializedview);
038        addCmd(TBaseType.rrw_create, "window", "view", " ", " ", " ", " ", ESqlStatementType.sstClickhouseCreateWindowView);
039        addCmd(TBaseType.rrw_create, "temporary", "table", " ", " ", " ", " ", ESqlStatementType.sstcreatetable);
040        addCmd(TBaseType.rrw_create, "temp", "table", " ", " ", " ", " ", ESqlStatementType.sstcreatetable);
041        addCmd(TBaseType.rrw_create, "table", " ", " ", " ", " ", " ", ESqlStatementType.sstcreatetable);
042        addCmd(TBaseType.rrw_create, "*", "*", "*", "*", "*", "view", ESqlStatementType.sstcreateview);
043        addCmd(TBaseType.rrw_create, "view", " ", " ", " ", " ", " ", ESqlStatementType.sstcreateview);
044
045        // ClickHouse access-entity and admin DDL. All route through the
046        // default branch of createstatement to a typed TUnknownSqlStatement
047        // (the sstClickhouseSystem pattern): recognized and typed, no deep
048        // AST yet. Without these the splitter hits its error-token path and
049        // reports "Error when tokenize" on perfectly valid statements.
050        addCmd(TBaseType.rrw_create, "user", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseCreateUser);
051        addCmd(TBaseType.rrw_create, "role", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseCreateRole);
052        addCmd(TBaseType.rrw_create, "row", "policy", " ", " ", " ", " ", ESqlStatementType.sstClickhouseCreateRowPolicy);
053        addCmd(TBaseType.rrw_create, "policy", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseCreateRowPolicy);
054        addCmd(TBaseType.rrw_create, "quota", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseCreateQuota);
055        addCmd(TBaseType.rrw_create, "settings", "profile", " ", " ", " ", " ", ESqlStatementType.sstClickhouseCreateSettingsProfile);
056        addCmd(TBaseType.rrw_create, "profile", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseCreateSettingsProfile);
057        addCmd(TBaseType.rrw_create, "masking", "policy", " ", " ", " ", " ", ESqlStatementType.sstClickhouseCreateMaskingPolicy);
058        addCmd(TBaseType.rrw_create, "named", "collection", " ", " ", " ", " ", ESqlStatementType.sstClickhouseCreateNamedCollection);
059        addCmd(TBaseType.rrw_create, "dictionary", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseCreateDictionary);
060        addCmd(TBaseType.rrw_create, "or", "replace", "dictionary", " ", " ", " ", ESqlStatementType.sstClickhouseCreateDictionary);
061        addCmd(TBaseType.rrw_create, "hypothetical", "index", " ", " ", " ", " ", ESqlStatementType.sstClickhouseCreateHypotheticalIndex);
062        addCmd(TBaseType.rrw_alter, "user", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseAlterUser);
063        addCmd(TBaseType.rrw_alter, "role", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseAlterRole);
064        addCmd(TBaseType.rrw_alter, "row", "policy", " ", " ", " ", " ", ESqlStatementType.sstClickhouseAlterRowPolicy);
065        addCmd(TBaseType.rrw_alter, "policy", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseAlterRowPolicy);
066        addCmd(TBaseType.rrw_alter, "quota", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseAlterQuota);
067        addCmd(TBaseType.rrw_alter, "settings", "profile", " ", " ", " ", " ", ESqlStatementType.sstClickhouseAlterSettingsProfile);
068        addCmd(TBaseType.rrw_alter, "profile", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseAlterSettingsProfile);
069        addCmd(TBaseType.rrw_alter, "masking", "policy", " ", " ", " ", " ", ESqlStatementType.sstClickhouseAlterMaskingPolicy);
070        addCmd(TBaseType.rrw_alter, "named", "collection", " ", " ", " ", " ", ESqlStatementType.sstClickhouseAlterNamedCollection);
071        addCmd(TBaseType.rrw_drop, "named", "collection", " ", " ", " ", " ", ESqlStatementType.sstClickhouseDropNamedCollection);
072        addCmd(TBaseType.rrw_check, "table", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseCheck);
073        addCmd(TBaseType.rrw_check, "database", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseCheck);
074        addCmd(TBaseType.rrw_check, "grant", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseCheck);
075        addCmd(TBaseType.rrw_check, "all", "tables", " ", " ", " ", " ", ESqlStatementType.sstClickhouseCheck);
076        addCmd(TBaseType.rrw_execute, "as", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseExecuteAs);
077        addCmd(TBaseType.rrw_clickhouse_exists, "table", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseExists);
078        addCmd(TBaseType.rrw_clickhouse_exists, "temporary", "table", " ", " ", " ", " ", ESqlStatementType.sstClickhouseExists);
079        addCmd(TBaseType.rrw_clickhouse_exists, "database", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseExists);
080        addCmd(TBaseType.rrw_clickhouse_exists, "dictionary", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseExists);
081        addCmd(TBaseType.rrw_move, "user", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseMoveAccessEntity);
082        addCmd(TBaseType.rrw_move, "role", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseMoveAccessEntity);
083        addCmd(TBaseType.rrw_move, "quota", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseMoveAccessEntity);
084        addCmd(TBaseType.rrw_move, "row", "policy", " ", " ", " ", " ", ESqlStatementType.sstClickhouseMoveAccessEntity);
085        addCmd(TBaseType.rrw_move, "settings", "profile", " ", " ", " ", " ", ESqlStatementType.sstClickhouseMoveAccessEntity);
086        addCmd(TBaseType.rrw_clickhouse_exchange, "tables", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseExchangeTables);
087        addCmd(TBaseType.rrw_clickhouse_exchange, "dictionaries", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseExchangeTables);
088        addCmd(TBaseType.rrw_clickhouse_undrop, "table", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseUndropTable);
089        addCmd(TBaseType.rrw_replace, "table", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseReplaceTable);
090        addCmd(TBaseType.rrw_rename, "*", "to", " ", " ", " ", " ", ESqlStatementType.sstClickhouseRename);
091        // Two EXPLAIN variants whose payload the in-procedure statement subset
092        // cannot host (TABLE OVERRIDE takes a table function plus PARTITION BY;
093        // AST ALTER carries ClickHouse mutations). Only these two spellings are
094        // routed to a typed TUnknownSqlStatement; every other EXPLAIN keeps its
095        // fully parsed statement AST.
096        addCmd(TBaseType.rrw_explain, "table", "override", " ", " ", " ", " ", ESqlStatementType.sstClickhouseExplain);
097        addCmd(TBaseType.rrw_explain, "ast", "alter", " ", " ", " ", " ", ESqlStatementType.sstClickhouseExplain);
098        addCmd(TBaseType.rrw_show, "access", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseShow);
099        addCmd(TBaseType.rrw_show, "changed", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseShow);
100        addCmd(TBaseType.rrw_show, "cluster", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseShow);
101        addCmd(TBaseType.rrw_show, "clusters", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseShow);
102        addCmd(TBaseType.rrw_show, "create", "dictionary", " ", " ", " ", " ", ESqlStatementType.sstClickhouseShow);
103        addCmd(TBaseType.rrw_show, "create", "temporary", "table", " ", " ", " ", ESqlStatementType.sstClickhouseShow);
104        addCmd(TBaseType.rrw_show, "dictionaries", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseShow);
105        addCmd(TBaseType.rrw_show, "extended", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseShow);
106        addCmd(TBaseType.rrw_show, "filesystem", "caches", " ", " ", " ", " ", ESqlStatementType.sstClickhouseShow);
107        addCmd(TBaseType.rrw_show, "grants", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseShow);
108        addCmd(TBaseType.rrw_show, "index", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseShow);
109        addCmd(TBaseType.rrw_show, "indexes", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseShow);
110        addCmd(TBaseType.rrw_show, "keys", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseShow);
111        addCmd(TBaseType.rrw_show, "merges", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseShow);
112        addCmd(TBaseType.rrw_show, "quotas", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseShow);
113        addCmd(TBaseType.rrw_show, "roles", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseShow);
114        addCmd(TBaseType.rrw_show, "row", "policies", " ", " ", " ", " ", ESqlStatementType.sstClickhouseShow);
115        addCmd(TBaseType.rrw_show, "settings", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseShow);
116        addCmd(TBaseType.rrw_show, "users", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseShow);
117        addCmd(TBaseType.rrw_show, "profiles", " ", " ", " ", " ", " ", ESqlStatementType.sstClickhouseShow);
118
119        // DELETE
120        addCmd(TBaseType.rrw_delete, " ", " ", " ", " ", " ", " ", ESqlStatementType.sstdelete);
121
122        // DESCRIBE / DESC
123        addCmd(TBaseType.rrw_describe, " ", " ", " ", " ", " ", " ", ESqlStatementType.sstdescribe);
124        addCmd(TBaseType.rrw_mysql_desc, " ", " ", " ", " ", " ", " ", ESqlStatementType.sstdescribe);
125
126        // DROP commands
127        addCmd(TBaseType.rrw_drop, "database", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqldropdatabase);
128        addCmd(TBaseType.rrw_drop, "function", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqldropfunction);
129        addCmd(TBaseType.rrw_drop, "index", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqldropindex);
130        addCmd(TBaseType.rrw_drop, "table", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqldroptable);
131        addCmd(TBaseType.rrw_drop, "temporary", "table", " ", " ", " ", " ", ESqlStatementType.sstmysqldroptable);
132        addCmd(TBaseType.rrw_drop, "view", " ", " ", " ", " ", " ", ESqlStatementType.sstdropview);
133
134        // EXPLAIN
135        addCmd(TBaseType.rrw_explain, " ", " ", " ", " ", " ", " ", ESqlStatementType.sstExplain);
136
137        // GRANT / REVOKE
138        addCmd(TBaseType.rrw_grant, " ", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlgrant);
139        addCmd(TBaseType.rrw_revoke, " ", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlrevoke);
140
141        // INSERT
142        addCmd(TBaseType.rrw_insert, " ", " ", " ", " ", " ", " ", ESqlStatementType.sstinsert);
143
144        // OPTIMIZE
145        addCmd(TBaseType.rrw_optimize, "table", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqloptimizetable);
146
147        // RENAME
148        addCmd(TBaseType.rrw_rename, "table", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlrenametable);
149
150        // SELECT
151        addCmd(TBaseType.rrw_select, " ", " ", " ", " ", " ", " ", ESqlStatementType.sstselect);
152
153        // SET
154        addCmd(TBaseType.rrw_set, " ", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlset);
155
156        // SHOW commands (ClickHouse supports a subset of MySQL SHOW)
157        addCmd(TBaseType.rrw_show, "columns", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlshowcolumns);
158        addCmd(TBaseType.rrw_show, "create", "database", " ", " ", " ", " ", ESqlStatementType.sstmysqlshowcreatedatabase);
159        addCmd(TBaseType.rrw_show, "create", "table", " ", " ", " ", " ", ESqlStatementType.sstmysqlshowcreatetable);
160        addCmd(TBaseType.rrw_show, "create", "view", " ", " ", " ", " ", ESqlStatementType.sstmysqlshowcreateview);
161        addCmd(TBaseType.rrw_show, "databases", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlshowdatabases);
162        addCmd(TBaseType.rrw_show, "processlist", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlshowprocesslist);
163        addCmd(TBaseType.rrw_show, "tables", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlshowtables);
164
165        // TRUNCATE
166        addCmd(TBaseType.rrw_truncate, " ", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqltruncate);
167
168        // UPDATE
169        addCmd(TBaseType.rrw_update, " ", " ", " ", " ", " ", " ", ESqlStatementType.sstupdate);
170
171        // USE
172        addCmd(TBaseType.rrw_use, " ", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqluse);
173    }
174
175    @Override
176    protected String getToken1Str(int token1) {
177        // Handle ClickHouse vendor-specific reserved words
178        switch (token1) {
179            case TBaseType.rrw_mysql_desc:
180                return "desc";
181            default:
182                return null;
183        }
184    }
185
186    @Override
187    public TCustomSqlStatement issql(TSourceToken pcst, EFindSqlStateType pstate, TCustomSqlStatement psqlstatement) {
188        TCustomSqlStatement ret = null;
189        int k;
190        boolean lcisnewsql;
191        TSourceToken lcpprevsolidtoken, lcnextsolidtoken;
192
193        gnewsqlstatementtype = ESqlStatementType.sstinvalid;
194
195        if ((pcst.tokencode == TBaseType.cmtdoublehyphen)
196                || (pcst.tokencode == TBaseType.cmtslashstar)
197                || (pcst.tokencode == TBaseType.lexspace)
198                || (pcst.tokencode == TBaseType.lexnewline)
199                || (pcst.tokentype == ETokenType.ttsemicolon)) {
200            return ret;
201        }
202
203        int lcpos = pcst.posinlist;
204        TSourceTokenList lcsourcetokenlist = pcst.container;
205        TCustomSqlStatement lccurrentsqlstatement = psqlstatement;
206
207        // subquery after semicolon || at first line
208        if ((pstate == EFindSqlStateType.stnormal) && (pcst.tokentype == ETokenType.ttleftparenthesis)) {
209            k = lcsourcetokenlist.solidtokenafterpos(lcpos, TBaseType.rrw_select, 1, "(");
210            if (k > 0) {
211                ret = new TSelectSqlStatement(vendor);
212            }
213            return ret;
214        }
215
216        // cte
217        if ((pstate == EFindSqlStateType.stnormal) && (pcst.tokencode == TBaseType.rrw_with)) {
218            ret = findcte(pcst);
219            if ((ret != null)) return ret;
220        }
221
222        gnewsqlstatementtype = getStatementTypeForToken(pcst);
223
224        TSourceToken lcprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcpos);
225
226        if (pcst.tokencode == TBaseType.rrw_create) {
227            TSourceToken nextToken = lcsourcetokenlist.nextsolidtoken(lcpos, 1, false);
228            if (TBaseType.assigned(nextToken) && nextToken.toString().equalsIgnoreCase("window")) {
229                TSourceToken viewAfterWindow = lcsourcetokenlist.nextsolidtoken(nextToken.posinlist, 1, false);
230                if (TBaseType.assigned(viewAfterWindow) && viewAfterWindow.toString().equalsIgnoreCase("view")) {
231                    gnewsqlstatementtype = ESqlStatementType.sstClickhouseCreateWindowView;
232                }
233            }
234        }
235
236        if (pcst.toString().equalsIgnoreCase("SYSTEM")) {
237            gnewsqlstatementtype = ESqlStatementType.sstClickhouseSystem;
238        }
239
240        if (pcst.toString().equalsIgnoreCase("DETACH")) {
241            gnewsqlstatementtype = ESqlStatementType.sstClickhouseDetach;
242        }
243
244        if (pcst.toString().equalsIgnoreCase("ATTACH")) {
245            gnewsqlstatementtype = ESqlStatementType.sstClickhouseAttach;
246        }
247
248        if (pcst.tokencode == TBaseType.rrw_kill) {
249            gnewsqlstatementtype = ESqlStatementType.sstClickhouseKill;
250        }
251
252        if (pcst.toString().equalsIgnoreCase("WATCH")) {
253            gnewsqlstatementtype = ESqlStatementType.sstClickhouseWatch;
254        }
255
256        if ((gnewsqlstatementtype == ESqlStatementType.sstinvalid) && (pcst.tokencode == TBaseType.rrw_create)) {
257            TSourceToken viewToken = pcst.container.searchToken(TBaseType.rrw_view, "", pcst, 15);
258            if (viewToken != null) {
259                gnewsqlstatementtype = ESqlStatementType.sstcreateview;
260            }
261        }
262
263        switch (gnewsqlstatementtype) {
264            case sstinvalid: {
265                ret = null;
266                break;
267            }
268            case sstselect: {
269                lcisnewsql = true;
270
271                if (pstate != EFindSqlStateType.stnormal) {
272                    if (TBaseType.assigned(lcprevsolidtoken)) {
273                        if (lcprevsolidtoken.tokentype == ETokenType.ttleftparenthesis)
274                            lcisnewsql = false;
275                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_union)
276                            lcisnewsql = false;
277                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_intersect)
278                            lcisnewsql = false;
279                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_except)
280                            lcisnewsql = false;
281                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_as) {
282                            if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatetable)
283                                lcisnewsql = false;
284                            if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreateview)
285                                lcisnewsql = false;
286                            if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatematerializedview)
287                                lcisnewsql = false;
288                            if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstClickhouseCreateWindowView)
289                                lcisnewsql = false;
290                        }
291
292                        if (lcisnewsql && (lcprevsolidtoken.tokencode == TBaseType.rrw_all)) {
293                            lcpprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcprevsolidtoken.posinlist);
294                            if (TBaseType.assigned(lcpprevsolidtoken)) {
295                                if (lcpprevsolidtoken.tokencode == TBaseType.rrw_union)
296                                    lcisnewsql = false;
297                            }
298                        }
299                    }
300
301                    if (TBaseType.assigned(lccurrentsqlstatement)) {
302                        if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstinsert)
303                            lcisnewsql = false;
304                    }
305                }
306
307                if (lcisnewsql)
308                    ret = new TSelectSqlStatement(vendor);
309                break;
310            }
311            case sstinsert: {
312                lcisnewsql = true;
313                if (pstate != EFindSqlStateType.stnormal) {
314                    if (TBaseType.assigned(lccurrentsqlstatement)) {
315                        // ClickHouse doesn't have stored procedures
316                    }
317                }
318
319                if (lcisnewsql)
320                    ret = new TInsertSqlStatement(vendor);
321                ret.sqlstatementtype = gnewsqlstatementtype;
322                break;
323            }
324            case sstupdate: {
325                lcisnewsql = true;
326                if (pstate != EFindSqlStateType.stnormal) {
327                    lcprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcpos);
328                    if (TBaseType.assigned(lcprevsolidtoken)) {
329                        if (lcprevsolidtoken.tokencode == TBaseType.rrw_on)
330                            lcisnewsql = false;
331                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_for)
332                            lcisnewsql = false;
333                    }
334
335                    lcnextsolidtoken = lcsourcetokenlist.nextsolidtoken(lcpos, 1, false);
336                    if (TBaseType.assigned(lcnextsolidtoken)) {
337                        if (lcnextsolidtoken.tokentype == ETokenType.ttleftparenthesis) {
338                            k = lcsourcetokenlist.solidtokenafterpos(lcnextsolidtoken.posinlist, TBaseType.rrw_select, 1, "(");
339                            if (k == 0) lcisnewsql = false;
340                        }
341                    }
342                }
343
344                if (lcisnewsql) {
345                    ret = new TUpdateSqlStatement(vendor);
346                    ret.dummytag = 1;
347                }
348                break;
349            }
350            case sstdelete: {
351                lcisnewsql = true;
352
353                if (pstate != EFindSqlStateType.stnormal) {
354                    lcprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcpos);
355                    if (TBaseType.assigned(lcprevsolidtoken)) {
356                        if (lcprevsolidtoken.tokencode == TBaseType.rrw_on)
357                            lcisnewsql = false;
358                    }
359                }
360
361                if (lcisnewsql)
362                    ret = new TDeleteSqlStatement(vendor);
363                break;
364            }
365            case sstcreatetable: {
366                ret = new TCreateTableSqlStatement(vendor);
367                break;
368            }
369            case sstcreateview: {
370                ret = new TCreateViewSqlStatement(vendor);
371                break;
372            }
373            case sstcreatematerializedview: {
374                ret = new TCreateMaterializedSqlStatement(vendor);
375                break;
376            }
377            case sstClickhouseCreateWindowView: {
378                ret = new TCreateViewSqlStatement(vendor);
379                ret.sqlstatementtype = ESqlStatementType.sstClickhouseCreateWindowView;
380                break;
381            }
382            case sstmysqlcreateindex: {
383                ret = new TCreateIndexSqlStatement(vendor);
384                break;
385            }
386            case sstcreatedatabase:
387            case sstmysqlcreatedatabase: {
388                ret = new TCreateDatabaseSqlStatement(vendor);
389                break;
390            }
391            case sstmysqldroptable:
392            case sstdroptable: {
393                ret = new TDropTableSqlStatement(vendor);
394                break;
395            }
396            case sstdropview: {
397                ret = new TDropViewSqlStatement(vendor);
398                break;
399            }
400            case sstdropindex:
401            case sstmysqldropindex: {
402                ret = new TDropIndexSqlStatement(vendor);
403                break;
404            }
405            case sstaltertable: {
406                ret = new TAlterTableStatement(vendor);
407                break;
408            }
409            case sstmysqlset: {
410                ret = new TSetStmt(vendor);
411                break;
412            }
413            case sstmysqlcreatefunction: {
414                ret = new TCreateFunctionStmt(vendor);
415                break;
416            }
417            case sstmysqltruncate: {
418                ret = new TTruncateStatement(vendor);
419                break;
420            }
421            case sstdescribe: {
422                ret = new TDescribeStmt(vendor);
423                break;
424            }
425            case sstExplain: {
426                ret = new TExplainPlan(vendor);
427                break;
428            }
429            case sstClickhouseSystem: {
430                ret = new TUnknownSqlStatement(vendor);
431                ret.sqlstatementtype = ESqlStatementType.sstClickhouseSystem;
432                break;
433            }
434            case sstClickhouseDetach: {
435                ret = new TUnknownSqlStatement(vendor);
436                ret.sqlstatementtype = ESqlStatementType.sstClickhouseDetach;
437                break;
438            }
439            case sstClickhouseAttach: {
440                ret = new TUnknownSqlStatement(vendor);
441                ret.sqlstatementtype = ESqlStatementType.sstClickhouseAttach;
442                break;
443            }
444            case sstClickhouseKill: {
445                ret = new TUnknownSqlStatement(vendor);
446                ret.sqlstatementtype = ESqlStatementType.sstClickhouseKill;
447                break;
448            }
449            case sstClickhouseWatch: {
450                ret = new TUnknownSqlStatement(vendor);
451                ret.sqlstatementtype = ESqlStatementType.sstClickhouseWatch;
452                break;
453            }
454            case sstmysqloptimizetable: {
455                ret = new TMySQLOptimizeTableStmt(vendor);
456                break;
457            }
458            case sstmysqlalterview: {
459                ret = new TAlterViewStatement(vendor);
460                break;
461            }
462            case sstmysqldropfunction: {
463                ret = new TDropFunctionStmt(vendor);
464                break;
465            }
466            case sstmysqlrenametable: {
467                ret = new TRenameStmt(vendor);
468                break;
469            }
470            case sstmysqluse: {
471                ret = new TUseDatabase(vendor);
472                break;
473            }
474            case sstmysqlshowcolumns:
475            case sstmysqlshowcreatedatabase:
476            case sstmysqlshowcreatetable:
477            case sstmysqlshowcreateview:
478            case sstmysqlshowdatabases:
479            case sstmysqlshowprocesslist:
480            case sstmysqlshowtables:
481                ret = new TMySQLShowStmt(vendor);
482                ret.sqlstatementtype = gnewsqlstatementtype;
483                break;
484            default: {
485                ret = new TUnknownSqlStatement(vendor);
486                ret.sqlstatementtype = gnewsqlstatementtype;
487                break;
488            }
489        }
490
491        return ret;
492    }
493}