You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tajo.apache.org by bl...@apache.org on 2014/04/05 01:23:45 UTC
[1/4] TAJO-725: Broadcast JOIN should supports multiple tables.
(hyoungjunkim via jaehwa)
Repository: tajo
Updated Branches:
refs/heads/branch-0.8.0 e5519cf0b -> 464f3e522
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testWhereClauseJoin4.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testWhereClauseJoin4.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testWhereClauseJoin4.result
new file mode 100644
index 0000000..b7f95a8
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testWhereClauseJoin4.result
@@ -0,0 +1,27 @@
+n_name,r_name,?plus
+-------------------------------
+ALGERIA,AFRICA,0
+ARGENTINA,AMERICA,2
+BRAZIL,AMERICA,3
+CANADA,AMERICA,4
+EGYPT,MIDDLE EAST,8
+ETHIOPIA,AFRICA,5
+FRANCE,EUROPE,9
+GERMANY,EUROPE,10
+INDIA,ASIA,10
+INDONESIA,ASIA,11
+IRAN,MIDDLE EAST,14
+IRAQ,MIDDLE EAST,15
+JAPAN,ASIA,14
+JORDAN,MIDDLE EAST,17
+KENYA,AFRICA,14
+MOROCCO,AFRICA,15
+MOZAMBIQUE,AFRICA,16
+PERU,AMERICA,18
+CHINA,ASIA,20
+ROMANIA,EUROPE,22
+SAUDI ARABIA,MIDDLE EAST,24
+VIETNAM,ASIA,23
+RUSSIA,EUROPE,25
+UNITED KINGDOM,EUROPE,26
+UNITED STATES,AMERICA,25
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testWhereClauseJoin5.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testWhereClauseJoin5.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testWhereClauseJoin5.result
new file mode 100644
index 0000000..ea3b0ff
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testWhereClauseJoin5.result
@@ -0,0 +1,5 @@
+s_acctbal,s_name,p_partkey
+-------------------------------
+4032.68,Supplier#000000002,1
+4192.4,Supplier#000000003,2
+4641.08,Supplier#000000004,3
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/results/TestNetTypes/testJoin.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestNetTypes/testJoin.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestNetTypes/testJoin.result
index 9d2cdf1..b5817f8 100644
--- a/tajo-core/tajo-core-backend/src/test/resources/results/TestNetTypes/testJoin.result
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestNetTypes/testJoin.result
@@ -1,6 +1,6 @@
id,name,score,type,addr,id,name,score,type,addr
-------------------------------
+0,,20.0,d,127.0.0.1,1,ooo,1.1,a,127.0.0.1
1,,0.0,a,127.0.0.8,3,qqq,3.4,c,127.0.0.8
2,,0.0,b,127.0.0.8,3,qqq,3.4,c,127.0.0.8
-0,,20.0,d,127.0.0.1,1,ooo,1.1,a,127.0.0.1
0,,20.0,d,127.0.0.1,4,rrr,4.5,d,127.0.0.1
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/results/TestUnionQuery/testUnion1.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestUnionQuery/testUnion1.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestUnionQuery/testUnion1.result
index 3b4dcf4..f384e9f 100644
--- a/tajo-core/tajo-core-backend/src/test/resources/results/TestUnionQuery/testUnion1.result
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestUnionQuery/testUnion1.result
@@ -2,9 +2,9 @@ num
-------------------------------
1
2
+2
+3
3
4
-5
-36901
-78002
-123314
\ No newline at end of file
+4
+5
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/tpch/orders.tbl
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/tpch/orders.tbl b/tajo-core/tajo-core-backend/src/test/tpch/orders.tbl
index 77cbcc0..15a1b6f 100644
--- a/tajo-core/tajo-core-backend/src/test/tpch/orders.tbl
+++ b/tajo-core/tajo-core-backend/src/test/tpch/orders.tbl
@@ -1,3 +1,3 @@
-1|36901|O|173665.47|1996-01-02|5-LOW|Clerk#000000951|0|nstructions sleep furiously among |
-2|78002|O|46929.18|1996-12-01|1-URGENT|Clerk#000000880|0| foxes. pending accounts at the pending, silent asymptot|
-3|123314|F|193846.25|1993-10-14|5-LOW|Clerk#000000955|0|sly final accounts boost. carefully regular ideas cajole carefully. depos|
+1|3|O|173665.47|1996-01-02|5-LOW|Clerk#000000951|0|nstructions sleep furiously among |
+2|4|O|46929.18|1996-12-01|1-URGENT|Clerk#000000880|0| foxes. pending accounts at the pending, silent asymptot|
+3|2|F|193846.25|1993-10-14|5-LOW|Clerk#000000955|0|sly final accounts boost. carefully regular ideas cajole carefully. depos|
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-storage/src/main/java/org/apache/tajo/storage/fragment/FragmentConvertor.java
----------------------------------------------------------------------
diff --git a/tajo-storage/src/main/java/org/apache/tajo/storage/fragment/FragmentConvertor.java b/tajo-storage/src/main/java/org/apache/tajo/storage/fragment/FragmentConvertor.java
index 3bfe96f..0315a8d 100644
--- a/tajo-storage/src/main/java/org/apache/tajo/storage/fragment/FragmentConvertor.java
+++ b/tajo-storage/src/main/java/org/apache/tajo/storage/fragment/FragmentConvertor.java
@@ -93,6 +93,9 @@ public class FragmentConvertor {
public static <T extends Fragment> List<T> convert(Class<T> clazz, FragmentProto...fragments)
throws IOException {
List<T> list = Lists.newArrayList();
+ if (fragments == null) {
+ return list;
+ }
for (FragmentProto proto : fragments) {
list.add(convert(clazz, proto));
}
@@ -102,6 +105,9 @@ public class FragmentConvertor {
public static <T extends Fragment> List<T> convert(Configuration conf, StoreType storeType,
FragmentProto...fragments) throws IOException {
List<T> list = Lists.newArrayList();
+ if (fragments == null) {
+ return list;
+ }
for (FragmentProto proto : fragments) {
list.add((T) convert(conf, storeType, proto));
}
@@ -110,6 +116,9 @@ public class FragmentConvertor {
public static List<FragmentProto> toFragmentProtoList(Fragment... fragments) {
List<FragmentProto> list = Lists.newArrayList();
+ if (fragments == null) {
+ return list;
+ }
for (Fragment fragment : fragments) {
list.add(fragment.getProto());
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-storage/src/main/java/org/apache/tajo/storage/parquet/TajoRecordMaterializer.java
----------------------------------------------------------------------
diff --git a/tajo-storage/src/main/java/org/apache/tajo/storage/parquet/TajoRecordMaterializer.java b/tajo-storage/src/main/java/org/apache/tajo/storage/parquet/TajoRecordMaterializer.java
index f099d04..e31828c 100644
--- a/tajo-storage/src/main/java/org/apache/tajo/storage/parquet/TajoRecordMaterializer.java
+++ b/tajo-storage/src/main/java/org/apache/tajo/storage/parquet/TajoRecordMaterializer.java
@@ -69,7 +69,7 @@ class TajoRecordMaterializer extends RecordMaterializer<Tuple> {
/**
* Returns the root converter.
*
- * @param return The root converter
+ * @return The root converter
*/
@Override
public GroupConverter getRootConverter() {
[2/4] TAJO-725: Broadcast JOIN should supports multiple tables.
(hyoungjunkim via jaehwa)
Posted by bl...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testCrossJoin.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testCrossJoin.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testCrossJoin.sql
new file mode 100644
index 0000000..1bb2916
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testCrossJoin.sql
@@ -0,0 +1 @@
+select n_name, r_name, n_regionkey, r_regionkey from nation, region order by n_name, r_name;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testCrossJoinAndCaseWhen.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testCrossJoinAndCaseWhen.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testCrossJoinAndCaseWhen.sql
new file mode 100644
index 0000000..d058aba
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testCrossJoinAndCaseWhen.sql
@@ -0,0 +1,18 @@
+select
+ r_regionkey,
+ n_regionkey,
+ case
+ when r_regionkey = 1 then 'one'
+ when r_regionkey = 2 then 'two'
+ when r_regionkey = 3 then 'three'
+ when r_regionkey = 4 then 'four'
+ else 'zero'
+ end as cond
+from
+ region,
+ nation
+where
+ r_regionkey = n_regionkey
+order by
+ r_regionkey,
+ n_regionkey
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testCrossJoinWithAsterisk1.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testCrossJoinWithAsterisk1.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testCrossJoinWithAsterisk1.sql
new file mode 100644
index 0000000..5451b4a
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testCrossJoinWithAsterisk1.sql
@@ -0,0 +1 @@
+select region.*, customer.* from region, customer order by r_regionkey,r_name;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testCrossJoinWithAsterisk2.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testCrossJoinWithAsterisk2.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testCrossJoinWithAsterisk2.sql
new file mode 100644
index 0000000..e9dac51
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testCrossJoinWithAsterisk2.sql
@@ -0,0 +1 @@
+select region.*, customer.* from customer, region order by r_regionkey,r_name;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testCrossJoinWithAsterisk3.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testCrossJoinWithAsterisk3.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testCrossJoinWithAsterisk3.sql
new file mode 100644
index 0000000..c98e19f
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testCrossJoinWithAsterisk3.sql
@@ -0,0 +1 @@
+select * from customer, region order by c_custkey,c_name;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testCrossJoinWithAsterisk4.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testCrossJoinWithAsterisk4.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testCrossJoinWithAsterisk4.sql
new file mode 100644
index 0000000..7130def
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testCrossJoinWithAsterisk4.sql
@@ -0,0 +1 @@
+select length(r_comment) as len, *, c_custkey*10 from customer, region order by len,r_regionkey,r_name;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testCrossJoinWithEmptyTable1.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testCrossJoinWithEmptyTable1.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testCrossJoinWithEmptyTable1.sql
new file mode 100644
index 0000000..1e0cb56
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testCrossJoinWithEmptyTable1.sql
@@ -0,0 +1,8 @@
+select
+ c_custkey,
+ empty_orders.o_orderkey
+from
+ customer, empty_orders
+where c_custkey = o_orderkey
+order by
+ c_custkey, o_orderkey;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testFullOuterJoin1.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testFullOuterJoin1.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testFullOuterJoin1.sql
new file mode 100644
index 0000000..ccaa5fb
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testFullOuterJoin1.sql
@@ -0,0 +1,8 @@
+select
+ c_custkey,
+ orders.o_orderkey
+from
+ orders full outer join customer on c_custkey = o_orderkey
+order by
+ c_custkey,
+ orders.o_orderkey;
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testFullOuterJoinWithEmptyTable1.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testFullOuterJoinWithEmptyTable1.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testFullOuterJoinWithEmptyTable1.sql
new file mode 100644
index 0000000..b9e3efd
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testFullOuterJoinWithEmptyTable1.sql
@@ -0,0 +1,8 @@
+select
+ c_custkey,
+ empty_orders.o_orderkey
+from
+ empty_orders full outer join customer on c_custkey = o_orderkey
+order by
+ c_custkey,
+ empty_orders.o_orderkey;
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testInnerJoinWithEmptyTable.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testInnerJoinWithEmptyTable.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testInnerJoinWithEmptyTable.sql
new file mode 100644
index 0000000..1e0cb56
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testInnerJoinWithEmptyTable.sql
@@ -0,0 +1,8 @@
+select
+ c_custkey,
+ empty_orders.o_orderkey
+from
+ customer, empty_orders
+where c_custkey = o_orderkey
+order by
+ c_custkey, o_orderkey;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testJoinCoReferredEvals1.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testJoinCoReferredEvals1.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testJoinCoReferredEvals1.sql
new file mode 100644
index 0000000..3a123bb
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testJoinCoReferredEvals1.sql
@@ -0,0 +1,11 @@
+select
+ r_regionkey,
+ n_regionkey,
+ (r_regionkey + n_regionkey) as plus
+from
+ region,
+ nation
+where
+ r_regionkey = n_regionkey
+order by
+ r_regionkey, n_regionkey;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testJoinCoReferredEvalsWithSameExprs1.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testJoinCoReferredEvalsWithSameExprs1.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testJoinCoReferredEvalsWithSameExprs1.sql
new file mode 100644
index 0000000..3638393
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testJoinCoReferredEvalsWithSameExprs1.sql
@@ -0,0 +1,14 @@
+select
+ n_regionkey + n_nationkey as v1,
+ n_regionkey,
+ r_regionkey,
+ (r_regionkey + n_regionkey) as plus1,
+ (r_regionkey + n_regionkey) as plus2,
+ ((r_regionkey + n_regionkey) / 2) as result
+from
+ region,
+ nation
+where
+ r_regionkey = n_regionkey and r_regionkey > 0
+order by
+ n_regionkey + n_nationkey, n_regionkey;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testJoinCoReferredEvalsWithSameExprs2.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testJoinCoReferredEvalsWithSameExprs2.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testJoinCoReferredEvalsWithSameExprs2.sql
new file mode 100644
index 0000000..a5b75d4
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testJoinCoReferredEvalsWithSameExprs2.sql
@@ -0,0 +1,22 @@
+select
+ n_regionkey + n_nationkey as v1,
+ n_regionkey,
+ r_regionkey,
+ (r_regionkey + n_regionkey) as plus1,
+ (r_regionkey + n_regionkey) as plus2,
+ ((r_regionkey + n_regionkey) / 2) as result,
+ sum(r_regionkey + n_regionkey) as total
+from
+ region,
+ nation
+where
+ r_regionkey = n_regionkey and r_regionkey > 0
+group by
+ n_regionkey + n_nationkey,
+ n_regionkey,
+ r_regionkey,
+ (r_regionkey + n_regionkey),
+ ((r_regionkey + n_regionkey) / 2)
+
+order by
+ n_regionkey + n_nationkey, n_regionkey;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testJoinOnMultipleDatabases.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testJoinOnMultipleDatabases.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testJoinOnMultipleDatabases.sql
new file mode 100644
index 0000000..eb5a2c5
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testJoinOnMultipleDatabases.sql
@@ -0,0 +1,25 @@
+select
+ s_acctbal,
+ s_name,
+ n_name,
+ JOINS.part_.p_partkey,
+ p_mfgr,
+ JOINS.supplier_.s_address,
+ JOINS.supplier_.s_phone,
+ s_comment
+from
+ JOINS.part_,
+ JOINS.supplier_,
+ partsupp,
+ nation,
+ region
+where
+ p_partkey = ps_partkey
+ and s_suppkey = ps_suppkey
+ and s_nationkey = n_nationkey
+ and n_regionkey = r_regionkey
+order by
+ s_acctbal,
+ s_name,
+ n_name,
+ p_partkey;
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testLeftOuterJoin1.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testLeftOuterJoin1.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testLeftOuterJoin1.sql
new file mode 100644
index 0000000..08a68e8
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testLeftOuterJoin1.sql
@@ -0,0 +1,9 @@
+select
+ c_custkey,
+ orders.o_orderkey,
+ orders.o_orderstatus,
+ orders.o_orderdate
+from
+ customer left outer join orders on c_custkey = o_orderkey
+order by
+ c_custkey, o_orderkey;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testLeftOuterJoinWithConstantExpr1.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testLeftOuterJoinWithConstantExpr1.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testLeftOuterJoinWithConstantExpr1.sql
new file mode 100644
index 0000000..f5b0ba7
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testLeftOuterJoinWithConstantExpr1.sql
@@ -0,0 +1,9 @@
+select
+ c_custkey,
+ orders.o_orderkey,
+ 'val' as val
+from
+ customer left outer join orders on c_custkey = o_orderkey
+order by
+ c_custkey,
+ o_orderkey;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testLeftOuterJoinWithConstantExpr2.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testLeftOuterJoinWithConstantExpr2.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testLeftOuterJoinWithConstantExpr2.sql
new file mode 100644
index 0000000..7333d54
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testLeftOuterJoinWithConstantExpr2.sql
@@ -0,0 +1,9 @@
+select
+ c_custkey,
+ o.o_orderkey,
+ 'val' as val
+from
+ customer left outer join (select * from orders) o on c_custkey = o.o_orderkey
+order by
+ c_custkey,
+ o_orderkey;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testLeftOuterJoinWithConstantExpr3.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testLeftOuterJoinWithConstantExpr3.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testLeftOuterJoinWithConstantExpr3.sql
new file mode 100644
index 0000000..90be13b
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testLeftOuterJoinWithConstantExpr3.sql
@@ -0,0 +1,17 @@
+select
+ a.c_custkey,
+ 123::INT8 as const_val,
+ b.min_name
+from
+ customer a
+left outer join (
+ select
+ c_custkey,
+ min(c_name) as min_name
+ from customer
+ group by
+ c_custkey)
+ b
+on a.c_custkey = b.c_custkey
+order by
+ c_custkey;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testLeftOuterJoinWithEmptyTable1.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testLeftOuterJoinWithEmptyTable1.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testLeftOuterJoinWithEmptyTable1.sql
new file mode 100644
index 0000000..27ac8bc
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testLeftOuterJoinWithEmptyTable1.sql
@@ -0,0 +1,9 @@
+select
+ c_custkey,
+ empty_orders.o_orderkey,
+ empty_orders.o_orderstatus,
+ empty_orders.o_orderdate
+from
+ customer left outer join empty_orders on c_custkey = o_orderkey
+order by
+ c_custkey, o_orderkey;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testLeftOuterJoinWithEmptyTable2.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testLeftOuterJoinWithEmptyTable2.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testLeftOuterJoinWithEmptyTable2.sql
new file mode 100644
index 0000000..b0639ff
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testLeftOuterJoinWithEmptyTable2.sql
@@ -0,0 +1,9 @@
+select
+ c_custkey,
+ sum(empty_orders.o_orderkey),
+ max(empty_orders.o_orderstatus),
+ max(empty_orders.o_orderdate)
+from
+ customer left outer join empty_orders on c_custkey = o_orderkey
+ group by c_custkey
+order by c_custkey ;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testLeftOuterJoinWithEmptyTable3.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testLeftOuterJoinWithEmptyTable3.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testLeftOuterJoinWithEmptyTable3.sql
new file mode 100644
index 0000000..6a79e34
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testLeftOuterJoinWithEmptyTable3.sql
@@ -0,0 +1,14 @@
+select count(*)
+from (
+ select
+ c_custkey,
+ sum(empty_orders.o_orderkey) as total1,
+ max(empty_orders.o_orderstatus) as total2,
+ max(empty_orders.o_orderdate) as total3
+ from
+ customer left outer join empty_orders on c_custkey = o_orderkey
+ group by c_custkey
+) t1
+group by
+ c_custkey
+order by c_custkey ;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testLeftOuterJoinWithEmptyTable4.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testLeftOuterJoinWithEmptyTable4.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testLeftOuterJoinWithEmptyTable4.sql
new file mode 100644
index 0000000..5f91a18
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testLeftOuterJoinWithEmptyTable4.sql
@@ -0,0 +1,17 @@
+
+ select
+ max(c_custkey),
+ sum(orders.o_orderkey),
+ max(orders.o_orderstatus),
+ max(orders.o_orderdate)
+ from
+ customer left outer join orders on c_custkey = o_orderkey
+ union
+ select
+ max(c_custkey),
+ sum(empty_orders.o_orderkey),
+ max(empty_orders.o_orderstatus),
+ max(empty_orders.o_orderdate)
+ from
+ customer left outer join empty_orders on c_custkey = o_orderkey
+;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testOuterJoinAndCaseWhen1.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testOuterJoinAndCaseWhen1.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testOuterJoinAndCaseWhen1.sql
new file mode 100644
index 0000000..a7ebef4
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testOuterJoinAndCaseWhen1.sql
@@ -0,0 +1,12 @@
+select
+ a.id,
+ a.name,
+ b.id as id2,
+ b.name as name2,
+ case when b.name is null then '9991231' else b.name end as c1,
+ case when c.name is null then '9991231' else c.name end as c2
+from
+ table1 a left outer join table2 b on a.id = b.id left outer join table1 c on b.id = c.id
+order by
+ a.id,
+ a.name;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testRightOuterJoin1.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testRightOuterJoin1.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testRightOuterJoin1.sql
new file mode 100644
index 0000000..ba4c713
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testRightOuterJoin1.sql
@@ -0,0 +1,8 @@
+select
+ c_custkey,
+ orders.o_orderkey
+from
+ orders right outer join customer on c_custkey = o_orderkey
+order by
+ c_custkey,
+ orders.o_orderkey;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testRightOuterJoinWithEmptyTable1.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testRightOuterJoinWithEmptyTable1.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testRightOuterJoinWithEmptyTable1.sql
new file mode 100644
index 0000000..651a3cf
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testRightOuterJoinWithEmptyTable1.sql
@@ -0,0 +1,8 @@
+select
+ c_custkey,
+ empty_orders.o_orderkey
+from
+ empty_orders right outer join customer on c_custkey = o_orderkey
+order by
+ c_custkey,
+ empty_orders.o_orderkey;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testTPCHQ2Join.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testTPCHQ2Join.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testTPCHQ2Join.sql
new file mode 100644
index 0000000..9b7b5b9
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testTPCHQ2Join.sql
@@ -0,0 +1,25 @@
+select
+ s_acctbal,
+ s_name,
+ n_name,
+ p_partkey,
+ p_mfgr,
+ s_address,
+ s_phone,
+ s_comment
+from
+ part,
+ supplier,
+ partsupp,
+ nation,
+ region
+where
+ p_partkey = ps_partkey
+ and s_suppkey = ps_suppkey
+ and s_nationkey = n_nationkey
+ and n_regionkey = r_regionkey
+order by
+ s_acctbal,
+ s_name,
+ n_name,
+ p_partkey;
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testWhereClauseJoin1.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testWhereClauseJoin1.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testWhereClauseJoin1.sql
new file mode 100644
index 0000000..069be09
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testWhereClauseJoin1.sql
@@ -0,0 +1,10 @@
+select
+ n_name,
+ r_name,
+ n_regionkey,
+ r_regionkey
+from
+ nation,
+ region
+where
+ n_regionkey = r_regionkey;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testWhereClauseJoin2.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testWhereClauseJoin2.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testWhereClauseJoin2.sql
new file mode 100644
index 0000000..0c6539b
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testWhereClauseJoin2.sql
@@ -0,0 +1,8 @@
+select
+ n_name,
+ r_name
+from
+ nation,
+ region
+where
+ n_regionkey = r_regionkey;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testWhereClauseJoin3.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testWhereClauseJoin3.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testWhereClauseJoin3.sql
new file mode 100644
index 0000000..6495958
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testWhereClauseJoin3.sql
@@ -0,0 +1,9 @@
+select
+ n_name,
+ r_name,
+ n_nationkey + 1 as p1,
+ r_regionkey + 1 as p2
+from
+ nation, region
+where
+ n_regionkey = r_regionkey;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testWhereClauseJoin4.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testWhereClauseJoin4.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testWhereClauseJoin4.sql
new file mode 100644
index 0000000..d8ee615
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testWhereClauseJoin4.sql
@@ -0,0 +1,8 @@
+select
+ n_name,
+ r_name,
+ n_nationkey + r_regionkey
+from
+ nation, region
+where
+ n_regionkey = r_regionkey;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testWhereClauseJoin5.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testWhereClauseJoin5.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testWhereClauseJoin5.sql
new file mode 100644
index 0000000..3494007
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testWhereClauseJoin5.sql
@@ -0,0 +1,15 @@
+select
+ s_acctbal,
+ s_name,
+ p_partkey
+from
+ part,
+ supplier,
+ partsupp
+where
+ p_partkey = ps_partkey and
+ s_suppkey = ps_suppkey
+order by
+ s_acctbal,
+ s_name,
+ p_partkey;
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testWhereClauseJoin6.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testWhereClauseJoin6.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testWhereClauseJoin6.sql
new file mode 100644
index 0000000..62d3b79
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testWhereClauseJoin6.sql
@@ -0,0 +1,19 @@
+select
+ s_acctbal,
+ s_name,
+ p_partkey,
+ n_name
+from
+ part,
+ supplier,
+ partsupp,
+ nation
+where
+ p_partkey = ps_partkey and
+ s_suppkey = ps_suppkey and
+ s_nationkey = n_nationkey
+order by
+ s_acctbal,
+ s_name,
+ p_partkey,
+ n_name;
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestNetTypes/testJoin.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestNetTypes/testJoin.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestNetTypes/testJoin.sql
index a163c4f..efb9db3 100644
--- a/tajo-core/tajo-core-backend/src/test/resources/queries/TestNetTypes/testJoin.sql
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestNetTypes/testJoin.sql
@@ -1 +1 @@
-select * from table1 as t1, table2 as t2 where t1.addr = t2.addr;
\ No newline at end of file
+select * from table1 as t1, table2 as t2 where t1.addr = t2.addr order by t2.name;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testBroadcastBasicJoin.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testBroadcastBasicJoin.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testBroadcastBasicJoin.result
new file mode 100644
index 0000000..174fd95
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testBroadcastBasicJoin.result
@@ -0,0 +1,99 @@
+l_orderkey,p_name,s_name
+-------------------------------
+1,spring green yellow purple cornsilk,Supplier#000000004
+1,goldenrod lavender spring chocolate lace,Supplier#000000004
+1,spring green yellow purple cornsilk,Supplier#000000004
+1,blush thistle blue yellow saddle,Supplier#000000003
+1,goldenrod lavender spring chocolate lace,Supplier#000000004
+1,goldenrod lavender spring chocolate lace,Supplier#000000002
+2,blush thistle blue yellow saddle,Supplier#000000002
+3,goldenrod lavender spring chocolate lace,Supplier#000000003
+3,blush thistle blue yellow saddle,Supplier#000000002
+3,spring green yellow purple cornsilk,Supplier#000000002
+3,goldenrod lavender spring chocolate lace,Supplier#000000003
+3,spring green yellow purple cornsilk,Supplier#000000002
+3,spring green yellow purple cornsilk,Supplier#000000004
+4,goldenrod lavender spring chocolate lace,Supplier#000000004
+5,blush thistle blue yellow saddle,Supplier#000000002
+5,spring green yellow purple cornsilk,Supplier#000000002
+5,goldenrod lavender spring chocolate lace,Supplier#000000003
+6,goldenrod lavender spring chocolate lace,Supplier#000000004
+7,goldenrod lavender spring chocolate lace,Supplier#000000003
+7,blush thistle blue yellow saddle,Supplier#000000002
+7,spring green yellow purple cornsilk,Supplier#000000004
+7,goldenrod lavender spring chocolate lace,Supplier#000000002
+7,blush thistle blue yellow saddle,Supplier#000000003
+7,goldenrod lavender spring chocolate lace,Supplier#000000004
+7,blush thistle blue yellow saddle,Supplier#000000002
+32,spring green yellow purple cornsilk,Supplier#000000003
+32,spring green yellow purple cornsilk,Supplier#000000004
+32,spring green yellow purple cornsilk,Supplier#000000002
+32,goldenrod lavender spring chocolate lace,Supplier#000000003
+32,spring green yellow purple cornsilk,Supplier#000000003
+32,spring green yellow purple cornsilk,Supplier#000000002
+33,goldenrod lavender spring chocolate lace,Supplier#000000003
+33,spring green yellow purple cornsilk,Supplier#000000002
+33,spring green yellow purple cornsilk,Supplier#000000003
+33,blush thistle blue yellow saddle,Supplier#000000004
+34,spring green yellow purple cornsilk,Supplier#000000004
+34,goldenrod lavender spring chocolate lace,Supplier#000000004
+34,blush thistle blue yellow saddle,Supplier#000000004
+35,spring green yellow purple cornsilk,Supplier#000000002
+35,spring green yellow purple cornsilk,Supplier#000000003
+35,spring green yellow purple cornsilk,Supplier#000000002
+35,spring green yellow purple cornsilk,Supplier#000000004
+35,goldenrod lavender spring chocolate lace,Supplier#000000002
+35,spring green yellow purple cornsilk,Supplier#000000002
+36,spring green yellow purple cornsilk,Supplier#000000003
+37,goldenrod lavender spring chocolate lace,Supplier#000000004
+37,goldenrod lavender spring chocolate lace,Supplier#000000003
+37,goldenrod lavender spring chocolate lace,Supplier#000000002
+38,blush thistle blue yellow saddle,Supplier#000000003
+39,blush thistle blue yellow saddle,Supplier#000000002
+39,blush thistle blue yellow saddle,Supplier#000000003
+39,blush thistle blue yellow saddle,Supplier#000000004
+39,spring green yellow purple cornsilk,Supplier#000000004
+39,blush thistle blue yellow saddle,Supplier#000000003
+39,blush thistle blue yellow saddle,Supplier#000000004
+64,goldenrod lavender spring chocolate lace,Supplier#000000004
+65,spring green yellow purple cornsilk,Supplier#000000003
+65,blush thistle blue yellow saddle,Supplier#000000002
+65,spring green yellow purple cornsilk,Supplier#000000002
+66,spring green yellow purple cornsilk,Supplier#000000002
+66,spring green yellow purple cornsilk,Supplier#000000003
+67,goldenrod lavender spring chocolate lace,Supplier#000000003
+67,goldenrod lavender spring chocolate lace,Supplier#000000003
+67,goldenrod lavender spring chocolate lace,Supplier#000000004
+67,spring green yellow purple cornsilk,Supplier#000000002
+67,goldenrod lavender spring chocolate lace,Supplier#000000003
+67,blush thistle blue yellow saddle,Supplier#000000004
+68,blush thistle blue yellow saddle,Supplier#000000004
+68,goldenrod lavender spring chocolate lace,Supplier#000000003
+68,blush thistle blue yellow saddle,Supplier#000000003
+68,blush thistle blue yellow saddle,Supplier#000000003
+68,spring green yellow purple cornsilk,Supplier#000000004
+68,goldenrod lavender spring chocolate lace,Supplier#000000003
+68,goldenrod lavender spring chocolate lace,Supplier#000000004
+69,spring green yellow purple cornsilk,Supplier#000000002
+69,blush thistle blue yellow saddle,Supplier#000000002
+69,blush thistle blue yellow saddle,Supplier#000000002
+69,spring green yellow purple cornsilk,Supplier#000000004
+69,spring green yellow purple cornsilk,Supplier#000000004
+69,blush thistle blue yellow saddle,Supplier#000000002
+70,spring green yellow purple cornsilk,Supplier#000000004
+70,spring green yellow purple cornsilk,Supplier#000000002
+70,blush thistle blue yellow saddle,Supplier#000000002
+70,blush thistle blue yellow saddle,Supplier#000000002
+70,blush thistle blue yellow saddle,Supplier#000000002
+70,spring green yellow purple cornsilk,Supplier#000000002
+71,spring green yellow purple cornsilk,Supplier#000000002
+71,spring green yellow purple cornsilk,Supplier#000000002
+71,spring green yellow purple cornsilk,Supplier#000000003
+71,spring green yellow purple cornsilk,Supplier#000000002
+71,spring green yellow purple cornsilk,Supplier#000000002
+71,goldenrod lavender spring chocolate lace,Supplier#000000003
+96,goldenrod lavender spring chocolate lace,Supplier#000000002
+96,spring green yellow purple cornsilk,Supplier#000000004
+97,goldenrod lavender spring chocolate lace,Supplier#000000003
+97,goldenrod lavender spring chocolate lace,Supplier#000000003
+97,goldenrod lavender spring chocolate lace,Supplier#000000002
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testBroadcastSubquery.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testBroadcastSubquery.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testBroadcastSubquery.result
new file mode 100644
index 0000000..e3c4bd7
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testBroadcastSubquery.result
@@ -0,0 +1,15 @@
+l_orderkey,o_custkey,p_name
+-------------------------------
+1,3,goldenrod lavender spring chocolate lace
+1,3,goldenrod lavender spring chocolate lace
+1,3,goldenrod lavender spring chocolate lace
+3,2,goldenrod lavender spring chocolate lace
+3,2,goldenrod lavender spring chocolate lace
+1,3,blush thistle blue yellow saddle
+2,4,blush thistle blue yellow saddle
+3,2,blush thistle blue yellow saddle
+1,3,spring green yellow purple cornsilk
+1,3,spring green yellow purple cornsilk
+3,2,spring green yellow purple cornsilk
+3,2,spring green yellow purple cornsilk
+3,2,spring green yellow purple cornsilk
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testBroadcastSubquery2.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testBroadcastSubquery2.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testBroadcastSubquery2.result
new file mode 100644
index 0000000..14c2211
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testBroadcastSubquery2.result
@@ -0,0 +1,3 @@
+?sum
+-------------------------------
+360.0
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testBroadcastTwoPartJoin.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testBroadcastTwoPartJoin.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testBroadcastTwoPartJoin.result
new file mode 100644
index 0000000..1a3d68c
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testBroadcastTwoPartJoin.result
@@ -0,0 +1,15 @@
+l_orderkey,p_name,n_name
+-------------------------------
+3,goldenrod lavender spring chocolate lace,GERMANY
+3,blush thistle blue yellow saddle,GERMANY
+3,spring green yellow purple cornsilk,GERMANY
+3,goldenrod lavender spring chocolate lace,GERMANY
+3,spring green yellow purple cornsilk,GERMANY
+3,spring green yellow purple cornsilk,GERMANY
+1,spring green yellow purple cornsilk,GERMANY
+1,goldenrod lavender spring chocolate lace,GERMANY
+1,spring green yellow purple cornsilk,GERMANY
+1,blush thistle blue yellow saddle,GERMANY
+1,goldenrod lavender spring chocolate lace,GERMANY
+1,goldenrod lavender spring chocolate lace,GERMANY
+2,blush thistle blue yellow saddle,IRAN
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testCrossJoin.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testCrossJoin.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testCrossJoin.result
new file mode 100644
index 0000000..607adc4
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testCrossJoin.result
@@ -0,0 +1,127 @@
+n_name,r_name,n_regionkey,r_regionkey
+-------------------------------
+ALGERIA,AFRICA,0,0
+ALGERIA,AMERICA,0,1
+ALGERIA,ASIA,0,2
+ALGERIA,EUROPE,0,3
+ALGERIA,MIDDLE EAST,0,4
+ARGENTINA,AFRICA,1,0
+ARGENTINA,AMERICA,1,1
+ARGENTINA,ASIA,1,2
+ARGENTINA,EUROPE,1,3
+ARGENTINA,MIDDLE EAST,1,4
+BRAZIL,AFRICA,1,0
+BRAZIL,AMERICA,1,1
+BRAZIL,ASIA,1,2
+BRAZIL,EUROPE,1,3
+BRAZIL,MIDDLE EAST,1,4
+CANADA,AFRICA,1,0
+CANADA,AMERICA,1,1
+CANADA,ASIA,1,2
+CANADA,EUROPE,1,3
+CANADA,MIDDLE EAST,1,4
+CHINA,AFRICA,2,0
+CHINA,AMERICA,2,1
+CHINA,ASIA,2,2
+CHINA,EUROPE,2,3
+CHINA,MIDDLE EAST,2,4
+EGYPT,AFRICA,4,0
+EGYPT,AMERICA,4,1
+EGYPT,ASIA,4,2
+EGYPT,EUROPE,4,3
+EGYPT,MIDDLE EAST,4,4
+ETHIOPIA,AFRICA,0,0
+ETHIOPIA,AMERICA,0,1
+ETHIOPIA,ASIA,0,2
+ETHIOPIA,EUROPE,0,3
+ETHIOPIA,MIDDLE EAST,0,4
+FRANCE,AFRICA,3,0
+FRANCE,AMERICA,3,1
+FRANCE,ASIA,3,2
+FRANCE,EUROPE,3,3
+FRANCE,MIDDLE EAST,3,4
+GERMANY,AFRICA,3,0
+GERMANY,AMERICA,3,1
+GERMANY,ASIA,3,2
+GERMANY,EUROPE,3,3
+GERMANY,MIDDLE EAST,3,4
+INDIA,AFRICA,2,0
+INDIA,AMERICA,2,1
+INDIA,ASIA,2,2
+INDIA,EUROPE,2,3
+INDIA,MIDDLE EAST,2,4
+INDONESIA,AFRICA,2,0
+INDONESIA,AMERICA,2,1
+INDONESIA,ASIA,2,2
+INDONESIA,EUROPE,2,3
+INDONESIA,MIDDLE EAST,2,4
+IRAN,AFRICA,4,0
+IRAN,AMERICA,4,1
+IRAN,ASIA,4,2
+IRAN,EUROPE,4,3
+IRAN,MIDDLE EAST,4,4
+IRAQ,AFRICA,4,0
+IRAQ,AMERICA,4,1
+IRAQ,ASIA,4,2
+IRAQ,EUROPE,4,3
+IRAQ,MIDDLE EAST,4,4
+JAPAN,AFRICA,2,0
+JAPAN,AMERICA,2,1
+JAPAN,ASIA,2,2
+JAPAN,EUROPE,2,3
+JAPAN,MIDDLE EAST,2,4
+JORDAN,AFRICA,4,0
+JORDAN,AMERICA,4,1
+JORDAN,ASIA,4,2
+JORDAN,EUROPE,4,3
+JORDAN,MIDDLE EAST,4,4
+KENYA,AFRICA,0,0
+KENYA,AMERICA,0,1
+KENYA,ASIA,0,2
+KENYA,EUROPE,0,3
+KENYA,MIDDLE EAST,0,4
+MOROCCO,AFRICA,0,0
+MOROCCO,AMERICA,0,1
+MOROCCO,ASIA,0,2
+MOROCCO,EUROPE,0,3
+MOROCCO,MIDDLE EAST,0,4
+MOZAMBIQUE,AFRICA,0,0
+MOZAMBIQUE,AMERICA,0,1
+MOZAMBIQUE,ASIA,0,2
+MOZAMBIQUE,EUROPE,0,3
+MOZAMBIQUE,MIDDLE EAST,0,4
+PERU,AFRICA,1,0
+PERU,AMERICA,1,1
+PERU,ASIA,1,2
+PERU,EUROPE,1,3
+PERU,MIDDLE EAST,1,4
+ROMANIA,AFRICA,3,0
+ROMANIA,AMERICA,3,1
+ROMANIA,ASIA,3,2
+ROMANIA,EUROPE,3,3
+ROMANIA,MIDDLE EAST,3,4
+RUSSIA,AFRICA,3,0
+RUSSIA,AMERICA,3,1
+RUSSIA,ASIA,3,2
+RUSSIA,EUROPE,3,3
+RUSSIA,MIDDLE EAST,3,4
+SAUDI ARABIA,AFRICA,4,0
+SAUDI ARABIA,AMERICA,4,1
+SAUDI ARABIA,ASIA,4,2
+SAUDI ARABIA,EUROPE,4,3
+SAUDI ARABIA,MIDDLE EAST,4,4
+UNITED KINGDOM,AFRICA,3,0
+UNITED KINGDOM,AMERICA,3,1
+UNITED KINGDOM,ASIA,3,2
+UNITED KINGDOM,EUROPE,3,3
+UNITED KINGDOM,MIDDLE EAST,3,4
+UNITED STATES,AFRICA,1,0
+UNITED STATES,AMERICA,1,1
+UNITED STATES,ASIA,1,2
+UNITED STATES,EUROPE,1,3
+UNITED STATES,MIDDLE EAST,1,4
+VIETNAM,AFRICA,2,0
+VIETNAM,AMERICA,2,1
+VIETNAM,ASIA,2,2
+VIETNAM,EUROPE,2,3
+VIETNAM,MIDDLE EAST,2,4
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testCrossJoinAndCaseWhen.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testCrossJoinAndCaseWhen.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testCrossJoinAndCaseWhen.result
new file mode 100644
index 0000000..a4c33f8
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testCrossJoinAndCaseWhen.result
@@ -0,0 +1,27 @@
+r_regionkey,n_regionkey,cond
+-------------------------------
+0,0,zero
+0,0,zero
+0,0,zero
+0,0,zero
+0,0,zero
+1,1,one
+1,1,one
+1,1,one
+1,1,one
+1,1,one
+2,2,two
+2,2,two
+2,2,two
+2,2,two
+2,2,two
+3,3,three
+3,3,three
+3,3,three
+3,3,three
+3,3,three
+4,4,four
+4,4,four
+4,4,four
+4,4,four
+4,4,four
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testCrossJoinWithAsterisk1.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testCrossJoinWithAsterisk1.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testCrossJoinWithAsterisk1.result
new file mode 100644
index 0000000..f4e8c88
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testCrossJoinWithAsterisk1.result
@@ -0,0 +1,27 @@
+r_regionkey,r_name,r_comment,c_custkey,c_name,c_address,c_nationkey,c_phone,c_acctbal,c_mktsegment,c_comment
+-------------------------------
+0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e
+0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref
+0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov
+0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou
+0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor
+1,AMERICA,hs use ironic, even requests. s,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e
+1,AMERICA,hs use ironic, even requests. s,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref
+1,AMERICA,hs use ironic, even requests. s,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov
+1,AMERICA,hs use ironic, even requests. s,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou
+1,AMERICA,hs use ironic, even requests. s,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor
+2,ASIA,ges. thinly even pinto beans ca,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e
+2,ASIA,ges. thinly even pinto beans ca,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref
+2,ASIA,ges. thinly even pinto beans ca,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov
+2,ASIA,ges. thinly even pinto beans ca,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou
+2,ASIA,ges. thinly even pinto beans ca,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor
+3,EUROPE,ly final courts cajole furiously final excuse,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e
+3,EUROPE,ly final courts cajole furiously final excuse,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref
+3,EUROPE,ly final courts cajole furiously final excuse,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov
+3,EUROPE,ly final courts cajole furiously final excuse,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou
+3,EUROPE,ly final courts cajole furiously final excuse,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor
+4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e
+4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref
+4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov
+4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou
+4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testCrossJoinWithAsterisk2.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testCrossJoinWithAsterisk2.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testCrossJoinWithAsterisk2.result
new file mode 100644
index 0000000..f4e8c88
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testCrossJoinWithAsterisk2.result
@@ -0,0 +1,27 @@
+r_regionkey,r_name,r_comment,c_custkey,c_name,c_address,c_nationkey,c_phone,c_acctbal,c_mktsegment,c_comment
+-------------------------------
+0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e
+0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref
+0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov
+0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou
+0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor
+1,AMERICA,hs use ironic, even requests. s,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e
+1,AMERICA,hs use ironic, even requests. s,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref
+1,AMERICA,hs use ironic, even requests. s,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov
+1,AMERICA,hs use ironic, even requests. s,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou
+1,AMERICA,hs use ironic, even requests. s,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor
+2,ASIA,ges. thinly even pinto beans ca,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e
+2,ASIA,ges. thinly even pinto beans ca,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref
+2,ASIA,ges. thinly even pinto beans ca,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov
+2,ASIA,ges. thinly even pinto beans ca,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou
+2,ASIA,ges. thinly even pinto beans ca,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor
+3,EUROPE,ly final courts cajole furiously final excuse,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e
+3,EUROPE,ly final courts cajole furiously final excuse,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref
+3,EUROPE,ly final courts cajole furiously final excuse,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov
+3,EUROPE,ly final courts cajole furiously final excuse,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou
+3,EUROPE,ly final courts cajole furiously final excuse,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor
+4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e
+4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref
+4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov
+4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou
+4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testCrossJoinWithAsterisk3.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testCrossJoinWithAsterisk3.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testCrossJoinWithAsterisk3.result
new file mode 100644
index 0000000..9db83f0
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testCrossJoinWithAsterisk3.result
@@ -0,0 +1,27 @@
+c_custkey,c_name,c_address,c_nationkey,c_phone,c_acctbal,c_mktsegment,c_comment,r_regionkey,r_name,r_comment
+-------------------------------
+1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e,0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to
+1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e,1,AMERICA,hs use ironic, even requests. s
+1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e,2,ASIA,ges. thinly even pinto beans ca
+1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e,3,EUROPE,ly final courts cajole furiously final excuse
+1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e,4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl
+2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref,0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to
+2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref,1,AMERICA,hs use ironic, even requests. s
+2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref,2,ASIA,ges. thinly even pinto beans ca
+2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref,3,EUROPE,ly final courts cajole furiously final excuse
+2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref,4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl
+3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov,0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to
+3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov,1,AMERICA,hs use ironic, even requests. s
+3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov,2,ASIA,ges. thinly even pinto beans ca
+3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov,3,EUROPE,ly final courts cajole furiously final excuse
+3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov,4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl
+4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou,0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to
+4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou,1,AMERICA,hs use ironic, even requests. s
+4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou,2,ASIA,ges. thinly even pinto beans ca
+4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou,3,EUROPE,ly final courts cajole furiously final excuse
+4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou,4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl
+5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor,0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to
+5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor,1,AMERICA,hs use ironic, even requests. s
+5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor,2,ASIA,ges. thinly even pinto beans ca
+5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor,3,EUROPE,ly final courts cajole furiously final excuse
+5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor,4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testCrossJoinWithAsterisk4.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testCrossJoinWithAsterisk4.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testCrossJoinWithAsterisk4.result
new file mode 100644
index 0000000..23d985e
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testCrossJoinWithAsterisk4.result
@@ -0,0 +1,27 @@
+len,c_custkey,c_name,c_address,c_nationkey,c_phone,c_acctbal,c_mktsegment,c_comment,r_regionkey,r_name,r_comment,?multiply
+-------------------------------
+31,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e,1,AMERICA,hs use ironic, even requests. s,10
+31,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref,1,AMERICA,hs use ironic, even requests. s,20
+31,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov,1,AMERICA,hs use ironic, even requests. s,30
+31,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou,1,AMERICA,hs use ironic, even requests. s,40
+31,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor,1,AMERICA,hs use ironic, even requests. s,50
+31,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e,2,ASIA,ges. thinly even pinto beans ca,10
+31,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref,2,ASIA,ges. thinly even pinto beans ca,20
+31,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov,2,ASIA,ges. thinly even pinto beans ca,30
+31,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou,2,ASIA,ges. thinly even pinto beans ca,40
+31,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor,2,ASIA,ges. thinly even pinto beans ca,50
+45,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e,3,EUROPE,ly final courts cajole furiously final excuse,10
+45,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref,3,EUROPE,ly final courts cajole furiously final excuse,20
+45,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov,3,EUROPE,ly final courts cajole furiously final excuse,30
+45,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou,3,EUROPE,ly final courts cajole furiously final excuse,40
+45,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor,3,EUROPE,ly final courts cajole furiously final excuse,50
+108,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e,4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,10
+108,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref,4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,20
+108,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov,4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,30
+108,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou,4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,40
+108,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor,4,MIDDLE EAST,uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl,50
+115,1,Customer#000000001,IVhzIApeRb ot,c,E,15,25-989-741-2988,711.56,BUILDING,to the even, regular platelets. regular, ironic epitaphs nag e,0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,10
+115,2,Customer#000000002,XSTf4,NCwDVaWNe6tEgvwfmRchLXak,13,23-768-687-3665,121.65,AUTOMOBILE,l accounts. blithely ironic theodolites integrate boldly: caref,0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,20
+115,3,Customer#000000003,MG9kdTD2WBHm,1,11-719-748-3364,7498.12,AUTOMOBILE, deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov,0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,30
+115,4,Customer#000000004,XxVSJsLAGtn,4,14-128-190-5944,2866.83,MACHINERY, requests. final, regular ideas sleep final accou,0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,40
+115,5,Customer#000000005,KvpyuHCplrB84WgAiGV6sYpZq7Tj,3,13-750-942-6364,794.47,HOUSEHOLD,n accounts will have to unwind. foxes cajole accor,0,AFRICA,lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to ,50
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testCrossJoinWithEmptyTable1.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testCrossJoinWithEmptyTable1.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testCrossJoinWithEmptyTable1.result
new file mode 100644
index 0000000..6f07515
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testCrossJoinWithEmptyTable1.result
@@ -0,0 +1,2 @@
+c_custkey,o_orderkey
+-------------------------------
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testFullOuterJoin1.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testFullOuterJoin1.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testFullOuterJoin1.result
new file mode 100644
index 0000000..81dc055
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testFullOuterJoin1.result
@@ -0,0 +1,7 @@
+c_custkey,o_orderkey
+-------------------------------
+1,1
+2,2
+3,3
+4,0
+5,0
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testFullOuterJoinWithEmptyTable1.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testFullOuterJoinWithEmptyTable1.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testFullOuterJoinWithEmptyTable1.result
new file mode 100644
index 0000000..9124c6c
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testFullOuterJoinWithEmptyTable1.result
@@ -0,0 +1,7 @@
+c_custkey,o_orderkey
+-------------------------------
+1,0
+2,0
+3,0
+4,0
+5,0
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testInnerJoinWithEmptyTable.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testInnerJoinWithEmptyTable.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testInnerJoinWithEmptyTable.result
new file mode 100644
index 0000000..6f07515
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testInnerJoinWithEmptyTable.result
@@ -0,0 +1,2 @@
+c_custkey,o_orderkey
+-------------------------------
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testJoinCoReferredEvals1.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testJoinCoReferredEvals1.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testJoinCoReferredEvals1.result
new file mode 100644
index 0000000..b24e47e
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testJoinCoReferredEvals1.result
@@ -0,0 +1,27 @@
+r_regionkey,n_regionkey,plus
+-------------------------------
+0,0,0
+0,0,0
+0,0,0
+0,0,0
+0,0,0
+1,1,2
+1,1,2
+1,1,2
+1,1,2
+1,1,2
+2,2,4
+2,2,4
+2,2,4
+2,2,4
+2,2,4
+3,3,6
+3,3,6
+3,3,6
+3,3,6
+3,3,6
+4,4,8
+4,4,8
+4,4,8
+4,4,8
+4,4,8
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testJoinCoReferredEvalsWithSameExprs1.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testJoinCoReferredEvalsWithSameExprs1.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testJoinCoReferredEvalsWithSameExprs1.result
new file mode 100644
index 0000000..23776b6
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testJoinCoReferredEvalsWithSameExprs1.result
@@ -0,0 +1,22 @@
+v1,n_regionkey,r_regionkey,plus1,plus2,result
+-------------------------------
+2,1,1,2,2,1
+3,1,1,2,2,1
+4,1,1,2,2,1
+8,4,4,8,8,4
+9,3,3,6,6,3
+10,2,2,4,4,2
+10,3,3,6,6,3
+11,2,2,4,4,2
+14,2,2,4,4,2
+14,4,4,8,8,4
+15,4,4,8,8,4
+17,4,4,8,8,4
+18,1,1,2,2,1
+20,2,2,4,4,2
+22,3,3,6,6,3
+23,2,2,4,4,2
+24,4,4,8,8,4
+25,1,1,2,2,1
+25,3,3,6,6,3
+26,3,3,6,6,3
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testJoinCoReferredEvalsWithSameExprs2.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testJoinCoReferredEvalsWithSameExprs2.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testJoinCoReferredEvalsWithSameExprs2.result
new file mode 100644
index 0000000..0e31362
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testJoinCoReferredEvalsWithSameExprs2.result
@@ -0,0 +1,22 @@
+v1,n_regionkey,r_regionkey,plus1,plus2,result,total
+-------------------------------
+2,1,1,2,2,1,2
+3,1,1,2,2,1,2
+4,1,1,2,2,1,2
+8,4,4,8,8,4,8
+9,3,3,6,6,3,6
+10,2,2,4,4,2,4
+10,3,3,6,6,3,6
+11,2,2,4,4,2,4
+14,2,2,4,4,2,4
+14,4,4,8,8,4,8
+15,4,4,8,8,4,8
+17,4,4,8,8,4,8
+18,1,1,2,2,1,2
+20,2,2,4,4,2,4
+22,3,3,6,6,3,6
+23,2,2,4,4,2,4
+24,4,4,8,8,4,8
+25,1,1,2,2,1,2
+25,3,3,6,6,3,6
+26,3,3,6,6,3,6
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testJoinOnMultipleDatabases.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testJoinOnMultipleDatabases.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testJoinOnMultipleDatabases.result
new file mode 100644
index 0000000..dc0968f
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testJoinOnMultipleDatabases.result
@@ -0,0 +1,5 @@
+s_acctbal,s_name,n_name,p_partkey,p_mfgr,s_address,s_phone,s_comment
+-------------------------------
+4032.68,Supplier#000000002,ETHIOPIA,1,Manufacturer#1,89eJ5ksX3ImxJQBvxObC,,15-679-861-2259, slyly bold instructions. idle dependen
+4192.4,Supplier#000000003,ARGENTINA,2,Manufacturer#1,q1,G3Pj6OjIuUYfUoH18BFTKP5aU9bEV3,11-383-516-1199,blithely silent requests after the express dependencies are sl
+4641.08,Supplier#000000004,MOROCCO,3,Manufacturer#4,Bk7ah4CK8SYQTepEmvMkkgMwg,25-843-787-7479,riously even requests above the exp
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testLeftOuterJoin1.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testLeftOuterJoin1.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testLeftOuterJoin1.result
new file mode 100644
index 0000000..8893e12
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testLeftOuterJoin1.result
@@ -0,0 +1,7 @@
+c_custkey,o_orderkey,o_orderstatus,o_orderdate
+-------------------------------
+1,1,O,1996-01-02
+2,2,O,1996-12-01
+3,3,F,1993-10-14
+4,0,,
+5,0,,
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testLeftOuterJoinWithConstantExpr1.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testLeftOuterJoinWithConstantExpr1.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testLeftOuterJoinWithConstantExpr1.result
new file mode 100644
index 0000000..ed28172
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testLeftOuterJoinWithConstantExpr1.result
@@ -0,0 +1,7 @@
+c_custkey,o_orderkey,val
+-------------------------------
+1,1,val
+2,2,val
+3,3,val
+4,0,val
+5,0,val
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testLeftOuterJoinWithConstantExpr2.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testLeftOuterJoinWithConstantExpr2.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testLeftOuterJoinWithConstantExpr2.result
new file mode 100644
index 0000000..ed28172
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testLeftOuterJoinWithConstantExpr2.result
@@ -0,0 +1,7 @@
+c_custkey,o_orderkey,val
+-------------------------------
+1,1,val
+2,2,val
+3,3,val
+4,0,val
+5,0,val
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testLeftOuterJoinWithConstantExpr3.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testLeftOuterJoinWithConstantExpr3.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testLeftOuterJoinWithConstantExpr3.result
new file mode 100644
index 0000000..955cf44
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testLeftOuterJoinWithConstantExpr3.result
@@ -0,0 +1,7 @@
+c_custkey,const_val,min_name
+-------------------------------
+1,123,Customer#000000001
+2,123,Customer#000000002
+3,123,Customer#000000003
+4,123,Customer#000000004
+5,123,Customer#000000005
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testLeftOuterJoinWithEmptyTable1.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testLeftOuterJoinWithEmptyTable1.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testLeftOuterJoinWithEmptyTable1.result
new file mode 100644
index 0000000..5e85b28
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testLeftOuterJoinWithEmptyTable1.result
@@ -0,0 +1,7 @@
+c_custkey,o_orderkey,o_orderstatus,o_orderdate
+-------------------------------
+1,0,,
+2,0,,
+3,0,,
+4,0,,
+5,0,,
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testLeftOuterJoinWithEmptyTable2.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testLeftOuterJoinWithEmptyTable2.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testLeftOuterJoinWithEmptyTable2.result
new file mode 100644
index 0000000..3bf0ed2
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testLeftOuterJoinWithEmptyTable2.result
@@ -0,0 +1,7 @@
+c_custkey,?sum,?max_1,?max_2
+-------------------------------
+1,0,,
+2,0,,
+3,0,,
+4,0,,
+5,0,,
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testLeftOuterJoinWithEmptyTable3.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testLeftOuterJoinWithEmptyTable3.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testLeftOuterJoinWithEmptyTable3.result
new file mode 100644
index 0000000..f3e11cb
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testLeftOuterJoinWithEmptyTable3.result
@@ -0,0 +1,7 @@
+?count
+-------------------------------
+1
+1
+1
+1
+1
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testLeftOuterJoinWithEmptyTable4.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testLeftOuterJoinWithEmptyTable4.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testLeftOuterJoinWithEmptyTable4.result
new file mode 100644
index 0000000..b9ac208
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testLeftOuterJoinWithEmptyTable4.result
@@ -0,0 +1,4 @@
+?max,?sum_1,?max_2,?max_3
+-------------------------------
+5,6,O,1996-12-01
+5,0,,
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testOuterJoinAndCaseWhen1.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testOuterJoinAndCaseWhen1.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testOuterJoinAndCaseWhen1.result
new file mode 100644
index 0000000..f032d32
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testOuterJoinAndCaseWhen1.result
@@ -0,0 +1,7 @@
+id,name,id2,name2,c1,c2
+-------------------------------
+1,ooo,1,,9991231,ooo
+2,ppp,2,,9991231,ppp
+3,qqq,0,,9991231,9991231
+4,rrr,0,,9991231,9991231
+5,xxx,0,,9991231,9991231
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testRightOuterJoin1.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testRightOuterJoin1.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testRightOuterJoin1.result
new file mode 100644
index 0000000..81dc055
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testRightOuterJoin1.result
@@ -0,0 +1,7 @@
+c_custkey,o_orderkey
+-------------------------------
+1,1
+2,2
+3,3
+4,0
+5,0
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testRightOuterJoinWithEmptyTable1.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testRightOuterJoinWithEmptyTable1.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testRightOuterJoinWithEmptyTable1.result
new file mode 100644
index 0000000..9124c6c
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testRightOuterJoinWithEmptyTable1.result
@@ -0,0 +1,7 @@
+c_custkey,o_orderkey
+-------------------------------
+1,0
+2,0
+3,0
+4,0
+5,0
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testTPCHQ2Join.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testTPCHQ2Join.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testTPCHQ2Join.result
new file mode 100644
index 0000000..dc0968f
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testTPCHQ2Join.result
@@ -0,0 +1,5 @@
+s_acctbal,s_name,n_name,p_partkey,p_mfgr,s_address,s_phone,s_comment
+-------------------------------
+4032.68,Supplier#000000002,ETHIOPIA,1,Manufacturer#1,89eJ5ksX3ImxJQBvxObC,,15-679-861-2259, slyly bold instructions. idle dependen
+4192.4,Supplier#000000003,ARGENTINA,2,Manufacturer#1,q1,G3Pj6OjIuUYfUoH18BFTKP5aU9bEV3,11-383-516-1199,blithely silent requests after the express dependencies are sl
+4641.08,Supplier#000000004,MOROCCO,3,Manufacturer#4,Bk7ah4CK8SYQTepEmvMkkgMwg,25-843-787-7479,riously even requests above the exp
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testWhereClauseJoin1.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testWhereClauseJoin1.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testWhereClauseJoin1.result
new file mode 100644
index 0000000..5c54325
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testWhereClauseJoin1.result
@@ -0,0 +1,27 @@
+n_name,r_name,n_regionkey,r_regionkey
+-------------------------------
+ALGERIA,AFRICA,0,0
+ARGENTINA,AMERICA,1,1
+BRAZIL,AMERICA,1,1
+CANADA,AMERICA,1,1
+EGYPT,MIDDLE EAST,4,4
+ETHIOPIA,AFRICA,0,0
+FRANCE,EUROPE,3,3
+GERMANY,EUROPE,3,3
+INDIA,ASIA,2,2
+INDONESIA,ASIA,2,2
+IRAN,MIDDLE EAST,4,4
+IRAQ,MIDDLE EAST,4,4
+JAPAN,ASIA,2,2
+JORDAN,MIDDLE EAST,4,4
+KENYA,AFRICA,0,0
+MOROCCO,AFRICA,0,0
+MOZAMBIQUE,AFRICA,0,0
+PERU,AMERICA,1,1
+CHINA,ASIA,2,2
+ROMANIA,EUROPE,3,3
+SAUDI ARABIA,MIDDLE EAST,4,4
+VIETNAM,ASIA,2,2
+RUSSIA,EUROPE,3,3
+UNITED KINGDOM,EUROPE,3,3
+UNITED STATES,AMERICA,1,1
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testWhereClauseJoin2.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testWhereClauseJoin2.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testWhereClauseJoin2.result
new file mode 100644
index 0000000..178ddd6
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testWhereClauseJoin2.result
@@ -0,0 +1,27 @@
+n_name,r_name
+-------------------------------
+ALGERIA,AFRICA
+ARGENTINA,AMERICA
+BRAZIL,AMERICA
+CANADA,AMERICA
+EGYPT,MIDDLE EAST
+ETHIOPIA,AFRICA
+FRANCE,EUROPE
+GERMANY,EUROPE
+INDIA,ASIA
+INDONESIA,ASIA
+IRAN,MIDDLE EAST
+IRAQ,MIDDLE EAST
+JAPAN,ASIA
+JORDAN,MIDDLE EAST
+KENYA,AFRICA
+MOROCCO,AFRICA
+MOZAMBIQUE,AFRICA
+PERU,AMERICA
+CHINA,ASIA
+ROMANIA,EUROPE
+SAUDI ARABIA,MIDDLE EAST
+VIETNAM,ASIA
+RUSSIA,EUROPE
+UNITED KINGDOM,EUROPE
+UNITED STATES,AMERICA
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testWhereClauseJoin3.result
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testWhereClauseJoin3.result b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testWhereClauseJoin3.result
new file mode 100644
index 0000000..9f3123a
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/results/TestJoinBroadcast/testWhereClauseJoin3.result
@@ -0,0 +1,27 @@
+n_name,r_name,p1,p2
+-------------------------------
+ALGERIA,AFRICA,1,1
+ARGENTINA,AMERICA,2,2
+BRAZIL,AMERICA,3,2
+CANADA,AMERICA,4,2
+EGYPT,MIDDLE EAST,5,5
+ETHIOPIA,AFRICA,6,1
+FRANCE,EUROPE,7,4
+GERMANY,EUROPE,8,4
+INDIA,ASIA,9,3
+INDONESIA,ASIA,10,3
+IRAN,MIDDLE EAST,11,5
+IRAQ,MIDDLE EAST,12,5
+JAPAN,ASIA,13,3
+JORDAN,MIDDLE EAST,14,5
+KENYA,AFRICA,15,1
+MOROCCO,AFRICA,16,1
+MOZAMBIQUE,AFRICA,17,1
+PERU,AMERICA,18,2
+CHINA,ASIA,19,3
+ROMANIA,EUROPE,20,4
+SAUDI ARABIA,MIDDLE EAST,21,5
+VIETNAM,ASIA,22,3
+RUSSIA,EUROPE,23,4
+UNITED KINGDOM,EUROPE,24,4
+UNITED STATES,AMERICA,25,2
\ No newline at end of file
[4/4] git commit: TAJO-725: Broadcast JOIN should supports multiple
tables. (hyoungjunkim via jaehwa)
Posted by bl...@apache.org.
TAJO-725: Broadcast JOIN should supports multiple tables. (hyoungjunkim via jaehwa)
Project: http://git-wip-us.apache.org/repos/asf/tajo/repo
Commit: http://git-wip-us.apache.org/repos/asf/tajo/commit/464f3e52
Tree: http://git-wip-us.apache.org/repos/asf/tajo/tree/464f3e52
Diff: http://git-wip-us.apache.org/repos/asf/tajo/diff/464f3e52
Branch: refs/heads/branch-0.8.0
Commit: 464f3e5224d6c9e2fd49b95238169b80b93ece9f
Parents: e5519cf
Author: blrunner <jh...@gruter.com>
Authored: Sat Apr 5 08:21:59 2014 +0900
Committer: blrunner <jh...@gruter.com>
Committed: Sat Apr 5 08:21:59 2014 +0900
----------------------------------------------------------------------
CHANGES.txt | 2 +
.../org/apache/tajo/catalog/CatalogServer.java | 9 +-
.../java/org/apache/tajo/client/TajoClient.java | 2 +-
.../org/apache/tajo/jdbc/TajoResultSet.java | 4 +
.../java/org/apache/tajo/conf/TajoConf.java | 1 +
.../tajo/engine/function/string/Concat_ws.java | 3 -
.../planner/BroadcastJoinPlanVisitor.java | 86 ++++
.../engine/planner/PhysicalPlannerImpl.java | 3 +
.../engine/planner/RangePartitionAlgorithm.java | 4 +-
.../engine/planner/global/GlobalPlanner.java | 69 ++--
.../planner/graph/SimpleDirectedGraph.java | 2 +-
.../tajo/engine/planner/logical/JoinNode.java | 22 +
.../tajo/engine/planner/logical/ScanNode.java | 9 +
.../planner/physical/BinaryPhysicalExec.java | 3 +-
.../planner/physical/HashFullOuterJoinExec.java | 11 +-
.../engine/planner/physical/HashJoinExec.java | 23 +-
.../planner/physical/HashLeftAntiJoinExec.java | 6 +-
.../planner/physical/HashLeftOuterJoinExec.java | 11 +-
.../planner/physical/HashLeftSemiJoinExec.java | 6 +-
.../engine/planner/physical/SeqScanExec.java | 118 +++++-
.../apache/tajo/engine/utils/TupleCache.java | 122 ++++++
.../apache/tajo/engine/utils/TupleCacheKey.java | 60 +++
.../tajo/engine/utils/TupleCacheScanner.java | 109 +++++
.../tajo/master/DefaultTaskScheduler.java | 30 +-
.../org/apache/tajo/master/GlobalEngine.java | 25 +-
.../apache/tajo/master/LazyTaskScheduler.java | 10 +-
.../master/event/FragmentScheduleEvent.java | 16 +-
.../master/querymaster/QueryMasterTask.java | 6 +-
.../tajo/master/querymaster/QueryUnit.java | 18 +-
.../master/querymaster/QueryUnitAttempt.java | 6 +-
.../tajo/master/querymaster/Repartitioner.java | 94 +++--
.../tajo/master/querymaster/SubQuery.java | 88 ++--
.../apache/tajo/worker/TaskAttemptContext.java | 8 +
.../java/org/apache/tajo/worker/TaskRunner.java | 12 +-
.../src/main/resources/webapps/admin/query.jsp | 3 +
.../java/org/apache/tajo/QueryTestCaseBase.java | 4 +-
.../org/apache/tajo/TajoTestingCluster.java | 7 +
.../org/apache/tajo/client/TestTajoClient.java | 1 -
.../planner/global/TestBroadcastJoinPlan.java | 400 +++++++++++++++++++
.../tajo/engine/query/TestJoinBroadcast.java | 374 +++++++++++++++++
.../apache/tajo/engine/query/TestJoinQuery.java | 13 +
.../apache/tajo/engine/util/TestTupleCache.java | 89 +++++
.../tajo/master/TestExecutionBlockCursor.java | 8 +-
.../querymaster/TestQueryUnitStatusUpdate.java | 8 +-
.../customer_large/customer.tbl | 100 +++++
.../lineitem_large/lineitem.tbl | 97 +++++
.../create_customer_large_ddl.sql | 7 +
.../create_lineitem_large_ddl.sql | 7 +
.../queries/TestJoinBroadcast/oj_table1_ddl.sql | 6 +
.../queries/TestJoinBroadcast/oj_table2_ddl.sql | 6 +
.../testBroadcastBasicJoin.sql | 11 +
.../TestJoinBroadcast/testBroadcastSubquery.sql | 11 +
.../testBroadcastSubquery2.sql | 19 +
.../testBroadcastTwoPartJoin.sql | 15 +
.../queries/TestJoinBroadcast/testCrossJoin.sql | 1 +
.../testCrossJoinAndCaseWhen.sql | 18 +
.../testCrossJoinWithAsterisk1.sql | 1 +
.../testCrossJoinWithAsterisk2.sql | 1 +
.../testCrossJoinWithAsterisk3.sql | 1 +
.../testCrossJoinWithAsterisk4.sql | 1 +
.../testCrossJoinWithEmptyTable1.sql | 8 +
.../TestJoinBroadcast/testFullOuterJoin1.sql | 8 +
.../testFullOuterJoinWithEmptyTable1.sql | 8 +
.../testInnerJoinWithEmptyTable.sql | 8 +
.../testJoinCoReferredEvals1.sql | 11 +
.../testJoinCoReferredEvalsWithSameExprs1.sql | 14 +
.../testJoinCoReferredEvalsWithSameExprs2.sql | 22 +
.../testJoinOnMultipleDatabases.sql | 25 ++
.../TestJoinBroadcast/testLeftOuterJoin1.sql | 9 +
.../testLeftOuterJoinWithConstantExpr1.sql | 9 +
.../testLeftOuterJoinWithConstantExpr2.sql | 9 +
.../testLeftOuterJoinWithConstantExpr3.sql | 17 +
.../testLeftOuterJoinWithEmptyTable1.sql | 9 +
.../testLeftOuterJoinWithEmptyTable2.sql | 9 +
.../testLeftOuterJoinWithEmptyTable3.sql | 14 +
.../testLeftOuterJoinWithEmptyTable4.sql | 17 +
.../testOuterJoinAndCaseWhen1.sql | 12 +
.../TestJoinBroadcast/testRightOuterJoin1.sql | 8 +
.../testRightOuterJoinWithEmptyTable1.sql | 8 +
.../TestJoinBroadcast/testTPCHQ2Join.sql | 25 ++
.../TestJoinBroadcast/testWhereClauseJoin1.sql | 10 +
.../TestJoinBroadcast/testWhereClauseJoin2.sql | 8 +
.../TestJoinBroadcast/testWhereClauseJoin3.sql | 9 +
.../TestJoinBroadcast/testWhereClauseJoin4.sql | 8 +
.../TestJoinBroadcast/testWhereClauseJoin5.sql | 15 +
.../TestJoinBroadcast/testWhereClauseJoin6.sql | 19 +
.../resources/queries/TestNetTypes/testJoin.sql | 2 +-
.../testBroadcastBasicJoin.result | 99 +++++
.../testBroadcastSubquery.result | 15 +
.../testBroadcastSubquery2.result | 3 +
.../testBroadcastTwoPartJoin.result | 15 +
.../TestJoinBroadcast/testCrossJoin.result | 127 ++++++
.../testCrossJoinAndCaseWhen.result | 27 ++
.../testCrossJoinWithAsterisk1.result | 27 ++
.../testCrossJoinWithAsterisk2.result | 27 ++
.../testCrossJoinWithAsterisk3.result | 27 ++
.../testCrossJoinWithAsterisk4.result | 27 ++
.../testCrossJoinWithEmptyTable1.result | 2 +
.../TestJoinBroadcast/testFullOuterJoin1.result | 7 +
.../testFullOuterJoinWithEmptyTable1.result | 7 +
.../testInnerJoinWithEmptyTable.result | 2 +
.../testJoinCoReferredEvals1.result | 27 ++
...testJoinCoReferredEvalsWithSameExprs1.result | 22 +
...testJoinCoReferredEvalsWithSameExprs2.result | 22 +
.../testJoinOnMultipleDatabases.result | 5 +
.../TestJoinBroadcast/testLeftOuterJoin1.result | 7 +
.../testLeftOuterJoinWithConstantExpr1.result | 7 +
.../testLeftOuterJoinWithConstantExpr2.result | 7 +
.../testLeftOuterJoinWithConstantExpr3.result | 7 +
.../testLeftOuterJoinWithEmptyTable1.result | 7 +
.../testLeftOuterJoinWithEmptyTable2.result | 7 +
.../testLeftOuterJoinWithEmptyTable3.result | 7 +
.../testLeftOuterJoinWithEmptyTable4.result | 4 +
.../testOuterJoinAndCaseWhen1.result | 7 +
.../testRightOuterJoin1.result | 7 +
.../testRightOuterJoinWithEmptyTable1.result | 7 +
.../TestJoinBroadcast/testTPCHQ2Join.result | 5 +
.../testWhereClauseJoin1.result | 27 ++
.../testWhereClauseJoin2.result | 27 ++
.../testWhereClauseJoin3.result | 27 ++
.../testWhereClauseJoin4.result | 27 ++
.../testWhereClauseJoin5.result | 5 +
.../results/TestNetTypes/testJoin.result | 2 +-
.../results/TestUnionQuery/testUnion1.result | 8 +-
.../tajo-core-backend/src/test/tpch/orders.tbl | 6 +-
.../storage/fragment/FragmentConvertor.java | 9 +
.../storage/parquet/TajoRecordMaterializer.java | 2 +-
127 files changed, 3008 insertions(+), 227 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 3be6c34..361bdc6 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -143,6 +143,8 @@ Release 0.8.0 - unreleased
IMPROVEMENTS
+ TAJO-725: Broadcast JOIN should supports multiple tables. (hyoungjunkim via jaehwa)
+
TAJO-735: Remove multiple SLF4J bindings message. (hyoungjunkim via hyunsik)
TAJO-714: Enable setting Parquet tuning parameters. (David Chen via hyunsik)
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java
----------------------------------------------------------------------
diff --git a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java
index 19574bc..91aa219 100644
--- a/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java
+++ b/tajo-catalog/tajo-catalog-server/src/main/java/org/apache/tajo/catalog/CatalogServer.java
@@ -102,7 +102,12 @@ public class CatalogServer extends AbstractService {
this.builtingFuncs = sqlFuncs;
}
-
+ public void reloadBuiltinFunctions(List<FunctionDesc> builtingFuncs) throws ServiceException {
+ this.builtingFuncs = builtingFuncs;
+ initBuiltinFunctions(builtingFuncs);
+ }
+
+ @Override
public void serviceInit(Configuration conf) throws Exception {
Constructor<?> cons;
@@ -828,7 +833,7 @@ public class CatalogServer extends AbstractService {
return BOOL_TRUE;
}
- @Override
+ @Override
public BoolProto dropFunction(RpcController controller, UnregisterFunctionRequest request)
throws ServiceException {
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-client/src/main/java/org/apache/tajo/client/TajoClient.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/client/TajoClient.java b/tajo-client/src/main/java/org/apache/tajo/client/TajoClient.java
index 9d7c4ee..dc51b63 100644
--- a/tajo-client/src/main/java/org/apache/tajo/client/TajoClient.java
+++ b/tajo-client/src/main/java/org/apache/tajo/client/TajoClient.java
@@ -489,7 +489,7 @@ public class TajoClient implements Closeable {
return true;
} else {
if (response.hasErrorMessage()) {
- LOG.error(response.getErrorMessage());
+ System.err.println("ERROR: " + response.getErrorMessage());
}
return false;
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoResultSet.java
----------------------------------------------------------------------
diff --git a/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoResultSet.java b/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoResultSet.java
index d0a41c0..a64cea7 100644
--- a/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoResultSet.java
+++ b/tajo-client/src/main/java/org/apache/tajo/jdbc/TajoResultSet.java
@@ -178,4 +178,8 @@ public class TajoResultSet extends TajoResultSetBase {
public boolean hasResult() {
return scanner != null;
}
+
+ public QueryId getQueryId() {
+ return queryId;
+ }
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-common/src/main/java/org/apache/tajo/conf/TajoConf.java
----------------------------------------------------------------------
diff --git a/tajo-common/src/main/java/org/apache/tajo/conf/TajoConf.java b/tajo-common/src/main/java/org/apache/tajo/conf/TajoConf.java
index 17a06e3..e0f62f7 100644
--- a/tajo-common/src/main/java/org/apache/tajo/conf/TajoConf.java
+++ b/tajo-common/src/main/java/org/apache/tajo/conf/TajoConf.java
@@ -156,6 +156,7 @@ public class TajoConf extends Configuration {
//////////////////////////////////////////
// Distributed Query Execution Parameters
//////////////////////////////////////////
+ DIST_QUERY_BROADCAST_JOIN_AUTO("tajo.dist-query.join.broadcast.auto", true),
DIST_QUERY_BROADCAST_JOIN_THRESHOLD("tajo.dist-query.join.broadcast.threshold-bytes", (long)5 * 1048576),
DIST_QUERY_JOIN_TASK_VOLUME("tajo.dist-query.join.task-volume-mb", 128),
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/function/string/Concat_ws.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/function/string/Concat_ws.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/function/string/Concat_ws.java
index e512b60..dd48151 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/function/string/Concat_ws.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/function/string/Concat_ws.java
@@ -29,9 +29,6 @@ import org.apache.tajo.engine.function.annotation.Description;
import org.apache.tajo.engine.function.annotation.ParamTypes;
import org.apache.tajo.storage.Tuple;
-import java.lang.StringBuffer;
-
-
/**
* Function definition
*
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/BroadcastJoinPlanVisitor.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/BroadcastJoinPlanVisitor.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/BroadcastJoinPlanVisitor.java
new file mode 100644
index 0000000..14ac85f
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/BroadcastJoinPlanVisitor.java
@@ -0,0 +1,86 @@
+/**
+ * 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.tajo.engine.planner;
+
+import org.apache.tajo.engine.planner.global.GlobalPlanner;
+import org.apache.tajo.engine.planner.logical.JoinNode;
+import org.apache.tajo.engine.planner.logical.LogicalNode;
+import org.apache.tajo.engine.planner.logical.NodeType;
+
+import java.util.Stack;
+
+public class BroadcastJoinPlanVisitor extends BasicLogicalPlanVisitor<GlobalPlanner.GlobalPlanContext, LogicalNode> {
+
+ @Override
+ public LogicalNode visitJoin(GlobalPlanner.GlobalPlanContext context, LogicalPlan plan, LogicalPlan.QueryBlock block,
+ JoinNode node, Stack<LogicalNode> stack) throws PlanningException {
+ LogicalNode leftChild = node.getLeftChild();
+ LogicalNode rightChild = node.getRightChild();
+
+ if (isScanNode(leftChild) && isScanNode(rightChild)) {
+ node.setCandidateBroadcast(true);
+ node.getBroadcastTargets().add(leftChild);
+ node.getBroadcastTargets().add(rightChild);
+ return node;
+ }
+
+ if(!isScanNode(leftChild)) {
+ visit(context, plan, block, leftChild, stack);
+ }
+
+ if(!isScanNode(rightChild)) {
+ visit(context, plan, block, rightChild, stack);
+ }
+
+ if(isBroadcastCandidateNode(leftChild) && isBroadcastCandidateNode(rightChild)) {
+ node.setCandidateBroadcast(true);
+ if(leftChild.getType() == NodeType.JOIN) {
+ node.getBroadcastTargets().addAll(((JoinNode)leftChild).getBroadcastTargets());
+ } else {
+ node.getBroadcastTargets().add(leftChild);
+ }
+
+ if(rightChild.getType() == NodeType.JOIN) {
+ node.getBroadcastTargets().addAll(((JoinNode)rightChild).getBroadcastTargets());
+ } else {
+ node.getBroadcastTargets().add(rightChild);
+ }
+ }
+
+ return node;
+ }
+
+ private static boolean isBroadcastCandidateNode(LogicalNode node) {
+ if(node.getType() == NodeType.SCAN ||
+ node.getType() == NodeType.PARTITIONS_SCAN) {
+ return true;
+ }
+
+ if(node.getType() == NodeType.JOIN && ((JoinNode)node).isCandidateBroadcast()) {
+ return true;
+ }
+
+ return false;
+ }
+
+ private static boolean isScanNode(LogicalNode node) {
+ return node.getType() == NodeType.SCAN ||
+ node.getType() == NodeType.PARTITIONS_SCAN;
+ }
+}
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/PhysicalPlannerImpl.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/PhysicalPlannerImpl.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/PhysicalPlannerImpl.java
index 9c28a80..2053e36 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/PhysicalPlannerImpl.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/PhysicalPlannerImpl.java
@@ -833,6 +833,9 @@ public class PhysicalPlannerImpl implements PhysicalPlanner {
public PhysicalExec createScanPlan(TaskAttemptContext ctx, ScanNode scanNode, Stack<LogicalNode> node)
throws IOException {
+ if (ctx.getTable(scanNode.getCanonicalName()) == null) {
+ return new SeqScanExec(ctx, sm, scanNode, null);
+ }
Preconditions.checkNotNull(ctx.getTable(scanNode.getCanonicalName()),
"Error: There is no table matched to %s", scanNode.getCanonicalName() + "(" + scanNode.getTableName() + ")");
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/RangePartitionAlgorithm.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/RangePartitionAlgorithm.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/RangePartitionAlgorithm.java
index 35876ba..a3522c7 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/RangePartitionAlgorithm.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/RangePartitionAlgorithm.java
@@ -114,8 +114,8 @@ public abstract class RangePartitionAlgorithm {
}
break;
case TEXT:
- final char textStart = start instanceof NullDatum ? '0' : start.asChars().charAt(0);
- final char textEnd = end instanceof NullDatum ? '0' : end.asChars().charAt(0);
+ final char textStart = (start instanceof NullDatum || start.size() == 0) ? '0' : start.asChars().charAt(0);
+ final char textEnd = (end instanceof NullDatum || start.size() == 0) ? '0' : end.asChars().charAt(0);
if (isAscending) {
columnCard = new BigDecimal(textEnd - textStart);
} else {
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/global/GlobalPlanner.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/global/GlobalPlanner.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/global/GlobalPlanner.java
index 73de079..bf2bf7d 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/global/GlobalPlanner.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/global/GlobalPlanner.java
@@ -100,6 +100,7 @@ public class GlobalPlanner {
DistributedPlannerVisitor planner = new DistributedPlannerVisitor();
GlobalPlanContext globalPlanContext = new GlobalPlanContext();
globalPlanContext.plan = masterPlan;
+
LOG.info(masterPlan.getLogicalPlan());
// copy a logical plan in order to keep the original logical plan. The distributed planner can modify
@@ -107,6 +108,15 @@ public class GlobalPlanner {
LogicalNode inputPlan = PlannerUtil.clone(masterPlan.getLogicalPlan(),
masterPlan.getLogicalPlan().getRootBlock().getRoot());
+ boolean autoBroadcast = conf.getBoolVar(TajoConf.ConfVars.DIST_QUERY_BROADCAST_JOIN_AUTO);
+ if (autoBroadcast) {
+ // pre-visit finding broadcast join target table
+ // this visiting doesn't make any execution block and change plan
+ BroadcastJoinPlanVisitor broadcastJoinPlanVisitor = new BroadcastJoinPlanVisitor();
+ broadcastJoinPlanVisitor.visit(globalPlanContext,
+ masterPlan.getLogicalPlan(), masterPlan.getLogicalPlan().getRootBlock(), inputPlan, new Stack<LogicalNode>());
+ }
+
// create a distributed execution plan by visiting each logical node.
// Its output is a graph, where each vertex is an execution block, and each edge is a data channel.
// MasterPlan contains them.
@@ -200,53 +210,42 @@ public class GlobalPlanner {
throw new PlanningException("Invalid State");
}
- private static boolean checkIfCanBeOneOfBroadcastJoin(LogicalNode node) {
- return node.getType() == NodeType.SCAN || node.getType() == NodeType.PARTITIONS_SCAN;
- }
-
private ExecutionBlock buildJoinPlan(GlobalPlanContext context, JoinNode joinNode,
- ExecutionBlock leftBlock, ExecutionBlock rightBlock)
+ ExecutionBlock leftBlock, ExecutionBlock rightBlock)
throws PlanningException {
MasterPlan masterPlan = context.plan;
- ExecutionBlock currentBlock;
-
- LogicalNode leftNode = joinNode.getLeftChild();
- LogicalNode rightNode = joinNode.getRightChild();
-
- boolean leftBroadcasted = false;
- boolean rightBroadcasted = false;
+ ExecutionBlock currentBlock = null;
- if (checkIfCanBeOneOfBroadcastJoin(leftNode) && checkIfCanBeOneOfBroadcastJoin(rightNode)) {
- ScanNode leftScan = (ScanNode) leftNode;
- ScanNode rightScan = (ScanNode) rightNode;
+ boolean autoBroadcast = conf.getBoolVar(TajoConf.ConfVars.DIST_QUERY_BROADCAST_JOIN_AUTO);
- TableDesc leftDesc = leftScan.getTableDesc();
- TableDesc rightDesc = rightScan.getTableDesc();
+ if (autoBroadcast && joinNode.isCandidateBroadcast()) {
long broadcastThreshold = conf.getLongVar(TajoConf.ConfVars.DIST_QUERY_BROADCAST_JOIN_THRESHOLD);
-
- if (leftDesc.getStats().getNumBytes() < broadcastThreshold) {
- leftBroadcasted = true;
- }
- if (rightDesc.getStats().getNumBytes() < broadcastThreshold) {
- rightBroadcasted = true;
+ List<LogicalNode> broadtargetTables = new ArrayList<LogicalNode>();
+ int numLargeTables = 0;
+ for(LogicalNode eachNode: joinNode.getBroadcastTargets()) {
+ ScanNode scanNode = (ScanNode)eachNode;
+ TableDesc tableDesc = scanNode.getTableDesc();
+ if (tableDesc.getStats().getNumBytes() < broadcastThreshold) {
+ broadtargetTables.add(scanNode);
+ LOG.info("The table " + scanNode.getCanonicalName() + " ("
+ + scanNode.getTableDesc().getStats().getNumBytes() + ") is marked a broadcasted table");
+ } else {
+ numLargeTables++;
+ }
}
- if (leftBroadcasted || rightBroadcasted) {
+ //large table must be one
+ if (numLargeTables <= 1 && !broadtargetTables.isEmpty()) {
currentBlock = masterPlan.newExecutionBlock();
currentBlock.setPlan(joinNode);
- if (leftBroadcasted) {
- currentBlock.addBroadcastTable(leftScan.getCanonicalName());
- LOG.info("The left table " + rightScan.getCanonicalName() + " ("
- + rightScan.getTableDesc().getStats().getNumBytes() + ") is marked a broadcasted table");
- }
- if (rightBroadcasted) {
- currentBlock.addBroadcastTable(rightScan.getCanonicalName());
- LOG.info("The right table " + rightScan.getCanonicalName() + " ("
- + rightScan.getTableDesc().getStats().getNumBytes() + ") is marked a broadcasted table");
+
+ for (LogicalNode eachBroadcastTargetNode: broadtargetTables) {
+ currentBlock.addBroadcastTable(((ScanNode)eachBroadcastTargetNode).getCanonicalName());
}
- context.execBlockMap.remove(leftScan.getPID());
- context.execBlockMap.remove(rightScan.getPID());
+ for (LogicalNode eachNode: joinNode.getBroadcastTargets()) {
+ context.execBlockMap.remove(eachNode.getPID());
+ }
return currentBlock;
}
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/graph/SimpleDirectedGraph.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/graph/SimpleDirectedGraph.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/graph/SimpleDirectedGraph.java
index 586e643..396eb8b 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/graph/SimpleDirectedGraph.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/graph/SimpleDirectedGraph.java
@@ -118,7 +118,7 @@ public class SimpleDirectedGraph<V, E> implements DirectedGraph<V,E> {
if (reversedEdges.containsKey(v)) {
return reversedEdges.get(v).size();
} else {
- return -1;
+ return 0;
}
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/JoinNode.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/JoinNode.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/JoinNode.java
index 0d607d3..915c66d 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/JoinNode.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/JoinNode.java
@@ -29,11 +29,17 @@ import org.apache.tajo.engine.planner.PlannerUtil;
import org.apache.tajo.engine.planner.Target;
import org.apache.tajo.util.TUtil;
+import java.util.ArrayList;
+import java.util.List;
+
public class JoinNode extends BinaryNode implements Projectable, Cloneable {
@Expose private JoinType joinType;
@Expose private EvalNode joinQual;
@Expose private Target[] targets;
+ @Expose private boolean candidateBroadcast = false;
+ @Expose private List<LogicalNode> broadcastTargets = new ArrayList<LogicalNode>();
+
public JoinNode(int pid) {
super(pid, NodeType.JOIN);
}
@@ -44,6 +50,22 @@ public class JoinNode extends BinaryNode implements Projectable, Cloneable {
setRightChild(right);
}
+ public boolean isCandidateBroadcast() {
+ return candidateBroadcast;
+ }
+
+ public void setCandidateBroadcast(boolean candidateBroadcast) {
+ this.candidateBroadcast = candidateBroadcast;
+ }
+
+ public List<LogicalNode> getBroadcastTargets() {
+ return broadcastTargets;
+ }
+
+ public void setBroadcastTargets(List<LogicalNode> broadcastTargets) {
+ this.broadcastTargets = broadcastTargets;
+ }
+
public JoinType getJoinType() {
return this.joinType;
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/ScanNode.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/ScanNode.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/ScanNode.java
index 17ce4af..1488d8c 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/ScanNode.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/logical/ScanNode.java
@@ -36,6 +36,7 @@ public class ScanNode extends RelationNode implements Projectable, Cloneable {
@Expose protected Schema logicalSchema;
@Expose protected EvalNode qual;
@Expose protected Target[] targets;
+ @Expose protected boolean broadcastTable;
protected ScanNode(int pid, NodeType nodeType) {
super(pid, nodeType);
@@ -78,6 +79,14 @@ public class ScanNode extends RelationNode implements Projectable, Cloneable {
return alias != null;
}
+ public void setBroadcastTable(boolean broadcastTable) {
+ this.broadcastTable = broadcastTable;
+ }
+
+ public boolean isBroadcastTable() {
+ return broadcastTable;
+ }
+
public String getCanonicalName() {
if (CatalogUtil.isFQTableName(this.tableDesc.getName())) {
String databaseName = CatalogUtil.extractQualifier(this.tableDesc.getName());
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/BinaryPhysicalExec.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/BinaryPhysicalExec.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/BinaryPhysicalExec.java
index 35c8f6f..628c18c 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/BinaryPhysicalExec.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/BinaryPhysicalExec.java
@@ -36,6 +36,7 @@ public abstract class BinaryPhysicalExec extends PhysicalExec {
super(context, inSchema, outSchema);
this.leftChild = outer;
this.rightChild = inner;
+ this.inputStats = new TableStats();
}
public PhysicalExec getLeftChild() {
@@ -51,8 +52,6 @@ public abstract class BinaryPhysicalExec extends PhysicalExec {
leftChild.init();
rightChild.init();
progress = 0.0f;
-
- inputStats = new TableStats();
}
@Override
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/HashFullOuterJoinExec.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/HashFullOuterJoinExec.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/HashFullOuterJoinExec.java
index 3875b6d..dc06bd9 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/HashFullOuterJoinExec.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/HashFullOuterJoinExec.java
@@ -159,8 +159,9 @@ public class HashFullOuterJoinExec extends BinaryPhysicalExec {
// getting corresponding right
getKeyLeftTuple(leftTuple, leftKeyTuple); // get a left key tuple
- if (tupleSlots.containsKey(leftKeyTuple)) { // finds right tuples on in-memory hash table.
- iterator = tupleSlots.get(leftKeyTuple).iterator();
+ List<Tuple> rightTuples = tupleSlots.get(leftKeyTuple);
+ if (rightTuples != null) { // found right tuples on in-memory hash table.
+ iterator = rightTuples.iterator();
shouldGetLeftTuple = false;
} else {
//this left tuple doesn't have a match on the right.But full outer join => we should keep it anyway
@@ -202,15 +203,13 @@ public class HashFullOuterJoinExec extends BinaryPhysicalExec {
while ((tuple = rightChild.next()) != null) {
keyTuple = new VTuple(joinKeyPairs.size());
- List<Tuple> newValue;
for (int i = 0; i < rightKeyList.length; i++) {
keyTuple.put(i, tuple.get(rightKeyList[i]));
}
- if (tupleSlots.containsKey(keyTuple)) {
- newValue = tupleSlots.get(keyTuple);
+ List<Tuple> newValue = tupleSlots.get(keyTuple);
+ if (newValue != null) {
newValue.add(tuple);
- tupleSlots.put(keyTuple, newValue);
} else {
newValue = new ArrayList<Tuple>();
newValue.add(tuple);
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/HashJoinExec.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/HashJoinExec.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/HashJoinExec.java
index 9f576a7..0084031 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/HashJoinExec.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/HashJoinExec.java
@@ -19,6 +19,8 @@
package org.apache.tajo.engine.planner.physical;
import org.apache.tajo.catalog.Column;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.Int4Datum;
import org.apache.tajo.engine.eval.EvalNode;
import org.apache.tajo.engine.planner.PlannerUtil;
import org.apache.tajo.engine.planner.Projector;
@@ -63,7 +65,7 @@ public class HashJoinExec extends BinaryPhysicalExec {
leftExec, rightExec);
this.plan = plan;
this.joinQual = plan.getJoinQual();
- this.tupleSlots = new HashMap<Tuple, List<Tuple>>(10000);
+ this.tupleSlots = new HashMap<Tuple, List<Tuple>>(100000);
this.joinKeyPairs = PlannerUtil.getJoinKeyPairs(joinQual,
leftExec.getSchema(), rightExec.getSchema());
@@ -94,16 +96,17 @@ public class HashJoinExec extends BinaryPhysicalExec {
}
}
+ long scanStartTime = 0;
public Tuple next() throws IOException {
if (first) {
loadRightToHashTable();
+ scanStartTime = System.currentTimeMillis();
}
Tuple rightTuple;
boolean found = false;
while(!finished) {
-
if (shouldGetLeftTuple) { // initially, it is true.
// getting new outer
leftTuple = leftChild.next(); // it comes from a disk
@@ -114,8 +117,9 @@ public class HashJoinExec extends BinaryPhysicalExec {
// getting corresponding right
getKeyLeftTuple(leftTuple, leftKeyTuple); // get a left key tuple
- if (tupleSlots.containsKey(leftKeyTuple)) { // finds right tuples on in-memory hash table.
- iterator = tupleSlots.get(leftKeyTuple).iterator();
+ List<Tuple> rightTuples = tupleSlots.get(leftKeyTuple);
+ if (rightTuples != null) { // found right tuples on in-memory hash table.
+ iterator = rightTuples.iterator();
shouldGetLeftTuple = false;
} else {
shouldGetLeftTuple = true;
@@ -140,7 +144,7 @@ public class HashJoinExec extends BinaryPhysicalExec {
}
}
- return outTuple;
+ return new VTuple(outTuple);
}
protected void loadRightToHashTable() throws IOException {
@@ -149,21 +153,21 @@ public class HashJoinExec extends BinaryPhysicalExec {
while ((tuple = rightChild.next()) != null) {
keyTuple = new VTuple(joinKeyPairs.size());
- List<Tuple> newValue;
for (int i = 0; i < rightKeyList.length; i++) {
keyTuple.put(i, tuple.get(rightKeyList[i]));
}
- if (tupleSlots.containsKey(keyTuple)) {
- newValue = tupleSlots.get(keyTuple);
+ List<Tuple> newValue = tupleSlots.get(keyTuple);
+
+ if (newValue != null) {
newValue.add(tuple);
- tupleSlots.put(keyTuple, newValue);
} else {
newValue = new ArrayList<Tuple>();
newValue.add(tuple);
tupleSlots.put(keyTuple, newValue);
}
}
+
first = false;
}
@@ -195,4 +199,5 @@ public class HashJoinExec extends BinaryPhysicalExec {
public JoinNode getPlan() {
return this.plan;
}
+
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/HashLeftAntiJoinExec.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/HashLeftAntiJoinExec.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/HashLeftAntiJoinExec.java
index d7437c2..50a1438 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/HashLeftAntiJoinExec.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/HashLeftAntiJoinExec.java
@@ -25,6 +25,7 @@ import org.apache.tajo.storage.Tuple;
import org.apache.tajo.storage.VTuple;
import java.io.IOException;
+import java.util.List;
/**
* Prepare a hash table of the NOT IN side of the join. Scan the FROM side table.
@@ -74,9 +75,10 @@ public class HashLeftAntiJoinExec extends HashJoinExec {
// Try to find a hash bucket in in-memory hash table
getKeyLeftTuple(leftTuple, leftKeyTuple);
- if (tupleSlots.containsKey(leftKeyTuple)) {
+ List<Tuple> rightTuples = tupleSlots.get(leftKeyTuple);
+ if (rightTuples != null) {
// if found, it gets a hash bucket from the hash table.
- iterator = tupleSlots.get(leftKeyTuple).iterator();
+ iterator = rightTuples.iterator();
} else {
// if not found, it returns a tuple.
frameTuple.set(leftTuple, rightNullTuple);
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/HashLeftOuterJoinExec.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/HashLeftOuterJoinExec.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/HashLeftOuterJoinExec.java
index 9afe8e6..6d57961 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/HashLeftOuterJoinExec.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/HashLeftOuterJoinExec.java
@@ -122,8 +122,9 @@ public class HashLeftOuterJoinExec extends BinaryPhysicalExec {
// getting corresponding right
getKeyLeftTuple(leftTuple, leftKeyTuple); // get a left key tuple
- if (tupleSlots.containsKey(leftKeyTuple)) { // finds right tuples on in-memory hash table.
- iterator = tupleSlots.get(leftKeyTuple).iterator();
+ List<Tuple> rightTuples = tupleSlots.get(leftKeyTuple);
+ if (rightTuples != null) { // found right tuples on in-memory hash table.
+ iterator = rightTuples.iterator();
shouldGetLeftTuple = false;
} else {
// this left tuple doesn't have a match on the right, and output a tuple with the nulls padded rightTuple
@@ -162,15 +163,13 @@ public class HashLeftOuterJoinExec extends BinaryPhysicalExec {
while ((tuple = rightChild.next()) != null) {
keyTuple = new VTuple(joinKeyPairs.size());
- List<Tuple> newValue;
for (int i = 0; i < rightKeyList.length; i++) {
keyTuple.put(i, tuple.get(rightKeyList[i]));
}
- if (tupleSlots.containsKey(keyTuple)) {
- newValue = tupleSlots.get(keyTuple);
+ List<Tuple> newValue = tupleSlots.get(keyTuple);
+ if (newValue != null) {
newValue.add(tuple);
- tupleSlots.put(keyTuple, newValue);
} else {
newValue = new ArrayList<Tuple>();
newValue.add(tuple);
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/HashLeftSemiJoinExec.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/HashLeftSemiJoinExec.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/HashLeftSemiJoinExec.java
index 842c2e2..4fbb5e4 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/HashLeftSemiJoinExec.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/HashLeftSemiJoinExec.java
@@ -25,6 +25,7 @@ import org.apache.tajo.storage.Tuple;
import org.apache.tajo.storage.VTuple;
import java.io.IOException;
+import java.util.List;
/**
* Prepare a hash table of the NOT IN side of the join. Scan the FROM side table.
@@ -76,9 +77,10 @@ public class HashLeftSemiJoinExec extends HashJoinExec {
// Try to find a hash bucket in in-memory hash table
getKeyLeftTuple(leftTuple, leftKeyTuple);
- if (tupleSlots.containsKey(leftKeyTuple)) {
+ List<Tuple> rightTuples = tupleSlots.get(leftKeyTuple);
+ if (rightTuples != null) {
// if found, it gets a hash bucket from the hash table.
- iterator = tupleSlots.get(leftKeyTuple).iterator();
+ iterator = rightTuples.iterator();
} else {
continue;
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/SeqScanExec.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/SeqScanExec.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/SeqScanExec.java
index a59cc2f..6dbcc3f 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/SeqScanExec.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/SeqScanExec.java
@@ -32,21 +32,20 @@ import org.apache.tajo.engine.eval.FieldEval;
import org.apache.tajo.engine.planner.Projector;
import org.apache.tajo.engine.planner.Target;
import org.apache.tajo.engine.planner.logical.ScanNode;
-import org.apache.tajo.engine.utils.SchemaUtil;
-import org.apache.tajo.engine.utils.TupleUtil;
+import org.apache.tajo.engine.utils.*;
import org.apache.tajo.storage.*;
+import org.apache.tajo.storage.Scanner;
import org.apache.tajo.storage.fragment.FileFragment;
import org.apache.tajo.storage.fragment.FragmentConvertor;
import org.apache.tajo.worker.TaskAttemptContext;
import java.io.IOException;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
public class SeqScanExec extends PhysicalExec {
private ScanNode plan;
+
private Scanner scanner = null;
private EvalNode qual = null;
@@ -57,6 +56,10 @@ public class SeqScanExec extends PhysicalExec {
private TableStats inputStats;
+ private TupleCacheKey cacheKey;
+
+ private boolean cacheRead = false;
+
public SeqScanExec(TaskAttemptContext context, AbstractStorageManager sm,
ScanNode plan, CatalogProtos.FragmentProto [] fragments) throws IOException {
super(context, plan.getInSchema(), plan.getOutSchema());
@@ -64,6 +67,11 @@ public class SeqScanExec extends PhysicalExec {
this.plan = plan;
this.qual = plan.getQual();
this.fragments = fragments;
+
+ if (plan.isBroadcastTable()) {
+ cacheKey = new TupleCacheKey(
+ context.getTaskId().getQueryUnitId().getExecutionBlockId().toString(), plan.getTableName());
+ }
}
/**
@@ -84,7 +92,6 @@ public class SeqScanExec extends PhysicalExec {
// Remove partition key columns from an input schema.
this.inSchema = plan.getTableDesc().getSchema();
-
List<FileFragment> fileFragments = FragmentConvertor.convert(FileFragment.class, fragments);
// Get a partition key value from a given path
@@ -118,7 +125,8 @@ public class SeqScanExec extends PhysicalExec {
public void init() throws IOException {
Schema projected;
- if (plan.getTableDesc().hasPartition()
+ if (fragments != null
+ && plan.getTableDesc().hasPartition()
&& plan.getTableDesc().getPartitionMethod().getPartitionType() == CatalogProtos.PartitionType.COLUMN) {
rewriteColumnPartitionedTableSchema();
}
@@ -144,28 +152,93 @@ public class SeqScanExec extends PhysicalExec {
projected = outSchema;
}
+ if (cacheKey != null) {
+ TupleCache tupleCache = TupleCache.getInstance();
+ if (tupleCache.isBroadcastCacheReady(cacheKey)) {
+ openCacheScanner();
+ } else {
+ if (TupleCache.getInstance().lockBroadcastScan(cacheKey)) {
+ scanAndAddCache(projected);
+ openCacheScanner();
+ } else {
+ Object lockMonitor = tupleCache.getLockMonitor();
+ synchronized (lockMonitor) {
+ try {
+ lockMonitor.wait(20 * 1000);
+ } catch (InterruptedException e) {
+ }
+ }
+ if (tupleCache.isBroadcastCacheReady(cacheKey)) {
+ openCacheScanner();
+ } else {
+ initScanner(projected);
+ }
+ }
+ }
+ } else {
+ initScanner(projected);
+ }
+ }
+
+ private void initScanner(Schema projected) throws IOException {
this.projector = new Projector(inSchema, outSchema, plan.getTargets());
- if (fragments.length > 1) {
- this.scanner = new MergeScanner(context.getConf(), plan.getPhysicalSchema(), plan.getTableDesc().getMeta(),
- FragmentConvertor.<FileFragment>convert(context.getConf(), plan.getTableDesc().getMeta().getStoreType(),
- fragments), projected);
- } else {
- this.scanner = StorageManagerFactory.getStorageManager(
- context.getConf()).getScanner(plan.getTableDesc().getMeta(), plan.getPhysicalSchema(), fragments[0],
- projected);
+ if (fragments != null) {
+ if (fragments.length > 1) {
+ this.scanner = new MergeScanner(context.getConf(), plan.getPhysicalSchema(), plan.getTableDesc().getMeta(),
+ FragmentConvertor.<FileFragment>convert(context.getConf(), plan.getTableDesc().getMeta().getStoreType(),
+ fragments), projected
+ );
+ } else {
+ this.scanner = StorageManagerFactory.getStorageManager(
+ context.getConf()).getScanner(plan.getTableDesc().getMeta(), plan.getPhysicalSchema(), fragments[0],
+ projected);
+ }
+ scanner.init();
+ }
+ }
+
+ private void openCacheScanner() throws IOException {
+ Scanner cacheScanner = TupleCache.getInstance().openCacheScanner(cacheKey, plan.getPhysicalSchema());
+ if (cacheScanner != null) {
+ scanner = cacheScanner;
+ cacheRead = true;
}
+ }
+
+ private void scanAndAddCache(Schema projected) throws IOException {
+ initScanner(projected);
- scanner.init();
+ List<Tuple> broadcastTupleCacheList = new ArrayList<Tuple>();
+ while (true) {
+ Tuple tuple = next();
+ if (tuple != null) {
+ broadcastTupleCacheList.add(tuple);
+ } else {
+ break;
+ }
+ }
+
+ scanner.close();
+ scanner = null;
+
+ TupleCache.getInstance().addBroadcastCache(cacheKey, broadcastTupleCacheList);
}
@Override
public Tuple next() throws IOException {
+ if (fragments == null) {
+ return null;
+ }
+
Tuple tuple;
Tuple outTuple = new VTuple(outColumnNum);
if (!plan.hasQual()) {
if ((tuple = scanner.next()) != null) {
+ if (cacheRead) {
+ return tuple;
+ }
projector.eval(tuple, outTuple);
outTuple.setOffset(tuple.getOffset());
return outTuple;
@@ -174,7 +247,9 @@ public class SeqScanExec extends PhysicalExec {
}
} else {
while ((tuple = scanner.next()) != null) {
-
+ if (cacheRead) {
+ return tuple;
+ }
if (qual.eval(inSchema, tuple).isTrue()) {
projector.eval(tuple, outTuple);
return outTuple;
@@ -229,4 +304,13 @@ public class SeqScanExec extends PhysicalExec {
return inputStats;
}
}
+
+ @Override
+ public String toString() {
+ if (scanner != null) {
+ return "SeqScanExec:" + plan.getTableName() + "," + scanner.getClass().getName();
+ } else {
+ return "SeqScanExec:" + plan.getTableName();
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/utils/TupleCache.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/utils/TupleCache.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/utils/TupleCache.java
new file mode 100644
index 0000000..00647b5
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/utils/TupleCache.java
@@ -0,0 +1,122 @@
+/**
+ * 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.tajo.engine.utils;
+
+import org.apache.tajo.ExecutionBlockId;
+import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.storage.Tuple;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class TupleCache {
+ private static TupleCache instance;
+
+ private Map<TupleCacheKey, List<Tuple>> broadcastTupleCacheData
+ = new HashMap<TupleCacheKey, List<Tuple>>();
+ private Map<TupleCacheKey, TupleCacheStatus> broadcastTupleCacheStatus
+ = new HashMap<TupleCacheKey, TupleCacheStatus>();
+
+ private Object lockMonitor = new Object();
+
+ public static enum TupleCacheStatus {
+ STARTED,
+ ENDED
+ };
+
+ private TupleCache() {
+ }
+
+ public static synchronized TupleCache getInstance() {
+ if (instance == null) {
+ instance = new TupleCache();
+ }
+ return instance;
+ }
+
+ public Object getLockMonitor() {
+ return lockMonitor;
+ }
+
+ public void removeBroadcastCache(ExecutionBlockId ebId) {
+ if (ebId == null) {
+ return;
+ }
+ synchronized (lockMonitor) {
+ TupleCacheKey matchedKey = null;
+ for (TupleCacheKey eachKey: broadcastTupleCacheStatus.keySet()) {
+ if (eachKey.ebId.equals(ebId.toString())) {
+ matchedKey = eachKey;
+ break;
+ }
+ }
+ if (matchedKey != null) {
+ broadcastTupleCacheStatus.remove(matchedKey);
+ broadcastTupleCacheData.remove(matchedKey);
+ }
+ }
+ }
+
+ public void addBroadcastCache(TupleCacheKey cacheKey, List<Tuple> cacheData) {
+ synchronized (lockMonitor) {
+ if (broadcastTupleCacheStatus.containsKey(cacheKey) &&
+ broadcastTupleCacheStatus.get(cacheKey) == TupleCacheStatus.ENDED) {
+ return;
+ }
+ broadcastTupleCacheData.put(cacheKey, cacheData);
+ broadcastTupleCacheStatus.put(cacheKey, TupleCacheStatus.ENDED);
+ lockMonitor.notifyAll();
+ }
+ }
+
+ public boolean lockBroadcastScan(TupleCacheKey cacheKey) {
+ synchronized (lockMonitor) {
+ if (broadcastTupleCacheStatus.containsKey(cacheKey)) {
+ return false;
+ } else {
+ broadcastTupleCacheStatus.put(cacheKey, TupleCacheStatus.STARTED);
+ return true;
+ }
+ }
+ }
+
+ public boolean isBroadcastCacheReady(TupleCacheKey cacheKey) {
+ synchronized (lockMonitor) {
+ if (!broadcastTupleCacheStatus.containsKey(cacheKey)) {
+ return false;
+ }
+ return broadcastTupleCacheStatus.get(cacheKey) == TupleCacheStatus.ENDED;
+ }
+ }
+
+ public TupleCacheScanner openCacheScanner(TupleCacheKey cacheKey, Schema schema) throws IOException {
+ synchronized (lockMonitor) {
+ List<Tuple> cacheData = broadcastTupleCacheData.get(cacheKey);
+ if (cacheData != null) {
+ TupleCacheScanner scanner = new TupleCacheScanner(cacheData, schema);
+ scanner.init();
+ return scanner;
+ } else {
+ return null;
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/utils/TupleCacheKey.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/utils/TupleCacheKey.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/utils/TupleCacheKey.java
new file mode 100644
index 0000000..ad9204f
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/utils/TupleCacheKey.java
@@ -0,0 +1,60 @@
+/**
+ * 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.tajo.engine.utils;
+
+public class TupleCacheKey {
+ String ebId;
+ String tableName;
+
+ public TupleCacheKey(String ebId, String tableName) {
+ this.ebId = ebId;
+ this.tableName = tableName;
+ }
+
+ public String getEbId() {
+ return ebId;
+ }
+
+ public void setEbId(String ebId) {
+ this.ebId = ebId;
+ }
+
+ public String getTableName() {
+ return tableName;
+ }
+
+ public void setTableName(String tableName) {
+ this.tableName = tableName;
+ }
+
+ @Override
+ public int hashCode() {
+ return toString().hashCode();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return toString().equals(o.toString());
+ }
+
+ @Override
+ public String toString() {
+ return ebId + "," + tableName;
+ }
+}
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/utils/TupleCacheScanner.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/utils/TupleCacheScanner.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/utils/TupleCacheScanner.java
new file mode 100644
index 0000000..3b91f94
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/utils/TupleCacheScanner.java
@@ -0,0 +1,109 @@
+/**
+ * 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.tajo.engine.utils;
+
+import org.apache.tajo.catalog.Column;
+import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.catalog.statistics.TableStats;
+import org.apache.tajo.storage.Scanner;
+import org.apache.tajo.storage.Tuple;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+
+public class TupleCacheScanner implements Scanner {
+ List<Tuple> cacheData;
+ Schema schema;
+ Iterator<Tuple> it;
+ int count;
+ TableStats inputStats = new TableStats();
+
+ public TupleCacheScanner(List<Tuple> cacheData, Schema schema) {
+ this.cacheData = cacheData;
+ this.schema = schema;
+ }
+ @Override
+ public void init() throws IOException {
+ inputStats.setNumRows(cacheData.size());
+ inputStats.setReadBytes(0);
+ it = cacheData.iterator();
+ count = 0;
+ }
+
+ @Override
+ public Tuple next() throws IOException {
+ if (it.hasNext()) {
+ count++;
+ return it.next();
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public void reset() throws IOException {
+ init();
+ }
+
+ @Override
+ public void close() throws IOException {
+ }
+
+ @Override
+ public boolean isProjectable() {
+ return true;
+ }
+
+ @Override
+ public void setTarget(Column[] targets) {
+ }
+
+ @Override
+ public boolean isSelectable() {
+ return true;
+ }
+
+ @Override
+ public void setSearchCondition(Object expr) {
+ }
+
+ @Override
+ public boolean isSplittable() {
+ return false;
+ }
+
+ @Override
+ public float getProgress() {
+ if (cacheData.size() == 0) {
+ return 1.0f;
+ }
+ return count / cacheData.size();
+ }
+
+ @Override
+ public TableStats getInputStats() {
+ return inputStats;
+ }
+
+ @Override
+ public Schema getSchema() {
+ return schema;
+ }
+}
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/DefaultTaskScheduler.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/DefaultTaskScheduler.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/DefaultTaskScheduler.java
index 28015d5..61fa84e 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/DefaultTaskScheduler.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/DefaultTaskScheduler.java
@@ -1,4 +1,4 @@
-/**
+/*
* 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
@@ -44,6 +44,8 @@ import org.apache.tajo.storage.DataLocation;
import org.apache.tajo.storage.fragment.FileFragment;
import org.apache.tajo.util.NetUtils;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
import java.net.URI;
import java.util.*;
import java.util.Map.Entry;
@@ -186,17 +188,19 @@ public class DefaultTaskScheduler extends AbstractTaskScheduler {
if (context.isLeafQuery()) {
QueryUnitAttemptScheduleContext queryUnitContext = new QueryUnitAttemptScheduleContext();
QueryUnit task = SubQuery.newEmptyQueryUnit(context, queryUnitContext, subQuery, nextTaskId++);
- task.setFragment(castEvent.getLeftFragment());
+ task.addFragment(castEvent.getLeftFragment(), true);
scheduledObjectNum++;
- if (castEvent.getRightFragment() != null) {
- task.setFragment(castEvent.getRightFragment());
- scheduledObjectNum++;
+ if (castEvent.hasRightFragments()) {
+ task.addFragments(castEvent.getRightFragments());
+ //scheduledObjectNum += castEvent.getRightFragments().size();
}
subQuery.getEventHandler().handle(new TaskEvent(task.getId(), TaskEventType.T_SCHEDULE));
} else {
fragmentsForNonLeafTask = new FileFragment[2];
fragmentsForNonLeafTask[0] = castEvent.getLeftFragment();
- fragmentsForNonLeafTask[1] = castEvent.getRightFragment();
+ if (castEvent.hasRightFragments()) {
+ fragmentsForNonLeafTask[1] = castEvent.getRightFragments().toArray(new FileFragment[]{})[0];
+ }
}
} else if (event instanceof FetchScheduleEvent) {
FetchScheduleEvent castEvent = (FetchScheduleEvent) event;
@@ -206,9 +210,9 @@ public class DefaultTaskScheduler extends AbstractTaskScheduler {
scheduledObjectNum++;
for (Entry<String, List<URI>> eachFetch : fetches.entrySet()) {
task.addFetches(eachFetch.getKey(), eachFetch.getValue());
- task.setFragment(fragmentsForNonLeafTask[0]);
+ task.addFragment(fragmentsForNonLeafTask[0], true);
if (fragmentsForNonLeafTask[1] != null) {
- task.setFragment(fragmentsForNonLeafTask[1]);
+ task.addFragment(fragmentsForNonLeafTask[1], true);
}
}
subQuery.getEventHandler().handle(new TaskEvent(task.getId(), TaskEventType.T_SCHEDULE));
@@ -512,10 +516,10 @@ public class DefaultTaskScheduler extends AbstractTaskScheduler {
}
/**
- * volume of a host : 0 ~ n
- * compressed task, amazon s3, unKnown volume : -1
- * remote task : -2
- */
+ * volume of a host : 0 ~ n
+ * compressed task, amazon s3, unKnown volume : -1
+ * remote task : -2
+ */
public int getLowestVolumeId(){
Map.Entry<Integer, Integer> volumeEntry = null;
@@ -558,7 +562,7 @@ public class DefaultTaskScheduler extends AbstractTaskScheduler {
}
public int getRemainingLocalTaskSize(){
- return remainTasksNum.get();
+ return remainTasksNum.get();
}
public String getHost() {
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/GlobalEngine.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/GlobalEngine.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/GlobalEngine.java
index b0c0614..0d5453c 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/GlobalEngine.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/GlobalEngine.java
@@ -201,18 +201,23 @@ public class GlobalEngine extends AbstractService {
}
public QueryId updateQuery(Session session, String sql) throws IOException, SQLException, PlanningException {
- LOG.info("SQL: " + sql);
- // parse the query
- Expr expr = analyzer.parse(sql);
+ try {
+ LOG.info("==========>SQL: " + sql);
+ // parse the query
+ Expr expr = analyzer.parse(sql);
- LogicalPlan plan = createLogicalPlan(session, expr);
- LogicalRootNode rootNode = plan.getRootBlock().getRoot();
+ LogicalPlan plan = createLogicalPlan(session, expr);
+ LogicalRootNode rootNode = plan.getRootBlock().getRoot();
- if (!PlannerUtil.checkIfDDLPlan(rootNode)) {
- throw new SQLException("This is not update query:\n" + sql);
- } else {
- updateQuery(session, rootNode.getChild());
- return QueryIdFactory.NULL_QUERY_ID;
+ if (!PlannerUtil.checkIfDDLPlan(rootNode)) {
+ throw new SQLException("This is not update query:\n" + sql);
+ } else {
+ updateQuery(session, rootNode.getChild());
+ return QueryIdFactory.NULL_QUERY_ID;
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new IOException(e.getMessage(), e);
}
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/LazyTaskScheduler.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/LazyTaskScheduler.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/LazyTaskScheduler.java
index 43e6493..434ea22 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/LazyTaskScheduler.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/LazyTaskScheduler.java
@@ -38,6 +38,7 @@ import org.apache.tajo.master.event.TaskSchedulerEvent.EventType;
import org.apache.tajo.master.querymaster.QueryUnit;
import org.apache.tajo.master.querymaster.QueryUnitAttempt;
import org.apache.tajo.master.querymaster.SubQuery;
+import org.apache.tajo.storage.fragment.FileFragment;
import org.apache.tajo.util.NetUtils;
import java.io.IOException;
@@ -196,7 +197,14 @@ public class LazyTaskScheduler extends AbstractTaskScheduler {
if (event.getType() == EventType.T_SCHEDULE) {
if (event instanceof FragmentScheduleEvent) {
FragmentScheduleEvent castEvent = (FragmentScheduleEvent) event;
- scheduledFragments.addFragment(new FragmentPair(castEvent.getLeftFragment(), castEvent.getRightFragment()));
+ Collection<FileFragment> rightFragments = castEvent.getRightFragments();
+ if (rightFragments == null || rightFragments.isEmpty()) {
+ scheduledFragments.addFragment(new FragmentPair(castEvent.getLeftFragment(), null));
+ } else {
+ for (FileFragment eachFragment: rightFragments) {
+ scheduledFragments.addFragment(new FragmentPair(castEvent.getLeftFragment(), eachFragment));
+ }
+ }
initDiskBalancer(castEvent.getLeftFragment().getHosts(), castEvent.getLeftFragment().getDiskIds());
} else if (event instanceof FetchScheduleEvent) {
FetchScheduleEvent castEvent = (FetchScheduleEvent) event;
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/event/FragmentScheduleEvent.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/event/FragmentScheduleEvent.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/event/FragmentScheduleEvent.java
index 10182a4..8cc17cb 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/event/FragmentScheduleEvent.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/event/FragmentScheduleEvent.java
@@ -21,9 +21,11 @@ package org.apache.tajo.master.event;
import org.apache.tajo.ExecutionBlockId;
import org.apache.tajo.storage.fragment.FileFragment;
+import java.util.Collection;
+
public class FragmentScheduleEvent extends TaskSchedulerEvent {
private final FileFragment leftFragment;
- private final FileFragment rightFragment;
+ private final Collection<FileFragment> rightFragments;
public FragmentScheduleEvent(final EventType eventType, final ExecutionBlockId blockId,
final FileFragment fragment) {
@@ -33,27 +35,27 @@ public class FragmentScheduleEvent extends TaskSchedulerEvent {
public FragmentScheduleEvent(final EventType eventType,
final ExecutionBlockId blockId,
final FileFragment leftFragment,
- final FileFragment rightFragment) {
+ final Collection<FileFragment> rightFragments) {
super(eventType, blockId);
this.leftFragment = leftFragment;
- this.rightFragment = rightFragment;
+ this.rightFragments = rightFragments;
}
- public boolean hasRightFragment() {
- return this.rightFragment != null;
+ public boolean hasRightFragments() {
+ return this.rightFragments != null && !this.rightFragments.isEmpty();
}
public FileFragment getLeftFragment() {
return leftFragment;
}
- public FileFragment getRightFragment() { return rightFragment; }
+ public Collection<FileFragment> getRightFragments() { return rightFragments; }
@Override
public String toString() {
return "FragmentScheduleEvent{" +
"leftFragment=" + leftFragment +
- ", rightFragment=" + rightFragment +
+ ", rightFragments=" + rightFragments +
'}';
}
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/QueryMasterTask.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/QueryMasterTask.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/QueryMasterTask.java
index 39e2177..79b4a08 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/QueryMasterTask.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/QueryMasterTask.java
@@ -298,7 +298,6 @@ public class QueryMasterTask extends CompositeService {
LOG.warn("Query already started");
return;
}
-
CatalogService catalog = getQueryTaskContext().getQueryMasterContext().getWorkerContext().getCatalog();
LogicalPlanner planner = new LogicalPlanner(catalog);
LogicalOptimizer optimizer = new LogicalOptimizer(systemConf);
@@ -315,7 +314,8 @@ public class QueryMasterTask extends CompositeService {
plan = planner.createPlan(session, expr);
optimizer.optimize(plan);
} catch (PlanningException e) {
- e.printStackTrace();
+ //TODO how set query failed(???)
+ LOG.error(e.getMessage(), e);
}
GlobalEngine.DistributedQueryHookManager hookManager = new GlobalEngine.DistributedQueryHookManager();
@@ -341,7 +341,6 @@ public class QueryMasterTask extends CompositeService {
}
}
}
-
MasterPlan masterPlan = new MasterPlan(queryId, queryContext, plan);
queryMasterContext.getGlobalPlanner().build(masterPlan);
@@ -349,7 +348,6 @@ public class QueryMasterTask extends CompositeService {
"", queryTaskContext.getEventHandler(), masterPlan);
dispatcher.register(QueryEventType.class, query);
-
queryTaskContext.getEventHandler().handle(new QueryEvent(queryId, QueryEventType.START));
} catch (Exception e) {
LOG.error(e.getMessage(), e);
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/QueryUnit.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/QueryUnit.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/QueryUnit.java
index c4f86fb..d0fde4f 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/QueryUnit.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/QueryUnit.java
@@ -198,7 +198,7 @@ public class QueryUnit implements EventHandler<TaskEvent> {
readLock.unlock();
}
}
-
+
public void setLogicalPlan(LogicalNode plan) {
this.plan = plan;
@@ -230,7 +230,7 @@ public class QueryUnit implements EventHandler<TaskEvent> {
}
}
- public void setFragment(FileFragment fragment) {
+ public void addFragment(FileFragment fragment, boolean useDataLocation) {
Set<FragmentProto> fragmentProtos;
if (fragMap.containsKey(fragment.getTableName())) {
fragmentProtos = fragMap.get(fragment.getTableName());
@@ -239,15 +239,23 @@ public class QueryUnit implements EventHandler<TaskEvent> {
fragMap.put(fragment.getTableName(), fragmentProtos);
}
fragmentProtos.add(fragment.getProto());
- addDataLocation(fragment);
+ if (useDataLocation) {
+ addDataLocation(fragment);
+ }
totalFragmentNum++;
}
+ public void addFragments(Collection<FileFragment> fragments) {
+ for (FileFragment eachFragment: fragments) {
+ addFragment(eachFragment, false);
+ }
+ }
+
public void setFragment(FragmentPair[] fragmentPairs) {
for (FragmentPair eachFragmentPair : fragmentPairs) {
- this.setFragment(eachFragmentPair.getLeftFragment());
+ this.addFragment(eachFragmentPair.getLeftFragment(), true);
if (eachFragmentPair.getRightFragment() != null) {
- this.setFragment(eachFragmentPair.getRightFragment());
+ this.addFragment(eachFragmentPair.getRightFragment(), true);
}
}
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/QueryUnitAttempt.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/QueryUnitAttempt.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/QueryUnitAttempt.java
index 555b09f..7993ce9 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/QueryUnitAttempt.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/QueryUnitAttempt.java
@@ -261,17 +261,19 @@ public class QueryUnitAttempt implements EventHandler<TaskAttemptEvent> {
private void fillTaskStatistics(TaskCompletionReport report) {
this.progress = 1.0f;
+ List<IntermediateEntry> partitions = new ArrayList<IntermediateEntry>();
+
if (report.getShuffleFileOutputsCount() > 0) {
this.getQueryUnit().setShuffleFileOutputs(report.getShuffleFileOutputsList());
- List<IntermediateEntry> partitions = new ArrayList<IntermediateEntry>();
for (ShuffleFileOutput p : report.getShuffleFileOutputsList()) {
IntermediateEntry entry = new IntermediateEntry(getId().getQueryUnitId().getId(),
getId().getId(), p.getPartId(), getHost(), getPullServerPort());
partitions.add(entry);
}
- this.getQueryUnit().setIntermediateData(partitions);
}
+ this.getQueryUnit().setIntermediateData(partitions);
+
if (report.hasInputStats()) {
this.inputStats = report.getInputStats();
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/Repartitioner.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/Repartitioner.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/Repartitioner.java
index b2adaa4..df8b31b 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/Repartitioner.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/Repartitioner.java
@@ -18,7 +18,6 @@
package org.apache.tajo.master.querymaster;
-import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -80,11 +79,11 @@ public class Repartitioner {
ScanNode[] scans = execBlock.getScanNodes();
Path tablePath;
- FileFragment[] fragments = new FileFragment[2];
- long[] stats = new long[2];
+ FileFragment[] fragments = new FileFragment[scans.length];
+ long[] stats = new long[scans.length];
// initialize variables from the child operators
- for (int i = 0; i < 2; i++) {
+ for (int i = 0; i < scans.length; i++) {
TableDesc tableDesc = masterContext.getTableDescMap().get(scans[i].getCanonicalName());
if (tableDesc == null) { // if it is a real table stored on storage
// TODO - to be fixed (wrong directory)
@@ -115,31 +114,39 @@ public class Repartitioner {
}
}
- LOG.info(String.format("Left Volume: %d, Right Volume: %d", stats[0], stats[1]));
+ //LOG.info(String.format("Left Volume: %d, Right Volume: %d", stats[0], stats[1]));
// If one of inner join tables has no input data,
// it should return zero rows.
JoinNode joinNode = PlannerUtil.findMostBottomNode(execBlock.getPlan(), NodeType.JOIN);
if (joinNode != null) {
- if ( (joinNode.getJoinType().equals(JoinType.INNER)) && (stats[0] == 0 || stats[1] == 0)) {
- return;
+ if ( (joinNode.getJoinType().equals(JoinType.INNER))) {
+ for (int i = 0; i < stats.length; i++) {
+ if (stats[i] == 0) {
+ return;
+ }
+ }
}
}
// Assigning either fragments or fetch urls to query units
- boolean leftSmall = execBlock.isBroadcastTable(scans[0].getCanonicalName());
- boolean rightSmall = execBlock.isBroadcastTable(scans[1].getCanonicalName());
+ boolean isAllBroadcastTable = true;
+ int baseScanIdx = -1;
+ for (int i = 0; i < scans.length; i++) {
+ if (!execBlock.isBroadcastTable(scans[i].getCanonicalName())) {
+ isAllBroadcastTable = false;
+ baseScanIdx = i;
+ }
+ }
- if (leftSmall && rightSmall) {
- LOG.info("[Distributed Join Strategy] : Immediate Two Way Join on Single Machine");
- SubQuery.scheduleFragment(subQuery, fragments[0], fragments[1]);
+ if (isAllBroadcastTable) {
+ LOG.info("[Distributed Join Strategy] : Immediate " + fragments.length + " Way Join on Single Machine");
+ SubQuery.scheduleFragment(subQuery, fragments[0], Arrays.asList(Arrays.copyOfRange(fragments, 1, fragments.length)));
schedulerContext.setEstimatedTaskNum(1);
- } else if (leftSmall ^ rightSmall) {
- int broadcastIdx = leftSmall ? 0 : 1;
- int baseScanIdx = leftSmall ? 1 : 0;
- LOG.info(String.format("[BRDCAST JOIN] base_table=%s, base_volume=%d",
+ } else if (!execBlock.getBroadcastTables().isEmpty()) {
+ LOG.info(String.format("[Distributed Join Strategy] : Broadcast Join, base_table=%s, base_volume=%d",
scans[baseScanIdx].getCanonicalName(), stats[baseScanIdx]));
- scheduleLeafTasksWithBroadcastTable(schedulerContext, subQuery, baseScanIdx, fragments[broadcastIdx]);
+ scheduleLeafTasksWithBroadcastTable(schedulerContext, subQuery, baseScanIdx, fragments);
} else {
LOG.info("[Distributed Join Strategy] : Symmetric Repartition Join");
// The hash map is modeling as follows:
@@ -150,7 +157,7 @@ public class Repartitioner {
for (ScanNode scan : scans) {
SubQuery childSubQuery = masterContext.getSubQuery(TajoIdUtils.createExecutionBlockId(scan.getCanonicalName()));
for (QueryUnit task : childSubQuery.getQueryUnits()) {
- if (task.getIntermediateData() != null) {
+ if (task.getIntermediateData() != null && !task.getIntermediateData().isEmpty()) {
for (IntermediateEntry intermEntry : task.getIntermediateData()) {
if (hashEntries.containsKey(intermEntry.getPartId())) {
Map<String, List<IntermediateEntry>> tbNameToInterm =
@@ -168,6 +175,17 @@ public class Repartitioner {
hashEntries.put(intermEntry.getPartId(), tbNameToInterm);
}
}
+ } else {
+ //if no intermidatedata(empty table), make empty entry
+ int emptyPartitionId = 0;
+ if (hashEntries.containsKey(emptyPartitionId)) {
+ Map<String, List<IntermediateEntry>> tbNameToInterm = hashEntries.get(emptyPartitionId);
+ tbNameToInterm.put(scan.getCanonicalName(), new ArrayList<IntermediateEntry>());
+ } else {
+ Map<String, List<IntermediateEntry>> tbNameToInterm = new HashMap<String, List<IntermediateEntry>>();
+ tbNameToInterm.put(scan.getCanonicalName(), new ArrayList<IntermediateEntry>());
+ hashEntries.put(emptyPartitionId, tbNameToInterm);
+ }
}
}
}
@@ -198,7 +216,7 @@ public class Repartitioner {
int joinTaskNum = Math.min(maxTaskNum, hashEntries.size());
LOG.info("The determined number of join tasks is " + joinTaskNum);
- SubQuery.scheduleFragment(subQuery, fragments[0], fragments[1]);
+ SubQuery.scheduleFragment(subQuery, fragments[0], Arrays.asList(new FileFragment[]{fragments[1]}));
// Assign partitions to tasks in a round robin manner.
for (Entry<Integer, Map<String, List<IntermediateEntry>>> entry
@@ -228,25 +246,38 @@ public class Repartitioner {
}
private static void scheduleLeafTasksWithBroadcastTable(TaskSchedulerContext schedulerContext, SubQuery subQuery,
- int baseScanId, FileFragment broadcasted) throws IOException {
+ int baseScanId, FileFragment[] fragments) throws IOException {
ExecutionBlock execBlock = subQuery.getBlock();
ScanNode[] scans = execBlock.getScanNodes();
- Preconditions.checkArgument(scans.length == 2, "Must be Join Query");
+ //Preconditions.checkArgument(scans.length == 2, "Must be Join Query");
+
+ for (int i = 0; i < scans.length; i++) {
+ if (i != baseScanId) {
+ scans[i].setBroadcastTable(true);
+ }
+ }
+
TableMeta meta;
ScanNode scan = scans[baseScanId];
TableDesc desc = subQuery.getContext().getTableDescMap().get(scan.getCanonicalName());
meta = desc.getMeta();
- Collection<FileFragment> fragments;
+ Collection<FileFragment> baseFragments;
if (scan.getType() == NodeType.PARTITIONS_SCAN) {
- fragments = getFragmentsFromPartitionedTable(subQuery.getStorageManager(), scan, desc);
+ baseFragments = getFragmentsFromPartitionedTable(subQuery.getStorageManager(), scan, desc);
} else {
- fragments = subQuery.getStorageManager().getSplits(scan.getCanonicalName(), meta, desc.getSchema(),
+ baseFragments = subQuery.getStorageManager().getSplits(scan.getCanonicalName(), meta, desc.getSchema(),
desc.getPath());
}
- SubQuery.scheduleFragments(subQuery, fragments, broadcasted);
- schedulerContext.setEstimatedTaskNum(fragments.size());
+ List<FileFragment> broadcastFragments = new ArrayList<FileFragment>();
+ for (int i = 0; i < fragments.length; i++) {
+ if (i != baseScanId) {
+ broadcastFragments.add(fragments[i]);
+ }
+ }
+ SubQuery.scheduleFragments(subQuery, baseFragments, broadcastFragments);
+ schedulerContext.setEstimatedTaskNum(baseFragments.size());
}
private static void addJoinShuffle(SubQuery subQuery, int partitionId,
@@ -293,7 +324,7 @@ public class Repartitioner {
public static void scheduleFragmentsForNonLeafTasks(TaskSchedulerContext schedulerContext,
MasterPlan masterPlan, SubQuery subQuery, int maxNum)
- throws InternalException, IOException {
+ throws IOException {
DataChannel channel = masterPlan.getIncomingChannels(subQuery.getBlock().getId()).get(0);
if (channel.getShuffleType() == HASH_SHUFFLE) {
scheduleHashShuffledFetches(schedulerContext, masterPlan, subQuery, channel, maxNum);
@@ -317,7 +348,7 @@ public class Repartitioner {
public static void scheduleRangeShuffledFetches(TaskSchedulerContext schedulerContext, MasterPlan masterPlan,
SubQuery subQuery, DataChannel channel, int maxNum)
- throws InternalException, IOException {
+ throws IOException {
ExecutionBlock execBlock = subQuery.getBlock();
ScanNode scan = execBlock.getScanNodes()[0];
Path tablePath;
@@ -481,17 +512,17 @@ public class Repartitioner {
GroupbyNode groupby = PlannerUtil.findMostBottomNode(subQuery.getBlock().getPlan(), NodeType.GROUP_BY);
// get a proper number of tasks
int determinedTaskNum = Math.min(maxNum, finalFetchURI.size());
- LOG.info("ScheduleHashShuffledFetches - Max num=" + maxNum + ", finalFetchURI=" + finalFetchURI.size());
+ LOG.info(subQuery.getId() + ", ScheduleHashShuffledFetches - Max num=" + maxNum + ", finalFetchURI=" + finalFetchURI.size());
if (groupby != null && groupby.getGroupingColumns().length == 0) {
determinedTaskNum = 1;
- LOG.info("No Grouping Column - determinedTaskNum is set to 1");
+ LOG.info(subQuery.getId() + ", No Grouping Column - determinedTaskNum is set to 1");
}
// set the proper number of tasks to the estimated task num
schedulerContext.setEstimatedTaskNum(determinedTaskNum);
// divide fetch uris into the the proper number of tasks in a round robin manner.
scheduleFetchesByRoundRobin(subQuery, finalFetchURI, scan.getTableName(), determinedTaskNum);
- LOG.info("DeterminedTaskNum : " + determinedTaskNum);
+ LOG.info(subQuery.getId() + ", DeterminedTaskNum : " + determinedTaskNum);
}
public static Collection<URI> createHashFetchURL(String hostAndPort, ExecutionBlockId ebid,
@@ -594,7 +625,6 @@ public class Repartitioner {
}
}
-
// set the partition number for group by and sort
if (channel.getShuffleType() == HASH_SHUFFLE) {
if (execBlock.getPlan().getType() == NodeType.GROUP_BY) {
[3/4] TAJO-725: Broadcast JOIN should supports multiple tables.
(hyoungjunkim via jaehwa)
Posted by bl...@apache.org.
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/SubQuery.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/SubQuery.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/SubQuery.java
index b3aefbe..63b50ac 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/SubQuery.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/master/querymaster/SubQuery.java
@@ -665,7 +665,7 @@ public class SubQuery implements EventHandler<SubQueryEvent> {
subQuery.getMasterPlan().isLeaf(subQuery.getId()), subQuery.getId());
subQuery.taskScheduler = TaskSchedulerFactory.get(conf, subQuery.schedulerContext, subQuery);
subQuery.taskScheduler.init(conf);
- LOG.info(subQuery.taskScheduler.getName() + " is chosen for the task scheduling");
+ LOG.info(subQuery.taskScheduler.getName() + " is chosen for the task scheduling for " + subQuery.getId());
}
/**
@@ -716,31 +716,32 @@ public class SubQuery implements EventHandler<SubQueryEvent> {
if (parent != null && parent.getScanNodes().length == 2) {
List<ExecutionBlock> childs = masterPlan.getChilds(parent);
- // for inner
+ // for outer
ExecutionBlock outer = childs.get(0);
long outerVolume = getInputVolume(subQuery.masterPlan, subQuery.context, outer);
// for inner
ExecutionBlock inner = childs.get(1);
long innerVolume = getInputVolume(subQuery.masterPlan, subQuery.context, inner);
- LOG.info("Outer volume: " + Math.ceil((double) outerVolume / 1048576) + "MB, "
+ LOG.info(subQuery.getId() + ", Outer volume: " + Math.ceil((double) outerVolume / 1048576) + "MB, "
+ "Inner volume: " + Math.ceil((double) innerVolume / 1048576) + "MB");
long bigger = Math.max(outerVolume, innerVolume);
int mb = (int) Math.ceil((double) bigger / 1048576);
- LOG.info("Bigger Table's volume is approximately " + mb + " MB");
+ LOG.info(subQuery.getId() + ", Bigger Table's volume is approximately " + mb + " MB");
int taskNum = (int) Math.ceil((double) mb /
conf.getIntVar(ConfVars.DIST_QUERY_JOIN_PARTITION_VOLUME));
int totalMem = getClusterTotalMemory(subQuery);
- LOG.info("Total memory of cluster is " + totalMem + " MB");
+ LOG.info(subQuery.getId() + ", Total memory of cluster is " + totalMem + " MB");
int slots = Math.max(totalMem / conf.getIntVar(ConfVars.TASK_DEFAULT_MEMORY), 1);
// determine the number of task
taskNum = Math.min(taskNum, slots);
- LOG.info("The determined number of join partitions is " + taskNum);
+ LOG.info(subQuery.getId() + ", The determined number of join partitions is " + taskNum);
+
return taskNum;
// Is this subquery the first step of group-by?
@@ -752,17 +753,17 @@ public class SubQuery implements EventHandler<SubQueryEvent> {
long volume = getInputVolume(subQuery.masterPlan, subQuery.context, subQuery.block);
int mb = (int) Math.ceil((double) volume / 1048576);
- LOG.info("Table's volume is approximately " + mb + " MB");
+ LOG.info(subQuery.getId() + ", Table's volume is approximately " + mb + " MB");
// determine the number of task
int taskNumBySize = (int) Math.ceil((double) mb /
conf.getIntVar(ConfVars.DIST_QUERY_GROUPBY_PARTITION_VOLUME));
int totalMem = getClusterTotalMemory(subQuery);
- LOG.info("Total memory of cluster is " + totalMem + " MB");
+ LOG.info(subQuery.getId() + ", Total memory of cluster is " + totalMem + " MB");
int slots = Math.max(totalMem / conf.getIntVar(ConfVars.TASK_DEFAULT_MEMORY), 1);
int taskNum = Math.min(taskNumBySize, slots); //Maximum partitions
- LOG.info("The determined number of aggregation partitions is " + taskNum);
+ LOG.info(subQuery.getId() + ", The determined number of aggregation partitions is " + taskNum);
return taskNum;
}
} else {
@@ -770,10 +771,10 @@ public class SubQuery implements EventHandler<SubQueryEvent> {
long volume = getInputVolume(subQuery.masterPlan, subQuery.context, subQuery.block);
int mb = (int) Math.ceil((double)volume / 1048576);
- LOG.info("Table's volume is approximately " + mb + " MB");
+ LOG.info(subQuery.getId() + ", Table's volume is approximately " + mb + " MB");
// determine the number of task per 128MB
int taskNum = (int) Math.ceil((double)mb / 128);
- LOG.info("The determined number of partitions is " + taskNum);
+ LOG.info(subQuery.getId() + ", The determined number of partitions is " + taskNum);
return taskNum;
}
}
@@ -813,9 +814,15 @@ public class SubQuery implements EventHandler<SubQueryEvent> {
ExecutionBlock execBlock) {
Map<String, TableDesc> tableMap = context.getTableDescMap();
if (masterPlan.isLeaf(execBlock)) {
- ScanNode outerScan = execBlock.getScanNodes()[0];
- TableStats stat = tableMap.get(outerScan.getCanonicalName()).getStats();
- return stat.getNumBytes();
+ ScanNode[] outerScans = execBlock.getScanNodes();
+ long maxVolume = 0;
+ for (ScanNode eachScanNode: outerScans) {
+ TableStats stat = tableMap.get(eachScanNode.getCanonicalName()).getStats();
+ if (stat.getNumBytes() > maxVolume) {
+ maxVolume = stat.getNumBytes();
+ }
+ }
+ return maxVolume;
} else {
long aggregatedVolume = 0;
for (ExecutionBlock childBlock : masterPlan.getChilds(execBlock)) {
@@ -895,28 +902,29 @@ public class SubQuery implements EventHandler<SubQueryEvent> {
}
}
+ public static void scheduleFragment(SubQuery subQuery, FileFragment fragment) {
+ subQuery.taskScheduler.handle(new FragmentScheduleEvent(TaskSchedulerEvent.EventType.T_SCHEDULE,
+ subQuery.getId(), fragment));
+ }
+
+
public static void scheduleFragments(SubQuery subQuery, Collection<FileFragment> fragments) {
for (FileFragment eachFragment : fragments) {
scheduleFragment(subQuery, eachFragment);
}
}
- public static void scheduleFragment(SubQuery subQuery, FileFragment fragment) {
- subQuery.taskScheduler.handle(new FragmentScheduleEvent(TaskSchedulerEvent.EventType.T_SCHEDULE,
- subQuery.getId(), fragment));
- }
-
public static void scheduleFragments(SubQuery subQuery, Collection<FileFragment> leftFragments,
- FileFragment broadcastFragment) {
+ Collection<FileFragment> broadcastFragments) {
for (FileFragment eachLeafFragment : leftFragments) {
- scheduleFragment(subQuery, eachLeafFragment, broadcastFragment);
+ scheduleFragment(subQuery, eachLeafFragment, broadcastFragments);
}
}
public static void scheduleFragment(SubQuery subQuery,
- FileFragment leftFragment, FileFragment rightFragment) {
+ FileFragment leftFragment, Collection<FileFragment> rightFragments) {
subQuery.taskScheduler.handle(new FragmentScheduleEvent(TaskSchedulerEvent.EventType.T_SCHEDULE,
- subQuery.getId(), leftFragment, rightFragment));
+ subQuery.getId(), leftFragment, rightFragments));
}
public static void scheduleFetches(SubQuery subQuery, Map<String, List<URI>> fetches) {
@@ -1007,24 +1015,26 @@ public class SubQuery implements EventHandler<SubQueryEvent> {
subQuery.completedTaskCount++;
if (taskEvent.getState() == TaskState.SUCCEEDED) {
- if (task.isLeafTask()) {
- subQuery.succeededObjectCount += task.getTotalFragmentNum();
- } else {
- subQuery.succeededObjectCount++;
- }
+// if (task.isLeafTask()) {
+// subQuery.succeededObjectCount += task.getTotalFragmentNum();
+// } else {
+// subQuery.succeededObjectCount++;
+// }
+ subQuery.succeededObjectCount++;
} else if (task.getState() == TaskState.KILLED) {
- if (task.isLeafTask()) {
- subQuery.killedObjectCount += task.getTotalFragmentNum();
- } else {
- subQuery.killedObjectCount++;
- }
+// if (task.isLeafTask()) {
+// subQuery.killedObjectCount += task.getTotalFragmentNum();
+// } else {
+// subQuery.killedObjectCount++;
+// }
+ subQuery.killedObjectCount++;
} else if (task.getState() == TaskState.FAILED) {
- if (task.isLeafTask()) {
- subQuery.failedObjectCount+= task.getTotalFragmentNum();
- } else {
- subQuery.failedObjectCount++;
- }
-
+// if (task.isLeafTask()) {
+// subQuery.failedObjectCount+= task.getTotalFragmentNum();
+// } else {
+// subQuery.failedObjectCount++;
+// }
+ subQuery.failedObjectCount++;
// if at least one task is failed, try to kill all tasks.
subQuery.eventHandler.handle(new SubQueryEvent(subQuery.getId(), SubQueryEventType.SQ_KILL));
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/worker/TaskAttemptContext.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/worker/TaskAttemptContext.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/worker/TaskAttemptContext.java
index 92762c9..6f3281c 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/worker/TaskAttemptContext.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/worker/TaskAttemptContext.java
@@ -232,6 +232,10 @@ public class TaskAttemptContext {
}
public FragmentProto getTable(String id) {
+ if (fragmentMap.get(id) == null) {
+ //for empty table
+ return null;
+ }
return fragmentMap.get(id).get(0);
}
@@ -244,6 +248,10 @@ public class TaskAttemptContext {
}
public FragmentProto [] getTables(String id) {
+ if (fragmentMap.get(id) == null) {
+ //for empty table
+ return null;
+ }
return fragmentMap.get(id).toArray(new FragmentProto[fragmentMap.get(id).size()]);
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/worker/TaskRunner.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/worker/TaskRunner.java b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/worker/TaskRunner.java
index d74e0df..9e904cd 100644
--- a/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/worker/TaskRunner.java
+++ b/tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/worker/TaskRunner.java
@@ -37,7 +37,9 @@ import org.apache.tajo.QueryUnitAttemptId;
import org.apache.tajo.TajoProtos.TaskAttemptState;
import org.apache.tajo.conf.TajoConf;
import org.apache.tajo.conf.TajoConf.ConfVars;
+import org.apache.tajo.engine.planner.physical.SeqScanExec;
import org.apache.tajo.engine.query.QueryUnitRequestImpl;
+import org.apache.tajo.engine.utils.TupleCache;
import org.apache.tajo.ipc.QueryMasterProtocol;
import org.apache.tajo.ipc.QueryMasterProtocol.QueryMasterProtocolService;
import org.apache.tajo.rpc.CallFuture;
@@ -219,10 +221,8 @@ public class TaskRunner extends AbstractService {
tasks.clear();
fetchLauncher.shutdown();
this.queryEngine = null;
-// if(client != null) {
-// client.close();
-// client = null;
-// }
+
+ TupleCache.getInstance().removeBroadcastCache(executionBlockId);
LOG.info("Stop TaskRunner: " + executionBlockId);
synchronized (this) {
@@ -243,10 +243,6 @@ public class TaskRunner extends AbstractService {
return nodeId.toString();
}
-// public TajoWorkerProtocolService.Interface getMaster() {
-// return master;
-// }
-
public FileSystem getLocalFS() {
return localFS;
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/main/resources/webapps/admin/query.jsp
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/main/resources/webapps/admin/query.jsp b/tajo-core/tajo-core-backend/src/main/resources/webapps/admin/query.jsp
index e3a356d..2e64f15 100644
--- a/tajo-core/tajo-core-backend/src/main/resources/webapps/admin/query.jsp
+++ b/tajo-core/tajo-core-backend/src/main/resources/webapps/admin/query.jsp
@@ -42,6 +42,9 @@
Map<String, Integer> portMap = new HashMap<String, Integer>();
Collection<String> queryMasters = master.getContext().getResourceManager().getQueryMasters();
+ if (queryMasters == null || queryMasters.isEmpty()) {
+ queryMasters = master.getContext().getResourceManager().getWorkers().keySet();
+ }
for(String eachQueryMasterKey: queryMasters) {
WorkerResource queryMaster = workers.get(eachQueryMasterKey);
if(queryMaster != null) {
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/QueryTestCaseBase.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/QueryTestCaseBase.java b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/QueryTestCaseBase.java
index 784fea5..e3ca39b 100644
--- a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/QueryTestCaseBase.java
+++ b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/QueryTestCaseBase.java
@@ -206,6 +206,7 @@ public class QueryTestCaseBase {
} catch (ServiceException e) {
e.printStackTrace();
}
+ testingCluster.setAllTajoDaemonConfValue(TajoConf.ConfVars.DIST_QUERY_BROADCAST_JOIN_AUTO.varname, "false");
}
protected TajoClient getClient() {
@@ -433,7 +434,8 @@ public class QueryTestCaseBase {
if (expr.getType() == OpType.CreateTable) {
CreateTable createTable = (CreateTable) expr;
String tableName = createTable.getTableName();
- assertTrue("Table creation is failed.", client.updateQuery(parsedResult.getStatement()));
+ assertTrue("Table [" + tableName + "] creation is failed.", client.updateQuery(parsedResult.getStatement()));
+
TableDesc createdTable = client.getTableDesc(tableName);
String createdTableName = createdTable.getName();
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/TajoTestingCluster.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/TajoTestingCluster.java b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/TajoTestingCluster.java
index 10e46e0..b58116a 100644
--- a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/TajoTestingCluster.java
+++ b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/TajoTestingCluster.java
@@ -619,4 +619,11 @@ public class TajoTestingCluster {
Closeables.closeQuietly(writer);
}
}
+
+ public void setAllTajoDaemonConfValue(String key, String value) {
+ tajoMaster.getContext().getConf().set(key, value);
+ for (TajoWorker eachWorker: tajoWorkers) {
+ eachWorker.getConfig().set(key, value);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/client/TestTajoClient.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/client/TestTajoClient.java b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/client/TestTajoClient.java
index 5eb8af2..a2e3181 100644
--- a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/client/TestTajoClient.java
+++ b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/client/TestTajoClient.java
@@ -40,7 +40,6 @@ import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;
-import org.junit.rules.Timeout;
import java.io.IOException;
import java.sql.ResultSet;
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/planner/global/TestBroadcastJoinPlan.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/planner/global/TestBroadcastJoinPlan.java b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/planner/global/TestBroadcastJoinPlan.java
new file mode 100644
index 0000000..b56ab47
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/planner/global/TestBroadcastJoinPlan.java
@@ -0,0 +1,400 @@
+/**
+ * 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.tajo.engine.planner.global;
+
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.tajo.LocalTajoTestingUtility;
+import org.apache.tajo.QueryId;
+import org.apache.tajo.QueryIdFactory;
+import org.apache.tajo.TajoTestingCluster;
+import org.apache.tajo.algebra.Expr;
+import org.apache.tajo.catalog.*;
+import org.apache.tajo.catalog.proto.CatalogProtos;
+import org.apache.tajo.catalog.statistics.TableStats;
+import org.apache.tajo.common.TajoDataTypes;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.datum.TextDatum;
+import org.apache.tajo.engine.parser.SQLAnalyzer;
+import org.apache.tajo.engine.planner.LogicalOptimizer;
+import org.apache.tajo.engine.planner.LogicalPlan;
+import org.apache.tajo.engine.planner.LogicalPlanner;
+import org.apache.tajo.engine.planner.PlanningException;
+import org.apache.tajo.engine.planner.logical.GroupbyNode;
+import org.apache.tajo.engine.planner.logical.JoinNode;
+import org.apache.tajo.engine.planner.logical.LogicalNode;
+import org.apache.tajo.engine.planner.logical.NodeType;
+import org.apache.tajo.engine.query.QueryContext;
+import org.apache.tajo.master.TajoMaster;
+import org.apache.tajo.storage.*;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.Collection;
+
+import static junit.framework.Assert.assertNotNull;
+import static org.apache.tajo.TajoConstants.DEFAULT_DATABASE_NAME;
+import static org.apache.tajo.TajoConstants.DEFAULT_TABLESPACE_NAME;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class TestBroadcastJoinPlan {
+ private TajoConf conf;
+ private final String TEST_PATH = "target/test-data/TestBroadcastJoinPlan";
+ private TajoTestingCluster util;
+ private CatalogService catalog;
+ private SQLAnalyzer analyzer;
+ private Path testDir;
+
+ private TableDesc smallTable1;
+ private TableDesc smallTable2;
+ private TableDesc smallTable3;
+ private TableDesc largeTable1;
+ private TableDesc largeTable2;
+
+ @Before
+ public void setUp() throws Exception {
+ util = new TajoTestingCluster();
+ conf = util.getConfiguration();
+ conf.setLongVar(TajoConf.ConfVars.DIST_QUERY_BROADCAST_JOIN_THRESHOLD, 500 * 1024);
+ conf.setBoolVar(TajoConf.ConfVars.DIST_QUERY_BROADCAST_JOIN_AUTO, true);
+
+ testDir = CommonTestingUtil.getTestDir(TEST_PATH);
+ catalog = util.startCatalogCluster().getCatalog();
+ catalog.createTablespace(DEFAULT_TABLESPACE_NAME, testDir.toUri().toString());
+ catalog.createDatabase(DEFAULT_DATABASE_NAME, DEFAULT_TABLESPACE_NAME);
+ util.getMiniCatalogCluster().getCatalogServer().reloadBuiltinFunctions(TajoMaster.initBuiltinFunctions());
+
+ Schema smallTable1Schema = new Schema();
+ smallTable1Schema.addColumn("small1_id", TajoDataTypes.Type.INT4);
+ smallTable1Schema.addColumn("small1_contents", TajoDataTypes.Type.TEXT);
+ smallTable1 = makeTestData("default.small1", smallTable1Schema, 10 * 1024);
+
+ Schema smallTable2Schema = new Schema();
+ smallTable2Schema.addColumn("small2_id", TajoDataTypes.Type.INT4);
+ smallTable2Schema.addColumn("small2_contents", TajoDataTypes.Type.TEXT);
+ smallTable2 = makeTestData("default.small2", smallTable2Schema, 10 * 1024);
+
+ Schema smallTable3Schema = new Schema();
+ smallTable3Schema.addColumn("small3_id", TajoDataTypes.Type.INT4);
+ smallTable3Schema.addColumn("small3_contents", TajoDataTypes.Type.TEXT);
+ smallTable3 = makeTestData("default.small3", smallTable3Schema, 10 * 1024);
+
+ Schema largeTable1Schema = new Schema();
+ largeTable1Schema.addColumn("large1_id", TajoDataTypes.Type.INT4);
+ largeTable1Schema.addColumn("large1_contents", TajoDataTypes.Type.TEXT);
+ largeTable1 = makeTestData("default.large1", largeTable1Schema, 1024 * 1024); //1M
+
+ Schema largeTable2Schema = new Schema();
+ largeTable2Schema.addColumn("large2_id", TajoDataTypes.Type.INT4);
+ largeTable2Schema.addColumn("large2_contents", TajoDataTypes.Type.TEXT);
+ largeTable2 = makeTestData("default.large2", largeTable2Schema, 1024 * 1024); //1M
+
+ catalog.createTable(smallTable1);
+ catalog.createTable(smallTable2);
+ catalog.createTable(largeTable1);
+ catalog.createTable(largeTable2);
+
+ analyzer = new SQLAnalyzer();
+ }
+
+ private TableDesc makeTestData(String tableName, Schema schema, int dataSize) throws Exception {
+ TableMeta tableMeta = CatalogUtil.newTableMeta(CatalogProtos.StoreType.CSV);
+ Path dataPath = new Path(testDir, tableName + ".csv");
+
+ String contentsData = "";
+ for (int i = 0; i < 1000; i++) {
+ for (int j = 0; j < 10; j++) {
+ contentsData += j;
+ }
+ }
+ Appender appender = StorageManagerFactory.getStorageManager(conf).getAppender(tableMeta, schema,
+ dataPath);
+ appender.init();
+ Tuple tuple = new VTuple(schema.size());
+ int writtenSize = 0;
+ int count = 0;
+ while (true) {
+ TextDatum textDatum = DatumFactory.createText(count + "_" + contentsData);
+ tuple.put(new Datum[] {
+ DatumFactory.createInt4(count), textDatum });
+ appender.addTuple(tuple);
+
+ writtenSize += textDatum.size();
+ if (writtenSize >= dataSize) {
+ break;
+ }
+ }
+
+ appender.flush();
+ appender.close();
+
+ TableDesc tableDesc = CatalogUtil.newTableDesc(tableName, schema, tableMeta, dataPath);
+ TableStats tableStats = new TableStats();
+ FileSystem fs = dataPath.getFileSystem(conf);
+ tableStats.setNumBytes(fs.getFileStatus(dataPath).getLen());
+
+ tableDesc.setStats(tableStats);
+
+ return tableDesc;
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ util.shutdownCatalogCluster();
+ }
+
+ @Test
+ public final void testBroadcastJoin() throws IOException, PlanningException {
+ String query = "select count(*) from large1 " +
+ "join small1 on large1_id = small1_id " +
+ "join small2 on small1_id = small2_id";
+
+ LogicalPlanner planner = new LogicalPlanner(catalog);
+ LogicalOptimizer optimizer = new LogicalOptimizer(conf);
+ Expr expr = analyzer.parse(query);
+ LogicalPlan plan = planner.createPlan(LocalTajoTestingUtility.createDummySession(), expr);
+
+ optimizer.optimize(plan);
+
+ QueryId queryId = QueryIdFactory.newQueryId(System.currentTimeMillis(), 0);
+ QueryContext queryContext = new QueryContext();
+ MasterPlan masterPlan = new MasterPlan(queryId, queryContext, plan);
+ GlobalPlanner globalPlanner = new GlobalPlanner(conf, catalog);
+ globalPlanner.build(masterPlan);
+
+ /*
+ |-eb_1395714781593_0000_000007 (TERMINAL)
+ |-eb_1395714781593_0000_000006 (ROOT)
+ |-eb_1395714781593_0000_000005 (LEAF)
+ */
+
+ ExecutionBlock terminalEB = masterPlan.getRoot();
+ assertEquals(1, masterPlan.getChildCount(terminalEB.getId()));
+
+ ExecutionBlock rootEB = masterPlan.getChild(terminalEB.getId(), 0);
+ assertEquals(1, masterPlan.getChildCount(rootEB.getId()));
+
+ ExecutionBlock leafEB = masterPlan.getChild(rootEB.getId(), 0);
+ assertNotNull(leafEB);
+
+ assertEquals(0, masterPlan.getChildCount(leafEB.getId()));
+ Collection<String> broadcastTables = leafEB.getBroadcastTables();
+ assertEquals(2, broadcastTables.size());
+
+ assertTrue(broadcastTables.contains("default.small1"));
+ assertTrue(broadcastTables.contains("default.small2"));
+ assertTrue(!broadcastTables.contains("default.large1"));
+
+ LogicalNode leafNode = leafEB.getPlan();
+ assertEquals(NodeType.GROUP_BY, leafNode.getType());
+
+ LogicalNode joinNode = ((GroupbyNode)leafNode).getChild();
+ assertEquals(NodeType.JOIN, joinNode.getType());
+
+ LogicalNode leftNode = ((JoinNode)joinNode).getLeftChild();
+ LogicalNode rightNode = ((JoinNode)joinNode).getRightChild();
+
+ assertEquals(NodeType.JOIN, leftNode.getType());
+ assertEquals(NodeType.SCAN, rightNode.getType());
+
+ LogicalNode lastLeftNode = ((JoinNode)leftNode).getLeftChild();
+ LogicalNode lastRightNode = ((JoinNode)leftNode).getRightChild();
+
+ assertEquals(NodeType.SCAN, lastLeftNode.getType());
+ assertEquals(NodeType.SCAN, lastRightNode.getType());
+ }
+
+ @Test
+ public final void testNotBroadcastJoinTwoLargeTable() throws IOException, PlanningException {
+ // This query is not broadcast join
+ String query = "select count(*) from large1 " +
+ "join large2 on large1_id = large2_id ";
+
+ LogicalPlanner planner = new LogicalPlanner(catalog);
+ LogicalOptimizer optimizer = new LogicalOptimizer(conf);
+ Expr expr = analyzer.parse(query);
+ LogicalPlan plan = planner.createPlan(LocalTajoTestingUtility.createDummySession(), expr);
+
+ optimizer.optimize(plan);
+
+ QueryId queryId = QueryIdFactory.newQueryId(System.currentTimeMillis(), 0);
+ QueryContext queryContext = new QueryContext();
+ MasterPlan masterPlan = new MasterPlan(queryId, queryContext, plan);
+ GlobalPlanner globalPlanner = new GlobalPlanner(conf, catalog);
+ globalPlanner.build(masterPlan);
+
+ ExecutionBlockCursor ebCursor = new ExecutionBlockCursor(masterPlan);
+ while (ebCursor.hasNext()) {
+ ExecutionBlock eb = ebCursor.nextBlock();
+ Collection<String> broadcastTables = eb.getBroadcastTables();
+ assertTrue(broadcastTables == null || broadcastTables.isEmpty());
+ }
+ }
+
+ @Test
+ public final void testTwoBroadcastJoin() throws IOException, PlanningException {
+ String query = "select count(*) from large1 " +
+ "join small1 on large1_id = small1_id " +
+ "join large2 on large1_id = large2_id " +
+ "join small2 on large2_id = small2_id";
+
+ LogicalPlanner planner = new LogicalPlanner(catalog);
+ LogicalOptimizer optimizer = new LogicalOptimizer(conf);
+ Expr expr = analyzer.parse(query);
+ LogicalPlan plan = planner.createPlan(LocalTajoTestingUtility.createDummySession(), expr);
+
+ optimizer.optimize(plan);
+
+ QueryId queryId = QueryIdFactory.newQueryId(System.currentTimeMillis(), 0);
+ QueryContext queryContext = new QueryContext();
+ MasterPlan masterPlan = new MasterPlan(queryId, queryContext, plan);
+ GlobalPlanner globalPlanner = new GlobalPlanner(conf, catalog);
+ globalPlanner.build(masterPlan);
+
+ /*
+ |-eb_1395736346625_0000_000009
+ |-eb_1395736346625_0000_000008 (GROUP-BY)
+ |-eb_1395736346625_0000_000007 (GROUP-BY, JOIN)
+ |-eb_1395736346625_0000_000006 (LEAF, JOIN)
+ |-eb_1395736346625_0000_000003 (LEAF, JOIN)
+ */
+
+ ExecutionBlockCursor ebCursor = new ExecutionBlockCursor(masterPlan);
+ int index = 0;
+ while (ebCursor.hasNext()) {
+ ExecutionBlock eb = ebCursor.nextBlock();
+ if(index == 0) {
+ Collection<String> broadcastTables = eb.getBroadcastTables();
+ assertEquals(1, broadcastTables.size());
+
+ assertTrue(!broadcastTables.contains("default.large1"));
+ assertTrue(broadcastTables.contains("default.small1"));
+ } else if(index == 1) {
+ Collection<String> broadcastTables = eb.getBroadcastTables();
+ assertEquals(1, broadcastTables.size());
+ assertTrue(!broadcastTables.contains("default.large2"));
+ assertTrue(broadcastTables.contains("default.small2"));
+ }
+ index++;
+ }
+
+ assertEquals(5, index);
+ }
+
+ @Test
+ public final void testNotBroadcastJoinSubquery() throws IOException, PlanningException {
+ // This query is not broadcast join;
+ String query = "select count(*) from large1 " +
+ "join (select * from small1) a on large1_id = a.small1_id " +
+ "join small2 on a.small1_id = small2_id";
+
+ LogicalPlanner planner = new LogicalPlanner(catalog);
+ LogicalOptimizer optimizer = new LogicalOptimizer(conf);
+ Expr expr = analyzer.parse(query);
+ LogicalPlan plan = planner.createPlan(LocalTajoTestingUtility.createDummySession(), expr);
+
+ optimizer.optimize(plan);
+
+ QueryId queryId = QueryIdFactory.newQueryId(System.currentTimeMillis(), 0);
+ QueryContext queryContext = new QueryContext();
+ MasterPlan masterPlan = new MasterPlan(queryId, queryContext, plan);
+ GlobalPlanner globalPlanner = new GlobalPlanner(conf, catalog);
+ globalPlanner.build(masterPlan);
+
+ /*
+ |-eb_1395749810370_0000_000007
+ |-eb_1395749810370_0000_000006 (GROUP-BY)
+ |-eb_1395749810370_0000_000005 (GROUP-BY, JOIN)
+ |-eb_1395749810370_0000_000004 (LEAF, SCAN, large1)
+ |-eb_1395749810370_0000_000003 (JOIN)
+ |-eb_1395749810370_0000_000002 (LEAF, SCAN, small2)
+ |-eb_1395749810370_0000_000001 (LEAF, TABLE_SUBQUERY, small1)
+ */
+
+ ExecutionBlockCursor ebCursor = new ExecutionBlockCursor(masterPlan);
+ int index = 0;
+ while (ebCursor.hasNext()) {
+ ExecutionBlock eb = ebCursor.nextBlock();
+ Collection<String> broadcastTables = eb.getBroadcastTables();
+ assertTrue(broadcastTables == null || broadcastTables.isEmpty());
+ index++;
+ }
+
+ assertEquals(7, index);
+ }
+
+ @Test
+ public final void testBroadcastJoinSubquery() throws IOException, PlanningException {
+ String query = "select count(*) from large1 " +
+ "join (select * from small1) a on large1_id = a.small1_id " +
+ "join small2 on large1_id = small2_id";
+
+ LogicalPlanner planner = new LogicalPlanner(catalog);
+ LogicalOptimizer optimizer = new LogicalOptimizer(conf);
+ Expr expr = analyzer.parse(query);
+ LogicalPlan plan = planner.createPlan(LocalTajoTestingUtility.createDummySession(), expr);
+
+ optimizer.optimize(plan);
+
+ QueryId queryId = QueryIdFactory.newQueryId(System.currentTimeMillis(), 0);
+ QueryContext queryContext = new QueryContext();
+ MasterPlan masterPlan = new MasterPlan(queryId, queryContext, plan);
+ GlobalPlanner globalPlanner = new GlobalPlanner(conf, catalog);
+ globalPlanner.build(masterPlan);
+
+ /*
+ |-eb_1395794091662_0000_000007
+ |-eb_1395794091662_0000_000006
+ |-eb_1395794091662_0000_000005 (JOIN)
+ |-eb_1395794091662_0000_000004 (LEAF, SUBQUERY)
+ |-eb_1395794091662_0000_000003 (LEAF, JOIN)
+ */
+
+ ExecutionBlockCursor ebCursor = new ExecutionBlockCursor(masterPlan);
+ int index = 0;
+ while (ebCursor.hasNext()) {
+ ExecutionBlock eb = ebCursor.nextBlock();
+ if(index == 0) {
+ //LEAF, JOIN
+ Collection<String> broadcastTables = eb.getBroadcastTables();
+ assertEquals(1, broadcastTables.size());
+
+ assertTrue(!broadcastTables.contains("default.large1"));
+ assertTrue(broadcastTables.contains("default.small2"));
+ } else if(index == 1) {
+ //LEAF, SUBQUERY
+ Collection<String> broadcastTables = eb.getBroadcastTables();
+ assertTrue(broadcastTables == null || broadcastTables.isEmpty());
+ } else if(index == 2) {
+ //JOIN
+ Collection<String> broadcastTables = eb.getBroadcastTables();
+ assertTrue(broadcastTables == null || broadcastTables.isEmpty());
+ }
+ index++;
+ }
+
+ assertEquals(5, index);
+ }
+}
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestJoinBroadcast.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestJoinBroadcast.java b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestJoinBroadcast.java
new file mode 100644
index 0000000..78714c5
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestJoinBroadcast.java
@@ -0,0 +1,374 @@
+/**
+ * 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.tajo.engine.query;
+
+import org.apache.tajo.IntegrationTest;
+import org.apache.tajo.QueryId;
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.TajoConstants;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.engine.planner.global.ExecutionBlock;
+import org.apache.tajo.engine.planner.global.MasterPlan;
+import org.apache.tajo.engine.planner.logical.NodeType;
+import org.apache.tajo.jdbc.TajoResultSet;
+import org.apache.tajo.master.querymaster.QueryMasterTask;
+import org.apache.tajo.worker.TajoWorker;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.sql.ResultSet;
+
+import static junit.framework.TestCase.assertEquals;
+import static junit.framework.TestCase.assertTrue;
+import static junit.framework.TestCase.fail;
+import static org.junit.Assert.assertNotNull;
+
+@Category(IntegrationTest.class)
+public class TestJoinBroadcast extends QueryTestCaseBase {
+ public TestJoinBroadcast() throws Exception {
+ super(TajoConstants.DEFAULT_DATABASE_NAME);
+ testingCluster.setAllTajoDaemonConfValue(TajoConf.ConfVars.DIST_QUERY_BROADCAST_JOIN_AUTO.varname, "true");
+ testingCluster.setAllTajoDaemonConfValue(
+ TajoConf.ConfVars.DIST_QUERY_BROADCAST_JOIN_THRESHOLD.varname, "" + (5 * 1024));
+
+ executeDDL("create_lineitem_large_ddl.sql", "lineitem_large");
+ executeDDL("create_customer_large_ddl.sql", "customer_large");
+ }
+
+ @Test
+ public final void testCrossJoin() throws Exception {
+ ResultSet res = executeQuery();
+ assertResultSet(res);
+ cleanupQuery(res);
+ }
+
+ @Test
+ public final void testWhereClauseJoin1() throws Exception {
+ ResultSet res = executeQuery();
+ assertResultSet(res);
+ cleanupQuery(res);
+ }
+
+ @Test
+ public final void testWhereClauseJoin2() throws Exception {
+ ResultSet res = executeQuery();
+ assertResultSet(res);
+ cleanupQuery(res);
+ }
+
+ @Test
+ public final void testWhereClauseJoin3() throws Exception {
+ ResultSet res = executeQuery();
+ assertResultSet(res);
+ cleanupQuery(res);
+ }
+
+ @Test
+ public final void testWhereClauseJoin4() throws Exception {
+ ResultSet res = executeQuery();
+ assertResultSet(res);
+ cleanupQuery(res);
+ }
+
+ @Test
+ public final void testWhereClauseJoin5() throws Exception {
+ ResultSet res = executeQuery();
+ assertResultSet(res);
+ cleanupQuery(res);
+ }
+
+ @Test
+ public final void testWhereClauseJoin6() throws Exception {
+ ResultSet res = executeQuery();
+ System.out.println(resultSetToString(res));
+ cleanupQuery(res);
+ }
+
+ @Test
+ public final void testTPCHQ2Join() throws Exception {
+ ResultSet res = executeQuery();
+ assertResultSet(res);
+ cleanupQuery(res);
+ }
+
+ @Test
+ public final void testLeftOuterJoin1() throws Exception {
+ ResultSet res = executeQuery();
+ assertResultSet(res);
+ cleanupQuery(res);
+ }
+
+ @Test
+ public final void testLeftOuterJoinWithConstantExpr1() throws Exception {
+ // outer join with constant projections
+ //
+ // select c_custkey, orders.o_orderkey, 'val' as val from customer
+ // left outer join orders on c_custkey = o_orderkey;
+ ResultSet res = executeQuery();
+ assertResultSet(res);
+ cleanupQuery(res);
+ }
+
+ @Test
+ public final void testLeftOuterJoinWithConstantExpr2() throws Exception {
+ // outer join with constant projections
+ //
+ // select c_custkey, o.o_orderkey, 'val' as val from customer left outer join
+ // (select * from orders) o on c_custkey = o.o_orderkey
+ ResultSet res = executeQuery();
+ assertResultSet(res);
+ cleanupQuery(res);
+ }
+
+ @Test
+ public final void testLeftOuterJoinWithConstantExpr3() throws Exception {
+ // outer join with constant projections
+ //
+ // select a.c_custkey, 123::INT8 as const_val, b.min_name from customer a
+ // left outer join ( select c_custkey, min(c_name) as min_name from customer group by c_custkey) b
+ // on a.c_custkey = b.c_custkey;
+ ResultSet res = executeQuery();
+ assertResultSet(res);
+ cleanupQuery(res);
+ }
+
+ @Test
+ public final void testRightOuterJoin1() throws Exception {
+ ResultSet res = executeQuery();
+ assertResultSet(res);
+ cleanupQuery(res);
+ }
+
+ @Test
+ public final void testFullOuterJoin1() throws Exception {
+ ResultSet res = executeQuery();
+ assertResultSet(res);
+ cleanupQuery(res);
+ }
+
+ @Test
+ public void testJoinCoReferredEvals1() throws Exception {
+ ResultSet res = executeQuery();
+ assertResultSet(res);
+ cleanupQuery(res);
+ }
+
+ @Test
+ public void testJoinCoReferredEvalsWithSameExprs1() throws Exception {
+ ResultSet res = executeQuery();
+ assertResultSet(res);
+ cleanupQuery(res);
+ }
+
+ @Test
+ public void testJoinCoReferredEvalsWithSameExprs2() throws Exception {
+ // including grouping operator
+ ResultSet res = executeQuery();
+ assertResultSet(res);
+ cleanupQuery(res);
+ }
+
+ @Test
+ public void testCrossJoinAndCaseWhen() throws Exception {
+ ResultSet res = executeQuery();
+ assertResultSet(res);
+ cleanupQuery(res);
+ }
+
+ @Test
+ public void testCrossJoinWithAsterisk1() throws Exception {
+ // select region.*, customer.* from region, customer;
+ ResultSet res = executeQuery();
+ assertResultSet(res);
+ cleanupQuery(res);
+ }
+
+ @Test
+ public void testCrossJoinWithAsterisk2() throws Exception {
+ // select region.*, customer.* from customer, region;
+ ResultSet res = executeQuery();
+ assertResultSet(res);
+ cleanupQuery(res);
+ }
+
+ @Test
+ public void testCrossJoinWithAsterisk3() throws Exception {
+ // select * from customer, region
+ ResultSet res = executeQuery();
+ assertResultSet(res);
+ cleanupQuery(res);
+ }
+
+ @Test
+ public void testCrossJoinWithAsterisk4() throws Exception {
+ // select length(r_regionkey), *, c_custkey*10 from customer, region
+ ResultSet res = executeQuery();
+ assertResultSet(res);
+ cleanupQuery(res);
+ }
+
+ @Test
+ public final void testInnerJoinWithEmptyTable() throws Exception {
+ ResultSet res = executeQuery();
+ assertResultSet(res);
+ cleanupQuery(res);
+ }
+
+ @Test
+ public final void testLeftOuterJoinWithEmptyTable1() throws Exception {
+ ResultSet res = executeQuery();
+ assertResultSet(res);
+ cleanupQuery(res);
+ }
+
+ @Test
+ public final void testLeftOuterJoinWithEmptyTable2() throws Exception {
+ ResultSet res = executeQuery();
+ assertResultSet(res);
+ cleanupQuery(res);
+ }
+
+ @Test
+ public final void testLeftOuterJoinWithEmptyTable3() throws Exception {
+ ResultSet res = executeQuery();
+ assertResultSet(res);
+ cleanupQuery(res);
+ }
+
+ @Test
+ public final void testLeftOuterJoinWithEmptyTable4() throws Exception {
+ ResultSet res = executeQuery();
+ assertResultSet(res);
+ cleanupQuery(res);
+ }
+
+ @Test
+ public final void testRightOuterJoinWithEmptyTable1() throws Exception {
+ ResultSet res = executeQuery();
+ assertResultSet(res);
+ cleanupQuery(res);
+ }
+
+ @Test
+ public final void testFullOuterJoinWithEmptyTable1() throws Exception {
+ ResultSet res = executeQuery();
+ assertResultSet(res);
+ cleanupQuery(res);
+ }
+
+ @Test
+ public final void testCrossJoinWithEmptyTable1() throws Exception {
+ ResultSet res = executeQuery();
+ assertResultSet(res);
+ cleanupQuery(res);
+ }
+
+ @Test
+ public final void testJoinOnMultipleDatabases() throws Exception {
+ executeString("CREATE DATABASE JOINS");
+ assertDatabaseExists("JOINS");
+ executeString("CREATE TABLE JOINS.part_ as SELECT * FROM part");
+ assertTableExists("JOINS.part_");
+ executeString("CREATE TABLE JOINS.supplier_ as SELECT * FROM supplier");
+ assertTableExists("JOINS.supplier_");
+ ResultSet res = executeQuery();
+ assertResultSet(res);
+ cleanupQuery(res);
+ }
+
+ private MasterPlan getQueryPlan(QueryId queryId) {
+ for (TajoWorker eachWorker: testingCluster.getTajoWorkers()) {
+ QueryMasterTask queryMasterTask = eachWorker.getWorkerContext().getQueryMaster().getQueryMasterTask(queryId, true);
+ if (queryMasterTask != null) {
+ return queryMasterTask.getQuery().getPlan();
+ }
+ }
+
+ fail("Can't find query from workers" + queryId);
+ return null;
+ }
+
+ @Test
+ public final void testBroadcastBasicJoin() throws Exception {
+ ResultSet res = executeQuery();
+ TajoResultSet ts = (TajoResultSet)res;
+ assertResultSet(res);
+ cleanupQuery(res);
+
+ MasterPlan plan = getQueryPlan(ts.getQueryId());
+ ExecutionBlock rootEB = plan.getRoot();
+
+ /*
+ |-eb_1395998037360_0001_000006
+ |-eb_1395998037360_0001_000005
+ */
+ assertEquals(1, plan.getChildCount(rootEB.getId()));
+
+ ExecutionBlock firstEB = plan.getChild(rootEB.getId(), 0);
+
+ assertNotNull(firstEB);
+ assertEquals(2, firstEB.getBroadcastTables().size());
+ assertTrue(firstEB.getBroadcastTables().contains("default.supplier"));
+ assertTrue(firstEB.getBroadcastTables().contains("default.part"));
+ }
+
+ @Test
+ public final void testBroadcastTwoPartJoin() throws Exception {
+ ResultSet res = executeQuery();
+ assertResultSet(res);
+ cleanupQuery(res);
+
+ MasterPlan plan = getQueryPlan(((TajoResultSet)res).getQueryId());
+ ExecutionBlock rootEB = plan.getRoot();
+
+ /*
+ |-eb_1395996354406_0001_000010
+ |-eb_1395996354406_0001_000009
+ |-eb_1395996354406_0001_000008
+ |-eb_1395996354406_0001_000005
+ */
+ assertEquals(1, plan.getChildCount(rootEB.getId()));
+
+ ExecutionBlock firstJoinEB = plan.getChild(rootEB.getId(), 0);
+ assertNotNull(firstJoinEB);
+ assertEquals(NodeType.JOIN, firstJoinEB.getPlan().getType());
+ assertEquals(0, firstJoinEB.getBroadcastTables().size());
+
+ ExecutionBlock leafEB1 = plan.getChild(firstJoinEB.getId(), 0);
+ assertTrue(leafEB1.getBroadcastTables().contains("default.orders"));
+ assertTrue(leafEB1.getBroadcastTables().contains("default.part"));
+
+ ExecutionBlock leafEB2 = plan.getChild(firstJoinEB.getId(), 1);
+ assertTrue(leafEB2.getBroadcastTables().contains("default.nation"));
+ }
+
+ @Test
+ public final void testBroadcastSubquery() throws Exception {
+ ResultSet res = executeQuery();
+ assertResultSet(res);
+ cleanupQuery(res);
+ }
+
+ @Test
+ public final void testBroadcastSubquery2() throws Exception {
+ ResultSet res = executeQuery();
+ assertResultSet(res);
+ cleanupQuery(res);
+ }
+}
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestJoinQuery.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestJoinQuery.java b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestJoinQuery.java
index 19591ea..6d72ca7 100644
--- a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestJoinQuery.java
+++ b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/query/TestJoinQuery.java
@@ -21,6 +21,7 @@ package org.apache.tajo.engine.query;
import org.apache.tajo.IntegrationTest;
import org.apache.tajo.QueryTestCaseBase;
import org.apache.tajo.TajoConstants;
+import org.apache.tajo.conf.TajoConf;
import org.junit.Test;
import org.junit.experimental.categories.Category;
@@ -223,6 +224,18 @@ public class TestJoinQuery extends QueryTestCaseBase {
@Test
public final void testLeftOuterJoinWithEmptyTable1() throws Exception {
+ /*
+ select
+ c_custkey,
+ empty_orders.o_orderkey,
+ empty_orders.o_orderstatus,
+ empty_orders.o_orderdate
+ from
+ customer left outer join empty_orders on c_custkey = o_orderkey
+ order by
+ c_custkey, o_orderkey;
+ */
+
ResultSet res = executeQuery();
assertResultSet(res);
cleanupQuery(res);
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/util/TestTupleCache.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/util/TestTupleCache.java b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/util/TestTupleCache.java
new file mode 100644
index 0000000..1cbbdf9
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/engine/util/TestTupleCache.java
@@ -0,0 +1,89 @@
+/**
+ * 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.tajo.engine.util;
+
+import org.apache.tajo.ExecutionBlockId;
+import org.apache.tajo.QueryIdFactory;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.datum.TextDatum;
+import org.apache.tajo.engine.utils.TupleCache;
+import org.apache.tajo.engine.utils.TupleCacheKey;
+import org.apache.tajo.storage.Scanner;
+import org.apache.tajo.storage.Tuple;
+import org.apache.tajo.storage.VTuple;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static junit.framework.TestCase.assertEquals;
+import static junit.framework.TestCase.assertFalse;
+import static junit.framework.TestCase.assertTrue;
+import static org.junit.Assert.assertNotNull;
+
+public class TestTupleCache {
+ @Test
+ public void testTupleCcaheBasicFunction() throws Exception {
+ List<Tuple> tupleData = new ArrayList<Tuple>();
+ for (int i = 0; i < 100; i++) {
+ Datum[] datums = new Datum[5];
+ for (int j = 0; j < 5; j++) {
+ datums[j] = new TextDatum(i + "_" + j);
+ }
+ Tuple tuple = new VTuple(datums);
+ tupleData.add(tuple);
+ }
+
+ ExecutionBlockId ebId = QueryIdFactory.newExecutionBlockId(
+ QueryIdFactory.newQueryId(System.currentTimeMillis(), 0));
+
+ TupleCacheKey cacheKey = new TupleCacheKey(ebId.toString(), "TestTable");
+ TupleCache tupleCache = TupleCache.getInstance();
+
+ assertFalse(tupleCache.isBroadcastCacheReady(cacheKey));
+ assertTrue(tupleCache.lockBroadcastScan(cacheKey));
+ assertFalse(tupleCache.lockBroadcastScan(cacheKey));
+
+ tupleCache.addBroadcastCache(cacheKey, tupleData);
+ assertTrue(tupleCache.isBroadcastCacheReady(cacheKey));
+
+ Scanner scanner = tupleCache.openCacheScanner(cacheKey, null);
+ assertNotNull(scanner);
+
+ int count = 0;
+
+ while (true) {
+ Tuple tuple = scanner.next();
+ if (tuple == null) {
+ break;
+ }
+
+ assertEquals(tupleData.get(count), tuple);
+ count++;
+ }
+
+ assertEquals(tupleData.size(), count);
+
+ tupleCache.removeBroadcastCache(ebId);
+ assertFalse(tupleCache.isBroadcastCacheReady(cacheKey));
+ assertTrue(tupleCache.lockBroadcastScan(cacheKey));
+
+ tupleCache.removeBroadcastCache(ebId);
+ }
+}
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/master/TestExecutionBlockCursor.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/master/TestExecutionBlockCursor.java b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/master/TestExecutionBlockCursor.java
index 869d199..ab31c8d 100644
--- a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/master/TestExecutionBlockCursor.java
+++ b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/master/TestExecutionBlockCursor.java
@@ -58,6 +58,8 @@ public class TestExecutionBlockCursor {
util.startCatalogCluster();
conf = util.getConfiguration();
+ conf.set(TajoConf.ConfVars.DIST_QUERY_BROADCAST_JOIN_AUTO.varname, "false");
+
catalog = util.getMiniCatalogCluster().getCatalog();
catalog.createTablespace(DEFAULT_TABLESPACE_NAME, "hdfs://localhost:!234/warehouse");
catalog.createDatabase(DEFAULT_DATABASE_NAME, DEFAULT_TABLESPACE_NAME);
@@ -88,7 +90,9 @@ public class TestExecutionBlockCursor {
@AfterClass
public static void tearDown() {
util.shutdownCatalogCluster();
- dispatcher.stop();
+ if (dispatcher != null) {
+ dispatcher.stop();
+ }
}
@Test
@@ -114,6 +118,6 @@ public class TestExecutionBlockCursor {
count++;
}
- assertEquals(6, count);
+ assertEquals(10, count);
}
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/master/querymaster/TestQueryUnitStatusUpdate.java
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/master/querymaster/TestQueryUnitStatusUpdate.java b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/master/querymaster/TestQueryUnitStatusUpdate.java
index fe8c070..07b4ac5 100644
--- a/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/master/querymaster/TestQueryUnitStatusUpdate.java
+++ b/tajo-core/tajo-core-backend/src/test/java/org/apache/tajo/master/querymaster/TestQueryUnitStatusUpdate.java
@@ -86,11 +86,11 @@ public class TestQueryUnitStatusUpdate extends QueryTestCaseBase {
res = executeQuery();
- long[] expectedNumRows = new long[]{7, 2, 2, 2};
- long[] expectedNumBytes = new long[]{63, 34, 34, 18};
- long[] expectedReadBytes = new long[]{63, 0, 34, 0};
+ long[] expectedNumRows = new long[]{2, 2, 5, 5, 7, 2, 2, 2};
+ long[] expectedNumBytes = new long[]{18, 34, 45, 75, 109, 34, 34, 18};
+ long[] expectedReadBytes = new long[]{18, 0, 45, 0, 109, 0, 34, 0};
- assertStatus(2, expectedNumRows, expectedNumBytes, expectedReadBytes);
+ assertStatus(4, expectedNumRows, expectedNumBytes, expectedReadBytes);
} finally {
cleanupQuery(res);
}
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/dataset/TestJoinBroadcast/customer_large/customer.tbl
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/dataset/TestJoinBroadcast/customer_large/customer.tbl b/tajo-core/tajo-core-backend/src/test/resources/dataset/TestJoinBroadcast/customer_large/customer.tbl
new file mode 100644
index 0000000..cdccf00
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/dataset/TestJoinBroadcast/customer_large/customer.tbl
@@ -0,0 +1,100 @@
+1|Customer#000000001|IVhzIApeRb ot,c,E|10|25-989-741-2988|711.56|BUILDING|to the even, regular platelets. regular, ironic epitaphs nag e
+2|Customer#000000002|XSTf4,NCwDVaWNe6tEgvwfmRchLXak|7|23-768-687-3665|121.65|AUTOMOBILE|l accounts. blithely ironic theodolites integrate boldly: caref
+3|Customer#000000003|MG9kdTD2WBHm|7|11-719-748-3364|7498.12|AUTOMOBILE| deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov
+4|Customer#000000004|XxVSJsLAGtn|10|14-128-190-5944|2866.83|MACHINERY| requests. final, regular ideas sleep final accou
+5|Customer#000000005|KvpyuHCplrB84WgAiGV6sYpZq7Tj|5|13-750-942-6364|794.47|HOUSEHOLD|n accounts will have to unwind. foxes cajole accor
+6|Customer#000000006|sKZz0CsnMD7mp4Xd0YrBvx,LREYKUWAh yVn|17|30-114-968-4951|7638.57|AUTOMOBILE|tions. even deposits boost according to the slyly bold packages. final accounts cajole requests. furious
+7|Customer#000000007|TcGe5gaZNgVePxU5kRrvXBfkasDTea|21|28-190-982-9759|9561.95|AUTOMOBILE|ainst the ironic, express theodolites. express, even pinto beans among the exp
+8|Customer#000000008|I0B10bB0AymmC, 0PrRYBCP1yGJ8xcBPmWhl5|4|27-147-574-9335|6819.74|BUILDING|among the slyly regular theodolites kindle blithely courts. carefully even theodolites haggle slyly along the ide
+9|Customer#000000009|xKiAFTjUsCuxfeleNqefumTrjS|16|18-338-906-3675|8324.07|FURNITURE|r theodolites according to the requests wake thinly excuses: pending requests haggle furiousl
+10|Customer#000000010|6LrEaV6KR6PLVcgl2ArL Q3rqzLzcT1 v2|20|15-741-346-9870|2753.54|HOUSEHOLD|es regular deposits haggle. fur
+11|Customer#000000011|PkWS 3HlXqwTuzrKg633BEi|19|33-464-151-3439|-272.60|BUILDING|ckages. requests sleep slyly. quickly even pinto beans promise above the slyly regular pinto beans.
+12|Customer#000000012|9PWKuhzT4Zr1Q|16|23-791-276-1263|3396.49|HOUSEHOLD| to the carefully final braids. blithely regular requests nag. ironic theodolites boost quickly along
+13|Customer#000000013|nsXQu0oVjD7PM659uC3SRSp|9|13-761-547-5974|3857.34|BUILDING|ounts sleep carefully after the close frays. carefully bold notornis use ironic requests. blithely
+14|Customer#000000014|KXkletMlL2JQEA |22|11-845-129-3851|5266.30|FURNITURE|, ironic packages across the unus
+15|Customer#000000015|YtWggXoOLdwdo7b0y,BZaGUQMLJMX1Y,EC,6Dn|19|33-687-542-7601|2788.52|HOUSEHOLD| platelets. regular deposits detect asymptotes. blithely unusual packages nag slyly at the fluf
+16|Customer#000000016|cYiaeMLZSMAOQ2 d0W,|17|20-781-609-3107|4681.03|FURNITURE|kly silent courts. thinly regular theodolites sleep fluffily after
+17|Customer#000000017|izrh 6jdqtp2eqdtbkswDD8SG4SzXruMfIXyR7|12|12-970-682-3487|6.34|AUTOMOBILE|packages wake! blithely even pint
+18|Customer#000000018|3txGO AiuFux3zT0Z9NYaFRnZt|3|16-155-215-1315|5494.43|BUILDING|s sleep. carefully even instructions nag furiously alongside of t
+19|Customer#000000019|uc,3bHIx84H,wdrmLOjVsiqXCq2tr|10|28-396-526-5053|8914.71|HOUSEHOLD| nag. furiously careful packages are slyly at the accounts. furiously regular in
+20|Customer#000000020|JrPk8Pqplj4Ne|23|32-957-234-8742|7603.40|FURNITURE|g alongside of the special excuses-- fluffily enticing packages wake
+21|Customer#000000021|XYmVpr9yAHDEn|19|18-902-614-8344|1428.25|MACHINERY| quickly final accounts integrate blithely furiously u
+22|Customer#000000022|QI6p41,FNs5k7RZoCCVPUTkUdYpB|17|13-806-545-9701|591.98|MACHINERY|s nod furiously above the furiously ironic ideas.
+23|Customer#000000023|OdY W13N7Be3OC5MpgfmcYss0Wn6TKT|15|13-312-472-8245|3332.02|HOUSEHOLD|deposits. special deposits cajole slyly. fluffily special deposits about the furiously
+24|Customer#000000024|HXAFgIAyjxtdqwimt13Y3OZO 4xeLe7U8PqG|19|23-127-851-8031|9255.67|MACHINERY|into beans. fluffily final ideas haggle fluffily
+25|Customer#000000025|Hp8GyFQgGHFYSilH5tBfe|7|22-603-468-3533|7133.70|FURNITURE|y. accounts sleep ruthlessly according to the regular theodolites. unusual instructions sleep. ironic, final
+26|Customer#000000026|8ljrc5ZeMl7UciP|4|32-363-455-4837|5182.05|AUTOMOBILE|c requests use furiously ironic requests. slyly ironic dependencies us
+27|Customer#000000027|IS8GIyxpBrLpMT0u7|7|13-137-193-2709|5679.84|BUILDING| about the carefully ironic pinto beans. accoun
+28|Customer#000000028|iVyg0daQ,Tha8x2WPWA9m2529m|12|18-774-241-1462|1007.18|FURNITURE| along the regular deposits. furiously final pac
+29|Customer#000000029|sJ5adtfyAkCK63df2,vF25zyQMVYE34uh|13|10-773-203-7342|7618.27|FURNITURE|its after the carefully final platelets x-ray against
+30|Customer#000000030|nJDsELGAavU63Jl0c5NKsKfL8rIJQQkQnYL2QJY|13|11-764-165-5076|9321.01|BUILDING|lithely final requests. furiously unusual account
+31|Customer#000000031|LUACbO0viaAv6eXOAebryDB xjVst|21|33-197-837-7094|5236.89|HOUSEHOLD|s use among the blithely pending depo
+32|Customer#000000032|jD2xZzi UmId,DCtNBLXKj9q0Tlp2iQ6ZcO3J|15|25-430-914-2194|3471.53|BUILDING|cial ideas. final, furious requests across the e
+33|Customer#000000033|qFSlMuLucBmx9xnn5ib2csWUweg D|4|27-375-391-1280|-78.56|AUTOMOBILE|s. slyly regular accounts are furiously. carefully pending requests
+34|Customer#000000034|Q6G9wZ6dnczmtOx509xgE,M2KV|11|25-344-968-5422|8589.70|HOUSEHOLD|nder against the even, pending accounts. even
+35|Customer#000000035|TEjWGE4nBzJL2|22|27-566-888-7431|1228.24|HOUSEHOLD|requests. special, express requests nag slyly furiousl
+36|Customer#000000036|3TvCzjuPzpJ0,DdJ8kW5U|15|31-704-669-5769|4987.27|BUILDING|haggle. enticing, quiet platelets grow quickly bold sheaves. carefully regular acc
+37|Customer#000000037|7EV4Pwh,3SboctTWt|11|18-385-235-7162|-917.75|FURNITURE|ilent packages are carefully among the deposits. furiousl
+38|Customer#000000038|a5Ee5e9568R8RLP 2ap7|14|22-306-880-7212|6345.11|HOUSEHOLD|lar excuses. closely even asymptotes cajole blithely excuses. carefully silent pinto beans sleep carefully fin
+39|Customer#000000039|nnbRg,Pvy33dfkorYE FdeZ60|3|12-387-467-6509|6264.31|AUTOMOBILE|tions. slyly silent excuses slee
+40|Customer#000000040|gOnGWAyhSV1ofv|1|13-652-915-8939|1335.30|BUILDING|rges impress after the slyly ironic courts. foxes are. blithely
+41|Customer#000000041|IM9mzmyoxeBmvNw8lA7G3Ydska2nkZF|0|20-917-711-4011|270.95|HOUSEHOLD|ly regular accounts hang bold, silent packages. unusual foxes haggle slyly above the special, final depo
+42|Customer#000000042|ziSrvyyBke|12|15-416-330-4175|8727.01|BUILDING|ssly according to the pinto beans: carefully special requests across the even, pending accounts wake special
+43|Customer#000000043|ouSbjHk8lh5fKX3zGso3ZSIj9Aa3PoaFd|1|29-316-665-2897|9904.28|MACHINERY|ial requests: carefully pending foxes detect quickly. carefully final courts cajole quickly. carefully
+44|Customer#000000044|Oi,dOSPwDu4jo4x,,P85E0dmhZGvNtBwi|2|26-190-260-5375|7315.94|AUTOMOBILE|r requests around the unusual, bold a
+45|Customer#000000045|4v3OcpFgoOmMG,CbnF,4mdC|2|19-715-298-9917|9983.38|AUTOMOBILE|nto beans haggle slyly alongside of t
+46|Customer#000000046|eaTXWWm10L9|3|16-357-681-2007|5744.59|AUTOMOBILE|ctions. accounts sleep furiously even requests. regular, regular accounts cajole blithely around the final pa
+47|Customer#000000047|b0UgocSqEW5 gdVbhNT|18|12-427-271-9466|274.58|BUILDING|ions. express, ironic instructions sleep furiously ironic ideas. furi
+48|Customer#000000048|0UU iPhBupFvemNB|15|10-508-348-5882|3792.50|BUILDING|re fluffily pending foxes. pending, bold platelets sleep slyly. even platelets cajo
+49|Customer#000000049|cNgAeX7Fqrdf7HQN9EwjUa4nxT,68L FKAxzl|0|20-908-631-4424|4573.94|FURNITURE|nusual foxes! fluffily pending packages maintain to the regular
+50|Customer#000000050|9SzDYlkzxByyJ1QeTI o|18|16-658-112-3221|4266.13|MACHINERY|ts. furiously ironic accounts cajole furiously slyly ironic dinos.
+51|Customer#000000051|uR,wEaiTvo4|14|22-344-885-4251|855.87|FURNITURE|eposits. furiously regular requests integrate carefully packages. furious
+52|Customer#000000052|7 QOqGqqSy9jfV51BC71jcHJSD0|9|21-186-284-5998|5630.28|HOUSEHOLD|ic platelets use evenly even accounts. stealthy theodolites cajole furiou
+53|Customer#000000053|HnaxHzTfFTZs8MuCpJyTbZ47Cm4wFOOgib|10|25-168-852-5363|4113.64|HOUSEHOLD|ar accounts are. even foxes are blithely. fluffily pending deposits boost
+54|Customer#000000054|,k4vf 5vECGWFy,hosTE,|4|14-776-370-4745|868.90|AUTOMOBILE|sual, silent accounts. furiously express accounts cajole special deposits. final, final accounts use furi
+55|Customer#000000055|zIRBR4KNEl HzaiV3a i9n6elrxzDEh8r8pDom|12|20-180-440-8525|4572.11|MACHINERY|ully unusual packages wake bravely bold packages. unusual requests boost deposits! blithely ironic packages ab
+56|Customer#000000056|BJYZYJQk4yD5B|19|20-895-685-6920|6530.86|FURNITURE|. notornis wake carefully. carefully fluffy requests are furiously even accounts. slyly expre
+57|Customer#000000057|97XYbsuOPRXPWU|13|31-835-306-1650|4151.93|AUTOMOBILE|ove the carefully special packages. even, unusual deposits sleep slyly pend
+58|Customer#000000058|g9ap7Dk1Sv9fcXEWjpMYpBZIRUohi T|9|23-244-493-2508|6478.46|HOUSEHOLD|ideas. ironic ideas affix furiously express, final instructions. regular excuses use quickly e
+59|Customer#000000059|zLOCP0wh92OtBihgspOGl4|9|11-355-584-3112|3458.60|MACHINERY|ously final packages haggle blithely after the express deposits. furiou
+60|Customer#000000060|FyodhjwMChsZmUz7Jz0H|1|22-480-575-5866|2741.87|MACHINERY|latelets. blithely unusual courts boost furiously about the packages. blithely final instruct
+61|Customer#000000061|9kndve4EAJxhg3veF BfXr7AqOsT39o gtqjaYE|13|27-626-559-8599|1536.24|FURNITURE|egular packages shall have to impress along the
+62|Customer#000000062|upJK2Dnw13,|18|17-361-978-7059|595.61|MACHINERY|kly special dolphins. pinto beans are slyly. quickly regular accounts are furiously a
+63|Customer#000000063|IXRSpVWWZraKII|20|31-952-552-9584|9331.13|AUTOMOBILE|ithely even accounts detect slyly above the fluffily ir
+64|Customer#000000064|MbCeGY20kaKK3oalJD,OT|15|13-558-731-7204|-646.64|BUILDING|structions after the quietly ironic theodolites cajole be
+65|Customer#000000065|RGT yzQ0y4l0H90P783LG4U95bXQFDRXbWa1sl,X|10|33-733-623-5267|8795.16|AUTOMOBILE|y final foxes serve carefully. theodolites are carefully. pending i
+66|Customer#000000066|XbsEqXH1ETbJYYtA1A|1|32-213-373-5094|242.77|HOUSEHOLD|le slyly accounts. carefully silent packages benea
+67|Customer#000000067|rfG0cOgtr5W8 xILkwp9fpCS8|0|19-403-114-4356|8166.59|MACHINERY|indle furiously final, even theodo
+68|Customer#000000068|o8AibcCRkXvQFh8hF,7o|3|22-918-832-2411|6853.37|HOUSEHOLD| pending pinto beans impress realms. final dependencies
+69|Customer#000000069|Ltx17nO9Wwhtdbe9QZVxNgP98V7xW97uvSH1prEw|13|19-225-978-5670|1709.28|HOUSEHOLD|thely final ideas around the quickly final dependencies affix carefully quickly final theodolites. final accounts c
+70|Customer#000000070|mFowIuhnHjp2GjCiYYavkW kUwOjIaTCQ|3|32-828-107-2832|4867.52|FURNITURE|fter the special asymptotes. ideas after the unusual frets cajole quickly regular pinto be
+71|Customer#000000071|TlGalgdXWBmMV,6agLyWYDyIz9MKzcY8gl,w6t1B|16|17-710-812-5403|-611.19|HOUSEHOLD|g courts across the regular, final pinto beans are blithely pending ac
+72|Customer#000000072|putjlmskxE,zs,HqeIA9Wqu7dhgH5BVCwDwHHcf|8|12-759-144-9689|-362.86|FURNITURE|ithely final foxes sleep always quickly bold accounts. final wat
+73|Customer#000000073|8IhIxreu4Ug6tt5mog4|4|10-473-439-3214|4288.50|BUILDING|usual, unusual packages sleep busily along the furiou
+74|Customer#000000074|IkJHCA3ZThF7qL7VKcrU nRLl,kylf |11|14-199-862-7209|2764.43|MACHINERY|onic accounts. blithely slow packages would haggle carefully. qui
+75|Customer#000000075|Dh 6jZ,cwxWLKQfRKkiGrzv6pm|2|28-247-803-9025|6684.10|AUTOMOBILE| instructions cajole even, even deposits. finally bold deposits use above the even pains. slyl
+76|Customer#000000076|m3sbCvjMOHyaOofH,e UkGPtqc4|8|10-349-718-3044|5745.33|FURNITURE|pecial deposits. ironic ideas boost blithely according to the closely ironic theodolites! furiously final deposits n
+77|Customer#000000077|4tAE5KdMFGD4byHtXF92vx|1|27-269-357-4674|1738.87|BUILDING|uffily silent requests. carefully ironic asymptotes among the ironic hockey players are carefully bli
+78|Customer#000000078|HBOta,ZNqpg3U2cSL0kbrftkPwzX|5|19-960-700-9191|7136.97|FURNITURE|ests. blithely bold pinto beans h
+79|Customer#000000079|n5hH2ftkVRwW8idtD,BmM2|2|25-147-850-4166|5121.28|MACHINERY|es. packages haggle furiously. regular, special requests poach after the quickly express ideas. blithely pending re
+80|Customer#000000080|K,vtXp8qYB |4|10-267-172-7101|7383.53|FURNITURE|tect among the dependencies. bold accounts engage closely even pinto beans. ca
+81|Customer#000000081|SH6lPA7JiiNC6dNTrR|17|30-165-277-3269|2023.71|BUILDING|r packages. fluffily ironic requests cajole fluffily. ironically regular theodolit
+82|Customer#000000082|zhG3EZbap4c992Gj3bK,3Ne,Xn|3|28-159-442-5305|9468.34|AUTOMOBILE|s wake. bravely regular accounts are furiously. regula
+83|Customer#000000083|HnhTNB5xpnSF20JBH4Ycs6psVnkC3RDf|7|32-817-154-4122|6463.51|BUILDING|ccording to the quickly bold warhorses. final, regular foxes integrate carefully. bold packages nag blithely ev
+84|Customer#000000084|lpXz6Fwr9945rnbtMc8PlueilS1WmASr CB|19|21-546-818-3802|5174.71|FURNITURE|ly blithe foxes. special asymptotes haggle blithely against the furiously regular depo
+85|Customer#000000085|siRerlDwiolhYR 8FgksoezycLj|0|15-745-585-8219|3386.64|FURNITURE|ronic ideas use above the slowly pendin
+86|Customer#000000086|US6EGGHXbTTXPL9SBsxQJsuvy|15|10-677-951-2353|3306.32|HOUSEHOLD|quests. pending dugouts are carefully aroun
+87|Customer#000000087|hgGhHVSWQl 6jZ6Ev|2|33-869-884-7053|6327.54|FURNITURE|hely ironic requests integrate according to the ironic accounts. slyly regular pla
+88|Customer#000000088|wtkjBN9eyrFuENSMmMFlJ3e7jE5KXcg|14|26-516-273-2566|8031.44|AUTOMOBILE|s are quickly above the quickly ironic instructions; even requests about the carefully final deposi
+89|Customer#000000089|dtR, y9JQWUO6FoJExyp8whOU|17|24-394-451-5404|1530.76|FURNITURE|counts are slyly beyond the slyly final accounts. quickly final ideas wake. r
+90|Customer#000000090|QxCzH7VxxYUWwfL7|14|26-603-491-1238|7354.23|BUILDING|sly across the furiously even
+91|Customer#000000091|S8OMYFrpHwoNHaGBeuS6E 6zhHGZiprw1b7 q|2|18-239-400-3677|4643.14|AUTOMOBILE|onic accounts. fluffily silent pinto beans boost blithely according to the fluffily exp
+92|Customer#000000092|obP PULk2LH LqNF,K9hcbNqnLAkJVsl5xqSrY,|12|12-446-416-8471|1182.91|MACHINERY|. pinto beans hang slyly final deposits. ac
+93|Customer#000000093|EHXBr2QGdh|19|17-359-388-5266|2182.52|MACHINERY|press deposits. carefully regular platelets r
+94|Customer#000000094|IfVNIN9KtkScJ9dUjK3Pg5gY1aFeaXewwf|5|19-953-499-8833|5500.11|HOUSEHOLD|latelets across the bold, final requests sleep according to the fluffily bold accounts. unusual deposits amon
+95|Customer#000000095|EU0xvmWvOmUUn5J,2z85DQyG7QCJ9Xq7|5|25-923-255-2929|5327.38|MACHINERY|ithely. ruthlessly final requests wake slyly alongside of the furiously silent pinto beans. even the
+96|Customer#000000096|vWLOrmXhRR|7|18-422-845-1202|6323.92|AUTOMOBILE|press requests believe furiously. carefully final instructions snooze carefully.
+97|Customer#000000097|OApyejbhJG,0Iw3j rd1M|16|27-588-919-5638|2164.48|AUTOMOBILE|haggle slyly. bold, special ideas are blithely above the thinly bold theo
+98|Customer#000000098|7yiheXNSpuEAwbswDW|11|22-885-845-6889|-551.37|BUILDING|ages. furiously pending accounts are quickly carefully final foxes: busily pe
+99|Customer#000000099|szsrOiPtCHVS97Lt|9|25-515-237-9232|4088.65|HOUSEHOLD|cajole slyly about the regular theodolites! furiously bold requests nag along the pending, regular packages. somas
+100|Customer#000000100|fptUABXcmkC5Wx|17|30-749-445-4907|9889.89|FURNITURE|was furiously fluffily quiet deposits. silent, pending requests boost against
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/dataset/TestJoinBroadcast/lineitem_large/lineitem.tbl
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/dataset/TestJoinBroadcast/lineitem_large/lineitem.tbl b/tajo-core/tajo-core-backend/src/test/resources/dataset/TestJoinBroadcast/lineitem_large/lineitem.tbl
new file mode 100644
index 0000000..e637c73
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/dataset/TestJoinBroadcast/lineitem_large/lineitem.tbl
@@ -0,0 +1,97 @@
+1|3|4|1|17|21168.23|0.04|0.02|N|O|1996-03-13|1996-02-12|1996-03-22|DELIVER IN PERSON|TRUCK|egular courts above the
+1|1|4|2|36|45983.16|0.09|0.06|N|O|1996-04-12|1996-02-28|1996-04-20|TAKE BACK RETURN|MAIL|ly final dependencies: slyly bold
+1|3|4|3|8|13309.60|0.10|0.02|N|O|1996-01-29|1996-03-05|1996-01-31|TAKE BACK RETURN|REG AIR|riously. regular, express dep
+1|2|3|4|28|28955.64|0.09|0.06|N|O|1996-04-21|1996-03-30|1996-05-16|NONE|AIR|lites. fluffily even de
+1|1|4|5|24|22824.48|0.10|0.04|N|O|1996-03-30|1996-03-14|1996-04-01|NONE|FOB| pending foxes. slyly re
+1|1|2|6|32|49620.16|0.07|0.02|N|O|1996-01-30|1996-02-07|1996-02-03|DELIVER IN PERSON|MAIL|arefully slyly ex
+2|2|2|1|38|44694.46|0.00|0.05|N|O|1997-01-28|1997-01-14|1997-02-02|TAKE BACK RETURN|RAIL|ven requests. deposits breach a
+3|1|3|1|45|54058.05|0.06|0.00|R|F|1994-02-02|1994-01-04|1994-02-23|NONE|AIR|ongside of the furiously brave acco
+3|2|2|2|49|46796.47|0.10|0.00|R|F|1993-11-09|1993-12-20|1993-11-24|TAKE BACK RETURN|RAIL| unusual accounts. eve
+3|3|2|3|27|39890.88|0.06|0.07|A|F|1994-01-16|1993-11-22|1994-01-23|DELIVER IN PERSON|SHIP|nal foxes wake.
+3|1|3|4|2|2618.76|0.01|0.06|A|F|1993-12-04|1994-01-07|1994-01-01|NONE|TRUCK|y. fluffily pending d
+3|3|2|5|28|32986.52|0.04|0.00|R|F|1993-12-14|1994-01-10|1994-01-01|TAKE BACK RETURN|FOB|ages nag slyly pending
+3|3|4|6|26|28733.64|0.10|0.02|A|F|1993-10-29|1993-12-18|1993-11-04|TAKE BACK RETURN|RAIL|ges sleep after the caref
+4|1|4|1|30|30690.90|0.03|0.08|N|O|1996-01-10|1995-12-14|1996-01-18|DELIVER IN PERSON|REG AIR|- quickly regular packages sleep. idly
+5|2|2|1|15|23678.55|0.02|0.04|R|F|1994-10-31|1994-08-31|1994-11-20|NONE|AIR|ts wake furiously
+5|3|2|2|26|50723.92|0.07|0.08|R|F|1994-10-16|1994-09-25|1994-10-19|NONE|FOB|sts use slyly quickly special instruc
+5|1|3|3|50|73426.50|0.08|0.03|A|F|1994-08-08|1994-10-13|1994-08-26|DELIVER IN PERSON|AIR|eodolites. fluffily unusual
+6|1|4|1|37|61998.31|0.08|0.03|A|F|1992-04-27|1992-05-15|1992-05-02|TAKE BACK RETURN|TRUCK|p furiously special foxes
+7|1|3|1|12|13608.60|0.07|0.03|N|O|1996-05-07|1996-03-13|1996-06-03|TAKE BACK RETURN|FOB|ss pinto beans wake against th
+7|2|2|2|9|11594.16|0.08|0.08|N|O|1996-02-01|1996-03-02|1996-02-19|TAKE BACK RETURN|SHIP|es. instructions
+7|3|4|3|46|81639.88|0.10|0.07|N|O|1996-01-15|1996-03-27|1996-02-03|COLLECT COD|MAIL| unusual reques
+7|1|2|4|28|31809.96|0.03|0.04|N|O|1996-03-21|1996-04-08|1996-04-20|NONE|FOB|. slyly special requests haggl
+7|2|3|5|38|73943.82|0.08|0.01|N|O|1996-02-11|1996-02-24|1996-02-18|DELIVER IN PERSON|TRUCK|ns haggle carefully ironic deposits. bl
+7|1|4|6|35|43058.75|0.06|0.03|N|O|1996-01-16|1996-02-23|1996-01-22|TAKE BACK RETURN|FOB|jole. excuses wake carefully alongside of
+7|2|2|7|5|6476.15|0.04|0.02|N|O|1996-02-10|1996-03-26|1996-02-13|NONE|FOB|ithely regula
+32|3|3|1|28|47227.60|0.05|0.08|N|O|1995-10-23|1995-08-27|1995-10-26|TAKE BACK RETURN|TRUCK|sleep quickly. req
+32|3|4|2|32|64605.44|0.02|0.00|N|O|1995-08-14|1995-10-07|1995-08-27|COLLECT COD|AIR|lithely regular deposits. fluffily
+32|3|2|3|2|2210.32|0.09|0.02|N|O|1995-08-07|1995-10-07|1995-08-23|DELIVER IN PERSON|AIR| express accounts wake according to the
+32|1|3|4|4|6582.96|0.09|0.03|N|O|1995-08-04|1995-10-01|1995-09-03|NONE|REG AIR|e slyly final pac
+32|3|3|5|44|79059.64|0.05|0.06|N|O|1995-08-28|1995-08-20|1995-09-14|DELIVER IN PERSON|AIR|symptotes nag according to the ironic depo
+32|3|2|6|6|9159.66|0.04|0.03|N|O|1995-07-21|1995-09-23|1995-07-25|COLLECT COD|RAIL| gifts cajole carefully.
+33|1|3|1|31|40217.23|0.09|0.04|A|F|1993-10-29|1993-12-19|1993-11-08|COLLECT COD|TRUCK|ng to the furiously ironic package
+33|3|2|2|32|47344.32|0.02|0.05|A|F|1993-12-09|1994-01-04|1993-12-28|COLLECT COD|MAIL|gular theodolites
+33|3|3|3|5|7532.30|0.05|0.03|A|F|1993-12-09|1993-12-25|1993-12-23|TAKE BACK RETURN|AIR|. stealthily bold exc
+33|2|4|4|41|75928.31|0.09|0.00|R|F|1993-11-09|1994-01-24|1993-11-11|TAKE BACK RETURN|MAIL|unusual packages doubt caref
+34|3|4|1|13|17554.68|0.00|0.07|N|O|1998-10-23|1998-09-14|1998-11-06|NONE|REG AIR|nic accounts. deposits are alon
+34|1|4|2|22|30875.02|0.08|0.06|N|O|1998-10-09|1998-10-16|1998-10-12|NONE|FOB|thely slyly p
+34|2|4|3|6|9681.24|0.02|0.06|N|O|1998-10-30|1998-09-20|1998-11-05|NONE|FOB|ar foxes sleep
+35|3|2|1|24|32410.80|0.02|0.00|N|O|1996-02-21|1996-01-03|1996-03-18|TAKE BACK RETURN|FOB|, regular tithe
+35|3|3|2|34|68065.96|0.06|0.08|N|O|1996-01-22|1996-01-06|1996-01-27|DELIVER IN PERSON|RAIL|s are carefully against the f
+35|3|2|3|7|13418.23|0.06|0.04|N|O|1996-01-19|1995-12-22|1996-01-29|NONE|MAIL| the carefully regular
+35|3|4|4|25|29004.25|0.06|0.05|N|O|1995-11-26|1995-12-25|1995-12-21|DELIVER IN PERSON|SHIP| quickly unti
+35|1|2|5|34|65854.94|0.08|0.06|N|O|1995-11-08|1996-01-15|1995-11-26|COLLECT COD|MAIL|. silent, unusual deposits boost
+35|3|2|6|28|47397.28|0.03|0.02|N|O|1996-02-01|1995-12-24|1996-02-28|COLLECT COD|RAIL|ly alongside of
+36|3|3|1|42|75043.92|0.09|0.00|N|O|1996-02-03|1996-01-21|1996-02-23|COLLECT COD|SHIP| careful courts. special
+37|1|4|1|40|62105.20|0.09|0.03|A|F|1992-07-21|1992-08-01|1992-08-15|NONE|REG AIR|luffily regular requests. slyly final acco
+37|1|3|2|39|70542.42|0.05|0.02|A|F|1992-07-02|1992-08-18|1992-07-28|TAKE BACK RETURN|RAIL|the final requests. ca
+37|1|2|3|43|78083.70|0.05|0.08|A|F|1992-07-10|1992-07-06|1992-08-02|DELIVER IN PERSON|TRUCK|iously ste
+38|2|3|1|44|84252.52|0.04|0.02|N|O|1996-09-29|1996-11-17|1996-09-30|COLLECT COD|MAIL|s. blithely unusual theodolites am
+39|2|2|1|44|53782.08|0.09|0.06|N|O|1996-11-14|1996-12-15|1996-12-12|COLLECT COD|RAIL|eodolites. careful
+39|2|3|2|26|43383.08|0.08|0.04|N|O|1996-11-04|1996-10-20|1996-11-20|NONE|FOB|ckages across the slyly silent
+39|2|4|3|46|82746.18|0.06|0.08|N|O|1996-09-26|1996-12-19|1996-10-26|DELIVER IN PERSON|AIR|he carefully e
+39|3|4|4|32|48338.88|0.07|0.05|N|O|1996-10-02|1996-12-19|1996-10-14|COLLECT COD|MAIL|heodolites sleep silently pending foxes. ac
+39|2|3|5|43|63360.93|0.01|0.01|N|O|1996-10-17|1996-11-14|1996-10-26|COLLECT COD|MAIL|yly regular i
+39|2|4|6|40|54494.40|0.06|0.05|N|O|1996-12-08|1996-10-22|1997-01-01|COLLECT COD|AIR|quickly ironic fox
+64|1|4|1|21|40675.95|0.05|0.02|R|F|1994-09-30|1994-09-18|1994-10-26|DELIVER IN PERSON|REG AIR|ch slyly final, thin platelets.
+65|3|3|1|26|42995.94|0.03|0.03|A|F|1995-04-20|1995-04-25|1995-05-13|NONE|TRUCK|pending deposits nag even packages. ca
+65|2|2|2|22|39353.82|0.00|0.05|N|O|1995-07-17|1995-06-04|1995-07-19|COLLECT COD|FOB| ideas. special, r
+65|3|2|3|21|27076.98|0.09|0.07|N|O|1995-07-06|1995-05-14|1995-07-31|DELIVER IN PERSON|RAIL|bove the even packages. accounts nag carefu
+66|3|2|1|31|35126.41|0.00|0.08|R|F|1994-02-19|1994-03-11|1994-02-20|TAKE BACK RETURN|RAIL|ut the unusual accounts sleep at the bo
+66|3|3|2|41|64061.68|0.04|0.07|A|F|1994-02-21|1994-03-01|1994-03-18|COLLECT COD|AIR| regular de
+67|1|3|1|4|6230.52|0.09|0.04|N|O|1997-04-17|1997-01-31|1997-04-20|NONE|SHIP| cajole thinly expres
+67|1|3|2|12|13358.28|0.09|0.05|N|O|1997-01-27|1997-02-21|1997-02-22|NONE|REG AIR| even packages cajole
+67|1|4|3|5|8368.00|0.03|0.07|N|O|1997-02-20|1997-02-12|1997-02-21|DELIVER IN PERSON|TRUCK|y unusual packages thrash pinto
+67|3|2|4|44|66066.44|0.08|0.06|N|O|1997-03-18|1997-01-29|1997-04-13|DELIVER IN PERSON|RAIL|se quickly above the even, express reques
+67|1|3|5|23|35733.03|0.05|0.07|N|O|1997-04-19|1997-02-14|1997-05-06|DELIVER IN PERSON|REG AIR|ly regular deposit
+67|2|4|6|29|40144.70|0.02|0.05|N|O|1997-01-25|1997-01-27|1997-01-27|DELIVER IN PERSON|FOB|ultipliers
+68|2|4|1|3|2925.18|0.05|0.02|N|O|1998-07-04|1998-06-05|1998-07-21|NONE|RAIL|fully special instructions cajole. furious
+68|1|3|2|46|57738.28|0.02|0.05|N|O|1998-06-26|1998-06-07|1998-07-05|NONE|MAIL| requests are unusual, regular pinto
+68|2|3|3|46|88089.08|0.04|0.05|N|O|1998-08-13|1998-07-08|1998-08-29|NONE|RAIL|egular dependencies affix ironically along
+68|2|3|4|20|34454.40|0.07|0.01|N|O|1998-06-27|1998-05-23|1998-07-02|NONE|REG AIR| excuses integrate fluffily
+68|3|4|5|27|47000.25|0.03|0.06|N|O|1998-06-19|1998-06-25|1998-06-29|DELIVER IN PERSON|SHIP|ccounts. deposits use. furiously
+68|1|3|6|30|46906.80|0.05|0.06|N|O|1998-08-11|1998-07-11|1998-08-14|NONE|RAIL|oxes are slyly blithely fin
+68|1|4|7|41|52735.84|0.09|0.08|N|O|1998-06-24|1998-06-27|1998-07-06|NONE|SHIP|eposits nag special ideas. furiousl
+69|3|2|1|48|58761.60|0.01|0.07|A|F|1994-08-17|1994-08-11|1994-09-08|NONE|TRUCK|regular epitaphs. carefully even ideas hag
+69|2|2|2|32|37893.76|0.08|0.06|A|F|1994-08-24|1994-08-17|1994-08-31|NONE|REG AIR|s sleep carefully bold,
+69|2|2|3|17|22172.42|0.09|0.00|A|F|1994-07-02|1994-07-07|1994-07-03|TAKE BACK RETURN|AIR|final, pending instr
+69|3|4|4|3|4318.50|0.09|0.04|R|F|1994-06-06|1994-07-27|1994-06-15|NONE|MAIL| blithely final d
+69|3|4|5|42|44606.94|0.07|0.04|R|F|1994-07-31|1994-07-26|1994-08-28|DELIVER IN PERSON|REG AIR|tect regular, speci
+69|2|2|6|23|32717.50|0.05|0.00|A|F|1994-10-03|1994-08-06|1994-10-24|NONE|SHIP|nding accounts ca
+70|3|4|1|8|8736.96|0.03|0.08|R|F|1994-01-12|1994-02-27|1994-01-14|TAKE BACK RETURN|FOB|ggle. carefully pending dependenc
+70|3|2|2|13|16277.95|0.06|0.06|A|F|1994-03-03|1994-02-13|1994-03-26|COLLECT COD|AIR|lyly special packag
+70|2|2|3|1|1888.80|0.03|0.05|R|F|1994-01-26|1994-03-05|1994-01-28|TAKE BACK RETURN|RAIL|quickly. fluffily unusual theodolites c
+70|2|2|4|11|18477.03|0.01|0.05|A|F|1994-03-17|1994-03-17|1994-03-27|NONE|MAIL|alongside of the deposits. fur
+70|2|2|5|37|39520.81|0.09|0.04|R|F|1994-02-13|1994-03-16|1994-02-21|COLLECT COD|MAIL|n accounts are. q
+70|3|2|6|19|30602.35|0.06|0.03|A|F|1994-01-26|1994-02-17|1994-02-06|TAKE BACK RETURN|SHIP| packages wake pending accounts.
+71|3|2|1|25|47323.25|0.09|0.07|N|O|1998-04-10|1998-04-22|1998-04-11|COLLECT COD|FOB|ckly. slyly
+71|3|2|2|3|5645.73|0.09|0.07|N|O|1998-05-23|1998-04-03|1998-06-02|COLLECT COD|SHIP|y. pinto beans haggle after the
+71|3|3|3|45|61489.35|0.00|0.07|N|O|1998-02-23|1998-03-20|1998-03-24|DELIVER IN PERSON|SHIP| ironic packages believe blithely a
+71|3|2|4|33|54174.12|0.00|0.01|N|O|1998-04-12|1998-03-20|1998-04-15|NONE|FOB| serve quickly fluffily bold deposi
+71|3|2|5|39|49071.75|0.08|0.06|N|O|1998-01-29|1998-04-07|1998-02-18|DELIVER IN PERSON|RAIL|l accounts sleep across the pack
+71|1|3|6|34|58841.42|0.04|0.01|N|O|1998-03-05|1998-04-22|1998-03-30|DELIVER IN PERSON|TRUCK|s cajole.
+96|1|2|1|23|25278.61|0.10|0.06|A|F|1994-07-19|1994-06-29|1994-07-25|DELIVER IN PERSON|TRUCK|ep-- carefully reg
+96|3|4|2|30|42761.70|0.01|0.06|R|F|1994-06-03|1994-05-29|1994-06-22|DELIVER IN PERSON|TRUCK|e quickly even ideas. furiou
+97|1|3|1|13|19454.11|0.00|0.02|R|F|1993-04-01|1993-04-04|1993-04-08|NONE|TRUCK|ayers cajole against the furiously
+97|1|3|2|37|56149.72|0.02|0.06|A|F|1993-04-13|1993-03-30|1993-04-14|DELIVER IN PERSON|SHIP|ic requests boost carefully quic
+97|1|2|3|19|31857.11|0.06|0.08|R|F|1993-05-14|1993-03-05|1993-05-25|TAKE BACK RETURN|RAIL|gifts. furiously ironic packages cajole.
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/create_customer_large_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/create_customer_large_ddl.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/create_customer_large_ddl.sql
new file mode 100644
index 0000000..e5be236
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/create_customer_large_ddl.sql
@@ -0,0 +1,7 @@
+-- Large customer Table
+-- It is used for broadcast join
+
+create external table if not exists customer_large (
+ c_custkey INT4, c_name TEXT, c_address TEXT, c_nationkey INT4,
+ c_phone TEXT, c_acctbal FLOAT8, c_mktsegment TEXT, c_comment TEXT)
+using csv with ('csvfile.delimiter'='|', 'csvfile.null'='NULL') location ${table.path};
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/create_lineitem_large_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/create_lineitem_large_ddl.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/create_lineitem_large_ddl.sql
new file mode 100644
index 0000000..366f22b
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/create_lineitem_large_ddl.sql
@@ -0,0 +1,7 @@
+-- Large lineitem Table
+-- It is used for broadcast join
+
+create external table if not exists lineitem_large ( l_orderkey INT4, l_partkey INT4, l_suppkey INT4, l_linenumber INT4, l_quantity FLOAT8,
+ l_extendedprice FLOAT8, l_discount FLOAT8, l_tax FLOAT8, l_returnflag TEXT, l_linestatus TEXT, l_shipdate TEXT, l_commitdate TEXT,
+ l_receiptdate TEXT, l_shipinstruct TEXT, l_shipmode TEXT, l_comment TEXT)
+using csv with ('csvfile.delimiter'='|', 'csvfile.null'='NULL') location ${table.path};
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/oj_table1_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/oj_table1_ddl.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/oj_table1_ddl.sql
new file mode 100644
index 0000000..c373a64
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/oj_table1_ddl.sql
@@ -0,0 +1,6 @@
+-- Outer Join's Left Table
+-- It is used in TestJoin::testOuterJoinAndCaseWhen
+
+create external table if not exists table1 (id int, name text, score float, type text) using csv
+with ('csvfile.delimiter'='|', 'csvfile.null'='NULL') location ${table.path};
+
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/oj_table2_ddl.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/oj_table2_ddl.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/oj_table2_ddl.sql
new file mode 100644
index 0000000..ec2d82f
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/oj_table2_ddl.sql
@@ -0,0 +1,6 @@
+-- Outer Join's Left Table
+-- It is used in TestJoin::testOuterJoinAndCaseWhen
+
+create external table if not exists table2 (id int, name text, score float, type text) using csv
+with ('csvfile.delimiter'='|', 'csvfile.null'='NULL') location ${table.path};
+
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testBroadcastBasicJoin.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testBroadcastBasicJoin.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testBroadcastBasicJoin.sql
new file mode 100644
index 0000000..24ac942
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testBroadcastBasicJoin.sql
@@ -0,0 +1,11 @@
+select
+ l_orderkey,
+ p_name,
+ s_name
+from
+ lineitem_large,
+ part,
+ supplier
+where
+ lineitem_large.l_partkey = part.p_partkey
+ and lineitem_large.l_suppkey = supplier.s_suppkey;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testBroadcastSubquery.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testBroadcastSubquery.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testBroadcastSubquery.sql
new file mode 100644
index 0000000..dcd9569
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testBroadcastSubquery.sql
@@ -0,0 +1,11 @@
+select
+ l_orderkey,
+ a.o_custkey,
+ p_name
+from
+ lineitem_large,
+ part,
+ (select o_orderkey, o_custkey from orders) a
+where
+ l_partkey = p_partkey
+ and l_orderkey = a.o_orderkey
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testBroadcastSubquery2.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testBroadcastSubquery2.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testBroadcastSubquery2.sql
new file mode 100644
index 0000000..81729c9
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testBroadcastSubquery2.sql
@@ -0,0 +1,19 @@
+select sum(b.l_quantity)
+from (
+ select a.l_orderkey, a.l_quantity
+ from lineitem_large a
+ join part on a.l_partkey = p_partkey) b
+join orders c on c.o_orderkey = b.l_orderkey
+join (
+ select e.l_orderkey, avg(e.l_quantity) avg_quantity
+ from (
+ select d.l_orderkey, d.l_quantity
+ from lineitem_large d
+ join part on d.l_partkey = p_partkey
+ ) e
+ group by e.l_orderkey
+) f
+on c.o_orderkey = f.l_orderkey
+where
+ c.o_orderkey > 0 and
+ b.l_quantity > f.avg_quantity
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/464f3e52/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testBroadcastTwoPartJoin.sql
----------------------------------------------------------------------
diff --git a/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testBroadcastTwoPartJoin.sql b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testBroadcastTwoPartJoin.sql
new file mode 100644
index 0000000..bdad24f
--- /dev/null
+++ b/tajo-core/tajo-core-backend/src/test/resources/queries/TestJoinBroadcast/testBroadcastTwoPartJoin.sql
@@ -0,0 +1,15 @@
+select
+ l_orderkey,
+ p_name,
+ n_name
+from
+ lineitem_large,
+ orders,
+ part,
+ customer_large,
+ nation
+where
+ l_orderkey = o_orderkey
+ and l_partkey = p_partkey
+ and o_custkey = c_custkey
+ and c_nationkey = n_nationkey
\ No newline at end of file