From 893f16a01460b648a9b8f3368a183694c14924c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=ED=98=95=EC=A4=80?= Date: Thu, 10 Jul 2014 22:04:53 +0900 Subject: [PATCH 1/2] TAJO-929: Broadcast join with empty outer join table returns empty result. --- .../master/querymaster/Repartitioner.java | 9 +++++++-- .../tajo/engine/query/TestJoinBroadcast.java | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/tajo-core/src/main/java/org/apache/tajo/master/querymaster/Repartitioner.java b/tajo-core/src/main/java/org/apache/tajo/master/querymaster/Repartitioner.java index fc80bd1464..00efcd00f6 100644 --- a/tajo-core/src/main/java/org/apache/tajo/master/querymaster/Repartitioner.java +++ b/tajo-core/src/main/java/org/apache/tajo/master/querymaster/Repartitioner.java @@ -123,9 +123,14 @@ public static void scheduleFragmentsForJoinQuery(TaskSchedulerContext schedulerC JoinNode joinNode = PlannerUtil.findMostBottomNode(execBlock.getPlan(), NodeType.JOIN); if (joinNode != null) { if ( (joinNode.getJoinType() == JoinType.INNER)) { + LogicalNode leftNode = joinNode.getLeftChild(); + LogicalNode rightNode = joinNode.getRightChild(); for (int i = 0; i < stats.length; i++) { - if (stats[i] == 0) { - return; + if (scans[i].getPID() == leftNode.getPID() || scans[i].getPID() == rightNode.getPID()) { + if (stats[i] == 0) { + LOG.info(scans[i] + " 's input data is zero. Inner join's result is empty."); + return; + } } } } diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestJoinBroadcast.java b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestJoinBroadcast.java index 668992bfb3..0fe13002af 100644 --- a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestJoinBroadcast.java +++ b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestJoinBroadcast.java @@ -504,6 +504,25 @@ public final void testCasebyCase1() throws Exception { } } + @Test + public final void testInnerAndOuterWithEmpty() throws Exception { + executeDDL("customer_partition_ddl.sql", null); + executeFile("insert_into_customer_partition.sql").close(); + +// outer join table is empty + ResultSet res = executeString( + "select a.l_orderkey, b.o_orderkey, c.c_custkey from lineitem a " + + "inner join orders b on a.l_orderkey = b.o_orderkey " + + "left outer join customer_broad_parts c on a.l_orderkey = c.c_custkey and c.c_custkey < 0" + ); + + String expected = ""; + assertEquals(expected, resultSetToString(res)); + res.close(); + + executeString("DROP TABLE customer_broad_parts PURGE").close(); + } + static interface TupleCreator { public Tuple createTuple(String[] columnDatas); } From 186ae11f3ad8de0192cd367a35ff0ac8a76ccd7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=ED=98=95=EC=A4=80?= Date: Thu, 10 Jul 2014 22:41:11 +0900 Subject: [PATCH 2/2] TAJO-929: Broadcast join with empty outer join table returns empty result. --- .../apache/tajo/engine/query/TestJoinBroadcast.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestJoinBroadcast.java b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestJoinBroadcast.java index 0fe13002af..e01b3c5442 100644 --- a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestJoinBroadcast.java +++ b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestJoinBroadcast.java @@ -509,14 +509,21 @@ public final void testInnerAndOuterWithEmpty() throws Exception { executeDDL("customer_partition_ddl.sql", null); executeFile("insert_into_customer_partition.sql").close(); -// outer join table is empty + // outer join table is empty ResultSet res = executeString( "select a.l_orderkey, b.o_orderkey, c.c_custkey from lineitem a " + "inner join orders b on a.l_orderkey = b.o_orderkey " + "left outer join customer_broad_parts c on a.l_orderkey = c.c_custkey and c.c_custkey < 0" ); - String expected = ""; + String expected = "l_orderkey,o_orderkey,c_custkey\n" + + "-------------------------------\n" + + "1,1,null\n" + + "1,1,null\n" + + "2,2,null\n" + + "3,3,null\n" + + "3,3,null\n"; + assertEquals(expected, resultSetToString(res)); res.close();