Search in sources :

Example 21 with Dialect

use of mondrian.spi.Dialect in project mondrian by pentaho.

the class JdbcDialectFactory method createDialectHelper.

/**
 * Creates a temporary connection and calls
 * {@link mondrian.spi.DialectFactory#createDialect(javax.sql.DataSource, java.sql.Connection)}.
 *
 * <p>Helper method, called when {@code createDialect} is called without a
 * {@link java.sql.Connection} and the dialect factory
 * cannot create a dialect with {@link javax.sql.DataSource} alone.
 *
 * <p>It is a user error if {@code dataSource} is null (since this implies
 * that {@code createDialect} was called with {@code dataSource} and
 * {@code connection} both null.</p>
 *
 * @param factory Dialect factory
 * @param dataSource Data source, must not be null
 * @return Dialect, or null if factory cannot create suitable dialect
 */
public static Dialect createDialectHelper(DialectFactory factory, DataSource dataSource) {
    if (dataSource == null) {
        throw new IllegalArgumentException("Must specify either dataSource or connection");
    }
    Connection connection = null;
    try {
        connection = dataSource.getConnection();
        if (connection == null) {
            // let's be cautious.
            throw new IllegalArgumentException();
        }
        final Dialect dialect = factory.createDialect(dataSource, connection);
        // Close the connection in such a way that if there is a
        // SQLException,
        // (a) we propagate the exception,
        // (b) we don't try to close the connection again.
        Connection connection2 = connection;
        connection = null;
        connection2.close();
        return dialect;
    } catch (SQLException e) {
        throw Util.newError(e, "Error while creating dialect");
    } finally {
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
            // ignore
            }
        }
    }
}
Also used : Dialect(mondrian.spi.Dialect)

Example 22 with Dialect

use of mondrian.spi.Dialect in project mondrian by pentaho.

the class NumberSqlCompilerTest method setUp.

@Override
public void setUp() throws Exception {
    super.setUp();
    Dialect dialect = mock(Dialect.class);
    when(dialect.getDatabaseProduct()).thenReturn(Dialect.DatabaseProduct.MYSQL);
    SqlQuery query = mock(SqlQuery.class);
    when(query.getDialect()).thenReturn(dialect);
    RolapNativeSql sql = new RolapNativeSql(query, null, null, null);
    compiler = sql.new NumberSqlCompiler();
}
Also used : SqlQuery(mondrian.rolap.sql.SqlQuery) Dialect(mondrian.spi.Dialect)

Example 23 with Dialect

use of mondrian.spi.Dialect in project mondrian by pentaho.

the class RolapConnectionTest method testDataSourceOverrideUserPass.

public void testDataSourceOverrideUserPass() throws SQLException, NamingException {
    // use the datasource property to connect to the database
    Util.PropertyList properties = spy(TestContext.instance().getConnectionProperties().clone());
    final Dialect dialect = TestContext.instance().getDialect();
    if (dialect.getDatabaseProduct() == Dialect.DatabaseProduct.ACCESS) {
        // Access doesn't accept user/password, so this test is pointless.
        return;
    }
    final String jdbcUser = properties.get(RolapConnectionProperties.JdbcUser.name());
    final String jdbcPassword = properties.get(RolapConnectionProperties.JdbcPassword.name());
    if (jdbcUser == null || jdbcPassword == null) {
        // Can only run this test if username and password are explicit.
        return;
    }
    // Define a data source with bogus user and password.
    properties.put(RolapConnectionProperties.JdbcUser.name(), "bogususer");
    properties.put(RolapConnectionProperties.JdbcPassword.name(), "boguspassword");
    properties.put(RolapConnectionProperties.PoolNeeded.name(), "false");
    final StringBuilder buf = new StringBuilder();
    final DataSource dataSource = RolapConnection.createDataSource(null, properties, buf);
    final String desc = buf.toString();
    assertTrue(desc, desc.startsWith("Jdbc="));
    assertTrue(desc, desc.indexOf("JdbcUser=bogususer") >= 0);
    verify(properties, atLeastOnce()).get(RolapConnectionProperties.JdbcPassword.name());
    final String jndiName = "jndiDataSource";
    THREAD_INITIAL_CONTEXT.set(new InitialContext() {

        public Object lookup(String str) {
            return str.equals(jndiName) ? dataSource : null;
        }
    });
    // Create a property list that we will use for the actual mondrian
    // connection. Replace the original JDBC info with the data source we
    // just created.
    final Util.PropertyList properties2 = new Util.PropertyList();
    for (Pair<String, String> entry : properties) {
        properties2.put(entry.getKey(), entry.getValue());
    }
    properties2.remove(RolapConnectionProperties.Jdbc.name());
    properties2.put(RolapConnectionProperties.DataSource.name(), jndiName);
    // With JdbcUser and JdbcPassword credentials in the mondrian connect
    // string, the data source's "user" and "password" properties are
    // overridden and the connection succeeds.
    properties2.put(RolapConnectionProperties.JdbcUser.name(), jdbcUser);
    properties2.put(RolapConnectionProperties.JdbcPassword.name(), jdbcPassword);
    mondrian.olap.Connection connection = null;
    try {
        connection = DriverManager.getConnection(properties2, null);
        Query query = connection.parseQuery("select from [Sales]");
        final Result result = connection.execute(query);
        assertNotNull(result);
    } finally {
        if (connection != null) {
            connection.close();
            connection = null;
        }
    }
    // If we don't specify JdbcUser and JdbcPassword in the mondrian
    // connection properties, mondrian uses the data source's
    // bogus credentials, and the connection fails.
    properties2.remove(RolapConnectionProperties.JdbcUser.name());
    properties2.remove(RolapConnectionProperties.JdbcPassword.name());
    for (String poolNeeded : Arrays.asList("false", "true")) {
        // Important to test with & without pooling. Connection pools
        // typically do not let you change user, so it's important that
        // mondrian handles these right.
        properties2.put(RolapConnectionProperties.PoolNeeded.name(), poolNeeded);
        try {
            connection = DriverManager.getConnection(properties2, null);
            fail("Expected exception");
        } catch (MondrianException e) {
            final String s = TestContext.getStackTrace(e);
            assertTrue(s, s.indexOf("Error while creating SQL connection: " + "DataSource=jndiDataSource") >= 0);
            switch(dialect.getDatabaseProduct()) {
                case DERBY:
                    assertTrue(s, s.indexOf("Caused by: java.sql.SQLException: " + "Schema 'BOGUSUSER' does not exist") >= 0);
                    break;
                case ORACLE:
                    assertTrue(s, s.indexOf("Caused by: java.sql.SQLException: ORA-01017: " + "invalid username/password; logon denied") >= 0);
                    break;
                case MYSQL:
                case MARIADB:
                    assertTrue(s, s.indexOf("Caused by: java.sql.SQLException: Access denied " + "for user 'bogususer'") >= 0);
                    break;
                case POSTGRESQL:
                    assertTrue(s, s.indexOf("Caused by: org.postgresql.util.PSQLException: " + "FATAL: password authentication failed for " + "user \"bogususer\"") >= 0);
                    break;
            }
        } finally {
            if (connection != null) {
                connection.close();
                connection = null;
            }
        }
    }
}
Also used : Query(mondrian.olap.Query) Util(mondrian.olap.Util) InitialContext(javax.naming.InitialContext) DataSource(javax.sql.DataSource) Result(mondrian.olap.Result) Dialect(mondrian.spi.Dialect) MondrianException(mondrian.olap.MondrianException)

Example 24 with Dialect

use of mondrian.spi.Dialect in project mondrian by pentaho.

the class BatchTestCase method assertQuerySqlOrNot.

/**
 * During MDX query parse and execution, checks that the query results
 * (or does not result) in a particular SQL statement being generated.
 *
 * <p>Parses and executes the MDX query once for each SQL
 * pattern in the current dialect. If there are multiple patterns, runs the
 * MDX query multiple times, and expects to see each SQL statement appear.
 * If there are no patterns in this dialect, the test trivially succeeds.
 *
 * @param testContext non-default test context if required
 * @param mdxQuery MDX query
 * @param patterns Set of patterns
 * @param negative false to assert if SQL is generated;
 *                 true to assert if SQL is NOT generated
 * @param bypassSchemaCache whether to grab a new connection and bypass the
 *        schema cache before parsing the MDX query
 * @param clearCache whether to clear cache before executing the MDX query
 */
protected void assertQuerySqlOrNot(TestContext testContext, String mdxQuery, SqlPattern[] patterns, boolean negative, boolean bypassSchemaCache, boolean clearCache) {
    Connection connection = testContext.getConnection();
    mdxQuery = testContext.upgradeQuery(mdxQuery);
    // Run the test once for each pattern in this dialect.
    // (We could optimize and run it once, collecting multiple queries, and
    // comparing all queries at the end.)
    Dialect dialect = testContext.getDialect();
    Dialect.DatabaseProduct d = dialect.getDatabaseProduct();
    boolean patternFound = false;
    for (SqlPattern sqlPattern : patterns) {
        if (!sqlPattern.hasDatabaseProduct(d)) {
            // message if required.
            continue;
        }
        patternFound = true;
        String sql = sqlPattern.getSql();
        String trigger = sqlPattern.getTriggerSql();
        sql = dialectize(d, sql);
        trigger = dialectize(d, trigger);
        // Create a dummy DataSource which will throw a 'bomb' if it is
        // asked to execute a particular SQL statement, but will otherwise
        // behave exactly the same as the current DataSource.
        final TriggerHook hook = new TriggerHook(trigger);
        RolapUtil.setHook(hook);
        Bomb bomb = null;
        try {
            if (bypassSchemaCache) {
                connection = testContext.withSchemaPool(false).getConnection();
            }
            final Query query = connection.parseQuery(mdxQuery);
            if (clearCache) {
                clearCache((RolapCube) query.getCube());
            }
            final Result result = connection.execute(query);
            Util.discard(result);
            bomb = null;
        } catch (Bomb e) {
            bomb = e;
        } catch (RuntimeException e) {
            // Walk up the exception tree and see if the root cause
            // was a SQL bomb.
            bomb = Util.getMatchingCause(e, Bomb.class);
            if (bomb == null) {
                throw e;
            }
        } finally {
            RolapUtil.setHook(null);
        }
        if (negative) {
            if (bomb != null || hook.foundMatch()) {
                fail("forbidden query [" + sql + "] detected");
            }
        } else {
            if (bomb == null && !hook.foundMatch()) {
                fail("expected query [" + sql + "] did not occur");
            }
            if (bomb != null) {
                assertEquals(replaceQuotes(sql.replaceAll("\r\n", "\n")), replaceQuotes(bomb.sql.replaceAll("\r\n", "\n")));
            }
        }
    }
    // dialect.
    if (!patternFound) {
        String warnDialect = MondrianProperties.instance().WarnIfNoPatternForDialect.get();
        if (warnDialect.equals(d.toString())) {
            System.out.println("[No expected SQL statements found for dialect \"" + dialect.toString() + "\" and test not run]");
        }
    }
}
Also used : Query(mondrian.olap.Query) SqlPattern(mondrian.test.SqlPattern) Connection(mondrian.olap.Connection) Dialect(mondrian.spi.Dialect) Result(mondrian.olap.Result)

Example 25 with Dialect

use of mondrian.spi.Dialect in project mondrian by pentaho.

the class FastBatchingCellReaderTest method testCanBatchForBatchWithDifferentAggregationTable.

public void testCanBatchForBatchWithDifferentAggregationTable() {
    final Dialect dialect = getTestContext().getDialect();
    final Dialect.DatabaseProduct product = dialect.getDatabaseProduct();
    switch(product) {
        case TERADATA:
        case INFOBRIGHT:
        case NEOVIEW:
            // tables, so this test will fail.
            return;
    }
    final BatchLoader fbcr = createFbcr(null, salesCube);
    BatchLoader.Batch summaryBatch = createBatch(fbcr, new String[] { tableTime }, new String[] { fieldYear }, new String[][] { fieldValuesYear }, cubeNameSales, measureUnitSales);
    BatchLoader.Batch detailedBatch = createBatch(fbcr, new String[] { tableTime, tableCustomer }, new String[] { fieldYear, fieldGender }, new String[][] { fieldValuesYear, fieldValuesGender }, cubeNameSales, measureUnitSales);
    if (MondrianProperties.instance().UseAggregates.get() && MondrianProperties.instance().ReadAggregates.get()) {
        assertFalse(detailedBatch.canBatch(summaryBatch));
        assertFalse(summaryBatch.canBatch(detailedBatch));
    } else {
        assertTrue(detailedBatch.canBatch(summaryBatch));
        assertFalse(summaryBatch.canBatch(detailedBatch));
    }
}
Also used : Dialect(mondrian.spi.Dialect)

Aggregations

Dialect (mondrian.spi.Dialect)53 SqlPattern (mondrian.test.SqlPattern)8 Execution (mondrian.server.Execution)4 Result (mondrian.olap.Result)3 SqlQuery (mondrian.rolap.sql.SqlQuery)3 StatisticsProvider (mondrian.spi.StatisticsProvider)3 DataSource (javax.sql.DataSource)2 Query (mondrian.olap.Query)2 TestContext (mondrian.test.TestContext)2 java.sql (java.sql)1 ArrayList (java.util.ArrayList)1 InitialContext (javax.naming.InitialContext)1 Connection (mondrian.olap.Connection)1 MondrianException (mondrian.olap.MondrianException)1 Util (mondrian.olap.Util)1 RolapCube (mondrian.rolap.RolapCube)1 Column (mondrian.rolap.RolapStar.Column)1 Table (mondrian.rolap.RolapStar.Table)1 ListColumnPredicate (mondrian.rolap.agg.ListColumnPredicate)1 AggStar (mondrian.rolap.aggmatcher.AggStar)1