ActiveRecord: "uuid-ossp" extension added, but no uuid functions available - postgresql

Using rails-5.0.7.1 (according to bundle show rails)
I wrote a migration which adds the "uuid-ossp" extension, and the SQL gets executed, and the extension shows up when I type \dx in the psql console. However, the functions that this extension provides (such as uuid_generate_v4) do NOT show up when I type \df, and so any attempt to use the functions that should be added fails.
When I take the SQL from the ActiveRecord migration and copy+paste it into the psql console directly, everything works as expected - extension is added, and functions are available.
Here is my migration code:
class EnableUuidOssp < ActiveRecord::Migration[5.0]
def up
enable_extension "uuid-ossp"
end
def down
disable_extension "uuid-ossp"
end
end
Here is the output:
$ bundle exec rake db:migrate
== 20190308113821 EnableUuidOssp: migrating ==============================
-- enable_extension("uuid-ossp")
-> 0.0075s
== 20190308113821 EnableUuidOssp: migrated (0.0076s) =====================
^ this all appears to run successfully, but no functions are enabled. Which means future SQL that includes statements such as ... SET uuid = uuid_generate_v4() ... fail with the this error HINT: No function matches the given name and argument types. You might need to add explicit type casts.
What does work
Going directly into psql and typing:
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
^ This installs the extension and makes the functions avaiable.
And yet, what doesn't work
Okay, so if I take the above SQL and rewrite my migration this way:
...
def up
execute <<~SQL
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
SQL
end
...
^ this migration will run without error, yet it will still not make the functions available.
So, the same copy+paste SQL that works in psql doesn't work via the ActiveRecord execute method, which really puzzles me. I'm not sure what piece I'm missing that's causing this to fail.

I assume that the schema where the extension is installed is not on your search_path.
You can see that schema with
\dx "uuid-ossp"
Try to qualify the functions with the schema, like in public.uuid_generate_v4().

Related

PostGIS: function ST_AsRaster does not exist. Even using examples from the docs

I'm trying to convert geometries to images, and the functions to do so don't seem to exist.
The following example is from the ST_AsRaster Docs WHich specify the requirements are Availability: 2.0.0 - requires GDAL >= 1.6.0.
SELECT ST_AsPNG(ST_AsRaster(ST_Buffer(ST_Point(1,5),10),150, 150));
This results in:
ERROR: function st_asraster(geometry, integer, integer) does not exist
LINE 1: SELECT ST_AsPNG(ST_AsRaster(ST_Buffer(ST_Point(1,5),10),150,...
I found some info that points towards needing GDAL drivers, however, when I try:
SELECT short_name, long_name FROM ST_GdalDrivers();
I get:
ERROR: function st_gdaldrivers() does not exist
LINE 1: SELECT short_name, long_name FROM ST_GdalDrivers();
I have no idea where to even go to try solving this, why don't the functions exist, was there some config I needed to add, some doc I didn't read?
Even the https://postgis.net/docs/RT_reference.html seems to suggest that it should "just work"?
This is installed from the package manager on Ubuntu 20.0.4.
Version Info SELECT PostGIS_Full_Version();:
POSTGIS="3.0.0 r17983" [EXTENSION]
PGSQL="120"
GEOS="3.8.0-CAPI-1.13.1 "
PROJ="6.3.1"
LIBXML="2.9.4"
LIBJSON="0.13.1"
LIBPROTOBUF="1.3.3"
WAGYU="0.4.3 (Internal)"
You must have forgotten to install the postgis_raster extension:
CREATE EXTENSION postgis_raster;
This extension is new in PostGIS 3.0; before that, its objects were part of the postgis extension.
The documentation mentions that:
Once postgis is installed, it needs to be enabled in each individual database you want to use it in.
psql -d yourdatabase -c "CREATE EXTENSION postgis;"
-- if you built with raster support and want to install it --
psql -d yourdatabase -c "CREATE EXTENSION postgis_raster;"

postgresql – No crypt function on Debian stretch

I have PostgreSQL 9.6 installation on my Debian Stretch (9). When I want to use crypt() or gen_salt() functions, it says:
ERROR: function gen_salt(unknown, integer) does not exist
LINE 1: select gen_salt('bf', 8)
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
How can I get these functions working?
Installed postgresql packages
You have to enable it using SQL:
CREATE EXTENSION IF NOT EXISTS pgcrypto;
You have to do it on each database that uses pgcrypto functions.

Trouble installing additional module cube in PostgreSQL 8.4

I am trying to use PostgreSQL with the "Seven Databases in Seven Weeks" book. I am using PostgreSQL 8.4.1 on an Ubuntu 10.04 server.
The first task is to create a database named "book" and check if the contrib packages have been installed properly.
$ createdb book
$ psql book -c "SELECT '1'::cube;"
When I do that I get the following output:
ERROR: type "cube" does not exist
LINE 1: SELECT '1'::cube;
I already installed the cube package with the following command:
$ sudo -u postgres psql postgres < /usr/share/postgresql/8.4/contrib/cube.sql
I tried restarting PostgreSQL but the problem persists. When I tried running the package import a second time I got the following message, which explicitly states that type "cube" already exists:
SET
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
ERROR: type "cube" already exists
COMMENT
CREATE FUNCTION
COMMENT
CREATE FUNCTION
COMMENT
CREATE FUNCTION
COMMENT
CREATE FUNCTION
COMMENT
CREATE FUNCTION
COMMENT
CREATE FUNCTION
COMMENT
CREATE FUNCTION
COMMENT
CREATE FUNCTION
COMMENT
CREATE FUNCTION
COMMENT
CREATE FUNCTION
COMMENT
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
ERROR: operator < already exists
ERROR: operator > already exists
ERROR: operator <= already exists
ERROR: operator >= already exists
ERROR: operator && already exists
ERROR: operator = already exists
ERROR: operator <> already exists
ERROR: operator #> already exists
ERROR: operator <# already exists
ERROR: operator # already exists
ERROR: operator ~ already exists
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
CREATE FUNCTION
ERROR: operator class "cube_ops" for access method "btree" already exists
ERROR: operator class "gist_cube_ops" for access method "gist" already exists
So, what am I doing wrong?
You only installed the extension to your postgres database (the default system database named "postgres") - which is probably not what you want. You need to install the extension to your database - once per database in which to use it.
Or you can install it to a template database (template1 by default, but any database can be used as template) so that every new database created starts out with the functionality pre-installed.
In PostgreSQL 8.4 or older, you need to run in the shell:
psql -d dbname -f SHAREDIR/contrib/cube.sql
Where dbname is the name of your actual target db. Or use the equivalent line that you have in your question.
More info for PostgreSQL 8.4 in the manual here.
Since PostgreSQL 9.1 this has been further simplified and you can just run in a database session:
CREATE extension cube
More in the manual here.
The full command for 9.1 is:
psql -d dbname
CREATE EXTENSION cube;
\q
Where dbname is the name of the database you want to add the extension to.
Note that the last command is a backlash q for quit. And don't forget the semicolon at the end of the second one.

PostgreSQL pgp_sym_encrypt() broken in version 9.1

The following works in PostgreSQL 8.4:
insert into credentials values('demo', pgp_sym_encrypt('password', 'longpassword'));
When I try it in version 9.1 I get this:
ERROR: function pgp_sym_encrypt(unknown, unknown) does not exist LINE
1: insert into credentials values('demo', pgp_sym_encrypt('pass...
^ HINT: No function matches the given name and argument types. You might need to add
explicit type casts.
*** Error ***
ERROR: function pgp_sym_encrypt(unknown, unknown) does not exist SQL
state: 42883 Hint: No function matches the given name and argument
types. You might need to add explicit type casts. Character: 40
If I try some explicit casts like this
insert into credentials values('demo', pgp_sym_encrypt(cast('password' as text), cast('longpassword' as text)))
I get a slightly different error message:
ERROR: function pgp_sym_encrypt(text, text) does not exist
I have pgcrypto installed. Does anyone have pgp_sym_encrypt() working in PostgreSQL 9.1?
On explanation could be that the module was installed into a schema that is not in your search path - or to the wrong database.
Diagnose your problem with this query and report back the output:
SELECT n.nspname, p.proname, pg_catalog.pg_get_function_arguments(p.oid) as params
FROM pg_catalog.pg_proc p
JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace
WHERE p.proname ~~* '%pgp_sym_encrypt%'
AND pg_catalog.pg_function_is_visible(p.oid);
Finds functions in all schemas in your database. Similar to the psql meta-command
\df *pgp_sym_encrypt*
Make sure you install the extension on the desired schema.
sudo -i -u postgres
psql $database
CREATE EXTENSION pgcrypto;
OK, problem solved.
I was creating the pgcrypto extension as the first operation in the script. Then I dropped and added the VGDB database. That's why pgcrypto was there immediately after creating it, but didn't exist when running the sql later in the script or when I opened pgadmin.
This script is meant for setting up new databases and if I had tried it on a new database the create extension would have failed right away.
My bad. Thanks for the help, Erwin.
Just mention de schema where is installed pgcrypto like this:
#ColumnTransformer(forColumn = "TEST",
read = "public.pgp_sym_decrypt(TEST, 'password')",
write = "public.pgp_sym_encrypt(?, 'password')")
#Column(name = "TEST", columnDefinition = "bytea", nullable = false)
private String test;
I ran my (python) script again and the CREATE EXTENSION ran without error. The script also executes this command
psql -d VGDB -U postgres -c "select * from pg_available_extensions order by name"
which includes the following in the result set:
pgcrypto | 1.0 | 1.0 | cryptographic functions
So psql believes that it has installed pgcrypto.
Later in the same script when I execute
psql -d VGDB -U postgres -f sql/Create.Credentials.table.sql
where sql/Create.Credentials.table.sql includes this
insert into credentials values('demo', pgp_sym_encrypt('password', 'longpassword'));
I get this
psql:sql/Create.Credentials.table.sql:31: ERROR: function pgp_sym_encrypt(unknown, unknown) does not exist
LINE 1: insert into credentials values('demo', pgp_sym_encrypt('pass...
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
When I open pgadmin it does not show pgcrypto in either the VGDB or postgres databases even though the query above called by psql shows that pgcrypto is installed.
Could there be an issue with needing to commit after using psql to execute the "create extension ..." command? None of my other DDL or SQL statements require a commit when they get executed with psql.
It's starting to look like psql is just flakey. Is there another way to call "create extension pgcrypto" - e.g. with Python's database support classes - or does that have to be run through psql?

How to generate uuid with PostgreSQL 8.4.4 on Ubuntu 10.04?

I am running PostgreSQL 8.4.4 with Ubuntu 10.04.
I am trying to generate uuid but can't find a way to do it.
I do have the uuid-ossp.sql in /usr/share/postgresql/8.4/contrib/uuid-ossp.sql
When I try this is what I get :
postgres=# SELECT uuid_generate_v1();
ERROR: function uuid_generate_v1() does not exist
LINE 1: SELECT uuid_generate_v1();
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
Any idea ?
The stuff in contrib aren't run automatically. You have to run it yourself to install the functions. I don't know about the 8.4 version, but in the 8.3 version it appears to only install it per-database, so open up the database you're using in psql and issue the command \i /usr/share/postgresql/8.4/contrib/uuid-ossp.sql
I saw this in my PostgreSQL travels. It requires the pgcrypto contrib module.
CREATE OR REPLACE FUNCTION generate_uuid() RETURNS UUID AS
$$
SELECT ENCODE(GEN_RANDOM_BYTES(16), 'hex')::UUID
$$ LANGUAGE SQL IMMUTABLE;