Skip to content

Commit

Permalink
MONDRIAN: Fix for MONDRIAN-528 - MySQL incorrectly identified as usin…
Browse files Browse the repository at this point in the history
…g Infobright Dialect.

Included notes in Javadoc for implementing Dialects

[git-p4: depot-paths = "//open/mondrian/": change = 12593]
  • Loading branch information
Sherman Wood committed Apr 12, 2009
1 parent c67c1df commit 12198a8
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 59 deletions.
8 changes: 1 addition & 7 deletions src/main/mondrian/spi/impl/InfobrightDialect.java
Expand Up @@ -23,9 +23,7 @@ public class InfobrightDialect extends MySqlDialect {
public static final JdbcDialectFactory FACTORY =
new JdbcDialectFactory(
InfobrightDialect.class,
// While we're choosing dialects, this still looks like a MySQL
// connection.
DatabaseProduct.MYSQL);
DatabaseProduct.INFOBRIGHT);

/**
* Creates an InfobrightDialect.
Expand All @@ -36,10 +34,6 @@ public InfobrightDialect(Connection connection) throws SQLException {
super(connection);
}

public DatabaseProduct getDatabaseProduct() {
return DatabaseProduct.INFOBRIGHT;
}

public boolean allowsCompoundCountDistinct() {
return false;
}
Expand Down
57 changes: 27 additions & 30 deletions src/main/mondrian/spi/impl/JdbcDialectFactory.java
Expand Up @@ -110,6 +110,17 @@ public static Dialect createDialectHelper(
}
}

/**
* Generate a valid dialect for the connection, or null if
* the connection is not for the given DatabaseProduct.
*
* Instantiates a Dialect and tests it. Dialects may run queries and other
* operations to determine the database product behind the connection.
*
* @param dataSource JDBC data source, if null need connection
* @param connection JDBC connection, if null nee data source
* @return Dialect, or null if factory cannot create suitable dialect
*/
public Dialect createDialect(DataSource dataSource, Connection connection) {
// If connection is null, create a temporary connection and
// recursively call this method.
Expand All @@ -118,40 +129,26 @@ public Dialect createDialect(DataSource dataSource, Connection connection) {
}

assert connection != null;
if (acceptsConnection(connection)) {
try {
return constructor.newInstance(connection);
} catch (InstantiationException e) {
throw Util.newError(
e, "Error while instantiating dialect");
} catch (IllegalAccessException e) {
throw Util.newError(
e, "Error while instantiating dialect");
} catch (InvocationTargetException e) {
throw Util.newError(
e, "Error while instantiating dialect");
}
}
return null;
}

/**
* Returns whether this dialect is suitable for the given connection.
*
* @param connection Connection
* @return Whether suitable
*/
private boolean acceptsConnection(Connection connection) {
Dialect newDialect = null;
try {
final DatabaseMetaData metaData = connection.getMetaData();
final String productName = metaData.getDatabaseProductName();
final String productVersion = metaData.getDatabaseProductVersion();
final Dialect.DatabaseProduct product =
JdbcDialectImpl.getProduct(productName, productVersion);
return product == this.databaseProduct;
} catch (SQLException e) {
newDialect = constructor.newInstance(connection);
} catch (InstantiationException e) {
throw Util.newError(
e, "Error while instantiating dialect");
} catch (IllegalAccessException e) {
throw Util.newError(
e, "Error while instantiating dialect");
} catch (InvocationTargetException e) {
throw Util.newError(
e, "Error while instantiating dialect");
}

if (newDialect == null ||
newDialect.getDatabaseProduct() != this.databaseProduct) {
return null;
} else {
return newDialect;
}
}
}
Expand Down
10 changes: 10 additions & 0 deletions src/main/mondrian/spi/impl/JdbcDialectImpl.java
Expand Up @@ -28,6 +28,16 @@
* specific dialect. JdbcDialectImpl reads properties from the JDBC driver's
* metadata, so can deduce some of the dialect's behavior.</p>
*
* <p>Implementing a Dialect will include changing the getProduct method in this
* class and changing the list of Dialects in the {@link Dialect} interface. If
* dialect specific SQL is required in the schema, the Mondrian schema will need
* to be updated.</p>
*
* <p>Note that subclasses of JdbcDialectImpl will be instantiated with JDBC
* connections that are not of the actual database product the subclass
* supports. This is done as part of determining the correct dialect for the
* connection.</p>
*
* @author jhyde
* @version $Id$
* @since Oct 10, 2008
Expand Down
31 changes: 9 additions & 22 deletions src/main/mondrian/spi/impl/MySqlDialect.java
Expand Up @@ -11,7 +11,6 @@
import mondrian.olap.Util;
import mondrian.spi.Dialect;

import javax.sql.DataSource;
import java.util.List;
import java.sql.*;

Expand All @@ -27,27 +26,7 @@ public class MySqlDialect extends JdbcDialectImpl {
public static final JdbcDialectFactory FACTORY =
new JdbcDialectFactory(
MySqlDialect.class,
DatabaseProduct.MYSQL)
{
@Override
public Dialect createDialect(
DataSource dataSource,
Connection connection)
{
final Dialect dialect =
super.createDialect(
dataSource, connection);
// Infobright looks a lot like MySQL. If this is an Infobright
// connection, yield to the Infobright dialect.
if (dialect != null &&
dialect instanceof MySqlDialect &&
((MySqlDialect) dialect).getDatabaseProduct() ==
DatabaseProduct.INFOBRIGHT) {
return null;
}
return dialect;
}
};
DatabaseProduct.MYSQL);

/**
* Creates a MySqlDialect.
Expand All @@ -73,8 +52,16 @@ private static boolean isInfobright(
{
Statement statement = null;
try {
String productName =
databaseMetaData.getDatabaseProductName();
String productVersion =
databaseMetaData.getDatabaseProductVersion();

if (JdbcDialectImpl.getProduct(productName, productVersion) !=
DatabaseProduct.MYSQL) {
return false;
}

if (productVersion.compareTo("5.1") >= 0) {
statement = databaseMetaData.getConnection().createStatement();
final ResultSet resultSet =
Expand Down

0 comments on commit 12198a8

Please sign in to comment.