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}