X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/40d5d40955a88dbd5cd7c25292268f1ab4536bda..d63756d4e3c12c637c34cebe6208e582e67f1924:/services/api/lib/record_filters.rb?ds=sidebyside diff --git a/services/api/lib/record_filters.rb b/services/api/lib/record_filters.rb index 9ff21d5969..dc427c12c1 100644 --- a/services/api/lib/record_filters.rb +++ b/services/api/lib/record_filters.rb @@ -63,11 +63,17 @@ module RecordFilters attrs.each do |attr| subproperty = attr.split(".", 2) - if !model_class.searchable_columns(operator).index subproperty[0] - raise ArgumentError.new("Invalid attribute '#{subproperty[0]}' in filter") - end + col = model_class.columns.select { |c| c.name == subproperty[0] }.first if subproperty.length == 2 + if col.nil? or col.type != :jsonb + raise ArgumentError.new("Invalid attribute '#{subproperty[0]}' for subproperty filter") + end + + if subproperty[1][0] == "<" and subproperty[1][-1] == ">" + subproperty[1] = subproperty[1][1..-2] + end + # jsonb search case operator.downcase when '=', '!=' @@ -102,20 +108,30 @@ module RecordFilters raise ArgumentError.new("Invalid operand type '#{operand.class}' "\ "for '#{operator}' operator in filters") end - when 'exists', 'not exists' - if operand - raise ArgumentError.new("Invalid operand for subproperty existence filter, should be empty or null") - end - if operator.downcase[0..2] == "not" then + when 'exists' + if operand == true + cond_out << "jsonb_exists(#{ar_table_name}.#{subproperty[0]}, ?)" + elsif operand == false cond_out << "(NOT jsonb_exists(#{ar_table_name}.#{subproperty[0]}, ?)) OR #{ar_table_name}.#{subproperty[0]} is NULL" else - cond_out << "jsonb_exists(#{ar_table_name}.#{subproperty[0]}, ?)" + raise ArgumentError.new("Invalid operand '#{operand}' for '#{operator}' must be true or false") end param_out << subproperty[1] else raise ArgumentError.new("Invalid operator for subproperty search '#{operator}'") end + elsif operator.downcase == "exists" + if col.type != :jsonb + raise ArgumentError.new("Invalid attribute '#{subproperty[0]}' for operator '#{operator}' in filter") + end + + cond_out << "jsonb_exists(#{ar_table_name}.#{subproperty[0]}, ?)" + param_out << operand else + if !model_class.searchable_columns(operator).index subproperty[0] + raise ArgumentError.new("Invalid attribute '#{subproperty[0]}' in filter") + end + case operator.downcase when '=', '<', '<=', '>', '>=', '!=', 'like', 'ilike' attr_type = model_class.attribute_column(attr).type