001package gudusoft.gsqlparser.sqlcmds;
002
003import gudusoft.gsqlparser.*;
004import gudusoft.gsqlparser.stmt.*;
005import gudusoft.gsqlparser.stmt.presto.TResetSessionStmt;
006
007/**
008 * Athena SQL command resolver.
009 * Contains all Athena-specific SQL command recognition logic.
010 *
011 * @since 3.1.0.9
012 */
013public class TSqlCmdsAthena extends AbstractSqlCmds {
014
015    // Temporary field for statement type during issql processing
016    private ESqlStatementType gnewsqlstatementtype = ESqlStatementType.sstinvalid;
017
018    public TSqlCmdsAthena() {
019        super(EDbVendor.dbvathena);
020    }
021
022    @Override
023    protected String getToken1Str(int token1) {
024        // Athena vendor-specific token string mappings
025        switch (token1) {
026            case TBaseType.rrw_athena_unload:
027                return "unload";
028            case TBaseType.rrw_athena_msck:
029                return "msck";
030            default:
031                return null;
032        }
033    }
034
035    @Override
036    protected void initializeCommands() {
037        // Athena commands extracted from TSqlCmds.initathenacmds()
038        // Note: Commands with longer patterns should come before shorter ones for efficiency
039        addCmd(TBaseType.rrw_alter, "database", ESqlStatementType.sstalterdatabase);
040        addCmd(TBaseType.rrw_alter, "function", ESqlStatementType.sstalterfunction);
041        addCmd(TBaseType.rrw_alter, "schema", ESqlStatementType.sstalterdatabase);
042        addCmd(TBaseType.rrw_alter, "table", ESqlStatementType.sstaltertable);
043        addCmd(TBaseType.rrw_analyze, ESqlStatementType.sstAnalyzeTable);
044        addCmd(TBaseType.rrw_call, ESqlStatementType.sstcall);
045        addCmd(TBaseType.rrw_commit, ESqlStatementType.sstcommit);
046        addCmd(TBaseType.rrw_create, "database", ESqlStatementType.sstcreatedatabase);
047        addCmd(TBaseType.rrw_create, "or", "replace", "function", ESqlStatementType.sstcreatefunction);
048        addCmd(TBaseType.rrw_create, "temporary", "function", ESqlStatementType.sstcreatefunction);
049        addCmd(TBaseType.rrw_create, "function", ESqlStatementType.sstcreatefunction);
050        addCmd(TBaseType.rrw_create, "role", ESqlStatementType.sstcreaterole);
051        addCmd(TBaseType.rrw_create, "schema", ESqlStatementType.sstcreatedatabase);
052        addCmd(TBaseType.rrw_create, "external", "table", ESqlStatementType.sstcreatetable);
053        addCmd(TBaseType.rrw_create, "table", ESqlStatementType.sstcreatetable);
054        addCmd(TBaseType.rrw_create, "view", ESqlStatementType.sstcreateview);
055        addCmd(TBaseType.rrw_deallocate, "prepare", ESqlStatementType.sstpostgresqlDeallocate);
056        addCmd(TBaseType.rrw_delete, ESqlStatementType.sstdelete);
057        addCmd(TBaseType.rrw_describe, ESqlStatementType.sstdescribe);
058        addCmd(TBaseType.rrw_drop, "database", ESqlStatementType.sstdropdatabase);
059        addCmd(TBaseType.rrw_drop, "function", ESqlStatementType.sstdropfunction);
060        addCmd(TBaseType.rrw_drop, "role", ESqlStatementType.sstdroprole);
061        addCmd(TBaseType.rrw_drop, "schema", ESqlStatementType.sstdropdatabase);
062        addCmd(TBaseType.rrw_drop, "table", ESqlStatementType.sstdroptable);
063        addCmd(TBaseType.rrw_drop, "view", ESqlStatementType.sstdropview);
064        addCmd(TBaseType.rrw_execute, ESqlStatementType.sstExecute);
065        addCmd(TBaseType.rrw_explain, ESqlStatementType.sstExplain);
066        addCmd(TBaseType.rrw_grant, ESqlStatementType.sstGrant);
067        addCmd(TBaseType.rrw_insert, ESqlStatementType.sstinsert);
068        addCmd(TBaseType.rrw_athena_msck, ESqlStatementType.sstmsck);
069        addCmd(TBaseType.rrw_prepare, ESqlStatementType.sstprepare);
070        addCmd(TBaseType.rrw_reset, "session", ESqlStatementType.sstResetSession);
071        addCmd(TBaseType.rrw_revoke, ESqlStatementType.sstRevoke);
072        addCmd(TBaseType.rrw_rollback, ESqlStatementType.sstrollback);
073        addCmd(TBaseType.rrw_select, ESqlStatementType.sstselect);
074        addCmd(TBaseType.rrw_table, ESqlStatementType.sstselect);  // TABLE t = SELECT * FROM t
075        addCmd(TBaseType.rrw_set, "role", ESqlStatementType.sstset);
076        addCmd(TBaseType.rrw_set, "session", ESqlStatementType.sstset);
077        addCmd(TBaseType.rrw_show, "create", "function", ESqlStatementType.sstShow);
078        addCmd(TBaseType.rrw_show, "create", "table", ESqlStatementType.sstShow);
079        addCmd(TBaseType.rrw_show, "create", "view", ESqlStatementType.sstShow);
080        addCmd(TBaseType.rrw_show, "current", "roles", ESqlStatementType.sstShow);
081        addCmd(TBaseType.rrw_show, "role", "grants", ESqlStatementType.sstShow);
082        addCmd(TBaseType.rrw_show, "catalogs", ESqlStatementType.sstShow);
083        addCmd(TBaseType.rrw_show, "columns", ESqlStatementType.sstShow);
084        addCmd(TBaseType.rrw_show, "databases", ESqlStatementType.sstShow);
085        addCmd(TBaseType.rrw_show, "functions", ESqlStatementType.sstShow);
086        addCmd(TBaseType.rrw_show, "grants", ESqlStatementType.sstShow);
087        addCmd(TBaseType.rrw_show, "partitions", ESqlStatementType.sstShow);
088        addCmd(TBaseType.rrw_show, "roles", ESqlStatementType.sstShow);
089        addCmd(TBaseType.rrw_show, "schemas", ESqlStatementType.sstShow);
090        addCmd(TBaseType.rrw_show, "session", ESqlStatementType.sstShow);
091        addCmd(TBaseType.rrw_show, "stats", ESqlStatementType.sstShow);
092        addCmd(TBaseType.rrw_show, "tables", ESqlStatementType.sstShow);
093        addCmd(TBaseType.rrw_show, "tblproperties", ESqlStatementType.sstShow);
094        addCmd(TBaseType.rrw_show, "views", ESqlStatementType.sstShow);
095        addCmd(TBaseType.rrw_start, "transaction", ESqlStatementType.sstStartTransaction);
096        addCmd(TBaseType.rrw_athena_unload, ESqlStatementType.sstunload);
097        addCmd(TBaseType.rrw_use, ESqlStatementType.sstUse);
098        addCmd(TBaseType.rrw_values, ESqlStatementType.sstValues);
099    }
100
101    @Override
102    public TCustomSqlStatement issql(TSourceToken token, EFindSqlStateType state, TCustomSqlStatement currentStatement) {
103        TCustomSqlStatement ret = null;
104        int k;
105        boolean lcisnewsql;
106        TSourceToken lcpprevsolidtoken, lcnextsolidtoken;
107
108        gnewsqlstatementtype = ESqlStatementType.sstinvalid;
109
110        if ((token.tokencode == TBaseType.cmtdoublehyphen)
111                || (token.tokencode == TBaseType.cmtslashstar)
112                || (token.tokencode == TBaseType.lexspace)
113                || (token.tokencode == TBaseType.lexnewline)
114                || (token.tokentype == ETokenType.ttsemicolon)) {
115            return ret;
116        }
117
118        int lcpos = token.posinlist;
119        TSourceTokenList lcsourcetokenlist = token.container;
120        TCustomSqlStatement lccurrentsqlstatement = currentStatement;
121
122        //subquery after semicolon || at first line
123        if ((state == EFindSqlStateType.stnormal) && (token.tokentype == ETokenType.ttleftparenthesis)) { // (
124            k = lcsourcetokenlist.solidtokenafterpos(lcpos, TBaseType.rrw_select, 1, "(");
125            if (k > 0) {
126                ret = new TSelectSqlStatement(this.vendor);
127            }
128
129            return ret;
130        }
131
132        //cte
133        if ((state == EFindSqlStateType.stnormal) && (token.tokencode == TBaseType.rrw_with)) {
134            ret = findcte(token, this.vendor);
135            if ((ret != null)) return ret;
136        }
137
138        gnewsqlstatementtype = getStatementTypeForToken(token);
139
140        TSourceToken lcprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcpos);
141
142        if ((gnewsqlstatementtype == ESqlStatementType.sstinvalid) && (token.tokencode == TBaseType.rrw_create)) {
143            TSourceToken viewToken = token.container.searchToken(TBaseType.rrw_view, "", token, 15);
144            if (viewToken != null) {
145                gnewsqlstatementtype = ESqlStatementType.sstcreateview;
146            }
147        }
148
149        switch (gnewsqlstatementtype) {
150            case sstinvalid: {
151                ret = null;
152                break;
153            }
154            case sstselect: {
155                lcisnewsql = true;
156
157                if (state != EFindSqlStateType.stnormal) {
158                    if (TBaseType.assigned(lcprevsolidtoken)) {
159                        if (lcprevsolidtoken.tokentype == ETokenType.ttleftparenthesis)
160                            lcisnewsql = false; //subquery
161                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_union)
162                            lcisnewsql = false;
163                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_intersect)
164                            lcisnewsql = false;
165                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_minus)
166                            lcisnewsql = false;
167                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_except)
168                            lcisnewsql = false;
169                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_return)
170                            lcisnewsql = false;
171                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_as) {
172                            if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatetable)
173                                lcisnewsql = false;
174                            if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreateview)
175                                lcisnewsql = false;
176                        }
177
178                        if (lcisnewsql && (lcprevsolidtoken.tokencode == TBaseType.rrw_all)) {
179                            lcpprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcprevsolidtoken.posinlist);
180                            if (TBaseType.assigned(lcpprevsolidtoken)) {
181                                if (lcpprevsolidtoken.tokencode == TBaseType.rrw_union)
182                                    lcisnewsql = false;
183                            }
184                        }
185
186                    }
187
188
189                    if (TBaseType.assigned(lccurrentsqlstatement)) {
190                        if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstinsert)
191                            lcisnewsql = false;
192                    }
193
194                }
195
196                if (lcisnewsql)
197                    ret = new TSelectSqlStatement(this.vendor);
198                break;
199            }
200            case sstinsert: {
201                lcisnewsql = true;
202                if (state != EFindSqlStateType.stnormal) {
203                    if (TBaseType.assigned(lccurrentsqlstatement)) {
204
205                    }
206                }
207
208                if (lcisnewsql)
209                    ret = new TInsertSqlStatement(this.vendor);
210                ret.sqlstatementtype = gnewsqlstatementtype;
211                break;
212            }
213            case sstdelete: {
214                lcisnewsql = true;
215
216                if (state != EFindSqlStateType.stnormal) {
217                    lcprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcpos);
218                    if (TBaseType.assigned(lcprevsolidtoken)) {
219                        if (lcprevsolidtoken.tokencode == TBaseType.rrw_on)
220                            lcisnewsql = false;
221                    }
222
223                    if (TBaseType.assigned(lccurrentsqlstatement)) {
224                    }
225                }
226
227                if (lcisnewsql)
228                    ret = new TDeleteSqlStatement(this.vendor);
229                break;
230            }
231            case sstaltertable: {
232                ret = new TAlterTableStatement(this.vendor);
233                break;
234            }
235            case sstalterfunction: {
236                ret = new TAlterFunctionStmt(this.vendor);
237                break;
238            }
239            case sstAlterSchema: {
240                ret = new TAlterSchemaStmt(this.vendor);
241                break;
242            }
243            case sstanalyzeTable: {
244                ret = new TAnalyzeStmt(this.vendor);
245                break;
246            }
247            case sstcall: {
248                ret = new TCallStatement(this.vendor);
249                break;
250            }
251            case sstcommit: {
252                ret = new TCommitStmt(this.vendor);
253                break;
254            }
255            case sstcreatefunction: {
256                ret = new TCreateFunctionStmt(this.vendor);
257                break;
258            }
259            case sstcreaterole: {
260                ret = new TCreateRoleStmt(this.vendor);
261                break;
262            }
263            case sstcreateschema: {
264                ret = new TCreateSchemaSqlStatement(this.vendor);
265                break;
266            }
267            case sstcreatetable: {
268                ret = new TCreateTableSqlStatement(this.vendor);
269                break;
270            }
271            case sstcreateview: {
272                ret = new TCreateViewSqlStatement(this.vendor);
273                break;
274            }
275            case sstpostgresqlDeallocate: {
276                ret = new TUnknownSqlStatement(this.vendor);
277                ret.sqlstatementtype = gnewsqlstatementtype;
278                break;
279            }
280            case sstdescribe: {
281                ret = new TDescribeStmt(this.vendor);
282                break;
283            }
284            case sstdropfunction: {
285                ret = new TDropFunctionStmt(this.vendor);
286                break;
287            }
288            case sstdroprole: {
289                ret = new TDropRoleStmt(this.vendor);
290                break;
291            }
292            case sstdropschema: {
293                ret = new TDropSchemaSqlStatement(this.vendor);
294                break;
295            }
296            case sstdroptable: {
297                ret = new TDropTableSqlStatement(this.vendor);
298                break;
299            }
300            case sstdropview: {
301                ret = new TDropViewSqlStatement(this.vendor);
302                break;
303            }
304            case sstExecute: {
305                ret = new TExecuteSqlStatement(this.vendor);
306                break;
307            }
308            case sstExplain: {
309                ret = new TExplainPlan(this.vendor);
310                break;
311            }
312            case sstGrant: {
313                ret = new TGrantStmt(this.vendor);
314                break;
315            }
316            case sstprepare: {
317                ret = new TPrepareStmt(this.vendor);
318                break;
319            }
320            case sstset:
321            case sstReset: {
322                lcisnewsql = true;
323                if (state != EFindSqlStateType.stnormal) {
324                    if (TBaseType.assigned(lccurrentsqlstatement)) {
325                        lcisnewsql = false;
326                    }
327                }
328
329                if (lcisnewsql) {
330                    ret = new TSetStmt(this.vendor);
331                }
332                break;
333            }
334            case sstShow: {
335                ret = new TShowStmt(this.vendor);
336                ret.sqlstatementtype = gnewsqlstatementtype;
337                break;
338            }
339            case sstStartTransaction: {
340                ret = new TStartTransactionStmt(this.vendor);
341                break;
342            }
343            case sstUse: {
344                ret = new TUseDatabase(this.vendor);
345                break;
346            }
347            case sstValues: {
348                ret = new TSelectSqlStatement(this.vendor);
349                break;
350            }
351            case sstResetSession: {
352                ret = new TResetSessionStmt(this.vendor);
353                break;
354            }
355            case sstunload:
356                lcisnewsql = true;
357                if (state != EFindSqlStateType.stnormal) {
358                    lcisnewsql = false;
359                }
360                if (lcisnewsql) {
361                    ret = new TUnloadStmt(this.vendor);
362                    ret.sqlstatementtype = gnewsqlstatementtype;
363                }
364                break;
365            case sstmsck: {
366                ret = new TMSCKStmt(this.vendor);
367                break;
368            }
369            case sstcreatedatabase: {
370                ret = new TCreateDatabaseSqlStatement(this.vendor);
371                break;
372            }
373            case sstalterdatabase: {
374                ret = new TAlterDatabaseStmt(this.vendor);
375                break;
376            }
377            case sstdropdatabase:
378                ret = new TDropDatabaseStmt(this.vendor);
379                break;
380            default: {
381                ret = new TUnknownSqlStatement(this.vendor);
382                ret.sqlstatementtype = gnewsqlstatementtype;
383                break;
384            }
385        }    // case
386
387        return ret;
388    }
389
390    private TCustomSqlStatement findcte(TSourceToken ptoken, EDbVendor pdbvendor) {
391        TCustomSqlStatement ret = null;
392        TSourceToken lctoken = null;
393        int lcnested = 0, k, j;
394        boolean inXmlNamespaces = false;
395        boolean isXmlNamespaces = false;
396
397        int lcpos = ptoken.posinlist;
398        TSourceTokenList lcsourcetokenlist = ptoken.container;
399
400        // Walk the CTE list structurally before falling back to the keyword scan
401        // below, which cannot see a main query wrapped in its own parentheses.
402        TCustomSqlStatement structuralCte = findCteByStructure(ptoken);
403        if (structuralCte != null) return structuralCte;
404
405        for (int i = lcpos + 1; i < lcsourcetokenlist.size(); i++)    // iterate
406        {
407            lctoken = lcsourcetokenlist.get(i);
408            if (lctoken.tokencode == TBaseType.rrw_xmlnamespaces) {
409                inXmlNamespaces = true;
410                lcnested = 0;
411                continue;
412            }
413            if (inXmlNamespaces) {
414                if (lctoken.tokentype == ETokenType.ttleftparenthesis) lcnested++;
415                if (lctoken.tokentype == ETokenType.ttrightparenthesis) {
416                    lcnested--;
417                    if (lcnested == 0) {
418                        inXmlNamespaces = false;
419                        isXmlNamespaces = true;
420                    }
421                }
422                continue;
423            }
424            if ((lctoken.tokencode == TBaseType.rrw_as) || isXmlNamespaces) {
425                lcnested = 0;
426                int startPos = i + 1;
427                if (isXmlNamespaces) startPos = i;
428                for (j = startPos; j < lcsourcetokenlist.size(); j++) {
429                    lctoken = lcsourcetokenlist.get(j);
430                    if (lctoken.isnonsolidtoken()) continue;
431                    if (lctoken.tokentype == ETokenType.ttleftparenthesis) lcnested++;
432                    if (lctoken.tokentype == ETokenType.ttrightparenthesis) lcnested--;
433
434
435                    if ((lcnested == 0) && (lctoken.tokencode == TBaseType.rrw_delete)) {
436                        ret = new TDeleteSqlStatement(pdbvendor);
437                        ret.isctequery = true;
438                        gnewsqlstatementtype = ESqlStatementType.sstdelete;
439                        break;
440                    }
441
442                    if ((lcnested == 0) && (lctoken.tokencode == TBaseType.rrw_merge)) {
443                        ret = new TMergeSqlStatement(pdbvendor);
444                        ret.isctequery = true;
445                        gnewsqlstatementtype = ESqlStatementType.sstmerge;
446                        break;
447                    }
448
449                    if ((lcnested == 0) && (lctoken.tokencode == TBaseType.rrw_insert)) {
450                        ret = new TInsertSqlStatement(pdbvendor);
451                        ret.isctequery = true;
452                        gnewsqlstatementtype = ESqlStatementType.sstinsert;
453                        ret.dummytag = 1; //  select stmt in insert is permitted
454
455                        for (k = lctoken.posinlist + 1; k < lcsourcetokenlist.size(); k++)    // iterate
456                        {
457                            if (lcsourcetokenlist.get(k).isnonsolidtoken()) continue;
458                            if (lcsourcetokenlist.get(k).tokencode == TBaseType.rrw_values) break;
459                            if (lcsourcetokenlist.get(k).tokencode == TBaseType.rrw_go) break;
460                            if (lcsourcetokenlist.get(k).tokentype == ETokenType.ttsemicolon) break;
461                            if (lcsourcetokenlist.get(k).tokencode == TBaseType.rrw_select) break;
462                            if (lcsourcetokenlist.get(k).tokencode == TBaseType.rrw_execute) break;
463                            if (lcsourcetokenlist.get(k).tokencode == TBaseType.rrw_exec) break;
464                        }    // for
465                        if (k > lcsourcetokenlist.size() - 1)
466                            k = lcsourcetokenlist.size() - 1;
467
468                        for (int m = lctoken.posinlist + 1; m <= k; m++)    // iterate
469                        {
470                            lcsourcetokenlist.get(m).tokenstatus = ETokenStatus.tsignoredbygetrawstatement;
471                        }    // for
472
473                        break;
474                    }
475
476                    if ((lcnested == 0) && (lctoken.tokencode == TBaseType.rrw_values) && (pdbvendor == EDbVendor.dbvpostgresql)) {
477                        ret = new TSelectSqlStatement(pdbvendor);
478                        ret.isctequery = true;
479                        gnewsqlstatementtype = ESqlStatementType.sstselect;
480                        break;
481                    }
482
483                    if ((lcnested == 0) && (lctoken.tokencode == TBaseType.rrw_select)) {
484                        ret = new TSelectSqlStatement(pdbvendor);
485                        ret.isctequery = true;
486                        gnewsqlstatementtype = ESqlStatementType.sstselect;
487                        break;
488                    }
489
490                    if ((lcnested == 0) && (lctoken.tokencode == TBaseType.rrw_update)) {
491                        ret = new TUpdateSqlStatement(pdbvendor);
492                        ret.isctequery = true;
493                        ret.dummytag = 1; // means set clause in update is not found yet, used to seperate set clause from set statement
494                        gnewsqlstatementtype = ESqlStatementType.sstupdate;
495                        break;
496                    }
497
498                    if ((pdbvendor == EDbVendor.dbvhive) && (lcnested == 0) && (lctoken.tokencode == TBaseType.rrw_from)) {
499                        TSourceToken cmdToken = lctoken.searchToken(TBaseType.rrw_insert, 3);
500                        if (cmdToken != null) {
501                            ret = new TInsertSqlStatement(pdbvendor);
502                            ret.isctequery = true;
503                            gnewsqlstatementtype = ESqlStatementType.sstinsert;
504
505                        } else {
506                            ret = new TSelectSqlStatement(pdbvendor);
507                            ret.isctequery = true;
508                            gnewsqlstatementtype = ESqlStatementType.ssthiveFromQuery;
509                        }
510                        break;
511                    }
512
513
514                }    // for
515
516                if ((ret != null)) {
517                    for (k = lcpos + 1; k <= j; k++)    // iterate
518                    {
519                        lcsourcetokenlist.get(k).tokenstatus = ETokenStatus.tsignoredbygetrawstatement;
520                    }    // for
521                    break;
522                }
523
524            }
525        }
526
527        return ret;
528    }
529}