001package gudusoft.gsqlparser.sqlcmds;
002
003import gudusoft.gsqlparser.*;
004import gudusoft.gsqlparser.stmt.*;
005import gudusoft.gsqlparser.stmt.bigquery.TCreateModelSqlStatement;
006import gudusoft.gsqlparser.stmt.bigquery.TExportDataStmt;
007import gudusoft.gsqlparser.stmt.mssql.TMssqlDeclare;
008
009/**
010 * BigQuery SQL command resolver.
011 * Contains all BigQuery-specific SQL command recognition logic.
012 *
013 * @since 3.1.0.9
014 */
015public class TSqlCmdsBigquery extends AbstractSqlCmds {
016
017    // Temporary field for statement type during issql processing
018    private ESqlStatementType gnewsqlstatementtype = ESqlStatementType.sstinvalid;
019
020    public TSqlCmdsBigquery() {
021        super(EDbVendor.dbvbigquery);
022    }
023
024    @Override
025    protected String getToken1Str(int token1) {
026        // Handle BigQuery-specific reserved words (token codes > TBaseType.rrw_abort)
027        switch (token1) {
028            case TBaseType.rrw_bigquery_export:
029                return "export";
030            default:
031                return null;
032        }
033    }
034
035    @Override
036    protected void initializeCommands() {
037        // BigQuery commands must be sorted alphabetically by token1
038        addCmd(TBaseType.rrw_alter, "view", ESqlStatementType.sstalterview);
039        addCmd(TBaseType.rrw_alter, "table", ESqlStatementType.sstaltertable);
040
041        addCmd(TBaseType.rrw_begin, ESqlStatementType.sstBegin);
042        addCmd(TBaseType.rrw_begin, "transaction", ESqlStatementType.sstbegintran);
043
044        addCmd(TBaseType.rrw_call, ESqlStatementType.sstcall);
045        addCmd(TBaseType.rrw_case, ESqlStatementType.sst_casestmt);
046
047        // CREATE commands - longer patterns BEFORE shorter ones
048        addCmd(TBaseType.rrw_create, "or", "replace", "external", "table", ESqlStatementType.sstcreatetable);
049        addCmd(TBaseType.rrw_create, "or", "replace", "temporary", "table", ESqlStatementType.sstcreatetable);
050        addCmd(TBaseType.rrw_create, "or", "replace", "materialized", "view", ESqlStatementType.sstcreatematerializedview);
051        addCmd(TBaseType.rrw_create, "or", "replace", "table", "function", ESqlStatementType.sstcreatefunction);
052        addCmd(TBaseType.rrw_create, "or", "replace", "temporary", "function", ESqlStatementType.sstcreatefunction);
053        addCmd(TBaseType.rrw_create, "or", "replace", "temp", "function", ESqlStatementType.sstcreatefunction);
054        addCmd(TBaseType.rrw_create, "or", "replace", "temp", "table", ESqlStatementType.sstcreatetable);
055        addCmd(TBaseType.rrw_create, "or", "replace", "function", ESqlStatementType.sstcreatefunction);
056        addCmd(TBaseType.rrw_create, "or", "replace", "procedure", ESqlStatementType.sstcreateprocedure);
057        addCmd(TBaseType.rrw_create, "or", "replace", "table", ESqlStatementType.sstcreatetable);
058        addCmd(TBaseType.rrw_create, "or", "replace", "view", ESqlStatementType.sstcreateview);
059        addCmd(TBaseType.rrw_create, "or", "replace", "model", ESqlStatementType.sstcreatemodel);
060        addCmd(TBaseType.rrw_create, "external", "table", ESqlStatementType.sstcreatetable);
061        addCmd(TBaseType.rrw_create, "materialized", "view", ESqlStatementType.sstcreatematerializedview);
062        addCmd(TBaseType.rrw_create, "snapshot", "table", ESqlStatementType.sstcreatetable);
063        addCmd(TBaseType.rrw_create, "table", "function", ESqlStatementType.sstcreatefunction);
064        addCmd(TBaseType.rrw_create, "temporary", "function", ESqlStatementType.sstcreatefunction);
065        addCmd(TBaseType.rrw_create, "temporary", "table", ESqlStatementType.sstcreatetable);
066        addCmd(TBaseType.rrw_create, "temp", "function", ESqlStatementType.sstcreatefunction);
067        addCmd(TBaseType.rrw_create, "temp", "table", ESqlStatementType.sstcreatetable);
068        addCmd(TBaseType.rrw_create, "function", ESqlStatementType.sstcreatefunction);
069        addCmd(TBaseType.rrw_create, "model", ESqlStatementType.sstcreatemodel);
070        addCmd(TBaseType.rrw_create, "procedure", ESqlStatementType.sstcreateprocedure);
071        addCmd(TBaseType.rrw_create, "table", ESqlStatementType.sstcreatetable);
072        addCmd(TBaseType.rrw_create, "view", ESqlStatementType.sstcreateview);
073        addCmd(TBaseType.rrw_declare, ESqlStatementType.sstBigQueryDeclare);
074        addCmd(TBaseType.rrw_delete, ESqlStatementType.sstdelete);
075
076        // DROP commands - longer patterns BEFORE shorter ones
077        addCmd(TBaseType.rrw_drop, "all", "row", "access", "policies", ESqlStatementType.sstDropRowAccessPolicy);
078        addCmd(TBaseType.rrw_drop, "row", "access", "policy", ESqlStatementType.sstDropRowAccessPolicy);
079        addCmd(TBaseType.rrw_drop, "table", "function", ESqlStatementType.sstDropTableFunction);
080        addCmd(TBaseType.rrw_drop, "snapshot", "table", ESqlStatementType.sstDropSnapshotTable);
081        addCmd(TBaseType.rrw_drop, "materialized", "view", ESqlStatementType.sstDropMaterializedView);
082        addCmd(TBaseType.rrw_drop, "external", "table", ESqlStatementType.sstdroptable);
083        addCmd(TBaseType.rrw_drop, "assignment", ESqlStatementType.sstDropAssignment);
084        addCmd(TBaseType.rrw_drop, "function", ESqlStatementType.sstdropfunction);
085        addCmd(TBaseType.rrw_drop, "model", ESqlStatementType.sstdropmodel);
086        addCmd(TBaseType.rrw_drop, "procedure", ESqlStatementType.sstdropprocedure);
087        addCmd(TBaseType.rrw_drop, "reservation", ESqlStatementType.sstDropReservation);
088        addCmd(TBaseType.rrw_drop, "schema", ESqlStatementType.sstdropschema);
089        addCmd(TBaseType.rrw_drop, "table", ESqlStatementType.sstdroptable);
090        addCmd(TBaseType.rrw_drop, "view", ESqlStatementType.sstdropview);
091
092        addCmd(TBaseType.rrw_execute, "immediate", ESqlStatementType.sstExecute);
093
094        addCmd(TBaseType.rrw_bigquery_export, "data", ESqlStatementType.sstBigQueryExportData);
095        addCmd(TBaseType.rrw_for, ESqlStatementType.sstForStmt);
096        addCmd(TBaseType.rrw_if, ESqlStatementType.sst_ifstmt);
097        addCmd(TBaseType.rrw_insert, ESqlStatementType.sstinsert);
098        addCmd(TBaseType.rrw_loop, ESqlStatementType.sst_loopstmt);
099        addCmd(TBaseType.rrw_merge, ESqlStatementType.sstmerge);
100        addCmd(TBaseType.rrw_repeat, ESqlStatementType.sstRepeat);
101        addCmd(TBaseType.rrw_select, ESqlStatementType.sstselect);
102        addCmd(TBaseType.rrw_set, ESqlStatementType.sstset);
103        addCmd(TBaseType.rrw_truncate, ESqlStatementType.sstTruncate);
104        addCmd(TBaseType.rrw_update, ESqlStatementType.sstupdate);
105        addCmd(TBaseType.rrw_while, ESqlStatementType.sstWhilestmt);
106    }
107
108    @Override
109    public TCustomSqlStatement issql(TSourceToken pcst, EFindSqlStateType pstate, TCustomSqlStatement psqlstatement) {
110        TCustomSqlStatement ret = null;
111
112        gnewsqlstatementtype = ESqlStatementType.sstinvalid;
113
114        if ((pcst.tokencode == TBaseType.cmtdoublehyphen)
115                || (pcst.tokencode == TBaseType.cmtslashstar)
116                || (pcst.tokencode == TBaseType.lexspace)
117                || (pcst.tokencode == TBaseType.lexnewline)
118                || (pcst.tokentype == ETokenType.ttsemicolon)) {
119            return null;
120        }
121
122        int lcpos = pcst.posinlist;
123        TSourceTokenList lcsourcetokenlist = pcst.container;
124        TCustomSqlStatement lccurrentsqlstatement = psqlstatement;
125
126        //subquery after semicolon or at first line
127        if ((pstate == EFindSqlStateType.stnormal) && (pcst.tokentype == ETokenType.ttleftparenthesis)) // (
128        {
129            int k = lcsourcetokenlist.solidtokenafterpos(lcpos, TBaseType.rrw_select, 1, "(");
130            if (k > 0) {
131                ret = new TSelectSqlStatement(this.vendor);
132            }
133
134            return ret;
135        }
136
137        //cte
138        if ((pstate == EFindSqlStateType.stnormal) && (pcst.tokencode == TBaseType.rrw_with)) {
139            ret = findcte(pcst);
140            if ((ret != null)) return ret;
141        }
142
143        gnewsqlstatementtype = getStatementTypeForToken(pcst);
144
145        TSourceToken lcprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcpos);
146        switch (gnewsqlstatementtype) {    //
147            case sstinvalid: {
148                ret = null;
149
150                if (pstate == EFindSqlStateType.stnormal) {
151                    if (pcst.tokencode == TBaseType.rrw_begin) {
152
153                        ret = new TCommonBlock(this.vendor);
154                        gnewsqlstatementtype = ret.sqlstatementtype;
155                    }
156
157                }
158                break;
159            }
160            case sstselect: {
161                boolean lcisnewsql = true;
162
163                if (pstate != EFindSqlStateType.stnormal) {
164                    // lcprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcpos);
165                    if ((lcprevsolidtoken != null)) {
166                        if (lcprevsolidtoken.tokentype == ETokenType.ttleftparenthesis)
167                            lcisnewsql = false; //subqery
168                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_union)
169                            lcisnewsql = false;
170                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_intersect)
171                            lcisnewsql = false;
172                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_minus)
173                            lcisnewsql = false;
174                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_except)
175                            lcisnewsql = false;
176                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_return)
177                            lcisnewsql = false;
178                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_as) {
179                            if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatetable)
180                                lcisnewsql = false;
181                            if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreateview)
182                                lcisnewsql = false;
183                        }
184
185                        if (lcisnewsql && (lcprevsolidtoken.tokencode == TBaseType.rrw_all)) {
186                            TSourceToken lcpprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcprevsolidtoken.posinlist);
187                            if ((lcpprevsolidtoken != null)) {
188                                if (lcpprevsolidtoken.tokencode == TBaseType.rrw_union)
189                                    lcisnewsql = false;
190                            }
191                        }
192
193                    }
194
195
196                    if ((lccurrentsqlstatement != null)) {
197                        if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstinsert)
198                            lcisnewsql = false;
199                    }
200
201                }
202
203                if (lcisnewsql)
204                    ret = new TSelectSqlStatement(this.vendor);
205
206                break;
207            }
208            case sstinsert: {
209                boolean lcisnewsql = true;
210                if (pstate != EFindSqlStateType.stnormal) {
211                    if ((lccurrentsqlstatement != null)) {
212
213                    }
214                }
215
216                if (lcisnewsql)
217                    ret = new TInsertSqlStatement(this.vendor);
218
219                break;
220            }
221            case sstupdate: {
222                boolean lcisnewsql = true;
223                if (pstate != EFindSqlStateType.stnormal) {
224                    lcprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcpos);
225                    if ((lcprevsolidtoken != null)) { //
226                        if (lcprevsolidtoken.tokencode == TBaseType.rrw_on)
227                            lcisnewsql = false;
228                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_for)
229                            lcisnewsql = false;
230                    }
231
232                    TSourceToken lcnextsolidtoken = lcsourcetokenlist.nextsolidtoken(lcpos, 1, false);
233                    if ((lcnextsolidtoken != null)) {
234                        if (lcnextsolidtoken.tokentype == ETokenType.ttleftparenthesis) {
235                            int k = lcsourcetokenlist.solidtokenafterpos(lcnextsolidtoken.posinlist, TBaseType.rrw_select, 1, "(");
236                            if (k == 0) lcisnewsql = false;
237                        }
238                    }
239
240
241                    if ((lccurrentsqlstatement != null)) {
242                    }
243                }
244
245                if (lcisnewsql) {
246                    ret = new TUpdateSqlStatement(this.vendor);
247                    ret.dummytag = 1; // means set clause in update is not found yet, used to seperate set clause from set statement
248                }
249                break;
250            }
251            case sstdelete: {
252                boolean lcisnewsql = true;
253
254                if (pstate != EFindSqlStateType.stnormal) {
255                    lcprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcpos);
256                    if ((lcprevsolidtoken != null)) {
257                        if (lcprevsolidtoken.tokencode == TBaseType.rrw_on)
258                            lcisnewsql = false;
259                    }
260
261                    if ((lccurrentsqlstatement != null)) {
262                    }
263                }
264
265                if (lcisnewsql)
266                    ret = new TDeleteSqlStatement(this.vendor);
267
268                break;
269            }
270            case sstmerge: {
271                ret = new TMergeSqlStatement(this.vendor);
272                ret.sqlstatementtype = gnewsqlstatementtype;
273                break;
274            }
275            case sstcreatetable: {
276                ret = new TCreateTableSqlStatement(this.vendor);
277                break;
278            }
279            case sstcreateview: {
280                ret = new TCreateViewSqlStatement(this.vendor);
281                break;
282            }
283            case sstaltertable: {
284                ret = new TAlterTableStatement(this.vendor);
285                break;
286            }
287            case sstalterview: {
288                ret = new TAlterViewStatement(this.vendor);
289                break;
290            }
291            case sstdroptable: {
292                ret = new TDropTableSqlStatement(this.vendor);
293                break;
294            }
295            case sstdropview: {
296                ret = new TDropViewSqlStatement(this.vendor);
297                break;
298            }
299            case sstcreatefunction: {
300                ret = new TCreateFunctionStmt(this.vendor);
301                break;
302            }
303            case sstcreateprocedure: {
304                ret = new TCreateProcedureStmt(this.vendor);
305                break;
306            }
307            case sstBigQueryDeclare:
308                ret = new TMssqlDeclare(this.vendor);
309                break;
310            case sstTruncate: {
311                ret = new TTruncateStatement(this.vendor);
312                break;
313            }
314            case sstset: {
315                boolean lcisnewsql = true;
316                if (pstate != EFindSqlStateType.stnormal) {
317                    if (TBaseType.assigned(lccurrentsqlstatement)) {
318                        lcisnewsql = false;
319                    }
320                }
321
322                if (lcisnewsql) {
323                    ret = new TSetStmt(this.vendor);
324                }
325                break;
326            }
327            case sstcreatematerializedview: {
328                ret = new TCreateMaterializedSqlStatement(this.vendor);
329                break;
330            }
331            case sstdropprocedure: {
332                ret = new TDropProcedureStmt(this.vendor);
333                break;
334            }
335            case sstdropfunction: {
336                ret = new TDropFunctionStmt(this.vendor);
337                break;
338            }
339            case sstDropMaterializedView:
340                ret = new TDropMaterializedViewStmt(this.vendor);
341                break;
342            case sstcall:
343                ret = new TCallStatement(this.vendor);
344                break;
345            case sstBigQueryExportData:
346                ret = new TExportDataStmt(this.vendor);
347                break;
348            case sstcreatemodel:
349                ret = new TCreateModelSqlStatement(this.vendor);
350                break;
351            case sstdropmodel:
352                ret = new TDropStmt(this.vendor);
353                break;
354            case sstBegin: {
355                boolean isblock = false;
356                int numOfSolidToken = 0;
357                // if linebreak appears before the ;, then it a block, else it a
358                TSourceToken st;
359                if (lcpos == lcsourcetokenlist.size() - 1) {
360                    // this is the last token
361                } else {
362                    for (int i = lcpos + 1; i < lcsourcetokenlist.size(); i++) {
363                        st = lcsourcetokenlist.get(i);
364                        if (st.issolidtoken()) {
365                            numOfSolidToken++;
366                        }
367
368
369                        if (st.tokencode == ';') {
370                            if (numOfSolidToken <= 3) {
371
372                            } else {
373                                isblock = true;
374                            }
375                            break;
376                        }
377
378                        if (numOfSolidToken > 3) {
379                            isblock = true;
380                            break;
381                        }
382                    }
383                }
384
385                if (isblock) {
386                    ret = new TCommonBlock(this.vendor);
387                    gnewsqlstatementtype = ret.sqlstatementtype;
388                } else {
389                    ret = new TBeginTran(this.vendor);
390                    pcst.tokencode = TBaseType.rrw_bigquery_begin_transaction;
391                }
392
393
394                break;
395            }
396            case sstbegintran: {
397                ret = new TBeginTran(this.vendor);
398                if (pcst.tokencode == TBaseType.rrw_begin) {
399                    pcst.tokencode = TBaseType.rrw_bigquery_begin_transaction;
400                }
401
402                break;
403            }
404            case sstExecute: {
405                ret = new TExecImmeStmt(this.vendor);
406                break;
407            }
408            case sst_ifstmt:
409                ret = new TIfStmt(this.vendor);
410                break;
411            case sst_loopstmt:
412                ret = new TLoopStmt(this.vendor);
413                break;
414            case sstRepeat:
415                ret = new TRepeatStmt(this.vendor);
416                break;
417            case sstWhilestmt:
418                ret = new TWhileStmt(this.vendor);
419                break;
420            case sstForStmt:
421                ret = new TForStmt(this.vendor);
422                break;
423            case sst_casestmt:
424                ret = new TCaseStmt(this.vendor);
425                break;
426            case sstDropAssignment:
427                ret = new TDropStmt(this.vendor);
428                break;
429            case sstdropschema:
430                ret = new TDropSchemaSqlStatement(this.vendor);
431                break;
432            case sstDropReservation:
433                ret = new TDropStmt(this.vendor);
434                break;
435            case sstDropRowAccessPolicy:
436                ret = new TDropStmt(this.vendor);
437                break;
438            case sstDropSnapshotTable:
439                ret = new TDropStmt(this.vendor);
440                break;
441            case sstDropTableFunction:
442                ret = new TDropStmt(this.vendor);
443                break;
444            default: {
445                ret = new TUnknownSqlStatement(this.vendor);
446                ret.sqlstatementtype = gnewsqlstatementtype;
447                break;
448            }
449        }    // case
450
451        return ret;
452    }
453}