activerecord-postgres-earthdistance: ERROR: type "earth" does not exist at character 136

Everything seems to wok fine, but checking our rails app’s logs we keep seeing this:

[DATABASE] [4-1] ERROR:  type "earth" does not exist at character 136 
[DATABASE] [4-2] QUERY:  SELECT cube(cube(cube(earth()*cos(radians($1))*cos(radians($2))),earth()*cos(radians($1))*sin(radians($2))),earth()*sin(radians($1)))::earth 
[DATABASE] [4-3] CONTEXT:  SQL function "ll_to_earth" during inlining 
[DATABASE] [4-4] 	automatic analyze of table "d2la77ueqce997.public.addresses" 

We use postgresql 9.6.1

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 17 (2 by maintainers)

Most upvoted comments

I ended up coming to this thread with no clear answer, and finally found the solution deep in between the discussion. Posting here for everyone who gets stuck. The solution is to redefine ll_to_earth method from postgres console like this:

CREATE OR REPLACE FUNCTION ll_to_earth(
    double precision,
    double precision)
  RETURNS earth AS
'SELECT public.cube(public.cube(public.cube(public.earth()*cos(radians($1))*cos(radians($2))),public.earth()*cos(radians($1))*sin(radians($2))),public.earth()*sin(radians($1)))::public.earth'
  LANGUAGE sql IMMUTABLE STRICT
  COST 100;

I found this issue while looking for a solution to the general problem (i.e. not specific to this software).

The quoted solution is what needs to be done, but it wasn’t clear to me what changed (since the original/unmodified function is not provided).

So, for those who happen upon this ticket in the same manner as I did, and are looking for a general solution: What you need to do is to explicitly prefix anything declared in the database with public., so that it does not depend on the search path. E.g. earth()public.earth(). This also holds for types. The RETURNS $type return-type specification does not have to be prefixed.

(apologies for hijacking the ticket for this; I hope you won’t mind, as it seems to be one of the top results in Google, so it might help many others!)

I ended up coming to this thread with no clear answer, and finally found the solution deep in between the discussion. Posting here for everyone who gets stuck. The solution is to redefine ll_to_earth method from postgres console like this:

CREATE OR REPLACE FUNCTION ll_to_earth(
    double precision,
    double precision)
  RETURNS earth AS
'SELECT public.cube(public.cube(public.cube(public.earth()*cos(radians($1))*cos(radians($2))),public.earth()*cos(radians($1))*sin(radians($2))),public.earth()*sin(radians($1)))::public.earth'
  LANGUAGE sql IMMUTABLE STRICT
  COST 100;

Just do that to fix the search path of function ll_to_earth

ALTER FUNCTION ll_to_earth SET search_path = public;