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

com.datastax.oss.driver.api.querybuilder.select.Selector Maven / Gradle / Ivy

The 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.datastax.oss.driver.api.querybuilder.select;

import com.datastax.oss.driver.api.core.CqlIdentifier;
import com.datastax.oss.driver.api.core.type.DataType;
import com.datastax.oss.driver.api.core.type.DataTypes;
import com.datastax.oss.driver.api.querybuilder.CqlSnippet;
import com.datastax.oss.driver.api.querybuilder.QueryBuilder;
import com.datastax.oss.driver.api.querybuilder.term.Term;
import com.datastax.oss.driver.internal.querybuilder.ArithmeticOperator;
import com.datastax.oss.driver.internal.querybuilder.select.AllSelector;
import com.datastax.oss.driver.internal.querybuilder.select.BinaryArithmeticSelector;
import com.datastax.oss.driver.internal.querybuilder.select.CastSelector;
import com.datastax.oss.driver.internal.querybuilder.select.ColumnSelector;
import com.datastax.oss.driver.internal.querybuilder.select.CountAllSelector;
import com.datastax.oss.driver.internal.querybuilder.select.ElementSelector;
import com.datastax.oss.driver.internal.querybuilder.select.FieldSelector;
import com.datastax.oss.driver.internal.querybuilder.select.FunctionSelector;
import com.datastax.oss.driver.internal.querybuilder.select.ListSelector;
import com.datastax.oss.driver.internal.querybuilder.select.MapSelector;
import com.datastax.oss.driver.internal.querybuilder.select.OppositeSelector;
import com.datastax.oss.driver.internal.querybuilder.select.RangeSelector;
import com.datastax.oss.driver.internal.querybuilder.select.SetSelector;
import com.datastax.oss.driver.internal.querybuilder.select.TupleSelector;
import com.datastax.oss.driver.internal.querybuilder.select.TypeHintSelector;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.Nullable;
import java.util.Arrays;
import java.util.Map;

/**
 * A selected element in a SELECT query.
 *
 * 

To build instances of this type, use the factory methods, such as {@link * #column(CqlIdentifier) column}, {@link #function(CqlIdentifier, Iterable) function}, etc. * *

They are used as arguments to the {@link OngoingSelection#selectors(Iterable) selectors} * method, for example: * *

{@code
 * selectFrom("foo").selectors(Selector.column("bar"), Selector.column("baz"))
 * // SELECT bar,baz FROM foo
 * }
* *

There are also shortcuts in the fluent API when you build a statement, for example: * *

{@code
 * selectFrom("foo").column("bar").column("baz")
 * // SELECT bar,baz FROM foo
 * }
*/ public interface Selector extends CqlSnippet { /** Selects all columns, as in {@code SELECT *}. */ @NonNull static Selector all() { return AllSelector.INSTANCE; } /** Selects the count of all returned rows, as in {@code SELECT count(*)}. */ @NonNull static Selector countAll() { return new CountAllSelector(); } /** Selects a particular column by its CQL identifier. */ @NonNull static Selector column(@NonNull CqlIdentifier columnId) { return new ColumnSelector(columnId); } /** Shortcut for {@link #column(CqlIdentifier) column(CqlIdentifier.fromCql(columnName))} */ @NonNull static Selector column(@NonNull String columnName) { return column(CqlIdentifier.fromCql(columnName)); } /** * Selects the sum of two arguments, as in {@code SELECT col1 + col2}. * *

This is available in Cassandra 4 and above. */ @NonNull static Selector add(@NonNull Selector left, @NonNull Selector right) { return new BinaryArithmeticSelector(ArithmeticOperator.SUM, left, right); } /** * Selects the difference of two arguments, as in {@code SELECT col1 - col2}. * *

This is available in Cassandra 4 and above. */ @NonNull static Selector subtract(@NonNull Selector left, @NonNull Selector right) { return new BinaryArithmeticSelector(ArithmeticOperator.DIFFERENCE, left, right); } /** * Selects the product of two arguments, as in {@code SELECT col1 * col2}. * *

This is available in Cassandra 4 and above. * *

The arguments will be parenthesized if they are instances of {@link #add} or {@link * #subtract}. If they are raw selectors, you might have to parenthesize them yourself. */ @NonNull static Selector multiply(@NonNull Selector left, @NonNull Selector right) { return new BinaryArithmeticSelector(ArithmeticOperator.PRODUCT, left, right); } /** * Selects the quotient of two arguments, as in {@code SELECT col1 / col2}. * *

This is available in Cassandra 4 and above. * *

The arguments will be parenthesized if they are instances of {@link #add} or {@link * #subtract}. If they are raw selectors, you might have to parenthesize them yourself. */ @NonNull static Selector divide(@NonNull Selector left, @NonNull Selector right) { return new BinaryArithmeticSelector(ArithmeticOperator.QUOTIENT, left, right); } /** * Selects the remainder of two arguments, as in {@code SELECT col1 % col2}. * *

This is available in Cassandra 4 and above. * *

The arguments will be parenthesized if they are instances of {@link #add} or {@link * #subtract}. If they are raw selectors, you might have to parenthesize them yourself. */ @NonNull static Selector remainder(@NonNull Selector left, @NonNull Selector right) { return new BinaryArithmeticSelector(ArithmeticOperator.REMAINDER, left, right); } /** * Selects the opposite of an argument, as in {@code SELECT -col1}. * *

This is available in Cassandra 4 and above. * *

The argument will be parenthesized if it is an instance of {@link #add} or {@link * #subtract}. If it is a raw selector, you might have to parenthesize it yourself. */ @NonNull static Selector negate(@NonNull Selector argument) { return new OppositeSelector(argument); } /** Selects a field inside of a UDT column, as in {@code SELECT user.name}. */ @NonNull static Selector field(@NonNull Selector udt, @NonNull CqlIdentifier fieldId) { return new FieldSelector(udt, fieldId); } /** * Shortcut for {@link #field(Selector, CqlIdentifier) getUdtField(udt, * CqlIdentifier.fromCql(fieldName))}. */ @NonNull static Selector field(@NonNull Selector udt, @NonNull String fieldName) { return field(udt, CqlIdentifier.fromCql(fieldName)); } /** * Shortcut to select a UDT field when the UDT is a simple column (as opposed to a more complex * selection, like a nested UDT). */ @NonNull static Selector field(@NonNull CqlIdentifier udtColumnId, @NonNull CqlIdentifier fieldId) { return field(column(udtColumnId), fieldId); } /** * Shortcut for {@link #field(CqlIdentifier, CqlIdentifier) * field(CqlIdentifier.fromCql(udtColumnName), CqlIdentifier.fromCql(fieldName))}. */ @NonNull static Selector field(@NonNull String udtColumnName, @NonNull String fieldName) { return field(CqlIdentifier.fromCql(udtColumnName), CqlIdentifier.fromCql(fieldName)); } /** * Selects an element in a collection column, as in {@code SELECT m['key']}. * *

As of Cassandra 4, this is only allowed in SELECT for map and set columns. DELETE accepts * list elements as well. */ @NonNull static Selector element(@NonNull Selector collection, @NonNull Term index) { return new ElementSelector(collection, index); } /** * Shortcut for element selection when the target collection is a simple column. * *

In other words, this is the equivalent of {@link #element(Selector, Term) * element(column(collectionId), index)}. */ @NonNull static Selector element(@NonNull CqlIdentifier collectionId, @NonNull Term index) { return element(column(collectionId), index); } /** * Shortcut for {@link #element(CqlIdentifier, Term) * element(CqlIdentifier.fromCql(collectionName), index)}. */ @NonNull static Selector element(@NonNull String collectionName, @NonNull Term index) { return element(CqlIdentifier.fromCql(collectionName), index); } /** * Selects a slice in a collection column, as in {@code SELECT s[4..8]}. * *

As of Cassandra 4, this is only allowed for set and map columns. Those collections are * ordered, the elements (or keys in the case of a map), will be compared to the bounds for * inclusions. Either bound can be unspecified, but not both. * * @param left the left bound (inclusive). Can be {@code null} to indicate that the slice is only * right-bound. * @param right the right bound (inclusive). Can be {@code null} to indicate that the slice is * only left-bound. */ @NonNull static Selector range(@NonNull Selector collection, @Nullable Term left, @Nullable Term right) { return new RangeSelector(collection, left, right); } /** * Shortcut for slice selection when the target collection is a simple column. * *

In other words, this is the equivalent of {@link #range(Selector, Term, Term)} * range(column(collectionId), left, right)}. */ @NonNull static Selector range( @NonNull CqlIdentifier collectionId, @Nullable Term left, @Nullable Term right) { return range(column(collectionId), left, right); } /** * Shortcut for {@link #range(CqlIdentifier, Term, Term) * range(CqlIdentifier.fromCql(collectionName), left, right)}. */ @NonNull static Selector range(@NonNull String collectionName, @Nullable Term left, @Nullable Term right) { return range(CqlIdentifier.fromCql(collectionName), left, right); } /** * Selects a group of elements as a list, as in {@code SELECT [a,b,c]}. * *

None of the selectors should be aliased (the query builder checks this at runtime), and they * should all produce the same data type (the query builder can't check this, so the query will * fail at execution time). * * @throws IllegalArgumentException if any of the selectors is aliased. */ @NonNull static Selector listOf(@NonNull Iterable elementSelectors) { return new ListSelector(elementSelectors); } /** Var-arg equivalent of {@link #listOf(Iterable)}. */ @NonNull static Selector listOf(@NonNull Selector... elementSelectors) { return listOf(Arrays.asList(elementSelectors)); } /** * Selects a group of elements as a set, as in {@code SELECT {a,b,c}}. * *

None of the selectors should be aliased (the query builder checks this at runtime), and they * should all produce the same data type (the query builder can't check this, so the query will * fail at execution time). * * @throws IllegalArgumentException if any of the selectors is aliased. */ @NonNull static Selector setOf(@NonNull Iterable elementSelectors) { return new SetSelector(elementSelectors); } /** Var-arg equivalent of {@link #setOf(Iterable)}. */ @NonNull static Selector setOf(@NonNull Selector... elementSelectors) { return setOf(Arrays.asList(elementSelectors)); } /** * Selects a group of elements as a tuple, as in {@code SELECT (a,b,c)}. * *

None of the selectors should be aliased (the query builder checks this at runtime). * * @throws IllegalArgumentException if any of the selectors is aliased. */ @NonNull static Selector tupleOf(@NonNull Iterable elementSelectors) { return new TupleSelector(elementSelectors); } /** Var-arg equivalent of {@link #tupleOf(Iterable)}. */ @NonNull static Selector tupleOf(@NonNull Selector... elementSelectors) { return tupleOf(Arrays.asList(elementSelectors)); } /** * Selects a group of elements as a map, as in {@code SELECT {a:b,c:d}}. * *

None of the selectors should be aliased (the query builder checks this at runtime). In * addition, all key selectors should produce the same type, and all value selectors as well (the * key and value types can be different); the query builder can't check this, so the query will * fail at execution time if the types are not uniform. * *

Note that Cassandra often has trouble inferring the exact map type. This will manifest as * the error message: * *

   *   Cannot infer type for term xxx in selection clause (try using a cast to force a type)
   * 
* * If you run into this, consider providing the types explicitly with {@link #mapOf(Map, DataType, * DataType)}. * * @throws IllegalArgumentException if any of the selectors is aliased. */ @NonNull static Selector mapOf(@NonNull Map elementSelectors) { return mapOf(elementSelectors, null, null); } /** * Selects a group of elements as a map and force the resulting map type, as in {@code SELECT * (map){a:b,c:d}}. * *

To create the data types, use the constants and static methods in {@link DataTypes}, or * {@link QueryBuilder#udt(CqlIdentifier)}. * * @see #mapOf(Map) */ @NonNull static Selector mapOf( @NonNull Map elementSelectors, @Nullable DataType keyType, @Nullable DataType valueType) { return new MapSelector(elementSelectors, keyType, valueType); } /** * Provides a type hint for a selector, as in {@code SELECT (double)1/3}. * *

To create the data type, use the constants and static methods in {@link DataTypes}, or * {@link QueryBuilder#udt(CqlIdentifier)}. */ @NonNull static Selector typeHint(@NonNull Selector selector, @NonNull DataType targetType) { return new TypeHintSelector(selector, targetType); } /** * Selects the result of a function call, as is {@code SELECT f(a,b)} * *

None of the arguments should be aliased (the query builder checks this at runtime). * * @throws IllegalArgumentException if any of the selectors is aliased. */ @NonNull static Selector function( @NonNull CqlIdentifier functionId, @NonNull Iterable arguments) { return new FunctionSelector(null, functionId, arguments); } /** Var-arg equivalent of {@link #function(CqlIdentifier, Iterable)}. */ @NonNull static Selector function(@NonNull CqlIdentifier functionId, @NonNull Selector... arguments) { return function(functionId, Arrays.asList(arguments)); } /** * Shortcut for {@link #function(CqlIdentifier, Iterable) * function(CqlIdentifier.fromCql(functionName), arguments)}. */ @NonNull static Selector function(@NonNull String functionName, @NonNull Iterable arguments) { return function(CqlIdentifier.fromCql(functionName), arguments); } /** Var-arg equivalent of {@link #function(String, Iterable)}. */ @NonNull static Selector function(@NonNull String functionName, @NonNull Selector... arguments) { return function(functionName, Arrays.asList(arguments)); } /** * Selects the result of a function call, as is {@code SELECT ks.f(a,b)} * *

None of the arguments should be aliased (the query builder checks this at runtime). * * @throws IllegalArgumentException if any of the selectors is aliased. */ @NonNull static Selector function( @Nullable CqlIdentifier keyspaceId, @NonNull CqlIdentifier functionId, @NonNull Iterable arguments) { return new FunctionSelector(keyspaceId, functionId, arguments); } /** Var-arg equivalent of {@link #function(CqlIdentifier, CqlIdentifier, Iterable)}. */ @NonNull static Selector function( @Nullable CqlIdentifier keyspaceId, @NonNull CqlIdentifier functionId, @NonNull Selector... arguments) { return function(keyspaceId, functionId, Arrays.asList(arguments)); } /** * Shortcut for {@link #function(CqlIdentifier, CqlIdentifier, Iterable)} * function(CqlIdentifier.fromCql(functionName), arguments)}. */ @NonNull static Selector function( @Nullable String keyspaceName, @NonNull String functionName, @NonNull Iterable arguments) { return function( keyspaceName == null ? null : CqlIdentifier.fromCql(keyspaceName), CqlIdentifier.fromCql(functionName), arguments); } /** Var-arg equivalent of {@link #function(String, String, Iterable)}. */ @NonNull static Selector function( @Nullable String keyspaceName, @NonNull String functionName, @NonNull Selector... arguments) { return function(keyspaceName, functionName, Arrays.asList(arguments)); } /** * Shortcut to select the result of the built-in {@code writetime} function, as in {@code SELECT * writetime(c)}. */ @NonNull static Selector writeTime(@NonNull CqlIdentifier columnId) { return function("writetime", column(columnId)); } /** * Shortcut for {@link #writeTime(CqlIdentifier) writeTime(CqlIdentifier.fromCql(columnName))}. */ @NonNull static Selector writeTime(@NonNull String columnName) { return writeTime(CqlIdentifier.fromCql(columnName)); } /** * Shortcut to select the result of the built-in {@code ttl} function, as in {@code SELECT * ttl(c)}. */ @NonNull static Selector ttl(@NonNull CqlIdentifier columnId) { return function("ttl", column(columnId)); } /** Shortcut for {@link #ttl(CqlIdentifier) ttl(CqlIdentifier.fromCql(columnName))}. */ @NonNull static Selector ttl(@NonNull String columnName) { return ttl(CqlIdentifier.fromCql(columnName)); } /** * Casts a selector to a type, as in {@code SELECT CAST(a AS double)}. * *

To create the data type, use the constants and static methods in {@link DataTypes}, or * {@link QueryBuilder#udt(CqlIdentifier)}. * * @throws IllegalArgumentException if the selector is aliased. */ @NonNull static Selector cast(@NonNull Selector selector, @NonNull DataType targetType) { return new CastSelector(selector, targetType); } /** Shortcut to select the result of the built-in {@code toDate} function on a simple column. */ @NonNull static Selector toDate(@NonNull CqlIdentifier columnId) { return function("todate", Selector.column(columnId)); } /** Shortcut for {@link #toDate(CqlIdentifier) toDate(CqlIdentifier.fromCql(columnName))}. */ @NonNull static Selector toDate(@NonNull String columnName) { return toDate(CqlIdentifier.fromCql(columnName)); } /** * Shortcut to select the result of the built-in {@code toTimestamp} function on a simple column. */ @NonNull static Selector toTimestamp(@NonNull CqlIdentifier columnId) { return function("totimestamp", Selector.column(columnId)); } /** * Shortcut for {@link #toTimestamp(CqlIdentifier) * toTimestamp(CqlIdentifier.fromCql(columnName))}. */ @NonNull static Selector toTimestamp(@NonNull String columnName) { return toTimestamp(CqlIdentifier.fromCql(columnName)); } /** * Shortcut to select the result of the built-in {@code toUnixTimestamp} function on a simple * column. */ @NonNull static Selector toUnixTimestamp(@NonNull CqlIdentifier columnId) { return function("tounixtimestamp", Selector.column(columnId)); } /** * Shortcut for {@link #toUnixTimestamp(CqlIdentifier) * toUnixTimestamp(CqlIdentifier.fromCql(columnName))}. */ @NonNull static Selector toUnixTimestamp(@NonNull String columnName) { return toUnixTimestamp(CqlIdentifier.fromCql(columnName)); } /** Aliases the selector, as in {@code SELECT count(*) AS total}. */ @NonNull Selector as(@NonNull CqlIdentifier alias); /** Shortcut for {@link #as(CqlIdentifier) as(CqlIdentifier.fromCql(alias))} */ @NonNull default Selector as(@NonNull String alias) { return as(CqlIdentifier.fromCql(alias)); } /** @return null if the selector is not aliased. */ @Nullable CqlIdentifier getAlias(); }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy