001package gudusoft.gsqlparser.sqlcmds;
002
003import gudusoft.gsqlparser.*;
004import gudusoft.gsqlparser.stmt.*;
005import gudusoft.gsqlparser.stmt.mdx.*;
006
007/**
008 * MDX SQL command resolver.
009 * Contains all MDX-specific SQL command recognition logic.
010 *
011 * @since 3.1.0.9
012 */
013public class TSqlCmdsMdx extends AbstractSqlCmds {
014
015    // Temporary field for statement type during issql processing
016    private ESqlStatementType gnewsqlstatementtype = ESqlStatementType.sstinvalid;
017
018    public TSqlCmdsMdx() {
019        super(EDbVendor.dbvmdx);
020    }
021
022    @Override
023    protected String getToken1Str(int token1) {
024        // MDX currently has no vendor-specific reserved words requiring token1Str
025        return null;
026    }
027
028    @Override
029    protected void initializeCommands() {
030        // MDX commands must be sorted alphabetically by token1
031        // Longer patterns must come before shorter patterns with same prefix
032        addCmd(TBaseType.rrw_alter, "cube", ESqlStatementType.sstmdxaltercube);
033        addCmd(TBaseType.rrw_alter, "dimension", ESqlStatementType.sstmdxalterdimension);
034        addCmd(TBaseType.rrw_calculate, ESqlStatementType.sstmdxcalculate);
035        addCmd(TBaseType.rrw_call, ESqlStatementType.sstmdxcall);
036        addCmd(TBaseType.rrw_case, ESqlStatementType.sstmdxcase);
037        addCmd(TBaseType.rrw_clear, "calculations", ESqlStatementType.sstmdxclearcalculations);
038        addCmd(TBaseType.rrw_create, "action", ESqlStatementType.sstmdxcreateaction);
039        addCmd(TBaseType.rrw_create, "calculated", "member", ESqlStatementType.sstmdxcreatemember);
040        addCmd(TBaseType.rrw_create, "cell", "calculation", ESqlStatementType.sstmdxcreatecellcalculation);
041        addCmd(TBaseType.rrw_create, "dimension", "member", ESqlStatementType.sstmdxcreatedimensionmember);
042        addCmd(TBaseType.rrw_create, "global", "cube", ESqlStatementType.sstmdxcreateglobalcube);
043        addCmd(TBaseType.rrw_create, "hidden", "set", ESqlStatementType.sstmdxcreateset);
044        addCmd(TBaseType.rrw_create, "measure", ESqlStatementType.sstmdxcreatemeasure);
045        addCmd(TBaseType.rrw_create, "member", ESqlStatementType.sstmdxcreatemember);
046        addCmd(TBaseType.rrw_create, "session", "calculated", "memeber", ESqlStatementType.sstmdxcreatemember);
047        addCmd(TBaseType.rrw_create, "session", "cube", ESqlStatementType.sstmdxcreatesessioncube);
048        addCmd(TBaseType.rrw_create, "session", "dimension", "member", ESqlStatementType.sstmdxcreatedimensionmember);
049        addCmd(TBaseType.rrw_create, "session", "hidden", "set", ESqlStatementType.sstmdxcreateset);
050        addCmd(TBaseType.rrw_create, "session", "memeber", ESqlStatementType.sstmdxcreatemember);
051        addCmd(TBaseType.rrw_create, "session", "set", ESqlStatementType.sstmdxcreateset);
052        addCmd(TBaseType.rrw_create, "set", ESqlStatementType.sstmdxcreateset);
053        addCmd(TBaseType.rrw_create, "subcube", ESqlStatementType.sstmdxcreatesubcube);
054        addCmd(TBaseType.rrw_drillthrough, ESqlStatementType.sstmdxdrillthrough);
055        addCmd(TBaseType.rrw_drop, "action", ESqlStatementType.sstmdxdropaction);
056        addCmd(TBaseType.rrw_drop, "calculated", "member", ESqlStatementType.sstmdxdropmember);
057        addCmd(TBaseType.rrw_drop, "cell", "calcution", ESqlStatementType.sstmdxdropcellcalculation);
058        addCmd(TBaseType.rrw_drop, "dimension", "member", ESqlStatementType.sstmdxdropdimensionmember);
059        addCmd(TBaseType.rrw_drop, "member", ESqlStatementType.sstmdxdropmember);
060        addCmd(TBaseType.rrw_drop, "session", "calculated", "member", ESqlStatementType.sstmdxdropmember);
061        addCmd(TBaseType.rrw_drop, "session", "cell", "calcution", ESqlStatementType.sstmdxdropcellcalculation);
062        addCmd(TBaseType.rrw_drop, "session", "member", ESqlStatementType.sstmdxdropmember);
063        addCmd(TBaseType.rrw_drop, "set", ESqlStatementType.sstmdxdropset);
064        addCmd(TBaseType.rrw_drop, "subcube", ESqlStatementType.sstmdxdropsubcube);
065        addCmd(TBaseType.rrw_existing, ESqlStatementType.sstmdxexisting);
066        addCmd(TBaseType.rrw_freeze, ESqlStatementType.sstmdxfreeze);
067        addCmd(TBaseType.rrw_if, ESqlStatementType.sstmdxif);
068        addCmd(TBaseType.rrw_refresh, "cube", ESqlStatementType.sstmdxrefreshcube);
069        addCmd(TBaseType.rrw_scope, ESqlStatementType.sstmdxscope);
070        addCmd(TBaseType.rrw_select, ESqlStatementType.sstmdxselect);
071        addCmd(TBaseType.rrw_update, ESqlStatementType.sstmdxupdate);
072    }
073
074    @Override
075    public TCustomSqlStatement issql(TSourceToken token, EFindSqlStateType state,
076                                      TCustomSqlStatement currentStatement) {
077        TCustomSqlStatement ret = null;
078        gnewsqlstatementtype = ESqlStatementType.sstinvalid;
079
080        // Skip comments, whitespace, semicolons
081        if ((token.tokencode == TBaseType.cmtdoublehyphen)
082                || (token.tokencode == TBaseType.cmtslashstar)
083                || (token.tokencode == TBaseType.lexspace)
084                || (token.tokencode == TBaseType.lexnewline)
085                || (token.tokentype == ETokenType.ttsemicolon)) {
086            return null;
087        }
088
089        int lcpos = token.posinlist;
090        TSourceTokenList lcsourcetokenlist = token.container;
091        TCustomSqlStatement lccurrentsqlstatement = currentStatement;
092
093        // WITH clause before statement (MDX-specific handling)
094        if ((state == EFindSqlStateType.stnormal) && (token.tokencode == TBaseType.rrw_with)) {
095            ret = findMdxStmtBeginWithClause(token, this.vendor);
096            if (ret != null) return ret;
097        }
098
099        // Find command using initialized command list
100        gnewsqlstatementtype = getStatementTypeForToken(token);
101
102        TSourceToken lcprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcpos);
103        switch (gnewsqlstatementtype) {
104            case sstinvalid: {
105                ret = null;
106                if (state == EFindSqlStateType.stnormal) {
107                    // Treat all unrecognized statements as an expression
108                    ret = new TMdxExpression(this.vendor);
109                }
110                break;
111            }
112            case sstmdxselect: {
113                boolean lcisnewsql = true;
114
115                if (state != EFindSqlStateType.stnormal) {
116                    if (lccurrentsqlstatement.sqlstatementtype == ESqlStatementType.sstselect) {
117                        if (lccurrentsqlstatement.isctequery)
118                            lcisnewsql = false;
119                    }
120                }
121
122                if (lcisnewsql)
123                    ret = new TMdxSelect(this.vendor);
124
125                break;
126            }
127            case sstmdxupdate: {
128                boolean lcisnewsql = true;
129                if (state != EFindSqlStateType.stnormal) {
130                    lcprevsolidtoken = lcsourcetokenlist.solidtokenbefore(lcpos);
131                    if ((lcprevsolidtoken != null)) {
132                        //
133                    }
134
135                    TSourceToken lcnextsolidtoken = lcsourcetokenlist.nextsolidtoken(lcpos, 1, false);
136                    if ((lcnextsolidtoken != null)) {
137                    }
138
139                    if ((lccurrentsqlstatement != null)) {
140                    }
141                }
142
143                if (lcisnewsql) {
144                    ret = new TMdxUpdate(this.vendor);
145                }
146                break;
147            }
148            case sstmdxaltercube: {
149                ret = new TMdxAlterCube(this.vendor);
150                break;
151            }
152            case sstmdxcalculate: {
153                ret = new TMdxCalculate(this.vendor);
154                break;
155            }
156            case sstmdxcall: {
157                ret = new TMdxCall(this.vendor);
158                break;
159            }
160            case sstmdxcase: {
161                ret = new TMdxCase(this.vendor);
162                break;
163            }
164            case sstmdxclearcalculations: {
165                ret = new TMdxClearCalculations(this.vendor);
166                break;
167            }
168            case sstmdxcreateaction: {
169                ret = new TMdxCreateAction(this.vendor);
170                break;
171            }
172            case sstmdxcreatemember: {
173                ret = new TMdxCreateMember(this.vendor);
174                break;
175            }
176            case sstmdxcreatecellcalculation: {
177                ret = new TMdxCreateCellCalculation(this.vendor);
178                break;
179            }
180            case sstmdxcreateglobalcube: {
181                ret = new TMdxCreateGlobalCube(this.vendor);
182                break;
183            }
184            case sstmdxcreateset: {
185                ret = new TMdxCreateSet(this.vendor);
186                break;
187            }
188            case sstmdxcreatesessioncube: {
189                ret = new TMdxCreateSessionCube(this.vendor);
190                break;
191            }
192            case sstmdxcreatesubcube: {
193                ret = new TMdxCreateSubCube(this.vendor);
194                break;
195            }
196            case sstmdxdrillthrough: {
197                ret = new TMdxDrillthrough(this.vendor);
198                break;
199            }
200            case sstmdxdropaction: {
201                ret = new TMdxDropAction(this.vendor);
202                break;
203            }
204            case sstmdxdropmember: {
205                ret = new TMdxDropMember(this.vendor);
206                break;
207            }
208            case sstmdxdropcellcalculation: {
209                ret = new TMdxDropCellCalculation(this.vendor);
210                break;
211            }
212            case sstmdxdropset: {
213                ret = new TMdxDropSet(this.vendor);
214                break;
215            }
216            case sstmdxdropsubcube: {
217                ret = new TMdxDropSubcube(this.vendor);
218                break;
219            }
220            case sstmdxfreeze: {
221                ret = new TMdxFreeze(this.vendor);
222                break;
223            }
224            case sstmdxif: {
225                ret = new TMdxIf(this.vendor);
226                break;
227            }
228            case sstmdxrefreshcube: {
229                ret = new TMdxRefreshCube(this.vendor);
230                break;
231            }
232            case sstmdxscope: {
233                ret = new TMdxScope(this.vendor);
234                break;
235            }
236            case sstmdxcreatemeasure: {
237                ret = new TMdxCreateMeasure(this.vendor);
238                break;
239            }
240            case sstmdxexisting:
241            default: {
242                ret = new TUnknownSqlStatement(this.vendor);
243                ret.sqlstatementtype = gnewsqlstatementtype;
244                break;
245            }
246        }
247
248        return ret;
249    }
250
251    /**
252     * Handle MDX statements that begin with WITH clause.
253     * MDX WITH clause creates a CTE-like SELECT statement.
254     */
255    private TCustomSqlStatement findMdxStmtBeginWithClause(TSourceToken ptoken, EDbVendor pdbvendor) {
256        TCustomSqlStatement ret = null;
257        ret = new TMdxSelect(pdbvendor);
258        ret.isctequery = true;
259        gnewsqlstatementtype = ESqlStatementType.sstmdxselect;
260        return ret;
261    }
262}