mondrian.test
Class BasicQueryTest

java.lang.Object
  extended by junit.framework.Assert
      extended by junit.framework.TestCase
          extended by mondrian.test.FoodMartTestCase
              extended by mondrian.test.BasicQueryTest
All Implemented Interfaces:
junit.framework.Test
Direct Known Subclasses:
SegmentCacheTest

public class BasicQueryTest
extends FoodMartTestCase

BasicQueryTest is a test case which tests simple queries against the FoodMart database.

Since:
Feb 14, 2003
Author:
jhyde

Nested Class Summary
static class BasicQueryTest.CountConcurrentUdf
           
static class BasicQueryTest.MyJdbcStatisticsProvider
          Dummy statistics provider for testStatistics().
static class BasicQueryTest.SleepUdf
          A simple user-defined function which adds one to its argument, but sleeps 1 ms before doing so.
 
Nested classes/interfaces inherited from class mondrian.test.FoodMartTestCase
FoodMartTestCase.QueryAndResult
 
Field Summary
(package private) static String EmptyResult
           
 
Fields inherited from class mondrian.test.FoodMartTestCase
propSaver
 
Constructor Summary
BasicQueryTest()
           
BasicQueryTest(String name)
           
 
Method Summary
 void _badArgsToTupleFails()
           
 void _testBug793616()
          Bug 793616: Deeply nested UNION function takes forever to validate.
 void _testCubeWhichUsesSameSharedDimTwice()
          This test modifies the Sales cube to contain both the regular usage of the [Store] shared dimension, and another usage called [Other Store] which is connected to the [Unit Sales] column
 void _testCumlativeSums()
          How Can I Show Cumulative Sums as Measures?
 void _testDairy()
           
 void _testDateRange()
          How Can I Use Date Ranges in MDX?
 void _testDc4dtp2()
          Other techniques, such as the addition of member properties to the Time or Product dimensions to support such calculations, are not as flexible but are much more efficient.
 void _testDifferentCalculationsForDifferentDimensions()
          How Can I Use Different Calculations for Different Dimensions?
 void _testDifferentCalculationsForDifferentDimensions2()
          The second case is easier to resolve, because MDX provides the OpeningPeriod and ClosingPeriod MDX functions specifically to support opening and closing period values.
 void _testDrillingDownMoreThanOneLevel()
          How Can I Drill Down More Than One Level Deep, or Skip Levels When Drilling Down?
 void _testEver()
           
 void _testHalfYearsTrickyCase()
           
 void _testLookupCube()
          Basically, the LookupCube function can evaluate a single MDX statement against a cube other than the cube currently indicated by query context to retrieve a single string or numeric result.
 void _testMemberPropertyAsCalcMember()
          The drawback to using the DIMENSION PROPERTIES statement is that, for most client applications, the member property is not readily apparent.
 void _testMembersFunction()
           
 void _testProduct2()
           
 void _testRolling()
          How Can I Use Rolling Date Ranges in MDX?
 void _testSet()
          The WHERE clause in the previous MDX query effectively provides a logical AND operator, in which all unit sales for 1997 are returned only for drink products and only for those sold in stores in the USA.
 void _testSetArgToTupleFails()
           
 void _testTopmost()
          How Do I Get the Topmost Members of a Level Broken Out by an Ancestor Level?
 void _testWarehouseProfit()
           
 void _testYtdGrowth()
          How Can I Compare Time Periods in MDX?
 void dont_testParallelFlushCache()
           
 void dont_testParallelMutliple()
           
 void dont_testParallelNot()
           
 void dont_testParallelSomewhat()
           
 void dont_testParallelVery()
           
 void testAllLevelName()
           
 void testAllMemberCaption()
           
 void testAsSample7ButUsingVirtualCube()
           
 void testAvgCastProblem()
          This tests a fix for bug #1603653
 void testBadComments()
           
 void testBadMeasure1()
           
 void testBadMeasure2()
           
 void testBasketAnalysis()
          Basket analysis is a topic better suited to data mining discussions, but some basic forms of basket analysis can be handled through the use of MDX queries.
 void testBasketAnalysisAfterFlush()
          Flushes the cache then runs testBasketAnalysis(), because this test has been known to fail when run standalone.
 void testBigQuery()
          Requires the use of a sparse segment, because the product dimension has 6 atttributes, the product of whose cardinalities is ~8M.
 void testBothAxesEmpty()
          Tests that a query whose axes are empty works; bug MONDRIAN-52.
 void testBug1630754()
          Tests for bug #1630754.
 void testBug636687()
          The bug happened when a cell which was in cache was compared with a cell which was not in cache.
 void testBug769114()
          Bug 769114: Internal error ("not found") when executing Order(TopCount).
 void testBugMondrian14()
          If a measure (in this case, [Measures].[Sales Count]) occurs only within a format expression, bug MONDRIAN-14.
 void testBugMondrian34()
          This bug causes all of the format strings to be the same, because the required expression [Measures].[Unit Sales] is not in the cache; bug MONDRIAN-34.
 void testBugMondrian36()
          Tuple as slicer causes ClassCastException; bug MONDRIAN-36.
 void testBugMondrian46()
          Query with distinct-count measure and no other measures gives ArrayIndexOutOfBoundsException; MONDRIAN-46.
 void testBugMondrian8()
          Test case for MONDRIAN-8, "Problem getting children in hierarchy based on join.".
 void testCalculatedMemberWhichIsNotAMeasure()
           
 void testCancel()
           
 void testCatalogHierarchyBasedOnView()
           
 void testCatalogHierarchyBasedOnView2()
          Run a query against a large hierarchy, to make sure that we can generate joins correctly.
 void testCellValue()
           
 void testCompoundSlicer()
          Used to test that a slicer with multiple values gives an error; bug MONDRIAN-96.
 void testCompoundSlicerNonEmpty()
          Test case for MONDRIAN-814, "MDX with specific where clause doesn't work" .
 void testConcurrentStatementRun_2()
          This is a test for MONDRIAN-1161.
 void testConcurrentStatementRun()
          This is a test for MONDRIAN-1014.
 void testConstantNumber()
           
 void testConstantString()
           
 void testCountDistinct()
           
 void testCountDistinctAgg()
          Turn off aggregate caching and run query with both use of aggregate tables on and off - should result in the same answer.
 void testCrossjoinWithDescendantsAndUnknownMember()
          Test case for MONDRIAN-977, "NPE in Query with Crossjoin Descendants of Unknown Member".
 void testCustomMemberProperties()
          How Can I Use Custom Member Properties in MDX?
 void testCycle()
          Disabled test.
 void testCyclicalCalculatedMembers()
           
 void testDefaultMeasureInCube()
           
 void testDefaultMeasureInCubeForCaseSensitivity()
           
 void testDefaultMeasureInCubeForIncorrectMeasureName()
           
 void testDependsOn()
          Makes sure that the expression [Measures].[Unit Sales] / ([Measures].[Unit Sales], [Product].[All Products]) depends on the current member of the Product dimension, although [Product].[All Products] is referenced from the expression.
 void testDifferentCalcsForDifferentTimePeriods()
          How Can I Use Different Calculations for Different Time Periods?
 void testDifferentCalculations2()
          This calculated measure is more powerful than it seems; if, for example, you then want to see the average number of units ordered for beer products in all of the stores in the California area, the following MDX query can be executed with the same calculated measure.
 void testDifferentCalculationsForDifferentLevels()
          How Can I Use Different Calculations for Different Levels in a Dimension?
 void testDimWithoutAll()
          Bug 1250080 caused a dimension with no 'all' member to be constrained twice.
 void testDirectMemberReferenceOnDimensionWithCalculationsDefined()
           
 void testDuplicateAxisFails()
           
 void testDynamicFormat()
           
 void testEmptyAggregationListDueToFilterDoesNotThrowException()
           
 void testEmptyProperty()
          the following query raised a classcast exception because an empty property evaluated as "NullMember" note: Store "HQ" does not have a "Store Manager"
 void testEmptySqlBug()
          Testcase for Pentaho bug BISERVER-1323, empty SQL query generated when crossjoining more than two sets each containing just the 'all' member.
 void testEmptyTupleSlicerFails()
           
 void testExplain()
           
 void testExplainComplex()
           
 void testExplainInvalid()
           
 void testFilteredCrossJoin()
          This resulted in OutOfMemoryError when the BatchingCellReader did not know the values for the tuples that were used in filters.
 void testFilterWithCrossJoin()
          Testcase for bug 1755778, "CrossJoin / Filter query returns null row in result set"
 void testFormatInheritance()
           
 void testFormatInheritanceUseFirstValid()
          Tests format inheritance with complex expression to assert that the format of the first member that has a valid format is used.
 void testFormatInheritanceUseSecondIfFirstHasNoFormat()
          Test format inheritance to pickup format from second measure when the first does not have one.
 void testFormatInheritanceWithIIF()
           
 void testFormatInheritanceWorksWithFirstFormatItFinds()
          For a calulated member picks up the format of first member that has a format.
 void testFormatOfNil()
          Test case for bug MONDRIAN-434, "Small negative numbers cause exceptions w 2-section format".
 void testFormatOfNulls()
           
 void testFormatStringAppliedToStringValue()
          Test format string values.
 void testGetCaptionUsingMemberDotCaption()
           
 void testGetCaptionUsingMemberDotPropertiesCaption()
           
 void testGetContext()
          Unit test for the Cell.getContextMember(mondrian.olap.Hierarchy) method.
 void testGoodComments()
           
 void testHalfYears()
           
 void testHeterogeneousAxis()
          Tests bug MONDRIAN-7, "Heterogeneous axis gives wrong results".
 void testHierarchiesOfSameDimensionOnDifferentAxes()
          Tests hierarchies of the same dimension on different axes.
 void testHierDifferentKeyClass()
          description of this testcase: A calculated member is created on the time.month level.
 void testHighCardSqlTupleReaderLeakingConnections()
          This unit test would cause connection leaks without a fix for bug MONDRIAN-571, "HighCardSqlTupleReader does not close SQL Connections".
 void testIifWithMemberFirstAndTupleNextWithMeasure()
           
 void testIifWithMemberFirstAndTupleNextWithoutMeasure()
           
 void testIifWithTupleFirstAndMemberNextWithMeasure()
           
 void testIifWithTupleFirstAndMemberNextWithoutMeasure()
           
 void testIifWithTuplesOfUnequalSizes()
           
 void testIifWithTuplesOfUnequalSizesAndOrder()
           
 void testInvalidAxisFails()
           
 void testInvalidMembersInQuery()
           
 void testLogicalAnd()
          A logical AND, by contrast, can be supported by using two different techniques.
 void testLogicalOps()
          How Can I Implement a Logical AND or OR Condition in a WHERE Clause?
 void testMemberOnAxis()
          If an axis expression is a member, implicitly convert it to a set.
 void testMemberOrdinalCaching()
           
 void testMembersOfLargeDimensionTheHardWay()
           
 void testMemberVisibility()
           
 void testMemberWithNullKey()
          There are cross database order issues in this test.
 void testMid()
          Test case for MONDRIAN-539, "Problem with the MID function getting last character in a string.".
 void testMultipleCalculatedMembersWhichAreNotMeasures()
           
 void testMultipleCalculatedMembersWhichAreNotMeasures2()
          Testcase for bug MONDRIAN-77, "Calculated member name conflict".
 void testMultipleCalculatedMembersWhichAreNotMeasures3()
          This one had the same problem.
 void testMultipleConstraintsOnSameColumn()
          Tests whether the agg mgr behaves correctly if a cell request causes a column to be constrained multiple times.
 void testNonEmpty1()
           
 void testNonEmpty2()
           
 void testNonEmptyCrossJoin()
          Tests a query with a CrossJoin so large that we run out of memory unless we can push down evaluation to SQL.
 void testNonEmptyCrossjoinFilter()
          Tests a query which uses filter and crossjoin.
 void testNonEmptyNonEmptyCrossJoin1()
          NonEmptyCrossJoin() is not the same as NON EMPTY CrossJoin() because it's evaluated independently of the other axes.
 void testNonEmptyNonEmptyCrossJoin2()
           
 void testNonEmptyNonEmptyCrossJoin3()
           
 void testNonEmptyNonEmptyCrossJoin4()
           
 void testNullMember()
           
 void testNullMemberWithOneNonNull()
           
 void testNumericToLogicalConversion()
          This tests for bug #1706434, the ability to convert numeric types to logical (boolean) types.
 void testOneDimensionalQueryWithTupleAsSlicer()
           
 void testOverlappingCalculatedMembers()
          Bug #1005995 - many totals of various dimensions
 void testOverrideDimension()
           
 void testPercentagesAsMeasures()
          How Can I Show Percentages as Measures?
 void testQueryIterationLimit()
           
 void testQueryTimeout()
           
 void testRank()
          How Can I Rank or Reorder Members?
 void testResultLimit()
           
 void testRollup()
           
 void testRollupQuery()
           
 void testSameDimOnTwoAxesFails()
          It is illegal for a query to have the same dimension on more than one axis.
 void testSample0()
           
 void testSample1()
           
 void testSample2()
           
 void testSample3()
           
 void testSample4()
           
 void testSample5()
           
 void testSample5Snowflake()
           
 void testSample6()
           
 void testSample7()
           
 void testSample8()
           
 void testScalarOnAxisFails()
           
 void testSchemaLevelOrdinalInOtherTable()
           
 void testSchemaLevelTableInAnotherHierarchy()
           
 void testSchemaLevelTableIsBad()
           
 void testSchemaLevelWithViewSpecifiesTable()
           
 void testSchemaTopLevelNotUnique()
           
 void testSlicerIsEvaluatedBeforeAxes()
           
 void testSlicerOverride()
          Slicer contains [Promotion Media].[Daily Paper], but filter expression is in terms of [Promotion Media].[Radio].
 void testSlicerWithCalculatedMembers()
           
 void testSolveOrder()
           
 void testSolveOrderAmbiguous1()
          Test what happens when the solve orders are the same.
 void testSolveOrderAmbiguous2()
          In the second test, the answer should be 2 because Product comes before Promotions in the FoodMart.xml schema.
 void testSolveOrderNonMeasure()
           
 void testSolveOrderNonMeasure2()
           
 void testStatistics()
          Unit test for StatisticsProvider and implementations JdbcStatisticsProvider and SqlStatisticsProvider.
 void testStoreCube()
          Tests that the "Store" cube is working.
 void testStringComparisons()
          How Can I Perform Complex String Comparisons?
 void testSummingProperties()
          Tests various ways to sum the properties of the descendants of a member, inspired by forum post summing properties.
 void testTaglib0()
           
 void testTaglib1()
           
 void testTaglib2()
           
 void testTaglib3()
           
 void testTaglib4()
           
 void testTaglib5()
           
 void testTopmost2()
          The MDX Descendants function is used to construct a set consisting of only those members at the Store Name level in the Store dimension.
 void testUnparse()
           
 void testUnparse2()
           
 void testUseDimensionAsShorthandForMember()
           
 void testVirtualCube()
           
 void testZeroValuesAreNotTreatedAsNull()
           
 
Methods inherited from class mondrian.test.FoodMartTestCase
allMember, assertAxisReturns, assertAxisThrows, assertBooleanExprReturns, assertExprReturns, assertExprThrows, assertQueriesReturnSimilarResults, assertQueryReturns, assertQueryThrows, assertSize, cubeByName, execute, executeExpr, executeQuery, executeSingletonAxis, genderMembersIncludingAll, getConnection, getDimensionWithName, getTestContext, isDefaultNullMemberRepresentation, isGroupingSetsSupported, member, productMembersPotScrubbersPotsAndPans, storeMembersCAAndOR, storeMembersUsaAndCanada, tearDown, warehouseMembersCanadaMexicoUsa
 
Methods inherited from class junit.framework.TestCase
countTestCases, createResult, getName, run, run, runBare, runTest, setName, setUp, toString
 
Methods inherited from class junit.framework.Assert
assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertFalse, assertFalse, assertNotNull, assertNotNull, assertNotSame, assertNotSame, assertNull, assertNull, assertSame, assertSame, assertTrue, assertTrue, fail, fail
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

EmptyResult

static final String EmptyResult
See Also:
Constant Field Values
Constructor Detail

BasicQueryTest

public BasicQueryTest()

BasicQueryTest

public BasicQueryTest(String name)
Method Detail

testSample0

public void testSample0()

testSample1

public void testSample1()

testSample2

public void testSample2()

testSample3

public void testSample3()

testSample4

public void testSample4()

testSample5

public void testSample5()

testSample5Snowflake

public void testSample5Snowflake()

testSample6

public void testSample6()

testSample7

public void testSample7()

testSample8

public void testSample8()

testGoodComments

public void testGoodComments()

testBadComments

public void testBadComments()

testBothAxesEmpty

public void testBothAxesEmpty()
Tests that a query whose axes are empty works; bug MONDRIAN-52.


testCompoundSlicer

public void testCompoundSlicer()
Used to test that a slicer with multiple values gives an error; bug MONDRIAN-96. But now compound slicers are valid.


testCompoundSlicerNonEmpty

public void testCompoundSlicerNonEmpty()
Test case for MONDRIAN-814, "MDX with specific where clause doesn't work" . This test case was as close as I could get to the original test case on the foodmart data set, but it did not reproduce the bug.


testEmptyTupleSlicerFails

public void testEmptyTupleSlicerFails()

testBigQuery

public void testBigQuery()
Requires the use of a sparse segment, because the product dimension has 6 atttributes, the product of whose cardinalities is ~8M. If we use a dense segment, we run out of memory trying to allocate a huge array.


testGetContext

public void testGetContext()
Unit test for the Cell.getContextMember(mondrian.olap.Hierarchy) method.


testNonEmpty1

public void testNonEmpty1()

testNonEmpty2

public void testNonEmpty2()

testOneDimensionalQueryWithTupleAsSlicer

public void testOneDimensionalQueryWithTupleAsSlicer()

testSlicerIsEvaluatedBeforeAxes

public void testSlicerIsEvaluatedBeforeAxes()

testSlicerWithCalculatedMembers

public void testSlicerWithCalculatedMembers()

_testEver

public void _testEver()

_testDairy

public void _testDairy()

testSolveOrder

public void testSolveOrder()

testSolveOrderNonMeasure

public void testSolveOrderNonMeasure()

testSolveOrderNonMeasure2

public void testSolveOrderNonMeasure2()

testSolveOrderAmbiguous1

public void testSolveOrderAmbiguous1()
Test what happens when the solve orders are the same. According to http://msdn.microsoft.com/library/en-us/olapdmad/agmdxadvanced_6jn7.asp if solve orders are the same then the dimension specified first when defining the cube wins.

In the first test, the answer should be 1 because Promotions comes before Customers in the FoodMart.xml schema.


testSolveOrderAmbiguous2

public void testSolveOrderAmbiguous2()
In the second test, the answer should be 2 because Product comes before Promotions in the FoodMart.xml schema.


testCalculatedMemberWhichIsNotAMeasure

public void testCalculatedMemberWhichIsNotAMeasure()

testMultipleCalculatedMembersWhichAreNotMeasures

public void testMultipleCalculatedMembersWhichAreNotMeasures()

testMultipleCalculatedMembersWhichAreNotMeasures2

public void testMultipleCalculatedMembersWhichAreNotMeasures2()
Testcase for bug MONDRIAN-77, "Calculated member name conflict".

There used to be something wrong with non-measure calculated members where the ordering of the WITH MEMBER would determine whether or not the member would be found in the cube. This test would fail but the previous one would work ok.


testMultipleCalculatedMembersWhichAreNotMeasures3

public void testMultipleCalculatedMembersWhichAreNotMeasures3()
This one had the same problem. It wouldn't find the [Store].[x] member because it has the same leaf name as [Product].[x]. (See MONDRIAN-77.)


testConstantString

public void testConstantString()

testConstantNumber

public void testConstantNumber()

testCyclicalCalculatedMembers

public void testCyclicalCalculatedMembers()

testCycle

public void testCycle()
Disabled test. It used throw an 'infinite loop' error (which is what Plato does). But now we revert to the context of the default member when calculating calculated members (we used to stay in the context of the calculated member), and we get a result.


testHalfYears

public void testHalfYears()

_testHalfYearsTrickyCase

public void _testHalfYearsTrickyCase()

testAsSample7ButUsingVirtualCube

public void testAsSample7ButUsingVirtualCube()

testVirtualCube

public void testVirtualCube()

testUseDimensionAsShorthandForMember

public void testUseDimensionAsShorthandForMember()

_testMembersFunction

public void _testMembersFunction()

_testProduct2

public void _testProduct2()

testTaglib0

public void testTaglib0()

testTaglib1

public void testTaglib1()

testTaglib2

public void testTaglib2()

testTaglib3

public void testTaglib3()

testTaglib4

public void testTaglib4()

testTaglib5

public void testTaglib5()

testCellValue

public void testCellValue()

testDynamicFormat

public void testDynamicFormat()

testFormatOfNulls

public void testFormatOfNulls()

testFormatOfNil

public void testFormatOfNil()
Test case for bug MONDRIAN-434, "Small negative numbers cause exceptions w 2-section format".


testBugMondrian14

public void testBugMondrian14()
If a measure (in this case, [Measures].[Sales Count]) occurs only within a format expression, bug MONDRIAN-14. causes an internal error ("value not found") when the cell's formatted value is retrieved.


testBugMondrian34

public void testBugMondrian34()
This bug causes all of the format strings to be the same, because the required expression [Measures].[Unit Sales] is not in the cache; bug MONDRIAN-34.


testBugMondrian36

public void testBugMondrian36()
Tuple as slicer causes ClassCastException; bug MONDRIAN-36.


testBugMondrian46

public void testBugMondrian46()
Query with distinct-count measure and no other measures gives ArrayIndexOutOfBoundsException; MONDRIAN-46.


testStoreCube

public void testStoreCube()
Tests that the "Store" cube is working.

The [Fact Count] measure, which is implicitly created because the cube definition does not include an explicit count measure, is flagged 'not visible' but is still correctly returned from [Measures].Members.


testSchemaLevelTableIsBad

public void testSchemaLevelTableIsBad()

testSchemaLevelTableInAnotherHierarchy

public void testSchemaLevelTableInAnotherHierarchy()

testSchemaLevelWithViewSpecifiesTable

public void testSchemaLevelWithViewSpecifiesTable()

testSchemaLevelOrdinalInOtherTable

public void testSchemaLevelOrdinalInOtherTable()

testSchemaTopLevelNotUnique

public void testSchemaTopLevelNotUnique()

testBugMondrian8

public void testBugMondrian8()
Test case for MONDRIAN-8, "Problem getting children in hierarchy based on join.". It happens when getting the children of a member crosses a table boundary.


testBug636687

public void testBug636687()
The bug happened when a cell which was in cache was compared with a cell which was not in cache. The compare method could not deal with the RuntimeException which indicates that the cell is not in cache.


testBug769114

public void testBug769114()
Bug 769114: Internal error ("not found") when executing Order(TopCount).


_testBug793616

public void _testBug793616()
Bug 793616: Deeply nested UNION function takes forever to validate. (Problem was that each argument of a function was validated twice, hence the validation time was O(2 ^ depth).)


testCatalogHierarchyBasedOnView

public void testCatalogHierarchyBasedOnView()

testCatalogHierarchyBasedOnView2

public void testCatalogHierarchyBasedOnView2()
Run a query against a large hierarchy, to make sure that we can generate joins correctly. This probably won't work in MySQL.


testCountDistinct

public void testCountDistinct()

testCountDistinctAgg

public void testCountDistinctAgg()
Turn off aggregate caching and run query with both use of aggregate tables on and off - should result in the same answer. Note that if the "mondrian.rolap.aggregates.Read" property is not true, then no aggregate tables is be read in any event.


testMemberWithNullKey

public void testMemberWithNullKey()
There are cross database order issues in this test. MySQL and Access show the rows as: [Store Size in SQFT].[All Store Size in SQFTs] [Store Size in SQFT].[null] [Store Size in SQFT].[] Postgres shows: [Store Size in SQFT].[All Store Size in SQFTs] [Store Size in SQFT].[] [Store Size in SQFT].[null] The test failure is due to some inherent differences in the way Postgres orders NULLs in a result set, compared with MySQL and Access. From the MySQL 4.X manual: When doing an ORDER BY, NULL values are presented first if you do ORDER BY ... ASC and last if you do ORDER BY ... DESC. From the Postgres 8.0 manual: The null value sorts higher than any other value. In other words, with ascending sort order, null values sort at the end, and with descending sort order, null values sort at the beginning. Oracle also sorts nulls high by default. So, this test has expected results that vary depending on whether the database is being used sorts nulls high or low.


testCrossjoinWithDescendantsAndUnknownMember

public void testCrossjoinWithDescendantsAndUnknownMember()
Test case for MONDRIAN-977, "NPE in Query with Crossjoin Descendants of Unknown Member".


testSlicerOverride

public void testSlicerOverride()
Slicer contains [Promotion Media].[Daily Paper], but filter expression is in terms of [Promotion Media].[Radio].


testMembersOfLargeDimensionTheHardWay

public void testMembersOfLargeDimensionTheHardWay()

testUnparse

public void testUnparse()

testUnparse2

public void testUnparse2()

_testLookupCube

public void _testLookupCube()
Basically, the LookupCube function can evaluate a single MDX statement against a cube other than the cube currently indicated by query context to retrieve a single string or numeric result.

For example, the Budget cube in the FoodMart 2000 database contains budget information that can be displayed by store. The Sales cube in the FoodMart 2000 database contains sales information that can be displayed by store. Since no virtual cube exists in the FoodMart 2000 database that joins the Sales and Budget cubes together, comparing the two sets of figures would be difficult at best.

Note In many situations a virtual cube can be used to integrate data from multiple cubes, which will often provide a simpler and more efficient solution than the LookupCube function. This example uses the LookupCube function for purposes of illustration.

The following MDX query, however, uses the LookupCube function to retrieve unit sales information for each store from the Sales cube, presenting it side by side with the budget information from the Budget cube.


testBasketAnalysis

public void testBasketAnalysis()

Basket analysis is a topic better suited to data mining discussions, but some basic forms of basket analysis can be handled through the use of MDX queries.

For example, one method of basket analysis groups customers based on qualification. In the following example, a qualified customer is one who has more than $10,000 in store sales or more than 10 unit sales. The following table illustrates such a report, run against the Sales cube in FoodMart 2000 with qualified customers grouped by the Country and State Province levels of the Customers dimension. The count and store sales total of qualified customers is represented by the Qualified Count and Qualified Sales columns, respectively.

To accomplish this basic form of basket analysis, the following MDX query constructs two calculated members. The first calculated member uses the MDX Count, Filter, and Descendants functions to create the Qualified Count column, while the second calculated member uses the MDX Sum, Filter, and Descendants functions to create the Qualified Sales column.

The key to this MDX query is the use of Filter and Descendants together to screen out non-qualified customers. Once screened out, the Sum and Count MDX functions can then be used to provide aggregation data only on qualified customers.


testBasketAnalysisAfterFlush

public void testBasketAnalysisAfterFlush()
Flushes the cache then runs testBasketAnalysis(), because this test has been known to fail when run standalone.


testStringComparisons

public void testStringComparisons()
How Can I Perform Complex String Comparisons?

MDX can handle basic string comparisons, but does not include complex string comparison and manipulation functions, for example, for finding substrings in strings or for supporting case-insensitive string comparisons. However, since MDX can take advantage of external function libraries, this question is easily resolved using string manipulation and comparison functions from the Microsoft Visual Basic for Applications (VBA) external function library.

For example, you want to report the unit sales of all fruit-based products -- not only the sales of fruit, but canned fruit, fruit snacks, fruit juices, and so on. By using the LCase and InStr VBA functions, the following results are easily accomplished in a single MDX query, without complex set construction or explicit member names within the query.

The following MDX query demonstrates how to achieve the results displayed in the previous table. For each member in the Product dimension, the name of the member is converted to lowercase using the LCase VBA function. Then, the InStr VBA function is used to discover whether or not the name contains the word "fruit". This information is used to then construct a set, using the Filter MDX function, from only those members from the Product dimension that contain the substring "fruit" in their names.


testMid

public void testMid()
Test case for MONDRIAN-539, "Problem with the MID function getting last character in a string.".


testPercentagesAsMeasures

public void testPercentagesAsMeasures()
How Can I Show Percentages as Measures?

Another common business question easily answered through MDX is the display of percent values created as available measures.

For example, the Sales cube in the FoodMart 2000 database contains unit sales for each store in a given city, state, and country, organized along the Sales dimension. A report is requested to show, for California, the percentage of total unit sales attained by each city with a store. The results are illustrated in the following table.

Because the parent of a member is typically another, aggregated member in a regular dimension, this is easily achieved by the construction of a calculated member, as demonstrated in the following MDX query, using the CurrentMember and Parent MDX functions.


_testCumlativeSums

public void _testCumlativeSums()
How Can I Show Cumulative Sums as Measures?

Another common business request, cumulative sums, is useful for business reporting purposes. However, since aggregations are handled in a hierarchical fashion, cumulative sums present some unique challenges in Analysis Services.

The best way to create a cumulative sum is as a calculated measure in MDX, using the Rank, Head, Order, and Sum MDX functions together.

For example, the following table illustrates a report that shows two views of employee count in all stores and cities in California, sorted by employee count. The first column shows the aggregated counts for each store and city, while the second column shows aggregated counts for each store, but cumulative counts for each city.

The cumulative number of employees for San Diego represents the value of both Los Angeles and San Diego, the value for Beverly Hills represents the cumulative total of Los Angeles, San Diego, and Beverly Hills, and so on.

Since the members within the state of California have been ordered from highest to lowest number of employees, this form of cumulative sum measure provides a form of pareto analysis within each state.

To support this, the Order function is first used to reorder members accordingly for both the Rank and Head functions. Once reordered, the Rank function is used to supply the ranking of each tuple within the reordered set of members, progressing as each member in the Store dimension is examined. The value is then used to determine the number of tuples to retrieve from the set of reordered members using the Head function. Finally, the retrieved members are then added together using the Sum function to obtain a cumulative sum. The following MDX query demonstrates how all of this works in concert to provide cumulative sums.

As an aside, a named set cannot be used in this situation to replace the duplicate Order function calls. Named sets are evaluated once, when a query is parsed -- since the set can change based on the fact that the set can be different for each store member because the set is evaluated for the children of multiple parents, the set does not change with respect to its use in the Sum function. Since the named set is only evaluated once, it would not satisfy the needs of this query.


testLogicalOps

public void testLogicalOps()
How Can I Implement a Logical AND or OR Condition in a WHERE Clause?

For SQL users, the use of AND and OR logical operators in the WHERE clause of a SQL statement is an essential tool for constructing business queries. However, the WHERE clause of an MDX statement serves a slightly different purpose, and understanding how the WHERE clause is used in MDX can assist in constructing such business queries.

The WHERE clause in MDX is used to further restrict the results of an MDX query, in effect providing another dimension on which the results of the query are further sliced. As such, only expressions that resolve to a single tuple are allowed. The WHERE clause implicitly supports a logical AND operation involving members across different dimensions, by including the members as part of a tuple. To support logical AND operations involving members within a single dimensions, as well as logical OR operations, a calculated member needs to be defined in addition to the use of the WHERE clause.

For example, the following MDX query illustrates the use of a calculated member to support a logical OR. The query returns unit sales by quarter and year for all food and drink related products sold in 1997, run against the Sales cube in the FoodMart 2000 database.

The calculated member simply adds the values of the Unit Sales measure for the Food and the Drink levels of the Product dimension together. The WHERE clause is then used to restrict return of information only to the calculated member, effectively implementing a logical OR to return information for all time periods that contain unit sales values for either food, drink, or both types of products.

You can use the Aggregate function in similar situations where all measures are not aggregated by summing. To return the same results in the above example using the Aggregate function, replace the definition for the calculated member with this definition:

'Aggregate({[Product].[Food], [Product].[Drink]})'


testLogicalAnd

public void testLogicalAnd()

A logical AND, by contrast, can be supported by using two different techniques. If the members used to construct the logical AND reside on different dimensions, all that is required is a WHERE clause that uses a tuple representing all involved members. The following MDX query uses a WHERE clause that effectively restricts the query to retrieve unit sales for drink products in the USA, shown by quarter and year for 1997.


_testSet

public void _testSet()

The WHERE clause in the previous MDX query effectively provides a logical AND operator, in which all unit sales for 1997 are returned only for drink products and only for those sold in stores in the USA.

If the members used to construct the logical AND condition reside on the same dimension, you can use a calculated member or a named set to filter out the unwanted members, as demonstrated in the following MDX query.

The named set, [Good AND Pearl Stores], restricts the displayed unit sales totals only to those stores that have sold both Good products and Pearl products.


testCustomMemberProperties

public void testCustomMemberProperties()
How Can I Use Custom Member Properties in MDX?

Member properties are a good way of adding secondary business information to members in a dimension. However, getting that information out can be confusing -- member properties are not readily apparent in a typical MDX query.

Member properties can be retrieved in one of two ways. The easiest and most used method of retrieving member properties is to use the DIMENSION PROPERTIES MDX statement when constructing an axis in an MDX query.

For example, a member property in the Store dimension in the FoodMart 2000 database details the total square feet for each store. The following MDX query can retrieve this member property as part of the returned cellset.


_testMemberPropertyAsCalcMember

public void _testMemberPropertyAsCalcMember()

The drawback to using the DIMENSION PROPERTIES statement is that, for most client applications, the member property is not readily apparent. If the previous MDX query is executed in the MDX sample application shipped with SQL Server 2000 Analysis Services, for example, you must double-click the name of the member in the grid to open the Member Properties dialog box, which displays all of the member properties shipped as part of the cellset, including the [Store].[Store Name].[Store Sqft] member property.

The other method of retrieving member properties involves the creation of a calculated member based on the member property. The following MDX query brings back the total square feet for each store as a measure, included in the COLUMNS axis.

The [Store SqFt] measure is constructed with the Properties MDX function to retrieve the [Store SQFT] member property for each member in the Store dimension. The benefit to this technique is that the calculated member is readily apparent and easily accessible in client applications that do not support member properties.


_testDrillingDownMoreThanOneLevel

public void _testDrillingDownMoreThanOneLevel()
How Can I Drill Down More Than One Level Deep, or Skip Levels When Drilling Down?

Drilling down is an essential ability for most OLAP products, and Analysis Services is no exception. Several functions exist that support drilling up and down the hierarchy of dimensions within a cube. Typically, drilling up and down the hierarchy is done one level at a time; think of this functionality as a zoom feature for OLAP data.

There are times, though, when the need to drill down more than one level at the same time, or even skip levels when displaying information about multiple levels, exists for a business scenario.

For example, you would like to show report results from a query of the Sales cube in the FoodMart 2000 sample database showing sales totals for individual cities and the subtotals for each country, as shown in the following table.

The Customers dimension, however, has Country, State Province, and City levels. In order to show the above report, you would have to show the Country level and then drill down two levels to show the City level, skipping the State Province level entirely.

However, the MDX ToggleDrillState and DrillDownMember functions provide drill down functionality only one level below a specified set. To drill down more than one level below a specified set, you need to use a combination of MDX functions, including Descendants, Generate, and Except. This technique essentially constructs a large set that includes all levels between both upper and lower desired levels, then uses a smaller set representing the undesired level or levels to remove the appropriate members from the larger set.

The MDX Descendants function is used to construct a set consisting of the descendants of each member in the Customers dimension. The descendants are determined using the MDX Descendants function, with the descendants of the City level and the level above, the State Province level, for each member of the Customers dimension being added to the set.

The MDX Generate function now creates a set consisting of all members at the Country level as well as the members of the set generated by the MDX Descendants function. Then, the MDX Except function is used to exclude all members at the State Province level, so the returned set contains members at the Country and City levels.

Note, however, that the previous MDX query will still order the members according to their hierarchy. Although the returned set contains members at the Country and City levels, the Country, State Province, and City levels determine the order of the members.


_testTopmost

public void _testTopmost()
How Do I Get the Topmost Members of a Level Broken Out by an Ancestor Level?

This type of MDX query is common when only the facts for the lowest level of a dimension within a cube are needed, but information about other levels within the same dimension may also be required to satisfy a specific business scenario.

For example, a report that shows the unit sales for the store with the highest unit sales from each country is needed for marketing purposes. The following table provides an example of this report, run against the Sales cube in the FoodMart 2000 sample database.

This looks simple enough, but the Country Name column provides unexpected difficulty. The values for the Store Country column are taken from the Store Country level of the Store dimension, so the Store Country column is constructed as a calculated member as part of the MDX query, using the MDX Ancestor and Name functions to return the country names for each store.

A combination of the MDX Generate, TopCount, and Descendants functions are used to create a set containing the top stores in unit sales for each country.


testTopmost2

public void testTopmost2()

The MDX Descendants function is used to construct a set consisting of only those members at the Store Name level in the Store dimension. Then, the MDX TopCount function is used to return only the topmost store based on the Unit Sales measure. The MDX Generate function then constructs a set based on the topmost stores, following the hierarchy of the Store dimension.

Alternate techniques, such as using the MDX Crossjoin function, may not provide the desired results because non-related joins can occur. Since the Store Country and Store Name levels are within the same dimension, they cannot be cross-joined. Another dimension that provides the same regional hierarchy structure, such as the Customers dimension, can be employed with the Crossjoin function. But, using this technique can cause non-related joins and return unexpected results.

For example, the following MDX query uses the Crossjoin function to attempt to return the same desired results.

However, some unexpected surprises occur because the topmost member in the Store dimension is cross-joined with all of the children of the Customers dimension, as shown in the following table.

In this instance, the use of a calculated member to provide store country names is easier to understand and debug than attempting to cross-join across unrelated members


testRank

public void testRank()
How Can I Rank or Reorder Members?

One of the issues commonly encountered in business scenarios is the need to rank the members of a dimension according to their corresponding measure values. The Order MDX function allows you to order a set based on a string or numeric expression evaluated against the members of a set. Combined with other MDX functions, the Order function can support several different types of ranking.

For example, the Sales cube in the FoodMart 2000 database can be used to show unit sales for each store. However, the business scenario requires a report that ranks the stores from highest to lowest unit sales, individually, of nonconsumable products.

Because of the requirement that stores be sorted individually, the hierarchy must be broken (in other words, ignored) for the purpose of ranking the stores. The Order function is capable of sorting within the hierarchy, based on the topmost level represented in the set to be sorted, or, by breaking the hierarchy, sorting all of the members of the set as if they existed on the same level, with the same parent.

The following MDX query illustrates the use of the Order function to rank the members according to unit sales.


testDifferentCalculationsForDifferentLevels

public void testDifferentCalculationsForDifferentLevels()
How Can I Use Different Calculations for Different Levels in a Dimension?

This type of MDX query frequently occurs when different aggregations are needed at different levels in a dimension. One easy way to support such functionality is through the use of a calculated measure, created as part of the query, which uses the MDX Descendants function in conjunction with one of the MDX aggregation functions to provide results.

For example, the Warehouse cube in the FoodMart 2000 database supplies the [Units Ordered] measure, aggregated through the Sum function. But, you would also like to see the average number of units ordered per store. The following table demonstrates the desired results.

By using the following MDX query, the desired results can be achieved. The calculated measure, [Average Units Ordered], supplies the average number of ordered units per store by using the Avg, CurrentMember, and Descendants MDX functions.


testDifferentCalculations2

public void testDifferentCalculations2()

This calculated measure is more powerful than it seems; if, for example, you then want to see the average number of units ordered for beer products in all of the stores in the California area, the following MDX query can be executed with the same calculated measure.


_testDifferentCalculationsForDifferentDimensions

public void _testDifferentCalculationsForDifferentDimensions()
How Can I Use Different Calculations for Different Dimensions?

Each measure in a cube uses the same aggregation function across all dimensions. However, there are times where a different aggregation function may be needed to represent a measure for reporting purposes. Two basic cases involve aggregating a single dimension using a different aggregation function than the one used for other dimensions.

  • Aggregating minimums, maximums, or averages along a time dimension
  • Aggregating opening and closing period values along a time dimension

The first case involves some knowledge of the behavior of the time dimension specified in the cube. For instance, to create a calculated measure that contains the average, along a time dimension, of measures aggregated as sums along other dimensions, the average of the aggregated measures must be taken over the set of averaging time periods, constructed through the use of the Descendants MDX function. Minimum and maximum values are more easily calculated through the use of the Min and Max MDX functions, also combined with the Descendants function.

For example, the Warehouse cube in the FoodMart 2000 database contains information on ordered and shipped inventory; from it, a report is requested to show the average number of units shipped, by product, to each store. Information on units shipped is added on a monthly basis, so the aggregated measure [Units Shipped] is divided by the count of descendants, at the Month level, of the current member in the Time dimension. This calculation provides a measure representing the average number of units shipped per month, as demonstrated in the following MDX query.


_testDifferentCalculationsForDifferentDimensions2

public void _testDifferentCalculationsForDifferentDimensions2()

The second case is easier to resolve, because MDX provides the OpeningPeriod and ClosingPeriod MDX functions specifically to support opening and closing period values.

For example, the Warehouse cube in the FoodMart 2000 database contains information on ordered and shipped inventory; from it, a report is requested to show on-hand inventory at the end of every month. Because the inventory on hand should equal ordered inventory minus shipped inventory, the ClosingPeriod MDX function can be used to create a calculated measure to supply the value of inventory on hand, as demonstrated in the following MDX query.


_testDateRange

public void _testDateRange()
How Can I Use Date Ranges in MDX?

Date ranges are a frequently encountered problem. Business questions use ranges of dates, but OLAP objects provide aggregated information in date levels.

Using the technique described here, you can establish date ranges in MDX queries at the level of granularity provided by a time dimension. Date ranges cannot be established below the granularity of the dimension without additional information. For example, if the lowest level of a time dimension represents months, you will not be able to establish a two-week date range without other information. Member properties can be added to supply specific dates for members; using such member properties, you can take advantage of the date and time functions provided by VBA and Excel external function libraries to establish date ranges.

The easiest way to specify a static date range is by using the colon (:) operator. This operator creates a naturally ordered set, using the members specified on either side of the operator as the endpoints for the ordered set. For example, to specify the first six months of 1998 from the Time dimension in FoodMart 2000, the MDX syntax would resemble:

[Time].[1998].[1]:[Time].[1998].[6]

For example, the Sales cube uses a time dimension that supports Year, Quarter, and Month levels. To add a six-month and nine-month total, two calculated members are created in the following MDX query.


_testRolling

public void _testRolling()
How Can I Use Rolling Date Ranges in MDX?

There are several techniques that can be used in MDX to support rolling date ranges. All of these techniques tend to fall into two groups. The first group involves the use of relative hierarchical functions to construct named sets or calculated members, and the second group involves the use of absolute date functions from external function libraries to construct named sets or calculated members. Both groups are applicable in different business scenarios.

In the first group of techniques, typically a named set is constructed which contains a number of periods from a time dimension. For example, the following table illustrates a 12-month rolling period, in which the figures for unit sales of the previous 12 months are shown.

The following MDX query accomplishes this by using a number of MDX functions, including LastPeriods, Tail, Filter, Members, and Item, to construct a named set containing only those members across all other dimensions that share data with the time dimension at the Month level. The example assumes that there is at least one measure, such as [Unit Sales], with a value greater than zero in the current period. The Filter function creates a set of months with unit sales greater than zero, while the Tail function returns the last month in this set, the current month. The LastPeriods function, finally, is then used to retrieve the last 12 periods at this level, including the current period.


testDifferentCalcsForDifferentTimePeriods

public void testDifferentCalcsForDifferentTimePeriods()
How Can I Use Different Calculations for Different Time Periods?

A few techniques can be used, depending on the structure of the cube being queried, to support different calculations for members depending on the time period. The following example includes the MDX IIf function, and is easy to use but difficult to maintain. This example works well for ad hoc queries, but is not the ideal technique for client applications in a production environment.

For example, the following table illustrates a standard and dynamic forecast of warehouse sales, from the Warehouse cube in the FoodMart 2000 database, for drink products. The standard forecast is double the warehouse sales of the previous year, while the dynamic forecast varies from month to month -- the forecast for January is 120 percent of previous sales, while the forecast for July is 260 percent of previous sales.

The most flexible way of handling this type of report is the use of nested MDX IIf functions to return a multiplier to be used on the members of the Products dimension, at the Drinks level. The following MDX query demonstrates this technique.


_testDc4dtp2

public void _testDc4dtp2()

Other techniques, such as the addition of member properties to the Time or Product dimensions to support such calculations, are not as flexible but are much more efficient. The primary drawback to using such techniques is that the calculations are not easily altered for speculative analysis purposes. For client applications, however, where the calculations are static or slowly changing, using a member property is an excellent way of supplying such functionality to clients while keeping maintenance of calculation variables at the server level. The same MDX query, for example, could be rewritten to use a member property named [Dynamic Forecast Multiplier] as shown in the following MDX query.


_testWarehouseProfit

public void _testWarehouseProfit()

_testYtdGrowth

public void _testYtdGrowth()
How Can I Compare Time Periods in MDX?

To answer such a common business question, MDX provides a number of functions specifically designed to navigate and aggregate information across time periods. For example, year-to-date (YTD) totals are directly supported through the YTD function in MDX. In combination with the MDX ParallelPeriod function, you can create calculated members to support direct comparison of totals across time periods.

For example, the following table represents a comparison of YTD unit sales between 1997 and 1998, run against the Sales cube in the FoodMart 2000 database.

The following MDX query uses three calculated members to illustrate how to use the YTD and ParallelPeriod functions in combination to compare time periods.


dont_testParallelMutliple

public void dont_testParallelMutliple()

dont_testParallelNot

public void dont_testParallelNot()

dont_testParallelSomewhat

public void dont_testParallelSomewhat()

dont_testParallelFlushCache

public void dont_testParallelFlushCache()

dont_testParallelVery

public void dont_testParallelVery()

testDependsOn

public void testDependsOn()
Makes sure that the expression [Measures].[Unit Sales] / ([Measures].[Unit Sales], [Product].[All Products]) depends on the current member of the Product dimension, although [Product].[All Products] is referenced from the expression.


testFilterWithCrossJoin

public void testFilterWithCrossJoin()
                             throws Exception
Testcase for bug 1755778, "CrossJoin / Filter query returns null row in result set"

Throws:
Exception - on error

testFilteredCrossJoin

public void testFilteredCrossJoin()
This resulted in OutOfMemoryError when the BatchingCellReader did not know the values for the tuples that were used in filters.


testNonEmptyCrossJoin

public void testNonEmptyCrossJoin()
Tests a query with a CrossJoin so large that we run out of memory unless we can push down evaluation to SQL.


testNonEmptyNonEmptyCrossJoin1

public void testNonEmptyNonEmptyCrossJoin1()
NonEmptyCrossJoin() is not the same as NON EMPTY CrossJoin() because it's evaluated independently of the other axes. (see http://blogs.msdn.com/bi_systems/articles/162841.aspx)


testNonEmptyNonEmptyCrossJoin2

public void testNonEmptyNonEmptyCrossJoin2()

testNonEmptyNonEmptyCrossJoin3

public void testNonEmptyNonEmptyCrossJoin3()

testNonEmptyNonEmptyCrossJoin4

public void testNonEmptyNonEmptyCrossJoin4()

testHierDifferentKeyClass

public void testHierDifferentKeyClass()
description of this testcase: A calculated member is created on the time.month level. On Hierarchize this member is compared to a month. The month has a numeric key, while the calculated members key type is string. No exeception must be thrown.


testOverlappingCalculatedMembers

public void testOverlappingCalculatedMembers()
Bug #1005995 - many totals of various dimensions


testEmptyProperty

public void testEmptyProperty()
the following query raised a classcast exception because an empty property evaluated as "NullMember" note: Store "HQ" does not have a "Store Manager"


_testCubeWhichUsesSameSharedDimTwice

public void _testCubeWhichUsesSameSharedDimTwice()
This test modifies the Sales cube to contain both the regular usage of the [Store] shared dimension, and another usage called [Other Store] which is connected to the [Unit Sales] column


testMemberVisibility

public void testMemberVisibility()

testAllMemberCaption

public void testAllMemberCaption()

testAllLevelName

public void testAllLevelName()

testDimWithoutAll

public void testDimWithoutAll()
Bug 1250080 caused a dimension with no 'all' member to be constrained twice.


testMemberOnAxis

public void testMemberOnAxis()
If an axis expression is a member, implicitly convert it to a set.


testScalarOnAxisFails

public void testScalarOnAxisFails()

testSameDimOnTwoAxesFails

public void testSameDimOnTwoAxesFails()
It is illegal for a query to have the same dimension on more than one axis.


_testSetArgToTupleFails

public void _testSetArgToTupleFails()

_badArgsToTupleFails

public void _badArgsToTupleFails()

testNullMember

public void testNullMember()

testNullMemberWithOneNonNull

public void testNullMemberWithOneNonNull()

testMultipleConstraintsOnSameColumn

public void testMultipleConstraintsOnSameColumn()
Tests whether the agg mgr behaves correctly if a cell request causes a column to be constrained multiple times. This happens if two levels map to the same column via the same join-path. If the constraints are inconsistent, no data will be returned.


testOverrideDimension

public void testOverrideDimension()

testBadMeasure1

public void testBadMeasure1()

testBadMeasure2

public void testBadMeasure2()

testInvalidMembersInQuery

public void testInvalidMembersInQuery()

testMemberOrdinalCaching

public void testMemberOrdinalCaching()

testCancel

public void testCancel()

testQueryTimeout

public void testQueryTimeout()

testFormatInheritance

public void testFormatInheritance()

testFormatInheritanceWithIIF

public void testFormatInheritanceWithIIF()

testFormatInheritanceWorksWithFirstFormatItFinds

public void testFormatInheritanceWorksWithFirstFormatItFinds()
For a calulated member picks up the format of first member that has a format. In this particular case foo will use profit's format, i.e neither [unit sales] nor [customer count] format is used.


testFormatStringAppliedToStringValue

public void testFormatStringAppliedToStringValue()
Test format string values. Previously, a bug meant that string values were printed as is, never passed through the format string.


testAvgCastProblem

public void testAvgCastProblem()
This tests a fix for bug #1603653


testFormatInheritanceUseSecondIfFirstHasNoFormat

public void testFormatInheritanceUseSecondIfFirstHasNoFormat()
Test format inheritance to pickup format from second measure when the first does not have one.


testFormatInheritanceUseFirstValid

public void testFormatInheritanceUseFirstValid()
Tests format inheritance with complex expression to assert that the format of the first member that has a valid format is used.


testQueryIterationLimit

public void testQueryIterationLimit()

testGetCaptionUsingMemberDotCaption

public void testGetCaptionUsingMemberDotCaption()

testGetCaptionUsingMemberDotPropertiesCaption

public void testGetCaptionUsingMemberDotPropertiesCaption()

testDefaultMeasureInCube

public void testDefaultMeasureInCube()

testDefaultMeasureInCubeForIncorrectMeasureName

public void testDefaultMeasureInCubeForIncorrectMeasureName()

testDefaultMeasureInCubeForCaseSensitivity

public void testDefaultMeasureInCubeForCaseSensitivity()

testNumericToLogicalConversion

public void testNumericToLogicalConversion()
This tests for bug #1706434, the ability to convert numeric types to logical (boolean) types.


testRollupQuery

public void testRollupQuery()

testBug1630754

public void testBug1630754()
Tests for bug #1630754. In Mondrian 2.2.2 the SqlTupleReader.readTuples method would create a SQL having an in-clause with more that 1000 entities under some circumstances. This exceeded the limit for Oracle resulting in an ORA-01795 error.


testNonEmptyCrossjoinFilter

public void testNonEmptyCrossjoinFilter()
Tests a query which uses filter and crossjoin. This query caused problems when the retrowoven version of mondrian was used in jdk1.5, specifically a ClassCastException trying to cast a List to a Iterable.


testDuplicateAxisFails

public void testDuplicateAxisFails()

testInvalidAxisFails

public void testInvalidAxisFails()

testSummingProperties

public void testSummingProperties()
Tests various ways to sum the properties of the descendants of a member, inspired by forum post summing properties.


testIifWithTupleFirstAndMemberNextWithMeasure

public void testIifWithTupleFirstAndMemberNextWithMeasure()

testIifWithMemberFirstAndTupleNextWithMeasure

public void testIifWithMemberFirstAndTupleNextWithMeasure()

testIifWithMemberFirstAndTupleNextWithoutMeasure

public void testIifWithMemberFirstAndTupleNextWithoutMeasure()

testIifWithTupleFirstAndMemberNextWithoutMeasure

public void testIifWithTupleFirstAndMemberNextWithoutMeasure()

testIifWithTuplesOfUnequalSizes

public void testIifWithTuplesOfUnequalSizes()

testIifWithTuplesOfUnequalSizesAndOrder

public void testIifWithTuplesOfUnequalSizesAndOrder()

testEmptyAggregationListDueToFilterDoesNotThrowException

public void testEmptyAggregationListDueToFilterDoesNotThrowException()

testEmptySqlBug

public void testEmptySqlBug()
Testcase for Pentaho bug BISERVER-1323, empty SQL query generated when crossjoining more than two sets each containing just the 'all' member.


testHeterogeneousAxis

public void testHeterogeneousAxis()
Tests bug MONDRIAN-7, "Heterogeneous axis gives wrong results". The bug is a misnomer; heterogeneous axes should give an error.


testHierarchiesOfSameDimensionOnDifferentAxes

public void testHierarchiesOfSameDimensionOnDifferentAxes()
Tests hierarchies of the same dimension on different axes.


testHighCardSqlTupleReaderLeakingConnections

public void testHighCardSqlTupleReaderLeakingConnections()
This unit test would cause connection leaks without a fix for bug MONDRIAN-571, "HighCardSqlTupleReader does not close SQL Connections". It would be better if there was a way to verify that no leaks occurred in the data source.


testZeroValuesAreNotTreatedAsNull

public void testZeroValuesAreNotTreatedAsNull()

testDirectMemberReferenceOnDimensionWithCalculationsDefined

public void testDirectMemberReferenceOnDimensionWithCalculationsDefined()

testExplain

public void testExplain()
                 throws SQLException
Throws:
SQLException

testExplainComplex

public void testExplainComplex()
                        throws SQLException
Throws:
SQLException

testExplainInvalid

public void testExplainInvalid()
                        throws SQLException
Throws:
SQLException

testConcurrentStatementRun

public void testConcurrentStatementRun()
                                throws Exception
This is a test for MONDRIAN-1014. Executing a statement twice concurrently would fail because the statement wasn't cleaning up properly its execution context.

Throws:
Exception

testRollup

public void testRollup()

testStatistics

public void testStatistics()
Unit test for StatisticsProvider and implementations JdbcStatisticsProvider and SqlStatisticsProvider.


testResultLimit

public void testResultLimit()
                     throws Exception
Throws:
Exception

testConcurrentStatementRun_2

public void testConcurrentStatementRun_2()
                                  throws Exception
This is a test for MONDRIAN-1161. It verifies that two queries can run at the same time.

Throws:
Exception

Get Mondrian at SourceForge.net. Fast, secure and free Open Source software downloads