@@ -1115,6 +1115,114 @@ TEST_F(PlanTest, lambdaArgs) {
11151115 AXIOM_ASSERT_PLAN (plan, matcher);
11161116}
11171117
1118+ TEST_F (PlanTest, joinWithFilterOverLimit) {
1119+ testConnector_->addTable (" t" , ROW ({" a" , " b" , " c" }, BIGINT ()));
1120+ testConnector_->addTable (" u" , ROW ({" x" , " y" , " z" }, BIGINT ()));
1121+
1122+ lp::PlanBuilder::Context ctx (kTestConnectorId );
1123+ auto logicalPlan =
1124+ lp::PlanBuilder (ctx)
1125+ .tableScan (" t" )
1126+ .limit (100 )
1127+ .filter (" b > 50" )
1128+ .join (
1129+ lp::PlanBuilder (ctx).tableScan (" u" ).limit (50 ).filter (" y < 100" ),
1130+ " a = x" ,
1131+ lp::JoinType::kInner )
1132+ .build ();
1133+
1134+ {
1135+ auto plan = toSingleNodePlan (logicalPlan);
1136+ auto matcher = core::PlanMatcherBuilder ()
1137+ .tableScan (" t" )
1138+ .limit ()
1139+ .filter (" b > 50" )
1140+ .hashJoin (
1141+ core::PlanMatcherBuilder ()
1142+ .tableScan (" u" )
1143+ .limit ()
1144+ .filter (" y < 100" )
1145+ .build ())
1146+ .build ();
1147+
1148+ AXIOM_ASSERT_PLAN (plan, matcher);
1149+ }
1150+ }
1151+
1152+ TEST_F (PlanTest, outerJoinWithInnerJoin) {
1153+ testConnector_->addTable (" t" , ROW ({" a" , " b" , " c" }, BIGINT ()));
1154+ testConnector_->addTable (" v" , ROW ({" vx" , " vy" , " vz" }, BIGINT ()));
1155+ testConnector_->addTable (" u" , ROW ({" x" , " y" , " z" }, BIGINT ()));
1156+
1157+ lp::PlanBuilder::Context ctx (kTestConnectorId );
1158+ auto logicalPlan = lp::PlanBuilder (ctx)
1159+ .tableScan (" t" )
1160+ .filter (" b > 50" )
1161+ .join (
1162+ lp::PlanBuilder (ctx).tableScan (" u" ).join (
1163+ lp::PlanBuilder (ctx).tableScan (" v" ),
1164+ " x = vx" ,
1165+ lp::JoinType::kInner ),
1166+ " a = x" ,
1167+ lp::JoinType::kLeft )
1168+ .build ();
1169+
1170+ {
1171+ SCOPED_TRACE (" left join with inner join on right" );
1172+
1173+ auto plan = toSingleNodePlan (logicalPlan);
1174+ auto matcher =
1175+ core::PlanMatcherBuilder ()
1176+ .tableScan (" t" )
1177+ .filter (" b > 50" )
1178+ .hashJoin (
1179+ core::PlanMatcherBuilder ()
1180+ .tableScan (" u" )
1181+ .hashJoin (core::PlanMatcherBuilder ().tableScan (" v" ).build ())
1182+
1183+ .build ())
1184+ .build ();
1185+
1186+ AXIOM_ASSERT_PLAN (plan, matcher);
1187+ }
1188+
1189+ logicalPlan = lp::PlanBuilder (ctx)
1190+ .tableScan (" t" )
1191+ .filter (" b > 50" )
1192+ .aggregate ({" a" , " b" }, {" sum(c)" })
1193+ .join (
1194+ lp::PlanBuilder (ctx)
1195+ .tableScan (" u" )
1196+ .join (
1197+ lp::PlanBuilder (ctx).tableScan (" v" ),
1198+ " x = vx" ,
1199+ lp::JoinType::kInner )
1200+ .filter (" not(x = vy)" ),
1201+ " a = x" ,
1202+ lp::JoinType::kLeft )
1203+ .build ();
1204+
1205+ {
1206+ SCOPED_TRACE (" Aggregation left join filter over inner join" );
1207+ auto plan = toSingleNodePlan (logicalPlan);
1208+ auto matcher =
1209+ core::PlanMatcherBuilder ()
1210+ .tableScan (" t" )
1211+ .filter ()
1212+ .aggregation ()
1213+ .hashJoin (
1214+ core::PlanMatcherBuilder ()
1215+ .tableScan (" u" )
1216+ .hashJoin (core::PlanMatcherBuilder ().tableScan (" v" ).build ())
1217+ .filter ()
1218+ .build ())
1219+ .project ()
1220+ .build ();
1221+
1222+ AXIOM_ASSERT_PLAN (plan, matcher);
1223+ }
1224+ }
1225+
11181226} // namespace
11191227} // namespace facebook::axiom::optimizer
11201228
0 commit comments