Source code for system.query_optimization.cardinality_table
#
# This is ExplainDB, educational database systems materials.
#
# Copyright (C) 2026 Prof. Dr. Jens Dittrich, Saarland University
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
#
"""Cardinality table storing and estimating relation and join cardinalities."""
from __future__ import annotations
from system.query_optimization.problems import Problem
[docs]
class CardinalityTable:
"""
A simple cardinality table used to store cardinalities for problems. Normally, cardinalities are obtained by
using system statistics to make an estimation about the sizes of the results.
"""
def __init__(self):
"""Create an empty cardinality table."""
# A mapping from a problem to its cardinality estimation
self.entries: dict[Problem, int] = {}
[docs]
def get_cardinality_estimation(self, problem: Problem) -> int:
"""
Returns the cardinality estimation for the problem.
:param problem: The problem.
:return: The cardinality for the problem.
"""
if problem not in self.entries:
raise ValueError("problem is not in the cardinality table.")
return self.entries[problem]
[docs]
def update_cardinality_estimation(self, problem: Problem, cardinality: int):
"""
Updates the cardinality estimation of the problem to the given cardinality.
:param problem: The problem.
:param cardinality: The cardinality.
"""
self.entries[problem] = cardinality
[docs]
def estimate_join_cardinality(self, left: Problem, right: Problem) -> int:
"""
Returns the join cardinality estimation for the left and right problem.
:param left: The left problem.
:param right: The right problem.
:return: The join cardinality of the left and right problem.
"""
join_problem: Problem = left | right
if join_problem in self.entries:
return self.entries[join_problem]
# Use Cartesian Product for estimation
self.update_cardinality_estimation(
join_problem,
self.get_cardinality_estimation(left)
* self.get_cardinality_estimation(right),
)
return self.entries[join_problem]