コード例 #1
0
  /**
   * Parse the scan_columns element out of the HSQL-generated XML. Fills scanColumns with a list of
   * the columns used in the plan, hashed by table name.
   *
   * @param columnsNode
   */
  void parseScanColumns(VoltXMLElement columnsNode) {
    scanColumns = new HashMap<String, ArrayList<SchemaColumn>>();

    for (VoltXMLElement child : columnsNode.children) {
      assert (child.name.equals("columnref"));
      AbstractExpression col_exp = parseExpressionTree(child);
      // TupleValueExpressions are always specifically typed,
      // so there is no need for expression type specialization, here.
      assert (col_exp != null);
      assert (col_exp instanceof TupleValueExpression);
      TupleValueExpression tve = (TupleValueExpression) col_exp;
      SchemaColumn col =
          new SchemaColumn(tve.getTableName(), tve.getColumnName(), tve.getColumnAlias(), col_exp);
      ArrayList<SchemaColumn> table_cols = null;
      if (!scanColumns.containsKey(col.getTableName())) {
        table_cols = new ArrayList<SchemaColumn>();
        scanColumns.put(col.getTableName(), table_cols);
      }
      table_cols = scanColumns.get(col.getTableName());
      table_cols.add(col);
    }
  }
コード例 #2
0
 public void setTypeSizeAndInBytes(SchemaColumn typeSource) {
   setValueType(typeSource.getType());
   setValueSize(typeSource.getSize());
   m_inBytes = typeSource.getExpression().getInBytes();
 }
コード例 #3
0
  @Override
  public String toString() {
    String retval = "SQL:\n\t" + sql + "\n";

    retval += "PARAMETERS:\n\t";
    for (VoltType param : paramList) {
      retval += param.toString() + " ";
    }

    retval += "\nTABLE SOURCES:\n\t";
    for (Table table : tableList) {
      retval += table.getTypeName() + " ";
    }

    retval += "\nSCAN COLUMNS:\n";
    if (scanColumns != null) {
      for (String table : scanColumns.keySet()) {
        retval += "\tTable: " + table + ":\n";
        for (SchemaColumn col : scanColumns.get(table)) {
          retval += "\t\tColumn: " + col.getColumnName() + ": ";
          retval += col.getExpression().toString() + "\n";
        }
      }
    } else {
      retval += "\tALL\n";
    }

    if (where != null) {
      retval += "\nWHERE:\n";
      retval += "\t" + where.toString() + "\n";

      retval += "WHERE SELECTION LIST:\n";
      int i = 0;
      for (AbstractExpression expr : whereSelectionList)
        retval += "\t(" + String.valueOf(i++) + ") " + expr.toString() + "\n";

      retval += "NO TABLE SELECTION LIST:\n";
      i = 0;
      for (AbstractExpression expr : noTableSelectionList)
        retval += "\t(" + String.valueOf(i++) + ") " + expr.toString() + "\n";

      retval += "TABLE FILTER LIST:\n";
      for (Entry<Table, ArrayList<AbstractExpression>> pair : tableFilterList.entrySet()) {
        i = 0;
        retval += "\tTABLE: " + pair.getKey().getTypeName() + "\n";
        for (AbstractExpression expr : pair.getValue())
          retval += "\t\t(" + String.valueOf(i++) + ") " + expr.toString() + "\n";
      }

      retval += "JOIN CLAUSE LIST:\n";
      for (Entry<TablePair, ArrayList<AbstractExpression>> pair : joinSelectionList.entrySet()) {
        i = 0;
        retval +=
            "\tTABLES: "
                + pair.getKey().t1.getTypeName()
                + " and "
                + pair.getKey().t2.getTypeName()
                + "\n";
        for (AbstractExpression expr : pair.getValue())
          retval += "\t\t(" + String.valueOf(i++) + ") " + expr.toString() + "\n";
      }
    }
    return retval;
  }
コード例 #4
0
  /**
   * Compile and cache the statement and plan and return the final plan graph.
   *
   * @param sql
   * @param paramCount
   */
  public List<AbstractPlanNode> compile(
      String sql,
      int paramCount,
      String joinOrder,
      Object partitionParameter,
      boolean inferSP,
      boolean lockInSP) {
    Statement catalogStmt = proc.getStatements().add("stmt-" + String.valueOf(compileCounter++));
    catalogStmt.setSqltext(sql);
    catalogStmt.setSinglepartition(partitionParameter != null);
    catalogStmt.setBatched(false);
    catalogStmt.setParamnum(paramCount);

    // determine the type of the query
    QueryType qtype = QueryType.SELECT;
    catalogStmt.setReadonly(true);
    if (sql.toLowerCase().startsWith("insert")) {
      qtype = QueryType.INSERT;
      catalogStmt.setReadonly(false);
    }
    if (sql.toLowerCase().startsWith("update")) {
      qtype = QueryType.UPDATE;
      catalogStmt.setReadonly(false);
    }
    if (sql.toLowerCase().startsWith("delete")) {
      qtype = QueryType.DELETE;
      catalogStmt.setReadonly(false);
    }
    catalogStmt.setQuerytype(qtype.getValue());
    // name will look like "basename-stmt-#"
    String name = catalogStmt.getParent().getTypeName() + "-" + catalogStmt.getTypeName();

    DatabaseEstimates estimates = new DatabaseEstimates();
    TrivialCostModel costModel = new TrivialCostModel();
    PartitioningForStatement partitioning =
        new PartitioningForStatement(partitionParameter, inferSP, lockInSP);
    QueryPlanner planner =
        new QueryPlanner(
            catalogStmt.getSqltext(),
            catalogStmt.getTypeName(),
            catalogStmt.getParent().getTypeName(),
            catalog.getClusters().get("cluster"),
            db,
            partitioning,
            hsql,
            estimates,
            false,
            StatementCompiler.DEFAULT_MAX_JOIN_TABLES,
            costModel,
            null,
            joinOrder);

    CompiledPlan plan = null;
    planner.parse();
    plan = planner.plan();
    assert (plan != null);

    // Input Parameters
    // We will need to update the system catalogs with this new information
    // If this is an adhoc query then there won't be any parameters
    for (int i = 0; i < plan.parameters.length; ++i) {
      StmtParameter catalogParam = catalogStmt.getParameters().add(String.valueOf(i));
      catalogParam.setJavatype(plan.parameters[i].getValue());
      catalogParam.setIndex(i);
    }

    // Output Columns
    int index = 0;
    for (SchemaColumn col : plan.columns.getColumns()) {
      Column catColumn = catalogStmt.getOutput_columns().add(String.valueOf(index));
      catColumn.setNullable(false);
      catColumn.setIndex(index);
      catColumn.setName(col.getColumnName());
      catColumn.setType(col.getType().getValue());
      catColumn.setSize(col.getSize());
      index++;
    }

    List<PlanNodeList> nodeLists = new ArrayList<PlanNodeList>();
    nodeLists.add(new PlanNodeList(plan.rootPlanGraph));
    if (plan.subPlanGraph != null) {
      nodeLists.add(new PlanNodeList(plan.subPlanGraph));
    }

    // Store the list of parameters types and indexes in the plan node list.
    List<Pair<Integer, VoltType>> parameters = nodeLists.get(0).getParameters();
    for (int i = 0; i < plan.parameters.length; ++i) {
      Pair<Integer, VoltType> parameter = new Pair<Integer, VoltType>(i, plan.parameters[i]);
      parameters.add(parameter);
    }

    // Now update our catalog information
    // HACK: We're using the node_tree's hashCode() as it's name. It would be really
    //     nice if the Catalog code give us an guid without needing a name first...

    String json = null;
    try {
      JSONObject jobj = new JSONObject(nodeLists.get(0).toJSONString());
      json = jobj.toString(4);
    } catch (JSONException e2) {
      // TODO Auto-generated catch block
      e2.printStackTrace();
      System.exit(-1);
    }

    //
    // We then stick a serialized version of PlanNodeTree into a PlanFragment
    //
    try {
      BuildDirectoryUtils.writeFile("statement-plans", name + "_json.txt", json);
      BuildDirectoryUtils.writeFile(
          "statement-plans", name + ".dot", nodeLists.get(0).toDOTString("name"));
    } catch (Exception e) {
      e.printStackTrace();
    }

    List<AbstractPlanNode> plannodes = new ArrayList<AbstractPlanNode>();
    for (PlanNodeList nodeList : nodeLists) {
      plannodes.add(nodeList.getRootPlanNode());
    }

    m_currentPlan = plan;
    return plannodes;
  }