Error handling long Postgres table names
See original GitHub issueEnvironment
Liquibase Version: 4.0.0
Liquibase Integration & Version: Java API
Liquibase Extension(s) & Version:
Database Vendor & Version: Postgres 10.12
Operating System Type & Version: Mac + Linux
Description
If I create a simple changeset with a single createTable directive with a 63-character length tableName Liquibase fails with a relation already exists error. Not only is this error misleading, it also is unnecessary since Postgres will not truncate table names until they are MORE THAN 63 characters. We are looking at upgrading from Liquibase 3.5.4 to 4.0.0 and we have a programmatic table name generator that currently banks on being able to create table names up to and including 63 characters in length so this is a problem for us as we have existing 63 character tables.
Steps To Reproduce
Create a simple changeset:
<changeSet id="1" author="Me">
<createTable tableName="my_63_char________________________________________________table">
<column name="id" type="SERIAL"><constraints primaryKey="true"/></column>
<column name="value" type="TEXT"><constraints nullable="false" /></column>
</createTable>
</changeSet>
Execute by some means (we do it programmatically via the Java API).
The operation will fail and the nested Exception root cause is
liquibase.exception.DatabaseException: ERROR: relation "my_63_char________________________________________________table" already exists [Failed SQL: (0) CREATE TABLE public.my_63_char________________________________________________table (id INTEGER GENERATED BY DEFAULT AS IDENTITY NOT NULL, value TEXT NOT NULL, CONSTRAINT MY_63_CHAR________________________________________________TABLE_PKEY PRIMARY KEY (id))]
This is interesting so I executed that directly in psql and what is happening is that the table creation is fine but the name of the derived primary key is automatically truncated by Postgres to 63 characters which makes it identical to the table name (the _PKEY
suffix is shaved off) and causes the confusing error message about the relation already existing.
For whatever reason this wasn’t a problem in Liquibase 3.5.4 and, if I just execute a simple create table via psql:
create table my_63_char________________________________________________table ( id serial primary key, value text not null );
this works fine and Postgres creates the associated PK constraint and sequence using the names my_63_char_________________________________________________pkey
and my_63_char_______________________________________________id_seq
.
My suspicion is that Liquibase 4.0.0 is doing it’s own name creation for things like the PK constraint but that it’s simply suffixing rather than first truncating to (63 - suffix_length) characters and then suffixing.
Actual Behavior
see above
Expected/Desired Behavior
see above
Screenshots (if appropriate)
n/a
Additional Context
see above
LIQUIBASE INTERNAL QA REQUIREMENTS
Validate you can reproduce the bug using the steps provided prior to testing the fix.
Test Cases
- Verify update of a table with a 63-character name that defines a primary key on a column is successful.
- Verify the primary key created has a name that is 63 characters long, including the suffix.
- Verify an update the 63-character name table with a primary key defined in a second changeset is successful.
- Verify all automated functional tests on Jenkins are passing
Note to Community: The functional Liquibase tests run on our internal build system and are not visible to the broader community.
- When manual tests and existing automated tests are passing, add a regression test to the functional test suite.
- The test is postgres-specific and should be added as a regression test.
The Associated PR: https://github.com/liquibase/liquibase/pull/1514
Issue Analytics
- State:
- Created 3 years ago
- Comments:25 (24 by maintainers)
Top GitHub Comments
Thanks for the additional research on PostgreSQL 10.
Thanks @molivasdat !