@@ -767,6 +767,73 @@ def test_cron_not_aligned_with_day_boundary_new_model(init_and_plan_context: t.C
767767 ]
768768
769769
770+ @time_machine .travel ("2023-01-08 00:00:00 UTC" )
771+ def test_forward_only_preview_child_that_runs_before_parent (init_and_plan_context : t .Callable ):
772+ context , _ = init_and_plan_context ("examples/sushi" )
773+
774+ # This model runs at minute 30 of every hour
775+ upstream_model = load_sql_based_model (
776+ d .parse (
777+ """
778+ MODEL (
779+ name memory.sushi.upstream_model,
780+ kind FULL,
781+ cron '30 * * * *',
782+ start '2023-01-01',
783+ );
784+
785+ SELECT 1 AS a;
786+ """
787+ )
788+ )
789+ context .upsert_model (upstream_model )
790+
791+ # This model runs at minute 0 of every hour, so it runs before the upstream model
792+ downstream_model = load_sql_based_model (
793+ d .parse (
794+ """
795+ MODEL (
796+ name memory.sushi.downstream_model,
797+ kind INCREMENTAL_BY_TIME_RANGE(
798+ time_column event_date,
799+ forward_only True,
800+ ),
801+ cron '0 * * * *',
802+ start '2023-01-01',
803+ );
804+
805+ SELECT a, '2023-01-06' AS event_date FROM memory.sushi.upstream_model;
806+ """
807+ )
808+ )
809+ context .upsert_model (downstream_model )
810+
811+ context .plan ("prod" , skip_tests = True , auto_apply = True )
812+
813+ with time_machine .travel ("2023-01-08 00:05:00 UTC" ):
814+ # The downstream model runs but not the upstream model
815+ context .run ("prod" )
816+
817+ # Now it's time for the upstream model to run but it hasn't run yet
818+ with time_machine .travel ("2023-01-08 00:35:00 UTC" ):
819+ # Make a change to the downstream model.
820+ downstream_model = add_projection_to_model (t .cast (SqlModel , downstream_model ), literal = True )
821+ context .upsert_model (downstream_model )
822+
823+ # The plan should only backfill the downstream model despite upstream missing intervals
824+ plan = context .plan_builder ("dev" , skip_tests = True , enable_preview = True ).build ()
825+ assert plan .missing_intervals == [
826+ SnapshotIntervals (
827+ snapshot_id = context .get_snapshot (
828+ downstream_model .name , raise_if_missing = True
829+ ).snapshot_id ,
830+ intervals = [
831+ (to_timestamp ("2023-01-07 23:00:00" ), to_timestamp ("2023-01-08 00:00:00" ))
832+ ],
833+ ),
834+ ]
835+
836+
770837@time_machine .travel ("2023-01-08 00:00:00 UTC" )
771838def test_forward_only_monthly_model (init_and_plan_context : t .Callable ):
772839 context , _ = init_and_plan_context ("examples/sushi" )
0 commit comments