001package gudusoft.gsqlparser.nodes.dax;
002
003import gudusoft.gsqlparser.*;
004import gudusoft.gsqlparser.nodes.*;
005import gudusoft.gsqlparser.stmt.dax.TDaxStmt;
006
007import java.util.Stack;
008
009/**
010 * Generic class of all DAX functions. If there is no specific class to represent a DAX function,
011 * then use this generic class.
012 *
013 * Most DAX functions share this class. Below function with their dedicated class:
014 *
015 *
016 * {@link gudusoft.gsqlparser.nodes.dax.TDaxAddMissingItems}
017 * {@link gudusoft.gsqlparser.nodes.dax.TDaxDatatable}
018 * {@link gudusoft.gsqlparser.nodes.dax.TDaxGroupBy}
019 * {@link gudusoft.gsqlparser.nodes.dax.TDaxIsOnOrAfter}
020 * {@link gudusoft.gsqlparser.nodes.dax.TDaxReturn}
021 * {@link gudusoft.gsqlparser.nodes.dax.TDaxSubstituteWithIndex}
022 * {@link gudusoft.gsqlparser.nodes.dax.TDaxSummarize}
023 * {@link gudusoft.gsqlparser.nodes.dax.TDaxSummerizeColumns}
024 */
025public class TDaxFunction extends TFunctionCall {
026
027
028    public TTable getReturnTable() {
029        return returnTable;
030    }
031
032
033    private TTable returnTable;
034
035    private TObjectName columnName;
036
037    public TObjectName getColumnName() {
038        return columnName;
039    }
040
041    private TPTNodeList<TDaxOrderByExpr> orderByExprList;
042
043    public TPTNodeList<TDaxOrderByExpr> getOrderByExprList() {
044        return orderByExprList;
045    }
046
047    private TPTNodeList<TDaxNameExpression> nameValues;
048    public TPTNodeList<TDaxNameExpression> getNameValues() {
049        return nameValues;
050    }
051
052    public void setNameValues(TPTNodeList<TDaxNameExpression> nameValues) {
053        this.nameValues = nameValues;
054    }
055
056    public void init(Object arg1,Object arg2){
057        super.init(arg1, arg2);
058        if (getFunctionType() == EFunctionType.builtin_t){
059            if (getFunctionName().toString().equalsIgnoreCase("distinct")){
060                setFunctionType(EFunctionType.distinct_t);
061            }else if(getFunctionName().toString().equalsIgnoreCase("crossjoin")){
062                setFunctionType(EFunctionType.crossjoin_t);
063            }
064
065        }
066    }
067
068    public void init(Object arg1,Object arg2,Object arg3){
069        init(arg1,arg2);
070        switch (getFunctionType()) {
071            case all_t:
072                if (arg3 instanceof TExpression) {
073                    this.tableExpr = (TExpression) arg3;
074                }else if (arg3 instanceof TObjectNameList){
075                    this.columnNameList = (TObjectNameList)arg3;
076                }
077                break;
078            case allnoblankrow_t:
079            case allselected_t:
080                if (arg3 instanceof TExpression) {
081                    this.tableExpr = (TExpression)arg3;
082                }else if (arg3 instanceof TObjectName){
083                    this.columnName = (TObjectName)arg3;
084                }
085                break;
086            case crossfilter_t:
087                this.columnNameList = (TObjectNameList)arg3;
088                break;
089            case relatedtable_t:
090                this.tableName = (TObjectName)arg3;
091                break;
092            case values_t:
093                //this.expr = (TExpression)arg3;
094                TObjectName objectName = (TObjectName)arg3;
095                if (objectName.getDbObjectType() == EDbObjectType.table){
096                    this.tableName = objectName;
097                }else{
098                    this.columnName = objectName;
099                }
100                break;
101            case rollupaddissubtotal_t:
102                this.setArgs((TExpressionList)arg3);
103                break;
104            case rollupgroup_t:
105                this.columnNameList = (TObjectNameList)arg3;
106                break;
107            case row_t:
108                this.nameValues = (TPTNodeList<TDaxNameExpression>) arg3;
109                break;
110            default:
111                break;
112        }
113    }
114
115    public void init(Object arg1,Object arg2,Object arg3,Object arg4){
116        init(arg1,arg2);
117        switch (getFunctionType()){
118            case minx_t:
119            case maxx_t:
120            case sumx_t:
121            case filter_t:
122            case stdevx_s_t:
123            case stdevx_p_t:
124            case varx_p_t:
125            case varx_s_t:
126            case concatenatex_t:
127                this.tableExpr = (TExpression)arg3;
128                this.expr  = (TExpression)arg4;
129                break;
130            case allexcept_t:
131                this.tableExpr = (TExpression)arg3;
132                this.columnNameList = (TObjectNameList)arg4;
133                break;
134            case addcolumns_t:
135            case selectcolumns_t:
136                this.tableExpr = (TExpression)arg3;
137                this.nameValues = (TPTNodeList<TDaxNameExpression>)arg4;
138                break;
139            default:
140                break;
141        }
142    }
143
144    public void init(Object arg1,Object arg2,Object arg3,Object arg4,Object arg5){
145        init(arg1,arg2);
146        switch (getFunctionType()){
147            case sample_t:
148            case topn_t:
149                this.expr = (TExpression)arg3;
150                this.tableExpr = (TExpression)arg4;
151                this.orderByExprList = (TPTNodeList<TDaxOrderByExpr>)arg5;
152                break;
153        }
154    }
155
156
157    public TObjectName getTableName() {
158        return tableName;
159    }
160
161    private TExpression expr;
162
163    public TExpression getExpr() {
164        return expr;
165    }
166
167    public void setColumnNameList(TObjectNameList columnNameList) {
168        this.columnNameList = columnNameList;
169    }
170
171    public void setReturnTable(TTable returnTable) {
172        this.returnTable = returnTable;
173    }
174
175    private TObjectNameList columnNameList;
176
177    public TObjectNameList getColumnNameList() {
178        return columnNameList;
179    }
180
181    private TExpression tableExpr;
182
183    public TExpression getTableExpr() {
184        return tableExpr;
185    }
186
187    private TObjectName tableName;
188    public void setTableName(TObjectName tableName) {
189        this.tableName = tableName;
190    }
191
192    private TTable defaultTable = null;
193
194    public void setDefaultTable(TTable defaultTable) {
195        this.defaultTable = defaultTable;
196    }
197
198    public TTable getDefaultTable() {
199        return defaultTable;
200    }
201
202    public void setTableExpr(TExpression tableExpr) {
203        this.tableExpr = tableExpr;
204    }
205
206    TTable parseTableExpr(TExpression pTableExpr, TCustomSqlStatement psql, ESqlClause plocation,boolean addToDefault){
207        if (pTableExpr.getExpressionType() == EExpressionType.simple_object_name_t) {
208            TTable lcTable = new TTable(pTableExpr.getObjectOperand());
209            psql.addToTables(lcTable);
210            if (addToDefault) this.setDefaultTable(lcTable);
211            return  lcTable;
212        }else {
213            pTableExpr.getFunctionCall().doParse(psql,plocation);
214            if (((TDaxFunction)pTableExpr.getFunctionCall()).getReturnTable() != null)
215                return ((TDaxFunction)pTableExpr.getFunctionCall()).getReturnTable();
216             else
217                return  ((TDaxFunction)pTableExpr.getFunctionCall()).getDefaultTable();
218        }
219    }
220
221    TTable parseTableName(TObjectName pTableName, TCustomSqlStatement psql, ESqlClause plocation){
222            TTable lcTable = new TTable(pTableName);
223            psql.addToTables(lcTable);
224            if (getDefaultTable() == null)
225                this.setDefaultTable(lcTable);
226
227        return lcTable;
228    }
229
230    void parseExpr(TExpression pExpr,TCustomSqlStatement psql, ESqlClause plocation,boolean pReturnTable){
231        switch (pExpr.getExpressionType()){
232            case simple_object_name_t:
233                if (psql.searchDaxVariableInStack(pExpr.getObjectOperand())){
234                    // it's a variable
235                }
236                else if (pExpr.getObjectOperand().getDbObjectType() == EDbObjectType.table){
237                    this.tableName = pExpr.getObjectOperand();
238                    if (pReturnTable) {
239                        this.returnTable = parseTableName(this.tableName, psql, plocation);
240                    }else {
241                        parseTableName(this.tableName, psql, plocation);
242                    }
243                }else{
244                    psql.linkColumnToTable(pExpr.getObjectOperand(),plocation);
245                }
246                break;
247            default:
248                pExpr.doParse(psql,plocation);
249                break;
250        }
251    }
252
253    void parseColumnExpr(TExpression pExpr,TCustomSqlStatement psql, ESqlClause plocation){
254        switch (pExpr.getExpressionType()){
255            case simple_object_name_t:
256                if (pExpr.getObjectOperand().getDbObjectType() == EDbObjectType.column) {
257                    psql.linkColumnToTable(pExpr.getObjectOperand(), plocation);
258                }
259                break;
260            case function_t:
261                pExpr.getFunctionCall().doParse(psql,plocation);
262                break;
263            default:
264                pExpr.doParse(psql,plocation);
265                break;
266        }
267    }
268
269    void parseArgs(TExpressionList pArgs, TCustomSqlStatement psql, ESqlClause plocation, boolean pReturnTable){
270        if (pArgs == null) return;
271        for (int i = 0; i < pArgs.size(); i++) {
272            TExpression expr = pArgs.getExpression(i);
273            parseExpr(expr,psql,plocation,pReturnTable);
274        }
275    }
276    public void doParse(TCustomSqlStatement psql, ESqlClause plocation){
277        TTable lcTable = null;
278        psql.getDaxFunctionStack().push(this);
279
280        switch (getFunctionType()){
281            case builtin_t:
282                parseArgs(getArgs(),psql,plocation,false);
283                break;
284            case calculatetable_t:
285                parseArgs(getArgs(),psql,plocation,true);
286                this.returnTable = getDefaultTable();
287                break;
288            case minx_t:
289            case maxx_t:
290            case sumx_t:
291            case stdevx_s_t:
292            case stdevx_p_t:
293            case varx_p_t:
294            case varx_s_t:
295            case concatenatex_t:
296                parseTableExpr(tableExpr,psql,plocation,true);
297                expr.doParse(psql, plocation);
298                break;
299            case all_t:
300                if (getTableExpr() != null){
301                   returnTable = parseTableExpr(tableExpr,psql,plocation,true);
302                }else{
303                    for(int i=0;i<getColumnNameList().size();i++){
304                        psql.linkColumnToTable(getColumnNameList().getObjectName(i),plocation);
305                    }
306                }
307                break;
308            case allexcept_t:
309                parseTableExpr(tableExpr,psql,plocation,true);
310                for(int i=0;i<getColumnNameList().size();i++){
311                    psql.linkColumnToTable(getColumnNameList().getObjectName(i), plocation);
312                }
313                break;
314            case allnoblankrow_t:
315            case allselected_t:
316                if (getTableExpr() != null) parseTableExpr(tableExpr,psql, plocation,true);
317                if (getColumnName() != null) psql.linkColumnToTable(getColumnName(),plocation);
318                break;
319            case crossfilter_t:
320                for(int i=0;i<getColumnNameList().size();i++){
321                    psql.linkColumnToTable(getColumnNameList().getObjectName(i), plocation);
322                }
323                break;
324            case relatedtable_t:
325                returnTable =  parseTableName(this.tableName, psql,plocation);
326                break;
327            case values_t:
328                if (this.columnName != null){
329                    psql.linkColumnToTable(this.columnName,plocation);
330                    if (this.getDefaultTable() != null) returnTable = this.getDefaultTable();
331                }else if (this.tableName != null){
332                    returnTable = parseTableName(this.tableName, psql,plocation);
333                }
334                //getExpr().doParse(psql,plocation);
335                break;
336            case filter_t:
337                returnTable = parseTableExpr(tableExpr,psql,plocation,true);
338                expr.doParse(psql, plocation);
339                break;
340            case rollupaddissubtotal_t:
341                parseArgs(getArgs(),psql,plocation,false);
342                break;
343            case rollupgroup_t:
344                for(int i=0;i<getColumnNameList().size();i++){
345                    psql.linkColumnToTable(getColumnNameList().getObjectName(i), plocation);
346                }
347                break;
348            case addcolumns_t:
349            case selectcolumns_t:
350                returnTable = parseTableExpr(tableExpr,psql,plocation,true);
351                for(int i=0;i<getNameValues().size();i++){
352                    getReturnTable().getLinkedColumns().addObjectName(getNameValues().getElement(i).getColumnName());
353                    getNameValues().getElement(i).getValueExpr().doParse(psql,plocation);
354                }
355                break;
356            case row_t:
357                for(int i=0;i<getNameValues().size();i++){
358                    psql.linkColumnToTable(getNameValues().getElement(i).getColumnName(), plocation);
359                    getNameValues().getElement(i).getValueExpr().doParse(psql,plocation);
360                }
361                break;
362            case sample_t:
363            case topn_t:
364                returnTable = parseTableExpr(tableExpr,psql,plocation,true);
365                this.expr.doParse(psql,plocation);
366                for(int i=0;i<getOrderByExprList().size();i++){
367                    getOrderByExprList().getElement(i).getOrderByExpr().doParse(psql,plocation);
368                }
369                break;
370            case calculate_t:
371                if (getArgs().size() > 1){
372                    for(int i=1;i<getArgs().size();i++){
373                        getArgs().getExpression(i).doParse(psql,plocation);
374                    }
375                }
376                getArgs().getExpression(0).doParse(psql,plocation);
377                break;
378            case distinct_t:
379                getArgs().getExpression(0).doParse(psql,plocation);
380                if (this.getDefaultTable() != null) this.setReturnTable(this.getReturnTable());
381                break;
382            case crossjoin_t:
383                parseArgs(getArgs(),psql,plocation,false);
384                this.returnTable = new TTable(TObjectName.createObjectName(EDbVendor.dbvdax, EDbObjectType.table,new TSourceToken("crossjoin")));
385                psql.addToTables(this.returnTable);
386                break;
387            default:
388                if (getArgs() != null){
389                    parseArgs(getArgs(),psql,plocation,false);
390                }
391                break;
392        }
393
394        psql.getDaxFunctionStack().pop();
395        if (returnTable != null){
396            if (psql.getDaxFunctionStack().size() > 0){
397                TDaxFunction function = psql.getDaxFunctionStack().peek();
398                function.setDefaultTable(returnTable);
399            }else{
400                ((TDaxStmt)psql).setDefaultTable(returnTable);
401            }
402        }
403
404    }
405
406    public void accept(TParseTreeVisitor v){
407        v.preVisit(this);
408        v.postVisit(this);
409    }
410
411    public void acceptChildren(TParseTreeVisitor v) {
412        v.preVisit(this);
413        v.postVisit(this);
414    }
415
416}