Merge branch '13939-unqualified-contents-orders'
[arvados.git] / services / api / lib / record_filters.rb
index 56e16495eecd2706f4941e92c1e588267758dbb4..dc427c12c1f82cfc76d8b53a13ad1d7b8a88c032 100644 (file)
@@ -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 '=', '!='
@@ -103,16 +109,29 @@ module RecordFilters
                                       "for '#{operator}' operator in filters")
             end
           when 'exists'
-          if operand
+          if operand == true
             cond_out << "jsonb_exists(#{ar_table_name}.#{subproperty[0]}, ?)"
-          else
+          elsif operand == false
             cond_out << "(NOT jsonb_exists(#{ar_table_name}.#{subproperty[0]}, ?)) OR #{ar_table_name}.#{subproperty[0]} is NULL"
+          else
+            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
@@ -185,9 +204,6 @@ module RecordFilters
               end
             end
             cond_out << cond.join(' OR ')
-          when 'exists'
-            cond_out << "jsonb_exists(#{ar_table_name}.#{subproperty[0]}, ?)"
-            param_out << operand
           else
             raise ArgumentError.new("Invalid operator '#{operator}'")
           end