You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@metamodel.apache.org by ka...@apache.org on 2017/07/23 04:41:31 UTC
metamodel git commit: METAMODEL-1143: Partially fixed (for HSQLDB
only).
Repository: metamodel
Updated Branches:
refs/heads/master 8a69372fb -> 1651957d0
METAMODEL-1143: Partially fixed (for HSQLDB only).
Closes #150
Project: http://git-wip-us.apache.org/repos/asf/metamodel/repo
Commit: http://git-wip-us.apache.org/repos/asf/metamodel/commit/1651957d
Tree: http://git-wip-us.apache.org/repos/asf/metamodel/tree/1651957d
Diff: http://git-wip-us.apache.org/repos/asf/metamodel/diff/1651957d
Branch: refs/heads/master
Commit: 1651957d0c3c0f59d676076ec63b9e9b839afb07
Parents: 8a69372
Author: Joerg Unbehauen <un...@informatik.uni-leipzig.de>
Authored: Sat Jul 22 21:37:51 2017 -0700
Committer: Kasper Sørensen <i....@gmail.com>
Committed: Sat Jul 22 21:40:24 2017 -0700
----------------------------------------------------------------------
jdbc/pom.xml | 4 +
.../jdbc/dialects/DefaultQueryRewriter.java | 24 ++--
.../jdbc/dialects/HsqldbQueryRewriter.java | 13 +++
.../org/apache/metamodel/jdbc/HsqldbTest.java | 115 ++++++++++++++-----
4 files changed, 116 insertions(+), 40 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/metamodel/blob/1651957d/jdbc/pom.xml
----------------------------------------------------------------------
diff --git a/jdbc/pom.xml b/jdbc/pom.xml
index 91aefc5..858e0ab 100644
--- a/jdbc/pom.xml
+++ b/jdbc/pom.xml
@@ -29,6 +29,10 @@
<groupId>commons-pool</groupId>
<artifactId>commons-pool</artifactId>
</dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
<!-- Test dependencies -->
<dependency>
http://git-wip-us.apache.org/repos/asf/metamodel/blob/1651957d/jdbc/src/main/java/org/apache/metamodel/jdbc/dialects/DefaultQueryRewriter.java
----------------------------------------------------------------------
diff --git a/jdbc/src/main/java/org/apache/metamodel/jdbc/dialects/DefaultQueryRewriter.java b/jdbc/src/main/java/org/apache/metamodel/jdbc/dialects/DefaultQueryRewriter.java
index 90a2411..a9881fa 100644
--- a/jdbc/src/main/java/org/apache/metamodel/jdbc/dialects/DefaultQueryRewriter.java
+++ b/jdbc/src/main/java/org/apache/metamodel/jdbc/dialects/DefaultQueryRewriter.java
@@ -45,11 +45,10 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
- * Generic query rewriter that adds syntax enhancements that are only possible
- * to resolve just before execution time.
+ * Generic query rewriter that adds syntax enhancements that are only possible to resolve just before execution time.
*/
public class DefaultQueryRewriter extends AbstractQueryRewriter {
-
+
private static final Logger logger = LoggerFactory.getLogger(DefaultQueryRewriter.class);
private static final String SPECIAL_ALIAS_CHARACTERS = "- ,.|*%()!#¤/\\=?;:~";
@@ -101,7 +100,7 @@ public class DefaultQueryRewriter extends AbstractQueryRewriter {
return super.rewriteColumnType(columnType, columnSize);
}
- private boolean needsQuoting(String alias, String identifierQuoteString) {
+ protected boolean needsQuoting(String alias, String identifierQuoteString) {
boolean result = false;
if (alias != null && identifierQuoteString != null) {
if (alias.indexOf(identifierQuoteString) == -1) {
@@ -139,11 +138,10 @@ public class DefaultQueryRewriter extends AbstractQueryRewriter {
// operand is a set of values (typically in combination with an
// IN or NOT IN operator). Each individual element must be escaped.
- assert OperatorType.IN.equals(item.getOperator()) ||
- OperatorType.NOT_IN.equals(item.getOperator());
+ assert OperatorType.IN.equals(item.getOperator()) || OperatorType.NOT_IN.equals(item.getOperator());
- @SuppressWarnings("unchecked")
- final List<Object> elements = (List<Object>) CollectionUtils.toList(operand);
+ @SuppressWarnings("unchecked") final List<Object> elements =
+ (List<Object>) CollectionUtils.toList(operand);
for (ListIterator<Object> it = elements.listIterator(); it.hasNext();) {
Object next = it.next();
@@ -169,8 +167,7 @@ public class DefaultQueryRewriter extends AbstractQueryRewriter {
}
/**
- * Rewrites a (non-compound) {@link FilterItem} when it's operand has
- * already been rewritten into a SQL literal.
+ * Rewrites a (non-compound) {@link FilterItem} when it's operand has already been rewritten into a SQL literal.
*
* @param item
* @param operandLiteral
@@ -187,11 +184,10 @@ public class DefaultQueryRewriter extends AbstractQueryRewriter {
}
/**
- * Rewrites a {@link Timestamp} into it's literal representation as known by
- * this SQL dialect.
+ * Rewrites a {@link Timestamp} into it's literal representation as known by this SQL dialect.
*
- * This default implementation returns the JDBC spec's escape syntax for a
- * timestamp: {ts 'yyyy-mm-dd hh:mm:ss.f . . .'}
+ * This default implementation returns the JDBC spec's escape syntax for a timestamp: {ts 'yyyy-mm-dd hh:mm:ss.f . .
+ * .'}
*
* @param ts
* @return
http://git-wip-us.apache.org/repos/asf/metamodel/blob/1651957d/jdbc/src/main/java/org/apache/metamodel/jdbc/dialects/HsqldbQueryRewriter.java
----------------------------------------------------------------------
diff --git a/jdbc/src/main/java/org/apache/metamodel/jdbc/dialects/HsqldbQueryRewriter.java b/jdbc/src/main/java/org/apache/metamodel/jdbc/dialects/HsqldbQueryRewriter.java
index 5d64b31..e98ec48 100644
--- a/jdbc/src/main/java/org/apache/metamodel/jdbc/dialects/HsqldbQueryRewriter.java
+++ b/jdbc/src/main/java/org/apache/metamodel/jdbc/dialects/HsqldbQueryRewriter.java
@@ -26,6 +26,8 @@ import org.apache.metamodel.query.SelectItem;
import org.apache.metamodel.schema.Column;
import org.apache.metamodel.schema.ColumnType;
+import com.google.common.base.CharMatcher;
+
/**
* Query rewriter for HSQLDB
*/
@@ -99,4 +101,15 @@ public class HsqldbQueryRewriter extends DefaultQueryRewriter {
return super.rewriteFilterItem(item);
}
+ /**
+ * HSQL converts all non-escaped characters to uppercases, this is prevented by always escaping
+ */
+ @Override
+ public boolean needsQuoting(String alias, String identifierQuoteString) {
+
+ boolean containsLowerCase = CharMatcher.JAVA_LOWER_CASE.matchesAnyOf(identifierQuoteString);
+
+ return containsLowerCase || super.needsQuoting(alias, identifierQuoteString);
+ }
+
}
http://git-wip-us.apache.org/repos/asf/metamodel/blob/1651957d/jdbc/src/test/java/org/apache/metamodel/jdbc/HsqldbTest.java
----------------------------------------------------------------------
diff --git a/jdbc/src/test/java/org/apache/metamodel/jdbc/HsqldbTest.java b/jdbc/src/test/java/org/apache/metamodel/jdbc/HsqldbTest.java
index 12d5fe2..d9f0587 100644
--- a/jdbc/src/test/java/org/apache/metamodel/jdbc/HsqldbTest.java
+++ b/jdbc/src/test/java/org/apache/metamodel/jdbc/HsqldbTest.java
@@ -23,12 +23,11 @@ import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.util.Arrays;
+import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.swing.table.TableModel;
-import junit.framework.TestCase;
-
import org.apache.metamodel.DataContext;
import org.apache.metamodel.MetaModelHelper;
import org.apache.metamodel.UpdateCallback;
@@ -47,10 +46,11 @@ import org.apache.metamodel.schema.ColumnType;
import org.apache.metamodel.schema.Schema;
import org.apache.metamodel.schema.Table;
+import junit.framework.TestCase;
+
/**
- * Test case that tests hsqldb interaction. The test uses an embedded copy of
- * the "pentaho sampledata" sample database that can be found at
- * http://pentaho.sourceforge.net.
+ * Test case that tests hsqldb interaction. The test uses an embedded copy of the "pentaho sampledata" sample database
+ * that can be found at http://pentaho.sourceforge.net.
*/
public class HsqldbTest extends TestCase {
@@ -71,7 +71,7 @@ public class HsqldbTest extends TestCase {
super.tearDown();
_connection.close();
}
-
+
public void testApproximateCount() throws Exception {
final JdbcDataContext dataContext = new JdbcDataContext(_connection);
final DataSet dataSet = dataContext.executeQuery("SELECT APPROXIMATE COUNT(*) FROM customers");
@@ -79,7 +79,7 @@ public class HsqldbTest extends TestCase {
assertEquals(122, dataSet.getRow().getValue(0));
assertFalse(dataSet.next());
}
-
+
public void testTimestampValueInsertSelect() throws Exception {
Connection connection = DriverManager.getConnection("jdbc:hsqldb:mem:" + getName(), USERNAME, PASSWORD);
JdbcTestTemplates.timestampValueInsertSelect(connection, TimeUnit.NANOSECONDS);
@@ -111,8 +111,7 @@ public class HsqldbTest extends TestCase {
+ "Table[name=CUSTOMER_W_TER,type=TABLE,remarks=null], "
+ "Table[name=DEPARTMENT_MANAGERS,type=TABLE,remarks=null], "
+ "Table[name=DIM_TIME,type=TABLE,remarks=null], " + "Table[name=EMPLOYEES,type=TABLE,remarks=null], "
- + "Table[name=OFFICES,type=TABLE,remarks=null], "
- + "Table[name=ORDERDETAILS,type=TABLE,remarks=null], "
+ + "Table[name=OFFICES,type=TABLE,remarks=null], " + "Table[name=ORDERDETAILS,type=TABLE,remarks=null], "
+ "Table[name=ORDERFACT,type=TABLE,remarks=null], " + "Table[name=ORDERS,type=TABLE,remarks=null], "
+ "Table[name=PAYMENTS,type=TABLE,remarks=null], " + "Table[name=PRODUCTS,type=TABLE,remarks=null], "
+ "Table[name=QUADRANT_ACTUALS,type=TABLE,remarks=null], "
@@ -146,8 +145,8 @@ public class HsqldbTest extends TestCase {
Table productsTable = schema.getTableByName("PRODUCTS");
Table factTable = schema.getTableByName("ORDERFACT");
- Query q = new Query().from(new FromItem(JoinType.INNER, productsTable.getRelationships(factTable)[0])).select(
- productsTable.getColumns()[0], factTable.getColumns()[0]);
+ Query q = new Query().from(new FromItem(JoinType.INNER, productsTable.getRelationships(factTable)[0]))
+ .select(productsTable.getColumns()[0], factTable.getColumns()[0]);
assertEquals(
"SELECT \"PRODUCTS\".\"PRODUCTCODE\", \"ORDERFACT\".\"ORDERNUMBER\" FROM PUBLIC.\"PRODUCTS\" INNER JOIN PUBLIC.\"ORDERFACT\" ON \"PRODUCTS\".\"PRODUCTCODE\" = \"ORDERFACT\".\"PRODUCTCODE\"",
q.toString());
@@ -158,8 +157,8 @@ public class HsqldbTest extends TestCase {
assertEquals(2, tableModel.getColumnCount());
assertEquals(2996, tableModel.getRowCount());
- assertEquals(110, MetaModelHelper.executeSingleRowQuery(dc, new Query().selectCount().from(productsTable))
- .getValue(0));
+ assertEquals(110,
+ MetaModelHelper.executeSingleRowQuery(dc, new Query().selectCount().from(productsTable)).getValue(0));
}
public void testLimit() throws Exception {
@@ -215,23 +214,21 @@ public class HsqldbTest extends TestCase {
Schema schema = dc.getSchemaByName("PUBLIC");
Table productsTable = schema.getTableByName("PRODUCTS");
- Query q = new Query().from(productsTable, "pro-ducts").select(
- new SelectItem(productsTable.getColumnByName("PRODUCTCODE")).setAlias("c|o|d|e"));
+ Query q = new Query().from(productsTable, "pro-ducts")
+ .select(new SelectItem(productsTable.getColumnByName("PRODUCTCODE")).setAlias("c|o|d|e"));
q.setMaxRows(5);
assertEquals("SELECT pro-ducts.\"PRODUCTCODE\" AS c|o|d|e FROM PUBLIC.\"PRODUCTS\" pro-ducts", q.toString());
String queryString = queryRewriter.rewriteQuery(q);
- assertEquals(
- "SELECT TOP 5 \"pro-ducts\".\"PRODUCTCODE\" AS \"c|o|d|e\" FROM PUBLIC.\"PRODUCTS\" \"pro-ducts\"",
+ assertEquals("SELECT TOP 5 \"pro-ducts\".\"PRODUCTCODE\" AS \"c|o|d|e\" FROM PUBLIC.\"PRODUCTS\" \"pro-ducts\"",
queryString);
// We have to test that no additional quoting characters are added every
// time we run the rewriting
queryString = queryRewriter.rewriteQuery(q);
queryString = queryRewriter.rewriteQuery(q);
- assertEquals(
- "SELECT TOP 5 \"pro-ducts\".\"PRODUCTCODE\" AS \"c|o|d|e\" FROM PUBLIC.\"PRODUCTS\" \"pro-ducts\"",
+ assertEquals("SELECT TOP 5 \"pro-ducts\".\"PRODUCTCODE\" AS \"c|o|d|e\" FROM PUBLIC.\"PRODUCTS\" \"pro-ducts\"",
queryString);
// Test that the original query is still the same (ie. it has been
@@ -248,9 +245,10 @@ public class HsqldbTest extends TestCase {
Column column = dc.getDefaultSchema().getTableByName("PRODUCTS").getColumnByName("PRODUCTCODE");
assertEquals("PUBLIC.PRODUCTS.PRODUCTCODE", column.getQualifiedLabel());
- assertEquals("Table[name=PRODUCTS,type=TABLE,remarks=null]", dc.getTableByQualifiedLabel("PUBLIC.PRODUCTS")
- .toString());
- assertEquals("Table[name=PRODUCTS,type=TABLE,remarks=null]", dc.getTableByQualifiedLabel("PRODUCTS").toString());
+ assertEquals("Table[name=PRODUCTS,type=TABLE,remarks=null]",
+ dc.getTableByQualifiedLabel("PUBLIC.PRODUCTS").toString());
+ assertEquals("Table[name=PRODUCTS,type=TABLE,remarks=null]",
+ dc.getTableByQualifiedLabel("PRODUCTS").toString());
assertEquals(
"Column[name=PRODUCTCODE,columnNumber=0,type=VARCHAR,nullable=false,nativeType=VARCHAR,columnSize=50]",
dc.getColumnByQualifiedLabel("PUBLIC.PRODUCTS.PRODUCTCODE").toString());
@@ -293,8 +291,8 @@ public class HsqldbTest extends TestCase {
q = dc.query().from(table).selectCount().where("name").isEquals("m'jello").toQuery();
assertEquals("SELECT COUNT(*) FROM PUBLIC.\"TESTTABLE\" WHERE \"TESTTABLE\".\"NAME\" = 'm'jello'", q.toSql());
- assertEquals("SELECT COUNT(*) FROM PUBLIC.\"TESTTABLE\" WHERE \"TESTTABLE\".\"NAME\" = 'm''jello'", dc
- .getQueryRewriter().rewriteQuery(q));
+ assertEquals("SELECT COUNT(*) FROM PUBLIC.\"TESTTABLE\" WHERE \"TESTTABLE\".\"NAME\" = 'm''jello'",
+ dc.getQueryRewriter().rewriteQuery(q));
row = MetaModelHelper.executeSingleRowQuery(dc, q);
assertEquals(1, ((Number) row.getValue(0)).intValue());
@@ -335,8 +333,8 @@ public class HsqldbTest extends TestCase {
}
public void testInsertOfDifferentTypes() throws Exception {
- Connection connection = DriverManager.getConnection("jdbc:hsqldb:mem:different_types_insert", USERNAME,
- PASSWORD);
+ Connection connection =
+ DriverManager.getConnection("jdbc:hsqldb:mem:different_types_insert", USERNAME, PASSWORD);
try {
connection.createStatement().execute("DROP TABLE my_table");
@@ -417,4 +415,69 @@ public class HsqldbTest extends TestCase {
Connection conn = DriverManager.getConnection("jdbc:hsqldb:mem:interpretation_of_null", USERNAME, PASSWORD);
JdbcTestTemplates.interpretationOfNulls(conn);
}
+
+ public void testCapitalization() throws Exception {
+ try (Connection connection =
+ DriverManager.getConnection("jdbc:hsqldb:mem:different_types_insert", USERNAME, PASSWORD)) {
+
+ final JdbcDataContext dcon = new JdbcDataContext(connection);
+
+ final String mixedcap = "MixedCapitalization";
+ final String idCol = "Id";
+ final String nameCol = "name";
+ final String emailCol = "EMAIL";
+ final String createTable = "CREATE TABLE \"" + mixedcap + "\" (\"" + idCol + "\" INTEGER, \"" + nameCol
+ + "\" LONGVARCHAR, \"" + emailCol + "\" LONGVARCHAR)";
+
+ try (Statement stmt = connection.createStatement();) {
+
+ stmt.execute(createTable);
+
+ }
+
+ dcon.refreshSchemas();
+ assertEquals(mixedcap, dcon.getDefaultSchema().getTable(0).getName());
+ assertEquals(idCol, dcon.getDefaultSchema().getTable(0).getColumn(0).getName());
+
+ dcon.query().from(mixedcap).select(idCol, nameCol, emailCol).execute();
+
+ try (Statement stmt = connection.createStatement()) {
+ stmt.execute("DROP TABLE \"" + mixedcap + "\"");
+ }
+ dcon.refreshSchemas();
+ dcon.executeUpdate(new UpdateScript() {
+
+ @Override
+ public void run(UpdateCallback callback) {
+ callback.createTable(dcon.getDefaultSchemaName(), mixedcap).withColumn(idCol).asPrimaryKey()
+ .ofType(ColumnType.INTEGER).withColumn(nameCol).ofType(ColumnType.STRING)
+ .withColumn(emailCol).ofType(ColumnType.STRING).execute();
+ }
+ });
+
+ dcon.executeUpdate(new UpdateScript() {
+
+ @Override
+ public void run(UpdateCallback callback) {
+ callback.insertInto(mixedcap).value(idCol, 1).value(nameCol, "Sarah")
+ .value(emailCol, "sarah@example.com").execute();
+ }
+ });
+
+ String queryNoQuotes = "SELECT " + nameCol + ", " + idCol + ", " + emailCol + " FROM " + mixedcap
+ + " WHERE " + idCol + "= 1";
+ DataSet dsStringQueryNQ = dcon.executeQuery(queryNoQuotes);
+ List<Row> rowsQueryNoQuotes = dsStringQueryNQ.toRows();
+ assertEquals(1, rowsQueryNoQuotes.size());
+ List<Row> rowsQueryObject = dcon.query().from(mixedcap).select(nameCol).select(idCol).select(emailCol)
+ .where(idCol).eq(1).execute().toRows();
+ assertEquals(1, rowsQueryObject.size());
+
+ assertEquals(rowsQueryObject.get(0).getValue(0), rowsQueryNoQuotes.get(0).getValue(0));
+ assertEquals(rowsQueryObject.get(0).getValue(1), rowsQueryNoQuotes.get(0).getValue(1));
+ assertEquals(rowsQueryObject.get(0).getValue(2), rowsQueryNoQuotes.get(0).getValue(2));
+
+ }
+
+ }
}
\ No newline at end of file