How can I create triggers for a postgreSQL db using liquibase? - postgresql

I'm using the dropwizard-migrations module for liquibase db refactoring. See the guide here: http://dropwizard.codahale.com/manual/migrations/
When I run
java -jar my_project.jar db migrate my_project.yml
I get the following error:
ERROR [2013-09-11 20:53:43,089] liquibase: Change Set migrations.xml::11::me failed. Error: Error executing SQL CREATE OR REPLACE TRIGGER add_current_date_to_my_table BEFORE UPDATE ON my_table FOR EACH ROW EXECUTE PROCEDURE change_update_time();: ERROR: syntax error at or near "TRIGGER"
Position: 19
Here are some relevant changesets from my migrations.xml file:
<changeSet id="1" author="me">
<createProcedure>
CREATE OR REPLACE FUNCTION change_update_time() RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
NEW.updated_at := CURRENT_TIMESTAMP;
RETURN NEW;
END;
$$;
</createProcedure>
<rollback>
DROP FUNCTION change_update_time();
</rollback>
</changeSet>
<changeSet id="2" author="me">
<preConditions>
<not>
<tableExists tableName="my_table"/>
</not>
</preConditions>
<createTable tableName="my_table">
<column name="_id" type="integer" defaultValue="0">
<constraints nullable="false"/>
</column>
<column name="updated_at" type="timestamp without time zone" defaultValue="now()">
<constraints nullable="false"/>
</column>
</createTable>
</changeSet>
<changeSet id="3" author="me">
<sql splitStatements="false">
CREATE OR REPLACE TRIGGER add_current_date_to_my_table BEFORE UPDATE ON my_table FOR EACH ROW EXECUTE PROCEDURE change_update_time();
</sql>
<rollback>
DROP TRIGGER add_current_date_to_my_table ON my_table;
</rollback>
</changeSet>
Is there any way I can create the trigger add_current_date_to_my_table? Is this redundant with the "RETURNS trigger" from creating the function?

The solution is:
<changeSet id="3" author="me">
<sql>
DROP TRIGGER IF EXISTS add_current_date_to_my_table ON my_table;
CREATE TRIGGER add_current_date_to_my_table BEFORE UPDATE ON my_table FOR EACH ROW EXECUTE PROCEDURE change_update_time();
</sql>
<rollback>
DROP TRIGGER add_current_date_to_my_table ON my_table;
</rollback>
</changeSet>
H/T Jens.

Ann Kilzer has provided the right answer as there is no CREATE OR REPLACE statement in Postgres, unlike PL/SQL.
So we need to split this statement into 2 atomic operations:
DROP TRIGGER
CREATE TRIGGER

Related

Liquibase ERROR: Column has unsupported type "serial" when creating a Redshift auto increment int column in XML

When creating a table in XML to be deployed to Redshift database using Liquibase
<createTable schemaName= "staging" tableName="tempauto">
<column name="key" type="integer" autoIncrement="true">
<constraints nullable="false"/>
</column>
ERROR: Column "key" has unsupported type "serial"
I expected the column key to be created as an int like SQL and to auto-increment.
However Liquibase converts the auto-increment column to type 'serial' which is not supported in Redshift.

Liquibase databasechangelog xml file - how to create enum in postgresql

I use liquibase and I want to create enum in my xml file (PostgreSQL).
As an example below changelog file (only a piece of the file) that creates new table:
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
<changeSet id="r3.3.0_table_creation_research_document "
author="anonim">
<createTable tableName="research_document">
<column name="id" type="bigint">
<constraints primaryKey="true"
primaryKeyName="research_document_pkey" nullable="false" />
</column>
I can't find any info/examples in Internet!
I don't think liquibase supports enum for postgres natively in the xml format. However, since it is possible in postgres, you could always use liquibase's formatted sql instead of xml:
--liquibase formatted sql
--changeset ronak:1
CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');
CREATE TABLE person (
name text,
current_mood mood
);
--rollback drop table person;

Create or replace view with liquibase on DB2

I would like to create or replace a view on DB2 using liquibase and its changeSet tag: XML Sample
This is what I include in the changelog.xml file:
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
logicalFilePath="lon-service-mpd/gin/15.100/15.100.0.0.changelog.xml"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
<changeSet author="mas-gin-gestion-echelon-service" id="create-view-from-table-periodeavancement-type-personnel">
<createView schemaName="GIN" viewName="V_PERIODEAVANCEMENT_1">select IDPERIODE, CAMPAGNETA from GIN.PERIODEAVANCEMENT</createView>
</changeSet>
</databaseChangeLog>
However, during the creation of the view, DB2 returns the following error liquibase.exception.DatabaseException: DB2 SQL Error: SQLCODE=-206, SQLSTATE=42703
I do not find the way to fix the problem, even if the SQL syntax is correct.
I have fixed the problem by calling directly a sql file instead of using the XML sample. Here is my solution:
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
logicalFilePath="mas-gin-gestion-echelon-service-mpd/gin/15.100/15.100.0.0.changelog.xml"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
<changeSet id="create_view_periodeavancement" author="mas-gin-gestion-echelon-service">
<sqlFile path="sql/create_view_periodeavancement.sql" relativeToChangelogFile="true"/>
</changeSet>
And the sql file:
CREATE OR REPLACE VIEW GIN.V_PERIODEAVANCEMENT_1 (IDPERIODE, TS_INSERT, BL_DELETE )
AS SELECT IDPERIODE, TS_INSERT, BL_DELETE
FROM PERIODEAVANCEMENT;

liquibase postgresql creating functions

I am using liquibase to create triggers for postgressql database. Below is the syntax which I use in liquibase
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
<changeSet id="1" author="yc14ik1">
<createProcedure catalogName="cat" dbms="postgresql"
encoding="utf8" procedureName="UPDATE_LAST_ROW_CHG_TS()" relativeToChangelogFile="true" schemaName="sub">
CREATE OR REPLACE FUNCTION UPDATE_LAST_ROW_CHG_TS() RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
NEW.LAST_ROW_CHG_TS = NOW();
RETURN NEW;
END;
$$;
</createProcedure>
<sql></sql>
</changeSet>
When this procedure is executed in Jenkins Job, I get this error
Unexpected error running Liquibase: ERROR: language "plpgsql" does not exist
Hint: Use CREATE LANGUAGE to load the language into the database. [Failed SQL: CREATE OR REPLACE FUNCTION UPDATE_LAST_ROW_CHG_TS() RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
NEW.LAST_ROW_CHG_TS = NOW();
RETURN NEW;
END;
$$;]
Build step 'Execute shell' marked build as failure
Notifying upstream projects of job completion
Warning: you have no plugins providing access control for builds, so falling back to legacy behavior of permitting any downstream builds to be triggered
Can some one help me how can I fix this problem ?
I set up mine differently and it works just fine.
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
<changeSet author="l" id="UPDATE_LAST_ROW_CHG_TS" runOnChange="true">
<createProcedure catalogName="UPDATE_LAST_ROW_CHG_TS"
dbms="postgresql"
encoding="utf8"
path="../files/UPDATE_LAST_ROW_CHG_TS.sql"
procedureName="UPDATE_LAST_ROW_CHG_TS"
relativeToChangelogFile="true"
schemaName="public"></createProcedure>
</changeSet>
</databaseChangeLog>
from there you put all the sql inside a .sql file referenced in the path attribute.
I dont know that your way wont work but it seems odd to me that you have empty tags towards the bottom. Maybe you meant for those to wrap your sql function?
Anyways I know the example above will work if liquibase is configured and ran properly.

create oid column in postgres through liquibase

The following liquibase statement when run against postgres (9.3,9.4):
<createTable tableName="document">
<column name="document_data" type="Blob">
</createTable>
creates a table document_data with the type bytea.
How do I tell liquibase that I want and OID type?
Who would expect: :
<column name="document_data" type="oid">
As of Liquibase 3.5.2, blob is mapped to oid, as one would expect: https://liquibase.jira.com/browse/CORE-1863