diff --git a/itests/src/test/resources/testconfiguration.properties b/itests/src/test/resources/testconfiguration.properties index a3a70ecd49..a66ec412a0 100644 --- a/itests/src/test/resources/testconfiguration.properties +++ b/itests/src/test/resources/testconfiguration.properties @@ -468,6 +468,7 @@ minillaplocal.query.files=\ runtime_stats_hs2.q,\ bucketsortoptimize_insert_2.q,\ change_allowincompatible_vectorization_false_date.q,\ + char_trailing_space.q,\ check_constraint.q,\ cbo_gby.q,\ cbo_join.q,\ diff --git a/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFCharacterLength.java b/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFCharacterLength.java index ce6cd301d7..30c40d39da 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFCharacterLength.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFCharacterLength.java @@ -27,6 +27,7 @@ import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorConverter; import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory; +import org.apache.hadoop.hive.serde2.typeinfo.CharTypeInfo; import org.apache.hadoop.io.BytesWritable; import org.apache.hadoop.io.IntWritable; @@ -40,6 +41,7 @@ private transient PrimitiveObjectInspector argumentOI; private transient PrimitiveObjectInspectorConverter.StringConverter stringConverter; private transient boolean isInputString; + private transient boolean isInputFixedLength; @Override public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException { @@ -59,6 +61,8 @@ public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumen ObjectInspector outputOI = null; switch (inputType) { case CHAR: + isInputFixedLength = true; + result.set(((CharTypeInfo) argumentOI.getTypeInfo()).getLength()); case VARCHAR: case STRING: isInputString = true; @@ -90,6 +94,11 @@ public Object evaluate(DeferredObject[] arguments) throws HiveException { return null; } + // For char, we do not need to explore the data + if (isInputFixedLength) { + return result; + } + data = val.getBytes(); } else { BytesWritable val = null; diff --git a/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFLength.java b/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFLength.java index f4ac350b71..f9ca15d5bd 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFLength.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFLength.java @@ -28,6 +28,7 @@ import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorConverter; import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory; +import org.apache.hadoop.hive.serde2.typeinfo.CharTypeInfo; import org.apache.hadoop.io.BytesWritable; import org.apache.hadoop.io.IntWritable; @@ -46,6 +47,7 @@ private transient PrimitiveObjectInspectorConverter.StringConverter stringConverter; private transient PrimitiveObjectInspectorConverter.BinaryConverter binaryConverter; private transient boolean isInputString; + private transient boolean isInputFixedLength; @Override public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException { @@ -64,6 +66,8 @@ public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumen ObjectInspector outputOI = null; switch (inputType) { case CHAR: + isInputFixedLength = true; + result.set(((CharTypeInfo) argumentOI.getTypeInfo()).getLength()); case VARCHAR: case STRING: isInputString = true; @@ -98,6 +102,11 @@ public Object evaluate(DeferredObject[] arguments) throws HiveException { return null; } + // For char, we do not need to explore the data + if (isInputFixedLength) { + return result; + } + data = val.getBytes(); int len = 0; diff --git a/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFOctetLength.java b/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFOctetLength.java index 825066fc02..2a39ebb63b 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFOctetLength.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFOctetLength.java @@ -27,6 +27,7 @@ import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorConverter; import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory; +import org.apache.hadoop.hive.serde2.typeinfo.CharTypeInfo; import org.apache.hadoop.io.BytesWritable; import org.apache.hadoop.io.IntWritable; @@ -40,6 +41,7 @@ private transient PrimitiveObjectInspector argumentOI; private transient PrimitiveObjectInspectorConverter.StringConverter stringConverter; private transient boolean isInputString; + private transient boolean isInputFixedLength; @Override public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException { @@ -59,6 +61,8 @@ public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumen ObjectInspector outputOI = null; switch (inputType) { case CHAR: + isInputFixedLength = true; + result.set(((CharTypeInfo) argumentOI.getTypeInfo()).getLength()); case VARCHAR: case STRING: isInputString = true; @@ -90,6 +94,11 @@ public Object evaluate(GenericUDF.DeferredObject[] arguments) throws HiveExcepti return null; } + // For char, we do not need to explore the data + if (isInputFixedLength) { + return result; + } + data = val.getBytes(); } else { BytesWritable val = null; diff --git a/ql/src/test/queries/clientpositive/char_trailing_space.q b/ql/src/test/queries/clientpositive/char_trailing_space.q new file mode 100644 index 0000000000..a8fb6d06cb --- /dev/null +++ b/ql/src/test/queries/clientpositive/char_trailing_space.q @@ -0,0 +1,8 @@ +create table char_trailing_space(a char(2), b varchar(2)); +insert into char_trailing_space values('L ', 'L '); + +select length(a),length(b) from char_trailing_space; +select character_length(a),character_length(b) from char_trailing_space; +select octet_length(a),octet_length(b) from char_trailing_space; + +drop table char_trailing_space; diff --git a/ql/src/test/results/clientpositive/llap/char_trailing_space.q.out b/ql/src/test/results/clientpositive/llap/char_trailing_space.q.out new file mode 100644 index 0000000000..cea90f7889 --- /dev/null +++ b/ql/src/test/results/clientpositive/llap/char_trailing_space.q.out @@ -0,0 +1,53 @@ +PREHOOK: query: create table char_trailing_space(a char(2), b varchar(2)) +PREHOOK: type: CREATETABLE +PREHOOK: Output: database:default +PREHOOK: Output: default@char_trailing_space +POSTHOOK: query: create table char_trailing_space(a char(2), b varchar(2)) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: database:default +POSTHOOK: Output: default@char_trailing_space +PREHOOK: query: insert into char_trailing_space values('L ', 'L ') +PREHOOK: type: QUERY +PREHOOK: Input: _dummy_database@_dummy_table +PREHOOK: Output: default@char_trailing_space +POSTHOOK: query: insert into char_trailing_space values('L ', 'L ') +POSTHOOK: type: QUERY +POSTHOOK: Input: _dummy_database@_dummy_table +POSTHOOK: Output: default@char_trailing_space +POSTHOOK: Lineage: char_trailing_space.a SCRIPT [] +POSTHOOK: Lineage: char_trailing_space.b SCRIPT [] +PREHOOK: query: select length(a),length(b) from char_trailing_space +PREHOOK: type: QUERY +PREHOOK: Input: default@char_trailing_space +#### A masked pattern was here #### +POSTHOOK: query: select length(a),length(b) from char_trailing_space +POSTHOOK: type: QUERY +POSTHOOK: Input: default@char_trailing_space +#### A masked pattern was here #### +2 2 +PREHOOK: query: select character_length(a),character_length(b) from char_trailing_space +PREHOOK: type: QUERY +PREHOOK: Input: default@char_trailing_space +#### A masked pattern was here #### +POSTHOOK: query: select character_length(a),character_length(b) from char_trailing_space +POSTHOOK: type: QUERY +POSTHOOK: Input: default@char_trailing_space +#### A masked pattern was here #### +2 2 +PREHOOK: query: select octet_length(a),octet_length(b) from char_trailing_space +PREHOOK: type: QUERY +PREHOOK: Input: default@char_trailing_space +#### A masked pattern was here #### +POSTHOOK: query: select octet_length(a),octet_length(b) from char_trailing_space +POSTHOOK: type: QUERY +POSTHOOK: Input: default@char_trailing_space +#### A masked pattern was here #### +2 2 +PREHOOK: query: drop table char_trailing_space +PREHOOK: type: DROPTABLE +PREHOOK: Input: default@char_trailing_space +PREHOOK: Output: default@char_trailing_space +POSTHOOK: query: drop table char_trailing_space +POSTHOOK: type: DROPTABLE +POSTHOOK: Input: default@char_trailing_space +POSTHOOK: Output: default@char_trailing_space