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

org.apache.calcite.linq4j.Extensions Maven / Gradle / Ivy

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

import org.apache.calcite.linq4j.function.Function2;

import java.math.BigDecimal;
import java.util.Comparator;
import java.util.Map;

/**
 * Contains what, in LINQ.NET, would be extension methods.
 *
 * 

Notes on mapping from LINQ.NET to Java

* *

We have preserved most of the API. But we've changed a few things, so that * the API is more typical Java API:

* *
    * *
  • Java method names start with a lower-case letter.
  • * *
  • A few methods became keywords when their first letter was converted * to lower case; hence * {@link org.apache.calcite.linq4j.tree.Expressions#break_}
  • * *
  • We created a Java interface {@link Enumerable}, similar to LINQ.NET's * IEnumerable. IEnumerable is built into C#, and that gives it * advantages: the standard collections implement it, and you can use * any IEnumerable in a foreach loop. We made the Java * {@code Enumerable} extend {@link Iterable}, * so that it can be used in for-each loops. But the standard * collections still don't implement it. A few methods that take an * IEnumerable in LINQ.NET take an Iterable in LINQ4J.
  • * *
  • LINQ.NET's Dictionary interface maps to Map in Java; * hence, the LINQ.NET {@code ToDictionary} methods become * {@code toMap}.
  • * *
  • LINQ.NET's decimal type changes to BigDecimal. (A little bit unnatural, * since decimal is primitive and BigDecimal is not.)
  • * *
  • There is no Nullable in Java. Therefore we distinguish between methods * that return, say, Long (which may be null) and long. See for example * {@link org.apache.calcite.linq4j.function.NullableLongFunction1} and * {@link org.apache.calcite.linq4j.function.LongFunction1}, and the * variants of {@link Enumerable#sum} that call them. * *
  • Java erases type parameters from argument types before resolving * overloading. Therefore similar methods have the same erasure. Methods * {@link ExtendedQueryable#averageDouble averageDouble}, * {@link ExtendedQueryable#averageInteger averageInteger}, * {@link ExtendedQueryable#groupByK groupByK}, * {@link ExtendedQueryable#selectN selectN}, * {@link ExtendedQueryable#selectManyN selectManyN}, * {@link ExtendedQueryable#skipWhileN skipWhileN}, * {@link ExtendedQueryable#sumBigDecimal sumBigDecimal}, * {@link ExtendedQueryable#sumNullableBigDecimal sumNullableBigDecimal}, * {@link ExtendedQueryable#whereN whereN} * have been renamed from {@code average}, {@code groupBy}, {@code max}, * {@code min}, {@code select}, {@code selectMany}, {@code skipWhile} and * {@code where} to prevent ambiguity.
  • * *
  • .NET allows extension methods — static methods that then * become, via compiler magic, a method of any object whose type is the * same as the first parameter of the extension method. In LINQ.NET, the * {@code IQueryable} and {@code IEnumerable} interfaces have many such methods. * In Java, those methods need to be explicitly added to the interface, and will * need to be implemented by every class that implements that interface. * We can help by implementing the methods as static methods, and by * providing an abstract base class that implements the extension methods * in the interface. Hence {@link AbstractEnumerable} and * {@link AbstractQueryable} call methods in {@link Extensions}.
  • * *
  • .NET Func becomes {@link org.apache.calcite.linq4j.function.Function0}, * {@link org.apache.calcite.linq4j.function.Function1}, * {@link org.apache.calcite.linq4j.function.Function2}, depending * on the number of arguments to the function, because Java types cannot be * overloaded based on the number of type parameters.
  • * *
  • Types map as follows: * {@code Int32} → {@code int} or {@link Integer}, * {@code Int64} → {@code long} or {@link Long}, * {@code bool} → {@code boolean} or {@link Boolean}, * {@code Dictionary} → {@link Map}, * {@code Lookup} → {@link Map} whose value type is an {@link Iterable}, *
  • * *
  • Function types that accept primitive types in LINQ.NET have become * boxed types in LINQ4J. For example, a predicate function * {@code Func<T, bool>} becomes {@code Func1<T, Boolean>}. * It would be wrong to infer that the function is allowed to return null.
  • * *
*/ public abstract class Extensions { private Extensions() {} static final Function2 BIG_DECIMAL_SUM = BigDecimal::add; static final Function2 FLOAT_SUM = (v1, v2) -> v1 + v2; static final Function2 DOUBLE_SUM = (v1, v2) -> v1 + v2; static final Function2 INTEGER_SUM = (v1, v2) -> v1 + v2; static final Function2 LONG_SUM = (v1, v2) -> v1 + v2; @SuppressWarnings("unchecked") static final Function2 COMPARABLE_MIN = (v1, v2) -> v1 == null || v1.compareTo(v2) > 0 ? v2 : v1; @SuppressWarnings("unchecked") static final Function2 COMPARABLE_MAX = (v1, v2) -> v1 == null || v1.compareTo(v2) < 0 ? v2 : v1; static final Function2 FLOAT_MIN = (v1, v2) -> v1 == null || v1.compareTo(v2) > 0 ? v2 : v1; static final Function2 FLOAT_MAX = (v1, v2) -> v1 == null || v1.compareTo(v2) < 0 ? v2 : v1; static final Function2 DOUBLE_MIN = (v1, v2) -> v1 == null || v1.compareTo(v2) > 0 ? v2 : v1; static final Function2 DOUBLE_MAX = (v1, v2) -> v1 == null || v1.compareTo(v2) < 0 ? v2 : v1; static final Function2 INTEGER_MIN = (v1, v2) -> v1 == null || v1.compareTo(v2) > 0 ? v2 : v1; static final Function2 INTEGER_MAX = (v1, v2) -> v1 == null || v1.compareTo(v2) < 0 ? v2 : v1; static final Function2 LONG_MIN = (v1, v2) -> v1 == null || v1.compareTo(v2) > 0 ? v2 : v1; static final Function2 LONG_MAX = (v1, v2) -> v1 == null || v1.compareTo(v2) < 0 ? v2 : v1; // flags a piece of code we're yet to implement public static RuntimeException todo() { return new RuntimeException(); } public static Queryable asQueryable(DefaultEnumerable source) { //noinspection unchecked return source instanceof Queryable ? ((Queryable) source) : new EnumerableQueryable( Linq4j.DEFAULT_PROVIDER, (Class) Object.class, null, source); } static > Comparator comparableComparator() { return Comparable::compareTo; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy