So I am reallly new to PostgreSQL and for the last 3 days I am stuck with this. I need to import a PostgreSQL Database. The database lies in a folder and has various .tab files.
I have PostgreSQL 9.1 release. The database is imported by user postgres to which I granted all the possible privileges. I also granted all the possible privileges to the language.
The command that is run by a script is:
CREATE OR REPLACE FUNCTION unique_toplevel_corpus_name() RETURNS TRIGGER AS $$
DECLARE
count INTEGER := 0;
BEGIN
IF NEW.top_level = 'y' THEN
PERFORM * FROM corpus WHERE corpus.name = NEW.name AND corpus.t$
GET DIAGNOSTICS count = ROW_COUNT;
IF count != 0 THEN
RAISE EXCEPTION 'conflicting top-level corpus found: %'$
END IF;
END IF;
RETURN NEW;
END;
$$ language plpgsql;
The code is not mine. It is provided and works fine on my local machine (Ubuntu 12.04), importing the db without any problems, but has problems only on Ubuntu server (also 12.04).
This is the exception I keep getting:
#valian:/opt/annis/annis-service-2.2.1/bin$ ./annis-admin.sh import /home/FilesForAnnis/Korpora/relANNIS/relANNIS/
19:38:45.755 CorpusAdministration INFO: Importing corpus from: /home/FilesForAnnis/Korpora/relANNIS/relANNIS/
19:38:45.758 SpringAnnisAdministrationDao INFO: creating staging area
19:38:45.788 SpringAnnisAdministrationDao INFO: bulk-loading data
19:38:46.236 SpringAnnisAdministrationDao INFO: computing top-level corpus
Exception in thread "main" org.springframework.jdbc.BadSqlGrammarException: StatementCallback; bad SQL grammar [-- find the top-level corpus
ALTER TABLE _corpus ADD top_level boolean;
CREATE TRIGGER unique_toplevel_corpus_name BEFORE UPDATE ON _corpus FOR EACH ROW EXECUTE PROCEDURE unique_toplevel_corpus_name();
UPDATE _corpus SET top_level = 'n';
UPDATE _corpus SET top_level = 'y' WHERE pre = (SELECT min(pre) FROM _corpus);
-- add the toplevel corpus to the node table
CREATE INDEX tmp_corpus_toplevel ON _corpus (id) WHERE top_level = 'y';
ALTER TABLE _node ADD toplevel_corpus bigint;
UPDATE _node SET toplevel_corpus = _corpus.id FROM _corpus WHERE _corpus.top_level = 'y';
DROP INDEX tmp_corpus_toplevel;
]; nested exception is org.postgresql.util.PSQLException: ERROR: function unique_toplevel_corpus_name() does not exist
at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:98)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:406)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:427)
at annis.administration.SpringAnnisAdministrationDao.executeSqlFromScript(SpringAnnisAdministrationDao.java:617)
at annis.administration.SpringAnnisAdministrationDao.executeSqlFromScript(SpringAnnisAdministrationDao.java:608)
at annis.administration.SpringAnnisAdministrationDao.computeTopLevelCorpus(SpringAnnisAdministrationDao.java:226)
at annis.administration.CorpusAdministration.importCorpora(CorpusAdministration.java:85)
at annis.administration.CorpusAdministration$$FastClassByCGLIB$$ce864c53.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)
at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:688)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:621)
at annis.administration.CorpusAdministration$$EnhancerByCGLIB$$b6899e79.importCorpora(<generated>)
at annis.administration.AnnisAdminRunner.doImport(AnnisAdminRunner.java:176)
at annis.administration.AnnisAdminRunner.run(AnnisAdminRunner.java:74)
at annis.administration.AnnisAdminRunner.main(AnnisAdminRunner.java:49)
Caused by: org.postgresql.util.PSQLException: ERROR: function unique_toplevel_corpus_name() does not exist
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2062)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1795)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:479)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:353)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:345)
at org.springframework.jdbc.core.JdbcTemplate$1ExecuteStatementCallback.doInStatement(JdbcTemplate.java:420)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:395)
... 16 more
I also updated jdbc posgtres connector. The only difference between my local machine where everything works perfectly and the server is that I have java 1.7 on the local machine and not 1.6 but I do not think it can be the problem.
I have no idea what else I could try there...
This is not a problem with Ubuntu. This is a problem with your database import. Your database import error says that you are missing the trigger function.
Additionally I know the code isn't yours. To the extent you can replace the trigger with a partial unique index however your performance will be a lot better.
If the code isn't yours you will need to follow up with whoever wrote it as to why the function isn't there, but when you do that, you may want to follow up with them about replacing the trigger with this:
CREATE UNIQUE INDEX ON corpus(name) WHERE corpus.t;
This will perform better and it is easier to maintain.
Related
I have this function
DO
$do$
BEGIN
IF EXISTS (SELECT FROM pg_database WHERE name = 'MydB') THEN
RAISE NOTICE 'db already created';
ELSE
CREATE DATABASE MydB;
END IF;
END
$do$;
However when this runs I get the error:
CREATE DATABASE cannot be executed from a function
can anyone recommend a good way around this?
You cannot run CREATE DATABASE inside a transaction, so you cannot run it in a function.
Run it without using the DO statement, and if you get an error with SQLSTATE 42P04, ignore it – it means that the database already exists.
I got a weird error while I was writing to my Postgres database over Aurora PostgreSQL on AWS
PostgreSQL version 9.6.11
my tries to fix that issue on table admin_user
Vacuum admin_user
Vacuum Freeze admin_user
I couldn't recreate the table as it's connected to all other tables and will cause a big mess
Update question
I cant access the table
For reasons that we probably cannot fathom here (could be a PostgreSQL software bug that might have been fixed by 9.6.19, could be a hardware problem), you have suffered data corruption.
Since you are using a hosted database and have no access to the database except through SQL, your options are limited.
The best is probably to use subtransactions to lift as many data as you can from the table (called test in this example):
/* will receive salvaged rows */
CREATE TABLE test_copy (LIKE test);
You can run something like this code:
DO
$$DECLARE
c CURSOR FOR SELECT * FROM test;
r test;
cnt bigint := 0;
BEGIN
OPEN c;
LOOP
cnt := cnt + 1;
/* block to start a subtransaction for each row */
BEGIN
FETCH c INTO r;
EXIT WHEN NOT FOUND;
EXCEPTION
WHEN OTHERS THEN
/* there was data corruption fetching the row */
RAISE WARNING 'skipped corrupt data at row number %', cnt;
NOVE c;
CONTINUE;
END;
/* row is good, salvage it */
INSERT INTO test_copy VALUES (r.*);
END LOOP;
END;$$;
Good luck.
as we start to migrate our Application from using Oracle to PostgreSQL we ran into the following problem:
A lot of our Oracle scripts create triggers that work on Oracle specific tables which dont exist in PostgreSQL. When running these scripts on the PG database they will not throw an error.
Only when the trigger is triggered an error is thrown.
Example code:
-- Invalid query under PostgreSQL
select * from v$mystat;
-- Create a view with the invalid query does not work (as expected)
create or replace view Invalid_View as
select * from v$mystat;
-- Create a test table
create table aaa_test_table (test timestamp);
-- Create a trigger with the invalid query does(!) work (not as expected)
create or replace trigger Invalid_Trigger
before insert
on aaa_test_table
begin
select * from v$mystat;
end;
-- Insert fails if the trigger exists
insert into aaa_test_table (test) values(sysdate);
-- Select from the test table
select * from aaa_test_table
order by test desc;
Is there a way to change this behavior to throw an error on trigger creation instead?
Kind Regards,
Hammerfels
Edit:
I was made aware, that we actually dont use basic PostgreSQL but EDB instead.
That would probably explain why the syntax for create trigger seems wrong.
I'm sorry for the confusion.
It will trigger an error, unless you have configured Postgres to postpone validation when creating functions.
Try issuing this before creating the trigger:
set check_function_bodies = on;
Creating the trigger should show
ERROR: syntax error at or near "trigger"
LINE 1: create or replace trigger Invalid_Trigger
I want to execute a SQL script in a client using JDBC (not the postgreSQL pslq client). In this script I would like to do something like that:
skip errors on;
alter table foo ...;
skip errors off;
Is there a way to do this with PostgreSQL >= 9.1?
I found this thread with a good solution usind DO blocks and error codes:
How to continue sql script on error?
And creating a function for my problem:
create or replace function continueOnError(v_sqlStatement text)
returns void
language plpgsql
as '
BEGIN
execute v_sqlStatement;
EXCEPTION
WHEN invalid_schema_name
OR undefined_table
OR undefined_column
THEN RAISE WARNING ''Continued on error sql statement: %'', v_sqlStatement;
END;
';
...use it:
select continueOnError('alter table test add constraint fk_test_valueid foreign key (valueid) references value(id)');
Using SQLFiddle, PostgreSQL 9.3.1.
I am learning to define triggers in PostgreSQL, and after doing some research I've found out the following:
Triggers in Postgres are different from MYSQL. Where in Postgres you must create a function that RETURNS TRIGGER, in MySQL you can just create a trigger. So this is what I've come up with:
On Employee Insert, we want to update Departments Total Salary.
CREATE FUNCTION update_sal() RETURNS TRIGGER AS $$
BEGIN
IF NEW.dno IS NOT NULL THEN
UPDATE Department SET Total_sal = total_sal + NEW.salary
WHERE department.dno = NEW.dno;
END IF;
RETURN NULL;
END;
$$ Language plpgsql;
CREATE TRIGGER updateInsert
AFTER INSERT ON Employee
FOR EACH ROW
EXECUTE PROCEDURE update_sal();
And I'm getting the following error:
Schema Creation Failed: ERROR: unterminated dollar-quoted string at or near "$$
BEGIN IF NEW.dno IS NOT NULL THEN UPDATE Department
SET Total_sal = total_sal +NEW.salary WHERE department.dno = NEW.dno":
I've solved the issue thanks to Database Function giving an error - Postgresql
It seems just changing the query terminator at the bottom of the Scheme Window solves this issue.
If you copy-pasted the code, then you've got a simple syntax error: ENDl should be END; in the last-but-one line of the function definition.
Otherwise, it looks good to me.