質問

I'm using JSON type in postgreSQL. I am able to solve the could not identify an equality operator for type json problem on my local machine by adding:

          execute <<-SPROC
    -- This creates a function named hashjson that transforms the
    -- json to texts and generates a hash
    CREATE OR REPLACE FUNCTION hashjson(
                                   json
                               ) RETURNS INTEGER LANGUAGE SQL STRICT IMMUTABLE AS $$
    SELECT hashtext($1::text);
    $$;

    -- This creates a function named json_eq that checks equality (as text)
    CREATE OR REPLACE FUNCTION json_eq(
                                   json,
                                   json
                               ) RETURNS BOOLEAN LANGUAGE SQL STRICT IMMUTABLE AS $$
    SELECT bttextcmp($1::text, $2::text) = 0;
    $$;

    -- This creates an operator from the equality function
    CREATE OPERATOR = (
    LEFTARG   = json,
        RIGHTARG  = json,
        PROCEDURE = json_eq
    );

    -- Finaly, this defines a new default JSON operator family with the
    -- operators and functions we just defined.
                                           CREATE OPERATOR CLASS json_ops
    DEFAULT FOR TYPE json USING hash AS
    OPERATOR 1  =,
        FUNCTION 1  hashjson(json);
      SPROC

However, I do not have the superuser privilege in Heroku. How should I solve the problem?


UPDATE

I am using JSON to store a nested hash, the record is like this: Company has column properties. properties can be:

{websites:[{url:1,images:[1,2,3],description:1},{url:2,images:[1,2,3],description:2}], wikipedia:{url:1, description:2},facebook:{id:1}}


UPDATE 2

The error message:

PG::UndefinedFunction: ERROR: could not identify an equality operator for type json LINE 1: SELECT DISTINCT "companies".* FROM "companies" INNER JOIN "reviews...

the error indicator arrow is on SELECT DISTINCT .

the sql is made by the this part in the view: @review.companies

In model:

class Company < ActiveRecord::Base
  store_accessor  :properties, [:websites, :fb, :twitter, :linkedin,:country, :city, :street, :postcode]

In migration:

class AddPropertiesToCompany < ActiveRecord::Migration
  def change
    add_column :companies, :properties, :json
  end
end

Thanks for help again.

役に立ちましたか?

解決

One solution is to use hstore instead of json field type. The problem with this is casting your existing json to hstore.

Another solution is to use GROUP BY, instead of SELECT DISTINCT, in your queries.

But there are some cases where it would be easier to just change the field type to hstore, for example when using active admin.

I had a HABTM association in one of my models, and active admin would try to query:

db_dev=# SELECT DISTINCT "api_v1_test".* FROM "api_v1_test" INNER JOIN "api_v1_test_users" ON "api_v1_test"."id" = "api_v1_test_users"."test_id" WHERE "api_v1_test_users"."user_id" = 200;
ERROR:  could not identify an equality operator for type json
LINE 1: SELECT DISTINCT "api_v1_test".* FROM "api_v1_test" INNER JOI...

Without wanting to spend much time fixing this and figuring out how to rewrite these queries I just converted the field to a hstore and everything is now working as it should.

Also, can you not enter a psql console from heroku to create your functions? or create a new migration for them?

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top