Exemplo n.º 1
0
  @Override
  protected RelationPlan visitUnnest(Unnest node, Void context) {
    TupleDescriptor descriptor = analysis.getOutputDescriptor(node);
    ImmutableList.Builder<Symbol> outputSymbolsBuilder = ImmutableList.builder();
    for (Field field : descriptor.getVisibleFields()) {
      Symbol symbol = symbolAllocator.newSymbol(field);
      outputSymbolsBuilder.add(symbol);
    }
    List<Symbol> unnestedSymbols = outputSymbolsBuilder.build();

    // If we got here, then we must be unnesting a constant, and not be in a join (where there could
    // be column references)
    ImmutableList.Builder<Symbol> argumentSymbols = ImmutableList.builder();
    ImmutableList.Builder<Expression> values = ImmutableList.builder();
    ImmutableMap.Builder<Symbol, List<Symbol>> unnestSymbols = ImmutableMap.builder();
    Iterator<Symbol> unnestedSymbolsIterator = unnestedSymbols.iterator();
    for (Expression expression : node.getExpressions()) {
      Object constantValue =
          evaluateConstantExpression(expression, analysis.getCoercions(), metadata, session);
      Type type = analysis.getType(expression);
      values.add(LiteralInterpreter.toExpression(constantValue, type));
      Symbol inputSymbol = symbolAllocator.newSymbol(expression, type);
      argumentSymbols.add(inputSymbol);
      if (type instanceof ArrayType) {
        unnestSymbols.put(inputSymbol, ImmutableList.of(unnestedSymbolsIterator.next()));
      } else if (type instanceof MapType) {
        unnestSymbols.put(
            inputSymbol,
            ImmutableList.of(unnestedSymbolsIterator.next(), unnestedSymbolsIterator.next()));
      } else {
        throw new IllegalArgumentException("Unsupported type for UNNEST: " + type);
      }
    }
    Optional<Symbol> ordinalitySymbol =
        node.isWithOrdinality() ? Optional.of(unnestedSymbolsIterator.next()) : Optional.empty();
    checkState(
        !unnestedSymbolsIterator.hasNext(),
        "Not all output symbols were matched with input symbols");
    ValuesNode valuesNode =
        new ValuesNode(
            idAllocator.getNextId(),
            argumentSymbols.build(),
            ImmutableList.<List<Expression>>of(values.build()));

    UnnestNode unnestNode =
        new UnnestNode(
            idAllocator.getNextId(),
            valuesNode,
            ImmutableList.<Symbol>of(),
            unnestSymbols.build(),
            ordinalitySymbol);
    return new RelationPlan(unnestNode, descriptor, unnestedSymbols, Optional.empty());
  }
Exemplo n.º 2
0
  @Override
  protected RelationPlan visitValues(Values node, Void context) {
    TupleDescriptor descriptor = analysis.getOutputDescriptor(node);
    ImmutableList.Builder<Symbol> outputSymbolsBuilder = ImmutableList.builder();
    for (Field field : descriptor.getVisibleFields()) {
      Symbol symbol = symbolAllocator.newSymbol(field);
      outputSymbolsBuilder.add(symbol);
    }

    ImmutableList.Builder<List<Expression>> rows = ImmutableList.builder();
    for (Expression row : node.getRows()) {
      ImmutableList.Builder<Expression> values = ImmutableList.builder();
      if (row instanceof Row) {
        List<Expression> items = ((Row) row).getItems();
        for (int i = 0; i < items.size(); i++) {
          Expression expression = items.get(i);
          Object constantValue =
              evaluateConstantExpression(expression, analysis.getCoercions(), metadata, session);
          values.add(
              LiteralInterpreter.toExpression(
                  constantValue, descriptor.getFieldByIndex(i).getType()));
        }
      } else {
        Object constantValue =
            evaluateConstantExpression(row, analysis.getCoercions(), metadata, session);
        values.add(
            LiteralInterpreter.toExpression(
                constantValue, descriptor.getFieldByIndex(0).getType()));
      }

      rows.add(values.build());
    }

    ValuesNode valuesNode =
        new ValuesNode(idAllocator.getNextId(), outputSymbolsBuilder.build(), rows.build());
    return new RelationPlan(valuesNode, descriptor, outputSymbolsBuilder.build(), Optional.empty());
  }