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

org.apache.cassandra.cql3.functions.types.DataType Maven / Gradle / Ivy

Go to download

The Apache Cassandra Project develops a highly scalable second-generation distributed database, bringing together Dynamo's fully distributed design and Bigtable's ColumnFamily-based data model.

There is a newer version: 5.0.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 org.apache.cassandra.cql3.functions.types;

import java.util.*;

import com.google.common.collect.ImmutableList;

import org.apache.cassandra.transport.ProtocolVersion;

/**
 * Data types supported by cassandra.
 */
public abstract class DataType
{

    /**
     * The CQL type name.
     */
    public enum Name
    {
        CUSTOM(0),
        ASCII(1),
        BIGINT(2),
        BLOB(3),
        BOOLEAN(4),
        COUNTER(5),
        DECIMAL(6),
        DOUBLE(7),
        FLOAT(8),
        INT(9),
        TEXT(10)
        {
            @Override
            public boolean isCompatibleWith(Name that)
            {
                return this == that || that == VARCHAR;
            }
        },
        TIMESTAMP(11),
        UUID(12),
        VARCHAR(13)
        {
            @Override
            public boolean isCompatibleWith(Name that)
            {
                return this == that || that == TEXT;
            }
        },
        VARINT(14),
        TIMEUUID(15),
        INET(16),
        DATE(17, ProtocolVersion.V4),
        TIME(18, ProtocolVersion.V4),
        SMALLINT(19, ProtocolVersion.V4),
        TINYINT(20, ProtocolVersion.V4),
        DURATION(21, ProtocolVersion.V5),
        LIST(32),
        MAP(33),
        SET(34),
        UDT(48, ProtocolVersion.V3),
        TUPLE(49, ProtocolVersion.V3),
        VECTOR(50, ProtocolVersion.V5);

        final int protocolId;

        final ProtocolVersion minProtocolVersion;

        private static final Name[] nameToIds;

        static
        {
            int maxCode = -1;
            for (Name name : Name.values()) maxCode = Math.max(maxCode, name.protocolId);
            nameToIds = new Name[maxCode + 1];
            for (Name name : Name.values())
            {
                if (nameToIds[name.protocolId] != null) throw new IllegalStateException("Duplicate Id");
                nameToIds[name.protocolId] = name;
            }
        }

        Name(int protocolId)
        {
            this(protocolId, ProtocolVersion.V1);
        }

        Name(int protocolId, ProtocolVersion minProtocolVersion)
        {
            this.protocolId = protocolId;
            this.minProtocolVersion = minProtocolVersion;
        }

        /**
         * Return {@code true} if the provided Name is equal to this one, or if they are aliases for
         * each other, and {@code false} otherwise.
         *
         * @param that the Name to compare with the current one.
         * @return {@code true} if the provided Name is equal to this one, or if they are aliases for
         * each other, and {@code false} otherwise.
         */
        public boolean isCompatibleWith(Name that)
        {
            return this == that;
        }

        @Override
        public String toString()
        {
            return super.toString().toLowerCase();
        }
    }

    private static final Map primitiveTypeMap =
    new EnumMap<>(Name.class);

    static
    {
        primitiveTypeMap.put(Name.ASCII, new DataType.NativeType(Name.ASCII));
        primitiveTypeMap.put(Name.BIGINT, new DataType.NativeType(Name.BIGINT));
        primitiveTypeMap.put(Name.BLOB, new DataType.NativeType(Name.BLOB));
        primitiveTypeMap.put(Name.BOOLEAN, new DataType.NativeType(Name.BOOLEAN));
        primitiveTypeMap.put(Name.COUNTER, new DataType.NativeType(Name.COUNTER));
        primitiveTypeMap.put(Name.DECIMAL, new DataType.NativeType(Name.DECIMAL));
        primitiveTypeMap.put(Name.DOUBLE, new DataType.NativeType(Name.DOUBLE));
        primitiveTypeMap.put(Name.FLOAT, new DataType.NativeType(Name.FLOAT));
        primitiveTypeMap.put(Name.INET, new DataType.NativeType(Name.INET));
        primitiveTypeMap.put(Name.INT, new DataType.NativeType(Name.INT));
        primitiveTypeMap.put(Name.TEXT, new DataType.NativeType(Name.TEXT));
        primitiveTypeMap.put(Name.TIMESTAMP, new DataType.NativeType(Name.TIMESTAMP));
        primitiveTypeMap.put(Name.UUID, new DataType.NativeType(Name.UUID));
        primitiveTypeMap.put(Name.VARCHAR, new DataType.NativeType(Name.VARCHAR));
        primitiveTypeMap.put(Name.VARINT, new DataType.NativeType(Name.VARINT));
        primitiveTypeMap.put(Name.TIMEUUID, new DataType.NativeType(Name.TIMEUUID));
        primitiveTypeMap.put(Name.SMALLINT, new DataType.NativeType(Name.SMALLINT));
        primitiveTypeMap.put(Name.TINYINT, new DataType.NativeType(Name.TINYINT));
        primitiveTypeMap.put(Name.DATE, new DataType.NativeType(Name.DATE));
        primitiveTypeMap.put(Name.TIME, new DataType.NativeType(Name.TIME));
        primitiveTypeMap.put(Name.DURATION, new DataType.NativeType(Name.DURATION));
    }

    protected final DataType.Name name;

    protected DataType(DataType.Name name)
    {
        this.name = name;
    }

    /**
     * Returns the ASCII type.
     *
     * @return The ASCII type.
     */
    public static DataType ascii()
    {
        return primitiveTypeMap.get(Name.ASCII);
    }

    /**
     * Returns the BIGINT type.
     *
     * @return The BIGINT type.
     */
    public static DataType bigint()
    {
        return primitiveTypeMap.get(Name.BIGINT);
    }

    /**
     * Returns the BLOB type.
     *
     * @return The BLOB type.
     */
    public static DataType blob()
    {
        return primitiveTypeMap.get(Name.BLOB);
    }

    /**
     * Returns the BOOLEAN type.
     *
     * @return The BOOLEAN type.
     */
    public static DataType cboolean()
    {
        return primitiveTypeMap.get(Name.BOOLEAN);
    }

    /**
     * Returns the COUNTER type.
     *
     * @return The COUNTER type.
     */
    public static DataType counter()
    {
        return primitiveTypeMap.get(Name.COUNTER);
    }

    /**
     * Returns the DECIMAL type.
     *
     * @return The DECIMAL type.
     */
    public static DataType decimal()
    {
        return primitiveTypeMap.get(Name.DECIMAL);
    }

    /**
     * Returns the DOUBLE type.
     *
     * @return The DOUBLE type.
     */
    public static DataType cdouble()
    {
        return primitiveTypeMap.get(Name.DOUBLE);
    }

    /**
     * Returns the FLOAT type.
     *
     * @return The FLOAT type.
     */
    public static DataType cfloat()
    {
        return primitiveTypeMap.get(Name.FLOAT);
    }

    /**
     * Returns the INET type.
     *
     * @return The INET type.
     */
    public static DataType inet()
    {
        return primitiveTypeMap.get(Name.INET);
    }

    /**
     * Returns the TINYINT type.
     *
     * @return The TINYINT type.
     */
    public static DataType tinyint()
    {
        return primitiveTypeMap.get(Name.TINYINT);
    }

    /**
     * Returns the SMALLINT type.
     *
     * @return The SMALLINT type.
     */
    public static DataType smallint()
    {
        return primitiveTypeMap.get(Name.SMALLINT);
    }

    /**
     * Returns the INT type.
     *
     * @return The INT type.
     */
    public static DataType cint()
    {
        return primitiveTypeMap.get(Name.INT);
    }

    /**
     * Returns the TEXT type.
     *
     * @return The TEXT type.
     */
    public static DataType text()
    {
        return primitiveTypeMap.get(Name.TEXT);
    }

    /**
     * Returns the TIMESTAMP type.
     *
     * @return The TIMESTAMP type.
     */
    public static DataType timestamp()
    {
        return primitiveTypeMap.get(Name.TIMESTAMP);
    }

    /**
     * Returns the DATE type.
     *
     * @return The DATE type.
     */
    public static DataType date()
    {
        return primitiveTypeMap.get(Name.DATE);
    }

    /**
     * Returns the TIME type.
     *
     * @return The TIME type.
     */
    public static DataType time()
    {
        return primitiveTypeMap.get(Name.TIME);
    }

    /**
     * Returns the UUID type.
     *
     * @return The UUID type.
     */
    public static DataType uuid()
    {
        return primitiveTypeMap.get(Name.UUID);
    }

    /**
     * Returns the VARCHAR type.
     *
     * @return The VARCHAR type.
     */
    public static DataType varchar()
    {
        return primitiveTypeMap.get(Name.VARCHAR);
    }

    /**
     * Returns the VARINT type.
     *
     * @return The VARINT type.
     */
    public static DataType varint()
    {
        return primitiveTypeMap.get(Name.VARINT);
    }

    /**
     * Returns the TIMEUUID type.
     *
     * @return The TIMEUUID type.
     */
    public static DataType timeuuid()
    {
        return primitiveTypeMap.get(Name.TIMEUUID);
    }

    /**
     * Returns the type of lists of {@code elementType} elements.
     *
     * @param elementType the type of the list elements.
     * @param frozen      whether the list is frozen.
     * @return the type of lists of {@code elementType} elements.
     */
    public static CollectionType list(DataType elementType, boolean frozen)
    {
        return new DataType.CollectionType(Name.LIST, ImmutableList.of(elementType), frozen);
    }

    /**
     * Returns the type of "not frozen" lists of {@code elementType} elements.
     *
     * 

This is a shorthand for {@code list(elementType, false);}. * * @param elementType the type of the list elements. * @return the type of "not frozen" lists of {@code elementType} elements. */ public static CollectionType list(DataType elementType) { return list(elementType, false); } /** * Returns the type of sets of {@code elementType} elements. * * @param elementType the type of the set elements. * @param frozen whether the set is frozen. * @return the type of sets of {@code elementType} elements. */ public static CollectionType set(DataType elementType, boolean frozen) { return new DataType.CollectionType(Name.SET, ImmutableList.of(elementType), frozen); } /** * Returns the type of "not frozen" sets of {@code elementType} elements. * *

This is a shorthand for {@code set(elementType, false);}. * * @param elementType the type of the set elements. * @return the type of "not frozen" sets of {@code elementType} elements. */ public static CollectionType set(DataType elementType) { return set(elementType, false); } /** * Returns the type of maps of {@code keyType} to {@code valueType} elements. * * @param keyType the type of the map keys. * @param valueType the type of the map values. * @param frozen whether the map is frozen. * @return the type of maps of {@code keyType} to {@code valueType} elements. */ public static CollectionType map(DataType keyType, DataType valueType, boolean frozen) { return new DataType.CollectionType(Name.MAP, ImmutableList.of(keyType, valueType), frozen); } /** * Returns the type of "not frozen" maps of {@code keyType} to {@code valueType} elements. * *

This is a shorthand for {@code map(keyType, valueType, false);}. * * @param keyType the type of the map keys. * @param valueType the type of the map values. * @return the type of "not frozen" maps of {@code keyType} to {@code valueType} elements. */ public static CollectionType map(DataType keyType, DataType valueType) { return map(keyType, valueType, false); } /** * Returns the type of vector of {@code elementType} elements with {@code dimensions} dimensions. * * @param elementType the type of the vector elements. * @param dimensions the number of dimensions of the vector. * @return the type of vectors of {@code elementType} elements and {@code dimensions} dimensions. */ public static VectorType vector(DataType elementType, int dimensions) { return new VectorType(elementType, dimensions); } /** * Returns a Custom type. * *

A custom type is defined by the name of the class used on the Cassandra side to implement * it. Note that the support for custom types by the driver is limited. * *

The use of custom types is rarely useful and is thus not encouraged. * * @param typeClassName the server-side fully qualified class name for the type. * @return the custom type for {@code typeClassName}. */ public static DataType.CustomType custom(String typeClassName) { if (typeClassName == null) throw new NullPointerException(); return new DataType.CustomType(Name.CUSTOM, typeClassName); } /** * Returns the Duration type, introduced in Cassandra 3.10. * *

Note that a Duration type does not have a native representation in CQL, and technically, is * merely a special {@link DataType#custom(String) custom type} from the driver's point of view. * * @return the Duration type. The returned instance is a singleton. */ public static DataType duration() { return primitiveTypeMap.get(Name.DURATION); } /** * Returns the name of that type. * * @return the name of that type. */ public Name getName() { return name; } /** * Returns whether this data type is frozen. * *

This applies to User Defined Types, tuples and nested collections. Frozen types are * serialized as a single value in Cassandra's storage engine, whereas non-frozen types are stored * in a form that allows updates to individual subfields. * * @return whether this data type is frozen. */ public abstract boolean isFrozen(); /** * Returns whether this data type represent a CQL {@link * DataType.CollectionType collection type}, that is, a list, set or map. * * @return whether this data type name represent the name of a collection type. */ public boolean isCollection() { return this instanceof CollectionType; } /** * Returns the type arguments of this type. * *

Note that only the collection types (LIST, MAP, SET) have type arguments. For the other * types, this will return an empty list. * *

For the collection types: * *

    *
  • For lists and sets, this method returns one argument, the type of the elements. *
  • For maps, this method returns two arguments, the first one is the type of the map keys, * the second one is the type of the map values. *
* * @return an immutable list containing the type arguments of this type. */ public List getTypeArguments() { return Collections.emptyList(); } /** * Returns a String representation of this data type suitable for inclusion as a parameter type in * a function or aggregate signature. * *

In such places, the String representation might vary from the canonical one as returned by * {@link #toString()}; e.g. the {@code frozen} keyword is not accepted. * * @return a String representation of this data type suitable for inclusion as a parameter type in * a function or aggregate signature. */ public String asFunctionParameterString() { return toString(); } /** * Instances of this class represent CQL native types, also known as CQL primitive types. */ public static class NativeType extends DataType { private NativeType(DataType.Name name) { super(name); } @Override public boolean isFrozen() { return false; } @Override public final int hashCode() { return (name == Name.TEXT) ? Name.VARCHAR.hashCode() : name.hashCode(); } @Override public final boolean equals(Object o) { if (!(o instanceof DataType.NativeType)) return false; NativeType that = (DataType.NativeType) o; return this.name.isCompatibleWith(that.name); } @Override public String toString() { return name.toString(); } } /** * Instances of this class represent collection types, that is, lists, sets or maps. */ public static class CollectionType extends DataType { private final List typeArguments; private final boolean frozen; private CollectionType(DataType.Name name, List typeArguments, boolean frozen) { super(name); this.typeArguments = typeArguments; this.frozen = frozen; } @Override public boolean isFrozen() { return frozen; } @Override public List getTypeArguments() { return typeArguments; } @Override public final int hashCode() { return Objects.hash(name, typeArguments); } @Override public final boolean equals(Object o) { if (!(o instanceof DataType.CollectionType)) return false; DataType.CollectionType d = (DataType.CollectionType) o; return name == d.name && typeArguments.equals(d.typeArguments); } @Override public String toString() { if (name == Name.MAP) { String template = frozen ? "frozen<%s<%s, %s>>" : "%s<%s, %s>"; return String.format(template, name, typeArguments.get(0), typeArguments.get(1)); } else { String template = frozen ? "frozen<%s<%s>>" : "%s<%s>"; return String.format(template, name, typeArguments.get(0)); } } @Override public String asFunctionParameterString() { if (name == Name.MAP) { String template = "%s<%s, %s>"; return String.format( template, name, typeArguments.get(0).asFunctionParameterString(), typeArguments.get(1).asFunctionParameterString()); } else { String template = "%s<%s>"; return String.format(template, name, typeArguments.get(0).asFunctionParameterString()); } } } /** * A "custom" type is a type that cannot be expressed as a CQL type. * *

Each custom type is merely identified by the fully qualified {@code * #getCustomTypeClassName() class name} that represents this type server-side. * *

The driver provides a minimal support for such types through instances of this class. * *

A codec for custom types can be obtained via {@link TypeCodec#custom(DataType.CustomType)}. */ public static class CustomType extends DataType { private final String customClassName; private CustomType(DataType.Name name, String className) { super(name); this.customClassName = className; } @Override public boolean isFrozen() { return false; } @Override public final int hashCode() { return Objects.hash(name, customClassName); } @Override public final boolean equals(Object o) { if (!(o instanceof DataType.CustomType)) return false; DataType.CustomType d = (DataType.CustomType) o; return name == d.name && Objects.equals(customClassName, d.customClassName); } @Override public String toString() { return String.format("'%s'", customClassName); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy