示例#1
0
 protected Result executeQuery(String mdx, Connection connection) {
   Query query = connection.parseQuery(mdx);
   query.setResultStyle(ResultStyle.LIST);
   return connection.execute(query);
 }
示例#2
0
  /**
   * 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)) {
        // If the dialect is not one in the pattern set, skip the
        // test. If in the end no pattern is located, print a warning
        // 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.
      RolapUtil.setHook(new TriggerHook(trigger));
      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) {
          fail("forbidden query [" + sql + "] detected");
        }
      } else {
        if (bomb == null) {
          fail("expected query [" + sql + "] did not occur");
        }
        assertEquals(
            replaceQuotes(sql.replaceAll("\r\n", "\n")),
            replaceQuotes(bomb.sql.replaceAll("\r\n", "\n")));
      }
    }

    // Print warning message that no pattern was specified for the current
    // 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]");
      }
    }
  }