@@ -1721,6 +1721,35 @@ def plan_builder(
17211721 execution_time or now (),
17221722 )
17231723
1724+ execution_time_ts = to_timestamp (execution_time ) if execution_time is not None else None
1725+ if (
1726+ execution_time_ts is not None
1727+ and end is None
1728+ and default_end is not None
1729+ and execution_time_ts > default_end
1730+ ):
1731+ # An explicitly provided execution time acts as the plan's effective "now", so the
1732+ # default end is allowed to extend past the recorded prod frontier instead of being
1733+ # capped by it. This mirrors how an explicit `end` causes the per-model interval end
1734+ # caps to be dropped entirely in PlanBuilder.build() (see `self.override_end`,
1735+ # sqlmesh/core/plan/builder.py line 206). Raising (rather than dropping) the caps is
1736+ # safe here because `plan --run` already runs with no caps at all.
1737+ #
1738+ # Note this raises every entry already present in max_interval_end_per_model (i.e.
1739+ # every model in this dict, which _get_max_interval_end_per_model above has already
1740+ # scoped down to backfill_models/its ancestors when a selection is in effect) - not
1741+ # just modified or explicitly selected models within that scope. That's intentional,
1742+ # not an oversight. It's what makes a plain, unscoped `sqlmesh plan --execution-time X`
1743+ # in prod report the same missing intervals as `sqlmesh plan --run --execution-time X`
1744+ # would at the same simulated time. Narrowing this further would reintroduce a `plan`
1745+ # vs `plan --run` mismatch for models within that scope.
1746+ default_end = execution_time_ts
1747+ execution_time_dt = to_datetime (execution_time_ts )
1748+ max_interval_end_per_model = {
1749+ model_fqn : max (interval_end , execution_time_dt )
1750+ for model_fqn , interval_end in max_interval_end_per_model .items ()
1751+ }
1752+
17241753 # Refresh snapshot intervals to ensure that they are up to date with values reflected in the max_interval_end_per_model.
17251754 self .state_sync .refresh_snapshot_intervals (context_diff .snapshots .values ())
17261755
0 commit comments