You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flink.apache.org by tw...@apache.org on 2019/05/29 06:19:31 UTC

[flink] 01/05: [hotfix][table-common] Update CHAR and BINARY in accordance with the SQL standard

This is an automated email from the ASF dual-hosted git repository.

twalthr pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/flink.git

commit 5b91db9fe01066980be78df9e8e8f177c8bc6543
Author: Timo Walther <tw...@apache.org>
AuthorDate: Mon May 27 11:47:13 2019 +0200

    [hotfix][table-common] Update CHAR and BINARY in accordance with the SQL standard
---
 .../java/org/apache/flink/table/api/DataTypes.java |  2 +-
 .../flink/table/types/logical/BinaryType.java      | 26 ++++++++++++++++-
 .../apache/flink/table/types/logical/CharType.java | 33 ++++++++++++++++++----
 .../apache/flink/table/types/LogicalTypesTest.java |  2 +-
 4 files changed, 55 insertions(+), 8 deletions(-)

diff --git a/flink-table/flink-table-common/src/main/java/org/apache/flink/table/api/DataTypes.java b/flink-table/flink-table-common/src/main/java/org/apache/flink/table/api/DataTypes.java
index dc7c319..288a2f6 100644
--- a/flink-table/flink-table-common/src/main/java/org/apache/flink/table/api/DataTypes.java
+++ b/flink-table/flink-table-common/src/main/java/org/apache/flink/table/api/DataTypes.java
@@ -81,7 +81,7 @@ public final class DataTypes {
 
 	/**
 	 * Data type of a fixed-length character string {@code CHAR(n)} where {@code n} is the number
-	 * of code points. {@code n} must have a value between 1 and 255 (both inclusive).
+	 * of code points. {@code n} must have a value between 1 and {@link Integer#MAX_VALUE} (both inclusive).
 	 *
 	 * @see CharType
 	 */
diff --git a/flink-table/flink-table-common/src/main/java/org/apache/flink/table/types/logical/BinaryType.java b/flink-table/flink-table-common/src/main/java/org/apache/flink/table/types/logical/BinaryType.java
index e342d9e..25dbcd4 100644
--- a/flink-table/flink-table-common/src/main/java/org/apache/flink/table/types/logical/BinaryType.java
+++ b/flink-table/flink-table-common/src/main/java/org/apache/flink/table/types/logical/BinaryType.java
@@ -32,10 +32,15 @@ import java.util.Set;
  * <p>The serialized string representation is {@code BINARY(n)} where {@code n} is the number of
  * bytes. {@code n} must have a value between 1 and {@link Integer#MAX_VALUE} (both inclusive). If
  * no length is specified, {@code n} is equal to 1.
+ *
+ * <p>For expressing a zero-length binary string literal, this type does also support {@code n} to
+ * be 0. However, this is not exposed through the API.
  */
 @PublicEvolving
 public final class BinaryType extends LogicalType {
 
+	public static final int EMPTY_LITERAL_LENGTH = 0;
+
 	public static final int MIN_LENGTH = 1;
 
 	public static final int MAX_LENGTH = Integer.MAX_VALUE;
@@ -72,13 +77,32 @@ public final class BinaryType extends LogicalType {
 		this(DEFAULT_LENGTH);
 	}
 
+	/**
+	 * Helper constructor for {@link #ofEmptyLiteral()} and {@link #copy(boolean)}.
+	 */
+	private BinaryType(int length, boolean isNullable) {
+		super(isNullable, LogicalTypeRoot.BINARY);
+		this.length = length;
+	}
+
+	/**
+	 * The SQL standard defines that character string literals are allowed to be zero-length strings
+	 * (i.e., to contain no characters) even though it is not permitted to declare a type that is zero.
+	 * For consistent behavior, the same logic applies to binary strings.
+	 *
+	 * <p>This method enables this special kind of binary string.
+	 */
+	public static BinaryType ofEmptyLiteral() {
+		return new BinaryType(EMPTY_LITERAL_LENGTH, false);
+	}
+
 	public int getLength() {
 		return length;
 	}
 
 	@Override
 	public LogicalType copy(boolean isNullable) {
-		return new BinaryType(isNullable, length);
+		return new BinaryType(length, isNullable);
 	}
 
 	@Override
diff --git a/flink-table/flink-table-common/src/main/java/org/apache/flink/table/types/logical/CharType.java b/flink-table/flink-table-common/src/main/java/org/apache/flink/table/types/logical/CharType.java
index fe870ce..8385d05 100644
--- a/flink-table/flink-table-common/src/main/java/org/apache/flink/table/types/logical/CharType.java
+++ b/flink-table/flink-table-common/src/main/java/org/apache/flink/table/types/logical/CharType.java
@@ -30,17 +30,22 @@ import java.util.Set;
  * Logical type of a fixed-length character string.
  *
  * <p>The serialized string representation is {@code CHAR(n)} where {@code n} is the number of
- * code points. {@code n} must have a value between 1 and 255 (both inclusive). If no length is
- * specified, {@code n} is equal to 1.
+ * code points. {@code n} must have a value between 1 and {@link Integer#MAX_VALUE} (both inclusive).
+ * If no length is specified, {@code n} is equal to 1.
+ *
+ * <p>For expressing a zero-length character string literal, this type does also support {@code n}
+ * to be 0. However, this is not exposed through the API.
  *
  * <p>A conversion from and to {@code byte[]} assumes UTF-8 encoding.
  */
 @PublicEvolving
 public final class CharType extends LogicalType {
 
+	public static final int EMPTY_LITERAL_LENGTH = 0;
+
 	public static final int MIN_LENGTH = 1;
 
-	public static final int MAX_LENGTH = 255;
+	public static final int MAX_LENGTH = Integer.MAX_VALUE;
 
 	public static final int DEFAULT_LENGTH = 1;
 
@@ -57,7 +62,7 @@ public final class CharType extends LogicalType {
 
 	public CharType(boolean isNullable, int length) {
 		super(isNullable, LogicalTypeRoot.CHAR);
-		if (length < MIN_LENGTH || length > MAX_LENGTH) {
+		if (length < MIN_LENGTH) {
 			throw new ValidationException(
 				String.format(
 					"Character string length must be between %d and %d (both inclusive).",
@@ -75,13 +80,31 @@ public final class CharType extends LogicalType {
 		this(DEFAULT_LENGTH);
 	}
 
+	/**
+	 * Helper constructor for {@link #ofEmptyLiteral()} and {@link #copy(boolean)}.
+	 */
+	private CharType(int length, boolean isNullable) {
+		super(isNullable, LogicalTypeRoot.CHAR);
+		this.length = length;
+	}
+
+	/**
+	 * The SQL standard defines that character string literals are allowed to be zero-length strings
+	 * (i.e., to contain no characters) even though it is not permitted to declare a type that is zero.
+	 *
+	 * <p>This method enables this special kind of character string.
+	 */
+	public static CharType ofEmptyLiteral() {
+		return new CharType(EMPTY_LITERAL_LENGTH, false);
+	}
+
 	public int getLength() {
 		return length;
 	}
 
 	@Override
 	public LogicalType copy(boolean isNullable) {
-		return new CharType(isNullable, length);
+		return new CharType(length, isNullable);
 	}
 
 	@Override
diff --git a/flink-table/flink-table-common/src/test/java/org/apache/flink/table/types/LogicalTypesTest.java b/flink-table/flink-table-common/src/test/java/org/apache/flink/table/types/LogicalTypesTest.java
index 853d37f..600b718 100644
--- a/flink-table/flink-table-common/src/test/java/org/apache/flink/table/types/LogicalTypesTest.java
+++ b/flink-table/flink-table-common/src/test/java/org/apache/flink/table/types/LogicalTypesTest.java
@@ -86,7 +86,7 @@ public class LogicalTypesTest {
 			new Class[]{String.class, byte[].class},
 			new Class[]{String.class, byte[].class},
 			new LogicalType[]{},
-			new CharType(12)
+			new CharType(Integer.MAX_VALUE)
 		);
 	}