/* * Licensed to CRATE Technology GmbH ("Crate") under one or more contributor * license agreements. See the NOTICE file distributed with this work for * additional information regarding copyright ownership. Crate 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. * * However, if you have executed another commercial license agreement * with Crate these terms will supersede the license and you may use the * software solely pursuant to the terms of the relevant commercial agreement. */ package io.crate.metadata; import com.google.common.base.Function; import com.google.common.base.MoreObjects; import com.google.common.base.Objects; import io.crate.analyze.symbol.Symbol; import io.crate.analyze.symbol.SymbolType; import io.crate.analyze.symbol.SymbolVisitor; import io.crate.metadata.table.ColumnPolicy; import io.crate.types.DataType; import io.crate.types.DataTypes; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import javax.annotation.Nullable; import java.io.IOException; import java.util.Comparator; public class Reference extends Symbol { public static final Comparator<Reference> COMPARE_BY_COLUMN_IDENT = new Comparator<Reference>() { @Override public int compare(Reference o1, Reference o2) { return o1.ident().columnIdent().compareTo(o2.ident().columnIdent()); } }; public static final Function<? super Reference, ColumnIdent> TO_COLUMN_IDENT = new Function<Reference, ColumnIdent>() { @Nullable @Override public ColumnIdent apply(@Nullable Reference input) { return input == null ? null : input.ident.columnIdent(); } }; public static final Function<? super Reference, String> TO_COLUMN_NAME = new Function<Reference, String>() { @Nullable @Override public String apply(@Nullable Reference input) { return input == null ? null : input.ident.columnIdent().sqlFqn(); } }; public enum IndexType { ANALYZED, NOT_ANALYZED, NO; } protected DataType type; private ReferenceIdent ident; private ColumnPolicy columnPolicy = ColumnPolicy.DYNAMIC; private RowGranularity granularity; private IndexType indexType = IndexType.NOT_ANALYZED; private boolean nullable = true; public Reference(StreamInput in) throws IOException { ident = new ReferenceIdent(in); type = DataTypes.fromStream(in); granularity = RowGranularity.fromStream(in); columnPolicy = ColumnPolicy.values()[in.readVInt()]; indexType = IndexType.values()[in.readVInt()]; nullable = in.readBoolean(); } public Reference() { } public Reference(ReferenceIdent ident, RowGranularity granularity, DataType type) { this(ident, granularity, type, ColumnPolicy.DYNAMIC, IndexType.NOT_ANALYZED, true); } public Reference(ReferenceIdent ident, RowGranularity granularity, DataType type, ColumnPolicy columnPolicy, IndexType indexType, boolean nullable) { this.ident = ident; this.type = type; this.granularity = granularity; this.columnPolicy = columnPolicy; this.indexType = indexType; this.nullable = nullable; } /** * Returns a cloned Reference with the given ident */ public Reference getRelocated(ReferenceIdent newIdent) { return new Reference(newIdent, granularity, type, columnPolicy, indexType, nullable); } @Override public SymbolType symbolType() { return SymbolType.REFERENCE; } @Override public <C, R> R accept(SymbolVisitor<C, R> visitor, C context) { return visitor.visitReference(this, context); } @Override public DataType valueType() { return type; } public ReferenceIdent ident() { return ident; } public RowGranularity granularity() { return granularity; } public ColumnPolicy columnPolicy() { return columnPolicy; } public IndexType indexType() { return indexType; } public boolean isNullable() { return nullable; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Reference that = (Reference) o; if (granularity != that.granularity) return false; if (ident != null ? !ident.equals(that.ident) : that.ident != null) return false; if (columnPolicy.ordinal() != that.columnPolicy.ordinal()) { return false; } if (indexType.ordinal() != that.indexType.ordinal()) { return false; } if (type != null ? !type.equals(that.type) : that.type != null) return false; if (nullable != that.nullable) return false; return true; } @Override public int hashCode() { int result = Objects.hashCode(granularity, ident, type, columnPolicy, indexType); return 31 * result + (nullable ? 1 : 0); } @Override public String toString() { MoreObjects.ToStringHelper helper = MoreObjects.toStringHelper(this) .add("ident", ident) .add("granularity", granularity) .add("type", type); if (type.equals(DataTypes.OBJECT)) { helper.add("column policy", columnPolicy.name()); } helper.add("index type", indexType.name()); helper.add("nullable", nullable); return helper.toString(); } @Override public void writeTo(StreamOutput out) throws IOException { ident.writeTo(out); DataTypes.toStream(type, out); RowGranularity.toStream(granularity, out); out.writeVInt(columnPolicy.ordinal()); out.writeVInt(indexType.ordinal()); out.writeBoolean(nullable); } public static void toStream(Reference reference, StreamOutput out) throws IOException { out.writeVInt(reference.symbolType().ordinal()); reference.writeTo(out); } public static <R extends Reference> R fromStream(StreamInput in) throws IOException { return (R) SymbolType.VALUES.get(in.readVInt()).newInstance(in); } }