mirror of
https://github.com/home-assistant/core.git
synced 2025-07-09 22:37:11 +00:00
Guard against selecting all invalid entity_ids in history (#89929)
If all the entity_ids that were provided do not exist we would end up passing an empty list of ids to the SQL query which would do an unbounded select
This commit is contained in:
parent
5ffb233004
commit
7f3e4cb3af
@ -14,6 +14,7 @@ from homeassistant.components.recorder import get_instance
|
||||
from homeassistant.components.recorder.filters import Filters
|
||||
from homeassistant.components.recorder.models import (
|
||||
bytes_to_uuid_hex_or_none,
|
||||
extract_metadata_ids,
|
||||
process_datetime_to_timestamp,
|
||||
process_timestamp_to_utc_isoformat,
|
||||
)
|
||||
@ -154,14 +155,11 @@ class EventProcessor:
|
||||
metadata_ids: list[int] | None = None
|
||||
if self.entity_ids:
|
||||
instance = get_instance(self.hass)
|
||||
entity_id_to_metadata_id = instance.states_meta_manager.get_many(
|
||||
self.entity_ids, session, False
|
||||
metadata_ids = extract_metadata_ids(
|
||||
instance.states_meta_manager.get_many(
|
||||
self.entity_ids, session, False
|
||||
)
|
||||
)
|
||||
metadata_ids = [
|
||||
metadata_id
|
||||
for metadata_id in entity_id_to_metadata_id.values()
|
||||
if metadata_id is not None
|
||||
]
|
||||
stmt = statement_for_request(
|
||||
start_day,
|
||||
end_day,
|
||||
|
@ -23,7 +23,12 @@ import homeassistant.util.dt as dt_util
|
||||
from ... import recorder
|
||||
from ..db_schema import RecorderRuns, StateAttributes, States, StatesMeta
|
||||
from ..filters import Filters
|
||||
from ..models import LazyState, process_timestamp, row_to_compressed_state
|
||||
from ..models import (
|
||||
LazyState,
|
||||
extract_metadata_ids,
|
||||
process_timestamp,
|
||||
row_to_compressed_state,
|
||||
)
|
||||
from ..util import execute_stmt_lambda_element, session_scope
|
||||
from .const import (
|
||||
IGNORE_DOMAINS_ENTITY_ID_LIKE,
|
||||
@ -232,14 +237,12 @@ def get_significant_states_with_session(
|
||||
entity_id_to_metadata_id: dict[str, int | None] | None = None
|
||||
if entity_ids:
|
||||
instance = recorder.get_instance(hass)
|
||||
entity_id_to_metadata_id = instance.states_meta_manager.get_many(
|
||||
entity_ids, session, False
|
||||
)
|
||||
metadata_ids = [
|
||||
metadata_id
|
||||
for metadata_id in entity_id_to_metadata_id.values()
|
||||
if metadata_id is not None
|
||||
]
|
||||
if not (
|
||||
entity_id_to_metadata_id := instance.states_meta_manager.get_many(
|
||||
entity_ids, session, False
|
||||
)
|
||||
) or not (metadata_ids := extract_metadata_ids(entity_id_to_metadata_id)):
|
||||
return {}
|
||||
stmt = _significant_states_stmt(
|
||||
start_time,
|
||||
end_time,
|
||||
@ -569,14 +572,9 @@ def _get_rows_with_session(
|
||||
# We have more than one entity to look at so we need to do a query on states
|
||||
# since the last recorder run started.
|
||||
if entity_ids:
|
||||
if not entity_id_to_metadata_id:
|
||||
return []
|
||||
metadata_ids = [
|
||||
metadata_id
|
||||
for metadata_id in entity_id_to_metadata_id.values()
|
||||
if metadata_id is not None
|
||||
]
|
||||
if not metadata_ids:
|
||||
if not entity_id_to_metadata_id or not (
|
||||
metadata_ids := extract_metadata_ids(entity_id_to_metadata_id)
|
||||
):
|
||||
return []
|
||||
stmt = _get_states_for_entities_stmt(
|
||||
run.start, utc_point_in_time, metadata_ids, no_attributes
|
||||
|
@ -8,7 +8,7 @@ from .context import (
|
||||
uuid_hex_to_bytes_or_none,
|
||||
)
|
||||
from .database import DatabaseEngine, DatabaseOptimizer, UnsupportedDialect
|
||||
from .state import LazyState, row_to_compressed_state
|
||||
from .state import LazyState, extract_metadata_ids, row_to_compressed_state
|
||||
from .statistics import (
|
||||
CalendarStatisticPeriod,
|
||||
FixedStatisticPeriod,
|
||||
@ -43,6 +43,7 @@ __all__ = [
|
||||
"bytes_to_ulid_or_none",
|
||||
"bytes_to_uuid_hex_or_none",
|
||||
"datetime_to_timestamp_or_none",
|
||||
"extract_metadata_ids",
|
||||
"process_datetime_to_timestamp",
|
||||
"process_timestamp",
|
||||
"process_timestamp_to_utc_isoformat",
|
||||
|
@ -24,6 +24,17 @@ from .time import process_timestamp
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def extract_metadata_ids(
|
||||
entity_id_to_metadata_id: dict[str, int | None],
|
||||
) -> list[int]:
|
||||
"""Extract metadata ids from entity_id_to_metadata_id."""
|
||||
return [
|
||||
metadata_id
|
||||
for metadata_id in entity_id_to_metadata_id.values()
|
||||
if metadata_id is not None
|
||||
]
|
||||
|
||||
|
||||
class LazyState(State):
|
||||
"""A lazy version of core State after schema 31."""
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user