From 4ea4139e5fd9893e350a2af710c5ccadbbc2fa73 Mon Sep 17 00:00:00 2001 From: Ying Su Date: Wed, 16 Sep 2020 18:58:23 -0700 Subject: [PATCH] Revert "Add long and varchar enum types" This reverts commit 7ced455b02032a99b7ce8991412897baba60d14d. --- .../client/ClientTypeSignatureParameter.java | 14 -- .../common/type/AbstractVarcharType.java | 185 ------------------ .../facebook/presto/common/type/EnumType.java | 24 --- .../presto/common/type/LongEnumType.java | 121 ------------ .../presto/common/type/ParameterKind.java | 4 +- .../presto/common/type/TypeParameter.java | 27 --- .../presto/common/type/TypeSignature.java | 178 +---------------- .../common/type/TypeSignatureParameter.java | 35 ---- .../presto/common/type/TypeUtils.java | 30 --- .../presto/common/type/VarcharEnumType.java | 109 ----------- .../presto/common/type/VarcharType.java | 167 +++++++++++++++- .../presto/common/type/TestTypeSignature.java | 54 +---- .../presto/type/LongEnumParametricType.java | 59 ------ .../type/VarcharEnumParametricType.java | 59 ------ 14 files changed, 172 insertions(+), 894 deletions(-) delete mode 100644 presto-common/src/main/java/com/facebook/presto/common/type/AbstractVarcharType.java delete mode 100644 presto-common/src/main/java/com/facebook/presto/common/type/EnumType.java delete mode 100644 presto-common/src/main/java/com/facebook/presto/common/type/LongEnumType.java delete mode 100644 presto-common/src/main/java/com/facebook/presto/common/type/VarcharEnumType.java delete mode 100644 presto-main/src/main/java/com/facebook/presto/type/LongEnumParametricType.java delete mode 100644 presto-main/src/main/java/com/facebook/presto/type/VarcharEnumParametricType.java diff --git a/presto-client/src/main/java/com/facebook/presto/client/ClientTypeSignatureParameter.java b/presto-client/src/main/java/com/facebook/presto/client/ClientTypeSignatureParameter.java index 9e187c8248f3..4ead2f14a168 100644 --- a/presto-client/src/main/java/com/facebook/presto/client/ClientTypeSignatureParameter.java +++ b/presto-client/src/main/java/com/facebook/presto/client/ClientTypeSignatureParameter.java @@ -14,11 +14,9 @@ package com.facebook.presto.client; import com.facebook.airlift.json.ObjectMapperProvider; -import com.facebook.presto.common.type.LongEnumType.LongEnumMap; import com.facebook.presto.common.type.NamedTypeSignature; import com.facebook.presto.common.type.ParameterKind; import com.facebook.presto.common.type.TypeSignatureParameter; -import com.facebook.presto.common.type.VarcharEnumType.VarcharEnumMap; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonParser; @@ -55,12 +53,6 @@ public ClientTypeSignatureParameter(TypeSignatureParameter typeParameterSignatur case NAMED_TYPE: value = typeParameterSignature.getNamedTypeSignature(); break; - case LONG_ENUM: - value = typeParameterSignature.getLongEnumMap(); - break; - case VARCHAR_ENUM: - value = typeParameterSignature.getVarcharEnumMap(); - break; default: throw new UnsupportedOperationException(format("Unknown kind [%s]", kind)); } @@ -161,12 +153,6 @@ public ClientTypeSignatureParameter deserialize(JsonParser jp, DeserializationCo case LONG: value = MAPPER.readValue(jsonValue, Long.class); break; - case LONG_ENUM: - value = MAPPER.readValue(jsonValue, LongEnumMap.class); - break; - case VARCHAR_ENUM: - value = MAPPER.readValue(jsonValue, VarcharEnumMap.class); - break; default: throw new UnsupportedOperationException(format("Unsupported kind [%s]", kind)); } diff --git a/presto-common/src/main/java/com/facebook/presto/common/type/AbstractVarcharType.java b/presto-common/src/main/java/com/facebook/presto/common/type/AbstractVarcharType.java deleted file mode 100644 index 8a2332ac8f1f..000000000000 --- a/presto-common/src/main/java/com/facebook/presto/common/type/AbstractVarcharType.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Licensed 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.facebook.presto.common.type; - -import com.facebook.presto.common.block.Block; -import com.facebook.presto.common.block.BlockBuilder; -import com.facebook.presto.common.function.SqlFunctionProperties; -import io.airlift.slice.Slice; -import io.airlift.slice.Slices; - -import java.util.Objects; - -public class AbstractVarcharType - extends AbstractVariableWidthType -{ - public static final int UNBOUNDED_LENGTH = Integer.MAX_VALUE; - public static final int MAX_LENGTH = Integer.MAX_VALUE - 1; - - private final int length; - - AbstractVarcharType(int length, TypeSignature typeSignature) - { - super(typeSignature, Slice.class); - - if (length < 0) { - throw new IllegalArgumentException("Invalid VARCHAR length " + length); - } - this.length = length; - } - - @Deprecated - public int getLength() - { - return length; - } - - public int getLengthSafe() - { - if (isUnbounded()) { - throw new IllegalStateException("Cannot get size of unbounded VARCHAR."); - } - return length; - } - - public boolean isUnbounded() - { - return length == UNBOUNDED_LENGTH; - } - - @Override - public boolean isComparable() - { - return true; - } - - @Override - public boolean isOrderable() - { - return true; - } - - @Override - public Object getObjectValue(SqlFunctionProperties properties, Block block, int position) - { - if (block.isNull(position)) { - return null; - } - - return block.getSlice(position, 0, block.getSliceLength(position)).toStringUtf8(); - } - - @Override - public boolean equalTo(Block leftBlock, int leftPosition, Block rightBlock, int rightPosition) - { - int leftLength = leftBlock.getSliceLength(leftPosition); - int rightLength = rightBlock.getSliceLength(rightPosition); - if (leftLength != rightLength) { - return false; - } - return leftBlock.equals(leftPosition, 0, rightBlock, rightPosition, 0, leftLength); - } - - @Override - public long hash(Block block, int position) - { - return block.hash(position, 0, block.getSliceLength(position)); - } - - @Override - public int compareTo(Block leftBlock, int leftPosition, Block rightBlock, int rightPosition) - { - int leftLength = leftBlock.getSliceLength(leftPosition); - int rightLength = rightBlock.getSliceLength(rightPosition); - return leftBlock.compareTo(leftPosition, 0, leftLength, rightBlock, rightPosition, 0, rightLength); - } - - @Override - public void appendTo(Block block, int position, BlockBuilder blockBuilder) - { - if (block.isNull(position)) { - blockBuilder.appendNull(); - } - else { - block.writeBytesTo(position, 0, block.getSliceLength(position), blockBuilder); - blockBuilder.closeEntry(); - } - } - - @Override - public Slice getSlice(Block block, int position) - { - return block.getSlice(position, 0, block.getSliceLength(position)); - } - - @Override - public Slice getSliceUnchecked(Block block, int internalPosition) - { - return block.getSliceUnchecked(internalPosition, 0, block.getSliceLengthUnchecked(internalPosition)); - } - - public void writeString(BlockBuilder blockBuilder, String value) - { - writeSlice(blockBuilder, Slices.utf8Slice(value)); - } - - @Override - public void writeSlice(BlockBuilder blockBuilder, Slice value) - { - writeSlice(blockBuilder, value, 0, value.length()); - } - - @Override - public void writeSlice(BlockBuilder blockBuilder, Slice value, int offset, int length) - { - blockBuilder.writeBytes(value, offset, length).closeEntry(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - AbstractVarcharType other = (AbstractVarcharType) o; - - return Objects.equals(this.length, other.length); - } - - @Override - public int hashCode() - { - return Objects.hash(length); - } - - @Override - public String getDisplayName() - { - if (length == UNBOUNDED_LENGTH) { - return getTypeSignature().getBase(); - } - - return getTypeSignature().toString(); - } - - @Override - public String toString() - { - return getDisplayName(); - } -} diff --git a/presto-common/src/main/java/com/facebook/presto/common/type/EnumType.java b/presto-common/src/main/java/com/facebook/presto/common/type/EnumType.java deleted file mode 100644 index 6d1ca90289ef..000000000000 --- a/presto-common/src/main/java/com/facebook/presto/common/type/EnumType.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Licensed 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.facebook.presto.common.type; - -import java.util.Map; - -public interface EnumType - extends Type -{ - Map getEnumMap(); - - Type getValueType(); -} diff --git a/presto-common/src/main/java/com/facebook/presto/common/type/LongEnumType.java b/presto-common/src/main/java/com/facebook/presto/common/type/LongEnumType.java deleted file mode 100644 index 71d323162b49..000000000000 --- a/presto-common/src/main/java/com/facebook/presto/common/type/LongEnumType.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Licensed 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.facebook.presto.common.type; - -import com.facebook.presto.common.block.Block; -import com.facebook.presto.common.function.SqlFunctionProperties; -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.util.Comparator; -import java.util.Map; -import java.util.Objects; -import java.util.stream.Collectors; - -import static com.facebook.presto.common.type.BigintType.BIGINT; -import static com.facebook.presto.common.type.TypeUtils.normalizeEnumMap; -import static com.facebook.presto.common.type.TypeUtils.validateEnumMap; -import static java.lang.String.format; - -public class LongEnumType - extends AbstractLongType - implements EnumType -{ - private final LongEnumMap enumMap; - - public LongEnumType(String name, LongEnumMap enumMap) - { - super(new TypeSignature(name, TypeSignatureParameter.of(enumMap))); - this.enumMap = enumMap; - } - - @Override - public Map getEnumMap() - { - return enumMap.getEnumMap(); - } - - @Override - public Object getObjectValue(SqlFunctionProperties properties, Block block, int position) - { - if (block.isNull(position)) { - return null; - } - - return block.getLong(position); - } - - @Override - public Type getValueType() - { - return BIGINT; - } - - @Override - public String getDisplayName() - { - return getTypeSignature().getBase(); - } - - public static class LongEnumMap - { - private final Map enumMap; - - @JsonCreator - public LongEnumMap(@JsonProperty("enumMap") Map enumMap) - { - validateEnumMap(enumMap); - this.enumMap = normalizeEnumMap(enumMap); - } - - @JsonProperty - public Map getEnumMap() - { - return enumMap; - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - LongEnumMap other = (LongEnumMap) o; - - return Objects.equals(this.enumMap, other.enumMap); - } - - @Override - public String toString() - { - return "enum:bigint{" - + enumMap.entrySet() - .stream() - .sorted(Comparator.comparing(Map.Entry::getKey)) - .map(e -> format("\"%s\": %d", e.getKey().replaceAll("\"", "\"\""), e.getValue())) - .collect(Collectors.joining(", ")) - + "}"; - } - - @Override - public int hashCode() - { - return Objects.hash(enumMap); - } - } -} diff --git a/presto-common/src/main/java/com/facebook/presto/common/type/ParameterKind.java b/presto-common/src/main/java/com/facebook/presto/common/type/ParameterKind.java index ab810c3021bc..36cc40f0358e 100644 --- a/presto-common/src/main/java/com/facebook/presto/common/type/ParameterKind.java +++ b/presto-common/src/main/java/com/facebook/presto/common/type/ParameterKind.java @@ -23,9 +23,7 @@ public enum ParameterKind TYPE(Optional.of("TYPE_SIGNATURE")), NAMED_TYPE(Optional.of("NAMED_TYPE_SIGNATURE")), LONG(Optional.of("LONG_LITERAL")), - VARIABLE(Optional.empty()), - LONG_ENUM(Optional.of("LONG_ENUM")), - VARCHAR_ENUM(Optional.of("VARCHAR_ENUM")); + VARIABLE(Optional.empty()); // TODO: drop special serialization code as soon as all clients // migrate to version which can deserialize new format. diff --git a/presto-common/src/main/java/com/facebook/presto/common/type/TypeParameter.java b/presto-common/src/main/java/com/facebook/presto/common/type/TypeParameter.java index eb1cc8628d5b..4f214a167e2c 100644 --- a/presto-common/src/main/java/com/facebook/presto/common/type/TypeParameter.java +++ b/presto-common/src/main/java/com/facebook/presto/common/type/TypeParameter.java @@ -13,9 +13,6 @@ */ package com.facebook.presto.common.type; -import com.facebook.presto.common.type.LongEnumType.LongEnumMap; -import com.facebook.presto.common.type.VarcharEnumType.VarcharEnumMap; - import java.util.Objects; import static java.lang.String.format; @@ -51,16 +48,6 @@ public static TypeParameter of(String variable) return new TypeParameter(ParameterKind.VARIABLE, variable); } - public static TypeParameter of(LongEnumMap enumMap) - { - return new TypeParameter(ParameterKind.LONG_ENUM, enumMap); - } - - public static TypeParameter of(VarcharEnumMap enumMap) - { - return new TypeParameter(ParameterKind.VARCHAR_ENUM, enumMap); - } - public static TypeParameter of(TypeSignatureParameter parameter, TypeManager typeManager) { switch (parameter.getKind()) { @@ -78,10 +65,6 @@ public static TypeParameter of(TypeSignatureParameter parameter, TypeManager typ } case VARIABLE: return of(parameter.getVariable()); - case LONG_ENUM: - return of(parameter.getLongEnumMap()); - case VARCHAR_ENUM: - return of(parameter.getVarcharEnumMap()); default: throw new UnsupportedOperationException(format("Unsupported parameter [%s]", parameter)); } @@ -115,16 +98,6 @@ public Long getLongLiteral() return getValue(ParameterKind.LONG, Long.class); } - public LongEnumMap getLongEnumMap() - { - return getValue(ParameterKind.LONG_ENUM, LongEnumMap.class); - } - - public VarcharEnumMap getVarcharEnumMap() - { - return getValue(ParameterKind.VARCHAR_ENUM, VarcharEnumMap.class); - } - public NamedType getNamedType() { return getValue(ParameterKind.NAMED_TYPE, NamedType.class); diff --git a/presto-common/src/main/java/com/facebook/presto/common/type/TypeSignature.java b/presto-common/src/main/java/com/facebook/presto/common/type/TypeSignature.java index d51e660ffe0a..9c2e4156a424 100644 --- a/presto-common/src/main/java/com/facebook/presto/common/type/TypeSignature.java +++ b/presto-common/src/main/java/com/facebook/presto/common/type/TypeSignature.java @@ -13,15 +13,13 @@ */ package com.facebook.presto.common.type; -import com.facebook.presto.common.type.LongEnumType.LongEnumMap; -import com.facebook.presto.common.type.VarcharEnumType.VarcharEnumMap; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; import java.util.ArrayList; -import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.Optional; @@ -29,13 +27,11 @@ import java.util.TreeMap; import java.util.TreeSet; import java.util.regex.Pattern; -import java.util.stream.Collectors; import static java.lang.Character.isDigit; import static java.lang.String.format; import static java.util.Arrays.asList; import static java.util.Collections.unmodifiableList; -import static java.util.Locale.ENGLISH; public class TypeSignature { @@ -49,9 +45,6 @@ public class TypeSignature private static final Set SIMPLE_TYPE_WITH_SPACES = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); - private static final String LONG_ENUM_PREFIX = "enum:bigint"; - private static final String VARCHAR_ENUM_PREFIX = "enum:varchar"; - static { BASE_NAME_ALIAS_TO_CANONICAL.put("int", StandardTypes.INTEGER); @@ -107,21 +100,6 @@ public boolean isCalculated() return calculated; } - public boolean isEnum() - { - return isLongEnum() || isVarcharEnum(); - } - - public boolean isLongEnum() - { - return parameters.size() == 1 && parameters.get(0).isLongEnum(); - } - - public boolean isVarcharEnum() - { - return parameters.size() == 1 && parameters.get(0).isVarcharEnum(); - } - @JsonCreator public static TypeSignature parseTypeSignature(String signature) { @@ -137,7 +115,7 @@ public static TypeSignature parseTypeSignature(String signature, Set lit checkArgument(!literalCalculationParameters.contains(signature), "Bad type signature: '%s'", signature); return new TypeSignature(canonicalizeBaseName(signature), new ArrayList<>()); } - if (signature.toLowerCase(ENGLISH).startsWith(StandardTypes.ROW + "(")) { + if (signature.toLowerCase(Locale.ENGLISH).startsWith(StandardTypes.ROW + "(")) { return parseRowTypeSignature(signature, literalCalculationParameters); } @@ -145,12 +123,8 @@ public static TypeSignature parseTypeSignature(String signature, Set lit List parameters = new ArrayList<>(); int parameterStart = -1; int bracketCount = 0; - int parameterEnd = -1; for (int i = 0; i < signature.length(); i++) { - if (i < parameterEnd) { - continue; - } char c = signature.charAt(i); // TODO: remove angle brackets support once ROW(name) will be dropped // Angle brackets here are checked not for the support of ARRAY<> and MAP<> @@ -177,9 +151,6 @@ else if (c == ')' || c == '>') { } } } - else if (isEnumMapStart(signature, i)) { - parameterEnd = parseEnumMap(signature, i).mapEndIndex; - } else if (c == ',') { if (bracketCount == 1) { checkArgument(parameterStart >= 0, "Bad type signature: '%s'", signature); @@ -192,133 +163,6 @@ else if (c == ',') { throw new IllegalArgumentException(format("Bad type signature: '%s'", signature)); } - private static class EnumMapParsingData - { - final int mapEndIndex; - private final Map map; - final boolean isLongEnum; - - EnumMapParsingData(int mapEndIndex, Map map, boolean isLongEnum) - { - this.mapEndIndex = mapEndIndex; - this.map = map; - this.isLongEnum = isLongEnum; - } - - LongEnumMap getLongEnumMap() - { - checkArgument(isLongEnum, "Invalid enum map format"); - return new LongEnumMap( - map.entrySet().stream() - .collect(Collectors.toMap(Map.Entry::getKey, e -> Long.parseLong(e.getValue())))); - } - - VarcharEnumMap getVarcharEnumMap() - { - checkArgument(!isLongEnum, "Invalid enum map format"); - return new VarcharEnumMap(map); - } - } - - private static boolean isEnumMapStart(String signature, int startIndex) - { - String suffix = signature.substring(startIndex).toLowerCase(ENGLISH); - return suffix.startsWith(LONG_ENUM_PREFIX + "{") || suffix.startsWith(VARCHAR_ENUM_PREFIX + "{"); - } - - private enum EnumMapParsingState - { - EXPECT_KEY, - IN_KEY, - IN_KEY_ESCAPE, - EXPECT_COLON, - EXPECT_VALUE, - IN_NUM_VALUE, - IN_STR_VALUE, - IN_STR_VALUE_ESCAPE, - EXPECT_COMMA_OR_CLOSING_BRACKET - } - - private static EnumMapParsingData parseEnumMap(String signature, int startIndex) - { - EnumMapParsingState state = EnumMapParsingState.EXPECT_KEY; - boolean isLongEnum = signature.substring(startIndex).trim().toLowerCase(ENGLISH).startsWith(LONG_ENUM_PREFIX); - int openBracketIndex = startIndex + (isLongEnum ? LONG_ENUM_PREFIX.length() : VARCHAR_ENUM_PREFIX.length()) + 1; - String key = null; - StringBuilder keyOrValue = new StringBuilder(); - Map map = new HashMap<>(); - - for (int i = openBracketIndex; i < signature.length(); i++) { - char c = signature.charAt(i); - if (state == EnumMapParsingState.IN_KEY_ESCAPE) { - state = EnumMapParsingState.IN_KEY; - keyOrValue.append(c); - } - if (state == EnumMapParsingState.IN_STR_VALUE_ESCAPE) { - state = EnumMapParsingState.IN_STR_VALUE; - keyOrValue.append(c); - } - else if (c == '"') { - if (state == EnumMapParsingState.EXPECT_KEY) { - state = EnumMapParsingState.IN_KEY; - } - else if (state == EnumMapParsingState.EXPECT_VALUE) { - if (isLongEnum) { - throw new IllegalStateException("Unexpected varchar value in numeric enum signature"); - } - state = EnumMapParsingState.IN_STR_VALUE; - } - else if ((state == EnumMapParsingState.IN_KEY || state == EnumMapParsingState.IN_STR_VALUE) - && i + 1 < signature.length() && signature.charAt(i + 1) == '"') { - state = state == EnumMapParsingState.IN_KEY ? EnumMapParsingState.IN_KEY_ESCAPE : EnumMapParsingState.IN_STR_VALUE_ESCAPE; - } - else if (state == EnumMapParsingState.IN_KEY) { - state = EnumMapParsingState.EXPECT_COLON; - } - else if (state == EnumMapParsingState.IN_STR_VALUE) { - state = EnumMapParsingState.EXPECT_COMMA_OR_CLOSING_BRACKET; - } - else { - throw new IllegalStateException("Cannot parse enum signature"); - } - } - else if (state == EnumMapParsingState.IN_KEY || state == EnumMapParsingState.IN_STR_VALUE) { - keyOrValue.append(c); - } - else if (c == ':' && state == EnumMapParsingState.EXPECT_COLON) { - key = keyOrValue.toString(); - keyOrValue = new StringBuilder(); - state = EnumMapParsingState.EXPECT_VALUE; - } - else if ((Character.isDigit(c) || c == '-') && state == EnumMapParsingState.EXPECT_VALUE) { - if (!isLongEnum) { - throw new IllegalStateException("Unexpected numeric value in varchar enum signature"); - } - state = EnumMapParsingState.IN_NUM_VALUE; - keyOrValue.append(c); - } - else if (Character.isDigit(c) && state == EnumMapParsingState.IN_NUM_VALUE) { - keyOrValue.append(c); - } - else if ((c == ',' || c == '}') && (state == EnumMapParsingState.EXPECT_COMMA_OR_CLOSING_BRACKET || state == EnumMapParsingState.IN_NUM_VALUE)) { - if (key == null) { - throw new IllegalStateException("Cannot parse enum signature"); - } - map.put(key, keyOrValue.toString()); - if (c == '}') { - return new EnumMapParsingData(i, map, isLongEnum); - } - key = null; - keyOrValue = new StringBuilder(); - state = EnumMapParsingState.EXPECT_KEY; - } - else if (!Character.isWhitespace(c)) { - throw new IllegalStateException("Cannot parse enum signature"); - } - } - throw new IllegalStateException("Cannot parse enum signature"); - } - private enum RowTypeSignatureParsingState { START_OF_FIELD, @@ -331,7 +175,7 @@ private enum RowTypeSignatureParsingState private static TypeSignature parseRowTypeSignature(String signature, Set literalParameters) { - checkArgument(signature.toLowerCase(ENGLISH).startsWith(StandardTypes.ROW + "("), "Not a row type signature: '%s'", signature); + checkArgument(signature.toLowerCase(Locale.ENGLISH).startsWith(StandardTypes.ROW + "("), "Not a row type signature: '%s'", signature); RowTypeSignatureParsingState state = RowTypeSignatureParsingState.START_OF_FIELD; int bracketLevel = 1; @@ -474,18 +318,6 @@ private static TypeSignatureParameter parseTypeSignatureParameter( else if (literalCalculationParameters.contains(parameterName)) { return TypeSignatureParameter.of(parameterName); } - else if (isEnumMapStart(signature, begin)) { - if (!parameterName.endsWith("}")) { - throw new IllegalStateException("Cannot parse enum signature"); - } - EnumMapParsingData enumMapData = parseEnumMap(signature, begin); - if (enumMapData.isLongEnum) { - return TypeSignatureParameter.of(enumMapData.getLongEnumMap()); - } - else { - return TypeSignatureParameter.of(enumMapData.getVarcharEnumMap()); - } - } else { return TypeSignatureParameter.of(parseTypeSignature(parameterName, literalCalculationParameters)); } @@ -562,13 +394,13 @@ public boolean equals(Object o) TypeSignature other = (TypeSignature) o; - return Objects.equals(this.base.toLowerCase(ENGLISH), other.base.toLowerCase(ENGLISH)) && + return Objects.equals(this.base.toLowerCase(Locale.ENGLISH), other.base.toLowerCase(Locale.ENGLISH)) && Objects.equals(this.parameters, other.parameters); } @Override public int hashCode() { - return Objects.hash(base.toLowerCase(ENGLISH), parameters); + return Objects.hash(base.toLowerCase(Locale.ENGLISH), parameters); } } diff --git a/presto-common/src/main/java/com/facebook/presto/common/type/TypeSignatureParameter.java b/presto-common/src/main/java/com/facebook/presto/common/type/TypeSignatureParameter.java index 965a927c865f..ab2b8c1e477a 100644 --- a/presto-common/src/main/java/com/facebook/presto/common/type/TypeSignatureParameter.java +++ b/presto-common/src/main/java/com/facebook/presto/common/type/TypeSignatureParameter.java @@ -13,9 +13,6 @@ */ package com.facebook.presto.common.type; -import com.facebook.presto.common.type.LongEnumType.LongEnumMap; -import com.facebook.presto.common.type.VarcharEnumType.VarcharEnumMap; - import java.util.Objects; import java.util.Optional; @@ -47,16 +44,6 @@ public static TypeSignatureParameter of(String variable) return new TypeSignatureParameter(ParameterKind.VARIABLE, variable); } - public static TypeSignatureParameter of(LongEnumMap enumMap) - { - return new TypeSignatureParameter(ParameterKind.LONG_ENUM, enumMap); - } - - public static TypeSignatureParameter of(VarcharEnumMap enumMap) - { - return new TypeSignatureParameter(ParameterKind.VARCHAR_ENUM, enumMap); - } - private TypeSignatureParameter(ParameterKind kind, Object value) { this.kind = requireNonNull(kind, "kind is null"); @@ -94,16 +81,6 @@ public boolean isVariable() return kind == ParameterKind.VARIABLE; } - public boolean isLongEnum() - { - return kind == ParameterKind.LONG_ENUM; - } - - public boolean isVarcharEnum() - { - return kind == ParameterKind.VARCHAR_ENUM; - } - private A getValue(ParameterKind expectedParameterKind, Class target) { if (kind != expectedParameterKind) { @@ -132,16 +109,6 @@ public String getVariable() return getValue(ParameterKind.VARIABLE, String.class); } - public LongEnumMap getLongEnumMap() - { - return getValue(ParameterKind.LONG_ENUM, LongEnumMap.class); - } - - public VarcharEnumMap getVarcharEnumMap() - { - return getValue(ParameterKind.VARCHAR_ENUM, VarcharEnumMap.class); - } - public Optional getTypeSignatureOrNamedTypeSignature() { switch (kind) { @@ -162,8 +129,6 @@ public boolean isCalculated() case NAMED_TYPE: return getNamedTypeSignature().getTypeSignature().isCalculated(); case LONG: - case LONG_ENUM: - case VARCHAR_ENUM: return false; case VARIABLE: return true; diff --git a/presto-common/src/main/java/com/facebook/presto/common/type/TypeUtils.java b/presto-common/src/main/java/com/facebook/presto/common/type/TypeUtils.java index d9d621fb2820..938e55bb1ec6 100644 --- a/presto-common/src/main/java/com/facebook/presto/common/type/TypeUtils.java +++ b/presto-common/src/main/java/com/facebook/presto/common/type/TypeUtils.java @@ -19,14 +19,6 @@ import io.airlift.slice.Slice; import io.airlift.slice.Slices; -import java.util.Map; -import java.util.Objects; -import java.util.stream.Collectors; - -import static java.util.Locale.ENGLISH; -import static java.util.stream.Collectors.toMap; -import static java.util.stream.Collectors.toSet; - public final class TypeUtils { public static final int NULL_HASH_CODE = 0; @@ -109,26 +101,4 @@ static void checkElementNotNull(boolean isNull, String errorMsg) throw new NotSupportedException(errorMsg); } } - - static void validateEnumMap(Map enumMap) - { - if (enumMap.containsKey(null)) { - throw new IllegalArgumentException("Enum cannot contain null key"); - } - int nUniqueAndNotNullValues = enumMap.values().stream() - .filter(Objects::nonNull).collect(toSet()).size(); - if (nUniqueAndNotNullValues != enumMap.size()) { - throw new IllegalArgumentException("Enum cannot contain null or duplicate values"); - } - int nCaseInsensitiveKeys = enumMap.keySet().stream().map(k -> k.toUpperCase(ENGLISH)).collect(Collectors.toSet()).size(); - if (nCaseInsensitiveKeys != enumMap.size()) { - throw new IllegalArgumentException("Enum cannot contain case-insensitive duplicate keys"); - } - } - - static Map normalizeEnumMap(Map entries) - { - return entries.entrySet().stream() - .collect(toMap(e -> e.getKey().toUpperCase(ENGLISH), Map.Entry::getValue)); - } } diff --git a/presto-common/src/main/java/com/facebook/presto/common/type/VarcharEnumType.java b/presto-common/src/main/java/com/facebook/presto/common/type/VarcharEnumType.java deleted file mode 100644 index 1933aec20046..000000000000 --- a/presto-common/src/main/java/com/facebook/presto/common/type/VarcharEnumType.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Licensed 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.facebook.presto.common.type; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.util.Comparator; -import java.util.Map; -import java.util.Objects; -import java.util.stream.Collectors; - -import static com.facebook.presto.common.type.TypeUtils.normalizeEnumMap; -import static com.facebook.presto.common.type.TypeUtils.validateEnumMap; -import static com.facebook.presto.common.type.VarcharType.VARCHAR; -import static java.lang.String.format; - -public class VarcharEnumType - extends AbstractVarcharType - implements EnumType -{ - private final VarcharEnumMap enumMap; - - public VarcharEnumType(String name, VarcharEnumMap enumMap) - { - super(VarcharType.UNBOUNDED_LENGTH, new TypeSignature(name, TypeSignatureParameter.of(enumMap))); - this.enumMap = enumMap; - } - - @Override - public Map getEnumMap() - { - return enumMap.getEnumMap(); - } - - @Override - public Type getValueType() - { - return VARCHAR; - } - - @Override - public String getDisplayName() - { - return getTypeSignature().getBase(); - } - - public static class VarcharEnumMap - { - private final Map enumMap; - - @JsonCreator - public VarcharEnumMap(@JsonProperty("enumMap") Map enumMap) - { - validateEnumMap(enumMap); - this.enumMap = normalizeEnumMap(enumMap); - } - - @JsonProperty - public Map getEnumMap() - { - return enumMap; - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - VarcharEnumMap other = (VarcharEnumMap) o; - - return Objects.equals(this.enumMap, other.enumMap); - } - - @Override - public String toString() - { - return "enum:varchar{" - + enumMap.entrySet() - .stream() - .sorted(Comparator.comparing(Map.Entry::getKey)) - .map(e -> format("\"%s\": \"%s\"", e.getKey().replaceAll("\"", "\"\""), e.getValue().replaceAll("\"", "\"\""))) - .collect(Collectors.joining(", ")) - + "}"; - } - - @Override - public int hashCode() - { - return Objects.hash(enumMap); - } - } -} diff --git a/presto-common/src/main/java/com/facebook/presto/common/type/VarcharType.java b/presto-common/src/main/java/com/facebook/presto/common/type/VarcharType.java index 92b0a7bde721..468f87c9cde6 100644 --- a/presto-common/src/main/java/com/facebook/presto/common/type/VarcharType.java +++ b/presto-common/src/main/java/com/facebook/presto/common/type/VarcharType.java @@ -13,11 +13,21 @@ */ package com.facebook.presto.common.type; +import com.facebook.presto.common.block.Block; +import com.facebook.presto.common.block.BlockBuilder; +import com.facebook.presto.common.function.SqlFunctionProperties; +import io.airlift.slice.Slice; +import io.airlift.slice.Slices; + +import java.util.Objects; + import static java.util.Collections.singletonList; public final class VarcharType - extends AbstractVarcharType + extends AbstractVariableWidthType { + public static final int UNBOUNDED_LENGTH = Integer.MAX_VALUE; + public static final int MAX_LENGTH = Integer.MAX_VALUE - 1; public static final VarcharType VARCHAR = new VarcharType(UNBOUNDED_LENGTH); public static VarcharType createUnboundedVarcharType() @@ -39,12 +49,163 @@ public static TypeSignature getParametrizedVarcharSignature(String param) return new TypeSignature(StandardTypes.VARCHAR, TypeSignatureParameter.of(param)); } + private final int length; + private VarcharType(int length) { super( - length, new TypeSignature( StandardTypes.VARCHAR, - singletonList(TypeSignatureParameter.of((long) length)))); + singletonList(TypeSignatureParameter.of((long) length))), + Slice.class); + + if (length < 0) { + throw new IllegalArgumentException("Invalid VARCHAR length " + length); + } + this.length = length; + } + + @Deprecated + public int getLength() + { + return length; + } + + public int getLengthSafe() + { + if (isUnbounded()) { + throw new IllegalStateException("Cannot get size of unbounded VARCHAR."); + } + return length; + } + + public boolean isUnbounded() + { + return length == UNBOUNDED_LENGTH; + } + + @Override + public boolean isComparable() + { + return true; + } + + @Override + public boolean isOrderable() + { + return true; + } + + @Override + public Object getObjectValue(SqlFunctionProperties properties, Block block, int position) + { + if (block.isNull(position)) { + return null; + } + + return block.getSlice(position, 0, block.getSliceLength(position)).toStringUtf8(); + } + + @Override + public boolean equalTo(Block leftBlock, int leftPosition, Block rightBlock, int rightPosition) + { + int leftLength = leftBlock.getSliceLength(leftPosition); + int rightLength = rightBlock.getSliceLength(rightPosition); + if (leftLength != rightLength) { + return false; + } + return leftBlock.equals(leftPosition, 0, rightBlock, rightPosition, 0, leftLength); + } + + @Override + public long hash(Block block, int position) + { + return block.hash(position, 0, block.getSliceLength(position)); + } + + @Override + public int compareTo(Block leftBlock, int leftPosition, Block rightBlock, int rightPosition) + { + int leftLength = leftBlock.getSliceLength(leftPosition); + int rightLength = rightBlock.getSliceLength(rightPosition); + return leftBlock.compareTo(leftPosition, 0, leftLength, rightBlock, rightPosition, 0, rightLength); + } + + @Override + public void appendTo(Block block, int position, BlockBuilder blockBuilder) + { + if (block.isNull(position)) { + blockBuilder.appendNull(); + } + else { + block.writeBytesTo(position, 0, block.getSliceLength(position), blockBuilder); + blockBuilder.closeEntry(); + } + } + + @Override + public Slice getSlice(Block block, int position) + { + return block.getSlice(position, 0, block.getSliceLength(position)); + } + + @Override + public Slice getSliceUnchecked(Block block, int internalPosition) + { + return block.getSliceUnchecked(internalPosition, 0, block.getSliceLengthUnchecked(internalPosition)); + } + + public void writeString(BlockBuilder blockBuilder, String value) + { + writeSlice(blockBuilder, Slices.utf8Slice(value)); + } + + @Override + public void writeSlice(BlockBuilder blockBuilder, Slice value) + { + writeSlice(blockBuilder, value, 0, value.length()); + } + + @Override + public void writeSlice(BlockBuilder blockBuilder, Slice value, int offset, int length) + { + blockBuilder.writeBytes(value, offset, length).closeEntry(); + } + + @Override + public boolean equals(Object o) + { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + VarcharType other = (VarcharType) o; + + return Objects.equals(this.length, other.length); + } + + @Override + public int hashCode() + { + return Objects.hash(length); + } + + @Override + public String getDisplayName() + { + if (length == UNBOUNDED_LENGTH) { + return getTypeSignature().getBase(); + } + + return getTypeSignature().toString(); + } + + @Override + public String toString() + { + return getDisplayName(); } } diff --git a/presto-common/src/test/java/com/facebook/presto/common/type/TestTypeSignature.java b/presto-common/src/test/java/com/facebook/presto/common/type/TestTypeSignature.java index 8dce48a338dc..d9302480d388 100644 --- a/presto-common/src/test/java/com/facebook/presto/common/type/TestTypeSignature.java +++ b/presto-common/src/test/java/com/facebook/presto/common/type/TestTypeSignature.java @@ -13,10 +13,7 @@ */ package com.facebook.presto.common.type; -import com.facebook.presto.common.type.LongEnumType.LongEnumMap; -import com.facebook.presto.common.type.VarcharEnumType.VarcharEnumMap; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import org.testng.annotations.Test; @@ -292,53 +289,6 @@ public void testIsCalculated() assertFalse(parseTypeSignature("row(a decimal(2,1),b decimal(3,2))").isCalculated()); } - @Test - public void testEnumSignature() - { - assertEquals( - parseTypeSignature("test_enum(enum:varchar{\"test\" :\"\"\"\", \"hello\": \" \" , \"a\":\"}{{\" })"), - new VarcharEnumType("test_enum", new VarcharEnumMap(ImmutableMap.of("a", "}{{", "hello", " ", "test", "\""))).getTypeSignature()); - - assertEquals( - parseTypeSignature("test_enum(enum:varchar{\"my key\" :\"मूल्य\"})"), - new VarcharEnumType("test_enum", new VarcharEnumMap(ImmutableMap.of("my key", "मूल्य"))).getTypeSignature()); - - assertEquals( - parseTypeSignature("other_enum(ENUM:bigint{\"hello\" : -5, \"AaA\" : 9999 })"), - new LongEnumType("other_enum", new LongEnumMap(ImmutableMap.of("hello", -5L, "AAA", 9999L))).getTypeSignature()); - - assertEquals( - parseTypeSignature("my_enum(enum:varchar{\"))(\" :\"){}\"})"), - new VarcharEnumType("my_enum", new VarcharEnumMap(ImmutableMap.of("))(", "){}"))).getTypeSignature()); - - assertEquals( - parseTypeSignature("map(my_enum(enum:varchar{\"k\": \"v)))\"}), my_enum_2(enum:bigint{\"k\": 1}))"), - new TypeSignature( - StandardTypes.MAP, - TypeSignatureParameter.of((new VarcharEnumType("my_enum", new VarcharEnumMap(ImmutableMap.of("k", "v)))"))).getTypeSignature())), - TypeSignatureParameter.of(new LongEnumType("my_enum_2", new LongEnumMap(ImmutableMap.of("k", 1L))).getTypeSignature()))); - - assertSignatureFail("test_enum(enum:bigint{\"k\"})"); // no value - assertSignatureFail("test_enum(enum:bigint{\"k\", 2})"); // `,` instead of `:` - assertSignatureFail("test_enum(enum:bigint{})"); // empty map - assertSignatureFail("test_enum(enum:bigint{a: 2})"); // no quotes around key - assertSignatureFail("test_enum(enum:varchar{\"a\" \"b\"})"); // missing `:` - assertSignatureFail("test_enum(enum:varchar{:\"a\"})"); // missing key before `:` - assertSignatureFail("test_enum(enum:varchar{,\"a\"})"); // missing key before `,` - assertSignatureFail("test_enum(enum:bigint{{\"a\": 2})"); // extra `{` - assertSignatureFail("test_enum(enum:bigint{\"a\":: 2})"); // extra `:` - assertSignatureFail("t(enum:bigint{\"k\": {\"k1\": 1}})"); // nested enum - assertSignatureFail("test_enum(enum:bigint{\"k\": 2}haha)"); // extra input after `}` - assertSignatureFail("test_enum(enum:varchar{\"k\": 2})"); // long value for varchar enum - assertSignatureFail("test_enum(enum:bigint{\"k\": \"2\"})"); // varchar value for long enum - assertSignatureFail("test_enum(enum:bigint{\"k\": 2-})"); // invalid number - assertSignatureFail("test_enum(enum:bigint{\"k\": -})"); // invalid number - assertSignatureFail("test_enum(enum:bigint{\"k\": 2.29})"); // decimal value - assertSignatureFail("test_enum(enum:bigint{\"k\": \"2})"); // missing closing `"` - assertSignatureFail("test_enum(enum:varchar{\"k\": \"2\")"); // missing closing `}` - assertSignatureFail("test_enum(enum:bigint{\"k\": \"2\"}"); // missing closing `)` - } - private static void assertRowSignature( String typeName, Set literalParameters, @@ -380,7 +330,7 @@ private void assertSignatureFail(String typeName) { try { parseTypeSignature(typeName); - fail("Type signature should fail to parse"); + fail("Type signatures with zero parameters should fail to parse"); } catch (RuntimeException e) { // Expected @@ -391,7 +341,7 @@ private void assertSignatureFail(String typeName, Set literalCalculation { try { parseTypeSignature(typeName, literalCalculationParameters); - fail("Type signature should fail to parse"); + fail("Type signatures with zero parameters should fail to parse"); } catch (RuntimeException e) { // Expected diff --git a/presto-main/src/main/java/com/facebook/presto/type/LongEnumParametricType.java b/presto-main/src/main/java/com/facebook/presto/type/LongEnumParametricType.java deleted file mode 100644 index fa6940ae1f9a..000000000000 --- a/presto-main/src/main/java/com/facebook/presto/type/LongEnumParametricType.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Licensed 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.facebook.presto.type; - -import com.facebook.presto.common.type.LongEnumType; -import com.facebook.presto.common.type.LongEnumType.LongEnumMap; -import com.facebook.presto.common.type.ParameterKind; -import com.facebook.presto.common.type.ParametricType; -import com.facebook.presto.common.type.Type; -import com.facebook.presto.common.type.TypeManager; -import com.facebook.presto.common.type.TypeParameter; - -import java.util.List; - -import static com.google.common.base.Preconditions.checkArgument; - -public final class LongEnumParametricType - implements ParametricType -{ - private final String name; - private final LongEnumMap enumMap; - - public LongEnumParametricType(String name, LongEnumMap enumMap) - { - this.name = name; - this.enumMap = enumMap; - } - - @Override - public String getName() - { - return name; - } - - @Override - public Type createType(TypeManager typeManager, List parameters) - { - if (parameters.isEmpty()) { - return new LongEnumType(name, enumMap); - } - checkArgument(parameters.size() == 1, "Enum type expects exactly one parameter, got %s", parameters); - checkArgument( - parameters.get(0).getKind() == ParameterKind.LONG_ENUM, - "Enum definition expected, got %s", - parameters); - return new LongEnumType(name, parameters.get(0).getLongEnumMap()); - } -} diff --git a/presto-main/src/main/java/com/facebook/presto/type/VarcharEnumParametricType.java b/presto-main/src/main/java/com/facebook/presto/type/VarcharEnumParametricType.java deleted file mode 100644 index 8b6417164746..000000000000 --- a/presto-main/src/main/java/com/facebook/presto/type/VarcharEnumParametricType.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Licensed 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.facebook.presto.type; - -import com.facebook.presto.common.type.ParameterKind; -import com.facebook.presto.common.type.ParametricType; -import com.facebook.presto.common.type.Type; -import com.facebook.presto.common.type.TypeManager; -import com.facebook.presto.common.type.TypeParameter; -import com.facebook.presto.common.type.VarcharEnumType; -import com.facebook.presto.common.type.VarcharEnumType.VarcharEnumMap; - -import java.util.List; - -import static com.google.common.base.Preconditions.checkArgument; - -public final class VarcharEnumParametricType - implements ParametricType -{ - private final String name; - private final VarcharEnumMap enumMap; - - public VarcharEnumParametricType(String name, VarcharEnumMap enumMap) - { - this.name = name; - this.enumMap = enumMap; - } - - @Override - public String getName() - { - return name; - } - - @Override - public Type createType(TypeManager typeManager, List parameters) - { - if (parameters.isEmpty()) { - return new VarcharEnumType(name, enumMap); - } - checkArgument(parameters.size() == 1, "Enum type expects exactly one parameter, got %s", parameters); - checkArgument( - parameters.get(0).getKind() == ParameterKind.VARCHAR_ENUM, - "Enum definition expected, got %s", - parameters); - return new VarcharEnumType(name, parameters.get(0).getVarcharEnumMap()); - } -}