This is an automated email from the ASF dual-hosted git repository.
krisztiankasa pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hive.git
The following commit(s) were added to refs/heads/master by this push:
new 5bec1edeb26 HIVE-27264: Literals in conjunction of two IN expression
are considered not equals if type precision is different (Krisztian Kasa,
reviewed by Stamatis Zampetakis, Aman Sinha, Laszlo Vegh)
5bec1edeb26 is described below
commit 5bec1edeb269383416c37b16f67b2b8ff522df41
Author: Krisztian Kasa <[email protected]>
AuthorDate: Fri Apr 21 10:50:01 2023 +0200
HIVE-27264: Literals in conjunction of two IN expression are considered not
equals if type precision is different (Krisztian Kasa, reviewed by Stamatis
Zampetakis, Aman Sinha, Laszlo Vegh)
---
.../rules/HivePointLookupOptimizerRule.java | 80 ++++++++--
.../rules/TestHivePointLookupOptimizerRule.java | 171 +++++++++++++++++++++
ql/src/test/queries/clientpositive/pointlookup6.q | 19 +++
.../results/clientpositive/llap/pointlookup6.q.out | 79 ++++++++++
4 files changed, 333 insertions(+), 16 deletions(-)
diff --git
a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HivePointLookupOptimizerRule.java
b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HivePointLookupOptimizerRule.java
index a351a3d4952..bd43b7d6437 100644
---
a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HivePointLookupOptimizerRule.java
+++
b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HivePointLookupOptimizerRule.java
@@ -27,6 +27,7 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -41,6 +42,7 @@ import org.apache.calcite.rel.core.Join;
import org.apache.calcite.rel.core.Project;
import org.apache.calcite.rex.RexBuilder;
import org.apache.calcite.rex.RexCall;
+import org.apache.calcite.rex.RexLiteral;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.rex.RexShuttle;
import org.apache.calcite.rex.RexUtil;
@@ -592,7 +594,7 @@ public abstract class HivePointLookupOptimizerRule extends
RelOptRule {
// Visited nodes
final Set<RexNode> visitedRefs = new LinkedHashSet<>();
// IN clauses need to be combined by keeping only common elements
- final Multimap<RexNode,RexNode> inLHSExprToRHSExprs =
LinkedHashMultimap.create();
+ final Multimap<RexNode,SimilarRexNodeElement> inLHSExprToRHSExprs =
LinkedHashMultimap.create();
// We will use this set to keep those expressions that may evaluate
// into a null value.
final Multimap<RexNode,RexNode> inLHSExprToRHSNullableExprs =
LinkedHashMultimap.create();
@@ -611,15 +613,15 @@ public abstract class HivePointLookupOptimizerRule
extends RelOptRule {
inLHSExprToRHSNullableExprs.put(ref, ref);
}
if (inLHSExprToRHSExprs.containsKey(ref)) {
- Set<RexNode> expressions = Sets.newHashSet();
+ Set<SimilarRexNodeElement> expressions = Sets.newHashSet();
for (int j = 1; j < inCall.getOperands().size(); j++) {
RexNode constNode = inCall.getOperands().get(j);
- expressions.add(constNode);
+ expressions.add(new SimilarRexNodeElement(constNode));
if (constNode.getType().isNullable()) {
inLHSExprToRHSNullableExprs.put(ref, constNode);
}
}
- Collection<RexNode> knownConstants = inLHSExprToRHSExprs.get(ref);
+ Collection<SimilarRexNodeElement> knownConstants =
inLHSExprToRHSExprs.get(ref);
if (!shareSameType(knownConstants, expressions)) {
return call;
}
@@ -627,7 +629,7 @@ public abstract class HivePointLookupOptimizerRule extends
RelOptRule {
} else {
for (int j = 1; j < inCall.getOperands().size(); j++) {
RexNode constNode = inCall.getOperands().get(j);
- inLHSExprToRHSExprs.put(ref, constNode);
+ inLHSExprToRHSExprs.put(ref, new
SimilarRexNodeElement(constNode));
if (constNode.getType().isNullable()) {
inLHSExprToRHSNullableExprs.put(ref, constNode);
}
@@ -648,14 +650,14 @@ public abstract class HivePointLookupOptimizerRule
extends RelOptRule {
inLHSExprToRHSNullableExprs.put(c.exprNode, c.constNode);
}
if (inLHSExprToRHSExprs.containsKey(c.exprNode)) {
- Collection<RexNode> knownConstants =
inLHSExprToRHSExprs.get(c.exprNode);
- Collection<RexNode> nextConstant =
Collections.singleton(c.constNode);
+ Collection<SimilarRexNodeElement> knownConstants =
inLHSExprToRHSExprs.get(c.exprNode);
+ Collection<SimilarRexNodeElement> nextConstant =
Collections.singleton(new SimilarRexNodeElement(c.constNode));
if (!shareSameType(knownConstants, nextConstant)) {
return call;
}
knownConstants.retainAll(nextConstant);
} else {
- inLHSExprToRHSExprs.put(c.exprNode, c.constNode);
+ inLHSExprToRHSExprs.put(c.exprNode, new
SimilarRexNodeElement(c.constNode));
}
operands.remove(i);
--i;
@@ -669,6 +671,51 @@ public abstract class HivePointLookupOptimizerRule extends
RelOptRule {
return RexUtil.composeConjunction(rexBuilder, newOperands, false);
}
+ protected static class SimilarRexNodeElement {
+ private final RexNode rexNode;
+
+ protected SimilarRexNodeElement(RexNode rexNode) {
+ this.rexNode = rexNode;
+ }
+
+ public RexNode getRexNode() {
+ return rexNode;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ SimilarRexNodeElement that = (SimilarRexNodeElement) o;
+ return equalsWithSimilarType(rexNode, that.rexNode);
+ }
+
+ private static boolean equalsWithSimilarType(RexNode rexNode1, RexNode
rexNode2) {
+ if (!(rexNode1 instanceof RexLiteral) || !(rexNode2 instanceof
RexLiteral)) {
+ return rexNode1.equals(rexNode2);
+ }
+
+ RexLiteral rexLiteral1 = (RexLiteral) rexNode1;
+ RexLiteral rexLiteral2 = (RexLiteral) rexNode2;
+
+ if (rexLiteral1.getValue() == null && rexLiteral2.getValue() == null) {
+ return true;
+ }
+
+ return rexLiteral1.getValue() != null &&
rexLiteral1.getValue().compareTo(rexLiteral2.getValue()) == 0 &&
+
rexLiteral1.getType().getSqlTypeName().equals(rexLiteral2.getType().getSqlTypeName());
+ }
+
+ @Override
+ public int hashCode() {
+ if (rexNode instanceof RexLiteral) {
+ RexLiteral rexLiteral = (RexLiteral) rexNode;
+ return Objects.hash(rexLiteral.getValue(),
rexLiteral.getType().getSqlTypeName());
+ }
+ return Objects.hash(rexNode);
+ }
+ }
+
/**
* Check if the type of nodes in the two collections is homogeneous within
the collections
* and identical between them.
@@ -676,9 +723,10 @@ public abstract class HivePointLookupOptimizerRule extends
RelOptRule {
* @param nodes2 the second collection of nodes
* @return true if nodes in both collections is unique and identical,
false otherwise
*/
- private static boolean shareSameType(Collection<RexNode> nodes1,
Collection<RexNode> nodes2) {
+ private static boolean shareSameType(
+ Collection<SimilarRexNodeElement> nodes1,
Collection<SimilarRexNodeElement> nodes2) {
return Stream.of(nodes1, nodes2).flatMap(Collection::stream)
- .map(n -> n.getType().getSqlTypeName())
+ .map(n -> n.getRexNode().getType().getSqlTypeName())
.distinct()
.count() == 1;
}
@@ -686,7 +734,7 @@ public abstract class HivePointLookupOptimizerRule extends
RelOptRule {
private static RexNode handleOR(RexBuilder rexBuilder, RexCall call) {
// IN clauses need to be combined by keeping all elements
final List<RexNode> operands = new
ArrayList<>(RexUtil.flattenOr(call.getOperands()));
- final Multimap<RexNode,RexNode> inLHSExprToRHSExprs =
LinkedHashMultimap.create();
+ final Multimap<RexNode,SimilarRexNodeElement> inLHSExprToRHSExprs =
LinkedHashMultimap.create();
for (int i = 0; i < operands.size(); i++) {
RexNode operand = operands.get(i);
if (operand.getKind() == SqlKind.IN) {
@@ -696,7 +744,7 @@ public abstract class HivePointLookupOptimizerRule extends
RelOptRule {
}
RexNode ref = inCall.getOperands().get(0);
for (int j = 1; j < inCall.getOperands().size(); j++) {
- inLHSExprToRHSExprs.put(ref, inCall.getOperands().get(j));
+ inLHSExprToRHSExprs.put(ref, new
SimilarRexNodeElement(inCall.getOperands().get(j)));
}
operands.remove(i);
--i;
@@ -733,22 +781,22 @@ public abstract class HivePointLookupOptimizerRule
extends RelOptRule {
}
private static List<RexNode> createInClauses(RexBuilder rexBuilder,
Set<RexNode> visitedRefs,
- Multimap<RexNode, RexNode> inLHSExprToRHSExprs,
Multimap<RexNode,RexNode> inLHSExprToRHSNullableExprs) {
+ Multimap<RexNode, SimilarRexNodeElement> inLHSExprToRHSExprs,
Multimap<RexNode,RexNode> inLHSExprToRHSNullableExprs) {
final List<RexNode> newExpressions = new ArrayList<>();
for (RexNode ref : visitedRefs) {
- Collection<RexNode> exprs = inLHSExprToRHSExprs.get(ref);
+ Collection<SimilarRexNodeElement> exprs = inLHSExprToRHSExprs.get(ref);
if (exprs.isEmpty()) {
// Note that Multimap does not keep a key if all its values are
removed.
newExpressions.add(createResultFromEmptySet(rexBuilder, ref,
inLHSExprToRHSNullableExprs));
} else if (exprs.size() == 1) {
List<RexNode> newOperands = new ArrayList<>(2);
newOperands.add(ref);
- newOperands.add(exprs.iterator().next());
+ newOperands.add(exprs.iterator().next().getRexNode());
newExpressions.add(rexBuilder.makeCall(SqlStdOperatorTable.EQUALS,
newOperands));
} else {
List<RexNode> newOperands = new ArrayList<>(exprs.size() + 1);
newOperands.add(ref);
- newOperands.addAll(exprs);
+
newOperands.addAll(exprs.stream().map(SimilarRexNodeElement::getRexNode).collect(Collectors.toList()));
newExpressions.add(rexBuilder.makeCall(HiveIn.INSTANCE,
newOperands));
}
}
diff --git
a/ql/src/test/org/apache/hadoop/hive/ql/optimizer/calcite/rules/TestHivePointLookupOptimizerRule.java
b/ql/src/test/org/apache/hadoop/hive/ql/optimizer/calcite/rules/TestHivePointLookupOptimizerRule.java
index ba695f44af2..8e06699e316 100644
---
a/ql/src/test/org/apache/hadoop/hive/ql/optimizer/calcite/rules/TestHivePointLookupOptimizerRule.java
+++
b/ql/src/test/org/apache/hadoop/hive/ql/optimizer/calcite/rules/TestHivePointLookupOptimizerRule.java
@@ -21,17 +21,25 @@ package org.apache.hadoop.hive.ql.optimizer.calcite.rules;
import org.apache.calcite.plan.AbstractRelOptPlanner;
import org.apache.calcite.plan.RelOptSchema;
import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rex.RexBuilder;
import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.sql.SqlCollation;
+import org.apache.calcite.sql.fun.SqlStdOperatorTable;
+import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.calcite.tools.RelBuilder;
+import org.apache.calcite.util.ConversionUtil;
import org.apache.hadoop.hive.ql.metadata.Table;
import org.apache.hadoop.hive.ql.optimizer.calcite.RelOptHiveTable;
import org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveFilter;
+import org.apache.hadoop.hive.ql.parse.type.RexNodeExprFactory;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
+import java.nio.charset.Charset;
import java.util.Collections;
import static
org.apache.hadoop.hive.ql.optimizer.calcite.rules.TestRuleHelper.buildPlanner;
@@ -348,4 +356,167 @@ public class TestHivePointLookupOptimizerRule {
condition.toString());
}
+ @Test
+ public void testSameVarcharLiteralDifferentPrecision() {
+
+ final RexBuilder rexBuilder = relBuilder.getRexBuilder();
+ RelDataType stringType30 =
rexBuilder.getTypeFactory().createTypeWithCharsetAndCollation(
+ rexBuilder.getTypeFactory().createSqlType(SqlTypeName.VARCHAR, 30),
+ Charset.forName(ConversionUtil.NATIVE_UTF16_CHARSET_NAME),
SqlCollation.IMPLICIT);
+ RexNode lita30 =
rexBuilder.makeLiteral(RexNodeExprFactory.makeHiveUnicodeString("AAA111"),
stringType30, true);
+ RexNode litb30 =
rexBuilder.makeLiteral(RexNodeExprFactory.makeHiveUnicodeString("BBB222"),
stringType30, true);
+
+ RelDataType stringType14 =
rexBuilder.getTypeFactory().createTypeWithCharsetAndCollation(
+ rexBuilder.getTypeFactory().createSqlType(SqlTypeName.VARCHAR, 14),
+ Charset.forName(ConversionUtil.NATIVE_UTF16_CHARSET_NAME),
SqlCollation.IMPLICIT);
+ RexNode lita14 =
rexBuilder.makeLiteral(RexNodeExprFactory.makeHiveUnicodeString("AAA111"),
stringType14, true);
+ RexNode litb14 =
rexBuilder.makeLiteral(RexNodeExprFactory.makeHiveUnicodeString("BBB222"),
stringType14, true);
+
+ final RelNode basePlan = relBuilder
+ .scan("t")
+ .filter(and(relBuilder,
+ relBuilder.call(SqlStdOperatorTable.IN,
relBuilder.field("f2"), lita30, litb30),
+ relBuilder.call(SqlStdOperatorTable.IN,
relBuilder.field("f2"), lita14, litb14)))
+ .build();
+
+ planner.setRoot(basePlan);
+ RelNode optimizedRelNode = planner.findBestExp();
+
+ HiveFilter filter = (HiveFilter) optimizedRelNode;
+ RexNode condition = filter.getCondition();
+ System.out.println(condition);
+ assertEquals("IN($1, " +
+ "_UTF-16LE'AAA111':VARCHAR(30) CHARACTER SET \"UTF-16LE\",
" +
+ "_UTF-16LE'BBB222':VARCHAR(30) CHARACTER SET
\"UTF-16LE\")",
+ condition.toString());
+ }
+
+ @Test
+ public void testSameVarcharLiteralDifferentPrecisionValueOverflow() {
+
+ final RexBuilder rexBuilder = relBuilder.getRexBuilder();
+ RelDataType stringType30 =
rexBuilder.getTypeFactory().createTypeWithCharsetAndCollation(
+ rexBuilder.getTypeFactory().createSqlType(SqlTypeName.VARCHAR, 30),
+ Charset.forName(ConversionUtil.NATIVE_UTF16_CHARSET_NAME),
SqlCollation.IMPLICIT);
+ RexNode lita30 =
rexBuilder.makeLiteral(RexNodeExprFactory.makeHiveUnicodeString("AAA111"),
stringType30, true);
+ RexNode litb30 =
rexBuilder.makeLiteral(RexNodeExprFactory.makeHiveUnicodeString("BBB222"),
stringType30, true);
+
+ RelDataType stringType4 =
rexBuilder.getTypeFactory().createTypeWithCharsetAndCollation(
+ rexBuilder.getTypeFactory().createSqlType(SqlTypeName.VARCHAR, 4),
+ Charset.forName(ConversionUtil.NATIVE_UTF16_CHARSET_NAME),
SqlCollation.IMPLICIT);
+ RexNode litaOverflow =
+
rexBuilder.makeLiteral(RexNodeExprFactory.makeHiveUnicodeString("AAA111"),
stringType4, true);
+ RexNode litbOverflow =
+
rexBuilder.makeLiteral(RexNodeExprFactory.makeHiveUnicodeString("BBB222"),
stringType4, true);
+
+ final RelNode basePlan = relBuilder
+ .scan("t")
+ .filter(and(relBuilder,
+ relBuilder.call(SqlStdOperatorTable.IN,
relBuilder.field("f2"), lita30, litb30),
+ relBuilder.call(SqlStdOperatorTable.IN,
relBuilder.field("f2"), litaOverflow, litbOverflow)))
+ .build();
+
+ planner.setRoot(basePlan);
+ RelNode optimizedRelNode = planner.findBestExp();
+
+ HiveFilter filter = (HiveFilter) optimizedRelNode;
+ RexNode condition = filter.getCondition();
+ System.out.println(condition);
+ assertEquals("false", condition.toString());
+ }
+
+ @Test
+ public void testSameVarcharAndNullLiterals() {
+
+ final RexBuilder rexBuilder = relBuilder.getRexBuilder();
+ RelDataType stringType30 =
rexBuilder.getTypeFactory().createTypeWithCharsetAndCollation(
+ rexBuilder.getTypeFactory().createSqlType(SqlTypeName.VARCHAR, 30),
+ Charset.forName(ConversionUtil.NATIVE_UTF16_CHARSET_NAME),
SqlCollation.IMPLICIT);
+ RexNode lita30 = rexBuilder.makeNullLiteral(stringType30);
+ RexNode litb30 = rexBuilder.makeNullLiteral(stringType30);
+
+ RelDataType stringType14 =
rexBuilder.getTypeFactory().createTypeWithCharsetAndCollation(
+ rexBuilder.getTypeFactory().createSqlType(SqlTypeName.VARCHAR, 14),
+ Charset.forName(ConversionUtil.NATIVE_UTF16_CHARSET_NAME),
SqlCollation.IMPLICIT);
+ RexNode lita14 =
rexBuilder.makeLiteral(RexNodeExprFactory.makeHiveUnicodeString("AAA111"),
stringType14, true);
+ RexNode litb14 =
rexBuilder.makeLiteral(RexNodeExprFactory.makeHiveUnicodeString("BBB222"),
stringType14, true);
+
+ final RelNode basePlan = relBuilder
+ .scan("t")
+ .filter(and(relBuilder,
+ relBuilder.call(SqlStdOperatorTable.IN,
relBuilder.field("f2"), lita30, litb30),
+ relBuilder.call(SqlStdOperatorTable.IN,
relBuilder.field("f2"), lita14, litb14)))
+ .build();
+
+ planner.setRoot(basePlan);
+ RelNode optimizedRelNode = planner.findBestExp();
+
+ HiveFilter filter = (HiveFilter) optimizedRelNode;
+ RexNode condition = filter.getCondition();
+ System.out.println(condition);
+ assertEquals("AND(IS NULL(null:VARCHAR(30) CHARACTER SET \"UTF-16LE\"),
null)", condition.toString());
+ }
+
+ @Test
+ public void testSameVarcharLiteralsDifferentPrecisionInOrExpression() {
+
+ final RexBuilder rexBuilder = relBuilder.getRexBuilder();
+ RelDataType stringType30 =
rexBuilder.getTypeFactory().createTypeWithCharsetAndCollation(
+ rexBuilder.getTypeFactory().createSqlType(SqlTypeName.VARCHAR, 30),
+ Charset.forName(ConversionUtil.NATIVE_UTF16_CHARSET_NAME),
SqlCollation.IMPLICIT);
+ RexNode lita30 =
rexBuilder.makeLiteral(RexNodeExprFactory.makeHiveUnicodeString("AAA111"),
stringType30, true);
+ RexNode litb30 =
rexBuilder.makeLiteral(RexNodeExprFactory.makeHiveUnicodeString("BBB222"),
stringType30, true);
+
+ RelDataType stringType14 =
rexBuilder.getTypeFactory().createTypeWithCharsetAndCollation(
+ rexBuilder.getTypeFactory().createSqlType(SqlTypeName.VARCHAR, 14),
+ Charset.forName(ConversionUtil.NATIVE_UTF16_CHARSET_NAME),
SqlCollation.IMPLICIT);
+ RexNode lita14 =
rexBuilder.makeLiteral(RexNodeExprFactory.makeHiveUnicodeString("AAA111"),
stringType14, true);
+ RexNode litb14 =
rexBuilder.makeLiteral(RexNodeExprFactory.makeHiveUnicodeString("BBB222"),
stringType14, true);
+
+ final RelNode basePlan = relBuilder
+ .scan("t")
+ .filter(or(relBuilder,
+ relBuilder.call(SqlStdOperatorTable.IN,
relBuilder.field("f2"), lita30, litb30),
+ relBuilder.call(SqlStdOperatorTable.IN,
relBuilder.field("f2"), lita14, litb14)))
+ .build();
+
+ planner.setRoot(basePlan);
+ RelNode optimizedRelNode = planner.findBestExp();
+
+ HiveFilter filter = (HiveFilter) optimizedRelNode;
+ RexNode condition = filter.getCondition();
+ System.out.println(condition);
+ assertEquals("IN($1, " +
+ "_UTF-16LE'AAA111':VARCHAR(30) CHARACTER SET \"UTF-16LE\",
" +
+ "_UTF-16LE'BBB222':VARCHAR(30) CHARACTER SET
\"UTF-16LE\")",
+ condition.toString());
+ }
+
+ @Test
+ public void testSameDecimalLiteralDifferentPrecision() {
+
+ final RexBuilder rexBuilder = relBuilder.getRexBuilder();
+ RelDataType decimalType30 =
rexBuilder.getTypeFactory().createSqlType(SqlTypeName.DECIMAL, 30, 5);
+ RexNode lita30 = rexBuilder.makeLiteral(10000, decimalType30, true);
+ RexNode litb30 = rexBuilder.makeLiteral(11000, decimalType30, true);
+
+ RelDataType decimalType14 =
rexBuilder.getTypeFactory().createSqlType(SqlTypeName.DECIMAL, 14, 5);
+ RexNode lita14 = rexBuilder.makeLiteral(10000, decimalType14, true);
+ RexNode litb14 = rexBuilder.makeLiteral(11000, decimalType14, true);
+
+ final RelNode basePlan = relBuilder
+ .scan("t")
+ .filter(and(relBuilder,
+ relBuilder.call(SqlStdOperatorTable.IN,
relBuilder.field("f2"), lita30, litb30),
+ relBuilder.call(SqlStdOperatorTable.IN,
relBuilder.field("f2"), lita14, litb14)))
+ .build();
+
+ planner.setRoot(basePlan);
+ RelNode optimizedRelNode = planner.findBestExp();
+
+ HiveFilter filter = (HiveFilter) optimizedRelNode;
+ RexNode condition = filter.getCondition();
+ System.out.println(condition);
+ assertEquals("IN($1, 10000:DECIMAL(19, 5), 11000:DECIMAL(19, 5))",
condition.toString());
+ }
}
diff --git a/ql/src/test/queries/clientpositive/pointlookup6.q
b/ql/src/test/queries/clientpositive/pointlookup6.q
new file mode 100644
index 00000000000..d1b05e7fc0b
--- /dev/null
+++ b/ql/src/test/queries/clientpositive/pointlookup6.q
@@ -0,0 +1,19 @@
+set hive.optimize.point.lookup.min=2;
+
+create table r_table (
+ string_col varchar(30)
+);
+
+create table l_table (
+ string_col varchar(14)
+);
+
+insert into r_table VALUES ('AAA111');
+insert into l_table VALUES ('AAA111');
+
+explain cbo
+SELECT l_table.string_col from l_table, r_table
+WHERE r_table.string_col = l_table.string_col AND l_table.string_col IN
('AAA111', 'BBB222') AND r_table.string_col IN ('AAA111', 'BBB222');
+
+SELECT l_table.string_col from l_table, r_table
+WHERE r_table.string_col = l_table.string_col AND l_table.string_col IN
('AAA111', 'BBB222') AND r_table.string_col IN ('AAA111', 'BBB222');
diff --git a/ql/src/test/results/clientpositive/llap/pointlookup6.q.out
b/ql/src/test/results/clientpositive/llap/pointlookup6.q.out
new file mode 100644
index 00000000000..830ce446a86
--- /dev/null
+++ b/ql/src/test/results/clientpositive/llap/pointlookup6.q.out
@@ -0,0 +1,79 @@
+PREHOOK: query: create table r_table (
+ string_col varchar(30)
+)
+PREHOOK: type: CREATETABLE
+PREHOOK: Output: database:default
+PREHOOK: Output: default@r_table
+POSTHOOK: query: create table r_table (
+ string_col varchar(30)
+)
+POSTHOOK: type: CREATETABLE
+POSTHOOK: Output: database:default
+POSTHOOK: Output: default@r_table
+PREHOOK: query: create table l_table (
+ string_col varchar(14)
+)
+PREHOOK: type: CREATETABLE
+PREHOOK: Output: database:default
+PREHOOK: Output: default@l_table
+POSTHOOK: query: create table l_table (
+ string_col varchar(14)
+)
+POSTHOOK: type: CREATETABLE
+POSTHOOK: Output: database:default
+POSTHOOK: Output: default@l_table
+PREHOOK: query: insert into r_table VALUES ('AAA111')
+PREHOOK: type: QUERY
+PREHOOK: Input: _dummy_database@_dummy_table
+PREHOOK: Output: default@r_table
+POSTHOOK: query: insert into r_table VALUES ('AAA111')
+POSTHOOK: type: QUERY
+POSTHOOK: Input: _dummy_database@_dummy_table
+POSTHOOK: Output: default@r_table
+POSTHOOK: Lineage: r_table.string_col SCRIPT []
+PREHOOK: query: insert into l_table VALUES ('AAA111')
+PREHOOK: type: QUERY
+PREHOOK: Input: _dummy_database@_dummy_table
+PREHOOK: Output: default@l_table
+POSTHOOK: query: insert into l_table VALUES ('AAA111')
+POSTHOOK: type: QUERY
+POSTHOOK: Input: _dummy_database@_dummy_table
+POSTHOOK: Output: default@l_table
+POSTHOOK: Lineage: l_table.string_col SCRIPT []
+PREHOOK: query: explain cbo
+SELECT l_table.string_col from l_table, r_table
+WHERE r_table.string_col = l_table.string_col AND l_table.string_col IN
('AAA111', 'BBB222') AND r_table.string_col IN ('AAA111', 'BBB222')
+PREHOOK: type: QUERY
+PREHOOK: Input: default@l_table
+PREHOOK: Input: default@r_table
+#### A masked pattern was here ####
+POSTHOOK: query: explain cbo
+SELECT l_table.string_col from l_table, r_table
+WHERE r_table.string_col = l_table.string_col AND l_table.string_col IN
('AAA111', 'BBB222') AND r_table.string_col IN ('AAA111', 'BBB222')
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@l_table
+POSTHOOK: Input: default@r_table
+#### A masked pattern was here ####
+CBO PLAN:
+HiveProject(string_col=[$0])
+ HiveJoin(condition=[=($1, $0)], joinType=[inner], algorithm=[none],
cost=[not available])
+ HiveProject(string_col=[$0])
+ HiveFilter(condition=[IN($0, _UTF-16LE'AAA111':VARCHAR(14) CHARACTER SET
"UTF-16LE", _UTF-16LE'BBB222':VARCHAR(14) CHARACTER SET "UTF-16LE")])
+ HiveTableScan(table=[[default, l_table]], table:alias=[l_table])
+ HiveProject(string_col=[$0])
+ HiveFilter(condition=[IN($0, _UTF-16LE'AAA111':VARCHAR(30) CHARACTER SET
"UTF-16LE", _UTF-16LE'BBB222':VARCHAR(30) CHARACTER SET "UTF-16LE")])
+ HiveTableScan(table=[[default, r_table]], table:alias=[r_table])
+
+PREHOOK: query: SELECT l_table.string_col from l_table, r_table
+WHERE r_table.string_col = l_table.string_col AND l_table.string_col IN
('AAA111', 'BBB222') AND r_table.string_col IN ('AAA111', 'BBB222')
+PREHOOK: type: QUERY
+PREHOOK: Input: default@l_table
+PREHOOK: Input: default@r_table
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT l_table.string_col from l_table, r_table
+WHERE r_table.string_col = l_table.string_col AND l_table.string_col IN
('AAA111', 'BBB222') AND r_table.string_col IN ('AAA111', 'BBB222')
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@l_table
+POSTHOOK: Input: default@r_table
+#### A masked pattern was here ####
+AAA111