2525import java .util .Comparator ;
2626import java .util .List ;
2727import java .util .UUID ;
28- import java .util .function .Consumer ;
2928import java .util .function .Predicate ;
3029import java .util .stream .Collectors ;
3130import com .google .common .collect .ImmutableSet ;
7675import org .apache .ignite .internal .processors .query .calcite .schema .IgniteSchema ;
7776import org .apache .ignite .internal .processors .query .calcite .trait .IgniteDistribution ;
7877import org .apache .ignite .internal .processors .query .calcite .type .IgniteTypeFactory ;
78+ import org .apache .ignite .internal .util .lang .RunnableX ;
7979import org .apache .ignite .internal .util .typedef .F ;
80- import org .apache .ignite .internal .util .typedef .T2 ;
8180import org .apache .ignite .plugin .extensions .communication .Message ;
8281import org .apache .ignite .testframework .GridTestUtils ;
8382import org .apache .ignite .testframework .ListeningTestLogger ;
@@ -225,6 +224,32 @@ protected PlanningContext plannerCtx(
225224 return plannerCtx (sql , Collections .singleton (publicSchema ), planLsnr , null , disabledRules );
226225 }
227226
227+ /** */
228+ private PlanningContext plannerCtx (
229+ String sql ,
230+ Collection <IgniteSchema > schemas ,
231+ @ Nullable RelOptListener planLsnr ,
232+ Collection <Object > params ,
233+ Collection <String > disabledRules
234+ ) {
235+ PlanningContext .Builder ctxBuilder = PlanningContext .builder ()
236+ .parentContext (Contexts .of (baseQueryContext (schemas ), planLsnr ))
237+ .query (sql );
238+
239+ if (params != null )
240+ ctxBuilder .parameters (params .toArray (Object []::new ));
241+
242+ PlanningContext ctx = ctxBuilder .build ();
243+
244+ IgnitePlanner planner = ctx .planner ();
245+
246+ assertNotNull (planner );
247+
248+ planner .addDisabledRules (disabledRules );
249+
250+ return ctx ;
251+ }
252+
228253 /** */
229254 protected PlanningContext plannerCtx (
230255 String sql ,
@@ -445,14 +470,31 @@ protected static TestTable createTable(IgniteSchema schema, String name, RelData
445470 return table ;
446471 }
447472
473+ /** */
474+ protected <T extends RelNode > void assertPlan (
475+ TestPlanningContextBuilder ctxBuilder
476+ ) throws Exception {
477+ assertPlan (ctxBuilder , rel -> true );
478+ }
479+
480+ /** */
481+ protected <T extends RelNode > void assertPlan (
482+ TestPlanningContextBuilder ctxBuilder ,
483+ Predicate <T > predicate
484+ ) throws Exception {
485+ invalidatePlan (ctxBuilder , predicate );
486+ }
487+
448488 /** */
449489 protected <T extends RelNode > void assertPlan (
450490 String sql ,
451491 IgniteSchema schema ,
452492 Predicate <T > predicate ,
453493 String ... disabledRules
454494 ) throws Exception {
455- assertPlan (sql , schema , null , predicate , disabledRules );
495+ TestPlanningContextBuilder builder = contextBuilder ().query (sql ).schema (schema ).disabledRules (disabledRules );
496+
497+ assertPlan (builder , predicate );
456498 }
457499
458500 /** */
@@ -462,20 +504,34 @@ protected <T extends RelNode> void assertPlan(
462504 Predicate <T > predicate ,
463505 String ... disabledRules
464506 ) throws Exception {
465- assertPlan (sql , schemas , null , predicate , disabledRules );
507+ TestPlanningContextBuilder builder = contextBuilder ().query (sql ).schemas (schemas ).disabledRules (disabledRules );
508+
509+ assertPlan (builder , predicate );
466510 }
467511
468512 /** */
469513 protected <T extends RelNode > void assertPlan (
470514 String sql ,
471- Collection < IgniteSchema > schemas ,
472- @ Nullable RelOptListener planLsnr ,
515+ IgniteSchema schema ,
516+ RelOptListener planLsnr ,
473517 Predicate <T > predicate ,
474518 String ... disabledRules
475519 ) throws Exception {
476- IgniteRel plan = physicalPlan (plannerCtx (sql , schemas , planLsnr , null , disabledRules ));
520+ TestPlanningContextBuilder builder = contextBuilder ().query (sql ).schema (schema ).disabledRules (disabledRules )
521+ .planListener (planLsnr );
522+
523+ assertPlan (builder , predicate );
524+ }
525+
526+ /** */
527+ private <T extends RelNode > void invalidatePlan (
528+ TestPlanningContextBuilder ctxBuilder ,
529+ Predicate <T > predicate
530+ ) throws Exception {
531+ IgniteRel plan = physicalPlan (plannerCtx (ctxBuilder .query , ctxBuilder .schemas , ctxBuilder .planListener ,
532+ ctxBuilder .params , ctxBuilder .disabledRules ));
477533
478- checkSplitAndSerialization (plan , schemas );
534+ checkSplitAndSerialization (plan , ctxBuilder . schemas );
479535
480536 if (!predicate .test ((T )plan )) {
481537 String invalidPlanMsg = "Invalid plan (" + lastErrorMsg + "):\n " +
@@ -485,17 +541,6 @@ protected <T extends RelNode> void assertPlan(
485541 }
486542 }
487543
488- /** */
489- protected <T extends RelNode > void assertPlan (
490- String sql ,
491- IgniteSchema schema ,
492- @ Nullable RelOptListener planLsnr ,
493- Predicate <T > predicate ,
494- String ... disabledRules
495- ) throws Exception {
496- assertPlan (sql , Collections .singletonList (schema ), planLsnr , predicate , disabledRules );
497- }
498-
499544 /**
500545 * Predicate builder for "Instance of class" condition.
501546 */
@@ -813,48 +858,78 @@ class TestFailureProcessor extends FailureProcessor {
813858 }
814859 }
815860
816- /**
817- * Creates an instance of {@link StatementChecker statement checker} to test plans.
818- * <pre>
819- * checkStatement().sql("SELECT 1").ok()
820- * </pre>
821- */
822- public StatementChecker checkStatement () {
823- return new PlanChecker ();
824- }
861+ /** Test planning context builder. */
862+ public static class TestPlanningContextBuilder {
863+ /** */
864+ private String query ;
825865
826- /**
827- * Creates an instance of {@link PlanChecker statement checker} with the given setup.
828- * A shorthand for {@code checkStatement().setup(func)}.
829- */
830- public StatementChecker checkStatement (Consumer <StatementChecker > setup ) {
831- return new PlanChecker ().setup (setup );
832- }
866+ /** */
867+ private Collection <IgniteSchema > schemas ;
833868
834- /**
835- * An implementation of {@link PlanChecker} with initialized {@link SqlPrepare} to test plans.
836- */
837- public class PlanChecker extends StatementChecker {
838869 /** */
839- PlanChecker () {
840- super ((schema , sql , params , rulesToDisable ) -> {
841- PlanningContext planningCtx = plannerCtx (sql , List .of (schema ), null , params , rulesToDisable );
842-
843- IgnitePlanner planner = planningCtx .planner ();
844- try {
845- IgniteRel igniteRel = physicalPlan (planner , sql );
846- return new T2 <>(igniteRel , planner );
847- }
848- catch (Throwable t ) {
849- planner .close ();
850- throw t ;
851- }
852- });
870+ private Collection <Object > params = List .of ();
871+
872+ /** */
873+ private Collection <String > disabledRules = List .of ();
874+
875+ /** */
876+ @ Nullable private RelOptListener planListener ;
877+
878+ /** */
879+ public TestPlanningContextBuilder query (String qry ) {
880+ query = qry ;
881+ return this ;
853882 }
854883
855- /** {@inheritDoc} */
856- @ Override protected void checkRel (IgniteRel igniteRel , IgnitePlanner planner , IgniteSchema schema ) {
857- checkSplitAndSerialization (igniteRel , schema );
884+ /** */
885+ public TestPlanningContextBuilder schema (IgniteSchema schemas ) {
886+ this .schemas = List .of (schemas );
887+ return this ;
888+ }
889+
890+ /** */
891+ public TestPlanningContextBuilder schemas (Collection <IgniteSchema > schemas ) {
892+ this .schemas = List .copyOf (schemas );
893+ return this ;
894+ }
895+
896+ /** */
897+ public TestPlanningContextBuilder params (Collection <Object > params ) {
898+ this .params = List .copyOf (params );
899+ return this ;
900+ }
901+
902+ /** */
903+ public TestPlanningContextBuilder params (Object ... params ) {
904+ this .params = Arrays .asList (params );
905+ return this ;
858906 }
907+
908+ /** */
909+ public TestPlanningContextBuilder disabledRules (String ... rules ) {
910+ disabledRules = List .of (rules );
911+ return this ;
912+ }
913+
914+ /** */
915+ public TestPlanningContextBuilder planListener (@ Nullable RelOptListener planListener ) {
916+ this .planListener = planListener ;
917+ return this ;
918+ }
919+ }
920+
921+ /** */
922+ public static TestPlanningContextBuilder contextBuilder () {
923+ return new TestPlanningContextBuilder ();
924+ }
925+
926+ /** */
927+ @ SuppressWarnings ("ThrowableNotThrown" )
928+ static void assertThrows (
929+ RunnableX run ,
930+ Class <? extends Throwable > cls ,
931+ @ Nullable String msg
932+ ) {
933+ GridTestUtils .assertThrows (null , run , cls , msg );
859934 }
860935}
0 commit comments