All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hazelcast.org.apache.calcite.rel.core.Values Maven / Gradle / Ivy

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.hazelcast.org.apache.calcite.rel.core;

import com.hazelcast.org.apache.calcite.plan.RelOptCluster;
import com.hazelcast.org.apache.calcite.plan.RelOptCost;
import com.hazelcast.org.apache.calcite.plan.RelOptPlanner;
import com.hazelcast.org.apache.calcite.plan.RelOptRule;
import com.hazelcast.org.apache.calcite.plan.RelTraitSet;
import com.hazelcast.org.apache.calcite.rel.AbstractRelNode;
import com.hazelcast.org.apache.calcite.rel.RelInput;
import com.hazelcast.org.apache.calcite.rel.RelWriter;
import com.hazelcast.org.apache.calcite.rel.metadata.RelMetadataQuery;
import com.hazelcast.org.apache.calcite.rel.type.RelDataType;
import com.hazelcast.org.apache.calcite.rel.type.RelDataTypeField;
import com.hazelcast.org.apache.calcite.rex.RexDigestIncludeType;
import com.hazelcast.org.apache.calcite.rex.RexLiteral;
import com.hazelcast.org.apache.calcite.sql.SqlExplainLevel;
import com.hazelcast.org.apache.calcite.sql.type.SqlTypeUtil;
import com.hazelcast.org.apache.calcite.util.Pair;

import com.hazelcast.com.google.common.collect.ImmutableList;

import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * Relational expression whose value is a sequence of zero or more literal row
 * values.
 */
public abstract class Values extends AbstractRelNode {

  public static final Predicate IS_EMPTY_J = Values::isEmpty;

  @SuppressWarnings("Guava")
  @Deprecated // to be removed before 2.0
  public static final com.hazelcast.com.google.common.base.Predicate
      IS_EMPTY = Values::isEmpty;

  @SuppressWarnings("Guava")
  @Deprecated // to be removed before 2.0
  public static final com.hazelcast.com.google.common.base.Predicate
      IS_NOT_EMPTY = Values::isNotEmpty;

  //~ Instance fields --------------------------------------------------------

  public final ImmutableList> tuples;

  //~ Constructors -----------------------------------------------------------

  /**
   * Creates a new Values.
   *
   * 

Note that tuples passed in become owned by * this rel (without a deep copy), so caller must not modify them after this * call, otherwise bad things will happen. * * @param cluster Cluster that this relational expression belongs to * @param rowType Row type for tuples produced by this rel * @param tuples 2-dimensional array of tuple values to be produced; outer * list contains tuples; each inner list is one tuple; all * tuples must be of same length, conforming to rowType */ protected Values( RelOptCluster cluster, RelDataType rowType, ImmutableList> tuples, RelTraitSet traits) { super(cluster, traits); this.rowType = rowType; this.tuples = tuples; assert assertRowType(); } /** * Creates a Values by parsing serialized output. */ public Values(RelInput input) { this(input.getCluster(), input.getRowType("type"), input.getTuples("tuples"), input.getTraitSet()); } //~ Methods ---------------------------------------------------------------- /** Predicate, to be used when defining an operand of a {@link RelOptRule}, * that returns true if a Values contains zero tuples. * *

This is the conventional way to represent an empty relational * expression. There are several rules that recognize empty relational * expressions and prune away that section of the tree. */ public static boolean isEmpty(Values values) { return values.getTuples().isEmpty(); } /** Predicate, to be used when defining an operand of a {@link RelOptRule}, * that returns true if a Values contains one or more tuples. * *

This is the conventional way to represent an empty relational * expression. There are several rules that recognize empty relational * expressions and prune away that section of the tree. */ public static boolean isNotEmpty(Values values) { return !isEmpty(values); } public ImmutableList> getTuples(RelInput input) { return input.getTuples("tuples"); } /** Returns the rows of literals represented by this Values relational * expression. */ public ImmutableList> getTuples() { return tuples; } /** Returns true if all tuples match rowType; otherwise, assert on * mismatch. */ private boolean assertRowType() { for (List tuple : tuples) { assert tuple.size() == rowType.getFieldCount(); for (Pair pair : Pair.zip(tuple, rowType.getFieldList())) { RexLiteral literal = pair.left; RelDataType fieldType = pair.right.getType(); // TODO jvs 19-Feb-2006: strengthen this a bit. For example, // overflow, rounding, and padding/truncation must already have // been dealt with. if (!RexLiteral.isNullLiteral(literal)) { assert SqlTypeUtil.canAssignFrom(fieldType, literal.getType()) : "to " + fieldType + " from " + literal; } } } return true; } @Override protected RelDataType deriveRowType() { return rowType; } @Override public RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery mq) { double dRows = mq.getRowCount(this); // Assume CPU is negligible since values are precomputed. double dCpu = 1; double dIo = 0; return planner.getCostFactory().makeCost(dRows, dCpu, dIo); } // implement RelNode public double estimateRowCount(RelMetadataQuery mq) { return tuples.size(); } // implement RelNode public RelWriter explainTerms(RelWriter pw) { // A little adapter just to get the tuples to come out // with curly brackets instead of square brackets. Plus // more whitespace for readability. RelWriter relWriter = super.explainTerms(pw) // For rel digest, include the row type since a rendered // literal may leave the type ambiguous (e.g. "null"). .itemIf("type", rowType, pw.getDetailLevel() == SqlExplainLevel.DIGEST_ATTRIBUTES) .itemIf("type", rowType.getFieldList(), pw.nest()); if (pw.nest()) { pw.item("tuples", tuples); } else { pw.item("tuples", tuples.stream() .map(row -> row.stream() .map(lit -> lit.computeDigest(RexDigestIncludeType.NO_TYPE)) .collect(Collectors.joining(", ", "{ ", " }"))) .collect(Collectors.joining(", ", "[", "]"))); } return relWriter; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy