Module: OpenEHR::AQL::PredicateEvaluator

Defined in:
lib/openehr/aql/engine/predicate_evaluator.rb

Overview

Evaluates a WHERE clause's boolean expression tree against a Binding and the query's runtime params. E5 scope: comparisons (reusing PathEvaluator for both sides), AND/OR/NOT and EXISTS. LIKE, MATCHES and functionCall operands are added by later engine milestones.

Constant Summary collapse

COMPARATORS =
{
  '=' => :==, '!=' => :!=, '<' => :<, '<=' => :<=, '>' => :>, '>=' => :>=
}.freeze

Class Method Summary collapse

Class Method Details

.compare(left, operator, right) ⇒ Object



59
60
61
62
# File 'lib/openehr/aql/engine/predicate_evaluator.rb', line 59

def compare(left, operator, right)
  method = COMPARATORS.fetch(operator) { raise ExecutionError, "unknown comparison operator #{operator.inspect}" }
  left.public_send(method, right)
end

.evaluate_comparison(comparison, binding, params) ⇒ Object

A comparison against an absent (nil) value is neither true nor false in AQL/SQL terms - it simply fails to select the row, the same as SQL's NULL-comparison-is-UNKNOWN convention.



38
39
40
41
42
43
44
# File 'lib/openehr/aql/engine/predicate_evaluator.rb', line 38

def evaluate_comparison(comparison, binding, params)
  left = resolve_operand(comparison.left, binding, params)
  right = resolve_operand(comparison.right, binding, params)
  return false if left.nil? || right.nil?

  compare(left, comparison.operator, right)
end

.lookup_param(parameter, params) ⇒ Object



52
53
54
55
56
57
# File 'lib/openehr/aql/engine/predicate_evaluator.rb', line 52

def lookup_param(parameter, params)
  return params[parameter.name.to_sym] if params.key?(parameter.name.to_sym)
  return params[parameter.name] if params.key?(parameter.name)

  raise UnboundParameterError, "unbound parameter: $#{parameter.name}"
end

.matches?(expression, binding, params) ⇒ Boolean

expression is nil when there is no WHERE clause at all.

Returns:

  • (Boolean)


16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/openehr/aql/engine/predicate_evaluator.rb', line 16

def matches?(expression, binding, params)
  case expression
  when nil
    true
  when Model::Comparison
    evaluate_comparison(expression, binding, params)
  when Model::AndExpr
    matches?(expression.left, binding, params) && matches?(expression.right, binding, params)
  when Model::OrExpr
    matches?(expression.left, binding, params) || matches?(expression.right, binding, params)
  when Model::NotExpr
    !matches?(expression.operand, binding, params)
  when Model::ExistsExpr
    !PathEvaluator.evaluate(expression.path, binding).nil?
  else
    raise ExecutionError, "cannot evaluate a #{expression.class} WHERE expression yet"
  end
end

.resolve_operand(node, binding, params) ⇒ Object



46
47
48
49
50
# File 'lib/openehr/aql/engine/predicate_evaluator.rb', line 46

def resolve_operand(node, binding, params)
  return lookup_param(node, params) if node.is_a?(Model::Parameter)

  PathEvaluator.evaluate(node, binding)
end