Skip to content

Commit a0ad741

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 4f67238 commit a0ad741

File tree

1 file changed

+37
-31
lines changed

1 file changed

+37
-31
lines changed

lib/miq_expression.rb

Lines changed: 37 additions & 31 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,31 +332,40 @@ 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-
# op => {"regkey"=>"foo", "regval"=>"bar", "value"=>"baz"}
347-
# op => {"field" => "foo", "value" => "baz"}
348-
# op => {"field" => "<count>, "value" => "0"}
349-
# op => {"count" => "Vm.snapshots", "value"=>"1"}
350-
# op => {"tag"=>"Host.managed-environment", "value"=>"prod"}
351-
operator_values = operator_values.dup
352-
field = operator_values["field"]
353-
field_field = operator_values["field-field"] = Field.parse(field) if field
354-
value = operator_values["value"]
355-
operator_values["value-field"] = Field.parse(value) if value
356-
357-
# attempt to do conversion only if db type of column is integer and value to compare to is String
358-
if %w[= != <= >= > <].include?(operator) && field_field&.integer? && value.instance_of?(String)
359-
operator_values["value"] = convert_size_in_units_to_integer(field, field_field.sub_type, value)
360-
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 # field
350+
# op => {"regkey"=>"foo", "regval"=>"bar", "value"=>"baz"}
351+
# op => {"field" => "foo", "value" => "baz"}
352+
# op => {"field" => "<count>, "value" => "0"}
353+
# op => {"count" => "Vm.snapshots", "value"=>"1"}
354+
# op => {"tag"=>"Host.managed-environment", "value"=>"prod"}
355+
operator_values = operator_values.dup
356+
field = operator_values["field"]
357+
field_field = operator_values["field-field"] = Field.parse(field) if field
358+
value = operator_values["value"]
359+
operator_values["value-field"] = Field.parse(value) if value
360+
361+
# attempt to do conversion only if db type of column is integer and value to compare to is String
362+
if %w[= != <= >= > <].include?(operator) && field_field&.integer? && value.instance_of?(String)
363+
operator_values["value"] = convert_size_in_units_to_integer(field, field_field.sub_type, value)
364+
end
365+
366+
operator_values
367+
end
361368
end
362-
{operator => operator_values}
363369
end
364370

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

0 commit comments

Comments
 (0)