ERROR: syntax error at or near "FUNCTION" while db restoring - postgresql

I have an error while restoring DB from dump. What does it mean?
ERROR: syntax error at or near "FUNCTION"
LINE 1: ...LETE ON public.currency_rate FOR EACH ROW EXECUTE FUNCTION p...
--
-- Name: currency_rate currency_rate_bt_delete; Type: TRIGGER; Schema: public; Owner: -
--
CREATE TRIGGER currency_rate_bt_delete
INSTEAD OF DELETE ON public.currency_rate
FOR EACH ROW
EXECUTE FUNCTION public.currency_rate_bt_delete();

The problem of your dump/restore is that your create dump with PostgreSQL v13 It generates dump you have shown.
But then you try to restore this dump on PostgreSQL v10 which does not understand that dump

You have to use PROCEDURE instead of FUNCTION before public.currency_rate_bt_delete()
Your trigger query should be like below:
CREATE TRIGGER currency_rate_bt_delete
INSTEAD OF DELETE ON public.currency_rate
FOR EACH ROW
EXECUTE PROCEDURE public.currency_rate_bt_delete();
NOTE : - This answer is limited to the error mentioned in the question.

Related

How to create procedure in PostgreSQL

I'm trying to convert Oracle to PostgreSQL. I'm getting error like ERROR: syntax error at or near "UPDATE_USER_PWD_INVALID1" while creating procedure
CALL PROCEDURE UPDATE_USER_PWD_INVALID1 IS
-- PRAGMA AUTONOMOUS_TRANSACTION;
V_INVALID_COUNT USERSMPININVALID.INVALID_COUNT%TYPE;

data corrupted in postgres - right sibling's left-link doesn't match: block 9550 links to 12028 instead of expected 12027 in index "log_attach_id_idx"

I am new to Postgres and we are using it for tests reports, we had an issue with our environment that entered duplicate keys to one of the table and since then we are getting this message when trying to run migration scripts:
error: migration failed: right sibling's left-link doesn't match: block 9550 links to 12028 instead of expected 12027 in index "log_attach_id_idx" in line 0: UPDATE log SET project_id = (SELECT project_id FROM item_project WHERE item_project.item_id=log.item_id LIMIT 1); (details: pq: right sibling's left-link doesn't match: block 9550 links to 12028 instead of expected 12027 in index "log_attach_id_idx")
I tried to run pg_dump and got this error:
pg_dump: error: query was: SELECT pg_catalog.pg_get_viewdef('457544'::pg_catalog.oid) AS viewdef
pg_dumpall: error: pg_dump failed on database "reportportal", exiting
Can anyone help here?
Restore your backup, and research what parameters you changed and what you did to end up with data corruption in the first place.

Is it possible to call a function/procedure in postgres without braces?

I am working on DB migration from Oracle to Postgres and came across a situation where a legacy Java code is calling a stored procedure from Oracle. It is a simple call without parentheses like this : Mgr.AdmSP.myproc = ad.ctlpk.proc
where ad is schema name, ctlpk is Package name and proc is Stored Procedure in Oracle
we have migrated procedure proc to Postgres but when it comes to calling, Postgres expects () for procedure or function calls even if it does not take any parameters.
So we tried to run it like this : Mgr.AdmSP.myproc = ad_ctlpk.proc(). Here ad_ctlpk is postgres schema name. After executing we are getting error : syntax error at or near "(".
Since this is a database migration only, we are not expected to make any changes to other components except database objects. Is there a way to mimic the Oracle like procedure calling style in Postgres?
Like Postgres have function now() and current_timestamp which perform same functionality but with different syntax. I am using Postgres Ver 11.11.
Adding some details as per comments for more details. In Oracle, it is defined as FUNCTION Proc RETURN INT and as of now we converted it into Postgres function as
CREATE FUNCTION ad_ctlpk.proc() RETURNS INTEGER
I am not sure about the Framework and other java code details since I dont have access to Java code. We have access to executables only, which when executed gives below error
[[AdmThread 1] [WARN:AbstractThreadedPublisherManager$ExceptionHandlingThreadGroup:48] Error in thread AdmThread 1 : Problem in doWork
Caused by: Problem running proc procedures
Caused by: ERROR: syntax error at or near "("
Position: 38, State: 42601, ErrorCode: 0
com.ubs.datait.common.distribution.exception.DistributionRuntimeException: Problem in doWork
at common.distribution.manager.AdmThread.doWork(AdmThread.java:72)
at common.distribution.common.AbstractDistributionThread.run(AbstractDistributionThread.java:30)
Caused by: common.distribution.exception.DistributionRuntimeException: Problem running proc procedures
at common.distribution.manager.AdmThread.runAdminProc(AdmThread.java:100)
at common.distribution.manager.AdmThread.doWork(AdmThread.java:67)
... 1 more
Caused by: org.postgresql.util.PSQLException: ERROR: syntax error at or near "("
Position: 38
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2552)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2284)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:322)
at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:481)
Update: :
Since Postgres does not support creating/calling functions without braces (), we finally had to ask for changes in java code to add () to the function calls where required.

Geometry Equality Operator Not Available on pg_restore WIthout Explicit Type Casts

Postgres 12, Postgis 3
Two triggers are originally defined w/ the criteria
WHEN (OLD.geom IS DISTINCT FROM NEW.geom). The geom column is of type geometry.
This caused issues when pg_restore-ing the database due to the geometry operator for equals not being available:
pg_restore: while PROCESSING TOC:
pg_restore: from TOC entry 10233; 2620 673186 TRIGGER lines the_trigger_name geo
pg_restore: error: could not execute query: ERROR: operator is not unique: public.geometry = public.geometry
LINE 1: ...public.lines FOR EACH ROW WHEN ((old.geom IS DISTINC...
^
HINT: Could not choose a best candidate operator. You might need to add explicit type casts.
Command was: CREATE TRIGGER the_trigger_name AFTER UPDATE ON public.lines FOR EACH ROW WHEN ((old.geom IS DISTINCT FROM new.geom)) EXECUTE FUNCTION public.the_function_name();
The backup database uses postgis 3.0.0
We load it in two different ways:
in one environment (postgis 3.0.1), we use a a database dump in the plain text (default) format (pg_dump -F p), and load it up by just executing the plaintext file, like psql -f /my/file.sql
this reported the error, but the database load still works
in another environment (postgis 3.0.2), we use a a database dump in the custom format (pg_dump -F custom) and load it up by running pg_restore --single-transaction < “$DB_FILE”
this reported the error, and failed
Adding a ::geometry cast on OLD/NEW geom fixes this issue. Why is pg unable to determine the equality operator in certain contexts (without type casts)?

pg_restore: can't import data if table has a constraint with a function calling another function

In PostgreSQL using only public schema, data in tables that use in check constraints functions that invoke other functions does not get imported with pg_restore after it was dumped with pg_dump. But if functions in check constraints do not invoke other functions, data is correctly imported.
I have noted this behavior after minor upgrading from 9.3.22 to 9.3.23 and from 9.4.16 to 9.4.17; in 9.3.22 and 9.4.17 it worked fine.
I understand is due to changes in search_path:
Avoid use of insecure search_path settings in pg_dump and other client
programs (Noah Misch, Tom Lane)
pg_dump, pg_upgrade, vacuumdb and other PostgreSQL-provided
applications were themselves vulnerable to the type of hijacking
described in the previous changelog entry; since these applications
are commonly run by superusers, they present particularly attractive
targets. To make them secure whether or not the installation as a
whole has been secured, modify them to include only the pg_catalog
schema in their search_path settings. Autovacuum worker processes now
do the same, as well.
In cases where user-provided functions are indirectly executed by
these programs — for example, user-provided functions in index
expressions — the tighter search_path may result in errors, which will
need to be corrected by adjusting those user-provided functions to not
assume anything about what search path they are invoked under. That
has always been good practice, but now it will be necessary for
correct behavior. (CVE-2018-1058 or CVE-2018-1058)
Still it's unclear to me why having one level public functions is allowed but it is not those functions to invoke other ones.
For example, having this structure and data:
CREATE OR REPLACE FUNCTION is_even(n integer) RETURNS boolean AS $BODY$
BEGIN
return n%2 = 0;
END ; $BODY$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION is_even_positive(n integer) RETURNS boolean AS $BODY$
BEGIN
return is_even(n) and n > 0;
END ; $BODY$ LANGUAGE plpgsql;
CREATE TABLE test_check (
n integer
CONSTRAINT even_chk CHECK (is_even(n)));
CREATE TABLE test_check2(
n integer
CONSTRAINT even_positive_chk CHECK (is_even_positive(n)));
insert into test_check values (2);
insert into test_check values (-2);
insert into test_check2 values (2);
Exporting it with:
pg_dump -h localhost -p 5432 -F c -b -v -f test.dmp test -U test
And importing it in a new database:
$ pg_restore -d test2 -U test -v test.dmp -h localhost
pg_restore: connecting to database for restore
pg_restore: creating SCHEMA "public"
pg_restore: creating COMMENT "SCHEMA public"
pg_restore: creating EXTENSION "plpgsql"
pg_restore: creating COMMENT "EXTENSION plpgsql"
pg_restore: creating FUNCTION "public.is_even(integer)"
pg_restore: creating FUNCTION "public.is_even_positive(integer)"
pg_restore: creating TABLE "public.test_check"
pg_restore: creating TABLE "public.test_check2"
pg_restore: processing data for table "public.test_check"
pg_restore: processing data for table "public.test_check2"
pg_restore: [archiver (db)] Error while PROCESSING TOC:
pg_restore: [archiver (db)] Error from TOC entry 2035; 0 7784774 TABLE DATA test_check2 tad
pg_restore: [archiver (db)] COPY failed for table "test_check2": ERROR: function is_even(integer) does not exist
LINE 1: SELECT is_even(n) and n > 0
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
QUERY: SELECT is_even(n) and n > 0
CONTEXT: PL/pgSQL function public.is_even_positive(integer) line 3 at RETURN
COPY test_check2, line 1: "2"
pg_restore: creating ACL "SCHEMA public"
WARNING: errors ignored on restore: 1
Note test_check table gets correctly imported with data whereas test_check2 fails.
The solution is to explicitly set a search_path for the functions.
Then it won't matter that pg_restore sets search_path = pg_catalog, bacause it will be overridden by the function's setting.
This will also protect the functions from inadvertedly picking up functions and operators from a different schema that happens to be set in the calling session (which is the security problem the change is trying to fix).
ALTER FUNCTION is_even_(integer) SET search_path=public;
ALTER FUNCTION is_even_positive(integer) SET search_path=public;