001/* 002// This software is subject to the terms of the Eclipse Public License v1.0 003// Agreement, available at the following URL: 004// http://www.eclipse.org/legal/epl-v10.html. 005// You must accept the terms of that agreement to use this software. 006// 007// Copyright (C) 2001-2005 Julian Hyde 008// Copyright (C) 2005-2011 Pentaho and others 009// All Rights Reserved. 010*/ 011package mondrian.olap; 012 013import mondrian.calc.ParameterSlot; 014import mondrian.calc.TupleIterable; 015 016import java.util.*; 017 018/** 019 * An <code>Evaluator</code> holds the context necessary to evaluate an 020 * expression. 021 * 022 * @author jhyde 023 * @since 27 July, 2001 024 */ 025public interface Evaluator { 026 027 /** 028 * Returns the current cube. 029 */ 030 Cube getCube(); 031 032 /** 033 * Returns the current query. 034 */ 035 Query getQuery(); 036 037 /** 038 * Returns the start time of the current query. 039 */ 040 Date getQueryStartTime(); 041 042 /** 043 * Creates a savepoint encapsulating the current state of the evalutor. 044 * You can restore the evaluator to this state by calling 045 * {@link #restore(int)} with the value returned by this method. 046 * 047 * <p>This method is typically called before evaluating an expression which 048 * is known to corrupt the evaluation context. 049 * 050 * <p>Multiple savepoints may be active at the same time for the same 051 * evaluator. And, it is allowable to restore to the save savepoint more 052 * than once (or not at all). However, when you have rolled back to a 053 * particular savepoint you may not restore to a later savepoint. 054 * 055 * @return Evaluator with each given member overriding the state of the 056 * current Evaluator for its hierarchy 057 */ 058 int savepoint(); 059 060 /** 061 * Creates a new Evaluator with each given member overriding the context of 062 * the current Evaluator for its hierarchy. Other hierarchies retain the 063 * same context as this Evaluator. 064 * 065 * <p>In mondrian-3.3 and later, a more efficient way to save the state of 066 * an evaluator is to call {@link #savepoint} followed by 067 * {@link #restore(int)}. We recommend using those methods. 068 * 069 * @param members Array of members to add to the context 070 * @return Evaluator with each given member overriding the state of the 071 * current Evaluator for its hierarchy 072 * 073 * @deprecated Use {@link #savepoint()} followed by 074 * {@link #setContext(Member[])}; will be removed in mondrian-4 075 */ 076 Evaluator push(Member[] members); 077 078 /** 079 * Creates a new Evaluator with the same context as this evaluator. 080 * 081 * <p>This method is typically called before evaluating an expression which 082 * may corrupt the evaluation context. 083 * 084 * <p>In mondrian-3.3 and later, a more efficient way to save the state of 085 * an evaluator is to call {@link #savepoint} followed by 086 * {@link #restore(int)}. We recommend using those methods most of the time. 087 * 088 * <p>However, it makes sense to use this method in the constructor of an 089 * iterator. It allows the iterator to modify its evaluation context without 090 * affecting the evaluation context of the calling code. This behavior 091 * cannot be achieved using {@code savepoint}. 092 * 093 * @return Evaluator with each given member overriding the state of the 094 * current Evaluator for its hierarchy 095 */ 096 Evaluator push(); 097 098 /** 099 * Creates a new Evaluator with the same context except for one member. 100 * 101 * <p>This method is typically called before evaluating an expression which 102 * may corrupt the evaluation context. 103 * 104 * <p>In mondrian-3.3 and later, a more efficient way to save the state of 105 * an evaluator is to call {@link #savepoint} followed by 106 * {@link #restore(int)}. We recommend using those methods. 107 * 108 * @param member Member to add to the context 109 * @return Evaluator with each given member overriding the state of the 110 * current Evaluator for its hierarchy 111 * 112 * @deprecated Use {@link #savepoint()} followed by 113 * {@link #setContext(Member)}; will be removed in mondrian-4 114 */ 115 Evaluator push(Member member); 116 117 /** 118 * Creates a new evaluator with the same state except nonEmpty property 119 * 120 * <p>In mondrian-3.3 and later, a more efficient way to save the state of 121 * an evaluator is to call {@link #savepoint} followed by 122 * {@link #restore(int)}. We recommend using those methods. 123 * 124 * @deprecated Use {@link #savepoint()} followed by 125 * {@link #setNonEmpty(boolean)}; will be removed in mondrian-4 126 */ 127 Evaluator push(boolean nonEmpty); 128 129 /** 130 * Creates a new evaluator with the same state except nonEmpty 131 * and nativeEnabled properties. 132 * 133 * <p>In mondrian-3.3 and later, a more efficient way to save the state of 134 * an evaluator is to call {@link #savepoint} followed by 135 * {@link #restore(int)}. We recommend using those methods. 136 * 137 * @deprecated Use {@link #savepoint()} followed by 138 * {@link #setNonEmpty(boolean)} and 139 * {@link #setNativeEnabled(boolean)}; will be removed in mondrian-4. 140 */ 141 Evaluator push(boolean nonEmpty, boolean nativeEnabled); 142 143 /** 144 * Restores previous evaluator. 145 * 146 * @param savepoint Savepoint returned by {@link #savepoint()} 147 */ 148 void restore(int savepoint); 149 150 /** 151 * Makes <code>member</code> the current member of its hierarchy. 152 * 153 * @param member New member 154 * 155 * @return Previous member of this hierarchy 156 */ 157 Member setContext(Member member); 158 159 /** 160 * Makes <code>member</code> the current member of its hierarchy. 161 * 162 * <p>If {@code safe}, checks whether this is the first time that 163 * a member of this hierarchy has been changed since {@link #savepoint()} 164 * was called. If so, saves the previous member. If {@code safe} is false, 165 * never saves the previous member. 166 * 167 * <p>Use {@code safe = false} only if you are sure that the context has 168 * been set before. For example, 169 * 170 * <blockquote> 171 * <code>int n = 0;<br/> 172 * for (Member member : members) {<br/> 173 * evaluator.setContext(member, n++ > 0);<br/> 174 * }<br/></code></blockquote> 175 * 176 * @param member New member 177 * @param safe Whether to store the member of this hierarchy that was 178 * current last time that {@link #savepoint()} was called. 179 */ 180 void setContext(Member member, boolean safe); 181 182 /** 183 * Sets the context to a list of members. 184 * 185 * <p>Equivalent to 186 * 187 * <blockquote><code>for (Member member : memberList) {<br/> 188 * setContext(member);<br/> 189 * }<br/></code></blockquote> 190 * 191 * @param memberList List of members 192 */ 193 void setContext(List<Member> memberList); 194 195 /** 196 * Sets the context to a list of members, optionally skipping the check 197 * whether it is necessary to store the previous member of each hierarchy. 198 * 199 * <p>Equivalent to 200 * 201 * <blockquote><code>for (Member member : memberList) {<br/> 202 * setContext(member, safe);<br/> 203 * }<br/></code></blockquote> 204 * 205 * @param memberList List of members 206 * @param safe Whether to store the member of each hierarchy that was 207 * current last time that {@link #savepoint()} was called. 208 */ 209 void setContext(List<Member> memberList, boolean safe); 210 211 /** 212 * Sets the context to an array of members. 213 * 214 * <p>Equivalent to 215 * 216 * <blockquote><code>for (Member member : memberList) {<br/> 217 * setContext(member);<br/> 218 * }<br/></code></blockquote> 219 * 220 * @param members Array of members 221 */ 222 void setContext(Member[] members); 223 224 /** 225 * Sets the context to an array of members, optionally skipping the check 226 * whether it is necessary to store the previous member of each hierarchy. 227 * 228 * <p>Equivalent to 229 * 230 * <blockquote><code>for (Member member : memberList) {<br/> 231 * setContext(member, safe);<br/> 232 * }<br/></code></blockquote> 233 * 234 * @param members Array of members 235 * @param safe Whether to store the member of each hierarchy that was 236 * current last time that {@link #savepoint()} was called. 237 */ 238 void setContext(Member[] members, boolean safe); 239 240 Member getContext(Hierarchy hierarchy); 241 242 /** 243 * Calculates and returns the value of the cell at the current context. 244 */ 245 Object evaluateCurrent(); 246 247 /** 248 * Returns the format string for this cell. This is computed by evaluating 249 * the format expression in the current context, and therefore different 250 * cells may have different format strings. 251 */ 252 public String getFormatString(); 253 254 /** 255 * Formats a value as a string according to the current context's 256 * format. 257 */ 258 String format(Object o); 259 260 /** 261 * Formats a value as a string according to the current context's 262 * format, using a given format string. 263 */ 264 String format(Object o, String formatString); 265 266 /** 267 * Obsolete method. 268 * 269 * @deprecated Will be removed in mondrian-4 270 */ 271 int getDepth(); 272 273 /** 274 * Returns parent evaluator. 275 * 276 * @deprecated Will be removed in mondrian-4 277 */ 278 Evaluator getParent(); 279 280 /** 281 * Returns the connection's locale. 282 */ 283 Locale getConnectionLocale(); 284 285 /** 286 * Retrieves the value of property <code>name</code>. If more than one 287 * member in the current context defines that property, the one with the 288 * highest solve order has precedence. 289 * 290 * <p>If the property is not defined, default value is returned. 291 */ 292 Object getProperty(String name, Object defaultValue); 293 294 /** 295 * Returns a {@link SchemaReader} appropriate for the current 296 * access-control context. 297 */ 298 SchemaReader getSchemaReader(); 299 300 /** 301 * Simple caching of the result of an <code>Exp</code>. The 302 * key for the cache consists of all members of the current 303 * context that <code>exp</code> depends on. Members of 304 * independent hierarchies are not part of the key. 305 * 306 * @see mondrian.calc.Calc#dependsOn(Hierarchy) 307 */ 308 Object getCachedResult(ExpCacheDescriptor key); 309 310 /** 311 * Returns true for an axis that is NON EMPTY. 312 * 313 * <p>May be used by expression 314 * evaluators to optimize their result. For example, a top-level crossjoin 315 * may be optimized by removing all non-empty set elements before 316 * performing the crossjoin. This is possible because of the identity 317 * 318 * <blockquote><code>nonempty(crossjoin(a, b)) == 319 * nonempty(crossjoin(nonempty(a), nonempty(b));</code></blockquote> 320 */ 321 boolean isNonEmpty(); 322 323 /** 324 * Sets whether an expression evaluation should filter out empty cells. 325 * Allows expressions to modify non empty flag to evaluate their children. 326 */ 327 void setNonEmpty(boolean nonEmpty); 328 329 /** 330 * Creates an exception which indicates that an error has occurred during 331 * the runtime evaluation of a function. The caller should then throw that 332 * exception. 333 */ 334 RuntimeException newEvalException(Object context, String s); 335 336 /** 337 * Returns an evaluator for a set. 338 * 339 * @param exp Expression 340 * @param create Whether to create evaluator if not found 341 * @return Evaluator of named set 342 */ 343 SetEvaluator getSetEvaluator(Exp exp, boolean create); 344 345 /** 346 * Returns an evaluator for a named set. 347 * 348 * @param namedSet Named set 349 * @param create Whether to create evaluator if not found 350 * @return Evaluator of named set 351 */ 352 NamedSetEvaluator getNamedSetEvaluator(NamedSet namedSet, boolean create); 353 354 /** 355 * Returns an array of the members which make up the current context. 356 */ 357 Member[] getMembers(); 358 359 /** 360 * Returns an array of the non-All members which make up the current 361 * context. 362 * 363 * <p>Notes:<ul> 364 * <li>The 0th element is a measure, but otherwise the order of the 365 * members is unspecified. 366 * <li>No hierarchy occurs more than once. 367 * <li>In rare circumstances, some of the members may be an 'All' member. 368 * <li>The list may contain calculated members. 369 * </ul> 370 */ 371 Member[] getNonAllMembers(); 372 373 /** 374 * Returns the number of times that this evaluator has told a lie when 375 * retrieving cell values. 376 */ 377 int getMissCount(); 378 379 /** 380 * Returns the value of a parameter, evaluating its default value if it is 381 * not set. 382 */ 383 Object getParameterValue(ParameterSlot slot); 384 385 /** 386 * @return the iteration length of the current context 387 */ 388 int getIterationLength(); 389 390 /** 391 * Sets the iteration length for the current evaluator context 392 * 393 * @param length length to be set 394 */ 395 void setIterationLength(int length); 396 397 /** 398 * @return true if evaluating axes 399 */ 400 boolean isEvalAxes(); 401 402 /** 403 * Indicate whether the evaluator is evaluating the axes 404 * 405 * @param evalAxes true if evaluating axes 406 */ 407 void setEvalAxes(boolean evalAxes); 408 409 /** 410 * Returns a new Aggregator whose aggregation context adds a given list of 411 * tuples, and whose evaluation context is the same as this 412 * Aggregator. 413 * 414 * @param list List of tuples 415 * @return Aggregator with <code>list</code> added to its aggregation 416 * context 417 */ 418 Evaluator pushAggregation(List<List<Member>> list); 419 420 /** 421 * Returns whether hierarchies unrelated to the measure in the current 422 * context should be ignored. 423 * 424 * @return whether hierarchies unrelated to the measure in the current 425 * context should be ignored 426 */ 427 boolean shouldIgnoreUnrelatedDimensions(); 428 429 /** 430 * Returns the base (non-virtual) cube that the current measure in the 431 * context belongs to. 432 * @return Cube 433 */ 434 Cube getMeasureCube(); 435 436 /** 437 * Returns whether it is necessary to check whether to return null for 438 * an unrelated dimension. If false, we never need to check: we can assume 439 * that {@link #needToReturnNullForUnrelatedDimension(mondrian.olap.Member[])} 440 * will always return false. 441 * 442 * @return whether it is necessary to check whether to return null for 443 * an unrelated dimension 444 */ 445 boolean mightReturnNullForUnrelatedDimension(); 446 447 /** 448 * If IgnoreMeasureForNonJoiningDimension is set to true and one or more 449 * members are on unrelated dimension for the measure in current context 450 * then returns true. 451 * 452 * <p>You must not call this method unless 453 * {@link #mightReturnNullForUnrelatedDimension()} has returned true. 454 * 455 * @param members Dimensions for the members need to be checked whether 456 * related or unrelated 457 * 458 * @return boolean 459 */ 460 boolean needToReturnNullForUnrelatedDimension(Member[] members); 461 462 /** 463 * Returns whether native evaluation is enabled in this context. 464 * 465 * @return whether native evaluation is enabled in this context 466 */ 467 boolean nativeEnabled(); 468 469 /** 470 * Sets whether native evaluation should be used. 471 * 472 * @param nativeEnabled Whether native evaluation should be used 473 */ 474 void setNativeEnabled(boolean nativeEnabled); 475 476 /** 477 * Returns whether the current context is an empty cell. 478 * 479 * @return Whether the current context is an empty cell 480 */ 481 boolean currentIsEmpty(); 482 483 /** 484 * Returns the member that was the current evaluation context for a 485 * particular hierarchy before the most recent change in context. 486 * 487 * @param hierarchy Hierarchy 488 * @return Previous context member for given hierarchy 489 */ 490 Member getPreviousContext(Hierarchy hierarchy); 491 492 /** 493 * Returns the query timing context for this execution. 494 * 495 * @return query timing context 496 */ 497 QueryTiming getTiming(); 498 499 /** 500 * Interface for evaluating a particular named set. 501 */ 502 interface NamedSetEvaluator { 503 /** 504 * Returns an iterator over the tuples of the named set. Applicable if 505 * the named set is a set of tuples. 506 * 507 * <p>The iterator from this iterable maintains the current ordinal 508 * property required for the methods {@link #currentOrdinal()} and 509 * {@link #currentTuple()}. 510 * 511 * @param eval Evaluator for current context 512 * 513 * @return Iterable over the tuples of the set 514 */ 515 TupleIterable evaluateTupleIterable(Evaluator eval); 516 517 /** 518 * Returns the ordinal of the current member or tuple in the named set. 519 * 520 * @return Ordinal of the current member or tuple in the named set 521 */ 522 int currentOrdinal(); 523 524 /** 525 * Returns the current member in the named set. 526 * 527 * <p>Applicable if the named set is a set of members. 528 * 529 * @return Current member 530 */ 531 Member currentMember(); 532 533 /** 534 * Returns the current tuple in the named set. 535 * 536 * <p>Applicable if the named set is a set of tuples. 537 * 538 * @return Current tuple. 539 */ 540 Member[] currentTuple(); 541 } 542 543 /** 544 * Interface for generically evaluating a set. 545 */ 546 interface SetEvaluator { 547 /** 548 * Returns an iterator over the tuples of the named set. Applicable if 549 * the named set is a set of tuples. 550 * 551 * <p>The iterator from this iterable maintains the current ordinal 552 * property required for the methods {@link #currentOrdinal()} and 553 * {@link #currentTuple()}. 554 * 555 * @return Iterable over the tuples of the set 556 */ 557 TupleIterable evaluateTupleIterable(); 558 559 /** 560 * Returns the ordinal of the current member or tuple in the named set. 561 * 562 * @return Ordinal of the current member or tuple in the named set 563 */ 564 int currentOrdinal(); 565 566 /** 567 * Returns the current member in the named set. 568 * 569 * <p>Applicable if the named set is a set of members. 570 * 571 * @return Current member 572 */ 573 Member currentMember(); 574 575 /** 576 * Returns the current tuple in the named set. 577 * 578 * <p>Applicable if the named set is a set of tuples. 579 * 580 * @return Current tuple. 581 */ 582 Member[] currentTuple(); 583 } 584} 585 586// End Evaluator.java