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

com.hazelcast.org.apache.calcite.materialize.LatticeSpace Maven / Gradle / Ivy

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

import com.hazelcast.org.apache.calcite.plan.RelOptTable;
import com.hazelcast.org.apache.calcite.rel.type.RelDataTypeField;
import com.hazelcast.org.apache.calcite.rex.RexNode;
import com.hazelcast.org.apache.calcite.util.Util;
import com.hazelcast.org.apache.calcite.util.graph.AttributedDirectedGraph;
import com.hazelcast.org.apache.calcite.util.mapping.IntPair;

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

import com.hazelcast.org.checkerframework.checker.initialization.qual.NotOnlyInitialized;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.TreeSet;

/** Space within which lattices exist. */
class LatticeSpace {
  final SqlStatisticProvider statisticProvider;
  private final Map, LatticeTable> tableMap = new HashMap<>();
  @SuppressWarnings("assignment.type.incompatible")
  final @NotOnlyInitialized AttributedDirectedGraph g =
      new AttributedDirectedGraph<>(new Step.Factory(this));
  private final Map, String> simpleTableNames = new HashMap<>();
  private final Set simpleNames = new HashSet<>();
  /** Root nodes, indexed by digest. */
  final Map nodeMap = new HashMap<>();
  final Map, Path> pathMap = new HashMap<>();
  final Map> tableExpressions = new HashMap<>();

  LatticeSpace(SqlStatisticProvider statisticProvider) {
    this.statisticProvider = Objects.requireNonNull(statisticProvider, "statisticProvider");
  }

  /** Derives a unique name for a table, qualifying with schema name only if
   * necessary. */
  String simpleName(LatticeTable table) {
    return simpleName(table.t.getQualifiedName());
  }

  String simpleName(RelOptTable table) {
    return simpleName(table.getQualifiedName());
  }

  String simpleName(List table) {
    final String name = simpleTableNames.get(table);
    if (name != null) {
      return name;
    }
    final String name2 = Util.last(table);
    if (simpleNames.add(name2)) {
      simpleTableNames.put(ImmutableList.copyOf(table), name2);
      return name2;
    }
    final String name3 = table.toString();
    simpleTableNames.put(ImmutableList.copyOf(table), name3);
    return name3;
  }

  LatticeTable register(RelOptTable t) {
    final LatticeTable table = tableMap.get(t.getQualifiedName());
    if (table != null) {
      return table;
    }
    final LatticeTable table2 = new LatticeTable(t);
    tableMap.put(t.getQualifiedName(), table2);
    g.addVertex(table2);
    return table2;
  }

  Step addEdge(LatticeTable source, LatticeTable target, List keys) {
    keys = sortUnique(keys);
    final Step step = g.addEdge(source, target, keys);
    if (step != null) {
      return step;
    }
    for (Step step2 : g.getEdges(source, target)) {
      if (step2.keys.equals(keys)) {
        return step2;
      }
    }
    throw new AssertionError("addEdge failed, yet no edge present");
  }

  /** Returns a list of {@link IntPair} that is sorted and unique. */
  static List sortUnique(List keys) {
    if (keys.size() > 1) {
      // list may not be sorted; sort it
      keys = IntPair.ORDERING.immutableSortedCopy(keys);
      if (!IntPair.ORDERING.isStrictlyOrdered(keys)) {
        // list may contain duplicates; sort and eliminate duplicates
        final Set set = new TreeSet<>(IntPair.ORDERING);
        set.addAll(keys);
        keys = ImmutableList.copyOf(set);
      }
    }
    return keys;
  }

  /** Returns a list of {@link IntPair}, transposing source and target fields,
   * and ensuring the result is sorted and unique. */
  static List swap(List keys) {
    return sortUnique(Util.transform(keys, x -> IntPair.of(x.target, x.source)));
  }

  Path addPath(List steps) {
    final ImmutableList key = ImmutableList.copyOf(steps);
    final Path path = pathMap.get(key);
    if (path != null) {
      return path;
    }
    final Path path2 = new Path(key, pathMap.size());
    pathMap.put(key, path2);
    return path2;
  }

  /** Registers an expression as a derived column of a given table.
   *
   * 

Its ordinal is the number of fields in the row type plus the ordinal * of the extended expression. For example, if a table has 10 fields then its * derived columns will have ordinals 10, 11, 12 etc. */ int registerExpression(LatticeTable table, RexNode e) { final List expressions = tableExpressions.computeIfAbsent(table, t -> new ArrayList<>()); final int fieldCount = table.t.getRowType().getFieldCount(); for (int i = 0; i < expressions.size(); i++) { if (expressions.get(i).toString().equals(e.toString())) { return fieldCount + i; } } final int result = fieldCount + expressions.size(); expressions.add(e); return result; } /** Returns the name of field {@code field} of {@code table}. * *

If the field is derived (see * {@link #registerExpression(LatticeTable, RexNode)}) its name is its * {@link RexNode#toString()}. */ public String fieldName(LatticeTable table, int field) { final List fieldList = table.t.getRowType().getFieldList(); final int fieldCount = fieldList.size(); if (field < fieldCount) { return fieldList.get(field).getName(); } else { List rexNodes = tableExpressions.get(table); assert rexNodes != null : "no expressions found for table " + table; return rexNodes.get(field - fieldCount).toString(); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy