001package gudusoft.gsqlparser.sqlcmds;
002
003import gudusoft.gsqlparser.*;
004import gudusoft.gsqlparser.stmt.*;
005
006/**
007 * Apache Doris SQL command resolver.
008 * Handles Doris-specific statement detection and command resolution.
009 *
010 * Doris is MySQL-compatible, so this extends MySQL commands with Doris-specific additions.
011 *
012 * @since 3.2.0.0
013 */
014public class TSqlCmdsDoris extends AbstractSqlCmds {
015
016    public TSqlCmdsDoris() {
017        super(EDbVendor.dbvdoris);
018    }
019
020    @Override
021    protected String getToken1Str(int token1) {
022        switch (token1) {
023            case TBaseType.rrw_doris_export:
024                return "EXPORT";
025            case TBaseType.rrw_doris_switch:
026                return "SWITCH";
027            case TBaseType.rrw_doris_admin:
028                return "ADMIN";
029            case TBaseType.rrw_doris_recover:
030                return "RECOVER";
031            case TBaseType.rrw_doris_cancel:
032                return "CANCEL";
033            case TBaseType.rrw_doris_pause:
034                return "PAUSE";
035            case TBaseType.rrw_doris_resume:
036                return "RESUME";
037            default:
038                return null;
039        }
040    }
041
042    @Override
043    protected void initializeCommands() {
044        // Standard SQL commands (SELECT, INSERT, UPDATE, DELETE)
045        addCmd(TBaseType.rrw_select, " ", " ", " ", " ", " ", " ", ESqlStatementType.sstselect);
046        addCmd(TBaseType.rrw_insert, " ", " ", " ", " ", " ", " ", ESqlStatementType.sstinsert);
047        addCmd(TBaseType.rrw_update, " ", " ", " ", " ", " ", " ", ESqlStatementType.sstupdate);
048        addCmd(TBaseType.rrw_delete, " ", " ", " ", " ", " ", " ", ESqlStatementType.sstdelete);
049
050        // MERGE INTO (Doris supports this)
051        addCmd(TBaseType.rrw_merge, " ", " ", " ", " ", " ", " ", ESqlStatementType.sstmerge);
052
053        // CREATE statements
054        addCmd(TBaseType.rrw_create, "database", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlcreatedatabase);
055        addCmd(TBaseType.rrw_create, "schema", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlcreatedatabase);
056        addCmd(TBaseType.rrw_create, "external", "table", " ", " ", " ", " ", ESqlStatementType.sstcreatetable);
057        addCmd(TBaseType.rrw_create, "table", " ", " ", " ", " ", " ", ESqlStatementType.sstcreatetable);
058        addCmd(TBaseType.rrw_create, "temporary", "table", " ", " ", " ", " ", ESqlStatementType.sstcreatetable);
059        addCmd(TBaseType.rrw_create, "view", " ", " ", " ", " ", " ", ESqlStatementType.sstcreateview);
060        addCmd(TBaseType.rrw_create, "or", "replace", "view", " ", " ", " ", ESqlStatementType.sstcreateview);
061        addCmd(TBaseType.rrw_create, "index", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlcreateindex);
062        addCmd(TBaseType.rrw_create, "unique", "index", " ", " ", " ", " ", ESqlStatementType.sstmysqlcreateindex);
063        addCmd(TBaseType.rrw_create, "user", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlcreateuser);
064        addCmd(TBaseType.rrw_create, "function", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlcreatefunction);
065        addCmd(TBaseType.rrw_create, "procedure", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlcreateprocedure);
066        addCmd(TBaseType.rrw_create, "routine", "load", " ", " ", " ", " ", ESqlStatementType.sstmysqlloaddatainfile);
067        addCmd(TBaseType.rrw_create, "catalog", " ", " ", " ", " ", " ", ESqlStatementType.sstcreatecatalog);
068        addCmd(TBaseType.rrw_create, "external", "catalog", " ", " ", " ", " ", ESqlStatementType.sstcreatecatalog);
069        addCmd(TBaseType.rrw_create, "resource", " ", " ", " ", " ", " ", ESqlStatementType.sstCreateResourcePool);
070        addCmd(TBaseType.rrw_create, "external", "resource", " ", " ", " ", " ", ESqlStatementType.sstCreateResourcePool);
071        addCmd(TBaseType.rrw_create, "workload", "group", " ", " ", " ", " ", ESqlStatementType.sstCreateResourcePool);
072
073        // BACKUP (Doris specific - BACKUP SNAPSHOT db.snapshot TO repository ON (...) PROPERTIES (...))
074        addCmd(TBaseType.rrw_backup, "snapshot", " ", " ", " ", " ", " ", ESqlStatementType.sstmssqlbackup);
075
076        // RESTORE (Doris specific - RESTORE SNAPSHOT db.snapshot FROM repository ON (...) PROPERTIES (...))
077        addCmd(TBaseType.rrw_restore, "snapshot", " ", " ", " ", " ", " ", ESqlStatementType.sstmssqlrestore);
078
079        // ALTER statements
080        addCmd(TBaseType.rrw_alter, "database", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlalterdatabase);
081        addCmd(TBaseType.rrw_alter, "table", " ", " ", " ", " ", " ", ESqlStatementType.sstaltertable);
082        addCmd(TBaseType.rrw_alter, "view", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlalterview);
083        addCmd(TBaseType.rrw_alter, "user", " ", " ", " ", " ", " ", ESqlStatementType.sstmssqlalteruser);
084
085        // DROP statements
086        addCmd(TBaseType.rrw_drop, "database", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqldropdatabase);
087        addCmd(TBaseType.rrw_drop, "schema", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqldropdatabase);
088        addCmd(TBaseType.rrw_drop, "table", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqldroptable);
089        addCmd(TBaseType.rrw_drop, "tables", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqldroptable);
090        addCmd(TBaseType.rrw_drop, "view", " ", " ", " ", " ", " ", ESqlStatementType.sstdropview);
091        addCmd(TBaseType.rrw_drop, "index", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqldropindex);
092        addCmd(TBaseType.rrw_drop, "user", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqldropuser);
093        addCmd(TBaseType.rrw_drop, "function", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqldropfunction);
094        addCmd(TBaseType.rrw_drop, "procedure", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqldropprocedure);
095
096        // TRUNCATE
097        addCmd(TBaseType.rrw_truncate, " ", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqltruncate);
098        addCmd(TBaseType.rrw_truncate, "table", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqltruncate);
099
100        // Transaction control
101        addCmd(TBaseType.rrw_begin, " ", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlstarttransaction);
102        addCmd(TBaseType.rrw_commit, " ", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlcommit);
103        addCmd(TBaseType.rrw_rollback, " ", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlrollback);
104
105        // SHOW statements (Doris supports many SHOW commands)
106        addCmd(TBaseType.rrw_show, "databases", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlshowdatabases);
107        addCmd(TBaseType.rrw_show, "tables", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlshowtables);
108        addCmd(TBaseType.rrw_show, "full", "tables", " ", " ", " ", " ", ESqlStatementType.sstmysqlshowtables);
109        addCmd(TBaseType.rrw_show, "columns", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlshowcolumns);
110        addCmd(TBaseType.rrw_show, "full", "columns", " ", " ", " ", " ", ESqlStatementType.sstmysqlshowcolumns);
111        addCmd(TBaseType.rrw_show, "create", "database", " ", " ", " ", " ", ESqlStatementType.sstmysqlshowcreatedatabase);
112        addCmd(TBaseType.rrw_show, "create", "table", " ", " ", " ", " ", ESqlStatementType.sstmysqlshowcreatetable);
113        addCmd(TBaseType.rrw_show, "create", "view", " ", " ", " ", " ", ESqlStatementType.sstmysqlshowcreateview);
114        addCmd(TBaseType.rrw_show, "index", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlshowindex);
115        addCmd(TBaseType.rrw_show, "indexes", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlshowindex);
116        addCmd(TBaseType.rrw_show, "status", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlshowstatus);
117        addCmd(TBaseType.rrw_show, "table", "status", " ", " ", " ", " ", ESqlStatementType.sstmysqlshowtablestatus);
118        addCmd(TBaseType.rrw_show, "variables", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlshowvariables);
119        addCmd(TBaseType.rrw_show, "global", "variables", " ", " ", " ", " ", ESqlStatementType.sstmysqlshowvariables);
120        addCmd(TBaseType.rrw_show, "session", "variables", " ", " ", " ", " ", ESqlStatementType.sstmysqlshowvariables);
121        addCmd(TBaseType.rrw_show, "warnings", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlshowwarnings);
122        addCmd(TBaseType.rrw_show, "errors", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlshowerrors);
123        addCmd(TBaseType.rrw_show, "processlist", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlshowprocesslist);
124        addCmd(TBaseType.rrw_show, "full", "processlist", " ", " ", " ", " ", ESqlStatementType.sstmysqlshowprocesslist);
125        addCmd(TBaseType.rrw_show, "grants", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlshowgrants);
126        addCmd(TBaseType.rrw_show, "partitions", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlshow);
127        addCmd(TBaseType.rrw_show, "data", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlshow);
128
129        // SET statements
130        addCmd(TBaseType.rrw_set, " ", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlset);
131        addCmd(TBaseType.rrw_set, "global", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlset);
132        addCmd(TBaseType.rrw_set, "session", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlset);
133
134        // USE statement
135        addCmd(TBaseType.rrw_use, " ", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqluse);
136
137        // DESCRIBE/DESC
138        addCmd(TBaseType.rrw_describe, " ", " ", " ", " ", " ", " ", ESqlStatementType.sstdescribe);
139
140        // EXPLAIN
141        addCmd(TBaseType.rrw_explain, " ", " ", " ", " ", " ", " ", ESqlStatementType.sstExplain);
142
143        // GRANT/REVOKE
144        addCmd(TBaseType.rrw_grant, " ", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlgrant);
145        addCmd(TBaseType.rrw_revoke, " ", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlrevoke);
146
147        // LOAD DATA (Doris specific)
148        addCmd(TBaseType.rrw_load, " ", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlloaddatainfile);
149        addCmd(TBaseType.rrw_load, "label", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlloaddatainfile);
150
151        // EXPORT (Doris specific)
152        addCmd(TBaseType.rrw_doris_export, "table", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlloaddatainfile);
153
154        // ANALYZE
155        addCmd(TBaseType.rrw_analyze, "table", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlanalyzetable);
156
157        // KILL
158        addCmd(TBaseType.rrw_kill, " ", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlkill);
159
160        // CALL
161        addCmd(TBaseType.rrw_call, " ", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlcall);
162
163        // PREPARE/EXECUTE/DEALLOCATE
164        addCmd(TBaseType.rrw_prepare, " ", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlprepare);
165        addCmd(TBaseType.rrw_execute, " ", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqlexecute);
166        addCmd(TBaseType.rrw_deallocate, "prepare", " ", " ", " ", " ", " ", ESqlStatementType.sstmysqldeallocateprepare);
167
168        // SWITCH (Doris specific - switch catalog)
169        addCmd(TBaseType.rrw_doris_switch, " ", " ", " ", " ", " ", " ", ESqlStatementType.sstUseCatalog);
170
171        // ADMIN commands (Doris specific)
172        // ADMIN SET REPLICA STATUS - Sets replica status for tablet management
173        addCmd(TBaseType.rrw_doris_admin, "set", "replica", "status", " ", " ", " ", ESqlStatementType.sstmysqlset);
174        // ADMIN REPAIR TABLE - Triggers repair of a table
175        addCmd(TBaseType.rrw_doris_admin, "repair", "table", " ", " ", " ", " ", ESqlStatementType.sstmysqlrepairtable);
176        // ADMIN CHECK TABLET - Checks tablet consistency
177        addCmd(TBaseType.rrw_doris_admin, "check", "tablet", " ", " ", " ", " ", ESqlStatementType.sstmysqlchecktable);
178
179        // RECOVER commands (Doris specific)
180        // RECOVER DATABASE - Recovers a dropped database
181        addCmd(TBaseType.rrw_doris_recover, "database", " ", " ", " ", " ", " ", ESqlStatementType.sstrecoverdatabase);
182        // RECOVER TABLE - Recovers a dropped table
183        addCmd(TBaseType.rrw_doris_recover, "table", " ", " ", " ", " ", " ", ESqlStatementType.sstrecoverdata);
184        // RECOVER PARTITION - Recovers a dropped partition
185        addCmd(TBaseType.rrw_doris_recover, "partition", " ", " ", " ", " ", " ", ESqlStatementType.sstrecoverdata);
186
187        // CANCEL commands (Doris specific)
188        // CANCEL LOAD - Cancel a running load job
189        addCmd(TBaseType.rrw_doris_cancel, "load", " ", " ", " ", " ", " ", ESqlStatementType.sstbackupcancel);
190
191        // PAUSE/RESUME commands (Doris specific)
192        // PAUSE ROUTINE LOAD FOR job_name - Pause a running routine load job
193        addCmd(TBaseType.rrw_doris_pause, "routine", "load", "for", " ", " ", " ", ESqlStatementType.sstmysqlloaddatainfile);
194        // RESUME ROUTINE LOAD FOR job_name - Resume a paused routine load job
195        addCmd(TBaseType.rrw_doris_resume, "routine", "load", "for", " ", " ", " ", ESqlStatementType.sstmysqlloaddatainfile);
196
197        // REFRESH commands (Doris specific)
198        // REFRESH CATALOG catalog_name - Refresh external catalog metadata
199        addCmd(TBaseType.rrw_refresh, "catalog", " ", " ", " ", " ", " ", ESqlStatementType.sstRefresh);
200    }
201
202    @Override
203    public TCustomSqlStatement issql(TSourceToken pcst, EFindSqlStateType pstate, TCustomSqlStatement psqlstatement) {
204        TCustomSqlStatement ret = null;
205        int k;
206        boolean lcisnewsql;
207        TSourceToken lcpprevsolidtoken, lcnextsolidtoken;
208
209        gnewsqlstatementtype = ESqlStatementType.sstinvalid;
210
211        if ((pcst.tokencode == TBaseType.cmtdoublehyphen)
212                || (pcst.tokencode == TBaseType.cmtslashstar)
213                || (pcst.tokencode == TBaseType.lexspace)
214                || (pcst.tokencode == TBaseType.lexnewline)
215                || (pcst.tokentype == ETokenType.ttsemicolon)) {
216            return ret;
217        }
218
219        int lcpos = pcst.posinlist;
220        TSourceTokenList lcsourcetokenlist = pcst.container;
221        TCustomSqlStatement lccurrentsqlstatement = psqlstatement;
222
223        // Subquery after semicolon or at first line
224        if ((pstate == EFindSqlStateType.stnormal) && (pcst.tokentype == ETokenType.ttleftparenthesis)) {
225            k = lcsourcetokenlist.solidtokenafterpos(lcpos, TBaseType.rrw_select, 1, "(");
226            if (k > 0) {
227                ret = new TSelectSqlStatement(vendor);
228            }
229            return ret;
230        }
231
232        // CTE
233        if ((pstate == EFindSqlStateType.stnormal) && (pcst.tokencode == TBaseType.rrw_with)) {
234            ret = findcte(pcst);
235            if ((ret != null)) return ret;
236        }
237
238        gnewsqlstatementtype = getStatementTypeForToken(pcst);
239
240        TSourceToken lcprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcpos);
241
242        // Handle CREATE ... VIEW pattern
243        if ((gnewsqlstatementtype == ESqlStatementType.sstinvalid) && (pcst.tokencode == TBaseType.rrw_create)) {
244            TSourceToken viewToken = pcst.container.searchToken(TBaseType.rrw_view, "", pcst, 15);
245            if (viewToken != null) {
246                gnewsqlstatementtype = ESqlStatementType.sstcreateview;
247            }
248        }
249
250        switch (gnewsqlstatementtype) {
251            case sstinvalid: {
252                ret = null;
253                break;
254            }
255            case sstselect: {
256                lcisnewsql = true;
257
258                if (pstate != EFindSqlStateType.stnormal) {
259                    if (TBaseType.assigned(lcprevsolidtoken)) {
260                        if (lcprevsolidtoken.tokentype == ETokenType.ttleftparenthesis)
261                            lcisnewsql = false;
262                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_union)
263                            lcisnewsql = false;
264                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_intersect)
265                            lcisnewsql = false;
266                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_minus)
267                            lcisnewsql = false;
268                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_except)
269                            lcisnewsql = false;
270                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_return)
271                            lcisnewsql = false;
272                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_as) {
273                            if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatetable)
274                                lcisnewsql = false;
275                            else if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreateview)
276                                lcisnewsql = false;
277                        }
278                    }
279                }
280                if (lcisnewsql) {
281                    ret = new TSelectSqlStatement(vendor);
282                }
283                break;
284            }
285            default: {
286                ret = new TUnknownSqlStatement(vendor);
287                ret.sqlstatementtype = gnewsqlstatementtype;
288                break;
289            }
290        }
291
292        return ret;
293    }
294}