class DDQL::AggOperator

AggOperators return a Hash structure describing the type of aggregation, an optional expression (filter) to apply, an optional factor (field) against which the aggregation is applied, and the entity type for which the aggregation is applicable.

Examples

+SUM {type: IssuerPerson, fields: [SomeFactor], expression: [OtherFactor] == 'Value'}+

  {
    agg: {op_sum: 'SUM'},
    sub_query_expression: "[OtherFactor] == 'Value'",
    sub_query_fields: 'SomeFactor',
    sub_query_type: 'IssuerPerson',
  }

+CNT{type:Issuer, fields: [SomeFactor]} / CNT{type:Issuer, fields: [OtherFactor]}+

  {
    left: {
       agg: {op_cnt: 'CNT'},
       sub_query_fields: 'SomeFactor',
       sub_query_type: 'Issuer',
    },
    op: {op_divide: '/'},
    right: {
       agg: {op_cnt: 'CNT'},
       sub_query_fields: 'OtherFactor',
       sub_query_type: 'Issuer',
    },
  }

+MAX{type:Case, fields: [SomeFactor]} > 5+

  {
    left: {
       agg: {op_max: 'MAX'},
       sub_query_fields: 'SomeFactor',
       sub_query_type: 'Case',
    },
    op: {op_gt: '>'},
    right: {int: 5},
  }

+ALIAS{type:Issuer, expression: [SomeFactor] > 5} AS [ThatFactor:That Factor]+

  {
     agg: {op_max: 'ALIAS'},
     sub_query_type: 'Issuer',
     sub_query_expression: '[SomeFactor] > 5',
     sub_query_alias: {factor: 'ThatFactor', desc: 'That Factor'},
  }

Public Class Methods

new(symbol, name, return_type:, type: :prefix, precedence: 8, right: false) click to toggle source
Calls superclass method
# File lib/ddql/agg_operator.rb, line 57
def initialize(symbol, name, return_type:, type: :prefix, precedence: 8, right: false)
  super(symbol, name, type, precedence, right, return_type)
end

Public Instance Methods

as_agg(expr) click to toggle source
# File lib/ddql/agg_operator.rb, line 104
def as_agg(expr)
  expression = expr.dup
  if expression.key?(:yes_no_op)
    # AGG Y/N
    yes_no_op = expression.delete(:yes_no_op)
    {
      left: expression,
      yes_no_op: yes_no_op,
    }
  elsif expression.key?(:op)
    # AGG COMP LIT
    expression.delete(:left)
    op = expression.delete(:op)
    right = expression.delete(:right)
    {
      left: expression,
      op: op,
      right: right,
    }
  elsif expression.key?(:boolean_operator)
    # AGG BOOL STMT
    bool_op = expression.delete(:boolean_operator)
    rstatement = expression.delete(:rstatement)
    {
      lstatement: as_left_op_right(expression),
      boolean_operator: bool_op,
      rstatement: rstatement,
    }
  else
    expression
  end
end
as_left_op_right(expression) click to toggle source
# File lib/ddql/agg_operator.rb, line 76
def as_left_op_right(expression)
  new_expression = {
    agg: expression.delete(:agg),
    sub_query_type: expression.delete(:sub_query_type),
    sub_query_fields: expression.delete(:sub_query_fields),
    sub_query_expression: expression.delete(:sub_query_expression),
  }.compact

  if expression[:lstatement].key?(:op) && expression[:lstatement][:left].blank?
    {
      left: new_expression,
      op: expression[:lstatement][:op],
      right: expression[:lstatement][:right],
    }
  elsif expression[:lstatement].key?(:lstatement)
    if expression[:lstatement][:lstatement].empty?
      expression[:lstatement][:lstatement] = new_expression
      expression[:lstatement]
    else
      final_expression = expression[:lstatement]
      final_expression[:lstatement][:left] = new_expression
      final_expression
    end
  else
    new_expression
  end
end
parse(parser, token, expression: nil) click to toggle source
# File lib/ddql/agg_operator.rb, line 61
def parse(parser, token, expression: nil)
  new_expression = parser.parse(precedence: precedence)
  if expression
    expression = expression.merge(new_expression)
  else
    expression = new_expression
  end

  expression.merge!(agg: {:"op_#{symbol.downcase}" => symbol})
  if parser.peek&.supports_post_processing?
    token, expression = parser.peek.post_process(parser: parser, expression: expression)
  end
  as_agg(expression)
end