Ejemplo n.º 1
0
  /**
   * Parse a SQL literal statement into an unplanned, intermediate representation. This is normally
   * followed by a call to {@link this#plan(AbstractCostModel, String, String, String, String, int,
   * ScalarValueHints[]) }, but splitting these two affords an opportunity to check a cache for a
   * plan matching the auto-parameterized parsed statement.
   */
  public void parse() throws PlanningErrorException {
    // reset any error message
    m_recentErrorMsg = null;

    // Reset plan node ids to start at 1 for this plan
    AbstractPlanNode.resetPlanNodeIds();

    // determine the type of the query
    //
    // (Hmmm...  seems like this pre-processing of the SQL text
    // and subsequent placement of UPSERT_TAG should be pushed down
    // into getXMLCompiledStatement)
    m_sql = m_sql.trim();
    if (m_sql.length() > 6
        && m_sql.substring(0, 6).toUpperCase().startsWith("UPSERT")) { // ENG-7395
      m_isUpsert = true;
      m_sql = "INSERT" + m_sql.substring(6);
    }

    // use HSQLDB to get XML that describes the semantics of the statement
    // this is much easier to parse than SQL and is checked against the catalog
    try {
      m_xmlSQL = m_HSQL.getXMLCompiledStatement(m_sql);
    } catch (HSQLParseException e) {
      // XXXLOG probably want a real log message here
      throw new PlanningErrorException(e.getMessage());
    }

    if (m_isUpsert) {
      assert (m_xmlSQL.name.equalsIgnoreCase("INSERT"));
      // for AdHoc cache distinguish purpose which is based on the XML
      m_xmlSQL.attributes.put(UPSERT_TAG, "true");
    }

    m_planSelector.outputCompiledStatement(m_xmlSQL);
  }