Source code for pg4n.inconsistent_expression_checker

from typing import Optional

import sqlglot.expressions as exp

from .errfmt import ErrorFormatter
from .qepparser import QEPAnalysis, QEPNode


[docs]class InconsistentExpressionChecker: """ Inconsistent expression is some expression that is never true. For example: x = 10 AND x = 20 This checker only finds a small subset of such expression, where postgresql itself detects the inconsistent expression in its query optimizer and exposes that information via its query execution plan. """ # TODO: Analyze the where expressions of the sql and find more inconsistent # expressions. # - One approach is to transform the expressions with its symbols from # sqlparser representation into a formula and finding whether it is # satisfiable with pysmt. # - This approach could also be used to find tautologies. # - Some preliminary work of this is in the experimental branch # feat/experimental-smt def __init__(self, parsed_sql: exp.Expression, qep_analysis: QEPAnalysis): self.parsed_sql: exp.Expression = parsed_sql self.qep_analysis: QEPAnalysis = qep_analysis
[docs] def check(self) -> Optional[str]: """ Returns warning msg if the sql contains inconsistent expression, otherwise None. """ if self.qep_analysis is None: return None def finder(node: QEPNode) -> bool: return node.get("One-Time Filter") is not None has_onetime_filter = len(self.qep_analysis.root.rfind(finder)) > 0 has_inconsistent_expression = has_onetime_filter if not has_inconsistent_expression: return None warning_name = type(self).__name__.rstrip("Checker") warning = "Some condition is always false" formatter = ErrorFormatter(warning, warning_name) warning_msg = formatter.format() return warning_msg