001package gudusoft.gsqlparser.sqlcmds;
002
003import gudusoft.gsqlparser.*;
004import gudusoft.gsqlparser.stmt.*;
005import gudusoft.gsqlparser.stmt.sparksql.*;
006import gudusoft.gsqlparser.stmt.mysql.TLoadDataStmt;
007
008/**
009 * SparkSQL SQL command resolver.
010 * Extracted from monolithic TSqlCmds to support modular lazy-loading.
011 *
012 * @since 3.1.0.9
013 */
014public class TSqlCmdsSparksql extends AbstractSqlCmds {
015
016    public TSqlCmdsSparksql() {
017        super(EDbVendor.dbvsparksql);
018    }
019
020    @Override
021    protected void initializeCommands() {
022        // Extracted from TSqlCmds.initsparksqlcmds() lines 1530-1597
023        // Commands ordered with longer patterns before shorter ones
024
025        // ADD commands
026        addCmd(TBaseType.rrw_add, "file", ESqlStatementType.sstAddFile);
027        addCmd(TBaseType.rrw_add, "jar", ESqlStatementType.sstAddJar);
028
029        // ALTER commands
030        addCmd(TBaseType.rrw_alter, "database", ESqlStatementType.sstalterdatabase);
031        addCmd(TBaseType.rrw_alter, "table", ESqlStatementType.sstaltertable);
032        addCmd(TBaseType.rrw_alter, "view", ESqlStatementType.sstalterview);
033
034        // ANALYZE commands
035        addCmd(TBaseType.rrw_analyze, "table", ESqlStatementType.sstanalyzeTable);
036
037        // CACHE commands
038        addCmd(TBaseType.rrw_cache, "lazy", "table", ESqlStatementType.sstCacheTable);
039        addCmd(TBaseType.rrw_cache, "table", ESqlStatementType.sstCacheTable);
040
041        // CLEAR commands
042        addCmd(TBaseType.rrw_clear, "cache", ESqlStatementType.sstClearCache);
043
044        // CREATE commands (longer patterns first)
045        addCmd(TBaseType.rrw_create, "or", "replace", "global", "temporary", "view", ESqlStatementType.sstcreateview);
046        addCmd(TBaseType.rrw_create, "or", "replace", "temporary", "function", ESqlStatementType.sstcreatefunction);
047        addCmd(TBaseType.rrw_create, "or", "replace", "temporary", "view", ESqlStatementType.sstcreateview);
048        addCmd(TBaseType.rrw_create, "or", "replace", "function", ESqlStatementType.sstcreatefunction);
049        addCmd(TBaseType.rrw_create, "or", "replace", "view", ESqlStatementType.sstcreateview);
050        addCmd(TBaseType.rrw_create, "global", "temporary", "view", ESqlStatementType.sstcreateview);
051        addCmd(TBaseType.rrw_create, "external", "table", ESqlStatementType.sstcreatetable);
052        addCmd(TBaseType.rrw_create, "temporary", "function", ESqlStatementType.sstcreatefunction);
053        addCmd(TBaseType.rrw_create, "temporary", "view", ESqlStatementType.sstcreateview);
054        addCmd(TBaseType.rrw_create, "database", ESqlStatementType.sstcreatedatabase);
055        addCmd(TBaseType.rrw_create, "function", ESqlStatementType.sstcreatefunction);
056        addCmd(TBaseType.rrw_create, "table", ESqlStatementType.sstcreatetable);
057        addCmd(TBaseType.rrw_create, "view", ESqlStatementType.sstcreateview);
058
059        // DESCRIBE commands (DESC and DESCRIBE variants)
060        addCmd(TBaseType.rrw_spark_desc, "database", ESqlStatementType.sstdescribeDatabase);
061        addCmd(TBaseType.rrw_spark_desc, "function", ESqlStatementType.sstdescribeFunction);
062        addCmd(TBaseType.rrw_spark_desc, "query", ESqlStatementType.sstdescribeQuery);
063        addCmd(TBaseType.rrw_spark_desc, "table", ESqlStatementType.sstdescribeTable);
064        addCmd(TBaseType.rrw_spark_desc, ESqlStatementType.sstdescribeTable);
065        addCmd(TBaseType.rrw_describe, "database", ESqlStatementType.sstdescribeDatabase);
066        addCmd(TBaseType.rrw_describe, "function", ESqlStatementType.sstdescribeFunction);
067        addCmd(TBaseType.rrw_describe, "query", ESqlStatementType.sstdescribeQuery);
068        addCmd(TBaseType.rrw_describe, "table", ESqlStatementType.sstdescribeTable);
069        addCmd(TBaseType.rrw_describe, ESqlStatementType.sstdescribe);
070
071        // DROP commands
072        addCmd(TBaseType.rrw_drop, "temporary", "function", ESqlStatementType.sstdropfunction);
073        addCmd(TBaseType.rrw_drop, "database", ESqlStatementType.sstdropdatabase);
074        addCmd(TBaseType.rrw_drop, "function", ESqlStatementType.sstdropfunction);
075        addCmd(TBaseType.rrw_drop, "schema", ESqlStatementType.sstdropdatabase);
076        addCmd(TBaseType.rrw_drop, "table", ESqlStatementType.sstdroptable);
077        addCmd(TBaseType.rrw_drop, "view", ESqlStatementType.sstdropview);
078
079        // EXPLAIN commands
080        addCmd(TBaseType.rrw_explain, ESqlStatementType.sstExplain);
081
082        // INSERT commands
083        addCmd(TBaseType.rrw_insert, ESqlStatementType.sstinsert);
084
085        // LIST commands
086        addCmd(TBaseType.rrw_spark_list, "file", ESqlStatementType.sstListFile);
087        addCmd(TBaseType.rrw_spark_list, "jar", ESqlStatementType.sstListJar);
088
089        // LOAD commands
090        addCmd(TBaseType.rrw_load, "data", ESqlStatementType.sstLoadData);
091
092        // MSCK commands
093        addCmd(TBaseType.rrw_spark_msck, "repair", "table", ESqlStatementType.sstmsck);
094
095        // REFRESH commands
096        addCmd(TBaseType.rrw_refresh, "function", ESqlStatementType.sstRefreshFunction);
097        addCmd(TBaseType.rrw_refresh, "table", ESqlStatementType.sstRefreshTable);
098        addCmd(TBaseType.rrw_refresh, ESqlStatementType.sstRefresh);
099
100        // REPAIR commands
101        addCmd(TBaseType.rrw_repair, "table", ESqlStatementType.sstrepairtable);
102
103        // RESET commands
104        addCmd(TBaseType.rrw_reset, ESqlStatementType.sstReset);
105
106        // SELECT commands
107        addCmd(TBaseType.rrw_select, ESqlStatementType.sstselect);
108
109        // SET commands
110        addCmd(TBaseType.rrw_set, "time", "zone", ESqlStatementType.sstSetTimeZone);
111        addCmd(TBaseType.rrw_set, ESqlStatementType.sstset);
112
113        // SHOW commands
114        addCmd(TBaseType.rrw_show, "create", "table", ESqlStatementType.sstShowCreateTable);
115        addCmd(TBaseType.rrw_show, "table", "extended", ESqlStatementType.sstShowTableExtended);
116        addCmd(TBaseType.rrw_show, "columns", ESqlStatementType.sstShowColumns);
117        addCmd(TBaseType.rrw_show, "databases", ESqlStatementType.sstShowDatabases);
118        addCmd(TBaseType.rrw_show, "functions", ESqlStatementType.sstShowFunctions);
119        addCmd(TBaseType.rrw_show, "partitions", ESqlStatementType.sstShowPartitions);
120        addCmd(TBaseType.rrw_show, "tables", ESqlStatementType.sstShowTables);
121        addCmd(TBaseType.rrw_show, "tblproperties", ESqlStatementType.sstShowTblProperties);
122        addCmd(TBaseType.rrw_show, "user", ESqlStatementType.sstShowUser);
123        addCmd(TBaseType.rrw_show, "views", ESqlStatementType.sstShowViews);
124
125        // TRUNCATE commands
126        addCmd(TBaseType.rrw_truncate, "table", ESqlStatementType.ssttruncatetable);
127
128        // UNCACHE commands
129        addCmd(TBaseType.rrw_spark_uncache, "table", ESqlStatementType.sstUnCacheTable);
130
131        // USE commands
132        addCmd(TBaseType.rrw_use, ESqlStatementType.sstUse);
133    }
134
135    @Override
136    protected String getToken1Str(int token1) {
137        // SparkSQL vendor-specific tokens
138        switch (token1) {
139            case TBaseType.rrw_spark_uncache:
140                return "uncache";
141            case TBaseType.rrw_spark_desc:
142                return "desc";
143            case TBaseType.rrw_spark_list:
144                return "list";
145            case TBaseType.rrw_spark_msck:
146                return "msck";
147            default:
148                return null;
149        }
150    }
151
152    @Override
153    public TCustomSqlStatement issql(TSourceToken token, EFindSqlStateType state, TCustomSqlStatement currentStatement) {
154        // Extracted from TSqlCmds.issparksql() lines 14877-15214
155
156        TCustomSqlStatement ret = null;
157        int k;
158        boolean lcisnewsql;
159        TSourceToken lcpprevsolidtoken, lcnextsolidtoken;
160
161        gnewsqlstatementtype = ESqlStatementType.sstinvalid;
162
163        if ((token.tokencode == TBaseType.cmtdoublehyphen)
164                || (token.tokencode == TBaseType.cmtslashstar)
165                || (token.tokencode == TBaseType.lexspace)
166                || (token.tokencode == TBaseType.lexnewline)
167                || (token.tokentype == ETokenType.ttsemicolon)) {
168            return ret;
169        }
170
171        int lcpos = token.posinlist;
172        TSourceTokenList lcsourcetokenlist = token.container;
173        TCustomSqlStatement lccurrentsqlstatement = currentStatement;
174
175        // subquery after semicolon || at first line
176        if ((state == EFindSqlStateType.stnormal) && (token.tokentype == ETokenType.ttleftparenthesis)) {
177            k = lcsourcetokenlist.solidtokenafterpos(lcpos, TBaseType.rrw_select, 1, "(");
178            if (k > 0) {
179                ret = new TSelectSqlStatement(this.vendor);
180            }
181            return ret;
182        }
183
184        // cte
185        if ((state == EFindSqlStateType.stnormal) && (token.tokencode == TBaseType.rrw_with)) {
186            ret = findcte(token);
187            if ((ret != null)) return ret;
188        }
189
190        gnewsqlstatementtype = getStatementTypeForToken(token);
191
192        TSourceToken lcprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcpos);
193
194        if ((gnewsqlstatementtype == ESqlStatementType.sstinvalid) && (token.tokencode == TBaseType.rrw_create)) {
195            TSourceToken viewToken = token.container.searchToken(TBaseType.rrw_view, "", token, 15);
196            if (viewToken != null) {
197                gnewsqlstatementtype = ESqlStatementType.sstcreateview;
198            }
199        }
200
201        switch (gnewsqlstatementtype) {
202            case sstinvalid: {
203                ret = null;
204                break;
205            }
206            case sstselect: {
207                lcisnewsql = true;
208
209                if (state != EFindSqlStateType.stnormal) {
210                    if (TBaseType.assigned(lcprevsolidtoken)) {
211                        if (lcprevsolidtoken.tokentype == ETokenType.ttleftparenthesis)
212                            lcisnewsql = false; // subquery
213                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_union)
214                            lcisnewsql = false;
215                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_intersect)
216                            lcisnewsql = false;
217                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_minus)
218                            lcisnewsql = false;
219                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_except)
220                            lcisnewsql = false;
221                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_return)
222                            lcisnewsql = false;
223                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_as) {
224                            if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatetable)
225                                lcisnewsql = false;
226                            if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreateview)
227                                lcisnewsql = false;
228                        }
229
230                        if (lcisnewsql && (lcprevsolidtoken.tokencode == TBaseType.rrw_all)) {
231                            lcpprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcprevsolidtoken.posinlist);
232                            if (TBaseType.assigned(lcpprevsolidtoken)) {
233                                if (lcpprevsolidtoken.tokencode == TBaseType.rrw_union)
234                                    lcisnewsql = false;
235                            }
236                        }
237                    }
238
239                    if (TBaseType.assigned(lccurrentsqlstatement)) {
240                        if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstinsert)
241                            lcisnewsql = false;
242                    }
243                }
244
245                if (lcisnewsql)
246                    ret = new TSelectSqlStatement(this.vendor);
247                break;
248            }
249            case sstinsert: {
250                lcisnewsql = true;
251                if (state != EFindSqlStateType.stnormal) {
252                    if (TBaseType.assigned(lccurrentsqlstatement)) {
253                        // No special handling needed
254                    }
255                }
256
257                if (lcisnewsql)
258                    ret = new TInsertSqlStatement(this.vendor);
259                ret.sqlstatementtype = gnewsqlstatementtype;
260                break;
261            }
262            case sstupdate: {
263                lcisnewsql = true;
264                if (state != EFindSqlStateType.stnormal) {
265                    lcprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcpos);
266                    if (TBaseType.assigned(lcprevsolidtoken)) {
267                        if (lcprevsolidtoken.tokencode == TBaseType.rrw_on)
268                            lcisnewsql = false;
269                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_for)
270                            lcisnewsql = false;
271                    }
272
273                    lcnextsolidtoken = lcsourcetokenlist.nextsolidtoken(lcpos, 1, false);
274                    if (TBaseType.assigned(lcnextsolidtoken)) {
275                        if (lcnextsolidtoken.tokentype == ETokenType.ttleftparenthesis) {
276                            k = lcsourcetokenlist.solidtokenafterpos(lcnextsolidtoken.posinlist, TBaseType.rrw_select, 1, "(");
277                            if (k == 0) lcisnewsql = false;
278                        }
279                    }
280
281                    if (TBaseType.assigned(lccurrentsqlstatement)) {
282                        // No special handling needed
283                    }
284                }
285
286                if (lcisnewsql) {
287                    ret = new TUpdateSqlStatement(this.vendor);
288                    ret.dummytag = 1; // means set clause in update is not found yet, used to separate set clause from set statement
289                }
290                break;
291            }
292            case sstdelete: {
293                lcisnewsql = true;
294
295                if (state != EFindSqlStateType.stnormal) {
296                    lcprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcpos);
297                    if (TBaseType.assigned(lcprevsolidtoken)) {
298                        if (lcprevsolidtoken.tokencode == TBaseType.rrw_on)
299                            lcisnewsql = false;
300                    }
301
302                    if (TBaseType.assigned(lccurrentsqlstatement)) {
303                        // No special handling needed
304                    }
305                }
306
307                if (lcisnewsql)
308                    ret = new TDeleteSqlStatement(this.vendor);
309                break;
310            }
311            case sstcreatetable: {
312                ret = new TCreateTableSqlStatement(this.vendor);
313                break;
314            }
315            case sstcreateview: {
316                ret = new TCreateViewSqlStatement(this.vendor);
317                break;
318            }
319            case sstcreatedatabase: {
320                ret = new TCreateDatabaseSqlStatement(this.vendor);
321                break;
322            }
323            case sstdroptable: {
324                ret = new TDropTableSqlStatement(this.vendor);
325                break;
326            }
327            case sstdropview: {
328                ret = new TDropViewSqlStatement(this.vendor);
329                break;
330            }
331            case sstaltertable: {
332                ret = new TAlterTableStatement(this.vendor);
333                break;
334            }
335            case sstset:
336            case sstReset:
337            case sstSetTimeZone: {
338                lcisnewsql = true;
339                if (state != EFindSqlStateType.stnormal) {
340                    if (TBaseType.assigned(lccurrentsqlstatement)) {
341                        lcisnewsql = false;
342                    }
343                }
344
345                if (lcisnewsql) {
346                    ret = new TSetStmt(this.vendor);
347                }
348                break;
349            }
350            case sstcreatefunction: {
351                ret = new TCreateFunctionStmt(this.vendor);
352                break;
353            }
354            case sstTruncate: {
355                ret = new TTruncateStatement(this.vendor);
356                break;
357            }
358            case sstdescribe: {
359                ret = new TDescribeStmt(this.vendor);
360                break;
361            }
362            case sstExplain: {
363                ret = new TExplainPlan(this.vendor);
364                break;
365            }
366            case sstUse: {
367                ret = new TUseDatabase(this.vendor);
368                break;
369            }
370            case sstLoadData: {
371                ret = new TLoadDataStmt(this.vendor);
372                break;
373            }
374            case sstShowColumns:
375            case sstShowCreateTable:
376            case sstShowDatabases:
377            case sstShowFunctions:
378            case sstShowPartitions:
379            case sstShowTableExtended:
380            case sstShowTables:
381            case sstShowTblProperties:
382            case sstShowViews:
383            case sstShowUser:
384                ret = new TShowStmt(this.vendor);
385                ret.sqlstatementtype = gnewsqlstatementtype;
386                break;
387            case sstalterdatabase:
388                ret = new TAlterDatabaseStmt(this.vendor);
389                break;
390            case sstdescribeDatabase:
391            case sstdescribeTable:
392            case sstdescribeFunction:
393                ret = new TDescribeStmt(this.vendor);
394                break;
395            case sstalterview:
396                ret = new TAlterViewStatement(this.vendor);
397                break;
398            case sstAddFile:
399            case sstAddJar:
400            case sstListFile:
401            case sstListJar:
402                ret = new TResourceManagement(this.vendor);
403                ret.sqlstatementtype = gnewsqlstatementtype;
404                break;
405            case sstdropdatabase:
406                ret = new TDropDatabaseStmt(this.vendor);
407                break;
408            case sstdropfunction:
409                ret = new TDropFunctionStmt(this.vendor);
410                break;
411            case ssttruncatetable:
412                ret = new TTruncateStatement(this.vendor);
413                break;
414            case sstmsck: {
415                ret = new TMSCKStmt(this.vendor);
416                break;
417            }
418            case sstanalyzeTable: {
419                ret = new TAnalyzeStmt(this.vendor);
420                break;
421            }
422            case sstCacheTable:
423            case sstUnCacheTable:
424            case sstClearCache:
425                ret = new TCacheTable(this.vendor);
426                break;
427            case sstRefreshTable:
428            case sstRefreshFunction:
429            case sstRefresh:
430                ret = new TRefresh(this.vendor);
431                break;
432            default: {
433                ret = new TUnknownSqlStatement(this.vendor);
434                ret.sqlstatementtype = gnewsqlstatementtype;
435                break;
436            }
437        }
438
439        return ret;
440    }
441}