"create or replace trigger" not available on AWS RDS/Postgres - postgresql

I have the following:
CREATE OR REPLACE TRIGGER trigger_commands
AFTER INSERT ON commands
FOR EACH ROW EXECUTE PROCEDURE on_commands_change();
it works on a local Postgres instance, but fails on AWS with:
[42601] ERROR: syntax error at or near "TRIGGER"
however, if I remove the 'OR REPLACE' part:
CREATE TRIGGER trigger_commands
AFTER INSERT ON commands
FOR EACH ROW EXECUTE PROCEDURE on_commands_change();
then RDS accepts it. Why is that? and what would be the best way to update the trigger at every code restart?

It's most likely a Postgresql version mismatch, CREATE OR REPLACE TRIGGER works only on Postgresql 14 (see documentation, 14 and 13).
I'd suggest to use DROP TRIGGER IF EXISTS then CREATE TRIGGER for backwards compatibility.

Related

Can't add column in pgAdmin4 and PostgreSQL 9.5.25

I'm working with pgAdmin4 and PostgreSQL 9.5.25 on Ubuntu 16.04 (I know it's outdated but I really need to work on it currently).
I can add a new table to my database, however, when I try to add a new column using GUI (Table --> Properties) to an existing table I get this error message:
ERROR pgadmin: Failed to execute query (execute_scalar) for the server #1 - DB:api_dev2 (Query-id: 1319646):
Error Message:ERROR: syntax error at or near "NOT"
LINE 2: ADD COLUMN IF NOT EXISTS is_for_sale boolean DEFAULT Fal...
^
The corresponding SQL query is this
ALTER TABLE IF EXISTS public."Products"
ADD COLUMN IF NOT EXISTS is_for_sale boolean DEFAULT False;
I know that "IF NOT EXISTS" is the source of the problem. When I simply run this query:
ALTER TABLE IF EXISTS public."Products"
ADD COLUMN is_for_sale boolean DEFAULT False;
it works. But why is this "IF NOT EXISTS" is added by pgAdmin4?
ADD COLUMN IF NOT EXISTS is only available in Postgres 9.6 and up. See the documentation for Postgres 9.5.
To address your edit, the version of PostgreSQL you are using is no longer supported - all supported versions support the ADD COLUMN IF NOT EXISTS syntax which is probably why pgadmin assumes it is fine to use it. You could try to use an older version of pgadmin.

PostgreSQL Syntax error at or near FUNCTION on create trigger

I installed postgresql and postgresql-plpython-10 (using apt) on a new machine running Ubuntu server 18.04
and I have reinstated a Postgresql database (extracted using pg_dumpall) from another machine onto a new machine (Linux).
I checked that the trackspreadsheetnztplpy function exists in the database and the table nztgsheet exists. I reran the function on the old machine and it worked perfectly. I checked plpythonu is installed on the new machine using psql command: \dL.
SQL error:
ERROR: syntax error at or near "FUNCTION"
LINE 1: ...H ROW WHEN (OLD.* IS DISTINCT FROM NEW.*) EXECUTE FUNCTION t...
^
In statement:
CREATE TRIGGER trackspreadsheetnzt AFTER UPDATE ON nztgsheet FOR EACH ROW WHEN (OLD.* IS DISTINCT FROM NEW.*) EXECUTE FUNCTION trackspreadsheetnztplpy();
I expected the trigger function to work, but it throws a syntax error instead.
The EXECUTE FUNCTION syntax for CREATE TRIGGER statements was introduced in Postgres 11.
In Postgres 10, you need to say EXECUTE PROCEDURE instead.
This syntax was deprecated in Postgres 11 with the introduction of procedures, which are distinct from functions and cannot be used to implement a trigger.
If you are trying to add trigger function from pgadmin UI,
In the code tab you need to specify function from BEGIN to END, as postgres implicitly specifies in the code " CREATE OR REPLACE FUNCTION ****()
RETURNS TRIGGER
AS
$$"

PostGIS installed, but unable to select version or add geography columns

I've got an existing Postgres 9.6 database on Google Cloud that has the PostGIS extension enabled, however whenever I try to create a table with a column with the geography type or select the PostGIS version I get an error.
For creating the geography column the error is non-descriptive — just an arrow pointing to the word geography in the following statement
create table place(coordinate geography(POINT,4326));
The version error looks as follows:
select postgis_full_version();
ERROR: could not access file "$libdir/postgis-2.3": No such file or directory
CONTEXT: SQL statement "SELECT postgis_lib_version()"
PL/pgSQL function postgis_full_version() line 22 at SQL statement
The create extension statement confirms it is already installed though e.g
create extension postgis;
error: the extension already exists
I've tried running these commands as the postgres user and as another user who's been granted permissions on the database in question but neither seem to work. Any help would be appreciated.
It's simpler than you think:
Your hosting privider has goofed up the PostGIS installation.
It looks like the file is really missing, or something else on the operating system level is misconfigured.
You should gripe at Google.

pgAdmin 4 does not create functions with geometry

I started recently using pgAdmin 4 after having used pgAdmin 3 for a long time.
The problem I have now is that I cannot replace existing functions that reference geometry objects. I am on Windows 10, and the current version of pgAdmin 4 is 2.1.
The PL/pgSQL function already exists in the database and it was created with flyway, psql or pgAdmin 3, and it works.
The PostGIS extension is enabled.
Now I go in pgAdmin 4 and use the same login as ever, choose "Scripts"->"Create script" for the function, and then click F5 - "run Script" to create it.
What I get is an error:
ERROR: type "geometry" does not exist
LINE 22: v_location geometry;
The same operation in pgAdmin 3 gives no error.
The function has the search_path set correctly and can be created in pgAdmin3 and psql.
Actually I can create a dummy function in the query tool in pgadmin4 and compile it. See below:
set search_path=res_cc_01,public;
create or replace function test() returns text
LANGUAGE plpgsql VOLATILE SECURITY DEFINER
COST 100
set search_path=res_cc_01,public
AS
$BODY$
DECLARE
v_g geometry := ST_GeometryFromText('POINT(142.279859 -9.561480)',4326);
begin
return 'xxx'::text;
end;
$BODY$
Only when recompiling through Scripts->Create Script then F5 ( Execute ) I got the error.
What is the problem here?
I could not find a similar problem on the net, nor into the manuals. But I haven't read them all.
You're certainly missing the postgis extension in the current database. If you already have it installed in your server, just execute the following command to create the extension and so the missing data type:
CREATE EXTENSION postgis;
If it happens to be that you don't have it installed in your database server, you can find the installation instructions to many operating systems here.
The problem is caused by the way pgadmin 4 shows the plpgsql code when using Scripts-> Create Script.
It adds unneeded quotes to the paths in the search_path directive that makes the entire search_path invalid. With an invalid search_path the compiler will not find the available extensions.
We actually have an item with PGAdmin4 with Scripts->Create Script malfunction.
In PgAdmin 3 the search_path directive used in the function was showed as alter function statement but in a correct form.
Many thanks to Jim Jones for the precious analysis on this problem.

Heroku Postgres delete trigger not replicating to Salesforce over Heroku Connect

A Heroku Postgres delete trigger is triggering and successfully deleting its target Postgres rows, however the delete isn't syncing over to Salesforce via Heroku Connect. When the same delete is done manually it syncs to Salesforce without issue.
Are there any special considerations for Postgres delete triggers that need to sync over to Salesforce via Heroku Connect, e.g., setting certain fields before performing the delete?
From Heroku support...
Connect uses an almost-entirely-unused Postgres session variable called xmlbinary as a flag to prevent Connect's own writes to a table from triggering additional _trigger_log entries. If these deletes are happening as a result of Connect activity (and therefore executing in the context of a Connect database connection), Connect is likely seeing this xmlbinary variable and ignoring the change.
If you can change the value of xmlbinary to base64 for the duration of your trigger, it should fix it. That would look like this:
CREATE OR REPLACE FUNCTION foo() RETURNS TRIGGER AS $$
DECLARE
oldxmlbinary varchar;
BEGIN
-- Save old value
oldxmlbinary := get_xmlbinary();
-- Change value to ensure writing to _trigger_log is enabled
SET SESSION xmlbinary TO 'base64';
-- Perform your trigger functions here
-- Reset the value
EXECUTE 'SET SESSION xmlbinary TO ' || oldxmlbinary;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;