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 selectpull/89941/head^2
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…
Reference in New Issue