Skip to content

Commit

Permalink
MONDRIAN: Fix date literal generation for Derby and Access.
Browse files Browse the repository at this point in the history
[git-p4: depot-paths = "//open/mondrian/": change = 11326]
  • Loading branch information
julianhyde committed Jul 21, 2008
1 parent 7453b70 commit 3ce84d5
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 21 deletions.
32 changes: 25 additions & 7 deletions src/main/mondrian/rolap/sql/SqlQuery.java
Expand Up @@ -21,11 +21,9 @@
import javax.sql.DataSource;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.*;
import java.util.*;
import java.util.Date;

/**
* <code>SqlQuery</code> allows us to build a <code>select</code>
Expand Down Expand Up @@ -1105,14 +1103,34 @@ public void quoteDateLiteral(StringBuilder buf, String value) {
// RolapSchemaReader.lookupMemberChildByName looks for
// NumberFormatException to suppress it, so that is why
// we convert the exception here.
final java.sql.Date date;
try {
java.sql.Date.valueOf(value);
date = java.sql.Date.valueOf(value);
} catch (IllegalArgumentException ex) {
throw new NumberFormatException(
"Illegal DATE literal: " + value);
}
buf.append("DATE ");
Util.singleQuoteString(value, buf);
if (isDerby()) {
// Derby accepts DATE('2008-01-23') but not SQL:2003 format.
buf.append("DATE(");
Util.singleQuoteString(value, buf);
buf.append(")");
} else if (isAccess()) {
// Access accepts #01/23/2008# but not SQL:2003 format.
buf.append("#");
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
buf.append(calendar.get(Calendar.MONTH) + 1);
buf.append("/");
buf.append(calendar.get(Calendar.DAY_OF_MONTH));
buf.append("/");
buf.append(calendar.get(Calendar.YEAR));
buf.append("#");
} else {
// SQL:2003 date format: DATE '2008-01-23'.
buf.append("DATE ");
Util.singleQuoteString(value, buf);
}
}

/**
Expand Down
53 changes: 39 additions & 14 deletions testsrc/main/mondrian/test/DialectTest.java
Expand Up @@ -16,10 +16,7 @@
import java.sql.Statement;
import java.sql.SQLException;
import java.sql.ResultSet;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.HashSet;
import java.util.*;

import mondrian.olap.Util;
import mondrian.rolap.sql.SqlQuery;
Expand Down Expand Up @@ -386,32 +383,60 @@ public void testResultSetConcurrency() {
}

public void testGenerateInline() throws SQLException {
assertInline(new String[]{"a", "1"});
assertInline(new String[]{"a", "1"}, new String[]{"bb", "2"});
final List<String> typeList = Arrays.asList("String", "Numeric");
final List<String> nameList = Arrays.asList("x", "y");
assertInline(
nameList, typeList,
new String[]{"a", "1"});

assertInline(
nameList, typeList,
new String[]{"a", "1"}, new String[]{"bb", "2"});

// date value
final List<String> typeList2 = Arrays.asList("String", "Date");
assertInline(
nameList, typeList2,
new String[]{"a", "2008-04-29"}, new String[]{"b", "2007-01-02"});
}

private void assertInline(String[]... valueList) throws SQLException {
private void assertInline(
List<String> nameList,
List<String> typeList,
String[]... valueList) throws SQLException {
String sql =
getDialect().generateInline(
Arrays.asList("x", "y"),
Arrays.asList("String", "Numeric"),
nameList,
typeList,
Arrays.asList(valueList));
Statement stmt = null;
try {
stmt = getConnection().createStatement();
ResultSet resultSet = stmt.executeQuery(sql);
Set<List<String>> actualValues = new HashSet<List<String>>();
while (resultSet.next()) {
actualValues.add(
Arrays.asList(
resultSet.getString(1),
String.valueOf(resultSet.getInt(2))));
final List<String> row = new ArrayList<String>();
for (int i = 0; i < typeList.size(); i++) {
final String s;
final String type = typeList.get(i);
if (type.equals("String")) {
s = resultSet.getString(i + 1);
} else if (type.equals("Date")) {
s = String.valueOf(resultSet.getDate(i + 1));
} else if (type.equals("Numeric")) {
s = String.valueOf(resultSet.getInt(i + 1));
} else {
throw new RuntimeException("unknown type " + type);
}
row.add(s);
}
actualValues.add(row);
}
Set<List<String>> expectedRows = new HashSet<List<String>>();
for (String[] strings : valueList) {
expectedRows.add(Arrays.asList(strings));
}
assertEquals(actualValues, expectedRows);
assertEquals(expectedRows, actualValues);
stmt.close();
stmt = null;
} finally {
Expand Down
52 changes: 52 additions & 0 deletions testsrc/main/mondrian/test/InlineTableTest.java
Expand Up @@ -175,6 +175,58 @@ public void testInlineTableSnowflake() {
"Row #0: \n" +
"Row #0: 266,773\n"));
}

public void testInlineTableDate() {
final String cubeName = "Sales_Inline_Date";
TestContext testContext = TestContext.create(
null,
"<Cube name=\"" + cubeName + "\">\n"
+ " <Table name=\"sales_fact_1997\"/>\n"
+ " <DimensionUsage name=\"Time\" source=\"Time\" foreignKey=\"time_id\"/>\n"
+ " <Dimension name=\"Alternative Promotion\" foreignKey=\"promotion_id\">\n"
+ " <Hierarchy hasAll=\"true\" primaryKey=\"id\">\n"
+ " <InlineTable alias=\"inline_promo\">\n"
+ " <ColumnDefs>\n"
+ " <ColumnDef name=\"id\" type=\"Numeric\"/>\n"
+ " <ColumnDef name=\"date\" type=\"Date\"/>\n"
+ " </ColumnDefs>\n"
+ " <Rows>\n"
+ " <Row>\n"
+ " <Value column=\"id\">1</Value>\n"
+ " <Value column=\"date\">2008-04-29</Value>\n"
+ " </Row>\n"
+ " <Row>\n"
+ " <Value column=\"id\">2</Value>\n"
+ " <Value column=\"date\">2007-01-20</Value>\n"
+ " </Row>\n"
+ " </Rows>\n"
+ " </InlineTable>\n"
+ " <Level name=\"Alternative Promotion\" column=\"id\" nameColumn=\"date\" uniqueMembers=\"true\"/> \n"
+ " </Hierarchy>\n"
+ " </Dimension>\n"
+ " <Measure name=\"Unit Sales\" column=\"unit_sales\" aggregator=\"sum\"\n"
+ " formatString=\"Standard\" visible=\"false\"/>\n"
+ " <Measure name=\"Store Sales\" column=\"store_sales\" aggregator=\"sum\"\n"
+ " formatString=\"#,###.00\"/>\n"
+ "</Cube>",
null, null, null, null);
// Access returns date literals as timestamp values, which results in
// extra fields when converted to a string.
final String extra =
testContext.getDialect().isAccess() ? " 00:00:00.0" : "";
testContext.assertQueryReturns(
"select {[Alternative Promotion].Members} ON COLUMNS\n"
+ "from [" + cubeName + "] ",
fold("Axis #0:\n" +
"{}\n" +
"Axis #1:\n" +
"{[Alternative Promotion].[All Alternative Promotions]}\n" +
"{[Alternative Promotion].[All Alternative Promotions].[2008-04-29" + extra + "]}\n" +
"{[Alternative Promotion].[All Alternative Promotions].[2007-01-20" + extra + "]}\n" +
"Row #0: 266,773\n" +
"Row #0: \n" +
"Row #0: \n"));
}
}

// End InlineTableTest.java

0 comments on commit 3ce84d5

Please sign in to comment.