Skip to content

Commit 361e823

Browse files
committed
MiqExpression#preprocess_exp for more cases
still work even if :token is the first key in the exp still process find sub targets this gets us more values with field-field
1 parent 196abcf commit 361e823

File tree

1 file changed

+39
-30
lines changed

1 file changed

+39
-30
lines changed

lib/miq_expression.rb

Lines changed: 39 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -303,19 +303,16 @@ def self._to_ruby(exp, context_type, tz)
303303
clause, = operands2rubyvalue(operator, op_args, context_type)
304304
when "is"
305305
col_ruby, _value = operands2rubyvalue(operator, {"field" => col_name}, context_type)
306-
col_type = Target.parse(col_name).column_type
307306
value = op_args["value"]
308-
clause = if col_type == :date && !RelativeDatetime.relative?(value)
309-
ruby_for_date_compare(col_ruby, col_type, tz, "==", value)
307+
clause = if field.date? && !RelativeDatetime.relative?(value)
308+
ruby_for_date_compare(col_ruby, field.column_type, tz, "==", value)
310309
else
311-
ruby_for_date_compare(col_ruby, col_type, tz, ">=", value, "<=", value)
310+
ruby_for_date_compare(col_ruby, field.column_type, tz, ">=", value, "<=", value)
312311
end
313312
when "from"
314313
col_ruby, _value = operands2rubyvalue(operator, {"field" => col_name}, context_type)
315-
col_type = Target.parse(col_name).column_type
316-
317314
start_val, end_val = op_args["value"]
318-
clause = ruby_for_date_compare(col_ruby, col_type, tz, ">=", start_val, "<=", end_val)
315+
clause = ruby_for_date_compare(col_ruby, field.column_type, tz, ">=", start_val, "<=", end_val)
319316
else
320317
raise _("operator '%{operator_name}' is not supported") % {:operator_name => operator.upcase}
321318
end
@@ -335,30 +332,42 @@ def to_sql(tz = nil)
335332
end
336333

337334
def preprocess_exp(exp)
338-
operator = exp.keys.first
339-
operator_values = exp[operator]
340-
case operator.downcase
341-
when "and", "or"
342-
operator_values = operator_values.map { |atom| preprocess_exp(atom) }
343-
when "not", "!"
344-
operator_values = preprocess_exp(operator_values)
345-
else # field
346-
# {"regkey"=>"foo", "regval"=>"bar", "value"=>"baz"}
347-
# {"field" => "foo", "value" => "baz"}
348-
# {"count" => "Vm.snapshots", "value"=>"1"}
349-
# {"tag"=>"Host.managed-environment", "value"=>"prod"}
350-
operator_values = operator_values.dup
351-
field = operator_values["field"]
352-
field_field = operator_values["field-field"] = Field.parse(field) if field
353-
value = operator_values["value"]
354-
operator_values["value-field"] = Field.parse(value) if value
355-
356-
# attempt to do conversion only if db type of column is integer and value to compare to is String
357-
if %w[= != <= >= > <].include?(operator) && field_field&.integer? && value.class == String
358-
operator_values["value"] = convert_size_in_units_to_integer(field, field_field.sub_type, value)
359-
end
335+
exp.each_with_object({}) do |(operator, operator_values), new_exp|
336+
next if operator == :token
337+
338+
new_exp[operator] =
339+
case operator.downcase
340+
when "and", "or"
341+
# "and" => [exp, exp, exp]
342+
operator_values.map { |atom| preprocess_exp(atom) }
343+
when "not", "!"
344+
# "not" => exp
345+
preprocess_exp(operator_values)
346+
when "find"
347+
# "find" => {"search" => exp, "checkall" => exp}
348+
operator_values.each_with_object({}) { |(op2, op_values2), hash| hash[op2] = preprocess_exp(op_values2) }
349+
else
350+
# op => {"regkey"=>"foo", "regval"=>"bar", "value"=>"baz"}
351+
# op => {"field" => "foo", "value" => "baz"}
352+
# op => {"count" => "Vm.snapshots", "value"=>"1"}
353+
# op => {"tag"=>"Host.managed-environment", "value"=>"prod"}
354+
operator_values = operator_values.dup
355+
field = operator_values["field"]
356+
if field
357+
field_field = operator_values["field-field"] = Field.parse(field)
358+
end
359+
value = operator_values["value"]
360+
if value
361+
value_field = operator_values["value-field"] = Field.parse(value)
362+
end
363+
364+
# attempt to do conversion only if db type of column is integer and value to compare to is String
365+
if %w[= != <= >= > <].include?(operator) && field_field&.integer? && value.class == String
366+
operator_values["value"] = convert_size_in_units_to_integer(field, field_field.sub_type, value)
367+
end
368+
operator_values
369+
end
360370
end
361-
{operator => operator_values}
362371
end
363372

364373
# @param operator [String] operator (i.e.: AND, OR, NOT)

0 commit comments

Comments
 (0)