<|start_filename|>core/src/main/java/org/eigenbase/sql/validate/WithItemNamespace.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql.validate;

import org.eigenbase.reltype.RelDataType;
import org.eigenbase.reltype.RelDataTypeFactory;
import org.eigenbase.reltype.RelDataTypeField;
import org.eigenbase.sql.SqlIdentifier;
import org.eigenbase.sql.SqlNode;
import org.eigenbase.sql.SqlWithItem;
import org.eigenbase.util.Pair;

/** Very similar to {@link AliasNamespace}. */
class WithItemNamespace extends AbstractNamespace {
  private final SqlWithItem withItem;

  WithItemNamespace(SqlValidatorImpl validator, SqlWithItem withItem,
      SqlNode enclosingNode) {
    super(validator, enclosingNode);
    this.withItem = withItem;
  }

  @Override protected RelDataType validateImpl() {
    final SqlValidatorNamespace childNs =
        validator.getNamespace(withItem.query);
    final RelDataType rowType = childNs.getRowTypeSansSystemColumns();
    if (withItem.columnList == null) {
      return rowType;
    }
    final RelDataTypeFactory.FieldInfoBuilder builder =
        validator.getTypeFactory().builder();
    for (Pair<SqlNode, RelDataTypeField> pair
        : Pair.zip(withItem.columnList, rowType.getFieldList())) {
      builder.add(((SqlIdentifier) pair.left).getSimple(),
          pair.right.getType());
    }
    return builder.build();
  }

  public SqlNode getNode() {
    return withItem;
  }

  @Override public String translate(String name) {
    if (withItem.columnList == null) {
      return name;
    }
    final RelDataType underlyingRowType =
          validator.getValidatedNodeType(withItem.query);
    int i = 0;
    for (RelDataTypeField field : rowType.getFieldList()) {
      if (field.getName().equals(name)) {
        return underlyingRowType.getFieldList().get(i).getName();
      }
      ++i;
    }
    throw new AssertionError(
        "unknown field '" + name
        + "' in rowtype " + underlyingRowType);
  }
}

// End WithItemNamespace.java


<|start_filename|>core/src/main/java/org/eigenbase/rel/ValuesRel.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel;

import java.util.*;

import org.eigenbase.relopt.*;
import org.eigenbase.reltype.*;
import org.eigenbase.rex.*;

/**
 * <code>ValuesRel</code> represents a sequence of zero or more literal row
 * values.
 */
public class ValuesRel extends ValuesRelBase {
  //~ Constructors -----------------------------------------------------------

  /**
   * Creates a new ValuesRel. 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 .
   * @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
   */
  public ValuesRel(
      RelOptCluster cluster,
      RelDataType rowType,
      List<List<RexLiteral>> tuples) {
    super(
        cluster,
        rowType,
        tuples,
        cluster.traitSetOf(Convention.NONE));
  }

  /**
   * Creates a ValuesRel by parsing serialized output.
   */
  public ValuesRel(RelInput input) {
    super(input);
  }

  public RelNode copy(RelTraitSet traitSet, List<RelNode> inputs) {
    assert traitSet.containsIfApplicable(Convention.NONE);
    assert inputs.isEmpty();
    return new ValuesRel(
        getCluster(),
        rowType,
        tuples);
  }

  @Override
  public RelNode accept(RelShuttle shuttle) {
    return shuttle.visit(this);
  }
}

// End ValuesRel.java


<|start_filename|>core/src/main/java/org/eigenbase/relopt/hep/HepRelVertex.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.relopt.hep;

import java.util.BitSet;
import java.util.List;

import org.eigenbase.rel.*;
import org.eigenbase.rel.metadata.*;
import org.eigenbase.relopt.*;
import org.eigenbase.reltype.*;
import org.eigenbase.util.*;

/**
 * HepRelVertex wraps a real {@link RelNode} as a vertex in a DAG representing
 * the entire query expression.
 */
public class HepRelVertex extends AbstractRelNode {
  //~ Instance fields --------------------------------------------------------

  /**
   * Wrapped rel currently chosen for implementation of expression.
   */
  private RelNode currentRel;

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

  HepRelVertex(RelNode rel) {
    super(
        rel.getCluster(),
        rel.getTraitSet());
    currentRel = rel;
  }

  //~ Methods ----------------------------------------------------------------

  @Override
  public RelNode copy(RelTraitSet traitSet, List<RelNode> inputs) {
    assert traitSet.equals(this.traitSet);
    assert inputs.equals(this.getInputs());
    return this;
  }

  @Override
  public RelOptCost computeSelfCost(RelOptPlanner planner) {
    // HepRelMetadataProvider is supposed to intercept this
    // and redirect to the real rels.
    throw Util.newInternal("should never get here");
  }

  @Override
  public double getRows() {
    return RelMetadataQuery.getRowCount(currentRel);
  }

  @Override
  protected RelDataType deriveRowType() {
    return currentRel.getRowType();
  }

  @Override
  public boolean isDistinct() {
    return currentRel.isDistinct();
  }

  @Override
  public boolean isKey(BitSet columns) {
    return currentRel.isKey(columns);
  }

  @Override
  protected String computeDigest() {
    return "HepRelVertex(" + currentRel + ")";
  }

  /**
   * Replaces the implementation for this expression with a new one.
   *
   * @param newRel new expression
   */
  void replaceRel(RelNode newRel) {
    currentRel = newRel;
  }

  /**
   * @return current implementation chosen for this vertex
   */
  public RelNode getCurrentRel() {
    return currentRel;
  }
}

// End HepRelVertex.java


<|start_filename|>core/src/main/java/org/eigenbase/relopt/volcano/ChainedPhaseRuleMappingInitializer.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.relopt.volcano;

import java.util.*;

/**
 * ChainedPhaseRuleMappingInitializer is an abstract implementation of {@link
 * VolcanoPlannerPhaseRuleMappingInitializer} that allows additional rules to be
 * layered ontop of those configured by a subordinate
 * VolcanoPlannerPhaseRuleMappingInitializer.
 *
 * @see VolcanoPlannerPhaseRuleMappingInitializer
 */
public abstract class ChainedPhaseRuleMappingInitializer
    implements VolcanoPlannerPhaseRuleMappingInitializer {
  //~ Instance fields --------------------------------------------------------

  private final VolcanoPlannerPhaseRuleMappingInitializer subordinate;

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

  public ChainedPhaseRuleMappingInitializer(
      VolcanoPlannerPhaseRuleMappingInitializer subordinate) {
    this.subordinate = subordinate;
  }

  //~ Methods ----------------------------------------------------------------

  public final void initialize(
      Map<VolcanoPlannerPhase, Set<String>> phaseRuleMap) {
    // Initialize subordinate's mappings.
    subordinate.initialize(phaseRuleMap);

    // Initialize our mappings.
    chainedInitialize(phaseRuleMap);
  }

  /**
   * Extend this method to provide phase-to-rule mappings beyond what is
   * provided by this initializer's subordinate.
   *
   * <p>When this method is called, the map will already be pre-initialized
   * with empty sets for each VolcanoPlannerPhase. Implementations must not
   * return having added or removed keys from the map, although it is safe to
   * temporarily add or remove keys.
   *
   * @param phaseRuleMap the {@link VolcanoPlannerPhase}-rule description map
   * @see VolcanoPlannerPhaseRuleMappingInitializer
   */
  public abstract void chainedInitialize(
      Map<VolcanoPlannerPhase, Set<String>> phaseRuleMap);
}

// End ChainedPhaseRuleMappingInitializer.java


<|start_filename|>core/src/main/java/org/eigenbase/rel/rules/PushProjectIntoMultiJoinRule.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel.rules;

import org.eigenbase.rel.*;
import org.eigenbase.relopt.*;

/**
 * PushProjectIntoMultiJoinRule implements the rule for pushing projection
 * information from a {@link ProjectRel} into the {@link MultiJoinRel} that is
 * input into the {@link ProjectRel}.
 */
public class PushProjectIntoMultiJoinRule extends RelOptRule {
  public static final PushProjectIntoMultiJoinRule INSTANCE =
      new PushProjectIntoMultiJoinRule();

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

  /**
   * Creates a PushProjectIntoMultiJoinRule.
   */
  private PushProjectIntoMultiJoinRule() {
    super(
        operand(
            ProjectRel.class,
            operand(MultiJoinRel.class, any())));
  }

  //~ Methods ----------------------------------------------------------------

  public void onMatch(RelOptRuleCall call) {
    ProjectRel project = call.rel(0);
    MultiJoinRel multiJoin = call.rel(1);

    // if all inputs have their projFields set, then projection information
    // has already been pushed into each input
    boolean allSet = true;
    for (int i = 0; i < multiJoin.getInputs().size(); i++) {
      if (multiJoin.getProjFields().get(i) == null) {
        allSet = false;
        break;
      }
    }
    if (allSet) {
      return;
    }

    // create a new MultiJoinRel that reflects the columns in the projection
    // above the MultiJoinRel
    MultiJoinRel newMultiJoin =
        RelOptUtil.projectMultiJoin(multiJoin, project);
    ProjectRel newProject =
        (ProjectRel) CalcRel.createProject(
            newMultiJoin,
            project.getProjects(),
            project.getRowType().getFieldNames());

    call.transformTo(newProject);
  }
}

// End PushProjectIntoMultiJoinRule.java


<|start_filename|>core/src/main/java/org/eigenbase/rex/RexPermuteInputsShuttle.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rex;

import java.util.ArrayList;
import java.util.List;

import org.eigenbase.rel.RelNode;
import org.eigenbase.reltype.RelDataTypeField;
import org.eigenbase.util.mapping.Mappings;

/**
 * Shuttle which applies a permutation to its input fields.
 *
 * @see RexPermutationShuttle
 */
public class RexPermuteInputsShuttle extends RexShuttle {
  //~ Instance fields --------------------------------------------------------

  private final Mappings.TargetMapping mapping;
  private final List<RelDataTypeField> fields =
      new ArrayList<RelDataTypeField>();

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

  /**
   * Creates a RexPermuteInputsShuttle.
   *
   * <p>The mapping provides at most one target for every source. If a source
   * has no targets and is referenced in the expression,
   * {@link org.eigenbase.util.mapping.Mappings.TargetMapping#getTarget(int)}
   * will give an error. Otherwise the mapping gives a unique target.
   *
   * @param mapping Mapping
   * @param inputs  Input relational expressions
   */
  public RexPermuteInputsShuttle(
      Mappings.TargetMapping mapping,
      RelNode... inputs) {
    this.mapping = mapping;
    for (RelNode input : inputs) {
      fields.addAll(input.getRowType().getFieldList());
    }
  }

  //~ Methods ----------------------------------------------------------------

  @Override
  public RexNode visitInputRef(RexInputRef local) {
    final int index = local.getIndex();
    int target = mapping.getTarget(index);
    return new RexInputRef(
        target,
        local.getType());
  }

  @Override
  public RexNode visitCall(RexCall call) {
    if (call.getOperator() == RexBuilder.GET_OPERATOR) {
      final String name =
          (String) ((RexLiteral) call.getOperands().get(1)).getValue2();
      final int i = lookup(fields, name);
      if (i >= 0) {
        return RexInputRef.of(i, fields);
      }
    }
    return super.visitCall(call);
  }

  private static int lookup(List<RelDataTypeField> fields, String name) {
    for (int i = 0; i < fields.size(); i++) {
      final RelDataTypeField field = fields.get(i);
      if (field.getName().equals(name)) {
        return i;
      }
    }
    return -1;
  }
}

// End RexPermuteInputsShuttle.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/validate/SqlMoniker.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql.validate;

import java.util.List;

import org.eigenbase.sql.*;

/**
 * An interface of an object identifier that represents a SqlIdentifier
 */
public interface SqlMoniker {
  //~ Methods ----------------------------------------------------------------

  /**
   * Returns the type of object referred to by this moniker. Never null.
   */
  SqlMonikerType getType();

  /**
   * Returns the array of component names.
   */
  List<String> getFullyQualifiedNames();

  /**
   * Creates a {@link SqlIdentifier} containing the fully-qualified name.
   */
  SqlIdentifier toIdentifier();

  String id();
}

// End SqlMoniker.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/type/MapSqlType.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql.type;

import org.eigenbase.reltype.RelDataType;
import org.eigenbase.reltype.RelDataTypeFamily;

/**
 * SQL map type.
 */
public class MapSqlType extends AbstractSqlType {
  //~ Instance fields --------------------------------------------------------

  private final RelDataType keyType;
  private final RelDataType valueType;

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

  /**
   * Creates a MapSqlType. This constructor should only be called
   * from a factory method.
   */
  public MapSqlType(
      RelDataType keyType, RelDataType valueType, boolean isNullable) {
    super(SqlTypeName.MAP, isNullable, null);
    assert keyType != null;
    assert valueType != null;
    this.keyType = keyType;
    this.valueType = valueType;
    computeDigest();
  }

  //~ Methods ----------------------------------------------------------------

  @Override
  public RelDataType getValueType() {
    return valueType;
  }

  @Override
  public RelDataType getKeyType() {
    return keyType;
  }

  // implement RelDataTypeImpl
  protected void generateTypeString(StringBuilder sb, boolean withDetail) {
    sb.append("(")
        .append(
            withDetail
                ? keyType.getFullTypeString()
                : keyType.toString())
        .append(", ")
        .append(
            withDetail
                ? valueType.getFullTypeString()
                : valueType.toString())
        .append(") MAP");
  }

  // implement RelDataType
  public RelDataTypeFamily getFamily() {
    return this;
  }
}

// End MapSqlType.java


<|start_filename|>mongodb/src/main/java/net/hydromatic/optiq/impl/mongodb/MongoRel.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.impl.mongodb;

import org.eigenbase.rel.RelNode;
import org.eigenbase.relopt.Convention;
import org.eigenbase.relopt.RelOptTable;
import org.eigenbase.util.Pair;

import java.util.ArrayList;
import java.util.List;

/**
 * Relational expression that uses Mongo calling convention.
 */
public interface MongoRel extends RelNode {
  void implement(Implementor implementor);

  /** Calling convention for relational operations that occur in MongoDB. */
  Convention CONVENTION = new Convention.Impl("MONGO", MongoRel.class);

  /** Callback for the implementation process that converts a tree of
   * {@link MongoRel} nodes into a MongoDB query. */
  class Implementor {
    final List<Pair<String, String>> list =
        new ArrayList<Pair<String, String>>();

    RelOptTable table;
    MongoTable mongoTable;

    public void add(String findOp, String aggOp) {
      list.add(Pair.of(findOp, aggOp));
    }

    public void visitChild(int ordinal, RelNode input) {
      assert ordinal == 0;
      ((MongoRel) input).implement(this);
    }
  }
}

// End MongoRel.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/type/SqlTypeTransform.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql.type;

import org.eigenbase.reltype.*;
import org.eigenbase.sql.*;

/**
 * Strategy to transform one type to another. The transformation is dependent on
 * the implemented strategy object and in the general case is a function of the
 * type and the other operands. Can not be used by itself. Must be used in an
 * object of type {@link SqlTypeTransformCascade}.
 *
 * <p>This class is an example of the {@link
 * org.eigenbase.util.Glossary#STRATEGY_PATTERN strategy pattern}.</p>
 */
public interface SqlTypeTransform {
  //~ Methods ----------------------------------------------------------------

  /**
   * Transforms a type.
   *
   * @param opBinding       call context in which transformation is being
   *                        performed
   * @param typeToTransform type to be transformed, never null
   * @return transformed type, never null
   */
  RelDataType transformType(
      SqlOperatorBinding opBinding,
      RelDataType typeToTransform);
}

// End SqlTypeTransform.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/SqlOperandCountRange.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql;


/**
 * A class that describes how many operands an operator can take.
 */
public interface SqlOperandCountRange {
  /**
   * Returns whether {@code count} is a valid number of operands.
   */
  boolean isValidCount(int count);

  /**
   * Returns an lower bound. -1 if there is no lower bound.
   */
  int getMin();

  /**
   * Returns an upper bound. -1 if there is no upper bound.
   */
  int getMax();

}

// End SqlOperandCountRange.java


<|start_filename|>core/src/main/java/org/eigenbase/sarg/SargMutableEndpoint.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sarg;

import org.eigenbase.reltype.*;
import org.eigenbase.rex.*;

/**
 * SargMutableEndpoint exposes methods for modifying a {@link SargEndpoint}.
 */
public class SargMutableEndpoint extends SargEndpoint {
  //~ Constructors -----------------------------------------------------------

  /**
   * @see SargFactory#newEndpoint
   */
  SargMutableEndpoint(SargFactory factory, RelDataType dataType) {
    super(factory, dataType);
  }

  //~ Methods ----------------------------------------------------------------

  // publicize SargEndpoint
  public void setInfinity(int infinitude) {
    super.setInfinity(infinitude);
  }

  // publicize SargEndpoint
  public void setFinite(
      SargBoundType boundType,
      SargStrictness strictness,
      RexNode coordinate) {
    super.setFinite(boundType, strictness, coordinate);
  }
}

// End SargMutableEndpoint.java


<|start_filename|>spark/src/main/java/net/hydromatic/optiq/impl/spark/SparkRuntime.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.impl.spark;

import net.hydromatic.linq4j.Enumerable;
import net.hydromatic.linq4j.Linq4j;

import net.hydromatic.optiq.DataContext;

import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.FlatMapFunction;

import java.util.*;

/**
 * Runtime utilities for Optiq's Spark adapter. Generated code calls these
 * methods.
 */
public abstract class SparkRuntime {
  private SparkRuntime() {}

  /** Converts an array into an RDD. */
  public static <T> JavaRDD<T> createRdd(JavaSparkContext sc, T[] ts) {
    final List<T> list = Arrays.asList(ts);
    return sc.parallelize(list);
  }

  /** Converts an enumerable into an RDD. */
  public static <T> JavaRDD<T> createRdd(JavaSparkContext sc,
      Enumerable<T> enumerable) {
    final List<T> list = enumerable.toList();
    return sc.parallelize(list);
  }

  /** Converts an RDD into an enumerable. */
  public static <T> Enumerable<T> asEnumerable(JavaRDD<T> rdd) {
    return Linq4j.asEnumerable(rdd.collect());
  }

  /** Returns the Spark context for the current execution.
   *
   * <p>Currently a global variable; maybe later held within {@code root}.</p>
   */
  public static JavaSparkContext getSparkContext(DataContext root) {
    return (JavaSparkContext) SparkHandlerImpl.instance().sparkContext();
  }

  /** Combines linq4j {@link net.hydromatic.linq4j.function.Function}
   * and Spark {@link org.apache.spark.api.java.function.FlatMapFunction}. */
  public abstract static class OptiqFlatMapFunction<T, R>
      extends FlatMapFunction<T, R>
      implements net.hydromatic.linq4j.function.Function {
  }
}

// End SparkRuntime.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/validate/SelectNamespace.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql.validate;

import org.eigenbase.reltype.*;
import org.eigenbase.sql.*;
import org.eigenbase.sql.type.*;

/**
 * Namespace offered by a subquery.
 *
 * @see SelectScope
 * @see SetopNamespace
 */
public class SelectNamespace extends AbstractNamespace {
  //~ Instance fields --------------------------------------------------------

  private final SqlSelect select;

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

  /**
   * Creates a SelectNamespace.
   *
   * @param validator     Validate
   * @param select        Select node
   * @param enclosingNode Enclosing node
   */
  public SelectNamespace(
      SqlValidatorImpl validator,
      SqlSelect select,
      SqlNode enclosingNode) {
    super(validator, enclosingNode);
    this.select = select;
  }

  //~ Methods ----------------------------------------------------------------

  // implement SqlValidatorNamespace, overriding return type
  public SqlSelect getNode() {
    return select;
  }

  public RelDataType validateImpl() {
    validator.validateSelect(select, validator.unknownType);
    return rowType;
  }

  public SqlMonotonicity getMonotonicity(String columnName) {
    final RelDataType rowType = this.getRowTypeSansSystemColumns();
    final int field = SqlTypeUtil.findField(rowType, columnName);
    final SqlNode selectItem =
        validator.getRawSelectScope(select)
            .getExpandedSelectList().get(field);
    return validator.getSelectScope(select).getMonotonicity(selectItem);
  }
}

// End SelectNamespace.java


<|start_filename|>core/src/test/java/net/hydromatic/optiq/examples/foodmart/java/JdbcExample.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.examples.foodmart.java;

import net.hydromatic.optiq.SchemaPlus;
import net.hydromatic.optiq.impl.java.ReflectiveSchema;
import net.hydromatic.optiq.jdbc.OptiqConnection;

import java.sql.*;

/**
 * Example of using Optiq via JDBC.
 *
 * <p>Schema is specified programmatically.</p>
 */
public class JdbcExample {
  public static void main(String[] args) throws Exception {
    new JdbcExample().run();
  }

  public void run() throws ClassNotFoundException, SQLException {
    Class.forName("net.hydromatic.optiq.jdbc.Driver");
    Connection connection =
        DriverManager.getConnection("jdbc:optiq:");
    OptiqConnection optiqConnection =
        connection.unwrap(OptiqConnection.class);
    SchemaPlus rootSchema = optiqConnection.getRootSchema();
    rootSchema.add("hr", new ReflectiveSchema(new Hr()));
    rootSchema.add("foodmart", new ReflectiveSchema(new Foodmart()));
    Statement statement = connection.createStatement();
    ResultSet resultSet =
        statement.executeQuery(
            "select *\n"
            + "from \"foodmart\".\"sales_fact_1997\" as s\n"
            + "join \"hr\".\"emps\" as e\n"
            + "on e.\"empid\" = s.\"cust_id\"");
    final StringBuilder buf = new StringBuilder();
    while (resultSet.next()) {
      int n = resultSet.getMetaData().getColumnCount();
      for (int i = 1; i <= n; i++) {
        buf.append(i > 1 ? "; " : "")
            .append(resultSet.getMetaData().getColumnLabel(i))
            .append("=")
            .append(resultSet.getObject(i));
      }
      System.out.println(buf.toString());
      buf.setLength(0);
    }
    resultSet.close();
    statement.close();
    connection.close();
  }

  public static class Hr {
    public final Employee[] emps = {
      new Employee(100, "Bill"),
      new Employee(200, "Eric"),
      new Employee(150, "Sebastian"),
    };
  }

  public static class Employee {
    public final int empid;
    public final String name;

    public Employee(int empid, String name) {
      this.empid = empid;
      this.name = name;
    }
  }

  public static class Foodmart {
    public final SalesFact[] sales_fact_1997 = {
      new SalesFact(100, 10),
      new SalesFact(150, 20),
    };
  }

  public static class SalesFact {
    public final int cust_id;
    public final int prod_id;

    public SalesFact(int cust_id, int prod_id) {
      this.cust_id = cust_id;
      this.prod_id = prod_id;
    }
  }
}

// End JdbcExample.java


<|start_filename|>core/src/main/java/org/eigenbase/rel/CalcRelBase.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel;

import java.util.*;

import org.eigenbase.rel.metadata.*;
import org.eigenbase.relopt.*;
import org.eigenbase.reltype.*;
import org.eigenbase.rex.*;

import com.google.common.collect.ImmutableList;

/**
 * <code>CalcRelBase</code> is an abstract base class for implementations of
 * {@link CalcRel}.
 */
public abstract class CalcRelBase extends SingleRel {
  //~ Instance fields --------------------------------------------------------

  protected final RexProgram program;
  private final ImmutableList<RelCollation> collationList;

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

  protected CalcRelBase(
      RelOptCluster cluster,
      RelTraitSet traits,
      RelNode child,
      RelDataType rowType,
      RexProgram program,
      List<RelCollation> collationList) {
    super(cluster, traits, child);
    this.rowType = rowType;
    this.program = program;
    this.collationList = ImmutableList.copyOf(collationList);
    assert isValid(true);
  }

  //~ Methods ----------------------------------------------------------------

  @Override
  public final CalcRelBase copy(RelTraitSet traitSet, List<RelNode> inputs) {
    return copy(traitSet, sole(inputs), program, collationList);
  }

  /**
   * Creates a copy of this {@code CalcRelBase}.
   */
  public abstract CalcRelBase copy(
      RelTraitSet traitSet,
      RelNode child,
      RexProgram program,
      List<RelCollation> collationList);

  public boolean isValid(boolean fail) {
    if (!RelOptUtil.equal(
        "program's input type",
        program.getInputRowType(),
        "child's output type",
        getChild().getRowType(),
        fail)) {
      return false;
    }
    if (!RelOptUtil.equal(
        "rowtype of program",
        program.getOutputRowType(),
        "declared rowtype of rel",
        rowType,
        fail)) {
      return false;
    }
    if (!program.isValid(fail)) {
      return false;
    }
    if (!program.isNormalized(fail, getCluster().getRexBuilder())) {
      return false;
    }
    if (!RelCollationImpl.isValid(
        getRowType(),
        collationList,
        fail)) {
      return false;
    }
    return true;
  }

  public RexProgram getProgram() {
    return program;
  }

  public double getRows() {
    return FilterRel.estimateFilteredRows(
        getChild(),
        program);
  }

  public List<RelCollation> getCollationList() {
    return collationList;
  }

  public RelOptCost computeSelfCost(RelOptPlanner planner) {
    double dRows = RelMetadataQuery.getRowCount(this);
    double dCpu =
        RelMetadataQuery.getRowCount(getChild())
            * program.getExprCount();
    double dIo = 0;
    return planner.getCostFactory().makeCost(dRows, dCpu, dIo);
  }

  public RelWriter explainTerms(RelWriter pw) {
    return program.explainCalc(super.explainTerms(pw));
  }
}

// End CalcRelBase.java


<|start_filename|>core/src/main/java/net/hydromatic/optiq/impl/java/JavaTypeFactory.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.impl.java;

import org.eigenbase.reltype.RelDataType;
import org.eigenbase.reltype.RelDataTypeFactory;

import java.lang.reflect.Type;
import java.util.List;

/**
 * Type factory that can register Java classes as record types.
 */
public interface JavaTypeFactory extends RelDataTypeFactory {
  /**
   * Creates a record type based upon the public fields of a Java class.
   *
   * @param clazz Java class
   * @return Record type that remembers its Java class
   */
  RelDataType createStructType(Class clazz);

  /**
   * Creates a type, deducing whether a record, scalar or primitive type
   * is needed.
   *
   * @param type Java type, such as a {@link Class}
   * @return Record or scalar type
   */
  RelDataType createType(Type type);

  Type getJavaClass(RelDataType type);

  /** Creates a synthetic Java class whose fields have the given Java
   * types. */
  Type createSyntheticType(List<Type> types);

  /** Converts a type in Java format to a SQL-oriented type. */
  RelDataType toSql(RelDataType type);
}

// End JavaTypeFactory.java


<|start_filename|>core/src/main/java/net/hydromatic/optiq/impl/java/AbstractQueryableTable.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.impl.java;

import net.hydromatic.linq4j.expressions.Expression;

import net.hydromatic.optiq.*;
import net.hydromatic.optiq.impl.AbstractTable;

import java.lang.reflect.Type;

/**
 * Abstract base class for implementing {@link net.hydromatic.optiq.Table}.
 */
public abstract class AbstractQueryableTable extends AbstractTable
    implements QueryableTable {
  protected final Type elementType;

  protected AbstractQueryableTable(Type elementType) {
    super();
    this.elementType = elementType;
  }

  public Type getElementType() {
    return elementType;
  }

  public Expression getExpression(SchemaPlus schema, String tableName,
      Class clazz) {
    return Schemas.tableExpression(schema, elementType, tableName, clazz);
  }
}

// End AbstractQueryableTable.java


<|start_filename|>core/src/main/java/org/eigenbase/rel/rules/PushFilterPastJoinRule.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel.rules;

import java.util.*;

import org.eigenbase.rel.*;
import org.eigenbase.relopt.*;
import org.eigenbase.rex.*;

import com.google.common.collect.ImmutableList;

/**
 * PushFilterPastJoinRule implements the rule for pushing filters above and
 * within a join node into the join node and/or its children nodes.
 */
public abstract class PushFilterPastJoinRule extends RelOptRule {
  public static final PushFilterPastJoinRule FILTER_ON_JOIN =
      new PushFilterPastJoinRule(
          operand(
              FilterRel.class,
              operand(JoinRel.class, any())),
          "PushFilterPastJoinRule:filter") {
        @Override
        public void onMatch(RelOptRuleCall call) {
          FilterRel filter = call.rel(0);
          JoinRel join = call.rel(1);
          perform(call, filter, join);
        }
      };

  public static final PushFilterPastJoinRule JOIN =
      new PushFilterPastJoinRule(
          operand(JoinRel.class, any()),
          "PushFilterPastJoinRule:no-filter") {
        @Override
        public void onMatch(RelOptRuleCall call) {
          JoinRel join = call.rel(0);
          perform(call, null, join);
        }
      };

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

  /**
   * Creates a PushFilterPastJoinRule with an explicit root operand.
   */
  private PushFilterPastJoinRule(
      RelOptRuleOperand operand,
      String id) {
    super(operand, "PushFilterRule: " + id);
  }

  //~ Methods ----------------------------------------------------------------

  protected void perform(RelOptRuleCall call, FilterRel filter,
      JoinRelBase join) {
    final List<RexNode> joinFilters =
        RelOptUtil.conjunctions(join.getCondition());

    if (filter == null) {
      // There is only the joinRel
      // make sure it does not match a cartesian product joinRel
      // (with "true" condition) otherwise this rule will be applied
      // again on the new cartesian product joinRel.
      boolean onlyTrueFilter = true;
      for (RexNode joinFilter : joinFilters) {
        if (!joinFilter.isAlwaysTrue()) {
          onlyTrueFilter = false;
          break;
        }
      }

      if (onlyTrueFilter) {
        return;
      }
    }

    final List<RexNode> aboveFilters =
        filter != null
            ? RelOptUtil.conjunctions(filter.getCondition())
            : ImmutableList.<RexNode>of();

    List<RexNode> leftFilters = new ArrayList<RexNode>();
    List<RexNode> rightFilters = new ArrayList<RexNode>();

    // TODO - add logic to derive additional filters.  E.g., from
    // (t1.a = 1 AND t2.a = 2) OR (t1.b = 3 AND t2.b = 4), you can
    // derive table filters:
    // (t1.a = 1 OR t1.b = 3)
    // (t2.a = 2 OR t2.b = 4)

    // Try to push down above filters. These are typically where clause
    // filters. They can be pushed down if they are not on the NULL
    // generating side.
    boolean filterPushed = false;
    if (RelOptUtil.classifyFilters(
        join,
        aboveFilters,
        join.getJoinType() == JoinRelType.INNER,
        !join.getJoinType().generatesNullsOnLeft(),
        !join.getJoinType().generatesNullsOnRight(),
        joinFilters,
        leftFilters,
        rightFilters)) {
      filterPushed = true;
    }

    // Try to push down filters in ON clause. A ON clause filter can only be
    // pushed down if it does not affect the non-matching set, i.e. it is
    // not on the side which is preserved.
    if (RelOptUtil.classifyFilters(
        join,
        joinFilters,
        false,
        !join.getJoinType().generatesNullsOnRight(),
        !join.getJoinType().generatesNullsOnLeft(),
        joinFilters,
        leftFilters,
        rightFilters)) {
      filterPushed = true;
    }

    if (!filterPushed) {
      return;
    }

    // create FilterRels on top of the children if any filters were
    // pushed to them
    RexBuilder rexBuilder = join.getCluster().getRexBuilder();
    RelNode leftRel =
        createFilterOnRel(
            rexBuilder,
            join.getLeft(),
            leftFilters);
    RelNode rightRel =
        createFilterOnRel(
            rexBuilder,
            join.getRight(),
            rightFilters);

    // create the new join node referencing the new children and
    // containing its new join filters (if there are any)
    RexNode joinFilter;

    if (joinFilters.size() == 0) {
      // if nothing actually got pushed and there is nothing leftover,
      // then this rule is a no-op
      if ((leftFilters.size() == 0) && (rightFilters.size() == 0)) {
        return;
      }
      joinFilter = rexBuilder.makeLiteral(true);
    } else {
      joinFilter =
          RexUtil.composeConjunction(rexBuilder, joinFilters, true);
    }
    RelNode newJoinRel = join.copy(
      join.getCluster().traitSetOf(Convention.NONE),
      joinFilter,
      leftRel,
      rightRel,
      join.getJoinType());
    call.getPlanner().onCopy(join, newJoinRel);

    // create a FilterRel on top of the join if needed
    RelNode newRel =
        createFilterOnRel(rexBuilder, newJoinRel, aboveFilters);

    call.transformTo(newRel);
  }

  /**
   * If the filter list passed in is non-empty, creates a FilterRel on top of
   * the existing RelNode; otherwise, just returns the RelNode
   *
   * @param rexBuilder rex builder
   * @param rel        the RelNode that the filter will be put on top of
   * @param filters    list of filters
   * @return new RelNode or existing one if no filters
   */
  private RelNode createFilterOnRel(
      RexBuilder rexBuilder,
      RelNode rel,
      List<RexNode> filters) {
    RexNode andFilters =
        RexUtil.composeConjunction(rexBuilder, filters, false);
    if (andFilters.isAlwaysTrue()) {
      return rel;
    }
    return CalcRel.createFilter(rel, andFilters);
  }
}

// End PushFilterPastJoinRule.java


<|start_filename|>core/src/main/java/org/eigenbase/relopt/RelOptMaterialization.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.relopt;

import org.eigenbase.rel.*;
import org.eigenbase.rel.rules.PullUpProjectsAboveJoinRule;
import org.eigenbase.relopt.hep.HepPlanner;
import org.eigenbase.relopt.hep.HepProgram;
import org.eigenbase.sql.SqlExplainLevel;
import org.eigenbase.util.Util;
import org.eigenbase.util.mapping.Mappings;

import net.hydromatic.optiq.Table;
import net.hydromatic.optiq.impl.StarTable;

/**
 * Records that a particular query is materialized by a particular table.
 */
public class RelOptMaterialization {
  public final RelNode tableRel;
  public final RelOptTable starRelOptTable;
  public final StarTable starTable;
  public final RelOptTable table;
  public final RelNode queryRel;

  /**
   * Creates a RelOptMaterialization.
   */
  public RelOptMaterialization(RelNode tableRel, RelNode queryRel,
      RelOptTable starRelOptTable) {
    this.tableRel = tableRel;
    this.starRelOptTable = starRelOptTable;
    if (starRelOptTable == null) {
      this.starTable = null;
    } else {
      this.starTable = starRelOptTable.unwrap(StarTable.class);
      assert starTable != null;
    }
    this.table = tableRel.getTable();
    this.queryRel = queryRel;
  }

  /**
   * Converts a relational expression to one that uses a
   * {@link net.hydromatic.optiq.impl.StarTable}.
   * The relational expression is already in leaf-join-form, per
   * {@link #toLeafJoinForm(org.eigenbase.rel.RelNode)}.
   */
  public static RelNode tryUseStar(RelNode rel,
      final RelOptTable starRelOptTable) {
    final StarTable starTable = starRelOptTable.unwrap(StarTable.class);
    assert starTable != null;
    return rel.accept(
        new RelShuttleImpl() {
          @Override
          public RelNode visit(TableAccessRelBase scan) {
            RelOptTable relOptTable = scan.getTable();
            final Table table = relOptTable.unwrap(Table.class);
            if (table.equals(starTable.tables.get(0))) {
              Mappings.TargetMapping mapping =
                  Mappings.createShiftMapping(
                      starRelOptTable.getRowType().getFieldCount(),
                      0, 0, relOptTable.getRowType().getFieldCount());

              return CalcRel.createProject(
                  new TableAccessRel(scan.getCluster(), starRelOptTable),
                  Mappings.asList(mapping.inverse()));
            }
            return scan;
          }

          @Override
          public RelNode visit(JoinRel join) {
            for (;;) {
              RelNode rel = super.visit(join);
              if (rel == join || !(rel instanceof JoinRel)) {
                return rel;
              }
              join = (JoinRel) rel;
              final RelNode left = join.getLeft();
              final RelNode right = join.getRight();
              try {
                if (left instanceof TableAccessRelBase
                    && right instanceof TableAccessRelBase) {
                  match(left, null, right, null, join.getCluster());
                }
                if (isProjectedTable(left)
                    && right instanceof TableAccessRelBase) {
                  final ProjectRel leftProject = (ProjectRel) left;
                  match(leftProject.getChild(), leftProject.getMapping(), right,
                      null, join.getCluster());
                }
                if (left instanceof TableAccessRelBase
                    && isProjectedTable(right)) {
                  final ProjectRel rightProject = (ProjectRel) right;
                  match(left, null, rightProject.getChild(),
                      rightProject.getMapping(), join.getCluster());
                }
                if (isProjectedTable(left)
                    && isProjectedTable(right)) {
                  final ProjectRel leftProject = (ProjectRel) left;
                  final ProjectRel rightProject = (ProjectRel) right;
                  match(leftProject.getChild(), leftProject.getMapping(),
                      rightProject.getChild(), rightProject.getMapping(),
                      join.getCluster());
                }
              } catch (Util.FoundOne e) {
                return (RelNode) e.getNode();
              }
            }
          }

          private boolean isProjectedTable(RelNode rel) {
            return rel instanceof ProjectRel
                && ((ProjectRel) rel).isMapping()
                && ((ProjectRel) rel).getChild() instanceof TableAccessRelBase;
          }

          /** Throws a {@link org.eigenbase.util.Util.FoundOne} containing a
           * {@link org.eigenbase.rel.TableAccessRel} on success.
           * (Yes, an exception for normal operation.) */
          private void match(RelNode left, Mappings.TargetMapping leftMapping,
              RelNode right, Mappings.TargetMapping rightMapping,
              RelOptCluster cluster) {
            if (leftMapping == null) {
              leftMapping =
                  Mappings.createIdentity(left.getRowType().getFieldCount());
            }
            if (rightMapping == null) {
              rightMapping =
                  Mappings.createIdentity(right.getRowType().getFieldCount());
            }
            final RelOptTable leftRelOptTable = left.getTable();
            final Table leftTable = leftRelOptTable.unwrap(Table.class);
            final RelOptTable rightRelOptTable = right.getTable();
            final Table rightTable = rightRelOptTable.unwrap(Table.class);
            if (leftTable instanceof StarTable
                && ((StarTable) leftTable).tables.contains(rightTable)) {
              System.out.println("left: " + leftMapping);
              System.out.println("right: " + rightMapping);
              Mappings.TargetMapping mapping =
                  Mappings.merge(leftMapping,
                      Mappings.offset(rightMapping,
                          ((StarTable) leftTable).columnOffset(rightTable),
                          leftRelOptTable.getRowType().getFieldCount()));
              throw new Util.FoundOne(
                  CalcRel.createProject(
                      new TableAccessRel(cluster, leftRelOptTable),
                      Mappings.asList(mapping.inverse())));
            }
            if (rightTable instanceof StarTable
                && ((StarTable) rightTable).tables.contains(leftTable)) {
              assert false; // TODO:
              Mappings.TargetMapping mapping =
                  Mappings.append(leftMapping, rightMapping);
              throw new Util.FoundOne(
                  CalcRel.createProject(
                      new TableAccessRel(cluster, rightRelOptTable),
                      Mappings.asList(mapping.inverse())));
            }
          }
        });
  }

  /**
   * Converts a relational expression to a form where
   * {@link org.eigenbase.rel.JoinRel}s are
   * as close to leaves as possible.
   */
  public static RelNode toLeafJoinForm(RelNode rel) {
    HepProgram program = HepProgram.builder()
        .addRuleInstance(PullUpProjectsAboveJoinRule.RIGHT_PROJECT)
        .addRuleInstance(PullUpProjectsAboveJoinRule.LEFT_PROJECT)
        .build();
    final HepPlanner planner =
        new HepPlanner(program);
    planner.setRoot(rel);
    System.out.println(
        RelOptUtil.dumpPlan(
            "before", rel, false, SqlExplainLevel.DIGEST_ATTRIBUTES));
    final RelNode rel2 = planner.findBestExp();
    System.out.println(
        RelOptUtil.dumpPlan(
            "after", rel2, false, SqlExplainLevel.DIGEST_ATTRIBUTES));
    return rel2;
  }
}

// End RelOptMaterialization.java


<|start_filename|>core/src/main/java/net/hydromatic/optiq/prepare/RelOptTableImpl.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.prepare;

import net.hydromatic.linq4j.expressions.Expression;

import net.hydromatic.optiq.QueryableTable;
import net.hydromatic.optiq.Table;
import net.hydromatic.optiq.TranslatableTable;
import net.hydromatic.optiq.jdbc.OptiqSchema;
import net.hydromatic.optiq.rules.java.EnumerableConvention;
import net.hydromatic.optiq.rules.java.JavaRules;

import org.eigenbase.rel.RelCollation;
import org.eigenbase.rel.RelNode;
import org.eigenbase.relopt.RelOptCluster;
import org.eigenbase.relopt.RelOptSchema;
import org.eigenbase.reltype.RelDataType;
import org.eigenbase.sql.SqlAccessType;
import org.eigenbase.sql.validate.SqlMonotonicity;

import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.collect.ImmutableList;

import java.lang.reflect.Type;
import java.util.BitSet;
import java.util.Collections;
import java.util.List;

/**
 * Implementation of {@link org.eigenbase.relopt.RelOptTable}.
 */
public class RelOptTableImpl implements Prepare.PreparingTable {
  private final RelOptSchema schema;
  private final RelDataType rowType;
  private final Table table;
  private final Function<Class, Expression> expressionFunction;
  private final ImmutableList<String> names;

  private RelOptTableImpl(
      RelOptSchema schema,
      RelDataType rowType,
      List<String> names,
      Table table,
      Function<Class, Expression> expressionFunction) {
    this.schema = schema;
    this.rowType = rowType;
    this.names = ImmutableList.copyOf(names);
    this.table = table; // may be null
    this.expressionFunction = expressionFunction;
    assert expressionFunction != null;
    assert rowType != null;
  }

  public static RelOptTableImpl create(
      RelOptSchema schema,
      RelDataType rowType,
      List<String> names,
      Expression expression) {
    //noinspection unchecked
    final Function<Class, Expression> expressionFunction =
        (Function) Functions.constant(expression);
    return new RelOptTableImpl(schema, rowType, names, null,
        expressionFunction);
  }

  public static RelOptTableImpl create(
      RelOptSchema schema,
      RelDataType rowType,
      final OptiqSchema.TableEntry tableEntry) {
    Function<Class, Expression> expressionFunction;
    if (tableEntry.getTable() instanceof QueryableTable) {
      final QueryableTable table = (QueryableTable) tableEntry.getTable();
      expressionFunction = new Function<Class, Expression>() {
        public Expression apply(Class clazz) {
          return table.getExpression(tableEntry.schema.plus(),
              tableEntry.name, clazz);
        }
      };
    } else {
      expressionFunction = new Function<Class, Expression>() {
        public Expression apply(Class input) {
          throw new UnsupportedOperationException();
        }
      };
    }
    return new RelOptTableImpl(schema, rowType, tableEntry.path(),
      tableEntry.getTable(), expressionFunction);
  }

  public static RelOptTableImpl create(
      RelOptSchema schema,
      RelDataType rowType,
      TranslatableTable table) {
    final Function<Class, Expression> expressionFunction =
        new Function<Class, Expression>() {
          public Expression apply(Class input) {
            throw new UnsupportedOperationException();
          }
        };
    return new RelOptTableImpl(schema, rowType, ImmutableList.<String>of(),
        table, expressionFunction);
  }

  public <T> T unwrap(Class<T> clazz) {
    if (clazz.isInstance(this)) {
      return clazz.cast(this);
    }
    if (clazz.isInstance(table)) {
      return clazz.cast(table);
    }
    return null;
  }

  public Expression getExpression(Class clazz) {
    return expressionFunction.apply(clazz);
  }

  public double getRowCount() {
    if (table != null) {
      final Double rowCount = table.getStatistic().getRowCount();
      if (rowCount != null) {
        return rowCount;
      }
    }
    return 100d;
  }

  public RelOptSchema getRelOptSchema() {
    return schema;
  }

  public RelNode toRel(ToRelContext context) {
    if (table instanceof TranslatableTable) {
      return ((TranslatableTable) table).toRel(context, this);
    }
    RelOptCluster cluster = context.getCluster();
    Class elementType = deduceElementType();
    return new JavaRules.EnumerableTableAccessRel(
        cluster, cluster.traitSetOf(EnumerableConvention.INSTANCE),
        this, elementType);
  }

  private Class deduceElementType() {
    if (table instanceof QueryableTable) {
      final QueryableTable queryableTable = (QueryableTable) table;
      final Type type = queryableTable.getElementType();
      if (type instanceof Class) {
        return (Class) type;
      } else {
        return Object[].class;
      }
    } else {
      return Object.class;
    }
  }

  public List<RelCollation> getCollationList() {
    return Collections.emptyList();
  }

  public boolean isKey(BitSet columns) {
    return table.getStatistic().isKey(columns);
  }

  public RelDataType getRowType() {
    return rowType;
  }

  public List<String> getQualifiedName() {
    return names;
  }

  public SqlMonotonicity getMonotonicity(String columnName) {
    return SqlMonotonicity.NOT_MONOTONIC;
  }

  public SqlAccessType getAllowedAccess() {
    return SqlAccessType.ALL;
  }
}

// End RelOptTableImpl.java


<|start_filename|>core/src/main/java/net/hydromatic/optiq/model/JsonTable.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.model;

import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;

import java.util.ArrayList;
import java.util.List;

/**
 * Table schema element.
 *
 * @see JsonRoot Description of schema elements
 */
@JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,
    property = "type",
    defaultImpl = JsonCustomTable.class)
@JsonSubTypes({
    @JsonSubTypes.Type(value = JsonCustomTable.class, name = "custom"),
    @JsonSubTypes.Type(value = JsonView.class, name = "view") })
public abstract class JsonTable {
  public String name;
  public final List<JsonColumn> columns = new ArrayList<JsonColumn>();

  public abstract void accept(ModelHandler handler);
}

// End JsonTable.java


<|start_filename|>core/src/main/java/org/eigenbase/rel/rules/ProjectToCalcRule.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel.rules;

import org.eigenbase.rel.*;
import org.eigenbase.relopt.*;
import org.eigenbase.reltype.*;
import org.eigenbase.rex.*;

import com.google.common.collect.ImmutableList;

/**
 * Rule to convert a {@link ProjectRel} to a {@link CalcRel}
 *
 * <p>The rule does not fire if the child is a {@link ProjectRel}, {@link
 * FilterRel} or {@link CalcRel}. If it did, then the same {@link CalcRel} would
 * be formed via several transformation paths, which is a waste of effort.</p>
 *
 * @see FilterToCalcRule
 */
public class ProjectToCalcRule extends RelOptRule {
  //~ Static fields/initializers ---------------------------------------------

  public static final ProjectToCalcRule INSTANCE = new ProjectToCalcRule();

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

  private ProjectToCalcRule() {
    super(operand(ProjectRel.class, any()));
  }

  //~ Methods ----------------------------------------------------------------

  public void onMatch(RelOptRuleCall call) {
    final ProjectRel project = call.rel(0);
    final RelNode child = project.getChild();
    final RelDataType rowType = project.getRowType();
    final RexProgram program =
        RexProgram.create(
            child.getRowType(),
            project.getProjects(),
            null,
            project.getRowType(),
            project.getCluster().getRexBuilder());
    final CalcRel calc =
        new CalcRel(
            project.getCluster(),
            project.getTraitSet(),
            child,
            rowType,
            program,
            ImmutableList.<RelCollation>of());
    call.transformTo(calc);
  }
}

// End ProjectToCalcRule.java


<|start_filename|>core/src/main/java/net/hydromatic/optiq/impl/AbstractTable.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.impl;

import net.hydromatic.optiq.*;

/**
 * Abstract base class for implementing {@link Table}.
 */
public abstract class AbstractTable implements Table {
  protected AbstractTable() {
  }

  // Default implementation. Override if you have statistics.
  public Statistic getStatistic() {
    return Statistics.UNKNOWN;
  }

  public Schema.TableType getJdbcTableType() {
    return Schema.TableType.TABLE;
  }
}

// End AbstractTable.java


<|start_filename|>core/src/main/java/net/hydromatic/optiq/QueryableTable.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq;

import net.hydromatic.linq4j.QueryProvider;
import net.hydromatic.linq4j.Queryable;
import net.hydromatic.linq4j.expressions.Expression;

import java.lang.reflect.Type;

/**
 * Extension to {@link Table} that can translate itself to a {@link Queryable}.
 */
public interface QueryableTable extends Table {
  /** Converts this table into a {@link Queryable}. */
  <T> Queryable<T> asQueryable(QueryProvider queryProvider, SchemaPlus schema,
      String tableName);

  /** Returns the element type of the collection that will implement this
   * table. */
  Type getElementType();

  /** Generates an expression with which this table can be referenced in
   * generated code.
   *
   * @param schema Schema
   * @param tableName Table name (unique within schema)
   * @param clazz The desired collection class; for example {@code Queryable}.
   */
  Expression getExpression(SchemaPlus schema, String tableName, Class clazz);
}

// End QueryableTable.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/type/SqlReturnTypeInference.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql.type;

import org.eigenbase.reltype.*;
import org.eigenbase.sql.*;

/**
 * Strategy interface to infer the type of an operator call from the type of the
 * operands.
 *
 * <p>This interface is an example of the {@link
 * org.eigenbase.util.Glossary#STRATEGY_PATTERN strategy pattern}. This makes
 * sense because many operators have similar, straightforward strategies, such
 * as to take the type of the first operand.</p>
 */
public interface SqlReturnTypeInference {
  //~ Methods ----------------------------------------------------------------

  /**
   * Infers the return type of a call to an {@link SqlOperator}.
   *
   * @param opBinding description of operator binding
   * @return inferred type; may be null
   */
  RelDataType inferReturnType(
      SqlOperatorBinding opBinding);
}

// End SqlReturnTypeInference.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/validate/SqlMonotonicity.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql.validate;

/**
 * Enumeration of types of monotonicity.
 */
public enum SqlMonotonicity {
  STRICTLY_INCREASING,
  INCREASING,
  STRICTLY_DECREASING,
  DECREASING,
  CONSTANT,
  /**
   * Catch-all value for expressions that have some monotonic properties.
   * Maybe it isn't known whether the expression is increasing or decreasing;
   * or maybe the value is neither increasing nor decreasing but the value
   * never repeats.
   */
  MONOTONIC,
  NOT_MONOTONIC;

  /**
   * If this is a strict monotonicity (StrictlyIncreasing, StrictlyDecreasing)
   * returns the non-strict equivalent (Increasing, Decreasing).
   *
   * @return non-strict equivalent monotonicity
   */
  public SqlMonotonicity unstrict() {
    switch (this) {
    case STRICTLY_INCREASING:
      return INCREASING;
    case STRICTLY_DECREASING:
      return DECREASING;
    default:
      return this;
    }
  }

  /**
   * Returns the reverse monotonicity.
   *
   * @return reverse monotonicity
   */
  public SqlMonotonicity reverse() {
    switch (this) {
    case STRICTLY_INCREASING:
      return STRICTLY_DECREASING;
    case INCREASING:
      return DECREASING;
    case STRICTLY_DECREASING:
      return STRICTLY_INCREASING;
    case DECREASING:
      return INCREASING;
    default:
      return this;
    }
  }

  /**
   * Whether values of this monotonicity are decreasing. That is, if a value
   * at a given point in a sequence is X, no point later in the sequence will
   * have a value greater than X.
   *
   * @return whether values are decreasing
   */
  public boolean isDecreasing() {
    switch (this) {
    case STRICTLY_DECREASING:
    case DECREASING:
      return true;
    default:
      return false;
    }
  }

  /**
   * Returns whether values of this monotonicity may ever repeat after moving
   * to another value: true for {@link #NOT_MONOTONIC} and {@link #CONSTANT},
   * false otherwise.
   *
   * <p>If a column is known not to repeat, a sort on that column can make
   * progress before all of the input has been seen.
   *
   * @return whether values repeat
   */
  public boolean mayRepeat() {
    switch (this) {
    case NOT_MONOTONIC:
    case CONSTANT:
      return true;
    default:
      return false;
    }
  }
}

// End SqlMonotonicity.java


<|start_filename|>core/src/main/java/org/eigenbase/util/IdentityHashSet.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.util;

import java.util.*;

/**
 * Set based on object identity, like {@link IdentityHashMap}.
 */
public class IdentityHashSet<E> extends AbstractSet<E> implements Set<E> {
  private final Map<E, Object> map;

  // Dummy value to associate with an Object in the backing Map
  private static final Object PRESENT = new Object();

  /**
   * Creates an empty IdentityHashSet.
   */
  public IdentityHashSet() {
    map = new IdentityHashMap<E, Object>();
  }

  /**
   * Creates an IdentityHashSet containing the elements of the specified
   * collection.
   *
   * @param c the collection whose elements are to be placed into this set
   */
  public IdentityHashSet(Collection<? extends E> c) {
    map = new IdentityHashMap<E, Object>(Math.max(c.size() * 2 + 1, 16));
    addAll(c);
  }

  public int size() {
    return map.size();
  }

  public boolean isEmpty() {
    return map.isEmpty();
  }

  public boolean contains(Object o) {
    //noinspection SuspiciousMethodCalls
    return map.containsKey(o);
  }

  public Iterator<E> iterator() {
    return map.keySet().iterator();
  }

  public Object[] toArray() {
    return map.keySet().toArray();
  }

  public <T> T[] toArray(T[] a) {
    //noinspection SuspiciousToArrayCall
    return map.keySet().toArray(a);
  }

  public boolean add(E e) {
    return map.put(e, PRESENT) != null;
  }

  public boolean remove(Object o) {
    return map.remove(o) != null;
  }

  public void clear() {
    map.clear();
  }
}

// End IdentityHashSet.java


<|start_filename|>core/src/main/java/org/eigenbase/relopt/MulticastRelOptListener.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.relopt;

import java.util.*;

/**
 * MulticastRelOptListener implements the {@link RelOptListener} interface by
 * forwarding events on to a collection of other listeners.
 */
public class MulticastRelOptListener implements RelOptListener {
  //~ Instance fields --------------------------------------------------------

  private final List<RelOptListener> listeners;

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

  /**
   * Creates a new empty multicast listener.
   */
  public MulticastRelOptListener() {
    listeners = new ArrayList<RelOptListener>();
  }

  //~ Methods ----------------------------------------------------------------

  /**
   * Adds a listener which will receive multicast events.
   *
   * @param listener listener to add
   */
  public void addListener(RelOptListener listener) {
    listeners.add(listener);
  }

  // implement RelOptListener
  public void relEquivalenceFound(RelEquivalenceEvent event) {
    for (RelOptListener listener : listeners) {
      listener.relEquivalenceFound(event);
    }
  }

  // implement RelOptListener
  public void ruleAttempted(RuleAttemptedEvent event) {
    for (RelOptListener listener : listeners) {
      listener.ruleAttempted(event);
    }
  }

  // implement RelOptListener
  public void ruleProductionSucceeded(RuleProductionEvent event) {
    for (RelOptListener listener : listeners) {
      listener.ruleProductionSucceeded(event);
    }
  }

  // implement RelOptListener
  public void relChosen(RelChosenEvent event) {
    for (RelOptListener listener : listeners) {
      listener.relChosen(event);
    }
  }

  // implement RelOptListener
  public void relDiscarded(RelDiscardedEvent event) {
    for (RelOptListener listener : listeners) {
      listener.relDiscarded(event);
    }
  }
}

// End MulticastRelOptListener.java


<|start_filename|>core/src/main/java/org/eigenbase/sql2rel/SqlNodeToRexConverter.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql2rel;

import org.eigenbase.rex.*;
import org.eigenbase.sql.*;

/**
 * Converts expressions from {@link SqlNode} to {@link RexNode}.
 */
public interface SqlNodeToRexConverter {
  //~ Methods ----------------------------------------------------------------

  /**
   * Converts a {@link SqlCall} to a {@link RexNode} expression.
   */
  RexNode convertCall(
      SqlRexContext cx,
      SqlCall call);

  /**
   * Converts a {@link SqlLiteral SQL literal} to a {@link RexLiteral REX
   * literal}.
   *
   * <p>The result is {@link RexNode}, not {@link RexLiteral} because if the
   * literal is NULL (or the boolean Unknown value), we make a <code>CAST(NULL
   * AS type)</code> expression.
   */
  RexNode convertLiteral(
      SqlRexContext cx,
      SqlLiteral literal);

  /**
   * Converts a {@link SqlIntervalQualifier SQL Interval Qualifier} to a
   * {@link RexLiteral REX literal}.
   */
  RexLiteral convertInterval(
      SqlRexContext cx,
      SqlIntervalQualifier intervalQualifier);
}

// End SqlNodeToRexConverter.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/type/SqlOperandTypeInference.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql.type;

import org.eigenbase.reltype.*;
import org.eigenbase.sql.*;

/**
 * Strategy to infer unknown types of the operands of an operator call.
 */
public interface SqlOperandTypeInference {
  //~ Methods ----------------------------------------------------------------

  /**
   * Infers any unknown operand types.
   *
   * @param callBinding  description of the call being analyzed
   * @param returnType   the type known or inferred for the result of the call
   * @param operandTypes receives the inferred types for all operands
   */
  void inferOperandTypes(
      SqlCallBinding callBinding,
      RelDataType returnType,
      RelDataType[] operandTypes);
}

// End SqlOperandTypeInference.java


<|start_filename|>core/src/main/java/net/hydromatic/optiq/runtime/Spaces.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.runtime;

import java.io.*;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;

/** Utilities for creating strings of spaces. */
public class Spaces {
  /** It doesn't look like this list is ever updated. But it is - when a call to
   * to {@link SpaceList#get} causes an {@link IndexOutOfBoundsException}. */
  @SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
  private static final List<String> SPACE_LIST = new SpaceList();

  /** The longest possible string of spaces. Fine as long as you don't try
   * to print it.
   *
   * <p>Use with {@link StringBuilder#append(CharSequence, int, int)} to
   * append spaces without doing memory allocation.</p>
   */
  public static final CharSequence MAX = sequence(Integer.MAX_VALUE);

  // Utility class. Do not instantiate.
  private Spaces() {}

  /** Creates a sequence of {@code n} spaces. */
  public static CharSequence sequence(int n) {
    return new SpaceString(n);
  }

  /** Returns a string of {@code n} spaces. */
  public static String of(int n) {
    return SPACE_LIST.get(n);
  }

  /** Appends {@code n} spaces to an {@link Appendable}. */
  public static Appendable append(Appendable buf, int n) throws IOException {
    buf.append(MAX, 0, n);
    return buf;
  }

  /** Appends {@code n} spaces to a {@link PrintWriter}. */
  public static PrintWriter append(PrintWriter pw, int n) {
    pw.append(MAX, 0, n);
    return pw;
  }

  /** Appends {@code n} spaces to a {@link StringWriter}. */
  public static StringWriter append(StringWriter pw, int n) {
    pw.append(MAX, 0, n);
    return pw;
  }

  /** Appends {@code n} spaces to a {@link StringBuilder}. */
  public static StringBuilder append(StringBuilder buf, int n) {
    buf.append(MAX, 0, n);
    return buf;
  }

  /** Appends {@code n} spaces to a {@link StringBuffer}. */
  public static StringBuffer append(StringBuffer buf, int n) {
    buf.append(MAX, 0, n);
    return buf;
  }

  /** Returns a string that is padded on the right with spaces to the given
   * length. */
  public static String padRight(String string, int n) {
    final int x = n - string.length();
    if (x <= 0) {
      return string;
    }
    // Replacing StringBuffer with String would hurt performance.
    //noinspection StringBufferReplaceableByString
    return append(new StringBuilder(string), x).toString();
  }

  /** Returns a string that is padded on the left with spaces to the given
   * length. */
  public static String padLeft(String string, int n) {
    final int x = n - string.length();
    if (x <= 0) {
      return string;
    }
    // Replacing StringBuffer with String would hurt performance.
    //noinspection StringBufferReplaceableByString
    return append(new StringBuilder(), x).append(string).toString();
  }

  /** A string of spaces. */
  private static class SpaceString implements CharSequence {
    private final int length;

    private SpaceString(int length) {
      this.length = length;
    }

    // Do not override equals and hashCode to be like String. CharSequence does
    // not require it.

    @SuppressWarnings("NullableProblems")
    @Override public String toString() {
      return of(length);
    }

    public int length() {
      return length;
    }

    public char charAt(int index) {
      return ' ';
    }

    public CharSequence subSequence(int start, int end) {
      return new SpaceString(end - start);
    }
  }

  /** List whose {@code i}th entry is a string consisting of {@code i} spaces.
   * It populates itself the first time you ask for a particular string, and
   * caches the result. */
  private static class SpaceList extends CopyOnWriteArrayList<String> {
    @Override public String get(int index) {
      for (;;) {
        try {
          return super.get(index);
        } catch (IndexOutOfBoundsException e) {
          if (index < 0) {
            throw e;
          }
          populate(Math.max(16, index + 1));
        }
      }
    }

    /**
     * Populates this list with all prefix strings of a given string. All
     * of the prefix strings share the same backing array of chars.
     */
    private synchronized void populate(int newSize) {
      final int size = size();
      if (newSize <= size) {
        return;
      }
      final char[] chars = new char[newSize];
      Arrays.fill(chars, ' ');
      final int length = newSize - size;
      final int offset = size;

      // addAll is much more efficient than repeated add for
      // CopyOnWriteArrayList
      addAll(
          new AbstractList<String>() {
            public String get(int index) {
              return new String(chars, 0, offset + index);
            }

            public int size() {
              return length;
            }
          });
    }
  }
}

// End Spaces.java


<|start_filename|>core/src/main/java/org/eigenbase/util/Stacks.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.util;

import java.util.List;

/**
 * Utilities to make vanilla lists look like stacks.
 */
public class Stacks {
  private Stacks() {
  }

  /**
   * Returns the most recently added element in the stack. Throws if the
   * stack is empty.
   */
  public static <T> T peek(List<T> stack) {
    return stack.get(stack.size() - 1);
  }

  /**
   * Adds an element to the stack.
   */
  public static <T> void push(List<T> stack, T element) {
    stack.add(element);
  }

  /**
   * Removes an element from the stack. Asserts of the element is not the
   * one last added; throws if the stack is empty.
   */
  public static <T> void pop(List<T> stack, T element) {
    assert stack.get(stack.size() - 1) == element;
    stack.remove(stack.size() - 1);
  }
}

// End Stacks.java


<|start_filename|>core/src/main/java/org/eigenbase/rel/FilterRelBase.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel;

import java.util.List;

import org.eigenbase.rel.metadata.*;
import org.eigenbase.relopt.*;
import org.eigenbase.rex.*;

import com.google.common.collect.ImmutableList;

/**
 * <code>FilterRelBase</code> is an abstract base class for implementations of
 * {@link FilterRel}.
 */
public abstract class FilterRelBase extends SingleRel {
  //~ Instance fields --------------------------------------------------------

  protected final RexNode condition;

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

  /**
   * Creates a filter.
   *
   * @param cluster   {@link RelOptCluster}  this relational expression belongs
   *                  to
   * @param traits    the traits of this rel
   * @param child     input relational expression
   * @param condition boolean expression which determines whether a row is
   *                  allowed to pass
   */
  protected FilterRelBase(
      RelOptCluster cluster,
      RelTraitSet traits,
      RelNode child,
      RexNode condition) {
    super(cluster, traits, child);
    assert condition != null;
    assert RexUtil.isFlat(condition) : condition;
    this.condition = condition;
  }

  /**
   * Creates a FilterRelBase by parsing serialized output.
   */
  protected FilterRelBase(RelInput input) {
    this(
        input.getCluster(), input.getTraitSet(), input.getInput(),
        input.getExpression("condition"));
  }

  //~ Methods ----------------------------------------------------------------

  @Override
  public List<RexNode> getChildExps() {
    return ImmutableList.of(condition);
  }

  public RexNode getCondition() {
    return condition;
  }

  public RelOptCost computeSelfCost(RelOptPlanner planner) {
    double dRows = RelMetadataQuery.getRowCount(this);
    double dCpu = RelMetadataQuery.getRowCount(getChild());
    double dIo = 0;
    return planner.getCostFactory().makeCost(dRows, dCpu, dIo);
  }

  // override RelNode
  public double getRows() {
    return estimateFilteredRows(
        getChild(),
        condition);
  }

  public static double estimateFilteredRows(RelNode child, RexProgram program) {
    // convert the program's RexLocalRef condition to an expanded RexNode
    RexLocalRef programCondition = program.getCondition();
    RexNode condition;
    if (programCondition == null) {
      condition = null;
    } else {
      condition = program.expandLocalRef(programCondition);
    }
    return estimateFilteredRows(
        child,
        condition);
  }

  public static double estimateFilteredRows(RelNode child, RexNode condition) {
    return RelMetadataQuery.getRowCount(child)
        * RelMetadataQuery.getSelectivity(child, condition);
  }

  public RelWriter explainTerms(RelWriter pw) {
    return super.explainTerms(pw)
        .item("condition", condition);
  }
}

// End FilterRelBase.java


<|start_filename|>core/src/main/java/net/hydromatic/optiq/impl/AbstractTableQueryable.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.impl;

import net.hydromatic.linq4j.*;
import net.hydromatic.linq4j.expressions.Expression;

import net.hydromatic.optiq.QueryableTable;
import net.hydromatic.optiq.SchemaPlus;

import java.lang.reflect.Type;
import java.util.Iterator;

/**
 * Abstract implementation of {@link net.hydromatic.linq4j.Queryable} for
 * {@link QueryableTable}.
 *
 * <p>Not to be confused with
 * {@link net.hydromatic.optiq.impl.java.AbstractQueryableTable}.</p>
 *
 * @param <T> element type
 */
public abstract class AbstractTableQueryable<T> extends AbstractQueryable<T> {
  public final QueryProvider queryProvider;
  public final SchemaPlus schema;
  public final QueryableTable table;
  public final String tableName;

  public AbstractTableQueryable(QueryProvider queryProvider,
      SchemaPlus schema, QueryableTable table, String tableName) {
    this.queryProvider = queryProvider;
    this.schema = schema;
    this.table = table;
    this.tableName = tableName;
  }

  public Expression getExpression() {
    return table.getExpression(schema, tableName, Queryable.class);
  }

  public QueryProvider getProvider() {
    return queryProvider;
  }

  public Type getElementType() {
    return table.getElementType();
  }

  public Iterator<T> iterator() {
    return Linq4j.enumeratorIterator(enumerator());
  }
}

// End AbstractTableQueryable.java


<|start_filename|>core/src/main/java/org/eigenbase/reltype/RelProtoDataType.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.reltype;

import net.hydromatic.linq4j.function.Function1;

/**
 * Can be converted into a {@link RelDataType} given a
 * {@link org.eigenbase.reltype.RelDataTypeFactory}.
 *
 * @see org.eigenbase.reltype.RelDataTypeImpl#proto
 */
public interface RelProtoDataType
    extends Function1<RelDataTypeFactory, RelDataType> {
}

// End RelProtoDataType.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/util/SqlVisitor.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql.util;

import org.eigenbase.sql.*;

/**
 * Visitor class, follows the {@link org.eigenbase.util.Glossary#VISITOR_PATTERN
 * visitor pattern}.
 *
 * <p>The type parameter <code>R</code> is the return type of each <code>
 * visit()</code> method. If the methods do not need to return a value, use
 * {@link Void}.
 *
 * @see SqlBasicVisitor
 * @see SqlNode#accept(SqlVisitor)
 * @see SqlOperator#acceptCall
 */
public interface SqlVisitor<R> {
  //~ Methods ----------------------------------------------------------------

  /**
   * Visits a literal.
   *
   * @param literal Literal
   * @see SqlLiteral#accept(SqlVisitor)
   */
  R visit(SqlLiteral literal);

  /**
   * Visits a call to a {@link SqlOperator}.
   *
   * @param call Call
   * @see SqlCall#accept(SqlVisitor)
   */
  R visit(SqlCall call);

  /**
   * Visits a list of {@link SqlNode} objects.
   *
   * @param nodeList list of nodes
   * @see SqlNodeList#accept(SqlVisitor)
   */
  R visit(SqlNodeList nodeList);

  /**
   * Visits an identifier.
   *
   * @param id identifier
   * @see SqlIdentifier#accept(SqlVisitor)
   */
  R visit(SqlIdentifier id);

  /**
   * Visits a datatype specification.
   *
   * @param type datatype specification
   * @see SqlDataTypeSpec#accept(SqlVisitor)
   */
  R visit(SqlDataTypeSpec type);

  /**
   * Visits a dynamic parameter.
   *
   * @param param Dynamic parameter
   * @see SqlDynamicParam#accept(SqlVisitor)
   */
  R visit(SqlDynamicParam param);

  /**
   * Visits an interval qualifier
   *
   * @param intervalQualifier Interval qualifier
   * @see SqlIntervalQualifier#accept(SqlVisitor)
   */
  R visit(SqlIntervalQualifier intervalQualifier);
}

// End SqlVisitor.java


<|start_filename|>core/src/main/java/org/eigenbase/rel/rules/FilterToCalcRule.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel.rules;

import org.eigenbase.rel.*;
import org.eigenbase.relopt.*;
import org.eigenbase.reltype.*;
import org.eigenbase.rex.*;

import com.google.common.collect.ImmutableList;

/**
 * Planner rule which converts a {@link FilterRel} to a {@link CalcRel}.
 *
 * <p>The rule does <em>NOT</em> fire if the child is a {@link FilterRel} or a
 * {@link ProjectRel} (we assume they they will be converted using {@link
 * FilterToCalcRule} or {@link ProjectToCalcRule}) or a {@link CalcRel}. This
 * {@link FilterRel} will eventually be converted by {@link
 * MergeFilterOntoCalcRule}.
 */
public class FilterToCalcRule extends RelOptRule {
  //~ Static fields/initializers ---------------------------------------------

  public static final FilterToCalcRule INSTANCE = new FilterToCalcRule();

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

  private FilterToCalcRule() {
    super(operand(FilterRel.class, any()));
  }

  //~ Methods ----------------------------------------------------------------

  public void onMatch(RelOptRuleCall call) {
    final FilterRel filter = call.rel(0);
    final RelNode rel = filter.getChild();

    // Create a program containing a filter.
    final RexBuilder rexBuilder = filter.getCluster().getRexBuilder();
    final RelDataType inputRowType = rel.getRowType();
    final RexProgramBuilder programBuilder =
        new RexProgramBuilder(inputRowType, rexBuilder);
    programBuilder.addIdentity();
    programBuilder.addCondition(filter.getCondition());
    final RexProgram program = programBuilder.getProgram();

    final CalcRel calc =
        new CalcRel(
            filter.getCluster(),
            filter.getTraitSet(),
            rel,
            inputRowType,
            program,
            ImmutableList.<RelCollation>of());
    call.transformTo(calc);
  }
}

// End FilterToCalcRule.java


<|start_filename|>core/src/main/java/org/eigenbase/rel/rules/PushFilterPastSetOpRule.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel.rules;

import java.util.ArrayList;
import java.util.List;

import org.eigenbase.rel.*;
import org.eigenbase.relopt.*;
import org.eigenbase.reltype.*;
import org.eigenbase.rex.*;

/**
 * PushFilterPastSetOpRule implements the rule for pushing a {@link FilterRel}
 * past a {@link SetOpRel}.
 */
public class PushFilterPastSetOpRule extends RelOptRule {
  public static final PushFilterPastSetOpRule INSTANCE =
      new PushFilterPastSetOpRule();

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

  /**
   * Creates a PushFilterPastSetOpRule.
   */
  private PushFilterPastSetOpRule() {
    super(
        operand(
            FilterRel.class,
            operand(SetOpRel.class, any())));
  }

  //~ Methods ----------------------------------------------------------------

  // implement RelOptRule
  public void onMatch(RelOptRuleCall call) {
    FilterRel filterRel = call.rel(0);
    SetOpRel setOpRel = call.rel(1);

    RelOptCluster cluster = setOpRel.getCluster();
    RexNode condition = filterRel.getCondition();

    // create filters on top of each setop child, modifying the filter
    // condition to reference each setop child
    RexBuilder rexBuilder = filterRel.getCluster().getRexBuilder();
    List<RelDataTypeField> origFields =
        setOpRel.getRowType().getFieldList();
    int[] adjustments = new int[origFields.size()];
    List<RelNode> newSetOpInputs = new ArrayList<RelNode>();
    for (RelNode input : setOpRel.getInputs()) {
      RexNode newCondition =
          condition.accept(
              new RelOptUtil.RexInputConverter(
                  rexBuilder,
                  origFields,
                  input.getRowType().getFieldList(),
                  adjustments));
      newSetOpInputs.add(
          new FilterRel(cluster, input, newCondition));
    }

    // create a new setop whose children are the filters created above
    SetOpRel newSetOpRel =
        setOpRel.copy(setOpRel.getTraitSet(), newSetOpInputs);

    call.transformTo(newSetOpRel);
  }
}

// End PushFilterPastSetOpRule.java


<|start_filename|>core/src/main/java/org/eigenbase/rel/CorrelatorRel.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel;

import java.util.*;

import org.eigenbase.relopt.*;
import org.eigenbase.rex.*;

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

/**
 * A <code>CorrelatorRel</code> behaves like a kind of {@link JoinRel}, but
 * works by setting variables in its environment and restarting its right-hand
 * input.
 *
 * <p>A CorrelatorRel is used to represent a correlated query. One
 * implementation strategy is to de-correlate the expression.
 */
public final class CorrelatorRel extends JoinRelBase {
  //~ Instance fields --------------------------------------------------------

  protected final ImmutableList<Correlation> correlations;

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

  /**
   * Creates a CorrelatorRel.
   *
   * @param cluster      cluster this relational expression belongs to
   * @param left         left input relational expression
   * @param right        right input relational expression
   * @param joinCond     join condition
   * @param correlations set of expressions to set as variables each time a
   *                     row arrives from the left input
   * @param joinType     join type
   */
  public CorrelatorRel(
      RelOptCluster cluster,
      RelNode left,
      RelNode right,
      RexNode joinCond,
      List<Correlation> correlations,
      JoinRelType joinType) {
    super(
        cluster,
        cluster.traitSetOf(Convention.NONE),
        left,
        right,
        joinCond,
        joinType,
        ImmutableSet.<String>of());
    this.correlations = ImmutableList.copyOf(correlations);
    assert (joinType == JoinRelType.LEFT)
        || (joinType == JoinRelType.INNER);
  }

  /**
   * Creates a CorrelatorRel with no join condition.
   *
   * @param cluster      cluster this relational expression belongs to
   * @param left         left input relational expression
   * @param right        right input relational expression
   * @param correlations set of expressions to set as variables each time a
   *                     row arrives from the left input
   * @param joinType     join type
   */
  public CorrelatorRel(
      RelOptCluster cluster,
      RelNode left,
      RelNode right,
      List<Correlation> correlations,
      JoinRelType joinType) {
    this(
        cluster,
        left,
        right,
        cluster.getRexBuilder().makeLiteral(true),
        correlations,
        joinType);
  }

  /**
   * Creates a CorrelatorRel by parsing serialized output.
   */
  public CorrelatorRel(RelInput input) {
    this(
        input.getCluster(), input.getInputs().get(0),
        input.getInputs().get(1), getCorrelations(input),
        input.getEnum("joinType", JoinRelType.class));
  }

  private static List<Correlation> getCorrelations(RelInput input) {
    final List<Correlation> list = new ArrayList<Correlation>();
    //noinspection unchecked
    final List<Map<String, Object>> correlations1 =
        (List<Map<String, Object>>) input.get("correlations");
    for (Map<String, Object> correlation : correlations1) {
      list.add(
          new Correlation(
              (Integer) correlation.get("correlation"),
              (Integer) correlation.get("offset")));
    }
    return list;
  }

  //~ Methods ----------------------------------------------------------------

  @Override
  public CorrelatorRel copy(RelTraitSet traitSet, RexNode conditionExpr,
      RelNode left, RelNode right, JoinRelType joinType) {
    assert traitSet.containsIfApplicable(Convention.NONE);
    return new CorrelatorRel(
        getCluster(),
        left,
        right,
        correlations,
        this.joinType);
  }

  public RelWriter explainTerms(RelWriter pw) {
    return super.explainTerms(pw)
        .item("correlations", correlations);
  }

  /**
   * Returns the correlating expressions.
   *
   * @return correlating expressions
   */
  public List<Correlation> getCorrelations() {
    return correlations;
  }

  //~ Inner Classes ----------------------------------------------------------

  /**
   * Describes the neccessary parameters for an implementation in order to
   * identify and set dynamic variables
   */
  public static class Correlation
      implements Cloneable, Comparable<Correlation> {
    private final int id;
    private final int offset;

    /**
     * Creates a correlation.
     *
     * @param id     Identifier
     * @param offset Offset
     */
    public Correlation(int id, int offset) {
      this.id = id;
      this.offset = offset;
    }

    /**
     * Returns the identifier.
     *
     * @return identifier
     */
    public int getId() {
      return id;
    }

    /**
     * Returns this correlation's offset.
     *
     * @return offset
     */
    public int getOffset() {
      return offset;
    }

    public String toString() {
      return "var" + id + "=offset" + offset;
    }

    public int compareTo(Correlation other) {
      return id - other.id;
    }
  }
}

// End CorrelatorRel.java


<|start_filename|>mongodb/src/main/java/net/hydromatic/optiq/impl/mongodb/MongoSortRel.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.impl.mongodb;

import org.eigenbase.rel.RelCollation;
import org.eigenbase.rel.RelFieldCollation;
import org.eigenbase.rel.RelNode;
import org.eigenbase.rel.SortRel;
import org.eigenbase.relopt.RelOptCluster;
import org.eigenbase.relopt.RelOptCost;
import org.eigenbase.relopt.RelOptPlanner;
import org.eigenbase.relopt.RelTraitSet;
import org.eigenbase.reltype.RelDataTypeField;
import org.eigenbase.rex.RexLiteral;
import org.eigenbase.rex.RexNode;
import org.eigenbase.util.Util;

import java.util.ArrayList;
import java.util.List;

/**
* Implementation of {@link SortRel} relational expression in MongoDB.
*/
public class MongoSortRel
    extends SortRel
    implements MongoRel {
  public MongoSortRel(RelOptCluster cluster, RelTraitSet traitSet,
      RelNode child, RelCollation collation, RexNode offset, RexNode fetch) {
    super(cluster, traitSet, child, collation, offset, fetch);
    assert getConvention() == MongoRel.CONVENTION;
    assert getConvention() == child.getConvention();
  }

  @Override
  public RelOptCost computeSelfCost(RelOptPlanner planner) {
    return super.computeSelfCost(planner).multiplyBy(0.05);
  }

  @Override public SortRel copy(RelTraitSet traitSet, RelNode input,
      RelCollation newCollation, RexNode offset, RexNode fetch) {
    return new MongoSortRel(getCluster(), traitSet, input, collation, offset,
        fetch);
  }

  public void implement(Implementor implementor) {
    implementor.visitChild(0, getChild());
    if (!collation.getFieldCollations().isEmpty()) {
      final List<String> keys = new ArrayList<String>();
      final List<RelDataTypeField> fields = getRowType().getFieldList();
      for (RelFieldCollation fieldCollation : collation.getFieldCollations()) {
        final String name =
            fields.get(fieldCollation.getFieldIndex()).getName();
        keys.add(name + ": " + direction(fieldCollation));
        if (false) {
          // TODO: NULLS FIRST and NULLS LAST
          switch (fieldCollation.nullDirection) {
          case FIRST:
            break;
          case LAST:
            break;
          }
        }
      }
      implementor.add(null,
          "{$sort: " + Util.toString(keys, "{", ", ", "}") + "}");
    }
    if (offset != null) {
      implementor.add(null,
          "{$skip: " + ((RexLiteral) offset).getValue() + "}");
    }
    if (fetch != null) {
      implementor.add(null,
          "{$limit: " + ((RexLiteral) fetch).getValue() + "}");
    }
  }

  private int direction(RelFieldCollation fieldCollation) {
    switch (fieldCollation.getDirection()) {
    case DESCENDING:
    case STRICTLY_DESCENDING:
      return -1;
    case ASCENDING:
    case STRICTLY_ASCENDING:
    default:
      return 1;
    }
  }
}

// End MongoSortRel.java


<|start_filename|>core/src/main/java/org/eigenbase/relopt/CommonRelSubExprRule.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.relopt;


/**
 * A <code>CommonRelSubExprRule</code> is an abstract base class for rules
 * that are fired only on relational expressions that appear more than once
 * in a query tree.
 */
public abstract class CommonRelSubExprRule extends RelOptRule {
  //~ Constructors -----------------------------------------------------------

  /**
   * Creates a <code>CommonRelSubExprRule</code>.
   *
   * @param operand root operand, must not be null
   */
  public CommonRelSubExprRule(RelOptRuleOperand operand) {
    super(operand);
  }
}

// End CommonRelSubExprRule.java


<|start_filename|>avatica/src/main/java/net/hydromatic/avatica/ArrayImpl.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.avatica;

import java.sql.*;
import java.util.*;

/** Implementation of JDBC {@link Array}. */
public class ArrayImpl implements Array {
  private final ColumnMetaData.AvaticaType elementType;
  private final Factory factory;
  private final List list;

  public ArrayImpl(List list, ColumnMetaData.AvaticaType elementType,
      Factory factory) {
    this.list = list;
    this.elementType = elementType;
    this.factory = factory;
  }

  public String getBaseTypeName() throws SQLException {
    return elementType.typeName;
  }

  public int getBaseType() throws SQLException {
    return elementType.type;
  }

  public Object getArray() throws SQLException {
    return getArray(list);
  }

  /**
   * Converts a list into an array.
   *
   * <p>If the elements of the list are primitives, converts to an array of
   * primitives (e.g. {@code boolean[]}.</p>
   *
   * @param list List of objects
   *
   * @return array
   * @throws ClassCastException   if any element is not of the box type
   * @throws NullPointerException if any element is null
   */
  @SuppressWarnings("unchecked")
  protected Object getArray(List list) throws SQLException {
    int i = 0;
    switch (elementType.representation) {
    case PRIMITIVE_DOUBLE:
      final double[] doubles = new double[list.size()];
      for (double v : (List<Double>) list) {
        doubles[i++] = v;
      }
      return doubles;
    case PRIMITIVE_FLOAT:
      final float[] floats = new float[list.size()];
      for (float v : (List<Float>) list) {
        floats[i++] = v;
      }
      return floats;
    case PRIMITIVE_INT:
      final int[] ints = new int[list.size()];
      for (int v : (List<Integer>) list) {
        ints[i++] = v;
      }
      return ints;
    case PRIMITIVE_LONG:
      final long[] longs = new long[list.size()];
      for (long v : (List<Long>) list) {
        longs[i++] = v;
      }
      return longs;
    case PRIMITIVE_SHORT:
      final short[] shorts = new short[list.size()];
      for (short v : (List<Short>) list) {
        shorts[i++] = v;
      }
      return shorts;
    case PRIMITIVE_BOOLEAN:
      final boolean[] booleans = new boolean[list.size()];
      for (boolean v : (List<Boolean>) list) {
        booleans[i++] = v;
      }
      return booleans;
    case PRIMITIVE_BYTE:
      final byte[] bytes = new byte[list.size()];
      for (byte v : (List<Byte>) list) {
        bytes[i++] = v;
      }
      return bytes;
    case PRIMITIVE_CHAR:
      final char[] chars = new char[list.size()];
      for (char v : (List<Character>) list) {
        chars[i++] = v;
      }
      return chars;
    default:
      // fall through
    }
    final Object[] objects = list.toArray();
    switch (elementType.type) {
    case Types.ARRAY:
      final ColumnMetaData.ArrayType arrayType =
          (ColumnMetaData.ArrayType) elementType;
      for (i = 0; i < objects.length; i++) {
        objects[i] =
            new ArrayImpl((List) objects[i], arrayType.component, factory);
      }
    }
    return objects;
  }

  public Object getArray(Map<String, Class<?>> map) throws SQLException {
    throw new UnsupportedOperationException(); // TODO
  }

  public Object getArray(long index, int count) throws SQLException {
    return getArray(list.subList((int) index, count));
  }

  public Object getArray(long index, int count, Map<String, Class<?>> map)
    throws SQLException {
    throw new UnsupportedOperationException(); // TODO
  }

  public ResultSet getResultSet() throws SQLException {
    return factory.create(elementType, list);
  }

  public ResultSet getResultSet(Map<String, Class<?>> map)
    throws SQLException {
    throw new UnsupportedOperationException(); // TODO
  }

  public ResultSet getResultSet(long index, int count) throws SQLException {
    throw new UnsupportedOperationException(); // TODO
  }

  public ResultSet getResultSet(long index, int count,
      Map<String, Class<?>> map) throws SQLException {
    throw new UnsupportedOperationException(); // TODO
  }

  public void free() throws SQLException {
    // nothing to do
  }

  /** Factory that can create a result set based on a list of values. */
  public interface Factory {
    ResultSet create(ColumnMetaData.AvaticaType elementType, Iterable iterable);
  }
}

// End ArrayImpl.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/fun/package-info.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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.
*/

/**
 * Defines the set of standard SQL row-level functions and
 * operators.
 *
 * <p>The standard set of row-level functions and operators are declared in
 * class {@link org.eigenbase.sql.fun.SqlStdOperatorTable}. Anonymous inner
 * classes within that table are allowed only for specifying an operator's test
 * function; if other custom code is needed for an operator, it should be
 * implemented in a top-level class within this package instead.  Operators
 * which are not row-level (e.g. select and join) should be defined in package
 * {@link org.eigenbase.sql} instead.</p>
 */
package org.eigenbase.sql.fun;

// End package-info.java


<|start_filename|>core/src/main/java/org/eigenbase/rel/rules/PushProjectPastFilterRule.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel.rules;

import org.eigenbase.rel.*;
import org.eigenbase.relopt.*;
import org.eigenbase.rex.*;

/**
 * PushProjectPastFilterRule implements the rule for pushing a projection past a
 * filter.
 */
public class PushProjectPastFilterRule extends RelOptRule {
  public static final PushProjectPastFilterRule INSTANCE =
      new PushProjectPastFilterRule(PushProjector.ExprCondition.FALSE);

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

  /**
   * Expressions that should be preserved in the projection
   */
  private final PushProjector.ExprCondition preserveExprCondition;

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

  /**
   * Creates a PushProjectPastFilterRule.
   *
   * @param preserveExprCondition Condition for expressions that should be
   *                              preserved in the projection
   */
  private PushProjectPastFilterRule(
      PushProjector.ExprCondition preserveExprCondition) {
    super(
        operand(
            ProjectRel.class,
            operand(FilterRel.class, any())));
    this.preserveExprCondition = preserveExprCondition;
  }

  //~ Methods ----------------------------------------------------------------

  // implement RelOptRule
  public void onMatch(RelOptRuleCall call) {
    ProjectRel origProj;
    FilterRel filterRel;

    if (call.rels.length == 2) {
      origProj = call.rel(0);
      filterRel = call.rel(1);
    } else {
      origProj = null;
      filterRel = call.rel(0);
    }
    RelNode rel = filterRel.getChild();
    RexNode origFilter = filterRel.getCondition();

    if ((origProj != null)
        && RexOver.containsOver(origProj.getProjects(), null)) {
      // Cannot push project through filter if project contains a windowed
      // aggregate -- it will affect row counts. Abort this rule
      // invocation; pushdown will be considered after the windowed
      // aggregate has been implemented. It's OK if the filter contains a
      // windowed aggregate.
      return;
    }

    PushProjector pushProjector =
        new PushProjector(
            origProj, origFilter, rel, preserveExprCondition);
    ProjectRel topProject = pushProjector.convertProject(null);

    if (topProject != null) {
      call.transformTo(topProject);
    }
  }
}

// End PushProjectPastFilterRule.java


<|start_filename|>core/src/main/java/org/eigenbase/util/CancelFlag.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.util;

/**
 * CancelFlag is used to post and check cancellation requests.
 */
public class CancelFlag {
  //~ Instance fields --------------------------------------------------------

  private boolean cancelRequested;

  //~ Methods ----------------------------------------------------------------

  /**
   * @return whether a cancellation has been requested
   */
  public boolean isCancelRequested() {
    return cancelRequested;
  }

  /**
   * Requests a cancellation.
   */
  public void requestCancel() {
    cancelRequested = true;
  }

  /**
   * Clears any pending cancellation request.
   */
  public void clearCancel() {
    cancelRequested = false;
  }
}

// End CancelFlag.java


<|start_filename|>core/src/main/java/net/hydromatic/optiq/impl/ScalarFunctionImpl.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.impl;

import net.hydromatic.optiq.*;

import net.hydromatic.optiq.rules.java.*;

import org.eigenbase.reltype.RelDataType;
import org.eigenbase.reltype.RelDataTypeFactory;

import java.lang.reflect.*;

import static org.eigenbase.util.Static.*;

/**
* Implementation of {@link net.hydromatic.optiq.ScalarFunction}.
*/
public class ScalarFunctionImpl extends ReflectiveFunctionBase implements
    ScalarFunction, ImplementableFunction {
  private final CallImplementor implementor;

  /** Private constructor. */
  private ScalarFunctionImpl(Method method, CallImplementor implementor) {
    super(method);
    this.implementor = implementor;
  }

  /**
   * Creates {@link net.hydromatic.optiq.ScalarFunction} from given class.
   * The class should contain {@code eval} method.
   * When {@code eval} method is not found or it does not suit,
   * {@code null} is returned.
   *
   * @param clazz class that is used to implement the function
   * @return created {@link ScalarFunction} or null
   */
  public static ScalarFunction create(Class<?> clazz) {
    final Method method = findMethod(clazz, "eval");
    if (method == null) {
      return null;
    }
    return create(method);
  }

  /**
   * Creates {@link net.hydromatic.optiq.ScalarFunction} from given method.
   * When {@code eval} method does not suit, {@code null} is returned.
   *
   * @param method method that is used to implement the function
   * @return created {@link ScalarFunction} or null
   */
  public static ScalarFunction create(Method method) {
    if (!Modifier.isStatic(method.getModifiers())) {
      Class clazz = method.getDeclaringClass();
      if (!classHasPublicZeroArgsConstructor(clazz)) {
        throw RESOURCE.requireDefaultConstructor(clazz.getName()).ex();
      }
    }
    CallImplementor implementor = createImplementor(method);
    return new ScalarFunctionImpl(method, implementor);
  }

  public RelDataType getReturnType(RelDataTypeFactory typeFactory) {
    return typeFactory.createJavaType(method.getReturnType());
  }

  public CallImplementor getImplementor() {
    return implementor;
  }

  private static CallImplementor createImplementor(final Method method) {
    return RexImpTable.createImplementor(new ReflectiveCallNotNullImplementor(
        method), NullPolicy.ANY, false);
  }
}

// End ScalarFunctionImpl.java


<|start_filename|>core/src/main/java/org/eigenbase/rel/rules/PushJoinThroughUnionRule.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel.rules;

import java.util.*;

import org.eigenbase.rel.*;
import org.eigenbase.relopt.*;

import com.google.common.collect.ImmutableSet;

/**
 * PushJoinThroughUnionRule implements the rule for pushing a
 * {@link JoinRel} past a non-distinct {@link UnionRel}.
 */
public class PushJoinThroughUnionRule extends RelOptRule {
  public static final PushJoinThroughUnionRule LEFT_UNION =
      new PushJoinThroughUnionRule(
          operand(JoinRel.class,
              operand(UnionRel.class, any()),
              operand(RelNode.class, any())),
          "union on left");

  public static final PushJoinThroughUnionRule RIGHT_UNION =
      new PushJoinThroughUnionRule(
          operand(JoinRel.class,
              operand(RelNode.class, any()),
              operand(UnionRel.class, any())),
          "union on right");

  private PushJoinThroughUnionRule(RelOptRuleOperand operand, String id) {
    super(
        operand,
        "PushJoinThroughUnionRule: " + id);
  }

  public void onMatch(RelOptRuleCall call) {
    JoinRel joinRel = call.rel(0);
    UnionRel unionRel;
    RelNode otherInput;
    boolean unionOnLeft;
    if (call.rel(1) instanceof UnionRel) {
      unionRel = call.rel(1);
      otherInput = call.rel(2);
      unionOnLeft = true;
    } else {
      otherInput = call.rel(1);
      unionRel = call.rel(2);
      unionOnLeft = false;
    }
    if (!unionRel.all) {
      return;
    }
    if (!joinRel.getVariablesStopped().isEmpty()) {
      return;
    }
    // The UNION ALL cannot be on the null generating side
    // of an outer join (otherwise we might generate incorrect
    // rows for the other side for join keys which lack a match
    // in one or both branches of the union)
    if (unionOnLeft) {
      if (joinRel.getJoinType().generatesNullsOnLeft()) {
        return;
      }
    } else {
      if (joinRel.getJoinType().generatesNullsOnRight()) {
        return;
      }
    }
    List<RelNode> newUnionInputs = new ArrayList<RelNode>();
    RelOptCluster cluster = unionRel.getCluster();
    for (RelNode input : unionRel.getInputs()) {
      RelNode joinLeft;
      RelNode joinRight;
      if (unionOnLeft) {
        joinLeft = input;
        joinRight = otherInput;
      } else {
        joinLeft = otherInput;
        joinRight = input;
      }
      newUnionInputs.add(
          new JoinRel(
              cluster,
              joinLeft,
              joinRight,
              joinRel.getCondition(),
              joinRel.getJoinType(),
              ImmutableSet.<String>of()));
    }
    UnionRel newUnionRel = new UnionRel(cluster, newUnionInputs, true);
    call.transformTo(newUnionRel);
  }
}

// End PushJoinThroughUnionRule.java


<|start_filename|>avatica/src/main/java/net/hydromatic/avatica/Helper.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.avatica;

import java.sql.SQLException;

/**
 * Utility methods, mainly concerning error-handling.
 */
public class Helper {
  public static final Helper INSTANCE = new Helper();

  private Helper() {
  }

  public RuntimeException todo() {
    return new RuntimeException("todo: implement this method");
  }

  public RuntimeException wrap(String message, Exception e) {
    return new RuntimeException(message, e);
  }

  public SQLException createException(String message, Exception e) {
    return new SQLException(message, e);
  }

  public SQLException createException(String message) {
    return new SQLException(message);
  }

  public SQLException toSQLException(SQLException exception) {
    return exception;
  }
}

// End Helper.java


<|start_filename|>core/src/main/java/org/eigenbase/rel/rules/PushFilterIntoMultiJoinRule.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel.rules;

import org.eigenbase.rel.*;
import org.eigenbase.relopt.*;

/**
 * PushFilterIntoMultiJoinRule implements the rule for pushing a {@link
 * FilterRel} into a {@link MultiJoinRel}.
 */
public class PushFilterIntoMultiJoinRule extends RelOptRule {
  public static final PushFilterIntoMultiJoinRule INSTANCE =
      new PushFilterIntoMultiJoinRule();

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

  /**
   * Creates a PushFilterIntoMultiJoinRule.
   */
  private PushFilterIntoMultiJoinRule() {
    super(
        operand(
            FilterRel.class,
            operand(MultiJoinRel.class, any())));
  }

  //~ Methods ----------------------------------------------------------------

  // implement RelOptRule
  public void onMatch(RelOptRuleCall call) {
    FilterRel filterRel = call.rel(0);
    MultiJoinRel multiJoinRel = call.rel(1);

    MultiJoinRel newMultiJoinRel =
        new MultiJoinRel(
            multiJoinRel.getCluster(),
            multiJoinRel.getInputs(),
            multiJoinRel.getJoinFilter(),
            multiJoinRel.getRowType(),
            multiJoinRel.isFullOuterJoin(),
            multiJoinRel.getOuterJoinConditions(),
            multiJoinRel.getJoinTypes(),
            multiJoinRel.getProjFields(),
            multiJoinRel.getJoinFieldRefCountsMap(),
            filterRel.getCondition());

    call.transformTo(newMultiJoinRel);
  }
}

// End PushFilterIntoMultiJoinRule.java


<|start_filename|>core/src/main/java/org/eigenbase/rel/rules/AddRedundantSemiJoinRule.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel.rules;

import java.util.*;

import org.eigenbase.rel.*;
import org.eigenbase.relopt.*;

/**
 * Rule to add a semijoin into a joinrel. Transformation is as follows:
 *
 * <p>JoinRel(X, Y) &rarr; JoinRel(SemiJoinRel(X, Y), Y)
 */
public class AddRedundantSemiJoinRule extends RelOptRule {
  public static final AddRedundantSemiJoinRule INSTANCE =
      new AddRedundantSemiJoinRule();

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

  /**
   * Creates an AddRedundantSemiJoinRule.
   */
  private AddRedundantSemiJoinRule() {
    super(operand(JoinRel.class, any()));
  }

  //~ Methods ----------------------------------------------------------------

  public void onMatch(RelOptRuleCall call) {
    JoinRel origJoinRel = call.rel(0);
    if (origJoinRel.isSemiJoinDone()) {
      return;
    }

    // can't process outer joins using semijoins
    if (origJoinRel.getJoinType() != JoinRelType.INNER) {
      return;
    }

    // determine if we have a valid join condition
    List<Integer> leftKeys = new ArrayList<Integer>();
    List<Integer> rightKeys = new ArrayList<Integer>();
    RelOptUtil.splitJoinCondition(
        origJoinRel.getLeft(),
        origJoinRel.getRight(),
        origJoinRel.getCondition(),
        leftKeys,
        rightKeys);
    if (leftKeys.size() == 0) {
      return;
    }

    RelNode semiJoin =
        new SemiJoinRel(
            origJoinRel.getCluster(),
            origJoinRel.getLeft(),
            origJoinRel.getRight(),
            origJoinRel.getCondition(),
            leftKeys,
            rightKeys);

    RelNode newJoinRel =
        new JoinRel(
            origJoinRel.getCluster(),
            semiJoin,
            origJoinRel.getRight(),
            origJoinRel.getCondition(),
            JoinRelType.INNER,
            Collections.<String>emptySet(),
            true,
            origJoinRel.getSystemFieldList());

    call.transformTo(newJoinRel);
  }
}

// End AddRedundantSemiJoinRule.java


<|start_filename|>core/src/main/java/org/eigenbase/util/ControlFlowException.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.util;

/**
 * Exception intended to be used for control flow, as opposed to the usual
 * use of exceptions which is to signal an error condition.
 *
 * <p>{@code ControlFlowException} does not populate its own stack trace, which
 * makes instantiating one of these (or a sub-class) more efficient.</p>
 */
public class ControlFlowException extends RuntimeException {
  @Override public Throwable fillInStackTrace() {
    return this;
  }
}

// End ControlFlowException.java


<|start_filename|>core/src/main/java/org/eigenbase/sql2rel/SubqueryConverter.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql2rel;

import org.eigenbase.rex.*;
import org.eigenbase.sql.*;

/**
 * SubqueryConverter provides the interface for classes that convert subqueries
 * into equivalent expressions.
 */
public interface SubqueryConverter {
  //~ Methods ----------------------------------------------------------------

  /**
   * @return true if the subquery can be converted
   */
  boolean canConvertSubquery();

  /**
   * Converts the subquery to an equivalent expression.
   *
   * @param subquery        the SqlNode tree corresponding to a subquery
   * @param parentConverter sqlToRelConverter of the parent query
   * @param isExists        whether the subquery is part of an EXISTS expression
   * @param isExplain       whether the subquery is part of an EXPLAIN PLAN
   *                        statement
   * @return the equivalent expression or null if the subquery couldn't be
   * converted
   */
  RexNode convertSubquery(
      SqlCall subquery,
      SqlToRelConverter parentConverter,
      boolean isExists,
      boolean isExplain);
}

// End SubqueryConverter.java


<|start_filename|>core/src/main/java/org/eigenbase/rel/rules/PushFilterPastProjectRule.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel.rules;

import org.eigenbase.rel.*;
import org.eigenbase.relopt.*;
import org.eigenbase.rex.*;

/**
 * PushFilterPastProjectRule implements the rule for pushing a {@link FilterRel}
 * past a {@link ProjectRel}.
 */
public class PushFilterPastProjectRule extends RelOptRule {
  public static final PushFilterPastProjectRule INSTANCE =
      new PushFilterPastProjectRule();

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

  /**
   * Creates a PushFilterPastProjectRule.
   */
  private PushFilterPastProjectRule() {
    super(
        operand(
            FilterRel.class,
            operand(ProjectRel.class, any())));
  }

  //~ Methods ----------------------------------------------------------------

  // implement RelOptRule
  public void onMatch(RelOptRuleCall call) {
    FilterRel filterRel = call.rel(0);
    ProjectRel projRel = call.rel(1);

    // convert the filter to one that references the child of the project
    RexNode newCondition =
        RelOptUtil.pushFilterPastProject(filterRel.getCondition(), projRel);

    FilterRel newFilterRel =
        new FilterRel(
            filterRel.getCluster(),
            projRel.getChild(),
            newCondition);

    ProjectRel newProjRel =
        (ProjectRel) CalcRel.createProject(
            newFilterRel,
            projRel.getNamedProjects(),
            false);

    call.transformTo(newProjRel);
  }
}

// End PushFilterPastProjectRule.java


<|start_filename|>core/src/main/java/net/hydromatic/optiq/ModifiableTable.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq;

import net.hydromatic.optiq.prepare.Prepare;

import org.eigenbase.rel.RelNode;
import org.eigenbase.rel.TableModificationRelBase;
import org.eigenbase.relopt.*;

import java.util.Collection;
import java.util.List;

/**
 * A table that can be modified.
 *
 * <p>NOTE: The current API is inefficient and experimental. It will change
 * without notice.</p>
 */
public interface ModifiableTable extends QueryableTable {
  /** Returns the modifiable collection.
   * Modifying the collection will change the table's contents. */
  Collection getModifiableCollection();

  /** Creates a relational expression that modifies this table. */
  TableModificationRelBase toModificationRel(
      RelOptCluster cluster,
      RelOptTable table,
      Prepare.CatalogReader catalogReader,
      RelNode child,
      TableModificationRelBase.Operation operation,
      List<String> updateColumnList,
      boolean flattened);
}

// End ModifiableTable.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/type/SqlReturnTypeInferenceChain.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql.type;

import org.eigenbase.reltype.*;
import org.eigenbase.sql.*;

import com.google.common.collect.ImmutableList;

/**
 * Strategy to infer the type of an operator call from the type of the operands
 * by using a series of {@link SqlReturnTypeInference} rules in a given order.
 * If a rule fails to find a return type (by returning NULL), next rule is tried
 * until there are no more rules in which case NULL will be returned.
 */
public class SqlReturnTypeInferenceChain implements SqlReturnTypeInference {
  //~ Instance fields --------------------------------------------------------

  private final ImmutableList<SqlReturnTypeInference> rules;

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

  /**
   * Creates a SqlReturnTypeInferenceChain from an array of rules.
   *
   * <p>Package-protected.
   * Use {@link org.eigenbase.sql.type.ReturnTypes#chain}.</p>
   */
  SqlReturnTypeInferenceChain(SqlReturnTypeInference... rules) {
    assert rules != null;
    assert rules.length > 1;
    for (SqlReturnTypeInference rule : rules) {
      assert rule != null;
    }
    this.rules = ImmutableList.copyOf(rules);
  }

  //~ Methods ----------------------------------------------------------------

  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
    for (SqlReturnTypeInference rule : rules) {
      RelDataType ret = rule.inferReturnType(opBinding);
      if (ret != null) {
        return ret;
      }
    }
    return null;
  }
}

// End SqlReturnTypeInferenceChain.java


<|start_filename|>core/src/main/java/org/eigenbase/rel/rules/RemoveEmptyRules.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel.rules;

import java.util.*;

import org.eigenbase.rel.*;
import org.eigenbase.relopt.*;
import org.eigenbase.rex.RexLiteral;

import static org.eigenbase.relopt.RelOptRule.*;

/**
 * Collection of rules which remove sections of a query plan known never to
 * produce any rows.
 *
 * @see EmptyRel
 */
public abstract class RemoveEmptyRules {
  //~ Static fields/initializers ---------------------------------------------

  /**
   * Rule that removes empty children of a
   * {@link UnionRel}.
   *
   * <p>Examples:
   *
   * <ul>
   * <li>Union(Rel, Empty, Rel2) becomes Union(Rel, Rel2)
   * <li>Union(Rel, Empty, Empty) becomes Rel
   * <li>Union(Empty, Empty) becomes Empty
   * </ul>
   */
  public static final RelOptRule UNION_INSTANCE =
      new RelOptRule(
          operand(UnionRel.class,
              unordered(operand(EmptyRel.class, none()))),
          "Union") {
        public void onMatch(RelOptRuleCall call) {
          UnionRel union = call.rel(0);
          final List<RelNode> childRels = call.getChildRels(union);
          final List<RelNode> newChildRels = new ArrayList<RelNode>();
          for (RelNode childRel : childRels) {
            if (!(childRel instanceof EmptyRel)) {
              newChildRels.add(childRel);
            }
          }
          assert newChildRels.size() < childRels.size()
              : "planner promised us at least one EmptyRel child";
          RelNode newRel;
          switch (newChildRels.size()) {
          case 0:
            newRel = empty(union);
            break;
          case 1:
            newRel =
                RelOptUtil.createCastRel(
                    newChildRels.get(0),
                    union.getRowType(),
                    true);
            break;
          default:
            newRel =
                new UnionRel(
                    union.getCluster(),
                    newChildRels,
                    union.all);
            break;
          }
          call.transformTo(newRel);
        }
      };

  /**
   * Rule that converts a {@link ProjectRel}
   * to empty if its child is empty.
   *
   * <p>Examples:
   *
   * <ul>
   * <li>Project(Empty) becomes Empty
   * </ul>
   */
  public static final RelOptRule PROJECT_INSTANCE =
      new RemoveEmptySingleRule(ProjectRelBase.class, "PruneEmptyProject");

  /**
   * Rule that converts a {@link FilterRel}
   * to empty if its child is empty.
   *
   * <p>Examples:
   *
   * <ul>
   * <li>Filter(Empty) becomes Empty
   * </ul>
   */
  public static final RelOptRule FILTER_INSTANCE =
      new RemoveEmptySingleRule(FilterRelBase.class, "PruneEmptyFilter");

  /**
   * Rule that converts a {@link SortRel}
   * to empty if its child is empty.
   *
   * <p>Examples:
   *
   * <ul>
   * <li>Sort(Empty) becomes Empty
   * </ul>
   */
  public static final RelOptRule SORT_INSTANCE =
      new RemoveEmptySingleRule(SortRel.class, "PruneEmptySort");

  /**
   * Rule that converts a {@link SortRel}
   * to empty if it has {@code LIMIT 0}.
   *
   * <p>Examples:
   *
   * <ul>
   * <li>Sort(Empty) becomes Empty
   * </ul>
   */
  public static final RelOptRule SORT_FETCH_ZERO_INSTANCE =
      new RelOptRule(
          operand(SortRel.class, any()), "PruneSortLimit0") {
        @Override
        public void onMatch(RelOptRuleCall call) {
          SortRel sort = call.rel(0);
          if (sort.fetch != null
              && RexLiteral.intValue(sort.fetch) == 0) {
            call.transformTo(empty(sort));
          }
        }
      };

  /**
   * Rule that converts an {@link AggregateRelBase}
   * to empty if its child is empty.
   *
   * <p>Examples:
   *
   * <ul>
   * <li>Aggregate(Empty) becomes Empty
   * </ul>
   */
  public static final RelOptRule AGGREGATE_INSTANCE =
      new RemoveEmptySingleRule(AggregateRelBase.class, "PruneEmptyAggregate");

  /**
   * Rule that converts a {@link JoinRelBase}
   * to empty if its left child is empty.
   *
   * <p>Examples:
   *
   * <ul>
   * <li>Join(Empty, Scan(Dept), INNER) becomes Empty
   * </ul>
   */
  public static final RelOptRule JOIN_LEFT_INSTANCE =
      new RelOptRule(
          operand(JoinRelBase.class,
              some(
                  operand(EmptyRel.class, none()),
                  operand(RelNode.class, any()))),
              "PruneEmptyJoin(left)") {
        @Override
        public void onMatch(RelOptRuleCall call) {
          JoinRelBase join = call.rel(0);
          if (join.getJoinType().generatesNullsOnLeft()) {
            // "select * from emp right join dept" is not necessarily empty if
            // emp is empty
            return;
          }
          call.transformTo(empty(join));
        }
      };

  /**
   * Rule that converts a {@link JoinRelBase}
   * to empty if its right child is empty.
   *
   * <p>Examples:
   *
   * <ul>
   * <li>Join(Scan(Emp), Empty, INNER) becomes Empty
   * </ul>
   */
  public static final RelOptRule JOIN_RIGHT_INSTANCE =
      new RelOptRule(
          operand(JoinRelBase.class,
              some(
                  operand(RelNode.class, any()),
                  operand(EmptyRel.class, none()))),
              "PruneEmptyJoin(right)") {
        @Override
        public void onMatch(RelOptRuleCall call) {
          JoinRelBase join = call.rel(0);
          if (join.getJoinType().generatesNullsOnRight()) {
            // "select * from emp left join dept" is not necessarily empty if
            // dept is empty
            return;
          }
          call.transformTo(empty(join));
        }
      };

  /** Creates an {@link EmptyRel} to replace {@code node}. */
  private static EmptyRel empty(RelNode node) {
    return new EmptyRel(node.getCluster(), node.getRowType());
  }

  /** Planner rule that converts a single-rel (e.g. project, sort, aggregate or
   * filter) on top of the empty relational expression into empty. */
  private static class RemoveEmptySingleRule extends RelOptRule {
    public RemoveEmptySingleRule(Class<? extends SingleRel> clazz,
        String description) {
      super(
          operand(clazz,
              operand(EmptyRel.class, none())),
          description);
    }

    public void onMatch(RelOptRuleCall call) {
      SingleRel single = call.rel(0);
      call.transformTo(empty(single));
    }
  }
}

// End RemoveEmptyRules.java


<|start_filename|>core/src/main/java/net/hydromatic/optiq/model/JsonJdbcSchema.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.model;

/**
 * JSON object representing a schema that maps to a JDBC database.
 *
 * @see JsonRoot Description of JSON schema elements
 */
public class JsonJdbcSchema extends JsonSchema {
  public String jdbcDriver;
  public String jdbcUrl;
  public String jdbcUser;
  public String jdbcPassword;
  public String jdbcCatalog;
  public String jdbcSchema;

  @Override
  public void accept(ModelHandler handler) {
    handler.visit(this);
  }
}

// End JsonJdbcSchema.java


<|start_filename|>core/src/main/java/org/eigenbase/relopt/RelOptSchema.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.relopt;

import java.util.List;

import org.eigenbase.reltype.*;

/**
 * A <code>RelOptSchema</code> is a set of {@link RelOptTable} objects.
 */
public interface RelOptSchema {
  //~ Methods ----------------------------------------------------------------

  /**
   * Retrieves a {@link RelOptTable} based upon a member access.
   *
   * <p>For example, the Saffron expression <code>salesSchema.emps</code>
   * would be resolved using a call to <code>salesSchema.getTableForMember(new
   * String[]{"emps" })</code>.</p>
   *
   * <p>Note that name.length is only greater than 1 for queries originating
   * from JDBC.</p>
   *
   * @param names Qualified name
   */
  RelOptTable getTableForMember(List<String> names);

  /**
   * Returns the {@link RelDataTypeFactory type factory} used to generate
   * types for this schema.
   */
  RelDataTypeFactory getTypeFactory();

  /**
   * Registers all of the rules supported by this schema. Only called by
   * {@link RelOptPlanner#registerSchema}.
   */
  void registerRules(RelOptPlanner planner) throws Exception;
}

// End RelOptSchema.java


<|start_filename|>core/src/main/java/org/eigenbase/relopt/RelOptSchemaWithSampling.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.relopt;

import java.util.List;

/**
 * Extension to {@link RelOptSchema} with support for sample data-sets.
 *
 * @see RelOptSchema
 */
public interface RelOptSchemaWithSampling extends RelOptSchema {
  //~ Methods ----------------------------------------------------------------

  /**
   * Retrieves a {@link RelOptTable} based upon a member access, using a
   * sample dataset if it exists.
   *
   * @param names       Compound name of table
   * @param datasetName Name of sample dataset to substitute, if it exists;
   *                    null to not look for a sample
   * @param usedDataset Output parameter which is set to true if a sample
   *                    dataset is found; may be null
   * @return Table, or null if not found
   */
  RelOptTable getTableForMember(
      List<String> names,
      String datasetName,
      boolean[] usedDataset);
}

// End RelOptSchemaWithSampling.java


<|start_filename|>core/src/main/java/org/eigenbase/rel/metadata/RelColumnMapping.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel.metadata;

/**
 * Mapping from an input column of a {@link org.eigenbase.rel.RelNode} to one
 * of its output columns.
 */
public class RelColumnMapping {
  public RelColumnMapping(
      int iOutputColumn, int iInputRel, int iInputColumn, boolean derived) {
    this.iOutputColumn = iOutputColumn;
    this.iInputRel = iInputRel;
    this.iInputColumn = iInputColumn;
    this.derived = derived;
  }

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

  /**
   * 0-based ordinal of mapped output column.
   */
  public final int iOutputColumn;

  /**
   * 0-based ordinal of mapped input rel.
   */
  public final int iInputRel;

  /**
   * 0-based ordinal of mapped column within input rel.
   */
  public final int iInputColumn;

  /**
   * Whether the column mapping transforms the input.
   */
  public final boolean derived;
}

// End RelColumnMapping.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/util/ReflectiveSqlOperatorTable.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql.util;

import java.lang.reflect.*;
import java.util.*;

import org.eigenbase.sql.*;
import org.eigenbase.util.*;

import com.google.common.collect.*;

/**
 * ReflectiveSqlOperatorTable implements the {@link SqlOperatorTable } interface
 * by reflecting the public fields of a subclass.
 */
public abstract class ReflectiveSqlOperatorTable implements SqlOperatorTable {
  public static final String IS_NAME = "INFORMATION_SCHEMA";

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

  private final Multimap<String, SqlOperator> operators = HashMultimap.create();

  private final Map<Pair<String, SqlSyntax>, SqlOperator> mapNameToOp =
      new HashMap<Pair<String, SqlSyntax>, SqlOperator>();

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

  protected ReflectiveSqlOperatorTable() {
  }

  //~ Methods ----------------------------------------------------------------

  /**
   * Performs post-constructor initialization of an operator table. It can't
   * be part of the constructor, because the subclass constructor needs to
   * complete first.
   */
  public final void init() {
    // Use reflection to register the expressions stored in public fields.
    for (Field field : getClass().getFields()) {
      try {
        if (SqlFunction.class.isAssignableFrom(field.getType())) {
          SqlFunction op = (SqlFunction) field.get(this);
          if (op != null) {
            register(op);
          }
        } else if (
            SqlOperator.class.isAssignableFrom(field.getType())) {
          SqlOperator op = (SqlOperator) field.get(this);
          register(op);
        }
      } catch (IllegalArgumentException e) {
        throw Util.newInternal(
            e,
            "Error while initializing operator table");
      } catch (IllegalAccessException e) {
        throw Util.newInternal(
            e,
            "Error while initializing operator table");
      }
    }
  }

  // implement SqlOperatorTable
  public void lookupOperatorOverloads(SqlIdentifier opName,
      SqlFunctionCategory category,
      SqlSyntax syntax,
      List<SqlOperator> operatorList) {
    // NOTE jvs 3-Mar-2005:  ignore category until someone cares

    String simpleName;
    if (opName.names.size() > 1) {
      if (opName.names.get(opName.names.size() - 2).equals(IS_NAME)) {
        // per SQL99 Part 2 Section 10.4 Syntax Rule 7.b.ii.1
        simpleName = Util.last(opName.names);
      } else {
        return;
      }
    } else {
      simpleName = opName.getSimple();
    }

    // Always look up built-in operators case-insensitively. Even in sessions
    // with unquotedCasing=UNCHANGED and caseSensitive=true.
    final Collection<SqlOperator> list =
        operators.get(simpleName.toUpperCase());
    if (list.isEmpty()) {
      return;
    }
    for (SqlOperator op : list) {
      if (op.getSyntax() == syntax) {
        operatorList.add(op);
      } else if (syntax == SqlSyntax.FUNCTION
          && op instanceof SqlFunction) {
        // this special case is needed for operators like CAST,
        // which are treated as functions but have special syntax
        operatorList.add(op);
      }
    }

    // REVIEW jvs 1-Jan-2005:  why is this extra lookup required?
    // Shouldn't it be covered by search above?
    switch (syntax) {
    case BINARY:
    case PREFIX:
    case POSTFIX:
      SqlOperator extra = mapNameToOp.get(Pair.of(simpleName, syntax));
      // REVIEW: should only search operators added during this method?
      if (extra != null && !operatorList.contains(extra)) {
        operatorList.add(extra);
      }
      break;
    }
  }

  public void register(SqlOperator op) {
    operators.put(op.getName(), op);
    if (op instanceof SqlBinaryOperator) {
      mapNameToOp.put(Pair.of(op.getName(), SqlSyntax.BINARY), op);
    } else if (op instanceof SqlPrefixOperator) {
      mapNameToOp.put(Pair.of(op.getName(), SqlSyntax.PREFIX), op);
    } else if (op instanceof SqlPostfixOperator) {
      mapNameToOp.put(Pair.of(op.getName(), SqlSyntax.POSTFIX), op);
    }
  }

  /**
   * Registers a function in the table.
   *
   * @param function Function to register
   */
  public void register(SqlFunction function) {
    operators.put(function.getName(), function);
    SqlFunctionCategory funcType = function.getFunctionType();
    assert funcType != null
        : "Function type for " + function.getName() + " not set";
  }

  public List<SqlOperator> getOperatorList() {
    return ImmutableList.copyOf(operators.values());
  }
}

// End ReflectiveSqlOperatorTable.java


<|start_filename|>core/src/main/java/org/eigenbase/sarg/SargInterval.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sarg;

import org.eigenbase.reltype.*;

/**
 * SargInterval represents a single contiguous search interval over a scalar
 * domain of a given datatype (including null values). It consists of two
 * endpoints: a lower bound and an upper bound, which may be the same for the
 * case of a single point. The endpoints are represented via instances of {@link
 * SargEndpoint}. An empty interval is represented by setting both bounds to be
 * open with the same value (the null value, but it doesn't really matter).
 *
 * <p>Instances of SargInterval are immutable after construction.
 *
 * <p>For string representation, we use the standard mathematical bracketed
 * bounds pair notation, with round brackets for open bounds and square brackets
 * for closed bounds, e.g.
 *
 * <ul>
 * <li>[3,5] represents all values between 3 and 5 inclusive
 * <li>(3,5] represents all values greater than 3 and less than or equal to 5
 * <li>[3,5) represents all values greatern than or equal to 3 and less than 5
 * <li>(3,5) represents all values between 3 and 5 exclusive
 * <li>(3,+infinity) represents all values greater than 3
 * <li>(-infinity,5] represents all values less than or equal to 5
 * <li>[5,5] represents the single point with coordinate 5
 * </ul>
 *
 * <p>Null values are ordered lower than any non-null value but higher than
 * -infinity. So the interval [null,7) would include the null value and any
 * non-null value less than 7.
 */
public class SargInterval extends SargIntervalBase {
  //~ Constructors -----------------------------------------------------------

  /**
   * Creates a SargInterval.
   */
  SargInterval(
      SargFactory factory,
      RelDataType dataType) {
    super(factory, dataType);
  }

  //~ Methods ----------------------------------------------------------------

  void copyFrom(SargIntervalBase other) {
    assert getDataType() == other.getDataType();
    lowerBound.copyFrom(other.getLowerBound());
    upperBound.copyFrom(other.getUpperBound());
  }

  boolean contains(SargInterval other) {
    assert getDataType() == other.getDataType();
    if (getLowerBound().compareTo(other.getLowerBound()) > 0) {
      return false;
    }
    if (getUpperBound().compareTo(other.getUpperBound()) < 0) {
      return false;
    }
    return true;
  }
}

// End SargInterval.java


<|start_filename|>core/src/main/java/org/eigenbase/util14/ZonelessTime.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.util14;

import java.sql.Time;

import java.text.*;

import java.util.Calendar;
import java.util.TimeZone;

/**
 * ZonelessTime is a time value without a time zone.
 */
public class ZonelessTime extends ZonelessDatetime {
  //~ Static fields/initializers ---------------------------------------------

  /**
   * SerialVersionUID created with JDK 1.5 serialver tool.
   */
  private static final long serialVersionUID = 906156904798141861L;

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

  protected final int precision;
  protected transient Time tempTime;

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

  /**
   * Constructs a ZonelessTime
   */
  public ZonelessTime() {
    precision = 0;
  }

  /**
   * Constructs a ZonelessTime with precision.
   *
   * <p>The precision is the number of digits to the right of the decimal
   * point in the seconds value. For example, a <code>TIME(6)</code> has a
   * precision to microseconds.
   *
   * @param precision Number of digits of precision
   */
  public ZonelessTime(int precision) {
    this.precision = precision;
  }

  //~ Methods ----------------------------------------------------------------

  // override ZonelessDatetime
  public void setZonelessTime(long value) {
    super.setZonelessTime(value);
    clearDate();
  }

  // override ZonelessDatetime
  public void setZonedTime(long value, TimeZone zone) {
    super.setZonedTime(value, zone);
    clearDate();
  }

  // implement ZonelessDatetime
  public Object toJdbcObject() {
    return new Time(getJdbcTime(DateTimeUtil.DEFAULT_ZONE));
  }

  /**
   * Override ZonelessDatetime.
   *
   * <p>NOTE: the returned timestamp is based on the current date of the
   * specified time zone, rather than the context variable for current_date,
   * as specified by the SQL standard.
   */
  public long getJdbcTimestamp(TimeZone zone) {
    Calendar cal = getCalendar(DateTimeUtil.GMT_ZONE);
    cal.setTimeInMillis(getTime());
    int hour = cal.get(Calendar.HOUR_OF_DAY);
    int minute = cal.get(Calendar.MINUTE);
    int second = cal.get(Calendar.SECOND);
    int millis = cal.get(Calendar.MILLISECOND);

    cal.setTimeZone(zone);
    cal.setTimeInMillis(System.currentTimeMillis());
    cal.set(Calendar.HOUR_OF_DAY, hour);
    cal.set(Calendar.MINUTE, minute);
    cal.set(Calendar.SECOND, second);
    cal.set(Calendar.MILLISECOND, millis);
    return cal.getTimeInMillis();
  }

  /**
   * Converts this ZonelessTime to a java.sql.Time and formats it via the
   * {@link java.sql.Time#toString() toString()} method of that class.
   *
   * @return the formatted time string
   */
  public String toString() {
    Time jdbcTime = getTempTime(getJdbcTime(DateTimeUtil.DEFAULT_ZONE));
    return jdbcTime.toString();
  }

  /**
   * Formats this ZonelessTime via a SimpleDateFormat
   *
   * @param format format string, as required by SimpleDateFormat
   * @return the formatted time string
   */
  public String toString(String format) {
    DateFormat formatter = getFormatter(format);
    Time jdbcTime = getTempTime(getTime());
    return formatter.format(jdbcTime);
  }

  /**
   * Parses a string as a ZonelessTime.
   *
   * @param s a string representing a time in ISO format, i.e. according to
   *          the {@link SimpleDateFormat} string "HH:mm:ss"
   * @return the parsed time, or null if parsing failed
   */
  public static ZonelessTime parse(String s) {
    return parse(s, DateTimeUtil.TIME_FORMAT_STRING);
  }

  /**
   * Parses a string as a ZonelessTime using a given format string.
   *
   * @param s      a string representing a time the given format
   * @param format format string as per {@link SimpleDateFormat}
   * @return the parsed time, or null if parsing failed
   */
  public static ZonelessTime parse(String s, String format) {
    DateTimeUtil.PrecisionTime pt =
        DateTimeUtil.parsePrecisionDateTimeLiteral(
            s,
            format,
            DateTimeUtil.GMT_ZONE);
    if (pt == null) {
      return null;
    }
    ZonelessTime zt = new ZonelessTime(pt.getPrecision());
    zt.setZonelessTime(pt.getCalendar().getTime().getTime());
    return zt;
  }

  /**
   * Gets a temporary Time object. The same object is returned every time.
   */
  protected Time getTempTime(long value) {
    if (tempTime == null) {
      tempTime = new Time(value);
    } else {
      tempTime.setTime(value);
    }
    return tempTime;
  }
}

// End ZonelessTime.java


<|start_filename|>core/src/main/java/org/eigenbase/reltype/RelDataTypeField.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.reltype;

import java.util.Map;

/**
 * RelDataTypeField represents the definition of a field in a structured {@link
 * RelDataType}.
 *
 * <p>Extends the {@link java.util.Map.Entry} interface to allow convenient
 * inter-operation with Java collections classes. In any implementation of this
 * interface, {@link #getKey()} must be equivalent to {@link #getName()}
 * and {@link #getValue()} must be equivalent to {@link #getType()}.
 */
public interface RelDataTypeField extends Map.Entry<String, RelDataType> {
  //~ Methods ----------------------------------------------------------------

  /**
   * Gets the name of this field, which is unique within its containing type.
   *
   * @return field name
   */
  String getName();

  /**
   * Gets the ordinal of this field within its containing type.
   *
   * @return 0-based ordinal
   */
  int getIndex();

  /**
   * Gets the type of this field.
   *
   * @return field type
   */
  RelDataType getType();
}

// End RelDataTypeField.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/fun/SqlCollectionTableOperator.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql.fun;

import org.eigenbase.sql.*;
import org.eigenbase.sql.type.*;

/**
 * SqlCollectionTableOperator is the "table function derived table" operator. It
 * converts a table-valued function into a relation, e.g. "<code>SELECT * FROM
 * TABLE(ramp(5))</code>".
 *
 * <p>This operator has function syntax (with one argument), whereas {@link
 * SqlStdOperatorTable#EXPLICIT_TABLE} is a prefix operator.
 */
public class SqlCollectionTableOperator extends SqlFunctionalOperator {
  //~ Static fields/initializers ---------------------------------------------

  public static final int MODALITY_RELATIONAL = 1;
  public static final int MODALITY_STREAM = 2;

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

  private final int modality;

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

  public SqlCollectionTableOperator(String name, int modality) {
    super(
        name,
        SqlKind.COLLECTION_TABLE,
        200,
        true,
        ReturnTypes.ARG0,
        null,
        OperandTypes.ANY);

    this.modality = modality;
  }

  //~ Methods ----------------------------------------------------------------

  public int getModality() {
    return modality;
  }
}

// End SqlCollectionTableOperator.java


<|start_filename|>core/src/main/java/org/eigenbase/rel/metadata/MetadataFactory.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel.metadata;

import org.eigenbase.rel.RelNode;

/**
 * Source of metadata about relational expressions.
 *
 * <p>The metadata is typically various kinds of statistics used to estimate
 * costs.</p>
 *
 * <p>Each kind of metadata has an interface that extends {@link Metadata} and
 * has a method. Some examples: {@link BuiltInMetadata.Selectivity},
 * {@link BuiltInMetadata.ColumnUniqueness}.</p>
 */
public interface MetadataFactory {
  /** Returns a metadata interface to get a particular kind of metadata
   * from a particular relational expression. Returns null if that kind of
   * metadata is not available. */
  <T extends Metadata> T query(RelNode rel, Class<T> clazz);
}

// End MetadataFactory.java


<|start_filename|>core/src/main/java/net/hydromatic/optiq/model/JsonMapSchema.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.model;

import java.util.ArrayList;
import java.util.List;

/**
 * JSON object representing a schema whose tables are explicitly specified.
 *
 * @see JsonRoot Description of JSON schema elements
 */
public class JsonMapSchema extends JsonSchema {
  public final List<JsonTable> tables = new ArrayList<JsonTable>();
  public final List<JsonFunction> functions = new ArrayList<JsonFunction>();

  @Override
  public void accept(ModelHandler handler) {
    handler.visit(this);
  }

  @Override
  public void visitChildren(ModelHandler modelHandler) {
    super.visitChildren(modelHandler);
    for (JsonTable jsonTable : tables) {
      jsonTable.accept(modelHandler);
    }
    for (JsonFunction jsonFunction : functions) {
      jsonFunction.accept(modelHandler);
    }
  }
}

// End JsonMapSchema.java


<|start_filename|>core/src/test/java/org/eigenbase/sql/test/DelegatingSqlTestFactory.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql.test;

import org.eigenbase.sql.SqlOperatorTable;
import org.eigenbase.sql.advise.SqlAdvisor;
import org.eigenbase.sql.parser.SqlParser;
import org.eigenbase.sql.validate.SqlValidator;
import org.eigenbase.sql.validate.SqlValidatorWithHints;

/**
* Implementation of {@link SqlTestFactory} that delegates
 * everything to an underlying factory.
 *
 * <p>Generally a chain starts with a
 * {@link org.eigenbase.sql.test.DefaultSqlTestFactory}, and continues with a
 * succession of objects that derive from {@code DelegatingSqlTestFactory}
 * and override one method.</p>
 *
 * <p>Methods such as {@link org.eigenbase.sql.test.SqlTester#withConformance}
 * help create such chains.</p>
*/
public class DelegatingSqlTestFactory implements SqlTestFactory {
  private final SqlTestFactory factory;

  public DelegatingSqlTestFactory(SqlTestFactory factory) {
    this.factory = factory;
  }

  public Object get(String name) {
    return factory.get(name);
  }

  public SqlOperatorTable createOperatorTable() {
    return factory.createOperatorTable();
  }

  public SqlAdvisor createAdvisor(SqlValidatorWithHints validator) {
    return factory.createAdvisor(validator);
  }

  public SqlValidator getValidator(SqlTestFactory factory) {
    return this.factory.getValidator(factory);
  }

  public SqlParser createParser(SqlTestFactory factory, String sql) {
    return this.factory.createParser(factory, sql);
  }
}

// End DelegatingSqlTestFactory.java


<|start_filename|>core/src/main/java/org/eigenbase/rel/rules/MergeFilterRule.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel.rules;

import org.eigenbase.rel.*;
import org.eigenbase.relopt.*;
import org.eigenbase.rex.*;

/**
 * MergeFilterRule implements the rule for combining two {@link FilterRel}s
 */
public class MergeFilterRule extends RelOptRule {
  public static final MergeFilterRule INSTANCE = new MergeFilterRule();

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

  /**
   * Creates a MergeFilterRule.
   */
  private MergeFilterRule() {
    super(
        operand(
            FilterRel.class,
            operand(FilterRel.class, any())));
  }

  //~ Methods ----------------------------------------------------------------

  // implement RelOptRule
  public void onMatch(RelOptRuleCall call) {
    FilterRel topFilter = call.rel(0);
    FilterRel bottomFilter = call.rel(1);

    // use RexPrograms to merge the two FilterRels into a single program
    // so we can convert the two FilterRel conditions to directly
    // reference the bottom FilterRel's child
    RexBuilder rexBuilder = topFilter.getCluster().getRexBuilder();
    RexProgram bottomProgram = createProgram(bottomFilter);
    RexProgram topProgram = createProgram(topFilter);

    RexProgram mergedProgram =
        RexProgramBuilder.mergePrograms(
            topProgram,
            bottomProgram,
            rexBuilder);

    RexNode newCondition =
        mergedProgram.expandLocalRef(
            mergedProgram.getCondition());

    FilterRel newFilterRel =
        new FilterRel(
            topFilter.getCluster(),
            bottomFilter.getChild(),
            newCondition);

    call.transformTo(newFilterRel);
  }

  /**
   * Creates a RexProgram corresponding to a FilterRel
   *
   * @param filterRel the FilterRel
   * @return created RexProgram
   */
  private RexProgram createProgram(FilterRel filterRel) {
    RexProgramBuilder programBuilder =
        new RexProgramBuilder(
            filterRel.getRowType(),
            filterRel.getCluster().getRexBuilder());
    programBuilder.addIdentity();
    programBuilder.addCondition(filterRel.getCondition());
    return programBuilder.getProgram();
  }
}

// End MergeFilterRule.java


<|start_filename|>core/src/main/java/org/eigenbase/rel/convert/NoneConverterRel.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel.convert;

import java.util.List;

import org.eigenbase.rel.*;
import org.eigenbase.relopt.*;
import org.eigenbase.util.*;

/**
 * <code>NoneConverter</code> converts a plan from <code>inConvention</code> to
 * {@link org.eigenbase.relopt.Convention#NONE}.
 */
public class NoneConverterRel extends ConverterRelImpl {
  //~ Constructors -----------------------------------------------------------

  public NoneConverterRel(
      RelOptCluster cluster,
      RelNode child) {
    super(
        cluster,
        ConventionTraitDef.INSTANCE,
        cluster.traitSetOf(Convention.NONE),
        child);
  }

  //~ Methods ----------------------------------------------------------------


  public RelNode copy(RelTraitSet traitSet, List<RelNode> inputs) {
    assert traitSet.comprises(Convention.NONE);
    return new NoneConverterRel(
        getCluster(),
        sole(inputs));
  }

  public static void init(RelOptPlanner planner) {
    // we can't convert from any conventions, therefore no rules to register
    Util.discard(planner);
  }
}

// End NoneConverterRel.java


<|start_filename|>core/src/main/java/net/hydromatic/optiq/model/JsonMaterialization.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.model;

/**
 * Element that describes how a table is a materialization of a query.
 *
 * @see JsonRoot Description of schema elements
 */
public class JsonMaterialization {
  public String view;
  public String table;
  public String sql;

  public void accept(ModelHandler handler) {
    handler.visit(this);
  }

  @Override
  public String toString() {
    return "JsonMaterialization(table=" + table + ", view=" + view + ")";
  }
}

// End JsonMaterialization.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/validate/AggregatingScope.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql.validate;

import org.eigenbase.sql.*;

/**
 * An extension to the {@link SqlValidatorScope} interface which indicates that
 * the scope is aggregating.
 *
 * <p>A scope which is aggregating must implement this interface. Such a scope
 * will return the same set of identifiers as its parent scope, but some of
 * those identifiers may not be accessible because they are not in the GROUP BY
 * clause.
 */
public interface AggregatingScope extends SqlValidatorScope {
  //~ Methods ----------------------------------------------------------------

  /**
   * Checks whether an expression is constant within the GROUP BY clause. If
   * the expression completely matches an expression in the GROUP BY clause,
   * returns true. If the expression is constant within the group, but does
   * not exactly match, returns false. If the expression is not constant,
   * throws an exception. Examples:
   *
   * <ul>
   * <li>If we are 'f(b, c)' in 'SELECT a + f(b, c) FROM t GROUP BY a', then
   * the whole expression matches a group column. Return true.
   * <li>Just an ordinary expression in a GROUP BY query, such as 'f(SUM(a),
   * 1, b)' in 'SELECT f(SUM(a), 1, b) FROM t GROUP BY b'. Returns false.
   * <li>Illegal expression, such as 'f(5, a, b)' in 'SELECT f(a, b) FROM t
   * GROUP BY a'. Throws when it enounters the 'b' operand, because it is not
   * in the group clause.
   * </ul>
   */
  boolean checkAggregateExpr(SqlNode expr, boolean deep);
}

// End AggregatingScope.java


<|start_filename|>core/src/main/java/net/hydromatic/optiq/util/graph/DepthFirstIterator.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.util.graph;

import java.util.*;

/**
 * Iterates over the vertices in a directed graph in depth-first order.
 *
 * @param <V> Vertex type
 * @param <E> Edge type
 */
public class DepthFirstIterator<V, E extends DefaultEdge>
    implements Iterator<V> {

  private final Iterator<V> iterator;

  public DepthFirstIterator(DirectedGraph<V, E> graph, V start) {
    // Dumb implementation that builds the list first.
    List<V> list = buildList(graph, start);
    iterator = list.iterator();
  }

  public static <V, E extends DefaultEdge> Iterable<V> of(
      final DirectedGraph<V, E> graph, final V start) {
    return new Iterable<V>() {
      public Iterator<V> iterator() {
        return new DepthFirstIterator<V, E>(graph, start);
      }
    };
  }

  private List<V> buildList(DirectedGraph<V, E> graph, V start) {
    final List<V> list = new ArrayList<V>();
    buildListRecurse(list, new HashSet<V>(), graph, start);
    return list;
  }

  private void buildListRecurse(List<V> list,
      Set<V> activeVertices,
      DirectedGraph<V, E> graph,
      V start) {
    if (!activeVertices.add(start)) {
      return;
    }
    list.add(start);
    List<E> edges = graph.getOutwardEdges(start);
    for (E edge : edges) {
      //noinspection unchecked
      buildListRecurse(list, activeVertices, graph, (V) edge.target);
    }
    activeVertices.remove(start);
  }

  public boolean hasNext() {
    return iterator.hasNext();
  }

  public V next() {
    return iterator.next();
  }

  public void remove() {
    throw new UnsupportedOperationException();
  }
}

// End DepthFirstIterator.java


<|start_filename|>core/src/main/java/org/eigenbase/rel/JoinRel.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel;

import java.util.*;

import org.eigenbase.relopt.*;
import org.eigenbase.reltype.RelDataTypeField;
import org.eigenbase.rex.*;

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

/**
 * A JoinRel represents two relational expressions joined according to some
 * condition.
 *
 * <p>Some rules:
 *
 * <ul> <li>{@link org.eigenbase.rel.rules.ExtractJoinFilterRule} converts an
 * {@link JoinRel inner join} to a {@link FilterRel filter} on top of a {@link
 * JoinRel cartesian inner join}.  <li>{@code
 * net.sf.farrago.fennel.rel.FennelCartesianJoinRule} implements a JoinRel as a
 * cartesian product.  </ul>
 */
public final class JoinRel extends JoinRelBase {
  //~ Instance fields --------------------------------------------------------

  // NOTE jvs 14-Mar-2006:  Normally we don't use state like this
  // to control rule firing, but due to the non-local nature of
  // semijoin optimizations, it's pretty much required.
  private final boolean semiJoinDone;

  private List<RelDataTypeField> systemFieldList;

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

  /**
   * Creates a JoinRel.
   *
   * @param cluster          Cluster
   * @param left             Left input
   * @param right            Right input
   * @param condition        Join condition
   * @param joinType         Join type
   * @param variablesStopped Set of names of variables which are set by the
   *                         LHS and used by the RHS and are not available to
   *                         nodes above this JoinRel in the tree
   */
  public JoinRel(
      RelOptCluster cluster,
      RelNode left,
      RelNode right,
      RexNode condition,
      JoinRelType joinType,
      Set<String> variablesStopped) {
    this(
        cluster,
        left,
        right,
        condition,
        joinType,
        variablesStopped,
        false,
        Collections.<RelDataTypeField>emptyList());
  }

  /**
   * Creates a JoinRel, flagged with whether it has been translated to a
   * semi-join.
   *
   * @param cluster          Cluster
   * @param left             Left input
   * @param right            Right input
   * @param condition        Join condition
   * @param joinType         Join type
   * @param variablesStopped Set of names of variables which are set by the
   *                         LHS and used by the RHS and are not available to
   *                         nodes above this JoinRel in the tree
   * @param semiJoinDone     Whether this join has been translated to a
   *                         semi-join
   * @param systemFieldList  List of system fields that will be prefixed to
   *                         output row type; typically empty but must not be
   *                         null
   * @see #isSemiJoinDone()
   */
  public JoinRel(
      RelOptCluster cluster,
      RelNode left,
      RelNode right,
      RexNode condition,
      JoinRelType joinType,
      Set<String> variablesStopped,
      boolean semiJoinDone,
      List<RelDataTypeField> systemFieldList) {
    super(
        cluster,
        cluster.traitSetOf(Convention.NONE),
        left,
        right,
        condition,
        joinType,
        variablesStopped);
    assert systemFieldList != null;
    this.semiJoinDone = semiJoinDone;
    this.systemFieldList = systemFieldList;
  }

  /**
   * Creates a JoinRel by parsing serialized output.
   */
  public JoinRel(RelInput input) {
    this(
        input.getCluster(), input.getInputs().get(0),
        input.getInputs().get(1), input.getExpression("condition"),
        input.getEnum("joinType", JoinRelType.class),
        ImmutableSet.<String>of(), false,
        ImmutableList.<RelDataTypeField>of());
  }

  //~ Methods ----------------------------------------------------------------

  @Override
  public JoinRel copy(RelTraitSet traitSet, RexNode conditionExpr, RelNode left,
      RelNode right, JoinRelType joinType) {
    assert traitSet.containsIfApplicable(Convention.NONE);
    return new JoinRel(
        getCluster(),
        left,
        right,
        conditionExpr,
        this.joinType,
        this.variablesStopped,
        this.semiJoinDone,
        systemFieldList);
  }

  @Override
  public RelNode accept(RelShuttle shuttle) {
    return shuttle.visit(this);
  }

  public RelWriter explainTerms(RelWriter pw) {
    // NOTE jvs 14-Mar-2006: Do it this way so that semijoin state
    // don't clutter things up in optimizers that don't use semijoins
    if (!semiJoinDone) {
      return super.explainTerms(pw);
    }
    return super.explainTerms(pw)
        .item("semiJoinDone", semiJoinDone);
  }

  /**
   * Returns whether this JoinRel has already spawned a {@link
   * org.eigenbase.rel.rules.SemiJoinRel} via {@link
   * org.eigenbase.rel.rules.AddRedundantSemiJoinRule}.
   *
   * @return whether this join has already spawned a semi join
   */
  public boolean isSemiJoinDone() {
    return semiJoinDone;
  }

  public List<RelDataTypeField> getSystemFieldList() {
    return systemFieldList;
  }
}

// End JoinRel.java


<|start_filename|>core/src/main/java/org/eigenbase/jdbc4/package-info.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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.
*/

/**
 * Provides source compatibility gunk when building a JDBC 4.0 driver
 * implementation against JDK 1.5. For more information, see
 * <a href="http://pub.eigenbase.org/wiki/Jdbc4Transition">Eigenpedia</a>.
 */
package org.eigenbase.jdbc4;

// End package-info.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/type/SqlTypeTransformCascade.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql.type;

import org.eigenbase.reltype.*;
import org.eigenbase.sql.*;

import com.google.common.collect.ImmutableList;

/**
 * Strategy to infer the type of an operator call from the type of the operands
 * by using one {@link SqlReturnTypeInference} rule and a combination of {@link
 * SqlTypeTransform}s
 */
public class SqlTypeTransformCascade implements SqlReturnTypeInference {
  //~ Instance fields --------------------------------------------------------

  private final SqlReturnTypeInference rule;
  private final ImmutableList<SqlTypeTransform> transforms;

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

  /**
   * Creates a SqlTypeTransformCascade from a rule and an array of one or more
   * transforms.
   */
  public SqlTypeTransformCascade(
      SqlReturnTypeInference rule,
      SqlTypeTransform... transforms) {
    assert rule != null;
    assert transforms.length > 0;
    this.rule = rule;
    this.transforms = ImmutableList.copyOf(transforms);
  }

  //~ Methods ----------------------------------------------------------------

  public RelDataType inferReturnType(
      SqlOperatorBinding opBinding) {
    RelDataType ret = rule.inferReturnType(opBinding);
    if (ret == null) {
      // inferReturnType may return null; transformType does not accept or
      // return null types
      return null;
    }
    for (SqlTypeTransform transform : transforms) {
      ret = transform.transformType(opBinding, ret);
    }
    return ret;
  }
}

// End SqlTypeTransformCascade.java


<|start_filename|>spark/src/main/java/net/hydromatic/optiq/impl/spark/JdbcToSparkConverter.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.impl.spark;

import net.hydromatic.linq4j.expressions.*;

import net.hydromatic.optiq.BuiltinMethod;
import net.hydromatic.optiq.impl.java.JavaTypeFactory;
import net.hydromatic.optiq.impl.jdbc.*;
import net.hydromatic.optiq.prepare.OptiqPrepareImpl;
import net.hydromatic.optiq.rules.java.*;

import org.eigenbase.rel.RelNode;
import org.eigenbase.rel.convert.ConverterRelImpl;
import org.eigenbase.relopt.*;
import org.eigenbase.sql.SqlDialect;

import java.util.ArrayList;
import java.util.List;

/**
 * Relational expression representing a scan of a table in a JDBC data source
 * that returns its results as a Spark RDD.
 */
public class JdbcToSparkConverter
    extends ConverterRelImpl
    implements SparkRel {
  protected JdbcToSparkConverter(RelOptCluster cluster, RelTraitSet traits,
      RelNode input) {
    super(cluster, ConventionTraitDef.INSTANCE, traits, input);
  }

  @Override
  public RelNode copy(RelTraitSet traitSet, List<RelNode> inputs) {
    return new JdbcToSparkConverter(
        getCluster(), traitSet, sole(inputs));
  }

  @Override
  public RelOptCost computeSelfCost(RelOptPlanner planner) {
    return super.computeSelfCost(planner).multiplyBy(.1);
  }

  public SparkRel.Result implementSpark(SparkRel.Implementor implementor) {
    // Generate:
    //   ResultSetEnumerable.of(schema.getDataSource(), "select ...")
    final BlockBuilder list = new BlockBuilder();
    final JdbcRel child = (JdbcRel) getChild();
    final PhysType physType =
        PhysTypeImpl.of(
            implementor.getTypeFactory(), getRowType(),
            JavaRowFormat.CUSTOM);
    final JdbcConvention jdbcConvention =
        (JdbcConvention) child.getConvention();
    String sql = generateSql(jdbcConvention.dialect);
    if (OptiqPrepareImpl.DEBUG) {
      System.out.println("[" + sql + "]");
    }
    final Expression sqlLiteral =
        list.append("sql", Expressions.constant(sql));
    final List<Primitive> primitives = new ArrayList<Primitive>();
    for (int i = 0; i < getRowType().getFieldCount(); i++) {
      final Primitive primitive = Primitive.ofBoxOr(physType.fieldClass(i));
      primitives.add(primitive != null ? primitive : Primitive.OTHER);
    }
    final Expression primitivesLiteral =
        list.append("primitives",
            Expressions.constant(
                primitives.toArray(new Primitive[primitives.size()])));
    final Expression enumerable =
        list.append(
            "enumerable",
            Expressions.call(
                BuiltinMethod.RESULT_SET_ENUMERABLE_OF.method,
                Expressions.call(
                    Expressions.convert_(
                        jdbcConvention.expression,
                        JdbcSchema.class),
                    BuiltinMethod.JDBC_SCHEMA_DATA_SOURCE.method),
                sqlLiteral,
                primitivesLiteral));
    list.add(
        Expressions.return_(null, enumerable));
    return implementor.result(physType, list.toBlock());
  }

  private String generateSql(SqlDialect dialect) {
    final JdbcImplementor jdbcImplementor =
        new JdbcImplementor(dialect,
            (JavaTypeFactory) getCluster().getTypeFactory());
    final JdbcImplementor.Result result =
        jdbcImplementor.visitChild(0, getChild());
    return result.asQuery().toSqlString(dialect).getSql();
  }
}

// End JdbcToSparkConverter.java


<|start_filename|>core/src/main/java/org/eigenbase/rel/MinusRel.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel;

import java.util.List;

import org.eigenbase.relopt.*;

/**
 * <code>MinusRel</code> returns the rows of its first input minus any matching
 * rows from its other inputs. If "all" is true, then multiset subtraction is
 * performed; otherwise, set subtraction is performed (implying no duplicates in
 * the results).
 */
public final class MinusRel extends MinusRelBase {
  //~ Constructors -----------------------------------------------------------

  public MinusRel(
      RelOptCluster cluster,
      List<RelNode> inputs,
      boolean all) {
    super(
        cluster,
        cluster.traitSetOf(Convention.NONE),
        inputs,
        all);
  }

  /**
   * Creates a MinusRel by parsing serialized output.
   */
  public MinusRel(RelInput input) {
    super(input);
  }

  //~ Methods ----------------------------------------------------------------

  @Override
  public MinusRel copy(
      RelTraitSet traitSet, List<RelNode> inputs, boolean all) {
    assert traitSet.containsIfApplicable(Convention.NONE);
    return new MinusRel(
        getCluster(),
        inputs,
        all);
  }

  @Override
  public RelNode accept(RelShuttle shuttle) {
    return shuttle.visit(this);
  }
}

// End MinusRel.java


<|start_filename|>core/src/main/java/org/eigenbase/rel/UnionRelBase.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel;

import java.util.List;

import org.eigenbase.rel.metadata.*;
import org.eigenbase.relopt.*;

/**
 * <code>UnionRelBase</code> is an abstract base class for implementations of
 * {@link UnionRel}.
 */
public abstract class UnionRelBase extends SetOpRel {
  //~ Constructors -----------------------------------------------------------

  protected UnionRelBase(
      RelOptCluster cluster,
      RelTraitSet traits,
      List<RelNode> inputs,
      boolean all) {
    super(cluster, traits, inputs, all);
  }

  /**
   * Creates a UnionRelBase by parsing serialized output.
   */
  protected UnionRelBase(RelInput input) {
    super(input);
  }

  //~ Methods ----------------------------------------------------------------

  // implement RelNode
  public double getRows() {
    double dRows = estimateRowCount(this);
    if (!all) {
      dRows *= 0.5;
    }
    return dRows;
  }

  /**
   * Helper method for computing row count for UNION ALL.
   *
   * @param rel node representing UNION ALL
   * @return estimated row count for rel
   */
  public static double estimateRowCount(RelNode rel) {
    double dRows = 0;
    for (RelNode input : rel.getInputs()) {
      dRows += RelMetadataQuery.getRowCount(input);
    }
    return dRows;
  }
}

// End UnionRelBase.java


<|start_filename|>core/src/main/java/org/eigenbase/rel/rules/PushProjectPastSetOpRule.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel.rules;

import java.util.*;

import org.eigenbase.rel.*;
import org.eigenbase.relopt.*;
import org.eigenbase.rex.*;

/**
 * PushProjectPastSetOpRule implements the rule for pushing a {@link ProjectRel}
 * past a {@link SetOpRel}. The children of the {@link SetOpRel} will project
 * only the {@link RexInputRef}s referenced in the original {@link ProjectRel}.
 */
public class PushProjectPastSetOpRule extends RelOptRule {
  public static final PushProjectPastSetOpRule INSTANCE =
      new PushProjectPastSetOpRule(PushProjector.ExprCondition.FALSE);

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

  /**
   * Expressions that should be preserved in the projection
   */
  private PushProjector.ExprCondition preserveExprCondition;

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

  /**
   * Creates a PushProjectPastSetOpRule with an explicit condition whether
   * to preserve expressions.
   *
   * @param preserveExprCondition Condition whether to preserve expressions
   */
  public PushProjectPastSetOpRule(
      PushProjector.ExprCondition preserveExprCondition) {
    super(
        operand(
            ProjectRel.class,
            operand(SetOpRel.class, any())));
    this.preserveExprCondition = preserveExprCondition;
  }

  //~ Methods ----------------------------------------------------------------

  // implement RelOptRule
  public void onMatch(RelOptRuleCall call) {
    ProjectRel origProj = call.rel(0);
    SetOpRel setOpRel = call.rel(1);

    // cannot push project past a distinct
    if (!setOpRel.all) {
      return;
    }

    // locate all fields referenced in the projection
    PushProjector pushProject =
        new PushProjector(origProj, null, setOpRel, preserveExprCondition);
    pushProject.locateAllRefs();

    List<RelNode> newSetOpInputs = new ArrayList<RelNode>();
    int[] adjustments = pushProject.getAdjustments();

    // push the projects completely below the setop; this
    // is different from pushing below a join, where we decompose
    // to try to keep expensive expressions above the join,
    // because UNION ALL does not have any filtering effect,
    // and it is the only operator this rule currently acts on
    for (RelNode input : setOpRel.getInputs()) {
      // be lazy:  produce two ProjectRels, and let another rule
      // merge them (could probably just clone origProj instead?)
      ProjectRel p =
          pushProject.createProjectRefsAndExprs(
              input, true, false);
      newSetOpInputs.add(
          pushProject.createNewProject(p, adjustments));
    }

    // create a new setop whose children are the ProjectRels created above
    SetOpRel newSetOpRel =
        setOpRel.copy(setOpRel.getTraitSet(), newSetOpInputs);

    call.transformTo(newSetOpRel);
  }
}

// End PushProjectPastSetOpRule.java


<|start_filename|>core/src/main/java/org/eigenbase/rel/rules/ExtractJoinFilterRule.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel.rules;

import java.util.*;

import org.eigenbase.rel.*;
import org.eigenbase.relopt.*;
import org.eigenbase.reltype.RelDataTypeField;

/**
 * Rule to convert an {@link JoinRel inner join} to a {@link FilterRel filter}
 * on top of a {@link JoinRel cartesian inner join}.
 *
 * <p>One benefit of this transformation is that after it, the join condition
 * can be combined with conditions and expressions above the join. It also makes
 * the <code>FennelCartesianJoinRule</code> applicable.
 */
public final class ExtractJoinFilterRule extends RelOptRule {
  //~ Static fields/initializers ---------------------------------------------

  /** The singleton. */
  public static final ExtractJoinFilterRule INSTANCE =
      new ExtractJoinFilterRule();

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

  /**
   * Creates an ExtractJoinFilterRule.
   */
  private ExtractJoinFilterRule() {
    super(operand(JoinRel.class, any()));
  }

  //~ Methods ----------------------------------------------------------------

  public void onMatch(RelOptRuleCall call) {
    JoinRel joinRel = call.rel(0);

    if (joinRel.getJoinType() != JoinRelType.INNER) {
      return;
    }

    if (joinRel.getCondition().isAlwaysTrue()) {
      return;
    }

    if (!joinRel.getSystemFieldList().isEmpty()) {
      // FIXME Enable this rule for joins with system fields
      return;
    }

    // NOTE jvs 14-Mar-2006:  See SwapJoinRule for why we
    // preserve attribute semiJoinDone here.

    RelNode cartesianJoinRel =
        new JoinRel(
            joinRel.getCluster(),
            joinRel.getLeft(),
            joinRel.getRight(),
            joinRel.getCluster().getRexBuilder().makeLiteral(true),
            joinRel.getJoinType(),
            Collections.<String>emptySet(),
            joinRel.isSemiJoinDone(),
            Collections.<RelDataTypeField>emptyList());

    RelNode filterRel =
        CalcRel.createFilter(
            cartesianJoinRel,
            joinRel.getCondition());

    call.transformTo(filterRel);
  }
}

// End ExtractJoinFilterRule.java


<|start_filename|>core/src/main/java/org/eigenbase/rel/RelFactories.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel;

import java.util.AbstractList;
import java.util.List;

import org.eigenbase.rex.RexNode;

/**
 * Contains factory interface and default implementation for creating various
 * rel nodes.
 */
public class RelFactories {

  public static final ProjectFactory DEFAULT_PROJECT_FACTORY =
      new ProjectFactoryImpl();

  private RelFactories() {
  }

  /**
   * Can create a {@link org.eigenbase.rel.ProjectRel} of the appropriate type
   * for this rule's calling convention.
   */
  public interface ProjectFactory {
    /**
     * Can create a {@link org.eigenbase.rel.ProjectRel} of the appropriate type
     * for this rule's calling convention.
     */
    RelNode createProject(RelNode child, List<RexNode> childExprs,
        List<String> fieldNames);
  }

  /**
   * Implementation of {@link ProjectFactory} that returns vanilla
   * {@link ProjectRel}.
   */
  private static class ProjectFactoryImpl implements ProjectFactory {
    public RelNode createProject(RelNode child, List<RexNode> childExprs,
        List<String> fieldNames) {
      return CalcRel.createProject(child, childExprs, fieldNames);
    }
  }

  /**
   * Creates a relational expression that projects the given fields of the
   * input.
   * <p>
   * Optimizes if the fields are the identity projection.
   * </p>
   * @param factory
   *          ProjectFactory
   * @param child
   *          Input relational expression
   * @param posList
   *          Source of each projected field
   * @return Relational expression that projects given fields
   */
  public static RelNode createProject(final ProjectFactory factory,
      final RelNode child, final List<Integer> posList) {
    if (isIdentity(posList, child.getRowType().getFieldCount())) {
      return child;
    }
    return factory.createProject(child, new AbstractList<RexNode>() {
      public int size() {
        return posList.size();
      }

      public RexNode get(int index) {
        final int pos = posList.get(index);
        return child.getCluster().getRexBuilder().makeInputRef(child, pos);
      }
    }, null);
  }

  private static boolean isIdentity(List<Integer> list, int count) {
    if (list.size() != count) {
      return false;
    }
    for (int i = 0; i < count; i++) {
      final Integer o = list.get(i);
      if (o == null || o != i) {
        return false;
      }
    }
    return true;
  }

}


<|start_filename|>core/src/main/java/org/eigenbase/sql/util/ListSqlOperatorTable.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql.util;

import java.util.*;

import org.eigenbase.sql.*;

/**
 * Implementation of the {@link SqlOperatorTable} interface by using a list of
 * {@link SqlOperator operators}.
 */
public class ListSqlOperatorTable implements SqlOperatorTable {
  //~ Instance fields --------------------------------------------------------

  private final List<SqlOperator> operatorList;

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

  public ListSqlOperatorTable() {
    this(new ArrayList<SqlOperator>());
  }

  public ListSqlOperatorTable(List<SqlOperator> operatorList) {
    this.operatorList = operatorList;
  }

  //~ Methods ----------------------------------------------------------------

  public void add(SqlOperator op) {
    operatorList.add(op);
  }

  public void lookupOperatorOverloads(SqlIdentifier opName,
      SqlFunctionCategory category,
      SqlSyntax syntax,
      List<SqlOperator> operatorList) {
    for (SqlOperator operator : this.operatorList) {
      if (operator.getSyntax() != syntax) {
        continue;
      }
      if (!opName.isSimple()
          || !operator.isName(opName.getSimple())) {
        continue;
      }
      SqlFunctionCategory functionCategory;
      if (operator instanceof SqlFunction) {
        functionCategory = ((SqlFunction) operator).getFunctionType();
      } else {
        functionCategory = SqlFunctionCategory.SYSTEM;
      }
      if (category != functionCategory
          && category != SqlFunctionCategory.USER_DEFINED_FUNCTION) {
        continue;
      }
      operatorList.add(operator);
    }
  }

  public List<SqlOperator> getOperatorList() {
    return operatorList;
  }
}

// End ListSqlOperatorTable.java


<|start_filename|>core/src/main/java/org/eigenbase/util/ReflectiveVisitor.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.util;

/**
 * Object which can be a target for a reflective visitation (see {@link
 * ReflectUtil#invokeVisitor(ReflectiveVisitor, Object, Class, String)}.
 *
 * <p>This is a tagging interface: it has no methods, and is not even required
 * in order to use reflective visitation, but serves to advise users of the
 * class of the intended use of the class and refer them to auxilliary classes.
 */
public interface ReflectiveVisitor {
}

// End ReflectiveVisitor.java


<|start_filename|>core/src/test/java/net/hydromatic/optiq/tools/TpchSchema.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.tools;

/**
 * TPC-H table schema.
 */
public class TpchSchema {
  public final Part[] part = { p(1), p(2) };
  public final PartSupp[] partsupp = { ps(1, 250), ps(2, 100) };

  /**
   * Part in TPC-H.
   */
  public static class Part {
    public int pPartkey;


    public Part(int pPartkey) {
      super();
      this.pPartkey = pPartkey;
    }

    @Override
    public String toString() {
      return "Part [pPartkey=" + pPartkey + "]";
    }
  }

  /**
   * Part supplier in TPC-H.
   */
  public static class PartSupp {
    public int psPartkey;
    public int psSupplyCost;

    public PartSupp(int psPartkey, int psSupplyCost) {
      super();
      this.psPartkey = psPartkey;
      this.psSupplyCost = psSupplyCost;
    }

    @Override
    public String toString() {
      return "PartSupp [pSupplyCost=" + psPartkey + ", pSupplyCost="
        + psSupplyCost + "]";
    }
  }

  public static PartSupp ps(int pPartkey, int pSupplyCost) {
    return new PartSupp(pPartkey, pSupplyCost);
  }

  public static Part p(int pPartkey) {
    return new Part(pPartkey);
  }
}

// End TpchSchema.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/fun/SqlNullifFunction.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql.fun;

import java.util.List;

import org.eigenbase.sql.*;
import org.eigenbase.sql.parser.*;
import org.eigenbase.sql.type.*;
import org.eigenbase.sql.validate.*;

/**
 * The <code>NULLIF</code> function.
 */
public class SqlNullifFunction extends SqlFunction {
  //~ Constructors -----------------------------------------------------------

  public SqlNullifFunction() {
    // NOTE jvs 26-July-2006:  We fill in the type strategies here,
    // but normally they are not used because the validator invokes
    // rewriteCall to convert NULLIF into CASE early.  However,
    // validator rewrite can optionally be disabled, in which case these
    // strategies are used.
    super(
        "NULLIF",
        SqlKind.OTHER_FUNCTION,
        ReturnTypes.ARG0_FORCE_NULLABLE,
        null,
        OperandTypes.COMPARABLE_UNORDERED_COMPARABLE_UNORDERED,
        SqlFunctionCategory.SYSTEM);
  }

  //~ Methods ----------------------------------------------------------------

  // override SqlOperator
  public SqlNode rewriteCall(SqlValidator validator, SqlCall call) {
    List<SqlNode> operands = call.getOperandList();
    SqlParserPos pos = call.getParserPosition();

    checkOperandCount(
        validator,
        getOperandTypeChecker(),
        call);
    assert operands.size() == 2;

    SqlNodeList whenList = new SqlNodeList(pos);
    SqlNodeList thenList = new SqlNodeList(pos);
    whenList.add(operands.get(1));
    thenList.add(SqlLiteral.createNull(SqlParserPos.ZERO));
    return SqlCase.createSwitched(
        pos, operands.get(0), whenList, thenList, operands.get(0).clone(
        operands.get(0).getParserPosition()));
  }
}

// End SqlNullifFunction.java


<|start_filename|>core/src/main/java/org/eigenbase/rel/IntersectRel.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel;

import java.util.List;

import org.eigenbase.relopt.*;

/**
 * <code>IntersectRel</code> returns the intersection of the rows of its inputs.
 * If "all" is true, then multiset intersection is performed; otherwise, set
 * intersection is performed (implying no duplicates in the results).
 */
public final class IntersectRel extends IntersectRelBase {
  //~ Constructors -----------------------------------------------------------

  public IntersectRel(
      RelOptCluster cluster,
      List<RelNode> inputs,
      boolean all) {
    super(
        cluster,
        cluster.traitSetOf(Convention.NONE),
        inputs,
        all);
  }

  /**
   * Creates an IntersectRel by parsing serialized output.
   */
  public IntersectRel(RelInput input) {
    super(input);
  }

  //~ Methods ----------------------------------------------------------------

  @Override
  public IntersectRel copy(
      RelTraitSet traitSet, List<RelNode> inputs, boolean all) {
    assert traitSet.containsIfApplicable(Convention.NONE);
    return new IntersectRel(
        getCluster(),
        inputs,
        all);
  }

  @Override
  public RelNode accept(RelShuttle shuttle) {
    return shuttle.visit(this);
  }
}

// End IntersectRel.java


<|start_filename|>core/src/main/java/net/hydromatic/optiq/model/JsonFunction.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.model;

import java.util.List;

/**
 * Function schema element.
 *
 * @see JsonRoot Description of schema elements
 */
public class JsonFunction {
  public String name;
  public String className;
  public List<String> path;

  public void accept(ModelHandler handler) {
    handler.visit(this);
  }
}

// End JsonFunction.java


<|start_filename|>core/src/main/java/org/eigenbase/rel/JoinRelType.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel;

/**
 * Enumeration of join types.
 */
public enum JoinRelType {
  INNER, LEFT, RIGHT, FULL;

  /**
   * Returns whether a join of this type may generate NULL values on the
   * right-hand side.
   */
  public boolean generatesNullsOnRight() {
    return (this == LEFT) || (this == FULL);
  }

  /**
   * Returns whether a join of this type may generate NULL values on the
   * left-hand side.
   */
  public boolean generatesNullsOnLeft() {
    return (this == RIGHT) || (this == FULL);
  }

  /**
   * Swaps left to right, and vice versa.
   */
  public JoinRelType swap() {
    switch (this) {
    case LEFT:
      return RIGHT;
    case RIGHT:
      return LEFT;
    default:
      return this;
    }
  }

  /** Returns whether this join type generates nulls on side #{@code i}. */
  public boolean generatesNullsOn(int i) {
    switch (i) {
    case 0:
      return generatesNullsOnLeft();
    case 1:
      return generatesNullsOnRight();
    default:
      throw new IllegalArgumentException("invalid: " + i);
    }
  }
}

// End JoinRelType.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/type/LiteralOperandTypeChecker.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql.type;

import org.eigenbase.sql.*;
import org.eigenbase.util.*;

import static org.eigenbase.util.Static.RESOURCE;

/**
 * Parameter type-checking strategy type must be a literal (whether null is
 * allowed is determined by the constructor). <code>CAST(NULL as ...)</code> is
 * considered to be a NULL literal but not <code>CAST(CAST(NULL as ...) AS
 * ...)</code>
 */
public class LiteralOperandTypeChecker implements SqlSingleOperandTypeChecker {
  //~ Instance fields --------------------------------------------------------

  private boolean allowNull;

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

  public LiteralOperandTypeChecker(boolean allowNull) {
    this.allowNull = allowNull;
  }

  //~ Methods ----------------------------------------------------------------

  public boolean checkSingleOperandType(
      SqlCallBinding callBinding,
      SqlNode node,
      int iFormalOperand,
      boolean throwOnFailure) {
    Util.discard(iFormalOperand);

    if (SqlUtil.isNullLiteral(node, true)) {
      if (allowNull) {
        return true;
      }
      if (throwOnFailure) {
        throw callBinding.newError(
            RESOURCE.argumentMustNotBeNull(
                callBinding.getOperator().getName()));
      }
      return false;
    }
    if (!SqlUtil.isLiteral(node) && !SqlUtil.isLiteralChain(node)) {
      if (throwOnFailure) {
        throw callBinding.newError(
            RESOURCE.argumentMustBeLiteral(
                callBinding.getOperator().getName()));
      }
      return false;
    }

    return true;
  }

  public boolean checkOperandTypes(
      SqlCallBinding callBinding,
      boolean throwOnFailure) {
    return checkSingleOperandType(
        callBinding,
        callBinding.getCall().operand(0),
        0,
        throwOnFailure);
  }

  public SqlOperandCountRange getOperandCountRange() {
    return SqlOperandCountRanges.of(1);
  }

  public String getAllowedSignatures(SqlOperator op, String opName) {
    return "<LITERAL>";
  }
}

// End LiteralOperandTypeChecker.java


<|start_filename|>core/src/main/java/net/hydromatic/optiq/runtime/RecordEnumeratorCursor.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.runtime;

import net.hydromatic.linq4j.Enumerator;

import java.lang.reflect.Field;

/**
 * Implementation of {@link net.hydromatic.avatica.Cursor} on top of an
 * {@link net.hydromatic.linq4j.Enumerator} that
 * returns a record for each row. The record is a synthetic class whose fields
 * are all public.
 *
 * @param <E> Element type
 */
public class RecordEnumeratorCursor<E> extends EnumeratorCursor<E> {
  private final Class<E> clazz;

  /**
   * Creates a RecordEnumeratorCursor.
   *
   * @param enumerator Enumerator
   * @param clazz Element type
   */
  public RecordEnumeratorCursor(
      Enumerator<E> enumerator,
      Class<E> clazz) {
    super(enumerator);
    this.clazz = clazz;
  }

  protected Getter createGetter(int ordinal) {
    return new RecordEnumeratorGetter(clazz.getFields()[ordinal]);
  }

  /** Implementation of {@link Getter} that reads fields via reflection. */
  class RecordEnumeratorGetter extends AbstractGetter {
    protected final Field field;

    public RecordEnumeratorGetter(Field field) {
      this.field = field;
    }

    public Object getObject() {
      Object o;
      try {
        o = field.get(current());
      } catch (IllegalAccessException e) {
        throw new RuntimeException(e);
      }
      wasNull[0] = o == null;
      return o;
    }
  }
}

// End RecordEnumeratorCursor.java


<|start_filename|>core/src/main/java/org/eigenbase/rex/RexAction.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rex;

/**
 * A <code>RexAction</code> is called when a {@link RexPattern} finds a match.
 * It yields a {@link RexNode} by substituting the matching tokens.
 */
public interface RexAction {
  //~ Methods ----------------------------------------------------------------

  void onMatch(RexNode[] tokens);
}

// End RexAction.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/fun/SqlMapValueConstructor.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql.fun;

import java.util.List;

import org.eigenbase.reltype.RelDataType;
import org.eigenbase.reltype.RelDataTypeFactory;
import org.eigenbase.sql.*;
import org.eigenbase.sql.type.SqlTypeUtil;
import org.eigenbase.util.Pair;
import org.eigenbase.util.Util;

import static org.eigenbase.util.Static.RESOURCE;

/**
 * Definition of the MAP constructor,
 * <code>MAP [&lt;key&gt;, &lt;value&gt;, ...]</code>.
 *
 * <p>This is an extension to standard SQL.</p>
 */
public class SqlMapValueConstructor extends SqlMultisetValueConstructor {
  public SqlMapValueConstructor() {
    super("MAP", SqlKind.MAP_VALUE_CONSTRUCTOR);
  }

  @Override
  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
    Pair<RelDataType, RelDataType> type =
        getComponentTypes(
            opBinding.getTypeFactory(), opBinding.collectOperandTypes());
    if (null == type) {
      return null;
    }
    return SqlTypeUtil.createMapType(
        opBinding.getTypeFactory(),
        type.left,
        type.right,
        false);
  }

  public boolean checkOperandTypes(
      SqlCallBinding callBinding,
      boolean throwOnFailure) {
    final List<RelDataType> argTypes =
        SqlTypeUtil.deriveAndCollectTypes(
            callBinding.getValidator(),
            callBinding.getScope(),
            callBinding.getCall().getOperandList());
    if (argTypes.size() == 0) {
      throw callBinding.newValidationError(RESOURCE.mapRequiresTwoOrMoreArgs());
    }
    if (argTypes.size() % 2 > 0) {
      throw callBinding.newValidationError(RESOURCE.mapRequiresEvenArgCount());
    }
    final Pair<RelDataType, RelDataType> componentType =
        getComponentTypes(
            callBinding.getTypeFactory(), argTypes);
    if (null == componentType.left || null == componentType.right) {
      if (throwOnFailure) {
        throw callBinding.newValidationError(RESOURCE.needSameTypeParameter());
      }
      return false;
    }
    return true;
  }

  private Pair<RelDataType, RelDataType> getComponentTypes(
      RelDataTypeFactory typeFactory,
      List<RelDataType> argTypes) {
    return Pair.of(
        typeFactory.leastRestrictive(Util.quotientList(argTypes, 2, 0)),
        typeFactory.leastRestrictive(Util.quotientList(argTypes, 2, 1)));
  }
}

// End SqlMapValueConstructor.java


<|start_filename|>core/src/main/java/org/eigenbase/javac/JavaCompiler.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.javac;

/**
 * The interface <code>JavaCompiler</code> represents an interface to invoke a
 * regular Java compiler. Classes implementing this interface should accept the
 * same arguments as Sun's javac.
 */
public interface JavaCompiler {
  //~ Methods ----------------------------------------------------------------

  void compile();

  JavaCompilerArgs getArgs();

  ClassLoader getClassLoader();

  int getTotalByteCodeSize();
}

// End JavaCompiler.java


<|start_filename|>avatica/src/main/java/net/hydromatic/avatica/Quoting.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.avatica;

/** Syntax for quoting identifiers in SQL statements. */
public enum Quoting {
  /** Quote identifiers in double-quotes. For example, {@code "my id"}. */
  DOUBLE_QUOTE("\""),

  /** Quote identifiers in back-quotes. For example, {@code `my id`}. */
  BACK_TICK("`"),

  /** Quote identifiers in brackets. For example, {@code [my id]}. */
  BRACKET("[");

  public String string;

  Quoting(String string) {
    this.string = string;
  }
}

// End Quoting.java


<|start_filename|>core/src/main/java/org/eigenbase/rel/MinusRelBase.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel;

import java.util.BitSet;
import java.util.List;

import org.eigenbase.rel.metadata.RelMetadataQuery;
import org.eigenbase.relopt.RelOptCluster;
import org.eigenbase.relopt.RelTraitSet;

/**
 * Abstract base class for implementations of
 * {@link MinusRel}.
 */
public abstract class MinusRelBase extends SetOpRel {
  public MinusRelBase(
      RelOptCluster cluster,
      RelTraitSet traits,
      List<RelNode> inputs,
      boolean all) {
    super(cluster, traits, inputs, all);
  }

  /**
   * Creates a MinusRelBase by parsing serialized output.
   */
  protected MinusRelBase(RelInput input) {
    super(input);
  }

  @Override
  public double getRows() {
    // REVIEW jvs 30-May-2005:  I just pulled this out of a hat.
    double dRows = RelMetadataQuery.getRowCount(inputs.get(0));
    for (int i = 1; i < inputs.size(); i++) {
      dRows -= 0.5 * RelMetadataQuery.getRowCount(inputs.get(i));
    }
    if (dRows < 0) {
      dRows = 0;
    }
    return dRows;
  }

  @Override
  public boolean isKey(BitSet columns) {
    return inputs.get(0).isKey(columns)
        || super.isKey(columns);
  }
}

// End MinusRelBase.java


<|start_filename|>core/src/main/java/org/eigenbase/rel/EmptyRel.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel;

import java.util.List;

import org.eigenbase.relopt.*;
import org.eigenbase.reltype.*;
import org.eigenbase.sql.*;

/**
 * <code>EmptyRel</code> represents a relational expression with zero rows.
 *
 * <p>EmptyRel can not be implemented, but serves as a token for rules to match
 * so that empty sections of queries can be eliminated.
 *
 * <p>Rules:
 *
 * <ul>
 * <li>Created by {@code net.sf.farrago.query.FarragoReduceValuesRule}</li>
 * <li>Triggers {@link org.eigenbase.rel.rules.RemoveEmptyRules}</li>
 * </ul>
 *
 * @see org.eigenbase.rel.ValuesRel
 */
public class EmptyRel extends AbstractRelNode {
  //~ Constructors -----------------------------------------------------------

  /**
   * Creates a new EmptyRel.
   *
   * @param cluster Cluster
   * @param rowType row type for tuples which would be produced by this rel if
   *                it actually produced any, but it doesn't (see, philosophy is
   *                good for something after all!)
   */
  public EmptyRel(
      RelOptCluster cluster,
      RelDataType rowType) {
    super(
        cluster,
        cluster.traitSetOf(Convention.NONE));
    this.rowType = rowType;
  }

  //~ Methods ----------------------------------------------------------------

  public RelNode copy(RelTraitSet traitSet, List<RelNode> inputs) {
    assert traitSet.comprises(Convention.NONE);
    assert inputs.isEmpty();
    // immutable with no children
    return this;
  }

  // implement RelNode
  protected RelDataType deriveRowType() {
    return rowType;
  }

  // implement RelNode
  public RelOptCost computeSelfCost(RelOptPlanner planner) {
    return planner.getCostFactory().makeZeroCost();
  }

  // implement RelNode
  public double getRows() {
    return 0.0;
  }

  // implement RelNode
  public RelWriter explainTerms(RelWriter pw) {
    return super.explainTerms(pw)
        // For rel digest, include the row type to discriminate
        // this from other empties with different row types.
        // For normal EXPLAIN PLAN, omit the type.
        .itemIf(
            "type",
            rowType,
            pw.getDetailLevel() == SqlExplainLevel.DIGEST_ATTRIBUTES);
  }
}

// End EmptyRel.java


<|start_filename|>core/src/main/java/net/hydromatic/optiq/materialize/MaterializationKey.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.materialize;

import java.io.Serializable;
import java.util.UUID;

/**
 * Unique identifier for a materialization.
 *
 * <p>It is immutable and can only be created by the
 * {@link MaterializationService}. For communicating with the service.</p>
 */
public class MaterializationKey implements Serializable {
  private final UUID uuid = UUID.randomUUID();

  @Override
  public int hashCode() {
    return uuid.hashCode();
  }

  @Override
  public boolean equals(Object obj) {
    return this == obj
        || obj instanceof MaterializationKey
        && uuid.equals(((MaterializationKey) obj).uuid);
  }

  @Override
  public String toString() {
    return uuid.toString();
  }
}

// End MaterializationKey.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/type/IntervalSqlType.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql.type;

import org.eigenbase.reltype.*;
import org.eigenbase.sql.*;
import org.eigenbase.sql.parser.*;

/**
 * IntervalSqlType represents a standard SQL datetime interval type.
 */
public class IntervalSqlType extends AbstractSqlType {
  //~ Instance fields --------------------------------------------------------

  private SqlIntervalQualifier intervalQualifier;

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

  /**
   * Constructs an IntervalSqlType. This should only be called from a factory
   * method.
   */
  public IntervalSqlType(
      SqlIntervalQualifier intervalQualifier,
      boolean isNullable) {
    super(
        intervalQualifier.isYearMonth() ? SqlTypeName.INTERVAL_YEAR_MONTH
            : SqlTypeName.INTERVAL_DAY_TIME,
        isNullable,
        null);
    this.intervalQualifier = intervalQualifier;
    computeDigest();
  }

  //~ Methods ----------------------------------------------------------------

  // implement RelDataTypeImpl
  protected void generateTypeString(StringBuilder sb, boolean withDetail) {
    sb.append("INTERVAL ");
    sb.append(intervalQualifier.toString());
  }

  // implement RelDataType
  public SqlIntervalQualifier getIntervalQualifier() {
    return intervalQualifier;
  }

  /**
   * Combines two IntervalTypes and returns the result. E.g. the result of
   * combining<br>
   * <code>INTERVAL DAY TO HOUR</code><br>
   * with<br>
   * <code>INTERVAL SECOND</code> is<br>
   * <code>INTERVAL DAY TO SECOND</code>
   */
  public IntervalSqlType combine(
      RelDataTypeFactoryImpl typeFactory,
      IntervalSqlType that) {
    assert this.intervalQualifier.isYearMonth()
        == that.intervalQualifier.isYearMonth();
    boolean nullable = isNullable || that.isNullable;
    SqlIntervalQualifier.TimeUnit thisStart =
        this.intervalQualifier.getStartUnit();
    SqlIntervalQualifier.TimeUnit thisEnd =
        this.intervalQualifier.getEndUnit();
    SqlIntervalQualifier.TimeUnit thatStart =
        that.intervalQualifier.getStartUnit();
    SqlIntervalQualifier.TimeUnit thatEnd =
        that.intervalQualifier.getEndUnit();

    assert null != thisStart;
    assert null != thatStart;

    int secondPrec =
        this.intervalQualifier.getStartPrecisionPreservingDefault();
    int fracPrec =
        SqlIntervalQualifier
            .combineFractionalSecondPrecisionPreservingDefault(
                this.intervalQualifier,
                that.intervalQualifier);

    if (thisStart.ordinal() > thatStart.ordinal()) {
      thisEnd = thisStart;
      thisStart = thatStart;
      secondPrec =
          that.intervalQualifier.getStartPrecisionPreservingDefault();
    } else if (thisStart.ordinal() == thatStart.ordinal()) {
      secondPrec =
          SqlIntervalQualifier.combineStartPrecisionPreservingDefault(
              this.intervalQualifier,
              that.intervalQualifier);
    } else if (
        (null == thisEnd)
            || (thisEnd.ordinal() < thatStart.ordinal())) {
      thisEnd = thatStart;
    }

    if (null != thatEnd) {
      if ((null == thisEnd)
          || (thisEnd.ordinal() < thatEnd.ordinal())) {
        thisEnd = thatEnd;
      }
    }

    RelDataType intervalType =
        typeFactory.createSqlIntervalType(
            new SqlIntervalQualifier(
                thisStart,
                secondPrec,
                thisEnd,
                fracPrec,
                SqlParserPos.ZERO));
    intervalType =
        typeFactory.createTypeWithNullability(
            intervalType,
            nullable);
    return (IntervalSqlType) intervalType;
  }

  // implement RelDataType
  public int getPrecision() {
    return intervalQualifier.getStartPrecision();
  }

  @Override
  public int getScale() {
    // TODO Auto-generated method stub
    return intervalQualifier.getFractionalSecondPrecision();
  }

}

// End IntervalSqlType.java


<|start_filename|>core/src/main/java/org/eigenbase/rel/ValuesRelBase.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel;

import java.util.*;

import org.eigenbase.rel.metadata.*;
import org.eigenbase.relopt.*;
import org.eigenbase.reltype.*;
import org.eigenbase.rex.*;
import org.eigenbase.sql.*;
import org.eigenbase.sql.type.*;
import org.eigenbase.util.Pair;

import net.hydromatic.linq4j.function.Function1;
import net.hydromatic.linq4j.function.Functions;

/**
 * <code>ValuesRelBase</code> is an abstract base class for implementations of
 * {@link ValuesRel}.
 */
public abstract class ValuesRelBase extends AbstractRelNode {
  /**
   * Lambda that helps render tuples as strings.
   */
  private static final Function1<List<RexLiteral>, Object> F =
      new Function1<List<RexLiteral>, Object>() {
        public Object apply(List<RexLiteral> tuple) {
          String s = tuple.toString();
          assert s.startsWith("[");
          assert s.endsWith("]");
          return "{ " + s.substring(1, s.length() - 1) + " }";
        }
      };

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

  protected final List<List<RexLiteral>> tuples;

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

  /**
   * Creates a new ValuesRelBase. 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 .
   * @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 ValuesRelBase(
      RelOptCluster cluster,
      RelDataType rowType,
      List<List<RexLiteral>> tuples,
      RelTraitSet traits) {
    super(cluster, traits);
    this.rowType = rowType;
    this.tuples = tuples;
    assert assertRowType();
  }

  /**
   * Creates a ValuesRelBase by parsing serialized output.
   */
  public ValuesRelBase(RelInput input) {
    this(
        input.getCluster(), input.getRowType("type"),
        input.getTuples("tuples"), input.getTraitSet());
  }

  //~ Methods ----------------------------------------------------------------

  public List<List<RexLiteral>> getTuples(RelInput input) {
    return input.getTuples("tuples");
  }

  /**
   * @return rows of literals represented by this rel
   */
  public List<List<RexLiteral>> getTuples() {
    return tuples;
  }

  /**
   * @return true if all tuples match rowType; otherwise, assert on mismatch
   */
  private boolean assertRowType() {
    for (List<RexLiteral> tuple : tuples) {
      assert tuple.size() == rowType.getFieldCount();
      for (Pair<RexLiteral, RelDataTypeField> 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;
  }

  // implement RelNode
  protected RelDataType deriveRowType() {
    return rowType;
  }

  // implement RelNode
  public RelOptCost computeSelfCost(RelOptPlanner planner) {
    double dRows = RelMetadataQuery.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 getRows() {
    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.
    return 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())
        .itemIf("tuples", Functions.adapt(tuples, F), !pw.nest())
        .itemIf("tuples", tuples, pw.nest());
  }
}

// End ValuesRelBase.java


<|start_filename|>core/src/main/java/net/hydromatic/optiq/model/JsonRoot.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.model;

import java.util.ArrayList;
import java.util.List;

/**
 * Root schema element.
 *
 * <p>A POJO with fields of {@link Boolean}, {@link String}, {@link ArrayList},
 * {@link java.util.LinkedHashMap}, per Jackson simple data binding.</p>
 *
 * <p>Schema structure is as follows:</p>
 *
 * <pre>{@code Root}
 *   {@link JsonSchema} (in collection {@link JsonRoot#schemas schemas})
 *     {@link JsonTable} (in collection {@link JsonMapSchema#tables tables})
 *       {@link JsonColumn} (in collection {@link JsonTable#columns column}
 *     {@link JsonView}
 *     {@link JsonFunction}  (in collection {@link JsonMapSchema#functions functions})
 * </pre>
 */
public class JsonRoot {
  public String version;
  public String defaultSchema;
  public final List<JsonSchema> schemas = new ArrayList<JsonSchema>();
}

// End JsonRoot.java


<|start_filename|>core/src/main/java/org/eigenbase/rel/rules/PushFilterPastTableFunctionRule.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel.rules;

import java.util.*;

import org.eigenbase.rel.*;
import org.eigenbase.rel.metadata.*;
import org.eigenbase.relopt.*;
import org.eigenbase.reltype.*;
import org.eigenbase.rex.*;

/**
 * PushFilterPastTableFunctionRule implements the rule for pushing a
 * {@link FilterRel} past a {@link TableFunctionRel}.
 */
public class PushFilterPastTableFunctionRule extends RelOptRule {
  public static final PushFilterPastTableFunctionRule INSTANCE =
      new PushFilterPastTableFunctionRule();

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

  /**
   * Creates a PushFilterPastTableFunctionRule.
   */
  private PushFilterPastTableFunctionRule() {
    super(
        operand(
            FilterRel.class,
            operand(TableFunctionRel.class, any())));
  }

  //~ Methods ----------------------------------------------------------------

  // implement RelOptRule
  public void onMatch(RelOptRuleCall call) {
    FilterRel filterRel = call.rel(0);
    TableFunctionRel funcRel = call.rel(1);
    Set<RelColumnMapping> columnMappings = funcRel.getColumnMappings();
    if ((columnMappings == null) || (columnMappings.isEmpty())) {
      // No column mapping information, so no pushdown
      // possible.
      return;
    }

    List<RelNode> funcInputs = funcRel.getInputs();
    if (funcInputs.size() != 1) {
      // TODO:  support more than one relational input; requires
      // offsetting field indices, similar to join
      return;
    }
    // TODO:  support mappings other than 1-to-1
    if (funcRel.getRowType().getFieldCount()
        != funcInputs.get(0).getRowType().getFieldCount()) {
      return;
    }
    for (RelColumnMapping mapping : columnMappings) {
      if (mapping.iInputColumn != mapping.iOutputColumn) {
        return;
      }
      if (mapping.derived) {
        return;
      }
    }
    final List<RelNode> newFuncInputs = new ArrayList<RelNode>();
    final RelOptCluster cluster = funcRel.getCluster();
    final RexNode condition = filterRel.getCondition();

    // create filters on top of each func input, modifying the filter
    // condition to reference the child instead
    RexBuilder rexBuilder = filterRel.getCluster().getRexBuilder();
    List<RelDataTypeField> origFields = funcRel.getRowType().getFieldList();
    // TODO:  these need to be non-zero once we
    // support arbitrary mappings
    int[] adjustments = new int[origFields.size()];
    for (RelNode funcInput : funcInputs) {
      RexNode newCondition =
          condition.accept(
              new RelOptUtil.RexInputConverter(
                  rexBuilder,
                  origFields,
                  funcInput.getRowType().getFieldList(),
                  adjustments));
      newFuncInputs.add(
          new FilterRel(cluster, funcInput, newCondition));
    }

    // create a new UDX whose children are the filters created above
    TableFunctionRel newFuncRel =
        new TableFunctionRel(
            cluster,
            newFuncInputs,
            funcRel.getCall(),
            funcRel.getElementType(), funcRel.getRowType(),
            columnMappings);
    call.transformTo(newFuncRel);
  }
}

// End PushFilterPastTableFunctionRule.java


<|start_filename|>core/src/main/java/org/eigenbase/stat/RelStatColumnStatistics.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.stat;

/**
 * This interface provides results based on column statistics. It may be used to
 * summarize the results of applying a predicate to a column of a relational
 * expression. Alternatively, it may be used to summarize aspects of the entire
 * column.
 */
public interface RelStatColumnStatistics {
  //~ Methods ----------------------------------------------------------------

  /**
   * Estimates the percentage of a relational expression's rows which satisfy
   * a given condition. This corresponds to the metadata query {@link
   * org.eigenbase.rel.metadata.RelMetadataQuery#getSelectivity}.
   *
   * @return an estimated percentage from 0.0 to 1.0 or null if no reliable
   * estimate can be determined
   */
  Double getSelectivity();

  /**
   * Estimates the number of distinct values returned from a relational
   * expression that satisfy a given condition.
   *
   * @return an estimate of the distinct values of a predicate or null if no
   * reliable estimate can be determined
   */
  Double getCardinality();

  /**
   * Determine how many blocks on disk will be read from physical storage
   * to retrieve the column values selected. This corresponds to an
   * attribute set by the Broadbase server. This feature is deferred until
   * we find a use for it
   */
  // public Long getNumBlocks();
}

// End RelStatColumnStatistics.java


<|start_filename|>avatica/src/main/java/net/hydromatic/avatica/Casing.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.avatica;

/** Policy for converting case of identifiers before storing them.
 *
 * <p>A database often has policies for quoted versus unquoted identifiers.
 * For example, Oracle converts unquoted identifiers to upper-case, but
 * quoted identifiers are unchanged.</p> */
public enum Casing {
  /** The case of identifiers is not changed. */
  UNCHANGED,

  /** Identifiers are converted to upper-case. */
  TO_UPPER,

  /** Identifiers are converted to lower-case. */
  TO_LOWER
}

// End Casing.java


<|start_filename|>core/src/main/java/net/hydromatic/optiq/impl/jdbc/JdbcQueryProvider.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.impl.jdbc;

import net.hydromatic.linq4j.*;

/**
 * Implementation of {@link QueryProvider} that talks to JDBC databases.
 */
public final class JdbcQueryProvider extends QueryProviderImpl {
  public static final JdbcQueryProvider INSTANCE = new JdbcQueryProvider();

  private JdbcQueryProvider() {
  }

  public <T> Enumerator<T> executeQuery(Queryable<T> queryable) {
    return null;
  }
}

// End JdbcQueryProvider.java


<|start_filename|>core/src/main/java/org/eigenbase/rel/metadata/RelMetadataProvider.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel.metadata;

import org.eigenbase.rel.*;

import com.google.common.base.Function;

/**
 * RelMetadataProvider defines an interface for obtaining metadata about
 * relational expressions. This interface is weakly-typed and is not intended to
 * be called directly in most contexts; instead, use a strongly-typed facade
 * such as {@link RelMetadataQuery}.
 *
 * <p>For background and motivation, see <a
 * href="http://wiki.eigenbase.org/RelationalExpressionMetadata">wiki</a>.
 */
public interface RelMetadataProvider {
  //~ Methods ----------------------------------------------------------------

  /**
   * Retrieves metadata of a particular type and for a particular sub-class
   * of relational expression.
   *
   * <p>The object returned is a function. It can be applied to a relational
   * expression of the given type to create a metadata object.</p>
   *
   * <p>For example, you might call</p>
   *
   * <blockquote><pre>
   * RelMetadataProvider provider;
   * FilterRel filter;
   * RexNode predicate;
   * Function&lt;RelNode, Metadata&gt; function =
   *   provider.apply(FilterRel.class, Selectivity.class};
   * Selectivity selectivity = function.apply(filter);
   * Double d = selectivity.selectivity(predicate);
   * </pre></blockquote>
   *
   * @param relClass Type of relational expression
   * @param metadataClass Type of metadata
   * @return Function that will field a metadata instance; or null if this
   *     provider cannot supply metadata of this type
   */
  Function<RelNode, Metadata> apply(
      Class<? extends RelNode> relClass,
      Class<? extends Metadata> metadataClass);
}

// End RelMetadataProvider.java


<|start_filename|>core/src/main/java/org/eigenbase/sarg/SargFactory.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sarg;

import org.eigenbase.reltype.*;
import org.eigenbase.rex.*;
import org.eigenbase.sql.*;

/**
 * SargFactory creates new instances of various sarg-related objects.
 */
public class SargFactory {
  //~ Instance fields --------------------------------------------------------

  private final RexBuilder rexBuilder;

  private final RexNode rexNull;

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

  /**
   * Creates a new SargFactory.
   *
   * @param rexBuilder factory for instances of {@link RexNode}, needed
   *                   internally in the sarg representation, and also for
   *                   recomposing sargs into equivalent rex trees
   */
  public SargFactory(RexBuilder rexBuilder) {
    this.rexBuilder = rexBuilder;
    rexNull = rexBuilder.constantNull();
  }

  //~ Methods ----------------------------------------------------------------

  /**
   * Creates a new endpoint. Initially, the endpoint represents a lower bound
   * of negative infinity.
   *
   * @param dataType datatype for domain
   * @return new endpoint
   */
  public SargMutableEndpoint newEndpoint(RelDataType dataType) {
    return new SargMutableEndpoint(this, dataType);
  }

  /**
   * Creates a new interval expression. The interval starts out as unbounded
   * (meaning it includes every non-null value of the datatype), with
   * SqlNullSemantics.NULL_MATCHES_NOTHING.
   *
   * @param dataType datatype for domain
   */
  public SargIntervalExpr newIntervalExpr(RelDataType dataType) {
    return newIntervalExpr(
        dataType,
        SqlNullSemantics.NULL_MATCHES_NOTHING);
  }

  /**
   * Creates a new unbounded interval expression with non-default null
   * semantics.
   *
   * @param dataType      datatype for domain
   * @param nullSemantics null semantics governing searches on this interval
   */
  public SargIntervalExpr newIntervalExpr(
      RelDataType dataType,
      SqlNullSemantics nullSemantics) {
    return new SargIntervalExpr(
        this,
        dataType,
        nullSemantics);
  }

  /**
   * Creates a new set expression, initially with no children.
   *
   * @param dataType datatype for domain
   * @param setOp    set operator
   */
  public SargSetExpr newSetExpr(RelDataType dataType, SargSetOperator setOp) {
    return new SargSetExpr(this, dataType, setOp);
  }

  /**
   * @return new analyzer for rex expressions
   */
  public SargRexAnalyzer newRexAnalyzer() {
    return new SargRexAnalyzer(this, false);
  }

  /**
   * @param simpleMode if true, the analyzer restricts the types of predicates
   *                   it allows; the following are disallowed - conjuntions on
   *                   the same RexInputRef, more than one range predicate, and
   *                   all disjunctions
   * @return new analyzer for rex expressions
   */
  public SargRexAnalyzer newRexAnalyzer(boolean simpleMode) {
    return new SargRexAnalyzer(this, simpleMode);
  }

  /**
   * @param lowerRexInputIdx if &ge; 0, treat RexInputRefs whose index is within
   *                         the range [lowerRexInputIdx, upperRexInputIdx) as
   *                         coordinates in expressions
   * @param upperRexInputIdx if &ge; 0, treat RexInputRefs whose index is within
   *                         the range [lowerRexInputIdx, upperRexInputIdx) as
   *                         coordinates in expressions
   * @return new analyzer for rex expressions
   */
  public SargRexAnalyzer newRexAnalyzer(
      int lowerRexInputIdx,
      int upperRexInputIdx) {
    return new SargRexAnalyzer(
        this,
        true,
        lowerRexInputIdx,
        upperRexInputIdx);
  }

  /**
   * @return the null literal, which can be used to represent a range matching
   * the null value
   */
  public RexNode newNullLiteral() {
    return rexNull;
  }

  /**
   * @return RexBuilder used by this factory
   */
  public RexBuilder getRexBuilder() {
    return rexBuilder;
  }
}

// End SargFactory.java


<|start_filename|>sqlline.bat<|end_filename|>
@echo off
:: sqlline.bat - Windows script to launch SQL shell
::
:: Licensed to <NAME> under one or more contributor license
:: agreements. See the NOTICE file distributed with this work for
:: additional information regarding copyright ownership.
::
:: <NAME> 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.
::
:: Example:
:: > sqlline.bat
:: sqlline> !connect jdbc:optiq: admin admin 

:: Copy dependency jars on first call. (To force jar refresh, remove target\dependencies)
if not exist target\dependencies (call mvn -B dependency:copy-dependencies -DoverWriteReleases=false -DoverWriteSnapshots=false -DoverWriteIfNewer=true -DoutputDirectory=target\dependencies)

java -Xmx1G -cp ".\target\dependencies\*;core\target\dependencies\*;avatica\target\dependencies\*;mongodb\target\dependencies\*;spark\target\dependencies\*;splunk\target\dependencies\*" sqlline.SqlLine --verbose=true %*

:: End sqlline.bat


<|start_filename|>core/src/main/java/org/eigenbase/rex/RexSqlConvertlet.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rex;

import org.eigenbase.sql.*;

/**
 * Converts a {@link RexNode} expression into a {@link SqlNode} expression.
 */
public interface RexSqlConvertlet {
  //~ Methods ----------------------------------------------------------------

  /**
   * Converts a {@link RexCall} to a {@link SqlNode} expression.
   *
   * @param converter to use in translating
   * @param call      RexCall to translate
   * @return SqlNode, or null if translation was unavailable
   */
  SqlNode convertCall(
      RexToSqlNodeConverter converter,
      RexCall call);
}

// End RexSqlConvertlet.java


<|start_filename|>core/src/test/java/net/hydromatic/optiq/tools/FrameworksTest.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.tools;

import net.hydromatic.optiq.SchemaPlus;
import net.hydromatic.optiq.Table;
import net.hydromatic.optiq.impl.AbstractTable;
import net.hydromatic.optiq.rules.java.EnumerableConvention;
import net.hydromatic.optiq.rules.java.JavaRules;

import org.eigenbase.rel.FilterRel;
import org.eigenbase.rel.RelNode;
import org.eigenbase.relopt.*;
import org.eigenbase.reltype.RelDataType;
import org.eigenbase.reltype.RelDataTypeFactory;
import org.eigenbase.rex.RexBuilder;
import org.eigenbase.rex.RexNode;
import org.eigenbase.sql.SqlExplainLevel;
import org.eigenbase.sql.fun.SqlStdOperatorTable;
import org.eigenbase.util.Util;

import org.junit.Test;

import java.math.BigDecimal;

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;

/**
 * Unit tests for methods in {@link Frameworks}.
 */
public class FrameworksTest {
  @Test public void testOptimize() {
    RelNode x =
        Frameworks.withPlanner(new Frameworks.PlannerAction<RelNode>() {
          public RelNode apply(RelOptCluster cluster,
              RelOptSchema relOptSchema,
              SchemaPlus rootSchema) {
            final RelDataTypeFactory typeFactory = cluster.getTypeFactory();
            final Table table = new AbstractTable() {
              public RelDataType getRowType(RelDataTypeFactory typeFactory) {
                final RelDataType stringType =
                    typeFactory.createJavaType(String.class);
                final RelDataType integerType =
                    typeFactory.createJavaType(Integer.class);
                return typeFactory.builder()
                    .add("s", stringType)
                    .add("i", integerType)
                    .build();
              }
            };

            // "SELECT * FROM myTable"
            final RelOptAbstractTable relOptTable = new RelOptAbstractTable(
                relOptSchema,
                "myTable",
                table.getRowType(typeFactory)) {
            };
            final JavaRules.EnumerableTableAccessRel tableRel =
                new JavaRules.EnumerableTableAccessRel(
                    cluster, cluster.traitSetOf(EnumerableConvention.INSTANCE),
                    relOptTable, Object[].class);

            // "WHERE i > 1"
            final RexBuilder rexBuilder = cluster.getRexBuilder();
            final RexNode condition =
                rexBuilder.makeCall(SqlStdOperatorTable.GREATER_THAN,
                    rexBuilder.makeFieldAccess(
                        rexBuilder.makeRangeReference(tableRel), "i", true),
                    rexBuilder.makeExactLiteral(BigDecimal.ONE));
            final FilterRel filterRel =
                new FilterRel(cluster, tableRel, condition);

            // Specify that the result should be in Enumerable convention.
            final RelNode rootRel = filterRel;
            final RelOptPlanner planner = cluster.getPlanner();
            RelTraitSet desiredTraits = rootRel.getTraitSet().replace(
                EnumerableConvention.INSTANCE);
            final RelNode rootRel2 = planner.changeTraits(rootRel,
                desiredTraits);
            planner.setRoot(rootRel2);

            // Now, plan.
            return planner.findBestExp();
          }
        });
    String s =
        RelOptUtil.dumpPlan("", x, false, SqlExplainLevel.DIGEST_ATTRIBUTES);
    assertThat(Util.toLinux(s), equalTo(
        "EnumerableFilterRel(condition=[>($1, 1)])\n"
        + "  EnumerableTableAccessRel(table=[[myTable]])\n"));
  }

  /** Unit test to test create root schema which has no "metadata" schema. */
  @Test public void testCreateRootSchemaWithNoMetadataSchema() {
    SchemaPlus rootSchema = Frameworks.createRootSchema(false);
    assertThat(rootSchema.getSubSchemaNames().size(), equalTo(0));
  }
}

// End FrameworksTest.java


<|start_filename|>core/src/main/java/org/eigenbase/rex/RexVariable.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rex;

import org.eigenbase.reltype.*;

/**
 * A row-expression which references a field.
 */
public abstract class RexVariable extends RexNode {
  //~ Instance fields --------------------------------------------------------

  protected final String name;
  protected final RelDataType type;

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

  protected RexVariable(
      String name,
      RelDataType type) {
    assert type != null;
    assert name != null;
    this.name = name;
    this.digest = name;
    this.type = type;
  }

  //~ Methods ----------------------------------------------------------------

  public RelDataType getType() {
    return type;
  }

  /**
   * Returns the name of this variable.
   */
  public String getName() {
    return name;
  }
}

// End RexVariable.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/JoinType.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql;

import org.eigenbase.sql.parser.SqlParserPos;

/**
 * Enumerates the types of join.
 */
public enum JoinType implements SqlLiteral.SqlSymbol {
  /**
   * Inner join.
   */
  INNER,

  /**
   * Full outer join.
   */
  FULL,

  /**
   * Cross join (also known as Cartesian product).
   */
  CROSS,

  /**
   * Left outer join.
   */
  LEFT,

  /**
   * Right outer join.
   */
  RIGHT,

  /**
   * Comma join: the good old-fashioned SQL <code>FROM</code> clause,
   * where table expressions are specified with commas between them, and
   * join conditions are specified in the <code>WHERE</code> clause.
   */
  COMMA;

  /**
   * Creates a parse-tree node representing an occurrence of this
   * condition type keyword at a particular position in the parsed
   * text.
   */
  public SqlLiteral symbol(SqlParserPos pos) {
    return SqlLiteral.createSymbol(this, pos);
  }
}

// End JoinType.java


<|start_filename|>core/src/main/java/net/hydromatic/optiq/util/Compatible.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.util;

import com.google.common.base.Function;
import com.google.common.collect.*;

import java.lang.reflect.*;
import java.util.*;

/** Compatibility layer.
 *
 * <p>Allows to use advanced functionality if the latest JDK or Guava version
 * is present.</p>
 */
public interface Compatible {
  Compatible INSTANCE = new Factory().create();

  /** Same as Guava {@code Maps.asMap(set, function)}. */
  <K, V> Map<K, V> asMap(Set<K> set, Function<? super K, V> function);

  /** Creates the implementation of Compatible suitable for the
   * current environment. */
  class Factory {
    Compatible create() {
      return (Compatible) Proxy.newProxyInstance(
          Compatible.class.getClassLoader(),
          new Class<?>[] {Compatible.class},
          new InvocationHandler() {
            public Object invoke(Object proxy, Method method, Object[] args)
              throws Throwable {
              if (method.getName().equals("asMap")) {
                // Use the Guava implementation Maps.asMap if it is available
                try {
                  final Method guavaMethod = Maps.class.getMethod(
                      method.getName(), method.getParameterTypes());
                  return guavaMethod.invoke(null, args);
                } catch (NoSuchMethodException e) {
                  Set set = (Set) args[0];
                  Function function = (Function) args[1];
                  return CompatibleGuava11.asMap(set, function);
                }
              }
              return null;
            }
          });
    }
  }
}

// End Compatible.java


<|start_filename|>core/src/main/java/org/eigenbase/util/ChunkList.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.util;

import java.util.*;

/**
 * Implementation of list similar to {@link LinkedList}, but stores elements
 * in chunks of 32 elements.
 *
 * <p>ArrayList has O(n) insertion and deletion into the middle of the list.
 * ChunkList insertion and deletion are O(1).</p>
 */
public class ChunkList<E> extends AbstractSequentialList<E> {
  private static final int HEADER_SIZE = 3;
  private int size;
  private Object[] first;
  private Object[] last;

  private static final int CHUNK_SIZE = 64;
  private static final Integer[] INTEGERS = new Integer[CHUNK_SIZE + 3];

  static {
    for (int i = 0; i < INTEGERS.length; i++) {
      INTEGERS[i] = i;
    }
  }

  /**
   * Creates an empty ChunkList.
   */
  public ChunkList() {
  }

  /**
   * Creates a ChunkList whose contents are a given Collection.
   */
  public ChunkList(Collection<E> collection) {
    addAll(collection);
  }

  /**
   * For debugging and testing.
   */
  boolean isValid(boolean fail) {
    if ((first == null) != (last == null)) {
      assert !fail;
      return false;
    }
    if ((first == null) != (size == 0)) {
      assert !fail;
      return false;
    }
    int n = 0;
    for (E e : this) {
      if (n++ > size) {
        assert !fail;
        return false;
      }
    }
    if (n != size) {
      assert !fail;
      return false;
    }
    Object[] prev = null;
    for (Object[] chunk = first; chunk != null; chunk = next(chunk)) {
      if (prev(chunk) != prev) {
        assert !fail;
        return false;
      }
      prev = chunk;
      if (occupied(chunk) == 0) {
        assert !fail;
        return false;
      }
    }
    return true;
  }

  @Override
  public ListIterator<E> listIterator(int index) {
    return locate(index);
  }

  @Override
  public int size() {
    return size;
  }

  @Override
  public boolean add(E element) {
    Object[] chunk = last;
    int occupied;
    if (chunk == null) {
      chunk = first = last = new Object[CHUNK_SIZE + HEADER_SIZE];
      occupied = 0;
    } else {
      occupied = occupied(chunk);
      if (occupied == CHUNK_SIZE) {
        chunk = new Object[CHUNK_SIZE + HEADER_SIZE];
        setNext(last, chunk);
        setPrev(chunk, last);
        occupied = 0;
        last = chunk;
      }
    }
    setOccupied(chunk, occupied + 1);
    setElement(chunk, HEADER_SIZE + occupied, element);
    ++size;
    return true;
  }

  @Override
  public void add(int index, E element) {
    if (index == size) {
      add(element);
    } else {
      super.add(index, element);
    }
  }

  private static Object[] prev(Object[] chunk) {
    return (Object[]) chunk[0];
  }

  private static void setPrev(Object[] chunk, Object[] prev) {
    chunk[0] = prev;
  }

  private static Object[] next(Object[] chunk) {
    return (Object[]) chunk[1];
  }

  private static void setNext(Object[] chunk, Object[] next) {
    assert chunk != next;
    chunk[1] = next;
  }

  private static int occupied(Object[] chunk) {
    return (Integer) chunk[2];
  }

  private static void setOccupied(Object[] chunk, int size) {
    chunk[2] = INTEGERS[size];
  }

  private static Object element(Object[] chunk, int index) {
    return chunk[index];
  }

  private static void setElement(Object[] chunk, int index, Object element) {
    chunk[index] = element;
  }

  private ChunkListIterator locate(int index) {
    if (index == 0) {
      return new ChunkListIterator();
    }
    int n = 0;
    for (Object[] chunk = first;;) {
      final int occupied = occupied(chunk);
      final int nextN = n + occupied;
      final Object[] next = next(chunk);
      if (nextN > index || next == null) {
        return new ChunkListIterator(
            chunk, n, index - n - 1 + HEADER_SIZE,
            occupied + HEADER_SIZE);
      }
      n = nextN;
      chunk = next;
    }
  }

  private class ChunkListIterator implements ListIterator<E> {
    private Object[] chunk;
    private int startIndex;
    private int offset;
    private int end;

    ChunkListIterator() {
      this(null, 0, -1, 0);
    }

    ChunkListIterator(Object[] chunk, int startIndex, int offset, int end) {
      this.chunk = chunk;
      this.startIndex = startIndex;
      this.offset = offset;
      this.end = end;
    }

    public boolean hasNext() {
      return offset + 1 < end
          || (chunk == null
          ? first != null
          : ChunkList.next(chunk) != null);
    }

    public E next() {
      ++offset;
      assert offset <= end;
      if (offset == end) {
        if (chunk == null) {
          chunk = first;
        } else {
          chunk = ChunkList.next(chunk);
          startIndex += end - HEADER_SIZE;
        }
        if (chunk == null) {
          throw new NoSuchElementException();
        }
        offset = HEADER_SIZE;
        end = occupied(chunk) + HEADER_SIZE;
      }
      return (E) element(chunk, offset);
    }

    public boolean hasPrevious() {
      return offset >= HEADER_SIZE || ChunkList.prev(chunk) != null;
    }

    public E previous() {
      --offset;
      if (offset == HEADER_SIZE - 1) {
        chunk = chunk == null ? last : ChunkList.prev(chunk);
        if (chunk == null) {
          throw new NoSuchElementException();
        }
        end = occupied(chunk);
        startIndex -= end;
        offset = end - 1;
      }
      return (E) element(chunk, offset);
    }

    public int nextIndex() {
      return startIndex + (offset - HEADER_SIZE) + 1;
    }

    public int previousIndex() {
      return startIndex + (offset - HEADER_SIZE);
    }

    public void remove() {
      --size;
      if (end == HEADER_SIZE + 1) {
        // Chunk is now empty.
        final Object[] prev = prev(chunk);
        final Object[] next = ChunkList.next(chunk);
        if (next == null) {
          last = prev;
          if (prev == null) {
            first = null;
          } else {
            setNext(prev, null);
          }
          chunk = null;
          end = HEADER_SIZE;
          offset = end - 1;
        } else {
          if (prev == null) {
            first = next;
            setPrev(next, null);
          } else {
            setNext(prev, next);
            setPrev(next, prev);
          }
          chunk = next;
          offset = HEADER_SIZE;
          end = HEADER_SIZE + occupied(next);
        }
        return;
      }
      // Move existing contents down one.
      System.arraycopy(
          chunk, offset + 1, chunk, offset, end - offset - 1);
      --end;
      setElement(chunk, end, null); // allow gc
      setOccupied(chunk, end - HEADER_SIZE);
      if (offset == end) {
        final Object[] next = ChunkList.next(chunk);
        if (next != null) {
          startIndex += end - HEADER_SIZE;
          chunk = next;
          offset = HEADER_SIZE - 1;
          end = HEADER_SIZE + occupied(next);
        }
      }
    }

    public void set(E e) {
      setElement(chunk, offset, e);
    }

    public void add(E e) {
      if (chunk == null || end == CHUNK_SIZE + HEADER_SIZE) {
        // FIXME We create a new chunk, but the next chunk might be
        // less than half full. We should consider using it.
        Object[] newChunk = new Object[CHUNK_SIZE + HEADER_SIZE];
        if (chunk == null) {
          if (first != null) {
            setNext(newChunk, first);
            setPrev(first, newChunk);
          }
          first = newChunk;
          if (last == null) {
            last = newChunk;
          }
        } else {
          final Object[] next = ChunkList.next(chunk);
          setPrev(newChunk, chunk);
          setNext(chunk, newChunk);

          if (next == null) {
            last = newChunk;
          } else {
            setPrev(next, newChunk);
            setNext(newChunk, next);
          }
          startIndex += CHUNK_SIZE;
        }
        chunk = newChunk;
        end = offset = HEADER_SIZE;
      } else {
        // Move existing contents up one.
        System.arraycopy(
            chunk, offset, chunk, offset + 1, end - offset);
      }
      setElement(chunk, offset, e);
//            ++offset;
      ++end;
      setOccupied(chunk, end - HEADER_SIZE);
      ++size;
    }
  }
}

// End ChunkList.java


<|start_filename|>core/src/main/java/org/eigenbase/rex/package-info.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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.
*/

/**
 * Provides a language for representing row-expressions.
 *
 * <h2>Life-cycle</h2>
 *
 * <p>A {@link org.eigenbase.sql2rel.SqlToRelConverter} converts a SQL parse tree
 *     consisting of {@link org.eigenbase.sql.SqlNode} objects into a relational
 *     expression ({@link org.eigenbase.rel.RelNode}). Several kinds of nodes in
 *     this tree have row expressions ({@link org.eigenbase.rex.RexNode}).</p>
 *
 * <p>After the relational expression has been optimized, a
 *     {@link net.hydromatic.optiq.rules.java.JavaRelImplementor} converts it
 *     into to a plan. If the plan is a Java
 *     parse tree, row-expressions are translated into equivalent Java
 *     expressions.</p>
 *
 * <h2>Expressions</h2>
 *
 *
 * <p>Every row-expression has a type. (Compare with
 *     {@link org.eigenbase.sql.SqlNode}, which is created before validation, and
 *     therefore types may not be available.)</p>
 *
 * <p>Every node in the parse tree is a {@link org.eigenbase.rex.RexNode}.
 *     Sub-types are:</p>
 * <ul>
 *     <li>{@link org.eigenbase.rex.RexLiteral} represents a boolean, numeric,
 *         string, or
 *         date constant, or the value <code>NULL</code>.
 *     </li>
 *     <li>{@link org.eigenbase.rex.RexVariable} represents a leaf of the tree. It
 *         has sub-types:
 *         <ul>
 *             <li>{@link org.eigenbase.rex.RexCorrelVariable} is a correlating
 *                 variable for
 *                 nested-loop joins
 *             </li>
 *             <li>{@link org.eigenbase.rex.RexInputRef} refers to a field of an
 *                 input
 *                 relational expression
 *             </li>
 *             <li>{@link org.eigenbase.rex.RexCall} is a call to an operator or
 *                 function.
 *                 By means of special operators, we can use this construct to
 *                 represent
 *                 virtually every non-leaf node in the tree.
 *             </li>
 *             <li>{@link org.eigenbase.rex.RexRangeRef} refers to a collection of
 *                 contiguous fields from an input relational expression. It
 *                 usually exists only
 *                 during translation.
 *             </li>
 *         </ul>
 *     </li>
 * </ul>
 *
 * <p>Expressions are generally
 *     created using a {@link org.eigenbase.rex.RexBuilder} factory.</p>
 *
 * <h2>Related packages</h2>
 * <ul>
 *     <li>{@link org.eigenbase.sql} SQL object model</li>
 *     <li>{@link org.eigenbase.relopt} Core classes, including {@link
 *         org.eigenbase.reltype.RelDataType} and {@link
 *         org.eigenbase.reltype.RelDataTypeFactory}.
 *     </li>
 * </ul>
 */
package org.eigenbase.rex;

// End package-info.java


<|start_filename|>core/src/main/java/org/eigenbase/sql2rel/SqlRexConvertlet.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql2rel;

import org.eigenbase.rex.*;
import org.eigenbase.sql.*;

/**
 * Thunk which converts a {@link SqlNode} expression into a {@link RexNode}
 * expression.
 */
public interface SqlRexConvertlet {
  //~ Methods ----------------------------------------------------------------

  RexNode convertCall(
      SqlRexContext cx,
      SqlCall call);
}

// End SqlRexConvertlet.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/parser/SqlParserImplFactory.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql.parser;

import java.io.Reader;

/**
 * Factory for {@link org.eigenbase.sql.parser.SqlAbstractParserImpl} objects.
 *
 * <p>A parser factory allows you to include a custom parser in
 * {@link net.hydromatic.optiq.tools.Planner} created through
 * {@link net.hydromatic.optiq.tools.Frameworks}.</p>
 */
public interface SqlParserImplFactory {

  /**
   * Get the underlying parser implementation.
   *
   * @return {@link SqlAbstractParserImpl} object.
   */
  SqlAbstractParserImpl getParser(Reader stream);
}


<|start_filename|>core/src/main/java/org/eigenbase/sql/validate/SqlUserDefinedFunction.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql.validate;

import org.eigenbase.sql.*;
import org.eigenbase.sql.type.*;
import org.eigenbase.util.Util;

import net.hydromatic.optiq.Function;

/**
* User-defined scalar function.
 *
 * <p>Created by the validator, after resolving a function call to a function
 * defined in an Optiq schema.</p>
*/
public class SqlUserDefinedFunction extends SqlFunction {
  public final Function function;

  public SqlUserDefinedFunction(SqlIdentifier opName,
      SqlReturnTypeInference returnTypeInference,
      SqlOperandTypeInference operandTypeInference,
      SqlOperandTypeChecker operandTypeChecker,
      Function function) {
    super(Util.last(opName.names), opName, SqlKind.OTHER_FUNCTION,
        returnTypeInference, operandTypeInference, operandTypeChecker,
        null, SqlFunctionCategory.USER_DEFINED_FUNCTION);
    this.function = function;
  }

  /**
   * Returns function that implements given operator call.
   * @return function that implements given operator call
   */
  public Function getFunction() {
    return function;
  }
}

// End SqlUserDefinedFunction.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/validate/SqlMonikerComparator.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql.validate;

import java.util.*;

/**
 * A general-purpose implementation of {@link Comparator} to compare {@link
 * SqlMoniker} values.
 */
public class SqlMonikerComparator implements Comparator<SqlMoniker> {
  //~ Methods ----------------------------------------------------------------

  public int compare(SqlMoniker m1, SqlMoniker m2) {
    if (m1.getType().ordinal() > m2.getType().ordinal()) {
      return 1;
    } else if (m1.getType().ordinal() < m2.getType().ordinal()) {
      return -1;
    } else {
      return m1.toString().compareTo(m2.toString());
    }
  }
}

// End SqlMonikerComparator.java


<|start_filename|>core/src/main/java/net/hydromatic/optiq/rules/java/NullPolicy.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.rules.java;

/**
 * Describes when a function/operator will return null.
 *
 * <p>STRICT and ANY are similar. STRICT says f(a0, a1) will NEVER return
 * null if a0 and a1 are not null. This means that we can check whether f
 * returns null just by checking its arguments. Use STRICT in preference to
 * ANY whenever possible.</p>
 */
public enum NullPolicy {
  /** Returns null if and only if one of the arguments are null. */
  STRICT,
  /** If any of the arguments are null, return null. */
  ANY,
  /** If any of the arguments are false, result is false; else if any
   * arguments are null, result is null; else true. */
  AND,
  /** If any of the arguments are true, result is true; else if any
   * arguments are null, result is null; else false. */
  OR,
  /** If any argument is true, result is false; else if any argument is null,
   * result is null; else true. */
  NOT,
  NONE
}


<|start_filename|>core/src/main/java/org/eigenbase/rel/rules/SemiJoinRel.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel.rules;

import java.util.*;

import org.eigenbase.rel.*;
import org.eigenbase.rel.metadata.*;
import org.eigenbase.relopt.*;
import org.eigenbase.reltype.*;
import org.eigenbase.rex.*;
import org.eigenbase.util.ImmutableIntList;

import com.google.common.collect.ImmutableSet;

/**
 * A SemiJoinRel represents two relational expressions joined according to some
 * condition, where the output only contains the columns from the left join
 * input.
 */
public final class SemiJoinRel extends JoinRelBase {
  //~ Instance fields --------------------------------------------------------

  private final ImmutableIntList leftKeys;
  private final ImmutableIntList rightKeys;

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

  /**
   * @param cluster   cluster that join belongs to
   * @param left      left join input
   * @param right     right join input
   * @param condition join condition
   * @param leftKeys  left keys of the semijoin
   * @param rightKeys right keys of the semijoin
   */
  public SemiJoinRel(
      RelOptCluster cluster,
      RelNode left,
      RelNode right,
      RexNode condition,
      List<Integer> leftKeys,
      List<Integer> rightKeys) {
    super(
        cluster,
        cluster.traitSetOf(Convention.NONE),
        left,
        right,
        condition,
        JoinRelType.INNER,
        ImmutableSet.<String>of());
    this.leftKeys = ImmutableIntList.copyOf(leftKeys);
    this.rightKeys = ImmutableIntList.copyOf(rightKeys);
  }

  //~ Methods ----------------------------------------------------------------

  @Override
  public SemiJoinRel copy(RelTraitSet traitSet, RexNode conditionExpr,
      RelNode left, RelNode right, JoinRelType joinType) {
    assert joinType == JoinRelType.INNER;
    return new SemiJoinRel(
        getCluster(),
        left,
        right,
        conditionExpr,
        getLeftKeys(),
        getRightKeys());
  }

  // implement RelNode
  public RelOptCost computeSelfCost(RelOptPlanner planner) {
    // REVIEW jvs 9-Apr-2006:  Just for now...
    return planner.getCostFactory().makeTinyCost();
  }

  // implement RelNode
  public double getRows() {
    // TODO:  correlation factor
    return RelMetadataQuery.getRowCount(left)
        * RexUtil.getSelectivity(condition);
  }

  /**
   * @return returns rowtype representing only the left join input
   */
  public RelDataType deriveRowType() {
    return deriveJoinRowType(
        left.getRowType(),
        null,
        JoinRelType.INNER,
        getCluster().getTypeFactory(),
        null,
        Collections.<RelDataTypeField>emptyList());
  }

  public List<Integer> getLeftKeys() {
    return leftKeys;
  }

  public List<Integer> getRightKeys() {
    return rightKeys;
  }
}

// End SemiJoinRel.java


<|start_filename|>core/src/test/java/net/hydromatic/optiq/test/ModelTest.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.test;

import net.hydromatic.optiq.model.*;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.ObjectMapper;

import org.junit.Test;

import java.io.IOException;
import java.util.*;

import static org.junit.Assert.*;

/**
 * Unit test for data models.
 */
public class ModelTest {
  private ObjectMapper mapper() {
    final ObjectMapper mapper = new ObjectMapper();
    mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
    mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
    return mapper;
  }

  /** Reads a simple schema from a string into objects. */
  @Test public void testRead() throws IOException {
    final ObjectMapper mapper = mapper();
    JsonRoot root = mapper.readValue(
        "{\n"
        + "  version: '1.0',\n"
        + "   schemas: [\n"
        + "     {\n"
        + "       name: 'FoodMart',\n"
        + "       tables: [\n"
        + "         {\n"
        + "           name: 'time_by_day',\n"
        + "           columns: [\n"
        + "             {\n"
        + "               name: 'time_id'\n"
        + "             }\n"
        + "           ]\n"
        + "         },\n"
        + "         {\n"
        + "           name: 'sales_fact_1997',\n"
        + "           columns: [\n"
        + "             {\n"
        + "               name: 'time_id'\n"
        + "             }\n"
        + "           ]\n"
        + "         }\n"
        + "       ]\n"
        + "     }\n"
        + "   ]\n"
        + "}",
        JsonRoot.class);
    assertEquals("1.0", root.version);
    assertEquals(1, root.schemas.size());
    final JsonMapSchema schema = (JsonMapSchema) root.schemas.get(0);
    assertEquals("FoodMart", schema.name);
    assertEquals(2, schema.tables.size());
    final JsonTable table0 = schema.tables.get(0);
    assertEquals("time_by_day", table0.name);
    final JsonTable table1 = schema.tables.get(1);
    assertEquals("sales_fact_1997", table1.name);
    assertEquals(1, table0.columns.size());
    final JsonColumn column = table0.columns.get(0);
    assertEquals("time_id", column.name);
  }

  /** Reads a simple schema containing JdbcSchema, a sub-type of Schema. */
  @Test public void testSubtype() throws IOException {
    final ObjectMapper mapper = mapper();
    JsonRoot root = mapper.readValue(
        "{\n"
        + "  version: '1.0',\n"
        + "   schemas: [\n"
        + "     {\n"
        + "       type: 'jdbc',\n"
        + "       name: 'FoodMart',\n"
        + "       jdbcUser: 'u_baz',\n"
        + "       jdbcPassword: '<PASSWORD>',\n"
        + "       jdbcUrl: 'jdbc:baz',\n"
        + "       jdbcCatalog: 'cat_baz',\n"
        + "       jdbcSchema: ''\n"
        + "     }\n"
        + "   ]\n"
        + "}",
        JsonRoot.class);
    assertEquals("1.0", root.version);
    assertEquals(1, root.schemas.size());
    final JsonJdbcSchema schema = (JsonJdbcSchema) root.schemas.get(0);
    assertEquals("FoodMart", schema.name);
  }

  /** Reads a custom schema. */
  @Test public void testCustomSchema() throws IOException {
    final ObjectMapper mapper = mapper();
    JsonRoot root = mapper.readValue(
        "{\n"
        + "  version: '1.0',\n"
        + "   schemas: [\n"
        + "     {\n"
        + "       type: 'custom',\n"
        + "       name: 'My Custom Schema',\n"
        + "       factory: 'com.acme.MySchemaFactory',\n"
        + "       operand: {a: 'foo', b: [1, 3.5] }\n"
        + "     }\n"
        + "   ]\n"
        + "}",
        JsonRoot.class);
    assertEquals("1.0", root.version);
    assertEquals(1, root.schemas.size());
    final JsonCustomSchema schema = (JsonCustomSchema) root.schemas.get(0);
    assertEquals("My Custom Schema", schema.name);
    assertEquals("com.acme.MySchemaFactory", schema.factory);
    assertEquals("foo", schema.operand.get("a"));
    assertNull(schema.operand.get("c"));
    assertTrue(schema.operand.get("b") instanceof List);
    final List list = (List) schema.operand.get("b");
    assertEquals(2, list.size());
    assertEquals(1, list.get(0));
    assertEquals(3.5, list.get(1));
  }

  /** Tests that an immutable schema in a model cannot contain a
   * materialization. */
  @Test public void testModelImmutableSchemaCannotContainMaterialization()
    throws Exception {
    final OptiqAssert.AssertThat that =
        OptiqAssert.that().withModel(
            "{\n"
            + "  version: '1.0',\n"
            + "  defaultSchema: 'adhoc',\n"
            + "  schemas: [\n"
            + "    {\n"
            + "      name: 'empty'\n"
            + "    },\n"
            + "    {\n"
            + "      name: 'adhoc',\n"
            + "      type: 'custom',\n"
            + "      factory: '"
            + JdbcTest.MySchemaFactory.class.getName()
            + "',\n"
            + "      operand: {\n"
            + "           'tableName': 'ELVIS',\n"
            + "           'mutable': false\n"
            + "      },\n"
            + "      materializations: [\n"
            + "        {\n"
            + "          table: 'v',\n"
            + "          sql: 'values (1)'\n"
            + "        }\n"
            + "      ]\n"
            + "    }\n"
            + "  ]\n"
            + "}");
    that.connectThrows(
        "Cannot define materialization; parent schema 'adhoc' is not a "
        + "SemiMutableSchema");
  }
}

// End ModelTest.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/validate/EmptyScope.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql.validate;

import java.util.*;

import org.eigenbase.reltype.*;
import org.eigenbase.sql.*;

import static org.eigenbase.util.Static.RESOURCE;

/**
 * Deviant implementation of {@link SqlValidatorScope} for the top of the scope
 * stack.
 *
 * <p>It is convenient, because we never need to check whether a scope's parent
 * is null. (This scope knows not to ask about its parents, just like Adam.)
 */
class EmptyScope implements SqlValidatorScope {
  //~ Instance fields --------------------------------------------------------

  protected final SqlValidatorImpl validator;

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

  EmptyScope(SqlValidatorImpl validator) {
    this.validator = validator;
  }

  //~ Methods ----------------------------------------------------------------

  public SqlValidator getValidator() {
    return validator;
  }

  public SqlIdentifier fullyQualify(SqlIdentifier identifier) {
    return identifier;
  }

  public SqlNode getNode() {
    throw new UnsupportedOperationException();
  }

  public SqlValidatorNamespace resolve(
      String name,
      SqlValidatorScope[] ancestorOut,
      int[] offsetOut) {
    return null;
  }

  public SqlValidatorNamespace getTableNamespace(List<String> names) {
    SqlValidatorTable table = validator.catalogReader.getTable(names);
    return table != null
        ? new TableNamespace(validator, table)
        : null;
  }

  public void findAllColumnNames(List<SqlMoniker> result) {
  }

  public void findAllTableNames(List<SqlMoniker> result) {
  }

  public void findAliases(List<SqlMoniker> result) {
  }

  public RelDataType resolveColumn(String name, SqlNode ctx) {
    return null;
  }

  public SqlValidatorScope getOperandScope(SqlCall call) {
    return this;
  }

  public void validateExpr(SqlNode expr) {
    // valid
  }

  public String findQualifyingTableName(String columnName, SqlNode ctx) {
    throw validator.newValidationError(ctx,
        RESOURCE.columnNotFound(columnName));
  }

  public void addChild(SqlValidatorNamespace ns, String alias) {
    // cannot add to the empty scope
    throw new UnsupportedOperationException();
  }

  public SqlWindow lookupWindow(String name) {
    // No windows defined in this scope.
    return null;
  }

  public SqlMonotonicity getMonotonicity(SqlNode expr) {
    return
        ((expr instanceof SqlLiteral)
            || (expr instanceof SqlDynamicParam)
            || (expr instanceof SqlDataTypeSpec)) ? SqlMonotonicity.CONSTANT
            : SqlMonotonicity.NOT_MONOTONIC;
  }

  public SqlNodeList getOrderList() {
    // scope is not ordered
    return null;
  }
}

// End EmptyScope.java


<|start_filename|>core/src/main/java/net/hydromatic/optiq/rules/java/JavaRelImplementor.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.rules.java;

import net.hydromatic.linq4j.expressions.ParameterExpression;

import net.hydromatic.optiq.DataContext;
import net.hydromatic.optiq.impl.java.JavaTypeFactory;

import org.eigenbase.rel.RelImplementorImpl;
import org.eigenbase.rex.RexBuilder;

/**
 * Abstract base class for implementations of {@link RelImplementorImpl}
 * that generate java code.
 */
public abstract class JavaRelImplementor extends RelImplementorImpl {
  public JavaRelImplementor(RexBuilder rexBuilder) {
    super(rexBuilder);
  }

  @Override
  public JavaTypeFactory getTypeFactory() {
    return (JavaTypeFactory) super.getTypeFactory();
  }

  /** Returns the expression with which to access the
   * {@link net.hydromatic.optiq.DataContext}. */
  public ParameterExpression getRootExpression() {
    return DataContext.ROOT;
  }
}

// End JavaRelImplementor.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/parser/SqlParser.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql.parser;

import java.io.*;

import org.eigenbase.sql.*;
import org.eigenbase.sql.parser.impl.*;
import org.eigenbase.util.*;

import net.hydromatic.avatica.Casing;
import net.hydromatic.avatica.Quoting;

/**
 * A <code>SqlParser</code> parses a SQL statement.
 */
public class SqlParser {
  //~ Instance fields --------------------------------------------------------

  private final SqlAbstractParserImpl parser;
  private String originalInput;

  //~ Constructors -----------------------------------------------------------
  private SqlParser(String s, SqlAbstractParserImpl parser,
      Quoting quoting, Casing unquotedCasing, Casing quotedCasing) {
    this.originalInput = s;
    this.parser = parser;
    parser.setTabSize(1);
    parser.setQuotedCasing(quotedCasing);
    parser.setUnquotedCasing(unquotedCasing);
    switch (quoting) {
    case DOUBLE_QUOTE:
      parser.switchTo("DQID");
      break;
    case BACK_TICK:
      parser.switchTo("BTID");
      break;
    case BRACKET:
      parser.switchTo("DEFAULT");
      break;
    }
  }

  //~ Methods ----------------------------------------------------------------

  /**
   * Creates a <code>SqlParser</code> to parse the given string using
   * Optiq's parser implementation.
   *
   * @param s An SQL statement or expression to parse.
   * @return A <code>SqlParser</code> object.
   */
  public static SqlParser create(String s) {
    return create(SqlParserImpl.FACTORY, s, Quoting.DOUBLE_QUOTE,
        Casing.TO_UPPER, Casing.UNCHANGED);
  }

  /**
   * Creates a <code>SqlParser</code> to parse the given string using the
   * parser implementation created from given {@link SqlParserImplFactory}
   * with given quoting syntax and casing policies for identifiers.
   *
   * @param parserFactory {@link SqlParserImplFactory} to get the parser
   *     implementation.
   * @param s An SQL statement or expression to parse.
   * @param quoting Syntax for quoting identifiers in SQL statements.
   * @param unquotedCasing Policy for converting case of <i>unquoted</i>
   *     identifiers.
   * @param quotedCasing Policy for converting case of <i>quoted</i>
   *     identifiers.
   * @return A <code>SqlParser</code> object.
   */
  public static SqlParser create(SqlParserImplFactory parserFactory, String s,
      Quoting quoting, Casing unquotedCasing, Casing quotedCasing) {
    SqlAbstractParserImpl parser = parserFactory.getParser(
        new StringReader(s));

    return new SqlParser(s, parser, quoting, unquotedCasing, quotedCasing);
  }

  /**
   * Parses a SQL expression.
   *
   * @throws SqlParseException if there is a parse error
   */
  public SqlNode parseExpression() throws SqlParseException {
    try {
      return parser.parseSqlExpressionEof();
    } catch (Throwable ex) {
      if ((ex instanceof EigenbaseContextException)
          && (originalInput != null)) {
        ((EigenbaseContextException) ex).setOriginalStatement(
            originalInput);
      }
      throw parser.normalizeException(ex);
    }
  }

  /**
   * Parses a <code>SELECT</code> statement.
   *
   * @return A {@link org.eigenbase.sql.SqlSelect} for a regular <code>
   * SELECT</code> statement; a {@link org.eigenbase.sql.SqlBinaryOperator}
   * for a <code>UNION</code>, <code>INTERSECT</code>, or <code>EXCEPT</code>.
   * @throws SqlParseException if there is a parse error
   */
  public SqlNode parseQuery() throws SqlParseException {
    try {
      return parser.parseSqlStmtEof();
    } catch (Throwable ex) {
      if ((ex instanceof EigenbaseContextException)
          && (originalInput != null)) {
        ((EigenbaseContextException) ex).setOriginalStatement(
            originalInput);
      }
      throw parser.normalizeException(ex);
    }
  }

  /**
   * Parses an SQL statement.
   *
   * @return top-level SqlNode representing stmt
   * @throws SqlParseException if there is a parse error
   */
  public SqlNode parseStmt() throws SqlParseException {
    try {
      return parser.parseSqlStmtEof();
    } catch (Throwable ex) {
      if ((ex instanceof EigenbaseContextException)
          && (originalInput != null)) {
        ((EigenbaseContextException) ex).setOriginalStatement(
            originalInput);
      }
      throw parser.normalizeException(ex);
    }
  }

  /**
   * Get the parser metadata.
   *
   * @return {@link SqlAbstractParserImpl.Metadata} implementation of
   *     underlying parser.
   */
  public SqlAbstractParserImpl.Metadata getMetadata() {
    return parser.getMetadata();
  }
}

// End SqlParser.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/type/AssignableOperandTypeChecker.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql.type;

import java.util.List;

import org.eigenbase.reltype.*;
import org.eigenbase.sql.*;
import org.eigenbase.util.Pair;

import net.hydromatic.linq4j.Ord;

import com.google.common.collect.ImmutableList;

/**
 * AssignableOperandTypeChecker implements {@link SqlOperandTypeChecker} by
 * verifying that the type of each argument is assignable to a predefined set of
 * parameter types (under the SQL definition of "assignable").
 */
public class AssignableOperandTypeChecker implements SqlOperandTypeChecker {
  //~ Instance fields --------------------------------------------------------

  private final List<RelDataType> paramTypes;

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

  /**
   * Instantiates this strategy with a specific set of parameter types.
   *
   * @param paramTypes parameter types for operands; index in this array
   *                   corresponds to operand number
   */
  public AssignableOperandTypeChecker(List<RelDataType> paramTypes) {
    this.paramTypes = ImmutableList.copyOf(paramTypes);
  }

  //~ Methods ----------------------------------------------------------------

  // implement SqlOperandTypeChecker
  public SqlOperandCountRange getOperandCountRange() {
    return SqlOperandCountRanges.of(paramTypes.size());
  }

  // implement SqlOperandTypeChecker
  public boolean checkOperandTypes(
      SqlCallBinding callBinding,
      boolean throwOnFailure) {
    final List<SqlNode> operands = callBinding.getCall().getOperandList();
    for (Pair<RelDataType, SqlNode> pair : Pair.zip(paramTypes, operands)) {
      RelDataType argType =
          callBinding.getValidator().deriveType(
              callBinding.getScope(),
              pair.right);
      if (!SqlTypeUtil.canAssignFrom(pair.left, argType)) {
        if (throwOnFailure) {
          throw callBinding.newValidationSignatureError();
        } else {
          return false;
        }
      }
    }
    return true;
  }

  // implement SqlOperandTypeChecker
  public String getAllowedSignatures(SqlOperator op, String opName) {
    StringBuilder sb = new StringBuilder();
    sb.append(opName);
    sb.append("(");
    for (Ord<RelDataType> paramType : Ord.zip(paramTypes)) {
      if (paramType.i > 0) {
        sb.append(", ");
      }
      sb.append("<");
      sb.append(paramType.e.getFamily());
      sb.append(">");
    }
    sb.append(")");
    return sb.toString();
  }
}

// End AssignableOperandTypeChecker.java


<|start_filename|>avatica/src/main/java/net/hydromatic/avatica/ColumnMetaData.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.avatica;

import java.lang.reflect.Type;
import java.sql.*;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Metadata for a column.
 * (Compare with {@link java.sql.ResultSetMetaData}.)
 */
public class ColumnMetaData {
  public final int ordinal; // 0-based
  public final boolean autoIncrement;
  public final boolean caseSensitive;
  public final boolean searchable;
  public final boolean currency;
  public final int nullable;
  public final boolean signed;
  public final int displaySize;
  public final String label;
  public final String columnName;
  public final String schemaName;
  public final int precision;
  public final int scale;
  public final String tableName;
  public final String catalogName;
  public final boolean readOnly;
  public final boolean writable;
  public final boolean definitelyWritable;
  public final String columnClassName;
  public final AvaticaType type;

  public ColumnMetaData(
      int ordinal,
      boolean autoIncrement,
      boolean caseSensitive,
      boolean searchable,
      boolean currency,
      int nullable,
      boolean signed,
      int displaySize,
      String label,
      String columnName,
      String schemaName,
      int precision,
      int scale,
      String tableName,
      String catalogName,
      AvaticaType type,
      boolean readOnly,
      boolean writable,
      boolean definitelyWritable,
      String columnClassName) {
    this.ordinal = ordinal;
    this.autoIncrement = autoIncrement;
    this.caseSensitive = caseSensitive;
    this.searchable = searchable;
    this.currency = currency;
    this.nullable = nullable;
    this.signed = signed;
    this.displaySize = displaySize;
    this.label = label;
    // Per the JDBC spec this should be just columnName.
    // For example, the query
    //     select 1 as x, c as y from t
    // should give columns
    //     (label=x, column=null, table=null)
    //     (label=y, column=c table=t)
    // But DbUnit requires every column to have a name. Duh.
    this.columnName = first(columnName, label);
    this.schemaName = schemaName;
    this.precision = precision;
    this.scale = scale;
    this.tableName = tableName;
    this.catalogName = catalogName;
    this.type = type;
    this.readOnly = readOnly;
    this.writable = writable;
    this.definitelyWritable = definitelyWritable;
    this.columnClassName = columnClassName;
  }

  private static <T> T first(T t0, T t1) {
    return t0 != null ? t0 : t1;
  }

  /** Creates a {@link ScalarType}. */
  public static ScalarType scalar(int type, String typeName, Rep rep) {
    return new ScalarType(type, typeName, rep);
  }

  /** Creates a {@link StructType}. */
  public static StructType struct(List<ColumnMetaData> columns) {
    return new StructType(columns, "STRUCT", Types.STRUCT,
        ColumnMetaData.Rep.OBJECT);
  }

  /** Creates an {@link ArrayType}. */
  public static ArrayType array(AvaticaType componentType, String typeName,
      Rep rep) {
    return new ArrayType(Types.ARRAY, typeName, rep, componentType);
  }

  /** Creates a ColumnMetaData for result sets that are not based on a struct
   * but need to have a single 'field' for purposes of
   * {@link ResultSetMetaData}. */
  public static ColumnMetaData dummy(AvaticaType type, boolean nullable) {
    return new ColumnMetaData(
        0,
        false,
        true,
        false,
        false,
        nullable
            ? DatabaseMetaData.columnNullable
            : DatabaseMetaData.columnNoNulls,
        true,
        -1,
        null,
        null,
        null,
        -1,
        -1,
        null,
        null, type,
        true,
        false,
        false,
        null);
  }

  /** Description of the type used to internally represent a value. For example,
   * a {@link java.sql.Date} might be represented as a {@link #PRIMITIVE_INT}
   * if not nullable, or a {@link #JAVA_SQL_DATE}. */
  public enum Rep {
    PRIMITIVE_BOOLEAN(boolean.class),
    PRIMITIVE_BYTE(byte.class),
    PRIMITIVE_CHAR(char.class),
    PRIMITIVE_SHORT(short.class),
    PRIMITIVE_INT(int.class),
    PRIMITIVE_LONG(long.class),
    PRIMITIVE_FLOAT(float.class),
    PRIMITIVE_DOUBLE(double.class),
    BOOLEAN(Boolean.class),
    BYTE(Byte.class),
    CHARACTER(Character.class),
    SHORT(Short.class),
    INTEGER(Integer.class),
    LONG(Long.class),
    FLOAT(Float.class),
    DOUBLE(Double.class),
    JAVA_SQL_TIME(Time.class),
    JAVA_SQL_TIMESTAMP(Timestamp.class),
    JAVA_SQL_DATE(java.sql.Date.class),
    JAVA_UTIL_DATE(java.util.Date.class),
    STRING(String.class),
    OBJECT(Object.class);

    private final Class clazz;

    public static final Map<Class, Rep> VALUE_MAP;

    static {
      Map<Class, Rep> builder = new HashMap<Class, Rep>();
      for (Rep rep : values()) {
        builder.put(rep.clazz, rep);
      }
      VALUE_MAP = Collections.unmodifiableMap(builder);
    }

    Rep(Class clazz) {
      this.clazz = clazz;
    }

    public static Rep of(Type clazz) {
      //noinspection SuspiciousMethodCalls
      final Rep rep = VALUE_MAP.get(clazz);
      return rep != null ? rep : OBJECT;
    }
  }

  /** Base class for a column type. */
  public static class AvaticaType {
    public final int type;
    public final String typeName;

    /** The type of the field that holds the value. Not a JDBC property. */
    public final Rep representation;

    protected AvaticaType(int type, String typeName, Rep representation) {
      this.type = type;
      this.typeName = typeName;
      this.representation = representation;
      assert representation != null;
    }
  }

  /** Scalar type. */
  public static class ScalarType extends AvaticaType {
    public ScalarType(int type, String typeName, Rep representation) {
      super(type, typeName, representation);
    }
  }

  /** Record type. */
  public static class StructType extends AvaticaType {
    public final List<ColumnMetaData> columns;

    private StructType(List<ColumnMetaData> columns, String typeName, int type,
        Rep representation) {
      super(type, typeName, representation);
      this.columns = columns;
    }
  }

  /** Array type. */
  public static class ArrayType extends AvaticaType {
    public final AvaticaType component;

    private ArrayType(int type, String typeName, Rep representation,
        AvaticaType component) {
      super(type, typeName, representation);
      this.component = component;
    }
  }
}

// End ColumnMetaData.java


<|start_filename|>core/src/main/java/org/eigenbase/relopt/RelOptRuleOperandChildren.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.relopt;

import com.google.common.collect.ImmutableList;

/**
 * Children of a {@link org.eigenbase.relopt.RelOptRuleOperand} and the policy
 * for matching them.
 *
 * <p>Often created by calling one of the following methods:
 * {@link RelOptRule#some},
 * {@link RelOptRule#none},
 * {@link RelOptRule#any},
 * {@link RelOptRule#unordered},</p>
 */
public class RelOptRuleOperandChildren {
  static final RelOptRuleOperandChildren ANY_CHILDREN =
      new RelOptRuleOperandChildren(
          RelOptRuleOperandChildPolicy.ANY,
          ImmutableList.<RelOptRuleOperand>of());

  static final RelOptRuleOperandChildren LEAF_CHILDREN =
      new RelOptRuleOperandChildren(
          RelOptRuleOperandChildPolicy.LEAF,
          ImmutableList.<RelOptRuleOperand>of());

  final RelOptRuleOperandChildPolicy policy;
  final ImmutableList<RelOptRuleOperand> operands;

  public RelOptRuleOperandChildren(
      RelOptRuleOperandChildPolicy policy,
      ImmutableList<RelOptRuleOperand> operands) {
    this.policy = policy;
    this.operands = operands;
  }
}

// End RelOptRuleOperandChildren.java


<|start_filename|>core/src/test/java/org/eigenbase/sql/test/SqlOperatorTest.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql.test;

import org.eigenbase.sql.validate.*;
import org.eigenbase.test.*;

/**
 * Concrete subclass of {@link SqlOperatorBaseTest} which checks against
 * a {@link SqlValidator}. Tests that involve execution trivially succeed.
 */
public class SqlOperatorTest extends SqlOperatorBaseTest {
  private static final SqlTester DEFAULT_TESTER =
      (SqlTester) new SqlValidatorTestCase().getTester();

  /**
   * Creates a SqlOperatorTest.
   */
  public SqlOperatorTest() {
    super(false, DEFAULT_TESTER);
  }
}

// End SqlOperatorTest.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/SqlBinaryStringLiteral.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql;

import java.util.List;

import org.eigenbase.sql.parser.*;
import org.eigenbase.sql.type.*;
import org.eigenbase.util.*;

import com.google.common.base.Function;
import com.google.common.collect.Lists;

/**
 * A binary (or hexadecimal) string literal.
 *
 * <p>The {@link #value} field is a {@link BitString} and {@link #typeName} is
 * {@link SqlTypeName#BINARY}.
 */
public class SqlBinaryStringLiteral extends SqlAbstractStringLiteral {
  private static final Function<SqlLiteral, BitString> F =
      new Function<SqlLiteral, BitString>() {
        public BitString apply(SqlLiteral literal) {
          return ((SqlBinaryStringLiteral) literal).getBitString();
        }
      };

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

  protected SqlBinaryStringLiteral(
      BitString val,
      SqlParserPos pos) {
    super(val, SqlTypeName.BINARY, pos);
  }

  //~ Methods ----------------------------------------------------------------

  /**
   * @return the underlying BitString
   */
  public BitString getBitString() {
    return (BitString) value;
  }

  public SqlNode clone(SqlParserPos pos) {
    return new SqlBinaryStringLiteral((BitString) value, pos);
  }

  public void unparse(
      SqlWriter writer,
      int leftPrec,
      int rightPrec) {
    assert value instanceof BitString;
    writer.literal("X'" + ((BitString) value).toHexString() + "'");
  }

  protected SqlAbstractStringLiteral concat1(List<SqlLiteral> literals) {
    return new SqlBinaryStringLiteral(
        BitString.concat(Lists.transform(literals, F)),
        literals.get(0).getParserPosition());
  }
}

// End SqlBinaryStringLiteral.java


<|start_filename|>core/src/main/java/net/hydromatic/optiq/jdbc/OptiqFactory.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.jdbc;

import net.hydromatic.avatica.*;

import net.hydromatic.optiq.impl.java.JavaTypeFactory;

import java.util.Properties;

/**
 * Extension of {@link net.hydromatic.avatica.AvaticaFactory}
 * for Optiq.
 */
public abstract class OptiqFactory implements AvaticaFactory {
  protected final int major;
  protected final int minor;

  /** Creates a JDBC factory with given major/minor version number. */
  protected OptiqFactory(int major, int minor) {
    this.major = major;
    this.minor = minor;
  }

  public int getJdbcMajorVersion() {
    return major;
  }

  public int getJdbcMinorVersion() {
    return minor;
  }

  public final AvaticaConnection newConnection(
      UnregisteredDriver driver,
      AvaticaFactory factory,
      String url,
      Properties info) {
    return newConnection(driver, factory, url, info, null, null);
  }

  /** Creates a connection with a root schema. */
  public abstract AvaticaConnection newConnection(UnregisteredDriver driver,
      AvaticaFactory factory, String url, Properties info,
      OptiqRootSchema rootSchema, JavaTypeFactory typeFactory);
}

// End OptiqFactory.java


<|start_filename|>mongodb/src/main/java/net/hydromatic/optiq/impl/mongodb/MongoTable.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.impl.mongodb;

import net.hydromatic.linq4j.*;
import net.hydromatic.linq4j.function.Function1;

import net.hydromatic.optiq.*;
import net.hydromatic.optiq.impl.AbstractTableQueryable;
import net.hydromatic.optiq.impl.java.AbstractQueryableTable;

import org.eigenbase.rel.RelNode;
import org.eigenbase.relopt.RelOptCluster;
import org.eigenbase.relopt.RelOptTable;
import org.eigenbase.reltype.RelDataType;
import org.eigenbase.reltype.RelDataTypeFactory;
import org.eigenbase.sql.type.SqlTypeName;
import org.eigenbase.util.Util;

import com.mongodb.*;
import com.mongodb.util.JSON;

import java.util.*;

/**
 * Table based on a MongoDB collection.
 */
public class MongoTable extends AbstractQueryableTable
    implements TranslatableTable {
  protected final String collectionName;

  /** Creates a MongoTable. */
  MongoTable(String collectionName) {
    super(Object[].class);
    this.collectionName = collectionName;
  }

  public String toString() {
    return "MongoTable {" + collectionName + "}";
  }

  public RelDataType getRowType(RelDataTypeFactory typeFactory) {
    final RelDataType mapType =
        typeFactory.createMapType(
            typeFactory.createSqlType(SqlTypeName.VARCHAR),
            typeFactory.createSqlType(SqlTypeName.ANY));
    return typeFactory.builder().add("_MAP", mapType).build();
  }

  public <T> Queryable<T> asQueryable(QueryProvider queryProvider,
      SchemaPlus schema, String tableName) {
    return new MongoQueryable<T>(queryProvider, schema, this, tableName);
  }

  public RelNode toRel(
      RelOptTable.ToRelContext context,
      RelOptTable relOptTable) {
    final RelOptCluster cluster = context.getCluster();
    return new MongoTableScan(cluster, cluster.traitSetOf(MongoRel.CONVENTION),
        relOptTable, this, null);
  }

  /** Executes a "find" operation on the underlying collection.
   *
   * <p>For example,
   * <code>zipsTable.find("{state: 'OR'}", "{city: 1, zipcode: 1}")</code></p>
   *
   * @param mongoDb MongoDB connection
   * @param filterJson Filter JSON string, or null
   * @param projectJson Project JSON string, or null
   * @param fields List of fields to project; or null to return map
   * @return Enumerator of results
   */
  public Enumerable<Object> find(DB mongoDb, String filterJson,
      String projectJson, List<Map.Entry<String, Class>> fields) {
    final DBCollection collection =
        mongoDb.getCollection(collectionName);
    final DBObject filter =
        filterJson == null ? null : (DBObject) JSON.parse(filterJson);
    final DBObject project =
        projectJson == null ? null : (DBObject) JSON.parse(projectJson);
    final Function1<DBObject, Object> getter = MongoEnumerator.getter(fields);
    return new AbstractEnumerable<Object>() {
      public Enumerator<Object> enumerator() {
        final DBCursor cursor = collection.find(filter, project);
        return new MongoEnumerator(cursor, getter);
      }
    };
  }

  /** Executes an "aggregate" operation on the underlying collection.
   *
   * <p>For example:
   * <code>zipsTable.aggregate(
   * "{$filter: {state: 'OR'}",
   * "{$group: {_id: '$city', c: {$sum: 1}, p: {$sum: '$pop'}}}")
   * </code></p>
   *
   * @param mongoDb MongoDB connection
   * @param fields List of fields to project; or null to return map
   * @param operations One or more JSON strings
   * @return Enumerator of results
   */
  public Enumerable<Object> aggregate(final DB mongoDb,
      final List<Map.Entry<String, Class>> fields,
      final List<String> operations) {
    List<DBObject> list = new ArrayList<DBObject>();
    for (String operation : operations) {
      list.add((DBObject) JSON.parse(operation));
    }
    final DBObject first = list.get(0);
    final List<DBObject> rest = Util.skip(list);
    final Function1<DBObject, Object> getter =
        MongoEnumerator.getter(fields);
    return new AbstractEnumerable<Object>() {
      public Enumerator<Object> enumerator() {
        final AggregationOutput result;
        try {
          result = mongoDb.getCollection(collectionName)
              .aggregate(first, rest.toArray(new DBObject[rest.size()]));
        } catch (Exception e) {
          throw new RuntimeException("While running MongoDB query "
              + Util.toString(operations, "[", ",\n", "]"), e);
        }
        return new MongoEnumerator(result.results().iterator(), getter);
      }
    };
  }

  /** Implementation of {@link net.hydromatic.linq4j.Queryable} based on
   * a {@link net.hydromatic.optiq.impl.mongodb.MongoTable}. */
  public static class MongoQueryable<T> extends AbstractTableQueryable<T> {
    public MongoQueryable(QueryProvider queryProvider, SchemaPlus schema,
        MongoTable table, String tableName) {
      super(queryProvider, schema, table, tableName);
    }

    public Enumerator<T> enumerator() {
      //noinspection unchecked
      final Enumerable<T> enumerable =
          (Enumerable<T>) getTable().find(getMongoDb(), null, null, null);
      return enumerable.enumerator();
    }

    private DB getMongoDb() {
      return schema.unwrap(MongoSchema.class).mongoDb;
    }

    private MongoTable getTable() {
      return (MongoTable) table;
    }

    /** Called via code-generation.
     *
     * @see net.hydromatic.optiq.impl.mongodb.MongoMethod#MONGO_QUERYABLE_AGGREGATE
     */
    @SuppressWarnings("UnusedDeclaration")
    public Enumerable<Object> aggregate(List<Map.Entry<String, Class>> fields,
        List<String> operations) {
      return getTable().aggregate(getMongoDb(), fields, operations);
    }

    /** Called via code-generation.
     *
     * @see net.hydromatic.optiq.impl.mongodb.MongoMethod#MONGO_QUERYABLE_FIND
     */
    @SuppressWarnings("UnusedDeclaration")
    public Enumerable<Object> find(String filterJson,
        String projectJson, List<Map.Entry<String, Class>> fields) {
      return getTable().find(getMongoDb(), filterJson, projectJson, fields);
    }
  }
}

// End MongoTable.java


<|start_filename|>mongodb/src/main/java/net/hydromatic/optiq/impl/mongodb/MongoMethod.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.impl.mongodb;

import net.hydromatic.linq4j.expressions.Types;

import com.google.common.collect.ImmutableMap;

import java.lang.reflect.Method;
import java.util.*;

/**
 * Builtin methods in the MongoDB adapter.
 */
public enum MongoMethod {
  MONGO_QUERYABLE_FIND(MongoTable.MongoQueryable.class, "find", String.class,
      String.class, List.class),
  MONGO_QUERYABLE_AGGREGATE(MongoTable.MongoQueryable.class, "aggregate",
      List.class, List.class);

  public final Method method;

  public static final ImmutableMap<Method, MongoMethod> MAP;

  static {
    final ImmutableMap.Builder<Method, MongoMethod> builder =
        ImmutableMap.builder();
    for (MongoMethod value : MongoMethod.values()) {
      builder.put(value.method, value);
    }
    MAP = builder.build();
  }

  MongoMethod(Class clazz, String methodName, Class... argumentTypes) {
    this.method = Types.lookupMethod(clazz, methodName, argumentTypes);
  }
}

// End MongoMethod.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/SqlUnresolvedFunction.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql;

import java.util.List;

import org.eigenbase.reltype.RelDataType;
import org.eigenbase.sql.type.SqlOperandTypeChecker;
import org.eigenbase.sql.type.SqlOperandTypeInference;
import org.eigenbase.sql.type.SqlReturnTypeInference;

/**
 * Placeholder for an unresolved function.
 *
 * <p>Created by the parser, then it is rewritten to proper SqlFunction by
 * the validator to a function defined in an Optiq schema.</p>
 */
public class SqlUnresolvedFunction extends SqlFunction {
  /**
   * Creates a placeholder SqlUnresolvedFunction for an invocation of a function
   * with a possibly qualified name. This name must be resolved into either
   * a builtin function or a user-defined function.
   *
   * @param sqlIdentifier        possibly qualified identifier for function
   * @param returnTypeInference  strategy to use for return type inference
   * @param operandTypeInference strategy to use for parameter type inference
   * @param operandTypeChecker   strategy to use for parameter type checking
   * @param paramTypes           array of parameter types
   * @param funcType             function category
   */
  public SqlUnresolvedFunction(
      SqlIdentifier sqlIdentifier,
      SqlReturnTypeInference returnTypeInference,
      SqlOperandTypeInference operandTypeInference,
      SqlOperandTypeChecker operandTypeChecker,
      List<RelDataType> paramTypes,
      SqlFunctionCategory funcType) {
    super(sqlIdentifier, returnTypeInference, operandTypeInference,
        operandTypeChecker, paramTypes, funcType);
  }
}

// End SqlUnresolvedFunction.java


<|start_filename|>spark/src/main/java/net/hydromatic/optiq/impl/spark/EnumerableToSparkConverter.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.impl.spark;

import net.hydromatic.linq4j.expressions.*;

import net.hydromatic.optiq.rules.java.*;

import org.eigenbase.rel.RelNode;
import org.eigenbase.rel.convert.ConverterRelImpl;
import org.eigenbase.relopt.*;

import java.util.List;

/**
 * Relational expression that converts input of {@link EnumerableConvention}
 * into {@link SparkRel#CONVENTION Spark convention}.
 *
 * <p>Concretely, this means iterating over the contents of an
 * {@link net.hydromatic.linq4j.Enumerable}, storing them in a list, and
 * building an {@link org.apache.spark.rdd.RDD} on top of it.</p>
 */
public class EnumerableToSparkConverter
    extends ConverterRelImpl
    implements SparkRel {
  protected EnumerableToSparkConverter(RelOptCluster cluster,
      RelTraitSet traits, RelNode input) {
    super(cluster, ConventionTraitDef.INSTANCE, traits, input);
  }

  @Override
  public RelNode copy(RelTraitSet traitSet, List<RelNode> inputs) {
    return new EnumerableToSparkConverter(
        getCluster(), traitSet, sole(inputs));
  }

  @Override
  public RelOptCost computeSelfCost(RelOptPlanner planner) {
    return super.computeSelfCost(planner).multiplyBy(.01);
  }

  public Result implementSpark(Implementor implementor) {
    // Generate:
    //   Enumerable source = ...;
    //   return SparkRuntime.createRdd(sparkContext, source);
    final BlockBuilder list = new BlockBuilder();
    final EnumerableRel child = (EnumerableRel) getChild();
    final PhysType physType =
        PhysTypeImpl.of(
            implementor.getTypeFactory(), getRowType(),
            JavaRowFormat.CUSTOM);
    final Expression source = null; // TODO:
    final Expression sparkContext =
        Expressions.call(
            SparkMethod.GET_SPARK_CONTEXT.method,
            implementor.getRootExpression());
    final Expression rdd =
        list.append(
            "rdd",
            Expressions.call(
                SparkMethod.CREATE_RDD.method,
                sparkContext,
                source));
    list.add(
        Expressions.return_(null, rdd));
    return implementor.result(physType, list.toBlock());
  }
}

// End EnumerableToSparkConverter.java


<|start_filename|>core/src/main/java/net/hydromatic/optiq/prepare/OptiqSqlValidator.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.prepare;

import net.hydromatic.optiq.impl.java.JavaTypeFactory;

import org.eigenbase.reltype.RelDataType;
import org.eigenbase.sql.SqlInsert;
import org.eigenbase.sql.SqlOperatorTable;
import org.eigenbase.sql.validate.SqlConformance;
import org.eigenbase.sql.validate.SqlValidatorImpl;

/** Validator. */
class OptiqSqlValidator extends SqlValidatorImpl {
  public OptiqSqlValidator(
      SqlOperatorTable opTab,
      OptiqCatalogReader catalogReader,
      JavaTypeFactory typeFactory) {
    super(opTab, catalogReader, typeFactory, SqlConformance.DEFAULT);
  }

  @Override
  protected RelDataType getLogicalSourceRowType(
      RelDataType sourceRowType, SqlInsert insert) {
    return ((JavaTypeFactory) typeFactory).toSql(sourceRowType);
  }

  @Override
  protected RelDataType getLogicalTargetRowType(
      RelDataType targetRowType, SqlInsert insert) {
    return ((JavaTypeFactory) typeFactory).toSql(targetRowType);
  }
}

// End OptiqSqlValidator.java


<|start_filename|>core/src/main/java/org/eigenbase/rel/rules/CoerceInputsRule.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel.rules;

import java.util.ArrayList;
import java.util.List;

import org.eigenbase.rel.*;
import org.eigenbase.relopt.*;
import org.eigenbase.reltype.*;

/**
 * CoerceInputsRule precasts inputs to a particular type. This can be used to
 * assist operator implementations which impose requirements on their input
 * types.
 */
public class CoerceInputsRule extends RelOptRule {
  //~ Instance fields --------------------------------------------------------

  private final Class consumerRelClass;

  private final boolean coerceNames;

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

  /**
   * Constructs the rule.
   *
   * @param consumerRelClass the RelNode class which will consume the inputs
   * @param coerceNames      if true, coerce names and types; if false, coerce
   *                         type only
   */
  public CoerceInputsRule(
      Class<? extends RelNode> consumerRelClass,
      boolean coerceNames) {
    super(
        operand(consumerRelClass, any()),
        "CoerceInputsRule:" + consumerRelClass.getName());
    this.consumerRelClass = consumerRelClass;
    this.coerceNames = coerceNames;
  }

  //~ Methods ----------------------------------------------------------------

  // implement RelOptRule
  public Convention getOutConvention() {
    return Convention.NONE;
  }

  // implement RelOptRule
  public void onMatch(RelOptRuleCall call) {
    RelNode consumerRel = call.rel(0);
    if (consumerRel.getClass() != consumerRelClass) {
      // require exact match on type
      return;
    }
    List<RelNode> inputs = consumerRel.getInputs();
    List<RelNode> newInputs = new ArrayList<RelNode>(inputs);
    boolean coerce = false;
    for (int i = 0; i < inputs.size(); ++i) {
      RelDataType expectedType = consumerRel.getExpectedInputRowType(i);
      RelNode input = inputs.get(i);
      RelNode newInput =
          RelOptUtil.createCastRel(
              input,
              expectedType,
              coerceNames);
      if (newInput != input) {
        newInputs.set(i, newInput);
        coerce = true;
      }
      assert RelOptUtil.areRowTypesEqual(
          newInputs.get(i).getRowType(),
          expectedType,
          coerceNames);
    }
    if (!coerce) {
      return;
    }
    RelNode newConsumerRel =
        consumerRel.copy(
            consumerRel.getTraitSet(),
            newInputs);
    call.transformTo(newConsumerRel);
  }
}

// End CoerceInputsRule.java


<|start_filename|>core/src/main/java/org/eigenbase/relopt/RelOptRuleOperandChildPolicy.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.relopt;

/**
 * Policy by which operands will be matched by relational expressions with
 * any number of children.
 */
public enum RelOptRuleOperandChildPolicy {
  /**
   * Signifies that operand can have any number of children.
   */
  ANY,

  /**
   * Signifies that operand has no children. Therefore it matches a
   * leaf node, such as a table scan or VALUES operator.
   *
   * <p>{@code RelOptRuleOperand(Foo.class, NONE)} is equivalent to
   * {@code RelOptRuleOperand(Foo.class)} but we prefer the former because
   * it is more explicit.</p>
   */
  LEAF,

  /**
   * Signifies that the operand's children must precisely match its
   * child operands, in order.
   */
  SOME,

  /**
   * Signifies that the rule matches any one of its parents' children.
   * The parent may have one or more children.
   */
  UNORDERED,
}

// End RelOptRuleOperandChildPolicy.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/validate/TableNamespace.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql.validate;

import org.eigenbase.reltype.RelDataType;
import org.eigenbase.sql.SqlNode;

/** Namespace based on a table from the catalog. */
class TableNamespace extends AbstractNamespace {
  private final SqlValidatorTable table;

  /** Creates a TableNamespace. */
  TableNamespace(SqlValidatorImpl validator, SqlValidatorTable table) {
    super(validator, null);
    this.table = table;
    assert table != null;
  }

  protected RelDataType validateImpl() {
    return table.getRowType();
  }

  public SqlNode getNode() {
    // This is the only kind of namespace not based on a node in the parse tree.
    return null;
  }

  @Override
  public SqlValidatorTable getTable() {
    return table;
  }
}

// End TableNamespace.java


<|start_filename|>core/src/test/java/org/eigenbase/test/SargTest.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.test;

import java.math.*;

import org.eigenbase.reltype.*;
import org.eigenbase.rex.*;
import org.eigenbase.sarg.*;
import org.eigenbase.sql.fun.*;
import org.eigenbase.sql.type.*;

import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.*;

/**
 * Tests for the {@code org.eigenbase.sarg} class library.
 *
 * <p>NOTE: This class lives in org.eigenbase.test rather than
 * org.eigenbase.sarg by design: we want to make sure we're only testing via the
 * public interface.
 */
public class SargTest {
  //~ Enums ------------------------------------------------------------------

  enum Zodiac {
    AQUARIUS, ARIES, CANCER, CAPRICORN, GEMINI, LEO, LIBRA, PISCES,
    SAGITTARIUS, SCORPIO, TAURUS, VIRGO
  }

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

  private SargFactory sargFactory;

  private RexBuilder rexBuilder;

  private RelDataType intType;

  private RelDataType stringType;

  private RexNode intLiteral7;

  private RexNode intLiteral8point5;

  private RexNode intLiteral490;

  private SargIntervalExpr[] exprs;

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

  /**
   * Creates a SargTest.
   */
  public SargTest() {
  }

  //~ Methods ----------------------------------------------------------------

  @Before
  public void setUp() {
    // create some reusable fixtures

    RelDataTypeFactory typeFactory = new SqlTypeFactoryImpl();
    intType = typeFactory.createSqlType(SqlTypeName.INTEGER);
    intType = typeFactory.createTypeWithNullability(intType, true);
    stringType = typeFactory.createSqlType(SqlTypeName.VARCHAR, 20);
    stringType = typeFactory.createTypeWithNullability(stringType, true);

    rexBuilder = new RexBuilder(typeFactory);
    intLiteral7 = rexBuilder.makeExactLiteral(
        BigDecimal.valueOf(7),
        intType);
    intLiteral490 =
        rexBuilder.makeExactLiteral(
            BigDecimal.valueOf(490),
            intType);
    intLiteral8point5 =
        rexBuilder.makeExactLiteral(
            new BigDecimal("8.5"),
            intType);

    sargFactory = new SargFactory(rexBuilder);
  }

  @Test public void testDefaultEndpoint() {
    SargMutableEndpoint ep = sargFactory.newEndpoint(intType);
    assertEquals(
        "-infinity",
        ep.toString());
  }

  @Test public void testInfiniteEndpoint() {
    SargMutableEndpoint ep = sargFactory.newEndpoint(intType);
    ep.setInfinity(1);
    assertEquals(
        "+infinity",
        ep.toString());
    ep.setInfinity(-1);
    assertEquals(
        "-infinity",
        ep.toString());
  }

  @Test public void testFiniteEndpoint() {
    SargMutableEndpoint ep = sargFactory.newEndpoint(intType);

    ep.setFinite(
        SargBoundType.LOWER,
        SargStrictness.OPEN,
        intLiteral7);
    assertEquals(
        "> 7",
        ep.toString());

    ep.setFinite(
        SargBoundType.LOWER,
        SargStrictness.CLOSED,
        intLiteral7);
    assertEquals(
        ">= 7",
        ep.toString());

    ep.setFinite(
        SargBoundType.UPPER,
        SargStrictness.OPEN,
        intLiteral7);
    assertEquals(
        "< 7",
        ep.toString());

    ep.setFinite(
        SargBoundType.UPPER,
        SargStrictness.CLOSED,
        intLiteral7);
    assertEquals(
        "<= 7",
        ep.toString());

    // after rounding, "> 8.5" is equivalent to ">= 9" over the domain
    // of integers
    ep.setFinite(
        SargBoundType.LOWER,
        SargStrictness.OPEN,
        intLiteral8point5);
    assertEquals(
        ">= 9",
        ep.toString());

    ep.setFinite(
        SargBoundType.LOWER,
        SargStrictness.CLOSED,
        intLiteral8point5);
    assertEquals(
        ">= 9",
        ep.toString());

    ep.setFinite(
        SargBoundType.UPPER,
        SargStrictness.OPEN,
        intLiteral8point5);
    assertEquals(
        "< 9",
        ep.toString());

    ep.setFinite(
        SargBoundType.UPPER,
        SargStrictness.CLOSED,
        intLiteral8point5);
    assertEquals(
        "< 9",
        ep.toString());
  }

  @Test public void testNullEndpoint() {
    SargMutableEndpoint ep = sargFactory.newEndpoint(intType);

    ep.setFinite(
        SargBoundType.LOWER,
        SargStrictness.OPEN,
        sargFactory.newNullLiteral());
    assertEquals(
        "> null",
        ep.toString());
  }

  @Test public void testTouchingEndpoint() {
    SargMutableEndpoint ep1 = sargFactory.newEndpoint(intType);
    SargMutableEndpoint ep2 = sargFactory.newEndpoint(intType);

    // "-infinity" does not touch "-infinity" (seems like something you
    // could argue for hours late at night in a college dorm)
    assertFalse(ep1.isTouching(ep2));

    // "< 7" does not touch "> 7"
    ep1.setFinite(
        SargBoundType.UPPER,
        SargStrictness.OPEN,
        intLiteral7);
    ep2.setFinite(
        SargBoundType.LOWER,
        SargStrictness.OPEN,
        intLiteral7);
    assertFalse(ep1.isTouching(ep2));
    assertTrue(ep1.compareTo(ep2) < 0);

    // "< 7" does touch ">= 7"
    ep2.setFinite(
        SargBoundType.LOWER,
        SargStrictness.CLOSED,
        intLiteral7);
    assertTrue(ep1.isTouching(ep2));
    assertTrue(ep1.compareTo(ep2) < 0);

    // "<= 7" does touch ">= 7"
    ep1.setFinite(
        SargBoundType.LOWER,
        SargStrictness.CLOSED,
        intLiteral7);
    assertTrue(ep1.isTouching(ep2));
    assertEquals(
        0,
        ep1.compareTo(ep2));

    // "<= 7" does not touch ">= 490"
    ep2.setFinite(
        SargBoundType.LOWER,
        SargStrictness.CLOSED,
        intLiteral490);
    assertFalse(ep1.isTouching(ep2));
    assertTrue(ep1.compareTo(ep2) < 0);
  }

  @Test public void testDefaultIntervalExpr() {
    SargIntervalExpr interval = sargFactory.newIntervalExpr(intType);
    assertEquals(
        "(-infinity, +infinity)",
        interval.toString());
  }

  @Test public void testPointExpr() {
    SargIntervalExpr interval = sargFactory.newIntervalExpr(intType);
    interval.setPoint(intLiteral7);
    assertTrue(interval.isPoint());
    assertFalse(interval.isUnconstrained());
    assertFalse(interval.isEmpty());
    assertEquals(
        "[7]",
        interval.toString());
    assertEquals(
        "[7]",
        interval.evaluate().toString());
  }

  @Test public void testRangeIntervalExpr() {
    SargIntervalExpr interval = sargFactory.newIntervalExpr(intType);

    interval.setLower(intLiteral7, SargStrictness.CLOSED);
    interval.setUpper(intLiteral490, SargStrictness.CLOSED);
    assertRange(interval);
    assertEquals(
        "[7, 490]",
        interval.toString());
    assertEquals(
        "[7, 490]",
        interval.evaluate().toString());

    interval.unsetLower();
    assertRange(interval);
    assertEquals(
        "(-infinity, 490]",
        interval.toString());
    assertEquals(
        "(null, 490]",
        interval.evaluate().toString());

    interval.setLower(intLiteral7, SargStrictness.CLOSED);
    interval.unsetUpper();
    assertRange(interval);
    assertEquals(
        "[7, +infinity)",
        interval.toString());
    assertEquals(
        "[7, +infinity)",
        interval.evaluate().toString());

    interval.setUpper(intLiteral490, SargStrictness.OPEN);
    assertRange(interval);
    assertEquals(
        "[7, 490)",
        interval.toString());
    assertEquals(
        "[7, 490)",
        interval.evaluate().toString());

    interval.setLower(intLiteral7, SargStrictness.OPEN);
    assertRange(interval);
    assertEquals(
        "(7, 490)",
        interval.toString());
    assertEquals(
        "(7, 490)",
        interval.evaluate().toString());
  }

  private void assertRange(SargIntervalExpr interval) {
    assertFalse(interval.isPoint());
    assertFalse(interval.isUnconstrained());
    assertFalse(interval.isEmpty());
  }

  @Test public void testNullExpr() {
    SargIntervalExpr interval = sargFactory.newIntervalExpr(intType);
    interval.setNull();
    assertTrue(interval.isPoint());
    assertFalse(interval.isUnconstrained());
    assertFalse(interval.isEmpty());
    assertEquals(
        "[null] NULL_MATCHES_NULL",
        interval.toString());
    assertEquals(
        "[null]",
        interval.evaluate().toString());
  }

  @Test public void testEmptyExpr() {
    SargIntervalExpr interval = sargFactory.newIntervalExpr(intType);
    interval.setEmpty();
    assertTrue(interval.isEmpty());
    assertFalse(interval.isUnconstrained());
    assertEquals(
        "()",
        interval.toString());
    assertEquals(
        "()",
        interval.evaluate().toString());
  }

  @Test public void testUnconstrainedExpr() {
    SargIntervalExpr interval = sargFactory.newIntervalExpr(intType);
    interval.setEmpty();
    assertFalse(interval.isUnconstrained());
    interval.setUnconstrained();
    assertTrue(interval.isUnconstrained());
    assertFalse(interval.isEmpty());
    assertEquals(
        "(-infinity, +infinity)",
        interval.toString());
    assertEquals(
        "(-infinity, +infinity)",
        interval.evaluate().toString());
  }

  @Test public void testSetExpr() {
    SargIntervalExpr interval1 = sargFactory.newIntervalExpr(intType);
    SargIntervalExpr interval2 = sargFactory.newIntervalExpr(intType);

    interval1.setLower(intLiteral7, SargStrictness.OPEN);
    interval2.setUpper(intLiteral490, SargStrictness.OPEN);

    SargSetExpr intersectExpr =
        sargFactory.newSetExpr(
            intType,
            SargSetOperator.INTERSECTION);
    intersectExpr.addChild(interval1);
    intersectExpr.addChild(interval2);
    assertEquals(
        "INTERSECTION( (7, +infinity) (-infinity, 490) )",
        intersectExpr.toString());
    assertEquals(
        "(7, 490)",
        intersectExpr.evaluate().toString());

    SargSetExpr unionExpr =
        sargFactory.newSetExpr(
            intType,
            SargSetOperator.UNION);
    unionExpr.addChild(interval1);
    unionExpr.addChild(interval2);
    assertEquals(
        "UNION( (7, +infinity) (-infinity, 490) )",
        unionExpr.toString());
    assertEquals(
        "(null, +infinity)",
        unionExpr.evaluate().toString());

    // NOTE jvs 17-Apr-2006:  See
    // http://issues.eigenbase.org/browse/LDB-60) for why the
    // expected result is what it is.

    SargSetExpr complementExpr =
        sargFactory.newSetExpr(
            intType,
            SargSetOperator.COMPLEMENT);
    complementExpr.addChild(interval1);
    assertEquals(
        "COMPLEMENT( (7, +infinity) )",
        complementExpr.toString());
    assertEquals(
        "(null, 7]",
        complementExpr.evaluate().toString());
  }

  @Test public void testComplement() {
    // test
    //   complement ( union (interval1, interval2) )
    // it is evaluated as
    //   intersect (complement(interval1), complement(interval2))
    //
    // commonly seen in sql expressins like
    //   not (a in ( list))
    // or
    //   a not in (list)
    // (rchen 2006-08-18) note the latter does not have SQL support yet.
    //
    SargIntervalExpr interval1 = sargFactory.newIntervalExpr(intType);
    SargIntervalExpr interval2 = sargFactory.newIntervalExpr(intType);
    SargIntervalExpr interval3 = sargFactory.newIntervalExpr(intType);

    interval1.setLower(intLiteral7, SargStrictness.CLOSED);
    interval1.setUpper(intLiteral7, SargStrictness.CLOSED);

    interval2.setLower(intLiteral490, SargStrictness.CLOSED);
    interval2.setUpper(intLiteral490, SargStrictness.CLOSED);

    interval3.setUpper(intLiteral490, SargStrictness.OPEN);

    // REVIEW (ruchen 2006-08-18) lower and upper extremems are different
    // in the complement result:
    //     the lower is null while the upper is +infinity.
    // Not sure why the lower needs to be null.
    SargSetExpr complementExpr1 =
        sargFactory.newSetExpr(
            intType,
            SargSetOperator.COMPLEMENT);
    complementExpr1.addChild(interval1);
    assertEquals(
        "UNION( (null, 7) (7, +infinity) )",
        complementExpr1.evaluate().toString());

    SargSetExpr complementExpr2 =
        sargFactory.newSetExpr(
            intType,
            SargSetOperator.COMPLEMENT);
    complementExpr2.addChild(interval2);
    assertEquals(
        "UNION( (null, 490) (490, +infinity) )",
        complementExpr2.evaluate().toString());

    SargSetExpr intersectExpr1 =
        sargFactory.newSetExpr(
            intType,
            SargSetOperator.INTERSECTION);
    intersectExpr1.addChild(complementExpr1);
    intersectExpr1.addChild(complementExpr2);

    assertEquals(
        "UNION( (null, 7) (7, 490) (490, +infinity) )",
        intersectExpr1.evaluate().toString());

    SargSetExpr intersectExpr2 =
        sargFactory.newSetExpr(
            intType,
            SargSetOperator.INTERSECTION);
    intersectExpr2.addChild(complementExpr2);
    intersectExpr2.addChild(complementExpr1);

    assertEquals(
        "UNION( (null, 7) (7, 490) (490, +infinity) )",
        intersectExpr2.evaluate().toString());

    SargSetExpr intersectExpr3 =
        sargFactory.newSetExpr(
            intType,
            SargSetOperator.INTERSECTION);
    intersectExpr3.addChild(complementExpr1);
    intersectExpr3.addChild(interval3);

    assertEquals(
        "UNION( (null, 7) (7, 490) )",
        intersectExpr3.evaluate().toString());

    SargSetExpr unionExpr1 =
        sargFactory.newSetExpr(
            intType,
            SargSetOperator.UNION);
    unionExpr1.addChild(interval1);
    unionExpr1.addChild(interval2);

    SargSetExpr complementExpr3 =
        sargFactory.newSetExpr(
            intType,
            SargSetOperator.COMPLEMENT);
    complementExpr3.addChild(unionExpr1);

    assertEquals(
        "UNION( (null, 7) (7, 490) (490, +infinity) )",
        complementExpr3.evaluate().toString());

    SargSetExpr unionExpr2 =
        sargFactory.newSetExpr(
            intType,
            SargSetOperator.UNION);
    unionExpr2.addChild(interval2);
    unionExpr2.addChild(interval1);

    SargSetExpr complementExpr4 =
        sargFactory.newSetExpr(
            intType,
            SargSetOperator.COMPLEMENT);
    complementExpr4.addChild(unionExpr2);
    assertEquals(
        "UNION( (null, 7) (7, 490) (490, +infinity) )",
        complementExpr4.evaluate().toString());
  }

  @Test public void testUnion() {
    exprs = new SargIntervalExpr[11];
    for (int i = 0; i < 11; ++i) {
      exprs[i] = sargFactory.newIntervalExpr(stringType);
    }

    exprs[0].setPoint(createCoordinate(Zodiac.AQUARIUS));

    exprs[1].setPoint(createCoordinate(Zodiac.LEO));

    exprs[2].setUpper(
        createCoordinate(Zodiac.CAPRICORN),
        SargStrictness.CLOSED);

    exprs[3].setLower(
        createCoordinate(Zodiac.GEMINI),
        SargStrictness.OPEN);

    exprs[4].setLower(
        createCoordinate(Zodiac.GEMINI),
        SargStrictness.CLOSED);

    exprs[5].setNull();

    exprs[6].setLower(
        createCoordinate(Zodiac.GEMINI),
        SargStrictness.CLOSED);
    exprs[6].setUpper(
        createCoordinate(Zodiac.PISCES),
        SargStrictness.CLOSED);

    exprs[7].setLower(
        createCoordinate(Zodiac.GEMINI),
        SargStrictness.CLOSED);
    exprs[7].setUpper(
        createCoordinate(Zodiac.SCORPIO),
        SargStrictness.CLOSED);

    exprs[8].setLower(
        createCoordinate(Zodiac.ARIES),
        SargStrictness.CLOSED);
    exprs[8].setUpper(
        createCoordinate(Zodiac.GEMINI),
        SargStrictness.CLOSED);

    exprs[9].setLower(
        createCoordinate(Zodiac.ARIES),
        SargStrictness.CLOSED);
    exprs[9].setUpper(
        createCoordinate(Zodiac.GEMINI),
        SargStrictness.OPEN);

    exprs[10].setEmpty();

    checkUnion(
        0,
        2,
        5,
        "[null, 'CAPRICORN']");

    checkUnion(
        2,
        5,
        0,
        "[null, 'CAPRICORN']");

    checkUnion(
        5,
        6,
        7,
        "UNION( [null] ['GEMINI', 'SCORPIO'] )");

    checkUnion(
        8,
        4,
        5,
        "UNION( [null] ['ARIES', +infinity) )");

    checkUnion(
        9,
        4,
        5,
        "UNION( [null] ['ARIES', +infinity) )");

    checkUnion(
        7,
        8,
        9,
        "['ARIES', 'SCORPIO']");

    checkUnion(
        6,
        7,
        10,
        "['GEMINI', 'SCORPIO']");

    checkUnion(
        5,
        6,
        0,
        "UNION( [null] ['AQUARIUS'] ['GEMINI', 'PISCES'] )");

    checkUnion(
        10,
        9,
        5,
        "UNION( [null] ['ARIES', 'GEMINI') )");

    checkUnion(
        9,
        8,
        7,
        "['ARIES', 'SCORPIO']");

    checkUnion(
        3,
        9,
        1,
        "UNION( ['ARIES', 'GEMINI') ('GEMINI', +infinity) )");
  }

  @Test public void testIntersection() {
    exprs = new SargIntervalExpr[11];
    for (int i = 0; i < 11; ++i) {
      exprs[i] = sargFactory.newIntervalExpr(stringType);
    }

    exprs[0].setUnconstrained();

    exprs[1].setPoint(createCoordinate(Zodiac.LEO));

    exprs[2].setUpper(
        createCoordinate(Zodiac.CAPRICORN),
        SargStrictness.CLOSED);

    exprs[3].setLower(
        createCoordinate(Zodiac.CANCER),
        SargStrictness.OPEN);

    exprs[4].setLower(
        createCoordinate(Zodiac.GEMINI),
        SargStrictness.CLOSED);

    exprs[5].setNull();

    exprs[6].setLower(
        createCoordinate(Zodiac.GEMINI),
        SargStrictness.CLOSED);
    exprs[6].setUpper(
        createCoordinate(Zodiac.PISCES),
        SargStrictness.CLOSED);

    exprs[7].setLower(
        createCoordinate(Zodiac.GEMINI),
        SargStrictness.CLOSED);
    exprs[7].setUpper(
        createCoordinate(Zodiac.SCORPIO),
        SargStrictness.CLOSED);

    exprs[8].setLower(
        createCoordinate(Zodiac.ARIES),
        SargStrictness.CLOSED);
    exprs[8].setUpper(
        createCoordinate(Zodiac.GEMINI),
        SargStrictness.CLOSED);

    exprs[9].setLower(
        createCoordinate(Zodiac.ARIES),
        SargStrictness.CLOSED);
    exprs[9].setUpper(
        createCoordinate(Zodiac.GEMINI),
        SargStrictness.OPEN);

    exprs[10].setEmpty();

    checkIntersection(
        2,
        3,
        0,
        "('CANCER', 'CAPRICORN']");

    checkIntersection(
        0,
        3,
        2,
        "('CANCER', 'CAPRICORN']");

    checkIntersection(
        6,
        7,
        0,
        "['GEMINI', 'PISCES']");

    checkIntersection(
        6,
        7,
        8,
        "['GEMINI']");

    checkIntersection(
        8,
        7,
        6,
        "['GEMINI']");

    checkIntersection(
        9,
        7,
        6,
        "()");
  }

  private void checkUnion(
      int i1,
      int i2,
      int i3,
      String expected) {
    checkSetOp(SargSetOperator.UNION, i1, i2, i3, expected);
  }

  private void checkIntersection(
      int i1,
      int i2,
      int i3,
      String expected) {
    checkSetOp(SargSetOperator.INTERSECTION, i1, i2, i3, expected);
  }

  private void checkSetOp(
      SargSetOperator setOp,
      int i1,
      int i2,
      int i3,
      String expected) {
    SargSetExpr setExpr =
        sargFactory.newSetExpr(
            stringType,
            setOp);
    setExpr.addChild(exprs[i1]);
    setExpr.addChild(exprs[i2]);
    setExpr.addChild(exprs[i3]);
    assertEquals(
        expected,
        setExpr.evaluate().toString());
  }

  private RexNode createCoordinate(Zodiac z) {
    return sargFactory.getRexBuilder().makeLiteral(z.toString());
  }

  @Test public void testRexAnalyzer() {
    SargRexAnalyzer rexAnalyzer = sargFactory.newRexAnalyzer();
    RexNode pred1;
    RexNode pred2;
    RexNode pred3;
    SargBinding binding;

    RexNode inputRef8 = rexBuilder.makeInputRef(intType, 8);
    RexNode inputRef9 = rexBuilder.makeInputRef(intType, 8);

    // test variable before literal
    pred1 =
        rexBuilder.makeCall(
            SqlStdOperatorTable.LESS_THAN,
            inputRef8,
            intLiteral7);
    binding = rexAnalyzer.analyze(pred1);
    assertNotNull(binding);
    assertEquals(
        "(-infinity, 7)",
        binding.getExpr().toString());

    // test literal before variable
    pred2 =
        rexBuilder.makeCall(
            SqlStdOperatorTable.GREATER_THAN_OR_EQUAL,
            intLiteral490,
            inputRef9);
    binding = rexAnalyzer.analyze(pred2);
    assertNotNull(binding);
    assertEquals(
        "(-infinity, 490]",
        binding.getExpr().toString());

    // test AND
    pred3 =
        rexBuilder.makeCall(
            SqlStdOperatorTable.AND,
            pred1,
            pred2);
    binding = rexAnalyzer.analyze(pred3);
    assertNotNull(binding);
    assertEquals(
        "INTERSECTION( (-infinity, 7) (-infinity, 490] )",
        binding.getExpr().toString());

    // test OR
    pred3 =
        rexBuilder.makeCall(
            SqlStdOperatorTable.OR,
            pred1,
            pred2);
    binding = rexAnalyzer.analyze(pred3);
    assertNotNull(binding);
    assertEquals(
        "UNION( (-infinity, 7) (-infinity, 490] )",
        binding.getExpr().toString());

    // test NOT
    pred3 =
        rexBuilder.makeCall(
            SqlStdOperatorTable.NOT,
            pred1);
    binding = rexAnalyzer.analyze(pred3);
    assertNotNull(binding);
    assertEquals(
        "COMPLEMENT( (-infinity, 7) )",
        binding.getExpr().toString());

    // This one should fail:  two variables
    pred1 =
        rexBuilder.makeCall(
            SqlStdOperatorTable.LESS_THAN,
            inputRef8,
            inputRef9);
    binding = rexAnalyzer.analyze(pred1);
    assertNull(binding);

    // This one should fail:  two literals
    pred1 =
        rexBuilder.makeCall(
            SqlStdOperatorTable.LESS_THAN,
            intLiteral7,
            intLiteral490);
    binding = rexAnalyzer.analyze(pred1);
    assertNull(binding);
  }
}

// End SargTest.java


<|start_filename|>avatica/src/main/java/net/hydromatic/avatica/DriverVersion.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.avatica;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

/**
 * Driver version information.
 *
 * <p>Each driver implementation must provide an instance of this class, in
 * order to implement {@link UnregisteredDriver#createDriverVersion()}.</p>
 *
 * <p>There are two typical ways for a driver to instantiate its version
 * information:</p>
 *
 * <ul>
 *
 * <li>A driver might create a subclass in a with a constructor that provides
 * all of the arguments for the base class. The instance is held in a separate
 * file, so that that version information can be generated.</li>
 *
 * <li>A driver might store the version information in a .properties file and
 * load it using {@link #load}.</li>
 *
 * </ul>
 */
public class DriverVersion {
  public final int majorVersion;
  public final int minorVersion;
  public final String name;
  public final String versionString;
  public final String productName;
  public final String productVersion;
  public final boolean jdbcCompliant;
  public final int databaseMajorVersion;
  public final int databaseMinorVersion;

  /** Creates a DriverVersion. */
  public DriverVersion(
      String name,
      String versionString,
      String productName,
      String productVersion,
      boolean jdbcCompliant,
      int majorVersion,
      int minorVersion,
      int databaseMajorVersion,
      int databaseMinorVersion) {
    this.majorVersion = majorVersion;
    this.minorVersion = minorVersion;
    this.name = name;
    this.versionString = versionString;
    this.productName = productName;
    this.productVersion = productVersion;
    this.jdbcCompliant = jdbcCompliant;
    this.databaseMajorVersion = databaseMajorVersion;
    this.databaseMinorVersion = databaseMinorVersion;
  }

  /** Loads a driver version from a properties file, read from the classpath.
   * The arguments provide defaults if the properties cannot be loaded.
   *
   * @param driverClass Class of driver; used to find resource
   * @param resourceName Name of resource file
   * @param driverName Fallback name of driver
   * @param driverVersion Fallback version of driver
   * @param productName Fallback product name
   * @param productVersion Fallback product version
   * @return A populated driver version object, never null
   */
  public static DriverVersion load(
      Class<? extends UnregisteredDriver> driverClass,
      String resourceName,
      String driverName,
      String driverVersion,
      String productName,
      String productVersion) {
    boolean jdbcCompliant = true;
    int majorVersion = 0;
    int minorVersion = 0;
    int databaseMajorVersion = 0;
    int databaseMinorVersion = 0;
    try {
      final InputStream inStream =
          driverClass.getClassLoader().getResourceAsStream(resourceName);
      if (inStream != null) {
        final Properties properties = new Properties();
        properties.load(inStream);
        driverName = properties.getProperty("driver.name");
        driverVersion = properties.getProperty("driver.version");
        productName = properties.getProperty("product.name");
        productVersion = properties.getProperty("product.version");
        jdbcCompliant =
            Boolean.valueOf(properties.getProperty("jdbc.compliant"));
        majorVersion =
            Integer.valueOf(
                properties.getProperty("driver.version.major"));
        minorVersion =
            Integer.valueOf(
                properties.getProperty("driver.version.minor"));
        databaseMajorVersion =
            Integer.valueOf(
                properties.getProperty("database.version.major"));
        databaseMinorVersion =
            Integer.valueOf(
                properties.getProperty("database.version.minor"));
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
    return new DriverVersion(
        driverName, driverVersion, productName, productVersion,
        jdbcCompliant, majorVersion, minorVersion, databaseMajorVersion,
        databaseMinorVersion);
  }
}

// End DriverVersion.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/advise/SqlAdvisorHint.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql.advise;

import java.util.List;

import org.eigenbase.sql.validate.SqlMoniker;

/**
 * This class is used to return values for {@link SqlAdvisor#getCompletionHints
 * (String, int, String[])}.
 */
public class SqlAdvisorHint {
  /** Fully qualified object name as string. */
  public final String id;
  /** Fully qualified object name as array of names. */
  public final String[] names;
  /** One of {@link org.eigenbase.sql.validate.SqlMonikerType}. */
  public final String type;

  public SqlAdvisorHint(String id, String[] names, String type) {
    this.id = id;
    this.names = names;
    this.type = type;
  }

  public SqlAdvisorHint(SqlMoniker id) {
    this.id = id.toString();
    final List<String> names = id.getFullyQualifiedNames();
    this.names = names == null
      ? null
      : names.toArray(new String[names.size()]);
    type = id.getType().name();
  }
}


<|start_filename|>core/src/main/java/org/eigenbase/sql/fun/SqlCoalesceFunction.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql.fun;

import java.util.List;

import org.eigenbase.sql.*;
import org.eigenbase.sql.parser.*;
import org.eigenbase.sql.type.*;
import org.eigenbase.sql.validate.*;
import org.eigenbase.util.Util;

/**
 * The <code>COALESCE</code> function.
 */
public class SqlCoalesceFunction extends SqlFunction {
  //~ Constructors -----------------------------------------------------------

  public SqlCoalesceFunction() {
    // NOTE jvs 26-July-2006:  We fill in the type strategies here,
    // but normally they are not used because the validator invokes
    // rewriteCall to convert COALESCE into CASE early.  However,
    // validator rewrite can optionally be disabled, in which case these
    // strategies are used.
    super(
        "COALESCE",
        SqlKind.OTHER_FUNCTION,
        ReturnTypes.LEAST_RESTRICTIVE,
        null,
        OperandTypes.SAME_VARIADIC,
        SqlFunctionCategory.SYSTEM);
  }

  //~ Methods ----------------------------------------------------------------

  // override SqlOperator
  public SqlNode rewriteCall(SqlValidator validator, SqlCall call) {
    validateQuantifier(validator, call); // check DISTINCT/ALL

    List<SqlNode> operands = call.getOperandList();

    if (operands.size() == 1) {
      // No CASE needed
      return operands.get(0);
    }

    SqlParserPos pos = call.getParserPosition();

    SqlNodeList whenList = new SqlNodeList(pos);
    SqlNodeList thenList = new SqlNodeList(pos);

    // todo: optimize when know operand is not null.

    for (int i = 0; (i + 1) < operands.size(); ++i) {
      whenList.add(
          SqlStdOperatorTable.IS_NOT_NULL.createCall(
              pos,
              operands.get(i)));
      thenList.add(operands.get(i).clone(operands.get(i).getParserPosition()));
    }
    SqlNode elseExpr = Util.last(operands);
    assert call.getFunctionQuantifier() == null;
    return SqlCase.createSwitched(
        pos, null, whenList, thenList, elseExpr);
  }
}

// End SqlCoalesceFunction.java


<|start_filename|>avatica/src/main/java/net/hydromatic/avatica/BuiltInConnectionProperty.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.avatica;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import static net.hydromatic.avatica.ConnectionConfigImpl.*;

/**
 * Enumeration of Avatica's built-in connection properties.
 */
public enum BuiltInConnectionProperty implements ConnectionProperty {
  /** Name of initial schema. */
  SCHEMA("schema", Type.STRING, null),

  /** Timezone, for example 'gmt-3'. Default is the JVM's time zone. */
  TIMEZONE("timezone", Type.STRING, null);

  private final String camelName;
  private final Type type;
  private final Object defaultValue;

  private static final Map<String, BuiltInConnectionProperty> NAME_TO_PROPS;

  static {
    NAME_TO_PROPS = new HashMap<String, BuiltInConnectionProperty>();
    for (BuiltInConnectionProperty p : BuiltInConnectionProperty.values()) {
      NAME_TO_PROPS.put(p.camelName.toUpperCase(), p);
      NAME_TO_PROPS.put(p.name(), p);
    }
  }

  BuiltInConnectionProperty(String camelName, Type type, Object defaultValue) {
    this.camelName = camelName;
    this.type = type;
    this.defaultValue = defaultValue;
    assert defaultValue == null || type.valid(defaultValue);
  }

  public String camelName() {
    return camelName;
  }

  public Object defaultValue() {
    return defaultValue;
  }

  public Type type() {
    return type;
  }

  public PropEnv wrap(Properties properties) {
    return new PropEnv(parse(properties, NAME_TO_PROPS), this);
  }
}

// End BuiltInConnectionProperty.java


<|start_filename|>core/src/main/java/org/eigenbase/rel/RelShuttle.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel;

/**
 * Visitor that has methods for the common logical relational expressions.
 */
public interface RelShuttle {
  RelNode visit(TableAccessRelBase scan);

  RelNode visit(TableFunctionRelBase scan);

  RelNode visit(ValuesRel values);

  RelNode visit(FilterRel filter);

  RelNode visit(ProjectRel project);

  RelNode visit(JoinRel join);

  RelNode visit(UnionRel union);

  RelNode visit(IntersectRel intersect);

  RelNode visit(MinusRel minus);

  RelNode visit(AggregateRel aggregate);

  RelNode visit(SortRel sort);

  RelNode visit(RelNode other);
}

// End RelShuttle.java


<|start_filename|>core/src/main/java/net/hydromatic/optiq/rules/java/EnumerableConvention.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.rules.java;

import org.eigenbase.relopt.*;

/**
 * Family of calling conventions that return results as an
 * {@link net.hydromatic.linq4j.Enumerable}.
 */
public enum EnumerableConvention implements Convention {
  INSTANCE;

  @Override
  public String toString() {
    return getName();
  }

  public Class getInterface() {
    return EnumerableRel.class;
  }

  public String getName() {
    return "ENUMERABLE";
  }

  public RelTraitDef getTraitDef() {
    return ConventionTraitDef.INSTANCE;
  }

  public boolean subsumes(RelTrait trait) {
    return this == trait;
  }

  public void register(RelOptPlanner planner) {}
}

// End EnumerableConvention.java


<|start_filename|>core/src/main/java/org/eigenbase/util/ImmutableIntList.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.util;

import java.lang.reflect.Array;
import java.util.*;

import net.hydromatic.optiq.runtime.FlatLists;

/**
 * An immutable list of {@link Integer} values backed by an array of
 * {@code int}s.
 */
public class ImmutableIntList extends FlatLists.AbstractFlatList<Integer> {
  private final int[] ints;

  private static final Object[] EMPTY_ARRAY = new Object[0];

  private static final ImmutableIntList EMPTY = new EmptyImmutableIntList();

  // Does not copy array. Must remain private.
  private ImmutableIntList(int... ints) {
    this.ints = ints;
  }

  /**
   * Returns an empty ImmutableIntList.
   */
  public static ImmutableIntList of() {
    return EMPTY;
  }

  /**
   * Creates an ImmutableIntList from an array of {@code int}.
   */
  public static ImmutableIntList of(int... ints) {
    return new ImmutableIntList(ints.clone());
  }

  /**
   * Creates an ImmutableIntList from an array of {@code Number}.
   */
  public static ImmutableIntList copyOf(Number... numbers) {
    final int[] ints = new int[numbers.length];
    for (int i = 0; i < ints.length; i++) {
      ints[i] = numbers[i].intValue();
    }
    return new ImmutableIntList(ints);
  }

  /**
   * Creates an ImmutableIntList from a collection of {@link Number}.
   */
  public static ImmutableIntList copyOf(Collection<? extends Number> list) {
    if (list instanceof ImmutableIntList) {
      return (ImmutableIntList) list;
    }
    if (list.isEmpty()) {
      return EMPTY;
    }
    final int[] ints = new int[list.size()];
    int i = 0;
    for (Number number : list) {
      ints[i++] = number.intValue();
    }
    return new ImmutableIntList(ints);
  }

  @Override
  public int hashCode() {
    return Arrays.hashCode(ints);
  }

  @Override
  public boolean equals(Object obj) {
    return this == obj
        || obj instanceof ImmutableIntList
        && Arrays.equals(ints, ((ImmutableIntList) obj).ints)
        || obj instanceof List
        && obj.equals(this);
  }

  @Override
  public String toString() {
    return Arrays.toString(ints);
  }

  @Override
  public boolean isEmpty() {
    return ints.length == 0;
  }

  public int size() {
    return ints.length;
  }

  public Object[] toArray() {
    final Object[] objects = new Object[ints.length];
    for (int i = 0; i < objects.length; i++) {
      objects[i] = ints[i];
    }
    return objects;
  }

  public <T> T[] toArray(T[] a) {
    final int size = ints.length;
    if (a.length < size) {
      // Make a new array of a's runtime type, but my contents:
      a = a.getClass() == Object[].class
          ? (T[]) new Object[size]
          : (T[]) Array.newInstance(
              a.getClass().getComponentType(), size);
    }
    if (a.getClass() == Integer[].class) {
      final Integer[] integers = (Integer[]) a;
      for (int i = 0; i < integers.length; i++) {
        integers[i] = ints[i];
      }
    } else {
      System.arraycopy(toArray(), 0, a, 0, size);
    }
    if (a.length > size) {
      a[size] = null;
    }
    return a;
  }

  public Integer get(int index) {
    return ints[index];
  }

  public int indexOf(Object o) {
    if (o instanceof Integer) {
      final int seek = (Integer) o;
      for (int i = 0; i < ints.length; i++) {
        if (ints[i] == seek) {
          return i;
        }
      }
    }
    return -1;
  }

  public int lastIndexOf(Object o) {
    if (o instanceof Integer) {
      final int seek = (Integer) o;
      for (int i = ints.length - 1; i >= 0; --i) {
        if (ints[i] == seek) {
          return i;
        }
      }
    }
    return -1;
  }

  private static class EmptyImmutableIntList extends ImmutableIntList {
    @Override
    public Object[] toArray() {
      return EMPTY_ARRAY;
    }

    @Override
    public <T> T[] toArray(T[] a) {
      if (a.length > 0) {
        a[0] = null;
      }
      return a;
    }
  }
}

// End ImmutableIntList.java


<|start_filename|>core/src/main/java/net/hydromatic/optiq/impl/DelegatingSchema.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.impl;

import net.hydromatic.linq4j.expressions.Expression;

import net.hydromatic.optiq.*;

import java.util.Collection;
import java.util.Set;

/**
 * Implementation of {@link net.hydromatic.optiq.Schema} that delegates to an
 * underlying schema.
 */
public class DelegatingSchema implements Schema {
  protected final Schema schema;

  /**
   * Creates a DelegatingSchema.
   *
   * @param schema Underlying schema
   */
  public DelegatingSchema(Schema schema) {
    this.schema = schema;
  }

  @Override
  public String toString() {
    return "DelegatingSchema(delegate=" + schema + ")";
  }

  public boolean isMutable() {
    return schema.isMutable();
  }

  public boolean contentsHaveChangedSince(long lastCheck, long now) {
    return schema.contentsHaveChangedSince(lastCheck, now);
  }

  public Expression getExpression(SchemaPlus parentSchema, String name) {
    return schema.getExpression(parentSchema, name);
  }

  public Table getTable(String name) {
    return schema.getTable(name);
  }

  public Set<String> getTableNames() {
    return schema.getTableNames();
  }

  public Collection<Function> getFunctions(String name) {
    return schema.getFunctions(name);
  }

  public Set<String> getFunctionNames() {
    return schema.getFunctionNames();
  }

  public Schema getSubSchema(String name) {
    return schema.getSubSchema(name);
  }

  public Set<String> getSubSchemaNames() {
    return schema.getSubSchemaNames();
  }
}

// End DelegatingSchema.java


<|start_filename|>core/src/main/java/net/hydromatic/optiq/jdbc/OptiqPreparedStatement.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.jdbc;

import net.hydromatic.avatica.AvaticaPrepareResult;
import net.hydromatic.avatica.AvaticaPreparedStatement;

import net.hydromatic.optiq.server.OptiqServerStatement;

import java.sql.*;

/**
 * Implementation of {@link java.sql.PreparedStatement}
 * for the Optiq engine.
 *
 * <p>This class has sub-classes which implement JDBC 3.0 and JDBC 4.0 APIs;
 * it is instantiated using {@link net.hydromatic.avatica.AvaticaFactory#newPreparedStatement}.</p>
 */
abstract class OptiqPreparedStatement
    extends AvaticaPreparedStatement
    implements OptiqServerStatement {
  /**
   * Creates an OptiqPreparedStatement.
   *
   * @param connection Connection
   * @param prepareResult Result of preparing statement
   *
   * @throws SQLException if database error occurs
   */
  protected OptiqPreparedStatement(
      OptiqConnectionImpl connection,
      AvaticaPrepareResult prepareResult,
      int resultSetType,
      int resultSetConcurrency,
      int resultSetHoldability)
    throws SQLException {
    super(
        connection, prepareResult, resultSetType, resultSetConcurrency,
        resultSetHoldability);
  }

  @Override
  public OptiqConnectionImpl getConnection() {
    return (OptiqConnectionImpl) super.getConnection();
  }

  public OptiqConnectionImpl.ContextImpl createPrepareContext() {
    return new OptiqConnectionImpl.ContextImpl(getConnection());
  }
}

// End OptiqPreparedStatement.java


<|start_filename|>core/src/test/java/org/eigenbase/relopt/RelWriterTest.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.relopt;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.Arrays;

import org.eigenbase.rel.*;
import org.eigenbase.reltype.RelDataType;
import org.eigenbase.rex.RexBuilder;
import org.eigenbase.sql.SqlExplainLevel;
import org.eigenbase.sql.fun.SqlStdOperatorTable;
import org.eigenbase.sql.type.SqlTypeName;
import org.eigenbase.util.Util;

import net.hydromatic.optiq.SchemaPlus;
import net.hydromatic.optiq.impl.java.ReflectiveSchema;
import net.hydromatic.optiq.test.JdbcTest;
import net.hydromatic.optiq.tools.Frameworks;
import net.hydromatic.optiq.util.BitSets;

import com.google.common.collect.ImmutableList;

import org.junit.Test;

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.assertThat;

/**
 * Unit test for {@link org.eigenbase.rel.RelJson}.
 */
public class RelWriterTest {
  public static final String XX =
      "{\n"
      + "  rels: [\n"
      + "    {\n"
      + "      id: \"0\",\n"
      + "      relOp: \"TableAccessRel\",\n"
      + "      table: [\n"
      + "        \"hr\",\n"
      + "        \"emps\"\n"
      + "      ],\n"
      + "      inputs: []\n"
      + "    },\n"
      + "    {\n"
      + "      id: \"1\",\n"
      + "      relOp: \"FilterRel\",\n"
      + "      condition: {\n"
      + "        op: \"=\",\n"
      + "        operands: [\n"
      + "          {\n"
      + "            input: 1\n"
      + "          },\n"
      + "          10\n"
      + "        ]\n"
      + "      }\n"
      + "    },\n"
      + "    {\n"
      + "      id: \"2\",\n"
      + "      relOp: \"AggregateRel\",\n"
      + "      group: [\n"
      + "        0\n"
      + "      ],\n"
      + "      aggs: [\n"
      + "        {\n"
      + "          agg: \"COUNT\",\n"
      + "          type: {\n"
      + "            type: \"INTEGER\",\n"
      + "            nullable: false\n"
      + "          },\n"
      + "          distinct: true,\n"
      + "          operands: [\n"
      + "            1\n"
      + "          ]\n"
      + "        },\n"
      + "        {\n"
      + "          agg: \"COUNT\",\n"
      + "          type: {\n"
      + "            type: \"INTEGER\",\n"
      + "            nullable: false\n"
      + "          },\n"
      + "          distinct: false,\n"
      + "          operands: []\n"
      + "        }\n"
      + "      ]\n"
      + "    }\n"
      + "  ]\n"
      + "}";

  /**
   * Unit test for {@link org.eigenbase.rel.RelJsonWriter} on
   * a simple tree of relational expressions, consisting of a table, a filter
   * and an aggregate node.
   */
  @Test public void testWriter() {
    String s =
        Frameworks.withPlanner(
            new Frameworks.PlannerAction<String>() {
              public String apply(RelOptCluster cluster,
                  RelOptSchema relOptSchema, SchemaPlus rootSchema) {
                rootSchema.add("hr",
                    new ReflectiveSchema(new JdbcTest.HrSchema()));
                TableAccessRel table =
                    new TableAccessRel(cluster,
                        relOptSchema.getTableForMember(
                            Arrays.asList("hr", "emps")));
                final RexBuilder rexBuilder = cluster.getRexBuilder();
                FilterRel filter =
                    new FilterRel(cluster, table,
                        rexBuilder.makeCall(
                            SqlStdOperatorTable.EQUALS,
                            rexBuilder.makeFieldAccess(
                                rexBuilder.makeRangeReference(table),
                                "deptno", true),
                            rexBuilder.makeExactLiteral(BigDecimal.TEN)));
                final RelJsonWriter writer = new RelJsonWriter();
                final RelDataType intType =
                    cluster.getTypeFactory().createSqlType(SqlTypeName.INTEGER);
                AggregateRel aggregate =
                    new AggregateRel(cluster, filter, BitSets.of(0),
                        ImmutableList.of(
                            new AggregateCall(SqlStdOperatorTable.COUNT,
                                true, ImmutableList.of(1), intType, "c"),
                            new AggregateCall(SqlStdOperatorTable.COUNT,
                                false, ImmutableList.<Integer>of(), intType,
                                "d")));
                aggregate.explain(writer);
                return writer.asString();
              }
            });
    assertThat(s, is(XX));
  }

  /**
   * Unit test for {@link org.eigenbase.rel.RelJsonReader}.
   */
  @Test public void testReader() {
    String s =
        Frameworks.withPlanner(
            new Frameworks.PlannerAction<String>() {
              public String apply(RelOptCluster cluster,
                  RelOptSchema relOptSchema, SchemaPlus rootSchema) {
                SchemaPlus schema =
                    rootSchema.add("hr",
                        new ReflectiveSchema(new JdbcTest.HrSchema()));
                final RelJsonReader reader =
                    new RelJsonReader(cluster, relOptSchema, schema);
                RelNode node;
                try {
                  node = reader.read(XX);
                } catch (IOException e) {
                  throw new RuntimeException(e);
                }
                return RelOptUtil.dumpPlan(
                    "",
                    node,
                    false,
                    SqlExplainLevel.EXPPLAN_ATTRIBUTES);
              }
            });

    assertThat(Util.toLinux(s), is(
        "AggregateRel(group=[{0}], agg#0=[COUNT(DISTINCT $1)], agg#1=[COUNT()])\n"
        + "  FilterRel(condition=[=($1, 10)])\n"
        + "    TableAccessRel(table=[[hr, emps]])\n"));
  }
}

// End RelWriterTest.java


<|start_filename|>core/src/main/java/org/eigenbase/rel/FilterRel.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel;

import java.util.List;

import org.eigenbase.relopt.*;
import org.eigenbase.rex.*;

/**
 * A <code>FilterRel</code> is a relational expression which iterates over its
 * input, and returns elements for which <code>condition</code> evaluates to
 * <code>true</code>.
 */
public final class FilterRel extends FilterRelBase {
  //~ Constructors -----------------------------------------------------------

  /**
   * Creates a filter.
   *
   * @param cluster   {@link RelOptCluster}  this relational expression belongs
   *                  to
   * @param child     input relational expression
   * @param condition boolean expression which determines whether a row is
   *                  allowed to pass
   */
  public FilterRel(
      RelOptCluster cluster,
      RelNode child,
      RexNode condition) {
    super(
        cluster,
        cluster.traitSetOf(Convention.NONE),
        child,
        condition);
  }

  /**
   * Creates a FilterRel by parsing serialized output.
   */
  public FilterRel(RelInput input) {
    super(input);
  }

  //~ Methods ----------------------------------------------------------------

  @Override
  public RelNode copy(RelTraitSet traitSet, List<RelNode> inputs) {
    assert traitSet.containsIfApplicable(Convention.NONE);
    return new FilterRel(
        getCluster(),
        sole(inputs),
        getCondition());
  }

  @Override
  public RelNode accept(RelShuttle shuttle) {
    return shuttle.visit(this);
  }
}

// End FilterRel.java


<|start_filename|>core/src/main/java/net/hydromatic/optiq/TranslatableTable.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq;

import org.eigenbase.rel.RelNode;
import org.eigenbase.relopt.RelOptTable;

/**
 * Extension to {@link Table} that specifies how it is to be translated to
 * a {@link org.eigenbase.rel.RelNode planner node}.
 *
 * <p>It is optional for a Table to implement this interface. A Table that does
 * not implement this interface, a Table will be converted to an
 * EnumerableTableAccessRel. Generally a Table will implements this interface to
 * create a particular subclass of RelNode, and also register rules that act
 * on that particular subclass of RelNode.</p>
 */
public interface TranslatableTable extends Table {
  /** Converts this table into a {@link RelNode relational expression}. */
  RelNode toRel(
      RelOptTable.ToRelContext context,
      RelOptTable relOptTable);
}

// End TranslatableTable.java


<|start_filename|>core/src/main/java/net/hydromatic/optiq/impl/clone/CloneSchema.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.impl.clone;

import net.hydromatic.avatica.ColumnMetaData;

import net.hydromatic.linq4j.*;

import net.hydromatic.optiq.*;
import net.hydromatic.optiq.impl.AbstractSchema;
import net.hydromatic.optiq.impl.java.*;
import net.hydromatic.optiq.impl.jdbc.JdbcSchema;
import net.hydromatic.optiq.jdbc.OptiqConnection;

import org.eigenbase.reltype.RelProtoDataType;

import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;

import java.lang.reflect.Type;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import static net.hydromatic.optiq.impl.MaterializedViewTable.MATERIALIZATION_CONNECTION;

/**
 * Schema that contains in-memory copies of tables from a JDBC schema.
 */
public class CloneSchema extends AbstractSchema {
  // TODO: implement 'driver' property
  // TODO: implement 'source' property
  // TODO: test Factory

  private final SchemaPlus sourceSchema;

  /**
   * Creates a CloneSchema.
   *
   * @param sourceSchema JDBC data source
   */
  public CloneSchema(SchemaPlus sourceSchema) {
    super();
    this.sourceSchema = sourceSchema;
  }

  @Override
  protected Map<String, Table> getTableMap() {
    final Map<String, Table> map = new LinkedHashMap<String, Table>();
    for (String name : sourceSchema.getTableNames()) {
      final QueryableTable sourceTable =
          (QueryableTable) sourceSchema.getTable(name);
      map.put(name,
          createCloneTable(MATERIALIZATION_CONNECTION, sourceTable, name));
    }
    return map;
  }

  private Table createCloneTable(QueryProvider queryProvider,
      QueryableTable sourceTable, String name) {
    final Queryable<Object> queryable =
        sourceTable.asQueryable(queryProvider, sourceSchema, name);
    final JavaTypeFactory typeFactory =
        ((OptiqConnection) queryProvider).getTypeFactory();
    return createCloneTable(typeFactory, Schemas.proto(sourceTable), null,
        queryable);
  }

  public static <T> Table createCloneTable(final JavaTypeFactory typeFactory,
      final RelProtoDataType protoRowType,
      final List<ColumnMetaData.Rep> repList,
      final Enumerable<T> source) {
    final Type elementType = source instanceof QueryableTable
        ? ((QueryableTable) source).getElementType()
        : Object[].class;
    return new ArrayTable(
        elementType,
        protoRowType,
        Suppliers.memoize(
            new Supplier<ArrayTable.Content>() {
              public ArrayTable.Content get() {
                final ColumnLoader loader =
                    new ColumnLoader<T>(typeFactory, source, protoRowType,
                        repList);
                return new ArrayTable.Content(loader.representationValues,
                    loader.size(), loader.sortField);
              }
            }));
  }

  /** Schema factory that creates a
   * {@link net.hydromatic.optiq.impl.clone.CloneSchema}.
   * This allows you to create a clone schema inside a model.json file.
   *
   * <pre>{@code
   * {
   *   version: '1.0',
   *   defaultSchema: 'FOODMART_CLONE',
   *   schemas: [
   *     {
   *       name: 'FOODMART_CLONE',
   *       type: 'custom',
   *       factory: 'net.hydromatic.optiq.impl.clone.CloneSchema$Factory',
   *       operand: {
   *         jdbcDriver: 'com.mysql.jdbc.Driver',
   *         jdbcUrl: 'jdbc:mysql://localhost/foodmart',
   *         jdbcUser: 'foodmart',
   *         jdbcPassword: '<PASSWORD>'
   *       }
   *     }
   *   ]
   * }
   * }</pre>
   */
  public static class Factory implements SchemaFactory {
    public Schema create(
        SchemaPlus parentSchema,
        String name,
        Map<String, Object> operand) {
      SchemaPlus schema =
          parentSchema.add(name,
              JdbcSchema.create(parentSchema, name + "$source", operand));
      return new CloneSchema(schema);
    }
  }
}

// End CloneSchema.java


<|start_filename|>core/src/main/java/net/hydromatic/optiq/materialize/package-info.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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.
*/

/**
 * Management of materialized query results.
 *
 * <p>An actor ({@link net.hydromatic.optiq.materialize.MaterializationActor})
 * maintains the state of all
 * materializations in the system and is wrapped in a service
 * ({@link net.hydromatic.optiq.materialize.MaterializationService})
 * for access from other parts of the system.</p>
 *
 * <p>Optimizer rules allow Optiq to rewrite queries using materializations, if
 * they are valid (that is, contain the same result as executing their defining
 * query) and lower cost.
 *
 * <p>In future, the actor may manage the process of updating materializations,
 * instantiating materializations from the intermediate results of queries, and
 * recognize what materializations would be useful based on actual query load.
 */
package net.hydromatic.optiq.materialize;

// End package-info.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/validate/ParameterScope.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql.validate;

import java.util.*;

import org.eigenbase.reltype.*;
import org.eigenbase.sql.*;

/**
 * A scope which contains nothing besides a few parameters. Like {@link
 * EmptyScope} (which is its base class), it has no parent scope.
 *
 * @see ParameterNamespace
 */
public class ParameterScope extends EmptyScope {
  //~ Instance fields --------------------------------------------------------

  /**
   * Map from the simple names of the parameters to types of the parameters
   * ({@link RelDataType}).
   */
  private final Map<String, RelDataType> nameToTypeMap;

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

  public ParameterScope(
      SqlValidatorImpl validator,
      Map<String, RelDataType> nameToTypeMap) {
    super(validator);
    this.nameToTypeMap = nameToTypeMap;
  }

  //~ Methods ----------------------------------------------------------------

  public SqlIdentifier fullyQualify(SqlIdentifier identifier) {
    return identifier;
  }

  public SqlValidatorScope getOperandScope(SqlCall call) {
    return this;
  }

  public SqlValidatorNamespace resolve(
      String name,
      SqlValidatorScope[] ancestorOut,
      int[] offsetOut) {
    final RelDataType type = nameToTypeMap.get(name);
    return new ParameterNamespace(validator, type);
  }
}

// End ParameterScope.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/validate/SqlValidatorException.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql.validate;

import java.util.logging.*;

// NOTE:  This class gets compiled independently of everything else so that
// resource generation can use reflection.  That means it must have no
// dependencies on other Eigenbase/Farrago code.

import org.eigenbase.util14.*;

/**
 * Exception thrown while validating a SQL statement.
 *
 * <p>Unlike {@link org.eigenbase.util.EigenbaseException}, this is a checked
 * exception, which reminds code authors to wrap it in another exception
 * containing the line/column context.
 */
public class SqlValidatorException extends Exception
    implements EigenbaseValidatorException {
  //~ Static fields/initializers ---------------------------------------------

  private static final Logger LOGGER =
      Logger.getLogger("org.eigenbase.util.EigenbaseException");

  static final long serialVersionUID = -831683113957131387L;

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

  /**
   * Creates a new SqlValidatorException object.
   *
   * @param message error message
   * @param cause   underlying cause
   */
  public SqlValidatorException(
      String message,
      Throwable cause) {
    super(message, cause);

    // TODO: see note in EigenbaseException constructor
    LOGGER.throwing("SqlValidatorException", "constructor", this);
    LOGGER.severe(toString());
  }
}

// End SqlValidatorException.java


<|start_filename|>core/src/main/java/net/hydromatic/optiq/jdbc/OptiqJdbc41Factory.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.jdbc;

import net.hydromatic.avatica.*;

import net.hydromatic.optiq.impl.java.JavaTypeFactory;

import java.io.InputStream;
import java.io.Reader;
import java.sql.*;
import java.util.List;
import java.util.Properties;
import java.util.TimeZone;

/**
 * Implementation of {@link net.hydromatic.avatica.AvaticaFactory}
 * for Optiq and JDBC 4.1 (corresponds to JDK 1.7).
 */
@SuppressWarnings("UnusedDeclaration")
public class OptiqJdbc41Factory extends OptiqFactory {
  /** Creates a factory for JDBC version 4.1. */
  public OptiqJdbc41Factory() {
    this(4, 1);
  }

  /** Creates a JDBC factory with given major/minor version number. */
  protected OptiqJdbc41Factory(int major, int minor) {
    super(major, minor);
  }

  public OptiqJdbc41Connection newConnection(UnregisteredDriver driver,
      AvaticaFactory factory, String url, Properties info,
      OptiqRootSchema rootSchema, JavaTypeFactory typeFactory) {
    return new OptiqJdbc41Connection(
        (Driver) driver, factory, url, info, rootSchema, typeFactory);
  }

  public OptiqJdbc41DatabaseMetaData newDatabaseMetaData(
      AvaticaConnection connection) {
    return new OptiqJdbc41DatabaseMetaData(
        (OptiqConnectionImpl) connection);
  }

  public OptiqJdbc41Statement newStatement(
      AvaticaConnection connection,
      int resultSetType,
      int resultSetConcurrency,
      int resultSetHoldability) {
    return new OptiqJdbc41Statement(
        (OptiqConnectionImpl) connection, resultSetType, resultSetConcurrency,
        resultSetHoldability);
  }

  public AvaticaPreparedStatement newPreparedStatement(
      AvaticaConnection connection,
      AvaticaPrepareResult prepareResult,
      int resultSetType,
      int resultSetConcurrency,
      int resultSetHoldability) throws SQLException {
    return new OptiqJdbc41PreparedStatement(
        (OptiqConnectionImpl) connection,
        (OptiqPrepare.PrepareResult) prepareResult, resultSetType,
        resultSetConcurrency, resultSetHoldability);
  }

  public OptiqResultSet newResultSet(
      AvaticaStatement statement,
      AvaticaPrepareResult prepareResult,
      TimeZone timeZone) {
    final ResultSetMetaData metaData =
        newResultSetMetaData(statement, prepareResult.getColumnList());
    return new OptiqResultSet(statement,
        (OptiqPrepare.PrepareResult) prepareResult, metaData, timeZone);
  }

  public ResultSetMetaData newResultSetMetaData(
      AvaticaStatement statement,
      List<ColumnMetaData> columnMetaDataList) {
    return new AvaticaResultSetMetaData(
        statement, null, columnMetaDataList);
  }

  /** Implementation of connection for JDBC 4.1. */
  private static class OptiqJdbc41Connection extends OptiqConnectionImpl {
    OptiqJdbc41Connection(Driver driver, AvaticaFactory factory, String url,
        Properties info, OptiqRootSchema rootSchema,
        JavaTypeFactory typeFactory) {
      super(driver, factory, url, info, rootSchema, typeFactory);
    }
  }

  /** Implementation of statement for JDBC 4.1. */
  private static class OptiqJdbc41Statement extends OptiqStatement {
    public OptiqJdbc41Statement(
        OptiqConnectionImpl connection,
        int resultSetType,
        int resultSetConcurrency,
        int resultSetHoldability) {
      super(connection, resultSetType, resultSetConcurrency,
          resultSetHoldability);
    }
  }

  /** Implementation of prepared statement for JDBC 4.1. */
  private static class OptiqJdbc41PreparedStatement
      extends OptiqPreparedStatement {
    OptiqJdbc41PreparedStatement(
        OptiqConnectionImpl connection,
        OptiqPrepare.PrepareResult prepareResult,
        int resultSetType,
        int resultSetConcurrency,
        int resultSetHoldability) throws SQLException {
      super(
          connection, prepareResult, resultSetType, resultSetConcurrency,
          resultSetHoldability);
    }

    public void setRowId(
        int parameterIndex,
        RowId x) throws SQLException {
      getParameter(parameterIndex).setRowId(x);
    }

    public void setNString(
        int parameterIndex, String value) throws SQLException {
      getParameter(parameterIndex).setNString(value);
    }

    public void setNCharacterStream(
        int parameterIndex,
        Reader value,
        long length) throws SQLException {
      getParameter(parameterIndex).setNCharacterStream(value, length);
    }

    public void setNClob(
        int parameterIndex,
        NClob value) throws SQLException {
      getParameter(parameterIndex).setNClob(value);
    }

    public void setClob(
        int parameterIndex,
        Reader reader,
        long length) throws SQLException {
      getParameter(parameterIndex).setClob(reader, length);
    }

    public void setBlob(
        int parameterIndex,
        InputStream inputStream,
        long length) throws SQLException {
      getParameter(parameterIndex).setBlob(inputStream, length);
    }

    public void setNClob(
        int parameterIndex,
        Reader reader,
        long length) throws SQLException {
      getParameter(parameterIndex).setNClob(reader, length);
    }

    public void setSQLXML(
        int parameterIndex, SQLXML xmlObject) throws SQLException {
      getParameter(parameterIndex).setSQLXML(xmlObject);
    }

    public void setAsciiStream(
        int parameterIndex,
        InputStream x,
        long length) throws SQLException {
      getParameter(parameterIndex).setAsciiStream(x, length);
    }

    public void setBinaryStream(
        int parameterIndex,
        InputStream x,
        long length) throws SQLException {
      getParameter(parameterIndex).setBinaryStream(x, length);
    }

    public void setCharacterStream(
        int parameterIndex,
        Reader reader,
        long length) throws SQLException {
      getParameter(parameterIndex).setCharacterStream(reader, length);
    }

    public void setAsciiStream(
        int parameterIndex, InputStream x) throws SQLException {
      getParameter(parameterIndex).setAsciiStream(x);
    }

    public void setBinaryStream(
        int parameterIndex, InputStream x) throws SQLException {
      getParameter(parameterIndex).setBinaryStream(x);
    }

    public void setCharacterStream(
        int parameterIndex, Reader reader) throws SQLException {
      getParameter(parameterIndex).setCharacterStream(reader);
    }

    public void setNCharacterStream(
        int parameterIndex, Reader value) throws SQLException {
      getParameter(parameterIndex).setNCharacterStream(value);
    }

    public void setClob(
        int parameterIndex,
        Reader reader) throws SQLException {
      getParameter(parameterIndex).setClob(reader);
    }

    public void setBlob(
        int parameterIndex, InputStream inputStream) throws SQLException {
      getParameter(parameterIndex).setBlob(inputStream);
    }

    public void setNClob(
        int parameterIndex, Reader reader) throws SQLException {
      getParameter(parameterIndex).setNClob(reader);
    }
  }

  /** Implementation of database metadata for JDBC 4.1. */
  private static class OptiqJdbc41DatabaseMetaData
      extends AvaticaDatabaseMetaData {
    OptiqJdbc41DatabaseMetaData(OptiqConnectionImpl connection) {
      super(connection);
    }
  }
}

// End OptiqJdbc41Factory.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/util/ChainedSqlOperatorTable.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql.util;

import java.util.*;

import org.eigenbase.sql.*;

/**
 * ChainedSqlOperatorTable implements the {@link SqlOperatorTable} interface by
 * chaining together any number of underlying operator table instances.
 */
public class ChainedSqlOperatorTable implements SqlOperatorTable {
  //~ Instance fields --------------------------------------------------------

  protected final List<SqlOperatorTable> tableList;

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

  /**
   * Creates a table based on a given list.
   */
  public ChainedSqlOperatorTable(List<SqlOperatorTable> tableList) {
    this.tableList = tableList;
  }

  //~ Methods ----------------------------------------------------------------

  /**
   * Adds an underlying table. The order in which tables are added is
   * significant; tables added earlier have higher lookup precedence. A table
   * is not added if it is already on the list.
   *
   * @param table table to add
   */
  public void add(SqlOperatorTable table) {
    if (!tableList.contains(table)) {
      tableList.add(table);
    }
  }

  public void lookupOperatorOverloads(SqlIdentifier opName,
      SqlFunctionCategory category, SqlSyntax syntax,
      List<SqlOperator> operatorList) {
    for (SqlOperatorTable table : tableList) {
      table.lookupOperatorOverloads(opName, category, syntax, operatorList);
    }
  }

  // implement SqlOperatorTable
  public List<SqlOperator> getOperatorList() {
    List<SqlOperator> list = new ArrayList<SqlOperator>();
    for (SqlOperatorTable table : tableList) {
      list.addAll(table.getOperatorList());
    }
    return list;
  }
}

// End ChainedSqlOperatorTable.java


<|start_filename|>spark/src/main/java/net/hydromatic/optiq/impl/spark/JdbcToSparkConverterRule.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.impl.spark;

import net.hydromatic.optiq.impl.jdbc.JdbcConvention;

import org.eigenbase.rel.RelNode;
import org.eigenbase.rel.convert.ConverterRule;
import org.eigenbase.relopt.RelTraitSet;

/**
 * Rule to convert a relational expression from
 * {@link net.hydromatic.optiq.impl.jdbc.JdbcConvention} to
 * {@link net.hydromatic.optiq.impl.spark.SparkRel#CONVENTION Spark convention}.
 */
public class JdbcToSparkConverterRule extends ConverterRule {
  JdbcToSparkConverterRule(JdbcConvention out) {
    super(
        RelNode.class,
        out, SparkRel.CONVENTION,
        "JdbcToSparkConverterRule");
  }

  @Override
  public RelNode convert(RelNode rel) {
    RelTraitSet newTraitSet = rel.getTraitSet().replace(getOutTrait());
    return new JdbcToSparkConverter(rel.getCluster(), newTraitSet, rel);
  }
}

// End JdbcToSparkConverterRule.java


<|start_filename|>core/src/main/java/org/eigenbase/rel/rules/MergeCalcRule.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel.rules;

import org.eigenbase.rel.*;
import org.eigenbase.relopt.*;
import org.eigenbase.rex.*;

/**
 * Planner rule which merges a {@link CalcRel} onto a {@link CalcRel}. The
 * resulting {@link CalcRel} has the same project list as the upper {@link
 * CalcRel}, but expressed in terms of the lower {@link CalcRel}'s inputs.
 */
public class MergeCalcRule extends RelOptRule {
  //~ Static fields/initializers ---------------------------------------------

  public static final MergeCalcRule INSTANCE = new MergeCalcRule();

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

  private MergeCalcRule() {
    super(
        operand(
            CalcRelBase.class,
            operand(CalcRelBase.class, any())));
  }

  //~ Methods ----------------------------------------------------------------

  public void onMatch(RelOptRuleCall call) {
    final CalcRelBase topCalc = call.rel(0);
    final CalcRelBase bottomCalc = call.rel(1);

    // Don't merge a calc which contains windowed aggregates onto a
    // calc. That would effectively be pushing a windowed aggregate down
    // through a filter.
    RexProgram topProgram = topCalc.getProgram();
    if (RexOver.containsOver(topProgram)) {
      return;
    }

    // Merge the programs together.

    RexProgram mergedProgram =
        RexProgramBuilder.mergePrograms(
            topCalc.getProgram(),
            bottomCalc.getProgram(),
            topCalc.getCluster().getRexBuilder());
    assert mergedProgram.getOutputRowType()
        == topProgram.getOutputRowType();
    final CalcRelBase newCalc =
        topCalc.copy(
            topCalc.getTraitSet(),
            bottomCalc.getChild(),
            mergedProgram,
            topCalc.getCollationList());

    if (newCalc.getDigest().equals(bottomCalc.getDigest())) {
      // newCalc is equivalent to bottomCalc, which means that topCalc
      // must be trivial. Take it out of the game.
      call.getPlanner().setImportance(topCalc, 0.0);
    }

    call.transformTo(newCalc);
  }
}

// End MergeCalcRule.java


<|start_filename|>splunk/src/main/java/net/hydromatic/optiq/impl/splunk/SplunkQuery.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.impl.splunk;

import net.hydromatic.linq4j.*;

import net.hydromatic.optiq.impl.splunk.search.*;
import net.hydromatic.optiq.impl.splunk.util.StringUtils;

import java.util.*;

/**
 * Query against Splunk.
 *
 * @param <T> Element type
 */
public class SplunkQuery<T> extends AbstractEnumerable<T> {
  private final SplunkConnection splunkConnection;
  private final String search;
  private final String earliest;
  private final String latest;
  private final List<String> fieldList;

  /** Creates a SplunkQuery. */
  public SplunkQuery(
      SplunkConnection splunkConnection,
      String search,
      String earliest,
      String latest,
      List<String> fieldList) {
    this.splunkConnection = splunkConnection;
    this.search = search;
    this.earliest = earliest;
    this.latest = latest;
    this.fieldList = fieldList;
    assert splunkConnection != null;
    assert search != null;
  }

  public String toString() {
    return "SplunkQuery {" + search + "}";
  }

  public Iterator<T> iterator() {
    return Linq4j.enumeratorIterator(enumerator());
  }

  public Enumerator<T> enumerator() {
    //noinspection unchecked
    return (Enumerator<T>) splunkConnection.getSearchResultEnumerator(
        search, getArgs(), fieldList);
  }

  private Map<String, String> getArgs() {
    Map<String, String> args = new HashMap<String, String>();
    if (fieldList != null) {
      String fields =
          StringUtils.encodeList(fieldList, ',').toString();
      args.put("field_list", fields);
    }
    if (earliest != null) {
      args.put("earliest_time", earliest);
    }
    if (latest != null) {
      args.put("latest_time", latest);
    }
    return args;
  }
}

// End SplunkQuery.java


<|start_filename|>avatica/src/main/java/net/hydromatic/avatica/AvaticaParameter.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.avatica;

import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
import java.net.URL;
import java.sql.*;
import java.util.Calendar;

/**
 * Metadata for a parameter. Plus a slot to hold its value.
 */
public class AvaticaParameter {
  public final boolean signed;
  public final int precision;
  public final int scale;
  public final int parameterType;
  public final String typeName;
  public final String className;
  public final String name;

  Object value;

  /** Value that means the parameter has been set to null.
   * If {@link #value} is null, parameter has not been set. */
  public static final Object DUMMY_VALUE = new Object();

  public AvaticaParameter(
      boolean signed,
      int precision,
      int scale,
      int parameterType,
      String typeName,
      String className,
      String name) {
    this.signed = signed;
    this.precision = precision;
    this.scale = scale;
    this.parameterType = parameterType;
    this.typeName = typeName;
    this.className = className;
    this.name = name;
  }

  public void setByte(byte o) {
    this.value = o;
  }

  public void setValue(char o) {
    this.value = o;
  }

  public void setShort(short o) {
    this.value = o;
  }

  public void setInt(int o) {
    this.value = o;
  }

  public void setValue(long o) {
    this.value = o;
  }

  public void setValue(byte[] o) {
    this.value = o == null ? DUMMY_VALUE : new ByteString(o);
  }

  public void setBoolean(boolean o) {
    this.value = o;
  }

  public void setValue(Object o) {
    this.value = wrap(o);
  }

  private static Object wrap(Object o) {
    if (o == null) {
      return DUMMY_VALUE;
    }
    return o;
  }

  public boolean isSet() {
    return value != null;
  }

  public void setRowId(RowId x) {
    this.value = wrap(x);
  }

  public void setNString(String o) {
    this.value = wrap(o);
  }

  public void setNCharacterStream(Reader value, long length) {
  }

  public void setNClob(NClob value) {
    this.value = wrap(value);
  }

  public void setClob(Reader reader, long length) {
  }

  public void setBlob(InputStream inputStream, long length) {
  }

  public void setNClob(Reader reader, long length) {
  }

  public void setSQLXML(SQLXML xmlObject) {
    this.value = wrap(xmlObject);
  }

  public void setAsciiStream(InputStream x, long length) {
  }

  public void setBinaryStream(InputStream x, long length) {
  }

  public void setCharacterStream(Reader reader, long length) {
  }

  public void setAsciiStream(InputStream x) {
  }

  public void setBinaryStream(InputStream x) {
  }

  public void setCharacterStream(Reader reader) {
  }

  public void setNCharacterStream(Reader value) {
  }

  public void setClob(Reader reader) {
  }

  public void setBlob(InputStream inputStream) {
  }

  public void setNClob(Reader reader) {
  }

  public void setUnicodeStream(InputStream x, int length) {
  }

  public void setTimestamp(Timestamp x) {
    this.value = wrap(x);
  }

  public void setTime(Time x) {
    this.value = wrap(x);
  }

  public void setFloat(float x) {
    this.value = wrap(x);
  }

  public void setDouble(double x) {
    this.value = wrap(x);
  }

  public void setBigDecimal(BigDecimal x) {
    this.value = wrap(x);
  }

  public void setString(String x) {
    this.value = wrap(x);
  }

  public void setBytes(byte[] x) {
    this.value = x == null ? DUMMY_VALUE : wrap(x);
  }

  public void setDate(Date x, Calendar cal) {
  }

  public void setDate(Date x) {
    this.value = wrap(x);
  }

  public void setObject(Object x, int targetSqlType) {
  }

  public void setObject(Object x) {
    this.value = wrap(x);
  }

  public void setNull(int sqlType) {
    this.value = DUMMY_VALUE;
  }

  public void setTime(Time x, Calendar cal) {
  }

  public void setRef(Ref x) {
  }

  public void setBlob(Blob x) {
  }

  public void setClob(Clob x) {
  }

  public void setArray(Array x) {
  }

  public void setTimestamp(Timestamp x, Calendar cal) {
  }

  public void setNull(int sqlType, String typeName) {
  }

  public void setURL(URL x) {
  }

  public void setObject(Object x, int targetSqlType, int scaleOrLength) {
  }
}

// End AvaticaParameter.java


<|start_filename|>spark/src/main/java/net/hydromatic/optiq/impl/spark/SparkToEnumerableConverter.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.impl.spark;

import net.hydromatic.linq4j.expressions.BlockBuilder;
import net.hydromatic.linq4j.expressions.BlockStatement;
import net.hydromatic.linq4j.expressions.Expression;
import net.hydromatic.linq4j.expressions.Expressions;

import net.hydromatic.optiq.impl.java.JavaTypeFactory;
import net.hydromatic.optiq.rules.java.*;

import org.eigenbase.rel.RelNode;
import org.eigenbase.rel.convert.ConverterRelImpl;
import org.eigenbase.relopt.*;

import java.util.List;

/**
 * Relational expression that converts input of
 * {@link net.hydromatic.optiq.impl.spark.SparkRel#CONVENTION Spark convention}
 * into {@link net.hydromatic.optiq.rules.java.EnumerableConvention}.
 *
 * <p>Concretely, this means calling the
 * {@link org.apache.spark.api.java.JavaRDD#collect()} method of an RDD
 * and converting it to enumerable.</p>
 */
public class SparkToEnumerableConverter
    extends ConverterRelImpl
    implements EnumerableRel {
  protected SparkToEnumerableConverter(RelOptCluster cluster,
      RelTraitSet traits,
      RelNode input) {
    super(cluster, ConventionTraitDef.INSTANCE, traits, input);
  }

  @Override
  public RelNode copy(RelTraitSet traitSet, List<RelNode> inputs) {
    return new SparkToEnumerableConverter(
        getCluster(), traitSet, sole(inputs));
  }

  @Override
  public RelOptCost computeSelfCost(RelOptPlanner planner) {
    return super.computeSelfCost(planner).multiplyBy(.01);
  }

  public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
    // Generate:
    //   RDD rdd = ...;
    //   return SparkRuntime.asEnumerable(rdd);
    final BlockBuilder list = new BlockBuilder();
    final SparkRel child = (SparkRel) getChild();
    final PhysType physType =
        PhysTypeImpl.of(implementor.getTypeFactory(),
            getRowType(),
            JavaRowFormat.CUSTOM);
    SparkRel.Implementor sparkImplementor =
        new SparkImplementorImpl(implementor);
    final SparkRel.Result result = child.implementSpark(sparkImplementor);
    final Expression rdd = list.append("rdd", result.block);
    final Expression enumerable =
        list.append(
            "enumerable",
            Expressions.call(
                SparkMethod.AS_ENUMERABLE.method,
                rdd));
    list.add(
        Expressions.return_(null, enumerable));
    return implementor.result(physType, list.toBlock());
  }

  /** Implementation of
   * {@link net.hydromatic.optiq.impl.spark.SparkRel.Implementor}. */
  private static class SparkImplementorImpl extends SparkRel.Implementor {
    private final EnumerableRelImplementor implementor;

    public SparkImplementorImpl(EnumerableRelImplementor implementor) {
      super(implementor.getRexBuilder());
      this.implementor = implementor;
    }

    public SparkRel.Result result(PhysType physType,
        BlockStatement blockStatement) {
      return new SparkRel.Result(physType, blockStatement);
    }

    SparkRel.Result visitInput(SparkRel parent, int ordinal, SparkRel input) {
      if (parent != null) {
        assert input == parent.getInputs().get(ordinal);
      }
      createFrame(parent, ordinal, input);
      return input.implementSpark(this);
    }

    public JavaTypeFactory getTypeFactory() {
      return implementor.getTypeFactory();
    }
  }
}

// End SparkToEnumerableConverter.java


<|start_filename|>core/src/main/java/org/eigenbase/rel/metadata/RelMdRowCount.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel.metadata;

import java.util.*;

import org.eigenbase.rel.*;
import org.eigenbase.rel.rules.*;
import org.eigenbase.rex.*;
import org.eigenbase.util14.*;

import net.hydromatic.optiq.BuiltinMethod;

/**
 * RelMdRowCount supplies a default implementation of {@link
 * RelMetadataQuery#getRowCount} for the standard logical algebra.
 */
public class RelMdRowCount {
  public static final RelMetadataProvider SOURCE =
      ReflectiveRelMetadataProvider.reflectiveSource(
          BuiltinMethod.ROW_COUNT.method, new RelMdRowCount());

  //~ Methods ----------------------------------------------------------------

  public Double getRowCount(UnionRelBase rel) {
    double nRows = 0.0;

    for (RelNode input : rel.getInputs()) {
      Double partialRowCount = RelMetadataQuery.getRowCount(input);
      if (partialRowCount == null) {
        return null;
      }
      nRows += partialRowCount;
    }
    return nRows;
  }

  public Double getRowCount(FilterRelBase rel) {
    return NumberUtil.multiply(
        RelMetadataQuery.getSelectivity(
            rel.getChild(),
            rel.getCondition()),
        RelMetadataQuery.getRowCount(rel.getChild()));
  }

  public Double getRowCount(ProjectRelBase rel) {
    return RelMetadataQuery.getRowCount(rel.getChild());
  }

  public Double getRowCount(SortRel rel) {
    return RelMetadataQuery.getRowCount(rel.getChild());
  }

  public Double getRowCount(SemiJoinRel rel) {
    // create a RexNode representing the selectivity of the
    // semijoin filter and pass it to getSelectivity
    RexNode semiJoinSelectivity =
        RelMdUtil.makeSemiJoinSelectivityRexNode(rel);

    return NumberUtil.multiply(
        RelMetadataQuery.getSelectivity(
            rel.getLeft(),
            semiJoinSelectivity),
        RelMetadataQuery.getRowCount(rel.getLeft()));
  }

  public Double getRowCount(AggregateRelBase rel) {
    BitSet groupKey = new BitSet();
    for (int i = 0; i < rel.getGroupCount(); i++) {
      groupKey.set(i);
    }

    // rowcount is the cardinality of the group by columns
    Double distinctRowCount =
        RelMetadataQuery.getDistinctRowCount(
            rel.getChild(),
            groupKey,
            null);
    if (distinctRowCount == null) {
      return RelMetadataQuery.getRowCount(rel.getChild()) / 10;
    } else {
      return distinctRowCount;
    }
  }

  // Catch-all rule when none of the others apply.
  public Double getRowCount(RelNode rel) {
    return rel.getRows();
  }
}

// End RelMdRowCount.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/fun/SqlArrayValueConstructor.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql.fun;

import org.eigenbase.reltype.RelDataType;
import org.eigenbase.sql.SqlKind;
import org.eigenbase.sql.SqlOperatorBinding;
import org.eigenbase.sql.type.SqlTypeUtil;

/**
 * Definition of the SQL:2003 standard ARRAY constructor, <code>MULTISET
 * [&lt;expr&gt;, ...]</code>.
 */
public class SqlArrayValueConstructor extends SqlMultisetValueConstructor {
  public SqlArrayValueConstructor() {
    super("ARRAY", SqlKind.ARRAY_VALUE_CONSTRUCTOR);
  }

  @Override
  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
    RelDataType type =
        getComponentType(
            opBinding.getTypeFactory(),
            opBinding.collectOperandTypes());
    if (null == type) {
      return null;
    }
    return SqlTypeUtil.createArrayType(
        opBinding.getTypeFactory(), type, false);
  }
}

// End SqlArrayValueConstructor.java


<|start_filename|>core/src/main/java/net/hydromatic/optiq/impl/StarTable.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.impl;

import net.hydromatic.optiq.Table;

import org.eigenbase.relopt.RelOptUtil;
import org.eigenbase.reltype.RelDataType;
import org.eigenbase.reltype.RelDataTypeFactory;
import org.eigenbase.sql.validate.SqlValidatorUtil;
import org.eigenbase.util.ImmutableIntList;
import org.eigenbase.util.Pair;

import com.google.common.collect.ImmutableList;

import java.util.ArrayList;
import java.util.List;

/**
 * Virtual table that is composed of two or more tables joined together.
 *
 * <p>Star tables do not occur in end-user queries. They are introduced by the
 * optimizer to help matching queries to materializations, and used only
 * during the planning process.</p>
 *
 * <p>When a materialization is defined, if it involves a join, it is converted
 * to a query on top of a star table. Queries that are candidates to map onto
 * the materialization are mapped onto the same star table.</p>
 */
public class StarTable extends AbstractTable {
  // TODO: we'll also need a list of join conditions between tables. For now
  //  we assume that join conditions match
  public final ImmutableList<Table> tables;

  /** Number of fields in each table's row type. */
  public ImmutableIntList fieldCounts;

  /** Creates a StarTable. */
  public StarTable(List<Table> tables) {
    super();
    this.tables = ImmutableList.copyOf(tables);
  }

  /** Creates a StarTable and registers it in a schema. */
  public static StarTable of(List<Table> tables) {
    return new StarTable(tables);
  }

  public RelDataType getRowType(RelDataTypeFactory typeFactory) {
    final List<RelDataType> typeList = new ArrayList<RelDataType>();
    final List<String> nameList = new ArrayList<String>();
    final List<Integer> fieldCounts = new ArrayList<Integer>();
    for (Table table : tables) {
      final RelDataType rowType = table.getRowType(typeFactory);
      typeList.addAll(RelOptUtil.getFieldTypeList(rowType));
      nameList.addAll(rowType.getFieldNames());
      fieldCounts.add(rowType.getFieldCount());
    }
    // Compute fieldCounts the first time this method is called. Safe to assume
    // that the field counts will be the same whichever type factory is used.
    if (this.fieldCounts == null) {
      this.fieldCounts = ImmutableIntList.copyOf(fieldCounts);
    }
    return typeFactory.createStructType(typeList,
        SqlValidatorUtil.uniquify(nameList));
  }

  public StarTable add(Table table) {
    final List<Table> tables1 = new ArrayList<Table>(tables);
    tables1.add(table);
    return of(tables1);
  }

  /** Returns the column offset of the first column of {@code table} in this
   * star table's output row type.
   *
   * @param table Table
   * @return Column offset
   * @throws IllegalArgumentException if table is not in this star
   */
  public int columnOffset(Table table) {
    int n = 0;
    for (Pair<Table, Integer> pair : Pair.zip(tables, fieldCounts)) {
      if (pair.left == table) {
        return n;
      }
      n += pair.right;
    }
    throw new IllegalArgumentException("star table " + this
        + " does not contain table " + table);
  }
}

// End StarTable.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/SqlExplainLevel.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql;

import org.eigenbase.sql.parser.SqlParserPos;

/**
 * SqlExplainLevel defines detail levels for EXPLAIN PLAN.
 */
public enum SqlExplainLevel implements SqlLiteral.SqlSymbol {
  /**
   * Suppress all attributes.
   */
  NO_ATTRIBUTES,

  /**
   * Display only attributes which contribute to the plan output.
   */
  EXPPLAN_ATTRIBUTES,

  /**
   * Display only attributes which contribute to an expression's digest.
   */
  DIGEST_ATTRIBUTES,

  /**
   * Display all attributes, including cost.
   */
  ALL_ATTRIBUTES;

  /**
   * Creates a parse-tree node representing an occurrence of this symbol at
   * a particular position in the parsed text.
   */
  public SqlLiteral symbol(SqlParserPos pos) {
    return SqlLiteral.createSymbol(this, pos);
  }
}

// End SqlExplainLevel.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/type/ExplicitOperandTypeInference.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql.type;

import org.eigenbase.reltype.*;
import org.eigenbase.sql.*;

import com.google.common.collect.ImmutableList;

/**
 * ExplicitOperandTypeInferences implements {@link SqlOperandTypeInference} by
 * explicity supplying a type for each parameter.
 */
public class ExplicitOperandTypeInference implements SqlOperandTypeInference {
  //~ Instance fields --------------------------------------------------------

  private final ImmutableList<RelDataType> paramTypes;

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

  /** Use {@link org.eigenbase.sql.type.InferTypes#explicit(List)}. */
  ExplicitOperandTypeInference(ImmutableList<RelDataType> paramTypes) {
    this.paramTypes = paramTypes;
  }

  //~ Methods ----------------------------------------------------------------

  public void inferOperandTypes(
      SqlCallBinding callBinding,
      RelDataType returnType,
      RelDataType[] operandTypes) {
    assert operandTypes.length == paramTypes.size();
    paramTypes.toArray(operandTypes);
  }
}

// End ExplicitOperandTypeInference.java


<|start_filename|>core/src/test/java/org/eigenbase/test/MockRelOptPlanner.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.test;

import java.util.*;

import org.eigenbase.rel.*;
import org.eigenbase.relopt.*;
import org.eigenbase.rex.RexExecutorImpl;
import org.eigenbase.util.Pair;

import net.hydromatic.optiq.Schemas;

/**
 * MockRelOptPlanner is a mock implementation of the {@link RelOptPlanner}
 * interface.
 */
public class MockRelOptPlanner extends AbstractRelOptPlanner {
  //~ Instance fields --------------------------------------------------------

  private RelNode root;

  private RelOptRule rule;

  private RelNode transformationResult;

  private long metadataTimestamp = 0L;

  //~ Methods ----------------------------------------------------------------

  /** Creates MockRelOptPlanner. */
  public MockRelOptPlanner() {
    super(RelOptCostImpl.FACTORY);
    setExecutor(new RexExecutorImpl(Schemas.createDataContext(null)));
  }

  // implement RelOptPlanner
  public void setRoot(RelNode rel) {
    this.root = rel;
  }

  // implement RelOptPlanner
  public RelNode getRoot() {
    return root;
  }

  public void addMaterialization(RelOptMaterialization materialization) {
    // ignore - this planner does not support materializations
  }

  @Override public void clear() {
    super.clear();
    this.rule = null;
  }

  public boolean addRule(RelOptRule rule) {
    assert this.rule == null
        : "MockRelOptPlanner only supports a single rule";
    this.rule = rule;

    return false;
  }

  public boolean removeRule(RelOptRule rule) {
    return false;
  }

  // implement RelOptPlanner
  public RelNode changeTraits(RelNode rel, RelTraitSet toTraits) {
    return rel;
  }

  // implement RelOptPlanner
  public RelNode findBestExp() {
    if (rule != null) {
      matchRecursive(root, null, -1);
    }
    return root;
  }

  /**
   * Recursively matches a rule.
   *
   * @param rel             Relational expression
   * @param parent          Parent relational expression
   * @param ordinalInParent Ordinal of relational expression among its
   *                        siblings
   * @return whether match occurred
   */
  private boolean matchRecursive(
      RelNode rel,
      RelNode parent,
      int ordinalInParent) {
    List<RelNode> bindings = new ArrayList<RelNode>();
    if (match(
        rule.getOperand(),
        rel,
        bindings)) {
      MockRuleCall call =
          new MockRuleCall(
              this,
              rule.getOperand(),
              bindings.toArray(new RelNode[bindings.size()]));
      if (rule.matches(call)) {
        rule.onMatch(call);
      }
    }

    if (transformationResult != null) {
      if (parent == null) {
        root = transformationResult;
      } else {
        parent.replaceInput(ordinalInParent, transformationResult);
      }
      return true;
    }

    List<? extends RelNode> children = rel.getInputs();
    for (int i = 0; i < children.size(); ++i) {
      if (matchRecursive(children.get(i), rel, i)) {
        return true;
      }
    }
    return false;
  }

  /**
   * Matches a relational expression to a rule.
   *
   * @param operand  Root operand of rule
   * @param rel      Relational expression
   * @param bindings Bindings, populated on successful match
   * @return whether relational expression matched rule
   */
  private boolean match(
      RelOptRuleOperand operand,
      RelNode rel,
      List<RelNode> bindings) {
    if (!operand.matches(rel)) {
      return false;
    }
    bindings.add(rel);
    switch (operand.childPolicy) {
    case ANY:
      return true;
    }
    List<RelOptRuleOperand> childOperands = operand.getChildOperands();
    List<? extends RelNode> childRels = rel.getInputs();
    if (childOperands.size() != childRels.size()) {
      return false;
    }
    for (Pair<RelOptRuleOperand, ? extends RelNode> pair
        : Pair.zip(childOperands, childRels)) {
      if (!match(pair.left, pair.right, bindings)) {
        return false;
      }
    }
    return true;
  }

  // implement RelOptPlanner
  public RelNode register(
      RelNode rel,
      RelNode equivRel) {
    return rel;
  }

  // implement RelOptPlanner
  public RelNode ensureRegistered(RelNode rel, RelNode equivRel) {
    return rel;
  }

  // implement RelOptPlanner
  public boolean isRegistered(RelNode rel) {
    return true;
  }

  @Override
  public long getRelMetadataTimestamp(RelNode rel) {
    return metadataTimestamp;
  }

  /** Allow tests to tweak the timestamp. */
  public void setRelMetadataTimestamp(long metadataTimestamp) {
    this.metadataTimestamp = metadataTimestamp;
  }

  //~ Inner Classes ----------------------------------------------------------

  private class MockRuleCall extends RelOptRuleCall {
    /**
     * Creates a MockRuleCall.
     *
     * @param planner Planner
     * @param operand Operand
     * @param rels    List of matched relational expressions
     */
    MockRuleCall(
        RelOptPlanner planner,
        RelOptRuleOperand operand,
        RelNode[] rels) {
      super(
          planner,
          operand,
          rels,
          Collections.<RelNode, List<RelNode>>emptyMap());
    }

    // implement RelOptRuleCall
    public void transformTo(RelNode rel, Map<RelNode, RelNode> equiv) {
      transformationResult = rel;
    }
  }
}

// End MockRelOptPlanner.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/advise/package-info.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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.
*/

/**
 * Provides hints and corrections for editing SQL statements.
 *
 * <p>The SQL statement might be partially-formed SQL statement or
 * invalid. It is edited in a SQL editor user-interface.</p>
 *
 * <p>The advisor uses the validation and parser framework set up in
 * <code>org.eigenbase.sql.validate</code> package.
*/
package org.eigenbase.sql.advise;

// End package-info.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/SqlDialect.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql;

import java.sql.*;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.*;

/**
 * <code>SqlDialect</code> encapsulates the differences between dialects of SQL.
 *
 * <p>It is used by classes such as {@link SqlWriter} and
 * {@link org.eigenbase.sql.util.SqlBuilder}.
 */
public class SqlDialect {
  //~ Static fields/initializers ---------------------------------------------

  /**
   * A dialect useful for generating generic SQL. If you need to do something
   * database-specific like quoting identifiers, don't rely on this dialect to
   * do what you want.
   */
  public static final SqlDialect DUMMY =
      DatabaseProduct.UNKNOWN.getDialect();

  /**
   * A dialect useful for generating SQL which can be parsed by the
   * Eigenbase parser, in particular quoting literals and identifiers. If you
   * want a dialect that knows the full capabilities of the database, create
   * one from a connection.
   */
  public static final SqlDialect EIGENBASE =
      DatabaseProduct.LUCIDDB.getDialect();

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

  private final String identifierQuoteString;
  private final String identifierEndQuoteString;
  private final String identifierEscapedQuote;
  private final DatabaseProduct databaseProduct;

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

  /**
   * Creates a <code>SqlDialect</code> from a DatabaseMetaData.
   *
   * <p>Does not maintain a reference to the DatabaseMetaData -- or, more
   * importantly, to its {@link java.sql.Connection} -- after this call has
   * returned.
   *
   * @param databaseMetaData used to determine which dialect of SQL to
   *                         generate
   */
  public static SqlDialect create(DatabaseMetaData databaseMetaData) {
    String identifierQuoteString;
    try {
      identifierQuoteString = databaseMetaData.getIdentifierQuoteString();
    } catch (SQLException e) {
      throw FakeUtil.newInternal(e, "while quoting identifier");
    }
    String databaseProductName;
    try {
      databaseProductName = databaseMetaData.getDatabaseProductName();
    } catch (SQLException e) {
      throw FakeUtil.newInternal(e, "while detecting database product");
    }
    final DatabaseProduct databaseProduct =
        getProduct(databaseProductName, null);
    return new SqlDialect(
        databaseProduct, databaseProductName, identifierQuoteString);
  }

  /**
   * Creates a SqlDialect.
   *
   * @param databaseProduct       Database product; may be UNKNOWN, never null
   * @param databaseProductName   Database product name from JDBC driver
   * @param identifierQuoteString String to quote identifiers. Null if quoting
   *                              is not supported. If "[", close quote is
   *                              deemed to be "]".
   */
  public SqlDialect(
      DatabaseProduct databaseProduct,
      String databaseProductName,
      String identifierQuoteString) {
    assert databaseProduct != null;
    assert databaseProductName != null;
    this.databaseProduct = databaseProduct;
    if (identifierQuoteString != null) {
      identifierQuoteString = identifierQuoteString.trim();
      if (identifierQuoteString.equals("")) {
        identifierQuoteString = null;
      }
    }
    this.identifierQuoteString = identifierQuoteString;
    this.identifierEndQuoteString =
        identifierQuoteString == null
            ? null
            : identifierQuoteString.equals("[")
                ? "]"
                : identifierQuoteString;
    this.identifierEscapedQuote =
        identifierQuoteString == null
            ? null
            : this.identifierEndQuoteString + this.identifierEndQuoteString;
  }

  //~ Methods ----------------------------------------------------------------

  /**
   * Converts a product name and version (per the JDBC driver) into a product
   * enumeration.
   *
   * @param productName    Product name
   * @param productVersion Product version
   * @return database product
   */
  public static DatabaseProduct getProduct(
      String productName,
      String productVersion) {
    final String upperProductName = productName.toUpperCase();
    if (productName.equals("ACCESS")) {
      return DatabaseProduct.ACCESS;
    } else if (upperProductName.trim().equals("APACHE DERBY")) {
      return DatabaseProduct.DERBY;
    } else if (upperProductName.trim().equals("DBMS:CLOUDSCAPE")) {
      return DatabaseProduct.DERBY;
    } else if (productName.startsWith("DB2")) {
      return DatabaseProduct.DB2;
    } else if (upperProductName.contains("FIREBIRD")) {
      return DatabaseProduct.FIREBIRD;
    } else if (productName.equals("Hive")) {
      return DatabaseProduct.HIVE;
    } else if (productName.startsWith("Informix")) {
      return DatabaseProduct.INFORMIX;
    } else if (upperProductName.equals("INGRES")) {
      return DatabaseProduct.INGRES;
    } else if (productName.equals("Interbase")) {
      return DatabaseProduct.INTERBASE;
    } else if (upperProductName.equals("LUCIDDB")) {
      return DatabaseProduct.LUCIDDB;
    } else if (upperProductName.contains("SQL SERVER")) {
      return DatabaseProduct.MSSQL;
    } else if (upperProductName.contains("PARACCEL")) {
      return DatabaseProduct.PARACCEL;
    } else if (productName.equals("Oracle")) {
      return DatabaseProduct.ORACLE;
    } else if (productName.equals("Phoenix")) {
      return DatabaseProduct.PHOENIX;
    } else if (upperProductName.contains("POSTGRE")) {
      return DatabaseProduct.POSTGRESQL;
    } else if (upperProductName.contains("NETEZZA")) {
      return DatabaseProduct.NETEZZA;
    } else if (upperProductName.equals("MYSQL (INFOBRIGHT)")) {
      return DatabaseProduct.INFOBRIGHT;
    } else if (upperProductName.equals("MYSQL")) {
      return DatabaseProduct.MYSQL;
    } else if (productName.startsWith("HP Neoview")) {
      return DatabaseProduct.NEOVIEW;
    } else if (upperProductName.contains("SYBASE")) {
      return DatabaseProduct.SYBASE;
    } else if (upperProductName.contains("TERADATA")) {
      return DatabaseProduct.TERADATA;
    } else if (upperProductName.contains("HSQL")) {
      return DatabaseProduct.HSQLDB;
    } else if (upperProductName.contains("VERTICA")) {
      return DatabaseProduct.VERTICA;
    } else {
      return DatabaseProduct.UNKNOWN;
    }
  }

  // -- detect various databases --

  /**
   * Encloses an identifier in quotation marks appropriate for the current SQL
   * dialect.
   *
   * <p>For example, <code>quoteIdentifier("emp")</code> yields a string
   * containing <code>"emp"</code> in Oracle, and a string containing <code>
   * [emp]</code> in Access.
   *
   * @param val Identifier to quote
   * @return Quoted identifier
   */
  public String quoteIdentifier(String val) {
    if (identifierQuoteString == null) {
      return val; // quoting is not supported
    }
    String val2 =
        val.replaceAll(
            identifierEndQuoteString,
            identifierEscapedQuote);
    return identifierQuoteString + val2 + identifierEndQuoteString;
  }

  /**
   * Encloses an identifier in quotation marks appropriate for the current SQL
   * dialect, writing the result to a {@link StringBuilder}.
   *
   * <p>For example, <code>quoteIdentifier("emp")</code> yields a string
   * containing <code>"emp"</code> in Oracle, and a string containing <code>
   * [emp]</code> in Access.
   *
   * @param buf Buffer
   * @param val Identifier to quote
   * @return The buffer
   */
  public StringBuilder quoteIdentifier(
      StringBuilder buf,
      String val) {
    if (identifierQuoteString == null) {
      buf.append(val); // quoting is not supported
      return buf;
    }
    String val2 =
        val.replaceAll(
            identifierEndQuoteString,
            identifierEscapedQuote);
    buf.append(identifierQuoteString);
    buf.append(val2);
    buf.append(identifierEndQuoteString);
    return buf;
  }

  /**
   * Quotes a multi-part identifier.
   *
   * @param buf         Buffer
   * @param identifiers List of parts of the identifier to quote
   * @return The buffer
   */
  public StringBuilder quoteIdentifier(
      StringBuilder buf,
      List<String> identifiers) {
    int i = 0;
    for (String identifier : identifiers) {
      if (i++ > 0) {
        buf.append('.');
      }
      quoteIdentifier(buf, identifier);
    }
    return buf;
  }

  /**
   * Returns whether a given identifier needs to be quoted.
   */
  public boolean identifierNeedsToBeQuoted(String val) {
    return !Pattern.compile("^[A-Z_$0-9]+").matcher(val).matches();
  }

  /**
   * Converts a string into a string literal. For example, <code>can't
   * run</code> becomes <code>'can''t run'</code>.
   */
  public String quoteStringLiteral(String val) {
    if (containsNonAscii(val)) {
      final StringBuilder buf = new StringBuilder();
      quoteStringLiteralUnicode(buf, val);
      return buf.toString();
    } else {
      val = FakeUtil.replace(val, "'", "''");
      return "'" + val + "'";
    }
  }

  /**
   * Returns whether the string contains any characters outside the
   * comfortable 7-bit ASCII range (32 through 127).
   *
   * @param s String
   * @return Whether string contains any non-7-bit-ASCII characters
   */
  private static boolean containsNonAscii(String s) {
    for (int i = 0; i < s.length(); i++) {
      char c = s.charAt(i);
      if (c < 32 || c >= 128) {
        return true;
      }
    }
    return false;
  }

  /**
   * Converts a string into a unicode string literal. For example,
   * <code>can't{tab}run\</code> becomes <code>u'can''t\0009run\\'</code>.
   */
  public void quoteStringLiteralUnicode(StringBuilder buf, String val) {
    buf.append("u&'");
    for (int i = 0; i < val.length(); i++) {
      char c = val.charAt(i);
      if (c < 32 || c >= 128) {
        buf.append('\\');
        buf.append(HEXITS[(c >> 12) & 0xf]);
        buf.append(HEXITS[(c >> 8) & 0xf]);
        buf.append(HEXITS[(c >> 4) & 0xf]);
        buf.append(HEXITS[c & 0xf]);
      } else if (c == '\'' || c == '\\') {
        buf.append(c);
        buf.append(c);
      } else {
        buf.append(c);
      }
    }
    buf.append("'");
  }

  private static final char[] HEXITS = {
    '0', '1', '2', '3', '4', '5', '6', '7',
    '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
  };

  /**
   * Converts a string literal back into a string. For example, <code>'can''t
   * run'</code> becomes <code>can't run</code>.
   */
  public String unquoteStringLiteral(String val) {
    if ((val != null)
        && (val.charAt(0) == '\'')
        && (val.charAt(val.length() - 1) == '\'')) {
      if (val.length() > 2) {
        val = FakeUtil.replace(val, "''", "'");
        return val.substring(1, val.length() - 1);
      } else {
        // zero length string
        return "";
      }
    }
    return val;
  }

  protected boolean allowsAs() {
    switch (databaseProduct) {
    case ORACLE:
    case HIVE:
      return false;
    default:
      return true;
    }
  }

  // -- behaviors --
  protected boolean requiresAliasForFromItems() {
    return getDatabaseProduct() == DatabaseProduct.POSTGRESQL;
  }

  /**
   * Converts a timestamp to a SQL timestamp literal, e.g.
   * {@code TIMESTAMP '2009-12-17 12:34:56'}.
   *
   * <p>Timestamp values do not have a time zone. We therefore interpret them
   * as the number of milliseconds after the UTC epoch, and the formatted
   * value is that time in UTC.
   *
   * <p>In particular,
   *
   * <blockquote><code>quoteTimestampLiteral(new Timestamp(0));</code>
   * </blockquote>
   *
   * returns {@code TIMESTAMP '1970-01-01 00:00:00'}, regardless of the JVM's
   * timezone.
   *
   * @param timestamp Timestamp
   * @return SQL timestamp literal
   */
  public String quoteTimestampLiteral(Timestamp timestamp) {
    final SimpleDateFormat format =
        new SimpleDateFormat(
            "'TIMESTAMP' ''yyyy-MM-DD HH:mm:SS''");
    format.setTimeZone(TimeZone.getTimeZone("GMT"));
    return format.format(timestamp);
  }

  /**
   * Returns the database this dialect belongs to,
   * {@link SqlDialect.DatabaseProduct#UNKNOWN} if not known, never null.
   *
   * @return Database product
   */
  public DatabaseProduct getDatabaseProduct() {
    return databaseProduct;
  }

  /**
   * Returns whether the dialect supports character set names as part of a
   * data type, for instance {@code VARCHAR(30) CHARACTER SET `ISO-8859-1`}.
   */
  public boolean supportsCharSet() {
    switch (databaseProduct) {
    case MYSQL:
    case HSQLDB:
    case PHOENIX:
      return false;
    default:
      return true;
    }
  }

  /**
   * A few utility functions copied from org.eigenbase.util.Util. We have
   * copied them because we wish to keep SqlDialect's dependencies to a
   * minimum.
   */
  public static class FakeUtil {
    public static Error newInternal(Throwable e, String s) {
      String message = "Internal error: \u0000" + s;
      AssertionError ae = new AssertionError(message);
      ae.initCause(e);
      return ae;
    }

    /**
     * Replaces every occurrence of <code>find</code> in <code>s</code> with
     * <code>replace</code>.
     */
    public static String replace(
        String s,
        String find,
        String replace) {
      // let's be optimistic
      int found = s.indexOf(find);
      if (found == -1) {
        return s;
      }
      StringBuilder sb = new StringBuilder(s.length());
      int start = 0;
      for (;;) {
        for (; start < found; start++) {
          sb.append(s.charAt(start));
        }
        if (found == s.length()) {
          break;
        }
        sb.append(replace);
        start += find.length();
        found = s.indexOf(find, start);
        if (found == -1) {
          found = s.length();
        }
      }
      return sb.toString();
    }
  }

  /**
   * Rough list of flavors of database.
   *
   * <p>These values cannot help you distinguish between features that exist
   * in different versions or ports of a database, but they are sufficient
   * to drive a {@code switch} statement if behavior is broadly different
   * between say, MySQL and Oracle.
   *
   * <p>If possible, you should not refer to particular database at all; write
   * extend the dialect to describe the particular capability, for example,
   * whether the database allows expressions to appear in the GROUP BY clause.
   */
  public enum DatabaseProduct {
    ACCESS("Access", "\""),
    MSSQL("Microsoft SQL Server", "["),
    MYSQL("MySQL", "`"),
    ORACLE("Oracle", "\""),
    DERBY("Apache Derby", null),
    DB2("IBM DB2", null),
    FIREBIRD("Firebird", null),
    HIVE("Apache Hive", null),
    INFORMIX("Informix", null),
    INGRES("Ingres", null),
    LUCIDDB("LucidDB", "\""),
    INTERBASE("Interbase", null),
    PHOENIX("Phoenix", "\""),
    POSTGRESQL("PostgreSQL", "\""),
    NETEZZA("Netezza", "\""),
    INFOBRIGHT("Infobright", "`"),
    NEOVIEW("Neoview", null),
    SYBASE("Sybase", null),
    TERADATA("Teradata", "\""),
    HSQLDB("Hsqldb", null),
    VERTICA("Vertica", "\""),
    SQLSTREAM("SQLstream", "\""),
    PARACCEL("Paraccel", "\""),
    /**
     * Placeholder for the unknown database.
     *
     * <p>Its dialect is useful for generating generic SQL. If you need to
     * do something database-specific like quoting identifiers, don't rely
     * on this dialect to do what you want.
     */
    UNKNOWN("Unknown", "`");

    private SqlDialect dialect = null;
    private String databaseProductName;
    private String quoteString;

    DatabaseProduct(String databaseProductName, String quoteString) {
      this.databaseProductName = databaseProductName;
      this.quoteString = quoteString;
    }

    /**
     * Returns a dummy dialect for this database.
     *
     * <p>Since databases have many versions and flavors, this dummy dialect
     * is at best an approximation. If you want exact information, better to
     * use a dialect created from an actual connection's metadata
     * (see {@link SqlDialect#create(java.sql.DatabaseMetaData)}).
     *
     * @return Dialect representing lowest-common-demoninator behavior for
     * all versions of this database
     */
    public SqlDialect getDialect() {
      if (dialect == null) {
        dialect =
            new SqlDialect(this, databaseProductName, quoteString);
      }
      return dialect;
    }
  }
}

// End SqlDialect.java


<|start_filename|>core/src/main/java/net/hydromatic/optiq/model/package-info.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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.
*/

/**
 * Provides model files, in JSON format, defining schemas and other metadata.
 *
 * <p>Models are specified using a <code>model=&lt;uri&gt;</code> parameter on
 * the JDBC connect string. Optiq loads the model while initializing the
 * connection. It first parses the JSON, then uses a
 * {@link net.hydromatic.optiq.model.ModelHandler} as visitor over the parse
 * tree.</p>
 *
 * <p>There are standard implementations of schema and table, but the user can
 * provide their own by implementing the
 * {@link net.hydromatic.optiq.SchemaFactory}
 * or {@link net.hydromatic.optiq.TableFactory}
 * interfaces and including a custom schema in the model.</p>
 *
 * <p>There are several examples of schemas in the
 * <a href="https://github.com/julianhyde/blog/master/optiq-csv/TUTORIAL.md">optiq-csv
 * tutorial</a>.
 */
package net.hydromatic.optiq.model;

// End package-info.java


<|start_filename|>mongodb/src/main/java/net/hydromatic/optiq/impl/mongodb/MongoAggregateRel.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.impl.mongodb;

import net.hydromatic.optiq.util.BitSets;

import org.eigenbase.rel.*;
import org.eigenbase.relopt.RelOptCluster;
import org.eigenbase.relopt.RelTraitSet;
import org.eigenbase.sql.fun.SqlStdOperatorTable;
import org.eigenbase.sql.fun.SqlSumAggFunction;
import org.eigenbase.sql.fun.SqlSumEmptyIsZeroAggFunction;
import org.eigenbase.util.Util;

import java.util.*;

/**
 * Implementation of {@link AggregateRelBase} relational expression in MongoDB.
 */
public class MongoAggregateRel
    extends AggregateRelBase
    implements MongoRel {
  public MongoAggregateRel(
      RelOptCluster cluster,
      RelTraitSet traitSet,
      RelNode child,
      BitSet groupSet,
      List<AggregateCall> aggCalls)
    throws InvalidRelException {
    super(cluster, traitSet, child, groupSet, aggCalls);
    assert getConvention() == MongoRel.CONVENTION;
    assert getConvention() == child.getConvention();

    for (AggregateCall aggCall : aggCalls) {
      if (aggCall.isDistinct()) {
        throw new InvalidRelException(
            "distinct aggregation not supported");
      }
    }
  }

  @Override public AggregateRelBase copy(RelTraitSet traitSet, RelNode input,
      BitSet groupSet, List<AggregateCall> aggCalls) {
    try {
      return new MongoAggregateRel(getCluster(), traitSet, input, groupSet,
          aggCalls);
    } catch (InvalidRelException e) {
      // Semantic error not possible. Must be a bug. Convert to
      // internal error.
      throw new AssertionError(e);
    }
  }

  public void implement(Implementor implementor) {
    implementor.visitChild(0, getChild());
    List<String> list = new ArrayList<String>();
    final List<String> inNames =
        MongoRules.mongoFieldNames(getChild().getRowType());
    final List<String> outNames = MongoRules.mongoFieldNames(getRowType());
    int i = 0;
    if (groupSet.cardinality() == 1) {
      final String inName = inNames.get(BitSets.toList(groupSet).get(0));
      list.add("_id: " + MongoRules.maybeQuote("$" + inName));
      ++i;
    } else {
      List<String> keys = new ArrayList<String>();
      for (int group : BitSets.toIter(groupSet)) {
        final String inName = inNames.get(group);
        keys.add(inName + ": " + MongoRules.quote("$" + inName));
        ++i;
      }
      list.add("_id: " + Util.toString(keys, "{", ", ", "}"));
    }
    for (AggregateCall aggCall : aggCalls) {
      list.add(
          MongoRules.maybeQuote(outNames.get(i++)) + ": "
          + toMongo(aggCall.getAggregation(), inNames, aggCall.getArgList()));
    }
    implementor.add(null,
        "{$group: " + Util.toString(list, "{", ", ", "}") + "}");
    final List<String> fixups;
    if (groupSet.cardinality() == 1) {
      fixups = new AbstractList<String>() {
        @Override public String get(int index) {
          final String outName = outNames.get(index);
          return MongoRules.maybeQuote(outName)
              + ": "
              + MongoRules.maybeQuote("$" + (index == 0 ? "_id" : outName));
        }

        @Override public int size() {
          return outNames.size();
        }
      };
    } else {
      fixups = new ArrayList<String>();
      fixups.add("_id: 0");
      i = 0;
      for (int group : BitSets.toIter(groupSet)) {
        fixups.add(
            MongoRules.maybeQuote(outNames.get(group))
            + ": "
            + MongoRules.maybeQuote("$_id." + outNames.get(group)));
        ++i;
      }
      for (AggregateCall ignored : aggCalls) {
        final String outName = outNames.get(i++);
        fixups.add(
            MongoRules.maybeQuote(outName) + ": " + MongoRules.maybeQuote(
                "$" + outName));
      }
    }
    if (!groupSet.isEmpty()) {
      implementor.add(null,
          "{$project: " + Util.toString(fixups, "{", ", ", "}") + "}");
    }
  }

  private String toMongo(Aggregation aggregation, List<String> inNames,
      List<Integer> args) {
    if (aggregation == SqlStdOperatorTable.COUNT) {
      if (args.size() == 0) {
        return "{$sum: 1}";
      } else {
        assert args.size() == 1;
        final String inName = inNames.get(args.get(0));
        return "{$sum: {$cond: [ {$eq: ["
            + MongoRules.quote(inName)
            + ", null]}, 0, 1]}}";
      }
    } else if (aggregation instanceof SqlSumAggFunction
        || aggregation instanceof SqlSumEmptyIsZeroAggFunction) {
      assert args.size() == 1;
      final String inName = inNames.get(args.get(0));
      return "{$sum: " + MongoRules.maybeQuote("$" + inName) + "}";
    } else if (aggregation == SqlStdOperatorTable.MIN) {
      assert args.size() == 1;
      final String inName = inNames.get(args.get(0));
      return "{$min: " + MongoRules.maybeQuote("$" + inName) + "}";
    } else if (aggregation == SqlStdOperatorTable.MAX) {
      assert args.size() == 1;
      final String inName = inNames.get(args.get(0));
      return "{$max: " + MongoRules.maybeQuote("$" + inName) + "}";
    } else {
      throw new AssertionError("unknown aggregate " + aggregation);
    }
  }
}

// End MongoAggregateRel.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/validate/AbstractNamespace.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql.validate;

import java.util.*;

import org.eigenbase.reltype.*;
import org.eigenbase.sql.*;
import org.eigenbase.util.*;

import com.google.common.collect.ImmutableList;

/**
 * Abstract implementation of {@link SqlValidatorNamespace}.
 */
abstract class AbstractNamespace implements SqlValidatorNamespace {
  //~ Instance fields --------------------------------------------------------

  protected final SqlValidatorImpl validator;

  /**
   * Whether this scope is currently being validated. Used to check for
   * cycles.
   */
  private SqlValidatorImpl.Status status =
      SqlValidatorImpl.Status.UNVALIDATED;

  /**
   * Type of the output row, which comprises the name and type of each output
   * column. Set on validate.
   */
  protected RelDataType rowType;

  /** As {@link #rowType}, but not necessarily a struct. */
  protected RelDataType type;

  private boolean forceNullable;

  protected final SqlNode enclosingNode;

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

  /**
   * Creates an AbstractNamespace.
   *
   * @param validator     Validator
   * @param enclosingNode Enclosing node
   */
  AbstractNamespace(
      SqlValidatorImpl validator,
      SqlNode enclosingNode) {
    this.validator = validator;
    this.enclosingNode = enclosingNode;
  }

  //~ Methods ----------------------------------------------------------------

  public SqlValidator getValidator() {
    return validator;
  }

  public final void validate() {
    switch (status) {
    case UNVALIDATED:
      try {
        status = SqlValidatorImpl.Status.IN_PROGRESS;
        Util.permAssert(
            rowType == null,
            "Namespace.rowType must be null before validate has been called");
        RelDataType type = validateImpl();
        Util.permAssert(
            type != null,
            "validateImpl() returned null");
        if (forceNullable) {
          // REVIEW jvs 10-Oct-2005: This may not be quite right
          // if it means that nullability will be forced in the
          // ON clause where it doesn't belong.
          type =
              validator.getTypeFactory().createTypeWithNullability(
                  type,
                  true);
        }
        setType(type);
      } finally {
        status = SqlValidatorImpl.Status.VALID;
      }
      break;
    case IN_PROGRESS:
      throw Util.newInternal("todo: Cycle detected during type-checking");
    case VALID:
      break;
    default:
      throw Util.unexpected(status);
    }
  }

  /**
   * Validates this scope and returns the type of the records it returns.
   * External users should call {@link #validate}, which uses the {@link
   * #status} field to protect against cycles.
   *
   * @return record data type, never null
   */
  protected abstract RelDataType validateImpl();

  public RelDataType getRowType() {
    if (rowType == null) {
      validator.validateNamespace(this);
      Util.permAssert(rowType != null, "validate must set rowType");
    }
    return rowType;
  }

  public RelDataType getRowTypeSansSystemColumns() {
    return getRowType();
  }

  public RelDataType getType() {
    Util.discard(getRowType());
    return type;
  }

  public void setType(RelDataType type) {
    this.type = type;
    this.rowType = convertToStruct(type);
  }

  public SqlNode getEnclosingNode() {
    return enclosingNode;
  }

  public SqlValidatorTable getTable() {
    return null;
  }

  public SqlValidatorNamespace lookupChild(String name) {
    return validator.lookupFieldNamespace(
        getRowType(),
        name);
  }

  public boolean fieldExists(String name) {
    final RelDataType rowType = getRowType();
    return validator.catalogReader.field(rowType, name) != null;
  }

  public List<Pair<SqlNode, SqlMonotonicity>> getMonotonicExprs() {
    return ImmutableList.of();
  }

  public SqlMonotonicity getMonotonicity(String columnName) {
    return SqlMonotonicity.NOT_MONOTONIC;
  }

  public void makeNullable() {
    forceNullable = true;
  }

  public String translate(String name) {
    return name;
  }

  public SqlValidatorNamespace resolve() {
    return this;
  }

  public <T> T unwrap(Class<T> clazz) {
    return clazz.cast(this);
  }

  public boolean isWrapperFor(Class<?> clazz) {
    return clazz.isInstance(this);
  }

  protected RelDataType convertToStruct(RelDataType type) {
    // "MULTISET [<expr>, ...]" needs to be wrapped in a record if
    // <expr> has a scalar type.
    // For example, "MULTISET [8, 9]" has type
    // "RECORD(INTEGER EXPR$0 NOT NULL) NOT NULL MULTISET NOT NULL".
    final RelDataType componentType = type.getComponentType();
    if (componentType == null || componentType.isStruct()) {
      return type;
    }
    final RelDataTypeFactory typeFactory = validator.getTypeFactory();
    final RelDataType structType =
        typeFactory.builder()
            .add(validator.deriveAlias(getNode(), 0), componentType)
            .build();
    final RelDataType collectionType;
    switch (type.getSqlTypeName()) {
    case ARRAY:
      collectionType = typeFactory.createArrayType(structType, -1);
      break;
    case MULTISET:
      collectionType = typeFactory.createMultisetType(structType, -1);
      break;
    default:
      throw new AssertionError(type);
    }
    return typeFactory.createTypeWithNullability(collectionType,
        type.isNullable());
  }
}

// End AbstractNamespace.java


<|start_filename|>core/src/main/java/net/hydromatic/optiq/util/graph/DefaultEdge.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.util.graph;

/**
 * Default implementation of Edge.
 */
public class DefaultEdge {
  public final Object source;
  public final Object target;

  public DefaultEdge(Object source, Object target) {
    this.source = source;
    this.target = target;
  }

  @Override
  public int hashCode() {
    return source.hashCode() * 31 + target.hashCode();
  }

  @Override
  public boolean equals(Object obj) {
    return this == obj
        || obj instanceof DefaultEdge
        && ((DefaultEdge) obj).source.equals(source)
        && ((DefaultEdge) obj).target.equals(target);
  }

  public static <V> DirectedGraph.EdgeFactory<V, DefaultEdge> factory() {
    return new DirectedGraph.EdgeFactory<V, DefaultEdge>() {
      public DefaultEdge createEdge(V v0, V v1) {
        return new DefaultEdge(v0, v1);
      }
    };
  }
}

// End DefaultEdge.java


<|start_filename|>avatica/src/main/java/net/hydromatic/avatica/AvaticaJdbc41Factory.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.avatica;

import java.io.InputStream;
import java.io.Reader;
import java.sql.*;
import java.util.List;
import java.util.Properties;
import java.util.TimeZone;

/**
 * Implementation of {@link AvaticaFactory} for JDBC 4.1 (corresponds to JDK
 * 1.7).
 */
@SuppressWarnings("UnusedDeclaration")
class AvaticaJdbc41Factory implements AvaticaFactory {
  private final int major;
  private final int minor;

  /** Creates a JDBC factory. */
  public AvaticaJdbc41Factory() {
    this(4, 1);
  }

  /** Creates a JDBC factory with given major/minor version number. */
  protected AvaticaJdbc41Factory(int major, int minor) {
    this.major = major;
    this.minor = minor;
  }

  public int getJdbcMajorVersion() {
    return major;
  }

  public int getJdbcMinorVersion() {
    return minor;
  }

  public AvaticaConnection newConnection(
      UnregisteredDriver driver,
      AvaticaFactory factory,
      String url,
      Properties info) {
    return new AvaticaJdbc41Connection(driver, factory, url, info);
  }

  public AvaticaDatabaseMetaData newDatabaseMetaData(
      AvaticaConnection connection) {
    return new AvaticaJdbc41DatabaseMetaData(connection);
  }

  public AvaticaStatement newStatement(
      AvaticaConnection connection,
      int resultSetType,
      int resultSetConcurrency,
      int resultSetHoldability) {
    return new AvaticaJdbc41Statement(
        connection, resultSetType, resultSetConcurrency,
        resultSetHoldability);
  }

  public AvaticaPreparedStatement newPreparedStatement(
      AvaticaConnection connection,
      AvaticaPrepareResult prepareResult,
      int resultSetType,
      int resultSetConcurrency,
      int resultSetHoldability) throws SQLException {
    return new AvaticaJdbc41PreparedStatement(
        connection, prepareResult, resultSetType, resultSetConcurrency,
        resultSetHoldability);
  }

  public AvaticaResultSet newResultSet(
      AvaticaStatement statement,
      AvaticaPrepareResult prepareResult,
      TimeZone timeZone) {
    final ResultSetMetaData metaData =
        newResultSetMetaData(statement, prepareResult.getColumnList());
    return new AvaticaResultSet(
        statement, prepareResult, metaData, timeZone);
  }

  public AvaticaResultSetMetaData newResultSetMetaData(
      AvaticaStatement statement,
      List<ColumnMetaData> columnMetaDataList) {
    return new AvaticaResultSetMetaData(
        statement, null, columnMetaDataList);
  }

  /** Implementation of Connection for JDBC 4.1. */
  private static class AvaticaJdbc41Connection extends AvaticaConnection {
    AvaticaJdbc41Connection(UnregisteredDriver driver,
        AvaticaFactory factory,
        String url,
        Properties info) {
      super(driver, factory, url, info);
    }
  }

  /** Implementation of Statement for JDBC 4.1. */
  private static class AvaticaJdbc41Statement extends AvaticaStatement {
    public AvaticaJdbc41Statement(AvaticaConnection connection,
        int resultSetType,
        int resultSetConcurrency,
        int resultSetHoldability) {
      super(
          connection, resultSetType, resultSetConcurrency,
          resultSetHoldability);
    }
  }

  /** Implementation of PreparedStatement for JDBC 4.1. */
  private static class AvaticaJdbc41PreparedStatement
      extends AvaticaPreparedStatement {
    AvaticaJdbc41PreparedStatement(
        AvaticaConnection connection,
        AvaticaPrepareResult sql,
        int resultSetType,
        int resultSetConcurrency,
        int resultSetHoldability) throws SQLException {
      super(
          connection, sql, resultSetType, resultSetConcurrency,
          resultSetHoldability);
    }

    public void setRowId(
        int parameterIndex,
        RowId x) throws SQLException {
      getParameter(parameterIndex).setRowId(x);
    }

    public void setNString(
        int parameterIndex, String value) throws SQLException {
      getParameter(parameterIndex).setNString(value);
    }

    public void setNCharacterStream(
        int parameterIndex,
        Reader value,
        long length) throws SQLException {
      getParameter(parameterIndex).setNCharacterStream(value, length);
    }

    public void setNClob(
        int parameterIndex,
        NClob value) throws SQLException {
      getParameter(parameterIndex).setNClob(value);
    }

    public void setClob(
        int parameterIndex,
        Reader reader,
        long length) throws SQLException {
      getParameter(parameterIndex).setClob(reader, length);
    }

    public void setBlob(
        int parameterIndex,
        InputStream inputStream,
        long length) throws SQLException {
      getParameter(parameterIndex).setBlob(inputStream, length);
    }

    public void setNClob(
        int parameterIndex,
        Reader reader,
        long length) throws SQLException {
      getParameter(parameterIndex).setNClob(reader, length);
    }

    public void setSQLXML(
        int parameterIndex, SQLXML xmlObject) throws SQLException {
      getParameter(parameterIndex).setSQLXML(xmlObject);
    }

    public void setAsciiStream(
        int parameterIndex,
        InputStream x,
        long length) throws SQLException {
      getParameter(parameterIndex).setAsciiStream(x, length);
    }

    public void setBinaryStream(
        int parameterIndex,
        InputStream x,
        long length) throws SQLException {
      getParameter(parameterIndex).setBinaryStream(x, length);
    }

    public void setCharacterStream(
        int parameterIndex,
        Reader reader,
        long length) throws SQLException {
      getParameter(parameterIndex).setCharacterStream(reader, length);
    }

    public void setAsciiStream(
        int parameterIndex, InputStream x) throws SQLException {
      getParameter(parameterIndex).setAsciiStream(x);
    }

    public void setBinaryStream(
        int parameterIndex, InputStream x) throws SQLException {
      getParameter(parameterIndex).setBinaryStream(x);
    }

    public void setCharacterStream(
        int parameterIndex, Reader reader) throws SQLException {
      getParameter(parameterIndex).setCharacterStream(reader);
    }

    public void setNCharacterStream(
        int parameterIndex, Reader value) throws SQLException {
      getParameter(parameterIndex).setNCharacterStream(value);
    }

    public void setClob(
        int parameterIndex,
        Reader reader) throws SQLException {
      getParameter(parameterIndex).setClob(reader);
    }

    public void setBlob(
        int parameterIndex, InputStream inputStream) throws SQLException {
      getParameter(parameterIndex).setBlob(inputStream);
    }

    public void setNClob(
        int parameterIndex, Reader reader) throws SQLException {
      getParameter(parameterIndex).setNClob(reader);
    }
  }

  /** Implementation of DatabaseMetaData for JDBC 4.1. */
  private static class AvaticaJdbc41DatabaseMetaData
      extends AvaticaDatabaseMetaData {
    AvaticaJdbc41DatabaseMetaData(AvaticaConnection connection) {
      super(connection);
    }
  }
}

// End AvaticaJdbc41Factory.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/type/ObjectSqlType.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql.type;

import java.util.List;

import org.eigenbase.reltype.*;
import org.eigenbase.sql.*;

/**
 * ObjectSqlType represents an SQL structured user-defined type.
 */
public class ObjectSqlType extends AbstractSqlType {
  //~ Instance fields --------------------------------------------------------

  private final SqlIdentifier sqlIdentifier;

  private final RelDataTypeComparability comparability;

  private RelDataTypeFamily family;

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

  /**
   * Constructs an object type. This should only be called from a factory
   * method.
   *
   * @param typeName      SqlTypeName for this type (either Distinct or
   *                      Structured)
   * @param sqlIdentifier identifier for this type
   * @param nullable      whether type accepts nulls
   * @param fields        object attribute definitions
   */
  public ObjectSqlType(
      SqlTypeName typeName,
      SqlIdentifier sqlIdentifier,
      boolean nullable,
      List<? extends RelDataTypeField> fields,
      RelDataTypeComparability comparability) {
    super(typeName, nullable, fields);
    this.sqlIdentifier = sqlIdentifier;
    this.comparability = comparability;
    computeDigest();
  }

  //~ Methods ----------------------------------------------------------------

  public void setFamily(RelDataTypeFamily family) {
    this.family = family;
  }

  // implement RelDataType
  public RelDataTypeComparability getComparability() {
    return comparability;
  }

  // override AbstractSqlType
  public SqlIdentifier getSqlIdentifier() {
    return sqlIdentifier;
  }

  // override AbstractSqlType
  public RelDataTypeFamily getFamily() {
    // each UDT is in its own lonely family, until one day when
    // we support inheritance (at which time also need to implement
    // getPrecedenceList).
    return family;
  }

  // implement RelDataTypeImpl
  protected void generateTypeString(StringBuilder sb, boolean withDetail) {
    // TODO jvs 10-Feb-2005:  proper quoting; dump attributes withDetail?
    sb.append("ObjectSqlType(");
    sb.append(sqlIdentifier.toString());
    sb.append(")");
  }
}

// End ObjectSqlType.java


<|start_filename|>core/src/main/java/org/eigenbase/util14/ZonelessTimestamp.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.util14;

import java.sql.*;

import java.text.*;

/**
 * ZonelessTimestamp is a timestamp value without a time zone.
 */
public class ZonelessTimestamp extends ZonelessDatetime {
  //~ Static fields/initializers ---------------------------------------------

  /**
   * SerialVersionUID created with JDK 1.5 serialver tool.
   */
  private static final long serialVersionUID = -6829714640541648394L;

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

  protected final int precision;

  protected transient Timestamp tempTimestamp;

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

  /**
   * Constructs a ZonelessTimestamp.
   */
  public ZonelessTimestamp() {
    this.precision = 0;
  }

  /**
   * Constructs a ZonelessTimestamp with precision.
   *
   * <p>The precision is the number of digits to the right of the decimal
   * point in the seconds value. For example, a <code>TIMESTAMP(3)</code> has
   * a precision to milliseconds.
   *
   * @param precision Number of digits of precision
   */
  public ZonelessTimestamp(int precision) {
    this.precision = precision;
  }

  //~ Methods ----------------------------------------------------------------

  // implement ZonelessDatetime
  public Object toJdbcObject() {
    return new Timestamp(getJdbcTimestamp(DateTimeUtil.DEFAULT_ZONE));
  }

  /**
   * Converts this ZonelessTimestamp to a java.sql.Timestamp and formats it
   * via the {@link java.sql.Timestamp#toString() toString()} method of that
   * class.
   *
   * <p>Note: Jdbc formatting always includes a decimal point and at least one
   * digit of milliseconds precision. Trailing zeros, except for the first one
   * after the decimal point, do not appear in the output.
   *
   * @return the formatted time string
   */
  public String toString() {
    Timestamp ts =
        getTempTimestamp(getJdbcTimestamp(DateTimeUtil.DEFAULT_ZONE));

    // Remove trailing '.0' so that format is consistent with SQL spec for
    // CAST(TIMESTAMP(0) TO VARCHAR). E.g. "1969-12-31 16:00:00.0"
    // becomes "1969-12-31 16:00:00"
    return ts.toString().substring(0, 19);
  }

  /**
   * Formats this ZonelessTimestamp via a SimpleDateFormat. This method does
   * not display milliseconds precision.
   *
   * @param format format string, as required by SimpleDateFormat
   * @return the formatted timestamp string
   */
  public String toString(String format) {
    DateFormat formatter = getFormatter(format);
    Timestamp ts = getTempTimestamp(getTime());
    return formatter.format(ts);
  }

  /**
   * Parses a string as a ZonelessTimestamp.
   *
   * <p>This method's parsing is strict and may parse fractional seconds (as
   * opposed to just milliseconds.)
   *
   * @param s a string representing a time in ISO format, i.e. according to
   *          the SimpleDateFormat string "yyyy-MM-dd HH:mm:ss"
   * @return the parsed time, or null if parsing failed
   */
  public static ZonelessTimestamp parse(String s) {
    return parse(s, DateTimeUtil.TIMESTAMP_FORMAT_STRING);
  }

  /**
   * Parses a string as a ZonelessTimestamp using a given format string.
   *
   * <p>This method's parsing is strict and may parse fractional seconds (as
   * opposed to just milliseconds.)
   *
   * @param s      a string representing a time in ISO format, i.e. according to
   *               the SimpleDateFormat string "yyyy-MM-dd HH:mm:ss"
   * @param format format string as per {@link SimpleDateFormat}
   * @return the parsed timestamp, or null if parsing failed
   */
  public static ZonelessTimestamp parse(String s, String format) {
    DateTimeUtil.PrecisionTime pt =
        DateTimeUtil.parsePrecisionDateTimeLiteral(
            s,
            format,
            DateTimeUtil.GMT_ZONE);
    if (pt == null) {
      return null;
    }
    ZonelessTimestamp zt = new ZonelessTimestamp(pt.getPrecision());
    zt.setZonelessTime(pt.getCalendar().getTime().getTime());
    return zt;
  }

  /**
   * Gets a temporary Timestamp object. The same object is returned every
   * time.
   */
  protected Timestamp getTempTimestamp(long value) {
    if (tempTimestamp == null) {
      tempTimestamp = new Timestamp(value);
    } else {
      tempTimestamp.setTime(value);
    }
    return tempTimestamp;
  }
}

// End ZonelessTimestamp.java


<|start_filename|>core/src/test/java/org/eigenbase/test/concurrent/ConcurrentTestPluginCommand.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.test.concurrent;

import java.io.IOException;
import java.sql.Connection;
import java.sql.Statement;

/**
 * Used to extend functionality of mtsql.
 */
public interface ConcurrentTestPluginCommand {

  interface TestContext {
    /**
     * Store a message as output for mtsql script.
     *
     * @param message Message to be output
     */
    void storeMessage(String message);

    /**
     * Get connection for thread.
     *
     * @return connection for thread
     */
    Connection getConnection();

    /**
     * Get current statement for thread, or null if none.
     *
     * @return current statement for thread
     */
    Statement getCurrentStatement();
  }

  /**
   * Implement this method to extend functionality of mtsql.
   *
   * @param testContext Exposed context for plugin to run in.
   * @throws IOException
   */
  void execute(TestContext testContext) throws IOException;
}
// End ConcurrentTestPluginCommand.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/SqlNullSemantics.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql;

/**
 * SqlNullSemantics defines the possible comparison rules for values which might
 * be null. In SQL (and internal plans used to process SQL) different rules are
 * used depending on the context.
 */
public enum SqlNullSemantics {
  /**
   * Predicate semantics: e.g. in the expression (WHERE X=5), if X is NULL,
   * the comparison result is unknown, and so a filter used to evaluate the
   * WHERE clause rejects the row.
   */
  NULL_MATCHES_NOTHING,

  /**
   * GROUP BY key semantics: e.g. in the expression (GROUP BY A,B), the key
   * (null,5) is treated as equal to another key (null,5).
   */
  NULL_MATCHES_NULL,

  /**
   * Wildcard semantics: logically, this is not present in any SQL construct.
   * However, it is required internally, for example to rewrite NOT IN to NOT
   * EXISTS; when we negate a predicate, we invert the null semantics, so
   * NULL_MATCHES_NOTHING must become NULL_MATCHES_ANYTHING.
   */
  NULL_MATCHES_ANYTHING
}

// End SqlNullSemantics.java


<|start_filename|>avatica/src/test/java/net/hydromatic/avatica/test/ConnectStringParserTest.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.avatica.test;

import net.hydromatic.avatica.ConnectStringParser;

import org.junit.Test;

import java.sql.SQLException;
import java.util.Properties;

import static org.junit.Assert.*;

/**
 * Unit test for JDBC connect string parser, {@link ConnectStringParser}. The
 * ConnectStringParser is adapted from code in Mondrian, but most of the tests
 * below were unfortunately "reinvented" prior to having the Mondrian unit tests
 * in hand.
 */
public class ConnectStringParserTest {
  /**
   * Tests simple connect string. Adapted from Mondrian tests.
   */
  @Test public void testSimpleStrings() throws Throwable {
    Properties props = ConnectStringParser.parse("foo=x;bar=y;foo=z");
    assertEquals(
        "bar",
        "y",
        props.get("bar"));
    assertNull(
        "BAR",
        props.get("BAR")); // case-sensitive, unlike Mondrian
    assertEquals(
        "last foo",
        "z",
        props.get("foo"));
    assertNull(
        "key=\" bar\"",
        props.get(" bar"));
    assertNull(
        "bogus key",
        props.get("kipper"));
    assertEquals(
        "param count",
        2,
        props.size());

    String synth = ConnectStringParser.getParamString(props);
    Properties synthProps = ConnectStringParser.parse(synth);
    assertEquals("reversible", props, synthProps);
  }

  /**
   * Tests complex connect strings. Adapted directly from Mondrian tests.
   */
  @Test public void testComplexStrings() throws Throwable {
    Properties props =
        ConnectStringParser.parse(
            "normalProp=value;"
            + "emptyValue=;"
            + " spaceBeforeProp=abc;"
            + " spaceBeforeAndAfterProp =def;"
            + " space in prop = foo bar ;"
            + "equalsInValue=foo=bar;"
            + "semiInProp;Name=value;"
            + " singleQuotedValue = 'single quoted value ending in space ' ;"
            + " doubleQuotedValue = "
            + "\"=double quoted value preceded by equals\" ;"
            + " singleQuotedValueWithSemi = 'one; two';"
            + " singleQuotedValueWithSpecials = 'one; two \"three''four=five'");

    assertEquals(
        "param count",
        11,
        props.size());

    String value;
    value = (String) props.get("normalProp");
    assertEquals("value", value);
    value = (String) props.get("emptyValue");
    assertEquals("", value); // empty string, not null!
    value = (String) props.get("spaceBeforeProp");
    assertEquals("abc", value);
    value = (String) props.get("spaceBeforeAndAfterProp");
    assertEquals("def", value);
    value = (String) props.get("space in prop");
    assertEquals(value, "foo bar");
    value = (String) props.get("equalsInValue");
    assertEquals("foo=bar", value);
    value = (String) props.get("semiInProp;Name");
    assertEquals("value", value);
    value = (String) props.get("singleQuotedValue");
    assertEquals("single quoted value ending in space ", value);
    value = (String) props.get("doubleQuotedValue");
    assertEquals("=double quoted value preceded by equals", value);
    value = (String) props.get("singleQuotedValueWithSemi");
    assertEquals(value, "one; two");
    value = (String) props.get("singleQuotedValueWithSpecials");
    assertEquals(value, "one; two \"three'four=five");
  }

  /**
   * Tests for specific errors thrown by the parser.
   */
  @Test public void testConnectStringErrors() throws Throwable {
    // force some parsing errors
    try {
      ConnectStringParser.parse("key='can't parse'");
      fail("quoted value ended too soon");
    } catch (SQLException e) {
      assertExceptionMatches(e, ".*quoted value ended.*position 9.*");
    }

    try {
      ConnectStringParser.parse("key='\"can''t parse\"");
      fail("unterminated quoted value");
    } catch (SQLException e) {
      assertExceptionMatches(e, ".*unterminated quoted value.*");
    }
  }

  /**
   * Tests most of the examples from the <a
   * href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/oledb/htm/oledbconnectionstringsyntax.asp">
   * OLE DB spec</a>. Omitted are cases for Window handles, returning multiple
   * values, and special handling of "Provider" keyword.
   *
   * @throws Throwable
   */
  @Test public void testOleDbExamples() throws Throwable {
    // test the parser with examples from OLE DB documentation
    Quad[] quads = {
      // {reason for test, key, val, string to parse},
      new Quad(
          "printable chars",
          "Jet OLE DB:System Database", "c:\\system.mda",
          "Jet OLE DB:System Database=c:\\system.mda"),
      new Quad(
          "key embedded semi",
          "Authentication;Info", "Column 5",
          "Authentication;Info=Column 5"),
      new Quad(
          "key embedded equal",
          "Verification=Security", "True",
          "Verification==Security=True"),
      new Quad(
          "key many equals",
          "Many==One", "Valid",
          "Many====One=Valid"),
      new Quad(
          "key too many equal",
          "TooMany=", "False",
          "TooMany===False"),
      new Quad(
          "value embedded quote and semi",
          "ExtProps", "Data Source='localhost';Key Two='value 2'",
          "ExtProps=\"Data Source='localhost';Key Two='value 2'\""),
      new Quad(
          "value embedded double quote and semi",
          "ExtProps", "Integrated Security=\"SSPI\";Key Two=\"value 2\"",
          "ExtProps='Integrated Security=\"SSPI\";Key Two=\"value 2\"'"),
      new Quad(
          "value double quoted",
          "DataSchema", "\"MyCustTable\"",
          "DataSchema='\"MyCustTable\"'"),
      new Quad(
          "value single quoted",
          "DataSchema", "'MyCustTable'",
          "DataSchema=\"'MyCustTable'\""),
      new Quad(
          "value double quoted double trouble",
          "Caption", "\"Company's \"new\" customer\"",
          "Caption=\"\"\"Company's \"\"new\"\" customer\"\"\""),
      new Quad(
          "value single quoted double trouble",
          "Caption", "\"Company's \"new\" customer\"",
          "Caption='\"Company''s \"new\" customer\"'"),
      new Quad(
          "embedded blanks and trim",
          "My Keyword", "My Value",
          " My Keyword = My Value ;MyNextValue=Value"),
      new Quad(
          "value single quotes preserve blanks",
          "My Keyword", " My Value ",
          " My Keyword =' My Value ';MyNextValue=Value"),
      new Quad(
          "value double quotes preserve blanks",
          "My Keyword", " My Value ",
          " My Keyword =\" My Value \";MyNextValue=Value"),
      new Quad(
          "last redundant key wins",
          "SomeKey", "NextValue",
          "SomeKey=FirstValue;SomeKey=NextValue"),
    };
    for (Quad quad : quads) {
      Properties props = ConnectStringParser.parse(quad.str);

      assertEquals(quad.why, quad.val, props.get(quad.key));
      String synth = ConnectStringParser.getParamString(props);

      try {
        assertEquals("reversible " + quad.why, quad.str, synth);
      } catch (Throwable e) {
        // it's OK that the strings don't match as long as the
        // two strings parse out the same way and are thus
        // "semantically reversible"
        Properties synthProps = ConnectStringParser.parse(synth);
        assertEquals("equivalent " + quad.why, props, synthProps);
      }
    }
  }

  static void assertExceptionMatches(
      Throwable e,
      String expectedPattern) {
    if (e == null) {
      fail(
          "Expected an error which matches pattern '" + expectedPattern
          + "'");
    }
    String msg = e.toString();
    if (!msg.matches(expectedPattern)) {
      fail(
          "Got a different error '" + msg + "' than expected '"
          + expectedPattern + "'");
    }
  }

  /** Collection of values comprising a test. */
  static class Quad {
    private final String why;
    private final String key;
    private final String val;
    private final String str;

    Quad(String why, String key, String val, String str) {
      this.why = why;
      this.key = key;
      this.val = val;
      this.str = str;
    }
  }
}

// End ConnectStringParserTest.java


<|start_filename|>core/src/main/java/net/hydromatic/optiq/tools/ValidationException.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.tools;

/**
 * An Exception thrown when attempting to validate a SQL parse tree.
 */
public class ValidationException extends Exception {
  /** Creates a ValidationException with the specified detail message and
   * cause. */
  public ValidationException(String message, Throwable cause) {
    super(message, cause);
  }

  /** Creates a ValidationException with the specified detail message. */
  public ValidationException(String message) {
    super(message);
  }

  /** Creates a ValidationException with the specified cause. */
  public ValidationException(Throwable cause) {
    super(cause);
  }
}

// End ValidationException.java


<|start_filename|>mongodb/src/main/java/net/hydromatic/optiq/impl/mongodb/MongoSchemaFactory.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.impl.mongodb;

import net.hydromatic.optiq.*;

import java.util.Map;

/**
 * Factory that creates a {@link MongoSchema}.
 *
 * <p>Allows a custom schema to be included in a model.json file.</p>
 */
@SuppressWarnings("UnusedDeclaration")
public class MongoSchemaFactory implements SchemaFactory {
  // public constructor, per factory contract
  public MongoSchemaFactory() {
  }

  public Schema create(SchemaPlus parentSchema, String name,
      Map<String, Object> operand) {
    Map map = (Map) operand;
    String host = (String) map.get("host");
    String database = (String) map.get("database");
    return new MongoSchema(host, database);
  }
}

// End MongoSchemaFactory.java


<|start_filename|>core/src/main/java/org/eigenbase/rex/RexVisitor.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rex;

/**
 * Visitor pattern for traversing a tree of {@link RexNode} objects.
 *
 * @see org.eigenbase.util.Glossary#VISITOR_PATTERN
 * @see RexShuttle
 * @see RexVisitorImpl
 */
public interface RexVisitor<R> {
  //~ Methods ----------------------------------------------------------------

  R visitInputRef(RexInputRef inputRef);

  R visitLocalRef(RexLocalRef localRef);

  R visitLiteral(RexLiteral literal);

  R visitCall(RexCall call);

  R visitOver(RexOver over);

  R visitCorrelVariable(RexCorrelVariable correlVariable);

  R visitDynamicParam(RexDynamicParam dynamicParam);

  R visitRangeRef(RexRangeRef rangeRef);

  R visitFieldAccess(RexFieldAccess fieldAccess);
}

// End RexVisitor.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/type/ExplicitReturnTypeInference.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql.type;

import org.eigenbase.reltype.*;
import org.eigenbase.sql.*;

/**
 * A {@link SqlReturnTypeInference} which always returns the same SQL type.
 */
public class ExplicitReturnTypeInference implements SqlReturnTypeInference {
  //~ Instance fields --------------------------------------------------------

  protected final RelProtoDataType protoType;

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

  /**
   * Creates an inference rule which always returns the same type object.
   *
   * <p>If the requesting type factory is different, returns a copy of the
   * type object made using {@link RelDataTypeFactory#copyType(RelDataType)}
   * within the requesting type factory.
   *
   * <p>A copy of the type is required because each statement is prepared using
   * a different type factory; each type factory maintains its own cache of
   * canonical instances of each type.
   *
   * @param protoType Type object
   */
  protected ExplicitReturnTypeInference(RelProtoDataType protoType) {
    assert protoType != null;
    this.protoType = protoType;
  }

  //~ Methods ----------------------------------------------------------------

  public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
    return protoType.apply(opBinding.getTypeFactory());
  }
}

// End ExplicitReturnTypeInference.java


<|start_filename|>core/src/main/java/org/eigenbase/rel/rules/ReduceValuesRule.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel.rules;

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

import org.eigenbase.rel.*;
import org.eigenbase.relopt.*;
import org.eigenbase.reltype.RelDataType;
import org.eigenbase.rex.*;
import org.eigenbase.trace.EigenbaseTrace;
import org.eigenbase.util.Util;

/**
 * Planner rule that folds projections and filters into an underlying
 * {@link ValuesRel}. Returns an {@link EmptyRel} if all rows are filtered away.
 *
 * <p>For example,</p>
 *
 * <blockquote><code>select a - b from (values (1, 2), (3, 5), (7, 11)) as t (a,
 * b) where a + b &gt; 4</code></blockquote>
 *
 * <p>becomes</p>
 *
 * <blockquote><code>select x from (values (-2), (-4))</code></blockquote>
 */
public abstract class ReduceValuesRule extends RelOptRule {
  //~ Static fields/initializers ---------------------------------------------

  private static final Logger LOGGER = EigenbaseTrace.getPlannerTracer();

  /**
   * Instance of this rule that applies to the pattern
   * Filter(Values).
   */
  public static final ReduceValuesRule FILTER_INSTANCE =
      new ReduceValuesRule(
          operand(FilterRel.class,
              operand(ValuesRel.class, none())),
          "ReduceValuesRule[Filter") {
        public void onMatch(RelOptRuleCall call) {
          FilterRel filter = call.rel(0);
          ValuesRel values = call.rel(1);
          apply(call, null, filter, values);
        }
      };

  /**
   * Instance of this rule that applies to the pattern
   * Project(Values).
   */
  public static final ReduceValuesRule PROJECT_INSTANCE =
      new ReduceValuesRule(
          operand(ProjectRel.class,
              operand(ValuesRel.class, none())),
          "ReduceValuesRule[Project]") {
        public void onMatch(RelOptRuleCall call) {
          ProjectRel project = call.rel(0);
          ValuesRel values = call.rel(1);
          apply(call, project, null, values);
        }
      };

  /**
   * Singleton instance of this rule that applies to the pattern
   * Project(Filter(Values)).
   */
  public static final ReduceValuesRule PROJECT_FILTER_INSTANCE =
      new ReduceValuesRule(
          operand(ProjectRel.class,
              operand(FilterRel.class,
                  operand(ValuesRel.class, none()))),
          "ReduceValuesRule[Project+Filter]") {
        public void onMatch(RelOptRuleCall call) {
          ProjectRel project = call.rel(0);
          FilterRel filter = call.rel(1);
          ValuesRel values = call.rel(2);
          apply(call, project, filter, values);
        }
      };

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

  /**
   * Creates a ReduceValuesRule.
   *
   * @param operand class of rels to which this rule should apply
   */
  private ReduceValuesRule(RelOptRuleOperand operand, String desc) {
    super(operand, desc);
    Util.discard(LOGGER);
  }

  //~ Methods ----------------------------------------------------------------

  /**
   * Does the work.
   *
   * @param call    Rule call
   * @param project Project, may be null
   * @param filter  Filter, may be null
   * @param values  Values rel to be reduced
   */
  protected void apply(RelOptRuleCall call, ProjectRel project,
      FilterRel filter, ValuesRel values) {
    assert values != null;
    assert filter != null || project != null;
    final RexNode conditionExpr =
        (filter == null) ? null : filter.getCondition();
    final List<RexNode> projectExprs =
        (project == null) ? null : project.getProjects();
    RexBuilder rexBuilder = values.getCluster().getRexBuilder();

    // Find reducible expressions.
    List<RexNode> reducibleExps = new ArrayList<RexNode>();
    final MyRexShuttle shuttle = new MyRexShuttle();
    for (final List<RexLiteral> literalList : values.getTuples()) {
      shuttle.literalList = literalList;
      if (conditionExpr != null) {
        RexNode c = conditionExpr.accept(shuttle);
        reducibleExps.add(c);
      }
      if (projectExprs != null) {
        int k = -1;
        for (RexNode projectExpr : projectExprs) {
          ++k;
          RexNode e = projectExpr.accept(shuttle);
          if (RexLiteral.isNullLiteral(e)) {
            e = rexBuilder.makeAbstractCast(
                project.getRowType().getFieldList().get(k).getType(),
                e);
          }
          reducibleExps.add(e);
        }
      }
    }
    int fieldsPerRow =
        ((conditionExpr == null) ? 0 : 1)
            + ((projectExprs == null) ? 0 : projectExprs.size());
    assert fieldsPerRow > 0;
    assert reducibleExps.size() == (values.getTuples().size() * fieldsPerRow);

    // Compute the values they reduce to.
    ReduceExpressionsRule.reduceExpressions(values, reducibleExps);

    int changeCount = 0;
    final List<List<RexLiteral>> tupleList =
        new ArrayList<List<RexLiteral>>();
    for (int row = 0; row < values.getTuples().size(); ++row) {
      int i = 0;
      RexNode reducedValue;
      if (conditionExpr != null) {
        reducedValue = reducibleExps.get((row * fieldsPerRow) + i);
        ++i;
        if (!reducedValue.isAlwaysTrue()) {
          ++changeCount;
          continue;
        }
      }

      List<RexLiteral> valuesList = new ArrayList<RexLiteral>();
      if (projectExprs != null) {
        ++changeCount;
        for (; i < fieldsPerRow; ++i) {
          reducedValue = reducibleExps.get((row * fieldsPerRow) + i);
          if (reducedValue instanceof RexLiteral) {
            valuesList.add((RexLiteral) reducedValue);
          } else if (RexUtil.isNullLiteral(reducedValue, true)) {
            valuesList.add(rexBuilder.constantNull());
          } else {
            return;
          }
        }
      } else {
        valuesList = values.getTuples().get(row);
      }
      tupleList.add(valuesList);
    }

    if (changeCount > 0) {
      final RelDataType rowType;
      if (projectExprs != null) {
        rowType = project.getRowType();
      } else {
        rowType = values.getRowType();
      }
      final RelNode newRel;
      if (tupleList.isEmpty()) {
        newRel =
            new EmptyRel(
                values.getCluster(),
                rowType);
      } else {
        newRel =
            new ValuesRel(
                values.getCluster(),
                rowType,
                tupleList);
      }
      call.transformTo(newRel);

    } else {
      // Filter had no effect, so we can say that Filter(Values) ==
      // Values.
      call.transformTo(values);
    }

    // New plan is absolutely better than old plan. (Moreover, if
    // changeCount == 0, we've proved that the filter was trivial, and that
    // can send the volcano planner into a loop; see dtbug 2070.)
    if (filter != null) {
      call.getPlanner().setImportance(filter, 0.0);
    }
  }

  //~ Inner Classes ----------------------------------------------------------

  /** Shuttle that converts inputs to literals. */
  private static class MyRexShuttle extends RexShuttle {
    private List<RexLiteral> literalList;

    public RexNode visitInputRef(RexInputRef inputRef) {
      return literalList.get(inputRef.getIndex());
    }
  }
}

// End ReduceValuesRule.java


<|start_filename|>core/src/main/java/org/eigenbase/rex/RexPermutationShuttle.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rex;

import org.eigenbase.util.*;

/**
 * Visitor which replaces {@link RexLocalRef} objects after the expressions in a
 * {@link RexProgram} have been reordered.
 *
 * @see RexPermuteInputsShuttle
 */
public class RexPermutationShuttle extends RexShuttle {
  //~ Instance fields --------------------------------------------------------

  private final Permutation permutation;

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

  public RexPermutationShuttle(Permutation permutation) {
    this.permutation = permutation;
  }

  //~ Methods ----------------------------------------------------------------

  public RexNode visitLocalRef(RexLocalRef local) {
    final int index = local.getIndex();
    int target = permutation.getTarget(index);
    return new RexLocalRef(
        target,
        local.getType());
  }
}

// End RexPermutationShuttle.java


<|start_filename|>core/src/test/java/org/eigenbase/test/MockRelOptCost.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.test;

import org.eigenbase.relopt.*;

/**
 * MockRelOptCost is a mock implementation of the {@link RelOptCost} interface.
 * TODO: constructors for various scenarios
 */
public class MockRelOptCost implements RelOptCost {
  //~ Methods ----------------------------------------------------------------

  @Override
  public boolean equals(Object obj) {
    return this == obj
        || obj instanceof MockRelOptCost
        && equals((MockRelOptCost) obj);
  }

  @Override
  public int hashCode() {
    return 1;
  }

  public double getCpu() {
    return 0;
  }

  public boolean isInfinite() {
    return false;
  }

  public double getIo() {
    return 0;
  }

  public boolean isLe(RelOptCost cost) {
    return true;
  }

  public boolean isLt(RelOptCost cost) {
    return false;
  }

  public double getRows() {
    return 0;
  }

  public boolean equals(RelOptCost cost) {
    return true;
  }

  public boolean isEqWithEpsilon(RelOptCost cost) {
    return true;
  }

  public RelOptCost minus(RelOptCost cost) {
    return this;
  }

  public RelOptCost multiplyBy(double factor) {
    return this;
  }

  public double divideBy(RelOptCost cost) {
    return 1;
  }

  public RelOptCost plus(RelOptCost cost) {
    return this;
  }

  public String toString() {
    return "MockRelOptCost(0)";
  }
}

// End MockRelOptCost.java


<|start_filename|>core/src/main/java/org/eigenbase/rel/rules/PushProjectPastJoinRule.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.rel.rules;

import java.util.*;

import org.eigenbase.rel.*;
import org.eigenbase.relopt.*;
import org.eigenbase.reltype.*;
import org.eigenbase.rex.*;

/**
 * PushProjectPastJoinRule implements the rule for pushing a projection past a
 * join by splitting the projection into a projection on top of each child of
 * the join.
 */
public class PushProjectPastJoinRule extends RelOptRule {
  public static final PushProjectPastJoinRule INSTANCE =
      new PushProjectPastJoinRule(PushProjector.ExprCondition.FALSE);

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

  /**
   * Condition for expressions that should be preserved in the projection.
   */
  private final PushProjector.ExprCondition preserveExprCondition;

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

  /**
   * Creates a PushProjectPastJoinRule with an explicit condition.
   *
   * @param preserveExprCondition Condition for expressions that should be
   *                              preserved in the projection
   */
  private PushProjectPastJoinRule(
      PushProjector.ExprCondition preserveExprCondition) {
    super(
        operand(
            ProjectRel.class,
            operand(JoinRel.class, any())));
    this.preserveExprCondition = preserveExprCondition;
  }

  //~ Methods ----------------------------------------------------------------

  // implement RelOptRule
  public void onMatch(RelOptRuleCall call) {
    ProjectRel origProj = call.rel(0);
    JoinRel joinRel = call.rel(1);

    // locate all fields referenced in the projection and join condition;
    // determine which inputs are referenced in the projection and
    // join condition; if all fields are being referenced and there are no
    // special expressions, no point in proceeding any further
    PushProjector pushProject =
        new PushProjector(
            origProj,
            joinRel.getCondition(),
            joinRel,
            preserveExprCondition);
    if (pushProject.locateAllRefs()) {
      return;
    }

    // create left and right projections, projecting only those
    // fields referenced on each side
    RelNode leftProjRel =
        pushProject.createProjectRefsAndExprs(
            joinRel.getLeft(),
            true,
            false);
    RelNode rightProjRel =
        pushProject.createProjectRefsAndExprs(
            joinRel.getRight(),
            true,
            true);

    // convert the join condition to reference the projected columns
    RexNode newJoinFilter = null;
    int[] adjustments = pushProject.getAdjustments();
    if (joinRel.getCondition() != null) {
      List<RelDataTypeField> projJoinFieldList =
          new ArrayList<RelDataTypeField>();
      projJoinFieldList.addAll(
          joinRel.getSystemFieldList());
      projJoinFieldList.addAll(
          leftProjRel.getRowType().getFieldList());
      projJoinFieldList.addAll(
          rightProjRel.getRowType().getFieldList());
      newJoinFilter =
          pushProject.convertRefsAndExprs(
              joinRel.getCondition(),
              projJoinFieldList,
              adjustments);
    }

    // create a new joinrel with the projected children
    JoinRel newJoinRel =
        new JoinRel(
            joinRel.getCluster(),
            leftProjRel,
            rightProjRel,
            newJoinFilter,
            joinRel.getJoinType(),
            Collections.<String>emptySet(),
            joinRel.isSemiJoinDone(),
            joinRel.getSystemFieldList());

    // put the original project on top of the join, converting it to
    // reference the modified projection list
    ProjectRel topProject =
        pushProject.createNewProject(newJoinRel, adjustments);

    call.transformTo(topProject);
  }
}

// End PushProjectPastJoinRule.java


<|start_filename|>core/src/main/java/net/hydromatic/optiq/runtime/EnumeratorCursor.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.runtime;

import net.hydromatic.linq4j.Enumerator;

/**
 * Implementation of {@link net.hydromatic.avatica.Cursor} on top of an
 * {@link net.hydromatic.linq4j.Enumerator} that
 * returns a record for each row. The returned record is cached to avoid
 * multiple computations of current row.
 * For instance,
 * {@link net.hydromatic.optiq.rules.java.JavaRules.EnumerableCalcRel}
 * computes result just in {@code current()} method, thus it makes sense to
 * cache the result and make it available for all the accesors.
 *
 * @param <T> Element type
 */
public abstract class EnumeratorCursor<T> extends AbstractCursor {
  private final Enumerator<T> enumerator;
  private T current;

  /**
   * Creates a {@code EnumeratorCursor}
   * @param enumerator input enumerator
   */
  protected EnumeratorCursor(Enumerator<T> enumerator) {
    this.enumerator = enumerator;
  }

  public boolean next() {
    if (enumerator.moveNext()) {
      current = enumerator.current();
      return true;
    }
    current = null;
    return false;
  }

  public void close() {
    current = null;
    enumerator.close();
  }

  /**
   * Returns current row.
   * @return current row
   */
  protected T current() {
    return current;
  }
}

// End EnumeratorCursor.java


<|start_filename|>core/src/main/java/org/eigenbase/sql/type/ArraySqlType.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.sql.type;

import org.eigenbase.reltype.RelDataType;
import org.eigenbase.reltype.RelDataTypeFamily;

/**
 * SQL array type.
 */
public class ArraySqlType extends AbstractSqlType {
  //~ Instance fields --------------------------------------------------------

  private final RelDataType elementType;

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

  /**
   * Creates an ArraySqlType. This constructor should only be called
   * from a factory method.
   */
  public ArraySqlType(RelDataType elementType, boolean isNullable) {
    super(SqlTypeName.ARRAY, isNullable, null);
    assert elementType != null;
    this.elementType = elementType;
    computeDigest();
  }

  //~ Methods ----------------------------------------------------------------

  // implement RelDataTypeImpl
  protected void generateTypeString(StringBuilder sb, boolean withDetail) {
    if (withDetail) {
      sb.append(elementType.getFullTypeString());
    } else {
      sb.append(elementType.toString());
    }
    sb.append(" ARRAY");
  }

  // implement RelDataType
  public RelDataType getComponentType() {
    return elementType;
  }

  // implement RelDataType
  public RelDataTypeFamily getFamily() {
    return this;
  }
}

// End ArraySqlType.java


<|start_filename|>splunk/src/main/java/net/hydromatic/optiq/impl/splunk/search/SplunkConnection.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 net.hydromatic.optiq.impl.splunk.search;

import net.hydromatic.linq4j.Enumerator;

import java.util.List;
import java.util.Map;

/**
 * Connection to Splunk.
 */
public interface SplunkConnection {
  void getSearchResults(String search, Map<String, String> otherArgs,
      List<String> fieldList, SearchResultListener srl);

  Enumerator<Object> getSearchResultEnumerator(String search,
      Map<String, String> otherArgs, List<String> fieldList);
}

// End SplunkConnection.java


<|start_filename|>core/src/main/java/org/eigenbase/relopt/hep/HepRelMetadataProvider.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.relopt.hep;

import org.eigenbase.rel.*;
import org.eigenbase.rel.metadata.*;

import com.google.common.base.Function;

/**
 * HepRelMetadataProvider implements the {@link RelMetadataProvider} interface
 * by combining metadata from the rels inside of a {@link HepRelVertex}.
 */
class HepRelMetadataProvider implements RelMetadataProvider {
  //~ Methods ----------------------------------------------------------------

  public Function<RelNode, Metadata> apply(Class<? extends RelNode> relClass,
      final Class<? extends Metadata> metadataClass) {
    return new Function<RelNode, Metadata>() {
      public Metadata apply(RelNode rel) {
        if (!(rel instanceof HepRelVertex)) {
          return null;
        }

        HepRelVertex vertex = (HepRelVertex) rel;
        final RelNode rel2 = vertex.getCurrentRel();
        Function<RelNode, Metadata> function =
            rel.getCluster().getMetadataProvider().apply(
                rel2.getClass(), metadataClass);
        return function.apply(rel2);
      }
    };
  }
}

// End HepRelMetadataProvider.java


<|start_filename|>core/src/test/java/org/eigenbase/test/EigenbaseResourceTest.java<|end_filename|>
/*
// Licensed to <NAME> under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// <NAME> 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 org.eigenbase.test;

import java.util.*;

import org.hamcrest.CoreMatchers;
import org.junit.Test;

import static org.eigenbase.util.Static.RESOURCE;

import static org.junit.Assert.*;

/**
 * Tests generated package org.eigenbase.resource (mostly a sanity check for
 * resgen infrastructure).
 */
public class EigenbaseResourceTest {
  //~ Constructors -----------------------------------------------------------

  public EigenbaseResourceTest() {
  }

  //~ Methods ----------------------------------------------------------------

  /**
   * Verifies that resource properties such as SQLSTATE are available at
   * runtime.
   */
  @Test public void testSqlstateProperty() {
    Map<String, String> props =
        RESOURCE.illegalIntervalLiteral("", "").getProperties();
    assertThat(props.get("SQLSTATE"), CoreMatchers.equalTo("42000"));
  }
}

// End EigenbaseResourceTest.java
