diff --git a/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFOPEqualNS.java b/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFOPEqualNS.java index 3707a33..7574d2c 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFOPEqualNS.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFOPEqualNS.java @@ -40,4 +40,9 @@ public Object evaluate(DeferredObject[] arguments) throws HiveException { } return super.evaluate(arguments); } + + @Override + public GenericUDF negative() { + return new GenericUDFOPNotEqualNS(); + } } diff --git a/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFOPNotEqualNS.java b/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFOPNotEqualNS.java new file mode 100644 index 0000000..4e89423 --- /dev/null +++ b/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFOPNotEqualNS.java @@ -0,0 +1,45 @@ +/** + * 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.hadoop.hive.ql.udf.generic; + +import org.apache.hadoop.hive.ql.metadata.HiveException; + +// this function is for internal use only +public class GenericUDFOPNotEqualNS extends GenericUDFOPNotEqual { + + @Override + public Object evaluate(DeferredObject[] arguments) throws HiveException { + Object o0 = arguments[0].get(); + Object o1 = arguments[1].get(); + if (o0 == null && o1 == null) { + result.set(false); + return result; + } + if (o0 == null || o1 == null) { + result.set(true); + return result; + } + return super.evaluate(arguments); + } + + @Override + public GenericUDF negative() { + return new GenericUDFOPEqualNS(); + } +} diff --git a/ql/src/test/queries/clientpositive/equal_ns.q b/ql/src/test/queries/clientpositive/equal_ns.q new file mode 100644 index 0000000..910d089 --- /dev/null +++ b/ql/src/test/queries/clientpositive/equal_ns.q @@ -0,0 +1,6 @@ +set hive.mapred.mode=nonstrict; +-- SORT_QUERY_RESULTS + +create table test(x string, y string); +insert into test values ('q', 'q'), ('q', 'w'), (NULL, 'q'), ('q', NULL), (NULL, NULL); +select *, x<=>y, not (x<=> y), (x <=> y) = false from test; diff --git a/ql/src/test/results/clientpositive/equal_ns.q.out b/ql/src/test/results/clientpositive/equal_ns.q.out new file mode 100644 index 0000000..6a38c05 --- /dev/null +++ b/ql/src/test/results/clientpositive/equal_ns.q.out @@ -0,0 +1,29 @@ +PREHOOK: query: create table test(x string, y string) +PREHOOK: type: CREATETABLE +PREHOOK: Output: database:default +PREHOOK: Output: default@test +POSTHOOK: query: create table test(x string, y string) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: database:default +POSTHOOK: Output: default@test +PREHOOK: query: insert into test values ('q', 'q'), ('q', 'w'), (NULL, 'q'), ('q', NULL), (NULL, NULL) +PREHOOK: type: QUERY +PREHOOK: Output: default@test +POSTHOOK: query: insert into test values ('q', 'q'), ('q', 'w'), (NULL, 'q'), ('q', NULL), (NULL, NULL) +POSTHOOK: type: QUERY +POSTHOOK: Output: default@test +POSTHOOK: Lineage: test.x SIMPLE [(values__tmp__table__1)values__tmp__table__1.FieldSchema(name:tmp_values_col1, type:string, comment:), ] +POSTHOOK: Lineage: test.y SIMPLE [(values__tmp__table__1)values__tmp__table__1.FieldSchema(name:tmp_values_col2, type:string, comment:), ] +PREHOOK: query: select *, x<=>y, not (x<=> y), (x <=> y) = false from test +PREHOOK: type: QUERY +PREHOOK: Input: default@test +#### A masked pattern was here #### +POSTHOOK: query: select *, x<=>y, not (x<=> y), (x <=> y) = false from test +POSTHOOK: type: QUERY +POSTHOOK: Input: default@test +#### A masked pattern was here #### +NULL NULL true false false +NULL q false true true +q NULL false true true +q q true false false +q w false true true