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_set, "role", ESqlStatementType.sstset);
075        addCmd(TBaseType.rrw_set, "session", ESqlStatementType.sstset);
076        addCmd(TBaseType.rrw_show, "create", "function", ESqlStatementType.sstShow);
077        addCmd(TBaseType.rrw_show, "create", "table", ESqlStatementType.sstShow);
078        addCmd(TBaseType.rrw_show, "create", "view", ESqlStatementType.sstShow);
079        addCmd(TBaseType.rrw_show, "current", "roles", ESqlStatementType.sstShow);
080        addCmd(TBaseType.rrw_show, "role", "grants", ESqlStatementType.sstShow);
081        addCmd(TBaseType.rrw_show, "catalogs", ESqlStatementType.sstShow);
082        addCmd(TBaseType.rrw_show, "columns", ESqlStatementType.sstShow);
083        addCmd(TBaseType.rrw_show, "databases", ESqlStatementType.sstShow);
084        addCmd(TBaseType.rrw_show, "functions", ESqlStatementType.sstShow);
085        addCmd(TBaseType.rrw_show, "grants", ESqlStatementType.sstShow);
086        addCmd(TBaseType.rrw_show, "partitions", ESqlStatementType.sstShow);
087        addCmd(TBaseType.rrw_show, "roles", ESqlStatementType.sstShow);
088        addCmd(TBaseType.rrw_show, "schemas", ESqlStatementType.sstShow);
089        addCmd(TBaseType.rrw_show, "session", ESqlStatementType.sstShow);
090        addCmd(TBaseType.rrw_show, "stats", ESqlStatementType.sstShow);
091        addCmd(TBaseType.rrw_show, "tables", ESqlStatementType.sstShow);
092        addCmd(TBaseType.rrw_show, "tblproperties", ESqlStatementType.sstShow);
093        addCmd(TBaseType.rrw_show, "views", ESqlStatementType.sstShow);
094        addCmd(TBaseType.rrw_start, "transaction", ESqlStatementType.sstStartTransaction);
095        addCmd(TBaseType.rrw_athena_unload, ESqlStatementType.sstunload);
096        addCmd(TBaseType.rrw_use, ESqlStatementType.sstUse);
097        addCmd(TBaseType.rrw_values, ESqlStatementType.sstValues);
098    }
099
100    @Override
101    public TCustomSqlStatement issql(TSourceToken token, EFindSqlStateType state, TCustomSqlStatement currentStatement) {
102        TCustomSqlStatement ret = null;
103        int k;
104        boolean lcisnewsql;
105        TSourceToken lcpprevsolidtoken, lcnextsolidtoken;
106
107        gnewsqlstatementtype = ESqlStatementType.sstinvalid;
108
109        if ((token.tokencode == TBaseType.cmtdoublehyphen)
110                || (token.tokencode == TBaseType.cmtslashstar)
111                || (token.tokencode == TBaseType.lexspace)
112                || (token.tokencode == TBaseType.lexnewline)
113                || (token.tokentype == ETokenType.ttsemicolon)) {
114            return ret;
115        }
116
117        int lcpos = token.posinlist;
118        TSourceTokenList lcsourcetokenlist = token.container;
119        TCustomSqlStatement lccurrentsqlstatement = currentStatement;
120
121        //subquery after semicolon || at first line
122        if ((state == EFindSqlStateType.stnormal) && (token.tokentype == ETokenType.ttleftparenthesis)) { // (
123            k = lcsourcetokenlist.solidtokenafterpos(lcpos, TBaseType.rrw_select, 1, "(");
124            if (k > 0) {
125                ret = new TSelectSqlStatement(this.vendor);
126            }
127
128            return ret;
129        }
130
131        //cte
132        if ((state == EFindSqlStateType.stnormal) && (token.tokencode == TBaseType.rrw_with)) {
133            ret = findcte(token, this.vendor);
134            if ((ret != null)) return ret;
135        }
136
137        gnewsqlstatementtype = getStatementTypeForToken(token);
138
139        TSourceToken lcprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcpos);
140
141        if ((gnewsqlstatementtype == ESqlStatementType.sstinvalid) && (token.tokencode == TBaseType.rrw_create)) {
142            TSourceToken viewToken = token.container.searchToken(TBaseType.rrw_view, "", token, 15);
143            if (viewToken != null) {
144                gnewsqlstatementtype = ESqlStatementType.sstcreateview;
145            }
146        }
147
148        switch (gnewsqlstatementtype) {
149            case sstinvalid: {
150                ret = null;
151                break;
152            }
153            case sstselect: {
154                lcisnewsql = true;
155
156                if (state != EFindSqlStateType.stnormal) {
157                    if (TBaseType.assigned(lcprevsolidtoken)) {
158                        if (lcprevsolidtoken.tokentype == ETokenType.ttleftparenthesis)
159                            lcisnewsql = false; //subquery
160                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_union)
161                            lcisnewsql = false;
162                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_intersect)
163                            lcisnewsql = false;
164                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_minus)
165                            lcisnewsql = false;
166                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_except)
167                            lcisnewsql = false;
168                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_return)
169                            lcisnewsql = false;
170                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_as) {
171                            if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatetable)
172                                lcisnewsql = false;
173                            if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreateview)
174                                lcisnewsql = false;
175                        }
176
177                        if (lcisnewsql && (lcprevsolidtoken.tokencode == TBaseType.rrw_all)) {
178                            lcpprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcprevsolidtoken.posinlist);
179                            if (TBaseType.assigned(lcpprevsolidtoken)) {
180                                if (lcpprevsolidtoken.tokencode == TBaseType.rrw_union)
181                                    lcisnewsql = false;
182                            }
183                        }
184
185                    }
186
187
188                    if (TBaseType.assigned(lccurrentsqlstatement)) {
189                        if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstinsert)
190                            lcisnewsql = false;
191                    }
192
193                }
194
195                if (lcisnewsql)
196                    ret = new TSelectSqlStatement(this.vendor);
197                break;
198            }
199            case sstinsert: {
200                lcisnewsql = true;
201                if (state != EFindSqlStateType.stnormal) {
202                    if (TBaseType.assigned(lccurrentsqlstatement)) {
203
204                    }
205                }
206
207                if (lcisnewsql)
208                    ret = new TInsertSqlStatement(this.vendor);
209                ret.sqlstatementtype = gnewsqlstatementtype;
210                break;
211            }
212            case sstdelete: {
213                lcisnewsql = true;
214
215                if (state != EFindSqlStateType.stnormal) {
216                    lcprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcpos);
217                    if (TBaseType.assigned(lcprevsolidtoken)) {
218                        if (lcprevsolidtoken.tokencode == TBaseType.rrw_on)
219                            lcisnewsql = false;
220                    }
221
222                    if (TBaseType.assigned(lccurrentsqlstatement)) {
223                    }
224                }
225
226                if (lcisnewsql)
227                    ret = new TDeleteSqlStatement(this.vendor);
228                break;
229            }
230            case sstaltertable: {
231                ret = new TAlterTableStatement(this.vendor);
232                break;
233            }
234            case sstalterfunction: {
235                ret = new TAlterFunctionStmt(this.vendor);
236                break;
237            }
238            case sstAlterSchema: {
239                ret = new TAlterSchemaStmt(this.vendor);
240                break;
241            }
242            case sstanalyzeTable: {
243                ret = new TAnalyzeStmt(this.vendor);
244                break;
245            }
246            case sstcall: {
247                ret = new TCallStatement(this.vendor);
248                break;
249            }
250            case sstcommit: {
251                ret = new TCommitStmt(this.vendor);
252                break;
253            }
254            case sstcreatefunction: {
255                ret = new TCreateFunctionStmt(this.vendor);
256                break;
257            }
258            case sstcreaterole: {
259                ret = new TCreateRoleStmt(this.vendor);
260                break;
261            }
262            case sstcreateschema: {
263                ret = new TCreateSchemaSqlStatement(this.vendor);
264                break;
265            }
266            case sstcreatetable: {
267                ret = new TCreateTableSqlStatement(this.vendor);
268                break;
269            }
270            case sstcreateview: {
271                ret = new TCreateViewSqlStatement(this.vendor);
272                break;
273            }
274            case sstpostgresqlDeallocate: {
275                ret = new TUnknownSqlStatement(this.vendor);
276                ret.sqlstatementtype = gnewsqlstatementtype;
277                break;
278            }
279            case sstdescribe: {
280                ret = new TDescribeStmt(this.vendor);
281                break;
282            }
283            case sstdropfunction: {
284                ret = new TDropFunctionStmt(this.vendor);
285                break;
286            }
287            case sstdroprole: {
288                ret = new TDropRoleStmt(this.vendor);
289                break;
290            }
291            case sstdropschema: {
292                ret = new TDropSchemaSqlStatement(this.vendor);
293                break;
294            }
295            case sstdroptable: {
296                ret = new TDropTableSqlStatement(this.vendor);
297                break;
298            }
299            case sstdropview: {
300                ret = new TDropViewSqlStatement(this.vendor);
301                break;
302            }
303            case sstExecute: {
304                ret = new TExecuteSqlStatement(this.vendor);
305                break;
306            }
307            case sstExplain: {
308                ret = new TExplainPlan(this.vendor);
309                break;
310            }
311            case sstGrant: {
312                ret = new TGrantStmt(this.vendor);
313                break;
314            }
315            case sstprepare: {
316                ret = new TPrepareStmt(this.vendor);
317                break;
318            }
319            case sstset:
320            case sstReset: {
321                lcisnewsql = true;
322                if (state != EFindSqlStateType.stnormal) {
323                    if (TBaseType.assigned(lccurrentsqlstatement)) {
324                        lcisnewsql = false;
325                    }
326                }
327
328                if (lcisnewsql) {
329                    ret = new TSetStmt(this.vendor);
330                }
331                break;
332            }
333            case sstShow: {
334                ret = new TShowStmt(this.vendor);
335                ret.sqlstatementtype = gnewsqlstatementtype;
336                break;
337            }
338            case sstStartTransaction: {
339                ret = new TStartTransactionStmt(this.vendor);
340                break;
341            }
342            case sstUse: {
343                ret = new TUseDatabase(this.vendor);
344                break;
345            }
346            case sstValues: {
347                ret = new TSelectSqlStatement(this.vendor);
348                break;
349            }
350            case sstResetSession: {
351                ret = new TResetSessionStmt(this.vendor);
352                break;
353            }
354            case sstunload:
355                lcisnewsql = true;
356                if (state != EFindSqlStateType.stnormal) {
357                    lcisnewsql = false;
358                }
359                if (lcisnewsql) {
360                    ret = new TUnloadStmt(this.vendor);
361                    ret.sqlstatementtype = gnewsqlstatementtype;
362                }
363                break;
364            case sstmsck: {
365                ret = new TMSCKStmt(this.vendor);
366                break;
367            }
368            case sstcreatedatabase: {
369                ret = new TCreateDatabaseSqlStatement(this.vendor);
370                break;
371            }
372            case sstalterdatabase: {
373                ret = new TAlterDatabaseStmt(this.vendor);
374                break;
375            }
376            case sstdropdatabase:
377                ret = new TDropDatabaseStmt(this.vendor);
378                break;
379            default: {
380                ret = new TUnknownSqlStatement(this.vendor);
381                ret.sqlstatementtype = gnewsqlstatementtype;
382                break;
383            }
384        }    // case
385
386        return ret;
387    }
388
389    private TCustomSqlStatement findcte(TSourceToken ptoken, EDbVendor pdbvendor) {
390        TCustomSqlStatement ret = null;
391        TSourceToken lctoken = null;
392        int lcnested = 0, k, j;
393        boolean inXmlNamespaces = false;
394        boolean isXmlNamespaces = false;
395
396        int lcpos = ptoken.posinlist;
397        TSourceTokenList lcsourcetokenlist = ptoken.container;
398
399        for (int i = lcpos + 1; i < lcsourcetokenlist.size(); i++)    // iterate
400        {
401            lctoken = lcsourcetokenlist.get(i);
402            if (lctoken.tokencode == TBaseType.rrw_xmlnamespaces) {
403                inXmlNamespaces = true;
404                lcnested = 0;
405                continue;
406            }
407            if (inXmlNamespaces) {
408                if (lctoken.tokentype == ETokenType.ttleftparenthesis) lcnested++;
409                if (lctoken.tokentype == ETokenType.ttrightparenthesis) {
410                    lcnested--;
411                    if (lcnested == 0) {
412                        inXmlNamespaces = false;
413                        isXmlNamespaces = true;
414                    }
415                }
416                continue;
417            }
418            if ((lctoken.tokencode == TBaseType.rrw_as) || isXmlNamespaces) {
419                lcnested = 0;
420                int startPos = i + 1;
421                if (isXmlNamespaces) startPos = i;
422                for (j = startPos; j < lcsourcetokenlist.size(); j++) {
423                    lctoken = lcsourcetokenlist.get(j);
424                    if (lctoken.isnonsolidtoken()) continue;
425                    if (lctoken.tokentype == ETokenType.ttleftparenthesis) lcnested++;
426                    if (lctoken.tokentype == ETokenType.ttrightparenthesis) lcnested--;
427
428
429                    if ((lcnested == 0) && (lctoken.tokencode == TBaseType.rrw_delete)) {
430                        ret = new TDeleteSqlStatement(pdbvendor);
431                        ret.isctequery = true;
432                        gnewsqlstatementtype = ESqlStatementType.sstdelete;
433                        break;
434                    }
435
436                    if ((lcnested == 0) && (lctoken.tokencode == TBaseType.rrw_merge)) {
437                        ret = new TMergeSqlStatement(pdbvendor);
438                        ret.isctequery = true;
439                        gnewsqlstatementtype = ESqlStatementType.sstmerge;
440                        break;
441                    }
442
443                    if ((lcnested == 0) && (lctoken.tokencode == TBaseType.rrw_insert)) {
444                        ret = new TInsertSqlStatement(pdbvendor);
445                        ret.isctequery = true;
446                        gnewsqlstatementtype = ESqlStatementType.sstinsert;
447                        ret.dummytag = 1; //  select stmt in insert is permitted
448
449                        for (k = lctoken.posinlist + 1; k < lcsourcetokenlist.size(); k++)    // iterate
450                        {
451                            if (lcsourcetokenlist.get(k).isnonsolidtoken()) continue;
452                            if (lcsourcetokenlist.get(k).tokencode == TBaseType.rrw_values) break;
453                            if (lcsourcetokenlist.get(k).tokencode == TBaseType.rrw_go) break;
454                            if (lcsourcetokenlist.get(k).tokentype == ETokenType.ttsemicolon) break;
455                            if (lcsourcetokenlist.get(k).tokencode == TBaseType.rrw_select) break;
456                            if (lcsourcetokenlist.get(k).tokencode == TBaseType.rrw_execute) break;
457                            if (lcsourcetokenlist.get(k).tokencode == TBaseType.rrw_exec) break;
458                        }    // for
459                        if (k > lcsourcetokenlist.size() - 1)
460                            k = lcsourcetokenlist.size() - 1;
461
462                        for (int m = lctoken.posinlist + 1; m <= k; m++)    // iterate
463                        {
464                            lcsourcetokenlist.get(m).tokenstatus = ETokenStatus.tsignoredbygetrawstatement;
465                        }    // for
466
467                        break;
468                    }
469
470                    if ((lcnested == 0) && (lctoken.tokencode == TBaseType.rrw_values) && (pdbvendor == EDbVendor.dbvpostgresql)) {
471                        ret = new TSelectSqlStatement(pdbvendor);
472                        ret.isctequery = true;
473                        gnewsqlstatementtype = ESqlStatementType.sstselect;
474                        break;
475                    }
476
477                    if ((lcnested == 0) && (lctoken.tokencode == TBaseType.rrw_select)) {
478                        ret = new TSelectSqlStatement(pdbvendor);
479                        ret.isctequery = true;
480                        gnewsqlstatementtype = ESqlStatementType.sstselect;
481                        break;
482                    }
483
484                    if ((lcnested == 0) && (lctoken.tokencode == TBaseType.rrw_update)) {
485                        ret = new TUpdateSqlStatement(pdbvendor);
486                        ret.isctequery = true;
487                        ret.dummytag = 1; // means set clause in update is not found yet, used to seperate set clause from set statement
488                        gnewsqlstatementtype = ESqlStatementType.sstupdate;
489                        break;
490                    }
491
492                    if ((pdbvendor == EDbVendor.dbvhive) && (lcnested == 0) && (lctoken.tokencode == TBaseType.rrw_from)) {
493                        TSourceToken cmdToken = lctoken.searchToken(TBaseType.rrw_insert, 3);
494                        if (cmdToken != null) {
495                            ret = new TInsertSqlStatement(pdbvendor);
496                            ret.isctequery = true;
497                            gnewsqlstatementtype = ESqlStatementType.sstinsert;
498
499                        } else {
500                            ret = new TSelectSqlStatement(pdbvendor);
501                            ret.isctequery = true;
502                            gnewsqlstatementtype = ESqlStatementType.ssthiveFromQuery;
503                        }
504                        break;
505                    }
506
507
508                }    // for
509
510                if ((ret != null)) {
511                    for (k = lcpos + 1; k <= j; k++)    // iterate
512                    {
513                        lcsourcetokenlist.get(k).tokenstatus = ETokenStatus.tsignoredbygetrawstatement;
514                    }    // for
515                    break;
516                }
517
518            }
519        }
520
521        return ret;
522    }
523}