Oracle NUMBER(precision,scale) in HSQLDB - java

In a unit test I am trying to generate a table in an in-mem HSQLDB, the table contains a column with the definition: #Column(name = "xxx", columnDefinition="NUMBER(10,0) default 0"). NUMBER is not recognized by HSQLDB (version 2.3.3), so I have added a script running this statement first: CREATE TYPE NUMBER AS NUMERIC;. Now it seems to recognize NUMBER, but I get the error unexpected token: ( instead. I cannot edit the column definition, so wow do I correctly map Oracle NUMBER(10,0) to NUMERIC? If I remove the precision and scale from NUMBER it seems to work.

You do not need to define the NUMBER type, as it is supported by HSQLDB.
HSQLDB supports Oracle syntax in one of its compatibility modes. Run this statement to enable it:
SET DATABASE SQL SYNTAX ORA TRUE

Related

Query for the allowed values in a constraint

I want to extract values from a CHECK constraint on a database table. The code is:
CONSTRAINT Shop_check_serviceType CHECK (service_type IN ('food or drink', 'entertainment', 'retail'))
In Postgres 12 there is a column named consrc in pg_catalog.pg_constraint. But I use Postgres 14 and I don't know how to extract the values there. I have tried to search the manual without success.
Use the dedicated function pg_get_constraintdef() to reverse-engineer the SQL-DDL code of constraint definition.
SELECT pg_get_constraintdef(oid)
FROM pg_catalog.pg_constraint
WHERE contype = 'c' -- CHECK constraint
AND conrelid = 'public.my_table'::regclass -- your table name here
AND connname = 'shop_check_servicetype'; -- lower-cased?
If you did not double-quote the constraint name "Shop_check_serviceType" it has been converted to lower-case.
Related:
Delete rows with foreign key in PostgreSQL
BTW, the (redundant) column consrc existed up to Postgres 11 and had already been dropped from pg_catalog.pg_constraint in Postgres 12. pg_get_constraintdef() reproduces what used to be in that column.
Quoting the release notes of Postgres 12:
Remove obsolete pg_constraint.consrc column (Peter Eisentraut)
This column has been deprecated for a long time, because it did not
update in response to other catalog changes (such as column
renamings). The recommended way to get a text version of a check
constraint's expression from pg_constraint is pg_get_expr(conbin, conrelid). pg_get_constraintdef() is also a useful alternative.

Flyway h2 postgressql mode migration not working

I have to following migration working in postgres:
ALTER TABLE task_def
DROP COLUMN retry_count,
DROP COLUMN timeout_seconds;
(and running in prod)
but now i want to switch to h2 for my unit test but h2 doesnt seem to accept it
My database config in spring boot:
spring.datasource.url=jdbc:h2:./target/testdb;MODE=PostgreSQL
spring.datasource.username="sa"
spring.datasource.password=""
spring.jpa.hibernate.ddl-auto=none
spring.datasource.driver-class-name=org.postgresql.Driver
spring.flyway.url=jdbc:h2:./target/testdb;MODE=PostgreSQL
spring.flyway.user="sa"
spring.flyway.password=""
spring.flyway.schemas=
The error:
Migration V3__.....sql failed
---------------------------------------
SQL State : 42S22
Error Code : 42122
Message : Column "DROP" not found; SQL statement:
ALTER TABLE task_def
DROP COLUMN retry_count,
DROP COLUMN timeout_seconds [42122-200]
Location : db/migration/V3__.....sql
Line : 1
Statement : ALTER TABLE task_def
DROP COLUMN retry_count,
DROP COLUMN timeout_seconds
I haven't worked with H2 but it looks like it supports the following:
2 Statements instead of one in the same migration (flyway should run them in the same transaction anyway):
ALTER TABLE task_def DROP COLUMN retry_count;
ALTER TABLE task_def DROP COLUMN timeout_seconds;
Use different syntax:
ALTER TABLE task_def DROP COLUMN retry_count, timeout_seconds;
Of course if postgresql allows to do so as well.
All in all, I don't think that H2 will be able to cover all the features offered by postgres with its dialect, so failures like this can't be avoided.
So in my experience the following approach works much better:
Create a "test container" of postgres (see testcontainers project) and configure flyway / data source to run against it in tests. Depending on your tests infrastructure you can even not stop the container, but drop the database and run flyway before each test case. Or alternatively you can do like in spring tests - create an artificial transaction before running the test and "fail" it when the test finishes (even if it finishes successfully) so that the db won't be dirty for the next test.
There is no portable way to drop multiple columns at once, ALTER TABLE … DROP COLUMN is a standard command, but only for one column.
Some databases, however, including PostgreSQL and H2, support such non-standard feature, but their syntax is different. PostgreSQL expects
ALTER TABLE tableName DROP COLUMN columnName1, DROP COLUMN columnName2, …
https://www.postgresql.org/docs/12/sql-altertable.html
H2 expects
ALTER TABLE tableName DROP COLUMN columnName1, columnName2, …
https://h2database.com/html/commands.html#alter_table_drop_column
If you use different databases, you should avoid non-portable commands when possible.

Hibernate #Formula / ERROR: schema "FOO" does not exist

I'm updating old libraries from a legacy system. Just now i'm trying to update Hibernate 3.4.0.GA to 4.3.11.Final, i just needed to change small things in the code, everything was fine. But when i put the system to run, i'm receiving a "schema "FOO" does not exist" while execute a query. Trying to isolate the problem, i discovered this happen from Hibernate 3.5.1 to 3.5.2 and the reasons.
Hibernate when generating the sql, is adding schema to functions. I show now the difference in two versions.
protocolo_1 is the alias of main schema, this is a subquery added by #Formula in Protocolo.java, the name of schema is protocolo too.
#Formula
select max (pm2.id) from protocolo.protocolomovimento pm2 where pm2.id_protocolo = id
Hibernate 3.5.1 SQL generated
select max (pm2.id) from protocolo.protocolomovimento pm2 where pm2.id_protocolo = protocolo1_.id
Hibernate 3.5.2 SQL generated
select protocolo_1.max (pm2.id) from protocolo.protocolomovimento pm2 where pm2.id_protocolo = protocolo1_.id
I'm using PostgreSQL 9.4.12 with respective driver and org.hibernate.dialect.PostgreSQLDialect (in this versions of hibernate, it's the unique dialect to PostgreSQL)
I found another guy with similar problem here Why is Hibernate adding schema name to Hsql functions? but i think its only similar, it's not my case.
Why is Hibernate doing this? How can i fix this?
Looks like hibernate don't understand space character between max and ( in expression max (pm2.id), so it thinks that max is column name and adds table alias there.
Removing space will solve the problem.

Removing quotes in openjpa generated sql for sybase

I need to be able to refer to a table on a different schema, using OpenJPA to access a Sybase db.
So, for example, I need to select as follows:
SELECT name FROM SHARE.dbo.PROVINCE;
However, the generated SQL is:
SELECT name FROM "SHARE.dbo".PROVINCE;
which Sybase rejects. Without the quotes it works fine.
I'm using the following annotations on the class:
#Entity
#Table(name="PROVINCE", schema="SHARE.dbo")
using schema="SHARE" doesn't work, although it generates the sql without any quotes. (Sybase requires schema.owner.table, so SCHEMA.PROVINCES is an unknown object)
Any thoughts on how to resolve this issue?
Try concatenating the schema to the table name: #Table(name="SHARE.dbo.PROVINCE")
This is a bit of a shot in the dark, but you could try to disable delimited identifier support?
openjpa.DBDictionary=sybase(SupportsDelimitedIdentifiers=false)

Retrieve column Default with Derby DB via JDBC

I have a table with a column defined like this:
Country VARCHAR(2) NOT NULL DEFAULT 'US'
When I try to detect this default with JDBC it fails. Basically when I use DatabaseMetaData.getColumns the result does not contain the COLUMN_DEFAULT column. It is there when I try this with H2.
Any ideas how to get the default with Derby?
Did you try for COLUMN_DEFAULT? Or for COLUMN_DEF? According to the Javadoc I think it should be COLUMN_DEF.
Also, what version of Java and of JDBC are you using? I think that Derby only added COLUMN_DEF as part of the JDBC 4.0 support, which may require Java 1.6.

Categories