001package gudusoft.gsqlparser.sqlcmds;
002
003import gudusoft.gsqlparser.*;
004import gudusoft.gsqlparser.stmt.*;
005import gudusoft.gsqlparser.stmt.sparksql.*;
006import gudusoft.gsqlparser.stmt.mysql.TLoadDataStmt;
007import gudusoft.gsqlparser.stmt.flink.TFlinkExplainStmt;
008import gudusoft.gsqlparser.stmt.flink.TFlinkCreateCatalogStmt;
009import gudusoft.gsqlparser.stmt.flink.TFlinkDropCatalogStmt;
010import gudusoft.gsqlparser.stmt.flink.TFlinkAlterCatalogStmt;
011
012/**
013 * Apache Flink SQL command resolver.
014 * Based on SparkSQL implementation with Flink-specific additions.
015 *
016 * @since 3.2.0.0
017 */
018public class TSqlCmdsFlink extends AbstractSqlCmds {
019
020    public TSqlCmdsFlink() {
021        super(EDbVendor.dbvflink);
022    }
023
024    @Override
025    protected void initializeCommands() {
026        // Commands ordered with longer patterns before shorter ones
027
028        // ALTER commands
029        addCmd(TBaseType.rrw_alter, "catalog", ESqlStatementType.sstaltercatalog);
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        addCmd(TBaseType.rrw_alter, "function", ESqlStatementType.sstalterfunction);
034
035        // ANALYZE commands
036        addCmd(TBaseType.rrw_analyze, "table", ESqlStatementType.sstanalyzeTable);
037
038        // CREATE commands (longer patterns first)
039        addCmd(TBaseType.rrw_create, "or", "replace", "temporary", "view", ESqlStatementType.sstcreateview);
040        addCmd(TBaseType.rrw_create, "or", "replace", "view", ESqlStatementType.sstcreateview);
041        addCmd(TBaseType.rrw_create, "or", "replace", "table", ESqlStatementType.sstcreatetable);
042        addCmd(TBaseType.rrw_create, "temporary", "system", "function", ESqlStatementType.sstcreatefunction);
043        addCmd(TBaseType.rrw_create, "temporary", "function", ESqlStatementType.sstcreatefunction);
044        addCmd(TBaseType.rrw_create, "temporary", "view", ESqlStatementType.sstcreateview);
045        addCmd(TBaseType.rrw_create, "temporary", "table", ESqlStatementType.sstcreatetable);
046        addCmd(TBaseType.rrw_create, "catalog", ESqlStatementType.sstcreatecatalog);
047        addCmd(TBaseType.rrw_create, "database", ESqlStatementType.sstcreatedatabase);
048        addCmd(TBaseType.rrw_create, "function", ESqlStatementType.sstcreatefunction);
049        addCmd(TBaseType.rrw_create, "table", ESqlStatementType.sstcreatetable);
050        addCmd(TBaseType.rrw_create, "view", ESqlStatementType.sstcreateview);
051
052        // DELETE commands
053        addCmd(TBaseType.rrw_delete, ESqlStatementType.sstdelete);
054
055        // DESCRIBE commands (DESC and DESCRIBE variants)
056        addCmd(TBaseType.rrw_spark_desc, "database", ESqlStatementType.sstdescribeDatabase);
057        addCmd(TBaseType.rrw_spark_desc, "function", ESqlStatementType.sstdescribeFunction);
058        addCmd(TBaseType.rrw_spark_desc, "table", ESqlStatementType.sstdescribeTable);
059        addCmd(TBaseType.rrw_spark_desc, ESqlStatementType.sstdescribeTable);
060        addCmd(TBaseType.rrw_describe, "database", ESqlStatementType.sstdescribeDatabase);
061        addCmd(TBaseType.rrw_describe, "function", ESqlStatementType.sstdescribeFunction);
062        addCmd(TBaseType.rrw_describe, "table", ESqlStatementType.sstdescribeTable);
063        addCmd(TBaseType.rrw_describe, ESqlStatementType.sstdescribe);
064
065        // DROP commands
066        addCmd(TBaseType.rrw_drop, "temporary", "system", "function", ESqlStatementType.sstdropfunction);
067        addCmd(TBaseType.rrw_drop, "temporary", "function", ESqlStatementType.sstdropfunction);
068        addCmd(TBaseType.rrw_drop, "temporary", "view", ESqlStatementType.sstdropview);
069        addCmd(TBaseType.rrw_drop, "temporary", "table", ESqlStatementType.sstdroptable);
070        addCmd(TBaseType.rrw_drop, "catalog", ESqlStatementType.sstdropcatalog);
071        addCmd(TBaseType.rrw_drop, "database", ESqlStatementType.sstdropdatabase);
072        addCmd(TBaseType.rrw_drop, "function", ESqlStatementType.sstdropfunction);
073        addCmd(TBaseType.rrw_drop, "table", ESqlStatementType.sstdroptable);
074        addCmd(TBaseType.rrw_drop, "view", ESqlStatementType.sstdropview);
075
076        // EXPLAIN commands
077        addCmd(TBaseType.rrw_explain, ESqlStatementType.sstExplain);
078
079        // INSERT commands
080        addCmd(TBaseType.rrw_insert, "overwrite", ESqlStatementType.sstinsert);
081        addCmd(TBaseType.rrw_insert, "into", ESqlStatementType.sstinsert);
082        addCmd(TBaseType.rrw_insert, ESqlStatementType.sstinsert);
083
084        // REPLACE commands (Flink RTAS)
085        addCmd(TBaseType.rrw_replace, "table", ESqlStatementType.sstcreatetable);
086
087        // RESET commands
088        addCmd(TBaseType.rrw_reset, ESqlStatementType.sstReset);
089
090        // SELECT commands
091        addCmd(TBaseType.rrw_select, ESqlStatementType.sstselect);
092
093        // SET commands
094        addCmd(TBaseType.rrw_set, ESqlStatementType.sstset);
095
096        // SHOW commands
097        addCmd(TBaseType.rrw_show, "create", "table", ESqlStatementType.sstShowCreateTable);
098        addCmd(TBaseType.rrw_show, "columns", ESqlStatementType.sstShowColumns);
099        addCmd(TBaseType.rrw_show, "databases", ESqlStatementType.sstShowDatabases);
100        addCmd(TBaseType.rrw_show, "functions", ESqlStatementType.sstShowFunctions);
101        addCmd(TBaseType.rrw_show, "partitions", ESqlStatementType.sstShowPartitions);
102        addCmd(TBaseType.rrw_show, "tables", ESqlStatementType.sstShowTables);
103        addCmd(TBaseType.rrw_show, "views", ESqlStatementType.sstShowViews);
104
105        // TRUNCATE commands
106        addCmd(TBaseType.rrw_truncate, "table", ESqlStatementType.ssttruncatetable);
107
108        // UPDATE commands
109        addCmd(TBaseType.rrw_update, ESqlStatementType.sstupdate);
110
111        // USE commands
112        addCmd(TBaseType.rrw_use, ESqlStatementType.sstUse);
113    }
114
115    @Override
116    protected String getToken1Str(int token1) {
117        // Flink vendor-specific tokens (inherited from SparkSQL)
118        switch (token1) {
119            case TBaseType.rrw_spark_desc:
120                return "desc";
121            default:
122                return null;
123        }
124    }
125
126    @Override
127    public TCustomSqlStatement issql(TSourceToken token, EFindSqlStateType state, TCustomSqlStatement currentStatement) {
128
129        TCustomSqlStatement ret = null;
130        int k;
131        boolean lcisnewsql;
132        TSourceToken lcpprevsolidtoken, lcnextsolidtoken;
133
134        gnewsqlstatementtype = ESqlStatementType.sstinvalid;
135
136        if ((token.tokencode == TBaseType.cmtdoublehyphen)
137                || (token.tokencode == TBaseType.cmtslashstar)
138                || (token.tokencode == TBaseType.lexspace)
139                || (token.tokencode == TBaseType.lexnewline)
140                || (token.tokentype == ETokenType.ttsemicolon)) {
141            return ret;
142        }
143
144        int lcpos = token.posinlist;
145        TSourceTokenList lcsourcetokenlist = token.container;
146        TCustomSqlStatement lccurrentsqlstatement = currentStatement;
147
148        // subquery after semicolon || at first line
149        if ((state == EFindSqlStateType.stnormal) && (token.tokentype == ETokenType.ttleftparenthesis)) {
150            k = lcsourcetokenlist.solidtokenafterpos(lcpos, TBaseType.rrw_select, 1, "(");
151            if (k > 0) {
152                ret = new TSelectSqlStatement(this.vendor);
153            }
154            return ret;
155        }
156
157        // cte
158        if ((state == EFindSqlStateType.stnormal) && (token.tokencode == TBaseType.rrw_with)) {
159            ret = findcte(token);
160            if ((ret != null)) return ret;
161        }
162
163        gnewsqlstatementtype = getStatementTypeForToken(token);
164
165        TSourceToken lcprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcpos);
166
167        if ((gnewsqlstatementtype == ESqlStatementType.sstinvalid) && (token.tokencode == TBaseType.rrw_create)) {
168            TSourceToken viewToken = token.container.searchToken(TBaseType.rrw_view, "", token, 15);
169            if (viewToken != null) {
170                gnewsqlstatementtype = ESqlStatementType.sstcreateview;
171            }
172        }
173
174        switch (gnewsqlstatementtype) {
175            case sstinvalid: {
176                ret = null;
177                break;
178            }
179            case sstselect: {
180                lcisnewsql = true;
181
182                if (state != EFindSqlStateType.stnormal) {
183                    if (TBaseType.assigned(lcprevsolidtoken)) {
184                        if (lcprevsolidtoken.tokentype == ETokenType.ttleftparenthesis)
185                            lcisnewsql = false; // subquery
186                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_union)
187                            lcisnewsql = false;
188                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_intersect)
189                            lcisnewsql = false;
190                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_minus)
191                            lcisnewsql = false;
192                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_except)
193                            lcisnewsql = false;
194                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_return)
195                            lcisnewsql = false;
196                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_as) {
197                            if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreatetable)
198                                lcisnewsql = false;
199                            if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstcreateview)
200                                lcisnewsql = false;
201                        }
202
203                        if (lcisnewsql && (lcprevsolidtoken.tokencode == TBaseType.rrw_all)) {
204                            lcpprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcprevsolidtoken.posinlist);
205                            if (TBaseType.assigned(lcpprevsolidtoken)) {
206                                if (lcpprevsolidtoken.tokencode == TBaseType.rrw_union)
207                                    lcisnewsql = false;
208                            }
209                        }
210                    }
211
212                    if (TBaseType.assigned(lccurrentsqlstatement)) {
213                        if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstinsert)
214                            lcisnewsql = false;
215                    }
216                }
217
218                if (lcisnewsql)
219                    ret = new TSelectSqlStatement(this.vendor);
220                break;
221            }
222            case sstinsert: {
223                lcisnewsql = true;
224                if (state != EFindSqlStateType.stnormal) {
225                    if (TBaseType.assigned(lccurrentsqlstatement)) {
226                        // No special handling needed
227                    }
228                }
229
230                if (lcisnewsql)
231                    ret = new TInsertSqlStatement(this.vendor);
232                ret.sqlstatementtype = gnewsqlstatementtype;
233                break;
234            }
235            case sstupdate: {
236                lcisnewsql = true;
237                if (state != EFindSqlStateType.stnormal) {
238                    lcprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcpos);
239                    if (TBaseType.assigned(lcprevsolidtoken)) {
240                        if (lcprevsolidtoken.tokencode == TBaseType.rrw_on)
241                            lcisnewsql = false;
242                        else if (lcprevsolidtoken.tokencode == TBaseType.rrw_for)
243                            lcisnewsql = false;
244                    }
245
246                    lcnextsolidtoken = lcsourcetokenlist.nextsolidtoken(lcpos, 1, false);
247                    if (TBaseType.assigned(lcnextsolidtoken)) {
248                        if (lcnextsolidtoken.tokentype == ETokenType.ttleftparenthesis) {
249                            k = lcsourcetokenlist.solidtokenafterpos(lcnextsolidtoken.posinlist, TBaseType.rrw_select, 1, "(");
250                            if (k == 0) lcisnewsql = false;
251                        }
252                    }
253
254                    if (TBaseType.assigned(lccurrentsqlstatement)) {
255                        // No special handling needed
256                    }
257                }
258
259                if (lcisnewsql) {
260                    ret = new TUpdateSqlStatement(this.vendor);
261                    ret.dummytag = 1;
262                }
263                break;
264            }
265            case sstdelete: {
266                lcisnewsql = true;
267
268                if (state != EFindSqlStateType.stnormal) {
269                    lcprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcpos);
270                    if (TBaseType.assigned(lcprevsolidtoken)) {
271                        if (lcprevsolidtoken.tokencode == TBaseType.rrw_on)
272                            lcisnewsql = false;
273                    }
274
275                    if (TBaseType.assigned(lccurrentsqlstatement)) {
276                        // No special handling needed
277                    }
278                }
279
280                if (lcisnewsql)
281                    ret = new TDeleteSqlStatement(this.vendor);
282                break;
283            }
284            case sstcreatetable: {
285                ret = new TCreateTableSqlStatement(this.vendor);
286                break;
287            }
288            case sstcreateview: {
289                ret = new TCreateViewSqlStatement(this.vendor);
290                break;
291            }
292            case sstcreatedatabase: {
293                ret = new TCreateDatabaseSqlStatement(this.vendor);
294                break;
295            }
296            case sstcreatecatalog: {
297                ret = new TFlinkCreateCatalogStmt(this.vendor);
298                break;
299            }
300            case sstdroptable: {
301                ret = new TDropTableSqlStatement(this.vendor);
302                break;
303            }
304            case sstdropview: {
305                ret = new TDropViewSqlStatement(this.vendor);
306                break;
307            }
308            case sstdropdatabase: {
309                ret = new TDropDatabaseStmt(this.vendor);
310                break;
311            }
312            case sstdropcatalog: {
313                ret = new TFlinkDropCatalogStmt(this.vendor);
314                break;
315            }
316            case sstaltertable: {
317                ret = new TAlterTableStatement(this.vendor);
318                break;
319            }
320            case sstalterview: {
321                ret = new TAlterViewStatement(this.vendor);
322                break;
323            }
324            case sstalterdatabase: {
325                ret = new TAlterDatabaseStmt(this.vendor);
326                break;
327            }
328            case sstaltercatalog: {
329                ret = new TFlinkAlterCatalogStmt(this.vendor);
330                break;
331            }
332            case sstset:
333            case sstReset: {
334                lcisnewsql = true;
335                if (state != EFindSqlStateType.stnormal) {
336                    if (TBaseType.assigned(lccurrentsqlstatement)) {
337                        lcisnewsql = false;
338                    }
339                }
340
341                if (lcisnewsql) {
342                    ret = new TSetStmt(this.vendor);
343                }
344                break;
345            }
346            case sstcreatefunction: {
347                ret = new TCreateFunctionStmt(this.vendor);
348                break;
349            }
350            case sstdropfunction: {
351                ret = new TDropFunctionStmt(this.vendor);
352                break;
353            }
354            case sstalterfunction: {
355                ret = new TAlterFunctionStmt(this.vendor);
356                break;
357            }
358            case sstTruncate:
359            case ssttruncatetable: {
360                ret = new TTruncateStatement(this.vendor);
361                break;
362            }
363            case sstdescribe: {
364                ret = new TDescribeStmt(this.vendor);
365                break;
366            }
367            case sstdescribeDatabase:
368            case sstdescribeTable:
369            case sstdescribeFunction: {
370                ret = new TDescribeStmt(this.vendor);
371                ret.sqlstatementtype = gnewsqlstatementtype;
372                break;
373            }
374            case sstExplain: {
375                ret = new TFlinkExplainStmt(this.vendor);
376                break;
377            }
378            case sstUse: {
379                ret = new TUseDatabase(this.vendor);
380                break;
381            }
382            case sstShowColumns:
383            case sstShowCreateTable:
384            case sstShowDatabases:
385            case sstShowFunctions:
386            case sstShowPartitions:
387            case sstShowTables:
388            case sstShowViews: {
389                ret = new TShowStmt(this.vendor);
390                ret.sqlstatementtype = gnewsqlstatementtype;
391                break;
392            }
393            case sstanalyzeTable: {
394                ret = new TAnalyzeStmt(this.vendor);
395                break;
396            }
397            default: {
398                ret = new TUnknownSqlStatement(this.vendor);
399                ret.sqlstatementtype = gnewsqlstatementtype;
400                break;
401            }
402        }
403
404        return ret;
405    }
406}