Ransack: PG::UndefinedFunction: ERROR: could not identify an equality operator for type json

Created on 20 Oct 2014  路  11Comments  路  Source: activerecord-hackery/ransack

When trying to use ransack on a table that has a postgresql json column it causes the following error:

PG::UndefinedFunction: ERROR: could not identify an equality operator for type json

Only occurs when passing distinct: true to #result

Most helpful comment

Ran into this error before, when calling uniq on a model that had a json field in postgres 9.3. If you are able to upgrade, switching the column to type jsonb and updating to >= postgres 9.4 will fix this.

All 11 comments

Thanks @jspillers for the bug report, could you please provide the information mentioned in the Contributing Guide?

Hi guys getting same here,

Using gem 'ransack', github: 'activerecord-hackery/ransack', branch: 'rails-4.1' version.

For now I'm getting repeated results...

Started GET "/manage/customers.json?q[first_name_or_last_name_or_phone_lines_phone_number_cont_any]=mic" for 127.0.0.1 at 2014-10-30 10:23:22 -0500
Processing by Manage::CustomersController#index as JSON
  Parameters: {"q"=>{"first_name_or_last_name_or_phone_lines_phone_number_cont_any"=>"mic"}}
  User Load (0.9ms)  SELECT  "users".* FROM "users"  WHERE "users"."id" = 1  ORDER BY "users"."id" ASC LIMIT 1
  Customer Load (1.8ms)  SELECT DISTINCT "customers".* FROM "customers" LEFT OUTER JOIN "phone_lines" ON "phone_lines"."phoneable_id" = "customers"."id" AND "phone_lines"."phoneable_type" = 'Customer' WHERE (((("customers"."first_name" ILIKE '%mic%') OR ("customers"."last_name" ILIKE '%mic%')) OR ("phone_lines"."phone_number" ILIKE '%mic%')))
PG::UndefinedFunction: ERROR:  could not identify an equality operator for type json
LINE 1: SELECT DISTINCT "customers".* FROM "customers" LEFT OUTER JO...
                        ^
: SELECT DISTINCT "customers".* FROM "customers" LEFT OUTER JOIN "phone_lines" ON "phone_lines"."phoneable_id" = "customers"."id" AND "phone_lines"."phoneable_type" = 'Customer' WHERE (((("customers"."first_name" ILIKE '%mic%') OR ("customers"."last_name" ILIKE '%mic%')) OR ("phone_lines"."phone_number" ILIKE '%mic%')))
Completed 500 Internal Server Error in 8ms

PG::UndefinedFunction - ERROR:  could not identify an equality operator for type json
LINE 1: SELECT DISTINCT "customers".* FROM "customers" LEFT OUTER JO...
                        ^
:
  activerecord (4.1.0) lib/active_record/connection_adapters/postgresql_adapter.rb:815:in `block in exec_no_cache'
  activerecord (4.1.0) lib/active_record/connection_adapters/abstract_adapter.rb:373:in `block in log'
  activesupport (4.1.0) lib/active_support/notifications/instrumenter.rb:20:in `instrument'
  activerecord (4.1.0) lib/active_record/connection_adapters/abstract_adapter.rb:367:in `log'
  activerecord (4.1.0) lib/active_record/connection_adapters/postgresql_adapter.rb:815:in `exec_no_cache'
  activerecord (4.1.0) lib/active_record/connection_adapters/postgresql/database_statements.rb:137:in `exec_query'
  activerecord (4.1.0) lib/active_record/connection_adapters/postgresql_adapter.rb:947:in `select'
  activerecord (4.1.0) lib/active_record/connection_adapters/abstract/database_statements.rb:31:in `select_all'
  activerecord (4.1.0) lib/active_record/connection_adapters/abstract/query_cache.rb:67:in `block in select_all'
  activerecord (4.1.0) lib/active_record/connection_adapters/abstract/query_cache.rb:82:in `cache_sql'
  activerecord (4.1.0) lib/active_record/connection_adapters/abstract/query_cache.rb:67:in `select_all'
  activerecord (4.1.0) lib/active_record/querying.rb:39:in `find_by_sql'
  activerecord (4.1.0) lib/active_record/relation.rb:603:in `exec_queries'
  activerecord (4.1.0) lib/active_record/relation.rb:487:in `load'
  activerecord (4.1.0) lib/active_record/relation.rb:231:in `to_a'
  activerecord (4.1.0) lib/active_record/relation.rb:236:in `as_json'
  activesupport (4.1.0) lib/active_support/core_ext/object/json.rb:159:in `block in as_json'
  activesupport (4.1.0) lib/active_support/core_ext/object/json.rb:159:in `as_json'
  activesupport (4.1.0) lib/active_support/json/encoding.rb:34:in `encode'
  activesupport (4.1.0) lib/active_support/json/encoding.rb:21:in `encode'
  activesupport (4.1.0) lib/active_support/core_ext/object/json.rb:37:in `to_json_with_active_support_encoder'
  actionpack (4.1.0) lib/action_controller/metal/renderers.rb:96:in `block in <module:Renderers>'
  active_model_serializers (0.9.0) lib/action_controller/serialization.rb:54:in `_render_option_json'
  actionpack (4.1.0) lib/action_controller/metal/renderers.rb:39:in `block in _handle_render_options'
  /home/marman/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/set.rb:263:in `each'
  actionpack (4.1.0) lib/action_controller/metal/renderers.rb:36:in `_handle_render_options'
  actionpack (4.1.0) lib/action_controller/metal/renderers.rb:32:in `render_to_body'
  actionpack (4.1.0) lib/abstract_controller/rendering.rb:25:in `render'
  actionpack (4.1.0) lib/action_controller/metal/rendering.rb:16:in `render'
  actionpack (4.1.0) lib/action_controller/metal/instrumentation.rb:41:in `block (2 levels) in render'
  activesupport (4.1.0) lib/active_support/core_ext/benchmark.rb:12:in `block in ms'
  /home/marman/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/benchmark.rb:294:in `realtime'
  activesupport (4.1.0) lib/active_support/core_ext/benchmark.rb:12:in `ms'
  actionpack (4.1.0) lib/action_controller/metal/instrumentation.rb:41:in `block in render'
  actionpack (4.1.0) lib/action_controller/metal/instrumentation.rb:84:in `cleanup_view_runtime'
  activerecord (4.1.0) lib/active_record/railties/controller_runtime.rb:25:in `cleanup_view_runtime'
  actionpack (4.1.0) lib/action_controller/metal/instrumentation.rb:40:in `render'
  app/controllers/manage/customers_controller.rb:8:in `block (2 levels) in index'
  actionpack (4.1.0) lib/action_controller/metal/mime_responds.rb:258:in `respond_to'
  app/controllers/manage/customers_controller.rb:6:in `index'
  actionpack (4.1.0) lib/action_controller/metal/implicit_render.rb:4:in `send_action'
  actionpack (4.1.0) lib/abstract_controller/base.rb:189:in `process_action'
  actionpack (4.1.0) lib/action_controller/metal/rendering.rb:10:in `process_action'
  actionpack (4.1.0) lib/abstract_controller/callbacks.rb:20:in `block in process_action'
  activesupport (4.1.0) lib/active_support/callbacks.rb:113:in `call'
  activesupport (4.1.0) lib/active_support/callbacks.rb:149:in `block in halting_and_conditional'
  activesupport (4.1.0) lib/active_support/callbacks.rb:166:in `block in halting'
  activesupport (4.1.0) lib/active_support/callbacks.rb:166:in `block in halting'
  activesupport (4.1.0) lib/active_support/callbacks.rb:229:in `block in halting'
  activesupport (4.1.0) lib/active_support/callbacks.rb:229:in `block in halting'
  activesupport (4.1.0) lib/active_support/callbacks.rb:166:in `block in halting'
  activesupport (4.1.0) lib/active_support/callbacks.rb:166:in `block in halting'
  activesupport (4.1.0) lib/active_support/callbacks.rb:166:in `block in halting'
  activesupport (4.1.0) lib/active_support/callbacks.rb:86:in `run_callbacks'
  actionpack (4.1.0) lib/abstract_controller/callbacks.rb:19:in `process_action'
  actionpack (4.1.0) lib/action_controller/metal/rescue.rb:29:in `process_action'
  actionpack (4.1.0) lib/action_controller/metal/instrumentation.rb:31:in `block in process_action'
  activesupport (4.1.0) lib/active_support/notifications.rb:159:in `block in instrument'
  activesupport (4.1.0) lib/active_support/notifications/instrumenter.rb:20:in `instrument'
  activesupport (4.1.0) lib/active_support/notifications.rb:159:in `instrument'
  actionpack (4.1.0) lib/action_controller/metal/instrumentation.rb:30:in `process_action'
  actionpack (4.1.0) lib/action_controller/metal/params_wrapper.rb:250:in `process_action'
  activerecord (4.1.0) lib/active_record/railties/controller_runtime.rb:18:in `process_action'
  actionpack (4.1.0) lib/abstract_controller/base.rb:136:in `process'
  actionview (4.1.0) lib/action_view/rendering.rb:30:in `process'
  actionpack (4.1.0) lib/action_controller/metal.rb:195:in `dispatch'
  actionpack (4.1.0) lib/action_controller/metal/rack_delegation.rb:13:in `dispatch'
  actionpack (4.1.0) lib/action_controller/metal.rb:231:in `block in action'
  actionpack (4.1.0) lib/action_dispatch/routing/route_set.rb:80:in `dispatch'
  actionpack (4.1.0) lib/action_dispatch/routing/route_set.rb:48:in `call'
  actionpack (4.1.0) lib/action_dispatch/journey/router.rb:71:in `block in call'
  actionpack (4.1.0) lib/action_dispatch/journey/router.rb:59:in `call'
  actionpack (4.1.0) lib/action_dispatch/routing/route_set.rb:676:in `call'
  dragonfly (1.0.7) lib/dragonfly/middleware.rb:14:in `call'
  warden (1.2.3) lib/warden/manager.rb:35:in `block in call'
  warden (1.2.3) lib/warden/manager.rb:34:in `call'
  rack (1.5.2) lib/rack/etag.rb:23:in `call'
  rack (1.5.2) lib/rack/conditionalget.rb:25:in `call'
  rack (1.5.2) lib/rack/head.rb:11:in `call'
  actionpack (4.1.0) lib/action_dispatch/middleware/params_parser.rb:27:in `call'
  actionpack (4.1.0) lib/action_dispatch/middleware/flash.rb:254:in `call'
  rack (1.5.2) lib/rack/session/abstract/id.rb:225:in `context'
  rack (1.5.2) lib/rack/session/abstract/id.rb:220:in `call'
  actionpack (4.1.0) lib/action_dispatch/middleware/cookies.rb:560:in `call'
  activerecord (4.1.0) lib/active_record/query_cache.rb:36:in `call'
  activerecord (4.1.0) lib/active_record/connection_adapters/abstract/connection_pool.rb:621:in `call'
  activerecord (4.1.0) lib/active_record/migration.rb:380:in `call'
  actionpack (4.1.0) lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'
  activesupport (4.1.0) lib/active_support/callbacks.rb:82:in `run_callbacks'
  actionpack (4.1.0) lib/action_dispatch/middleware/callbacks.rb:27:in `call'
  actionpack (4.1.0) lib/action_dispatch/middleware/reloader.rb:73:in `call'
  actionpack (4.1.0) lib/action_dispatch/middleware/remote_ip.rb:76:in `call'
  better_errors (2.0.0) lib/better_errors/middleware.rb:84:in `protected_app_call'
  better_errors (2.0.0) lib/better_errors/middleware.rb:79:in `better_errors_call'
  better_errors (2.0.0) lib/better_errors/middleware.rb:57:in `call'
  actionpack (4.1.0) lib/action_dispatch/middleware/debug_exceptions.rb:17:in `call'
  actionpack (4.1.0) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
  railties (4.1.0) lib/rails/rack/logger.rb:38:in `call_app'
  railties (4.1.0) lib/rails/rack/logger.rb:20:in `block in call'
  activesupport (4.1.0) lib/active_support/tagged_logging.rb:68:in `block in tagged'
  activesupport (4.1.0) lib/active_support/tagged_logging.rb:26:in `tagged'
  activesupport (4.1.0) lib/active_support/tagged_logging.rb:68:in `tagged'
  railties (4.1.0) lib/rails/rack/logger.rb:20:in `call'
  actionpack (4.1.0) lib/action_dispatch/middleware/request_id.rb:21:in `call'
  rack (1.5.2) lib/rack/methodoverride.rb:21:in `call'
  rack (1.5.2) lib/rack/runtime.rb:17:in `call'
  activesupport (4.1.0) lib/active_support/cache/strategy/local_cache_middleware.rb:26:in `call'
  dragonfly (1.0.7) lib/dragonfly/cookie_monster.rb:9:in `call'
  rack (1.5.2) lib/rack/lock.rb:17:in `call'
  actionpack (4.1.0) lib/action_dispatch/middleware/static.rb:64:in `call'
  rack (1.5.2) lib/rack/sendfile.rb:112:in `call'
  railties (4.1.0) lib/rails/engine.rb:514:in `call'
  railties (4.1.0) lib/rails/application.rb:144:in `call'
  rack (1.5.2) lib/rack/lock.rb:17:in `call'
  rack (1.5.2) lib/rack/content_length.rb:14:in `call'
  rack (1.5.2) lib/rack/handler/webrick.rb:60:in `service'
  /home/marman/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/webrick/httpserver.rb:138:in `service'
  /home/marman/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/webrick/httpserver.rb:94:in `run'
  /home/marman/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/webrick/server.rb:295:in `block in start_thread'

Hi @marlonmantilla, we no longer actively maintain the 4.1 branch (it's up to the community to do so if they wish). It may not solve the problem, but did you try with Ransack master? Thanks.

Seeing this on master as well

This is probably the same issue outlined here: https://github.com/mbleigh/acts-as-taggable-on/pull/496

Ran into this error before, when calling uniq on a model that had a json field in postgres 9.3. If you are able to upgrade, switching the column to type jsonb and updating to >= postgres 9.4 will fix this.

I can confirm that upgrading to Postgres 9.4 and using JSONB fixes this.

select '{}'::json = '{}'::json;
ERROR:  operator does not exist: json = json

select '{}'::jsonb = '{}'::jsonb;
 ?column? 
----------
 t
(1 row)

I suggest we add to the README that jsonb in Postgres 9.4+ should be used for json-type fields in Ransack operations.

@seanfcarroll You should note that you'll have to use a JSONB column in PG 9.4+ (or note that in general JSON columns will not work). The non-JSONB JSON types have no equality operator, hence the original error (DISTINCT with no arguments compares every column of each record, including those with no equality operator).

For what it's worth, SQL DISTINCT is a bit of a code smell. It can mean the queries are not well written and that they are needlessly loading duplicates.

Closed due to inactivity

Was this page helpful?
0 / 5 - 0 ratings

Related issues

AnnaErshova picture AnnaErshova  路  3Comments

grillorafael picture grillorafael  路  5Comments

ivanovaleksey picture ivanovaleksey  路  3Comments

JFimex picture JFimex  路  3Comments

MatsumotoHiroko picture MatsumotoHiroko  路  4Comments