Esempio n. 1
0
  void parseDisplayColumns(VoltXMLElement columnsNode) {
    for (VoltXMLElement child : columnsNode.children) {
      ParsedColInfo col = new ParsedColInfo();
      col.expression = parseExpressionTree(child);
      if (col.expression instanceof ConstantValueExpression) {
        assert (col.expression.getValueType() != VoltType.NUMERIC);
      }
      ExpressionUtil.finalizeValueTypes(col.expression);
      assert (col.expression != null);
      col.alias = child.attributes.get("alias");

      if (child.name.equals("columnref")) {
        col.columnName = child.attributes.get("column");
        col.tableName = child.attributes.get("table");
      } else {
        // XXX hacky, assume all non-column refs come from a temp table
        col.tableName = "VOLT_TEMP_TABLE";
        col.columnName = "";
      }
      // This index calculation is only used for sanity checking
      // materialized views (which use the parsed select statement but
      // don't go through the planner pass that does more involved
      // column index resolution).
      col.index = displayColumns.size();
      displayColumns.add(col);
    }
  }
Esempio n. 2
0
  void parseGroupByColumn(VoltXMLElement groupByNode) {

    ParsedColInfo col = new ParsedColInfo();
    col.expression = parseExpressionTree(groupByNode);
    assert (col.expression != null);

    if (groupByNode.name.equals("columnref")) {
      col.alias = groupByNode.attributes.get("alias");
      col.columnName = groupByNode.attributes.get("column");
      col.tableName = groupByNode.attributes.get("table");
      col.groupBy = true;
    } else {
      throw new RuntimeException("GROUP BY with complex expressions not yet supported");
    }

    assert (col.alias.equalsIgnoreCase(col.columnName));
    assert (getTableFromDB(col.tableName) != null);
    assert (getTableFromDB(col.tableName).getColumns().getIgnoreCase(col.columnName) != null);
    org.voltdb.catalog.Column catalogColumn =
        getTableFromDB(col.tableName).getColumns().getIgnoreCase(col.columnName);
    col.index = catalogColumn.getIndex();
    groupByColumns.add(col);
  }
Esempio n. 3
0
  void parseOrderColumn(VoltXMLElement orderByNode) {
    // make sure everything is kosher
    assert (orderByNode.name.equalsIgnoreCase("operation"));
    String operationType = orderByNode.attributes.get("type");
    assert (operationType != null);
    assert (operationType.equalsIgnoreCase("orderby"));

    // get desc/asc
    String desc = orderByNode.attributes.get("desc");
    boolean descending = (desc != null) && (desc.equalsIgnoreCase("true"));

    // get the columnref expression inside the orderby node
    VoltXMLElement child = orderByNode.children.get(0);
    assert (child != null);

    // create the orderby column
    ParsedColInfo order_col = new ParsedColInfo();
    order_col.orderBy = true;
    order_col.ascending = !descending;
    AbstractExpression order_exp = parseExpressionTree(child);

    // Cases:
    // inner child could be columnref, in which case it's just a normal
    // column.  Just make a ParsedColInfo object for it and the planner
    // will do the right thing later
    if (child.name.equals("columnref")) {
      order_col.columnName = child.attributes.get("column");
      order_col.tableName = child.attributes.get("table");
      String alias = child.attributes.get("alias");
      order_col.alias = alias;

      // The ORDER BY column MAY be identical to a simple display column, in which case,
      // tagging the actual display column as being also an order by column
      // helps later when trying to determine ORDER BY coverage (for determinism).
      if (order_exp instanceof TupleValueExpression) {
        ParsedColInfo orig_col = null;
        for (ParsedColInfo col : displayColumns) {
          if (col.expression.equals(order_exp)) {
            orig_col = col;
            break;
          }
        }
        if (orig_col != null) {
          orig_col.orderBy = true;
          orig_col.ascending = order_col.ascending;
        }
      }
    } else if (child.name.equals("operation")) {
      order_col.columnName = "";
      // I'm not sure anyone actually cares about this table name
      order_col.tableName = "VOLT_TEMP_TABLE";

      // If it's a simplecolumn operation.  This means that the alias that
      //    we have should refer to a column that we compute
      //    somewhere else (like an aggregate, mostly).
      //    Look up that column in the displayColumns list,
      //    and then create a new order by column with a magic TVE.
      // This case seems to be the result of cross-referencing a display column
      // by its position, as in "ORDER BY 2, 3". Otherwise the ORDER BY column
      // is a columnref as handled in the prior code block.
      if (order_exp instanceof TupleValueExpression) {
        String alias = child.attributes.get("alias");
        order_col.alias = alias;
        ParsedColInfo orig_col = null;
        for (ParsedColInfo col : displayColumns) {
          if (col.alias.equals(alias)) {
            orig_col = col;
            break;
          }
        }
        // We need the original column expression so we can extract
        // the value size and type for our TVE that refers back to it.
        // XXX: This check runs into problems for some cases where a display column expression gets
        // re-used in the ORDER BY.
        // I THINK one problem case was "select x, max(y) from t group by x order by max(y);" --paul
        if (orig_col == null) {
          throw new PlanningErrorException(
              "Unable to find source " + "column for simplecolumn: " + alias);
        }

        // Tagging the actual display column as being also an order by column
        // helps later when trying to determine ORDER BY coverage (for determinism).
        orig_col.orderBy = true;
        orig_col.ascending = order_col.ascending;

        assert (orig_col.tableName.equals("VOLT_TEMP_TABLE"));
        // Construct our fake TVE that will point back at the input
        // column.
        TupleValueExpression tve = (TupleValueExpression) order_exp;
        tve.setColumnAlias(alias);
        tve.setColumnName("");
        tve.setColumnIndex(-1);
        tve.setTableName("VOLT_TEMP_TABLE");
        tve.setValueSize(orig_col.expression.getValueSize());
        tve.setValueType(orig_col.expression.getValueType());
        if (orig_col.expression.hasAnySubexpressionOfClass(AggregateExpression.class)) {
          tve.setHasAggregate(true);
        }
      }
    } else if (child.name.equals("function") == false) {
      throw new RuntimeException("ORDER BY parsed with strange child node type: " + child.name);
    }
    if (order_exp instanceof ConstantValueExpression) {
      assert (order_exp.getValueType() != VoltType.NUMERIC);
    }
    ExpressionUtil.finalizeValueTypes(order_exp);
    order_col.expression = order_exp;
    orderColumns.add(order_col);
  }