### Body

Currently `start_date` is mandatory parameter.
For DAGs with `schedule=None` we can relax this requirement as no scheduling calculation needed so the `start_date` parameter isn't used.

### Committer

- [X] I acknowledge that I am a maintainer/committer of the Apache Airflow project.
from airflow.utils.helpers import chunks, is_container, prune_dict
from airflow.utils.log.logging_mixin import LoggingMixin
from airflow.utils.session import NEW_SESSION, provide_session
from airflow.utils.sqlalchemy import UtcDateTime, nulls_first, skip_locked, tuple_in_condition, with_row_locks
from airflow.utils.state import DagRunState, State, TaskInstanceState
from airflow.utils.types import NOTSET, DagRunType
if TYPE_CHECKING:
    from datetime import datetime
    from sqlalchemy.orm import Query, Session
    from airflow.models.dag import DAG
    from airflow.models.operator import Operator
    from airflow.serialization.pydantic.dag_run import DagRunPydantic
    from airflow.serialization.pydantic.taskinstance import TaskInstancePydantic
    from airflow.typing_compat import Literal
    from airflow.utils.types import ArgNotSet
    CreatedTasks = TypeVar("CreatedTasks", Iterator["dict[str, Any]"], Iterator[TI])
    TaskCreator = Callable[[Operator, Iterable[int]], CreatedTasks]
RUN_ID_REGEX = r"^(?:manual|scheduled|dataset_triggered)__(?:\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\+00:00)$"
class TISchedulingDecision(NamedTuple):
    """Type of return for DagRun.task_instance_scheduling_decisions."""
    tis: list[TI]
    schedulable_tis: list[TI]
    changed_tis: bool
    unfinished_tis: list[TI]
    finished_tis: list[TI]
class ConfDict(dict):
    """Custom dictionary for storing only JSON serializable values."""
    def __init__(self, val=None):
        super().__init__(self.is_jsonable(val))
    def __setitem__(self, key, value):