MySql to Hsqldb migration with engine=InnoDb in sql - mysql

I am creating a spring profile for dynamic environments in gitlab and don't want to create a separate mysql db for each instance, so what I try is to use my existing liquibase migrations with hsqldb in that speciffic profile, which seems to work besides the engine=InnoDb part in the sql.
I already added sql.syntax_mys=true to the datasource url, which supported the datatypes, not the engine part tho.
Since I want to avoid writing different sql migrations for the dynamic environments and already have a prod instance changing the migration or adding separate migrations is not really an option for me.
Is there a way to tell hsql to just ignore that part, or define it as some function which does nothing?
An example sql would be:
create table if not exists xy(
field1 varchar(255) not null,
field2 ....
) engine=InnoDB;

MySQL supports comments, including a special format for conditional execution:
https://dev.mysql.com/doc/refman/8.0/en/comments.html
If you add a version number after the ! character, the syntax within the comment is executed only if the MySQL version is greater than or equal to the specified version number. The KEY_BLOCK_SIZE keyword in the following comment is executed only by servers from MySQL 5.1.10 or higher:
CREATE TABLE t1(a INT, KEY (a)) /*!50110 KEY_BLOCK_SIZE=1024 */;
HSQLDB also supports comment syntax in SQL statements: http://www.hsqldb.org/doc/1.8/guide/ch09.html#N124ED
All these types of comments are ignored by the database.
Based on this, you could put the ENGINE=InnoDB into a comment so that HSQLDB will ignore it, but MySQL will run it:
create table if not exists xy(
field1 varchar(255) not null,
field2 ....
) /*!10000 engine=InnoDB; */

An automatic stripping feature will be added to HSQLDB in the next version.
In the meantime, you could modify the source code of JDBCStatement to check and strip the string when it is submitted.
Update: A snapshot jar with this feature is now available at http://hsqldb.org/download

Related

MySQL autoincrement column have diffrent behaviour with different databases

I have one working project in php and mysql.
In which I am using one column syntax for all my auto increment columns like below -
CREATE TABLE `mytable` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`sometext` int(11) NOT NULL
)
And for inserting records in this table in my whole proect I am using below syntax -
INSERT INTO mytable(ID,sometext)
VALUES(0,'Sometext')
And this is working fine.
But when I copied same DB and project and this code stopped working
So I changed my insert with below
INSERT INTO mytable( sometext)
VALUES( 'Sometext')
But this is very weird... In previous project old syntax is working fine but for new I have to make code change in 100 of places.
Can somebody tell me whats wrong with new MYSQL DB that it stopped supporting old syntax.
The difference is probably that your new database servers has the configuration option sql_mode=NO_AUTO_VALUE_ON_ZERO. Therefore only a NULL will cause an auto-increment to be generated.
Read https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html for full explanation of how sql modes affect your database server.
To avoid having to make code changes, you can change the server option.

MySQL 8: Create Collections via DDL

I’d like to be able to create MySQL Document Store Collections via simple SQL DDL statements rather than using the X-Protocol clients.
Is there any way to do so?
Edit: I’ll try and clarify the question.
Collections are tables using JSON datatypes and functions. That much is clear.
I would like know how I can create a Collection without using the X-Protocol calls and make sure that the aforementioned collection is picked up as an actual Collection.
Judging from MySQL workbench, collection tables have a _id blob PK with an expression, a doc JSON column and a few other elements I do not recall at the moment (might be indexes, etc).
I have no means to tell via the Workbench whatever additional schema/metadata information is required for a table to be considered a Document Store Collection, or if the mere presence of an _id and doc columns are enough.
I hope this clears things up.
All "x-api" instructions are directly mapped to sql syntax. When you e.g. run db.createCollection('my_collection'), MySQL will literally just execute
CREATE TABLE `my_collection` (
`doc` json DEFAULT NULL,
`_id` varbinary(32) GENERATED ALWAYS AS
(json_unquote(json_extract(`doc`,_utf8mb4'$._id'))) STORED NOT NULL,
`_json_schema` json GENERATED ALWAYS AS (_utf8mb4'{"type":"object"}') VIRTUAL,
PRIMARY KEY (`_id`),
CONSTRAINT `$val_strict` CHECK (json_schema_valid(`_json_schema`,`doc`))
NOT ENFORCED
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
You can run the corresponding sql statements yourself if you follow that format.
The doc and _id (with their type and the given expression) are required, the _json_schema is optional, the check too (and only added since MySQL 8.0.17). Since MySQL 8, no additional columns are allowed, except generated columns that use JSON_EXTRACT on doc and which are supposed to be used in an index, see below (although they don't actually have to be used in an index).
Any table that looks like that - doc and _id with their correct type/expression and no other columns except an optional _json_schema and generated JSON_EXTRACT(doc,-columns - will be found with getCollections().
To add an index, the corresponding syntax for
my_collection.createIndex("age", {fields: [{field: "$.age", type: "int"}]})
would be
ALTER TABLE `test`.`my_collection` ADD COLUMN `$ix_i_somename` int
GENERATED ALWAYS AS (JSON_EXTRACT(doc, '$.age')) VIRTUAL,
ADD INDEX `age` (`$ix_i_somename`)
Obviously,
db.dropCollection('my_collection')
simply translates to
DROP TABLE `my_collection`
Similarly, all CRUD operations on documents have a corresponding sql DML syntax (that will actually be executed when you use them via x-api).

MySQL schema name with dash causes errors for Hibernate hbm2ddl.auto

I'm working with hibernate.hbm2ddl.auto=update in development environments and recently I've upgraded hibernate version from 5.1.0.Final to 5.2.X.Final and I've started to experience errors in hibernate's auto generated commands for my schema called portal-appname.
In hibernate 5.1.0 when I add a new column for a given table the following command its executed:
Hibernate: alter table answer add column fake integer not null
But in Hibernate 5.2.X, the schema is added as a prefix to the given tablename:
Hibernate: alter table portal-appname.answer add column fake integer not null
This is not a valid sql command, obviously:
MySQL server version for the right syntax to use near '-appname.answer add column fake integer not null' at line 1
Hibernate should enclose portal-appname.table with backtips automatically as:
Hibernate: alter table `portal-appname`.`answer` add column fake integer not null
I've tried with hibernate.globally_quoted_identifiers but it only quotes column names but not the portal-appname.table pair.
Funny thing is that hibernate 5.2.X is only using that syntax with column names, but it's not prefixing the schema in other kind of alters such as:
Hibernate: alter table tablename add constraint FKftsiakun1f5qp01aabdw887kp foreign key (logo) references tablename2 (id)
Last but not least, I'm in moment where I'm able to rename my schema to other thing. Also, I can downgrade to hibernate 5.1.0 but I want to know why hibernate has introduced this behaviour and if there's something to avoid it.
Any help is much welcome.
To keep Hibernate 5.2+, you have to disable the shema qualifier in the dialect :
#Override
public NameQualifierSupport getNameQualifierSupport() {
return NameQualifierSupport.NONE;
}
Sample dialect there.
Also be sure to use a specific user able to see only the target database: do not use "root". Hibernate fetches all visible tables from all databases even if different from the one you specified.

How to delete when primary key contains two columns, and using safe mode

My table is created like this:
CREATE TABLE test(
num1 INT,
num2 INT,
PRIMARY KEY(num1, num2)
);
what should my delete query look like?
using
DELETE FROM test WHERE num1=1 AND num2=2;
only result in this error message:
Error Code: 1175. You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column To disable safe mode, toggle the option in Preferences -> SQL Editor and reconnect.
Also, before you ask, I do know how to turn safe update mode off, but that does not answer my question.
I've seen some other Stack Overflow posts where people complain that MySQL Workbench is blocking them from performing safe updates inappropriately.
But I just tried it with your table, both with the PK columns and with a non-key column. When safe mode is enabled, it blocks me from doing updates via non-key column, as it should. But I don't get the error you described.
I'm using MySQL Workbench 6.3.8 and MySQL Server 8.0.0-dmr.
Perhaps this is a bug in an old version of MySQL or an old version of MySQL Workbench.
Updated mysql and the error is gone.
what a waste of my time.

Symfony doctrine::build task cannot create table named order

I have a database with a table named order.
When i run php symfony doctrine:build --all, i got the folowing error:
SQLSTATE[42000]: Syntax error or
access violation: 1064 You have an
error in your SQL syntax; check the
manual that corresponds to your MySQL
server version for the right syntax to
use near 'order (id BIGINT
AUTO_INCREMENT, status VARCHAR(255),
colissimonumber VARCHAR(25' at line 1.
Failing Query: "CREATE TABLE order (id
BIGINT AUTO_INCREMENT, status
VARCHAR(255), colissimonumber
VARCHAR(255) NOT NULL, created_at
DATETIME NOT NULL, updated_at DATETIME
NOT NULL, PRIMARY KEY(id)) ENGINE =
MyISAM".
The problem is clearly that order has no backquotes arount it (if i run manually the query in phpmyadmin with backquotes, it works)
How do i tell doctrine to add backquotes around table and field names? Any workaround exept renaming my table ?
I run symfony 1.4.9 with doctrine 1.2
You can turn on Doctrine_Core::ATTR_QUOTE_IDENTIFIER in your doctrine configuration mthod on projectConfiguration which will quote tables and col names but its not recommended:
Just because you CAN use delimited
identifiers, it doesn't mean you
SHOULD use them. In general, they end
up causing way more problems than they
solve. Anyway, it may be necessary
when you have a reserved word as a
field name (in this case, we suggest
you to change it, if you can).
http://www.doctrine-project.org/projects/orm/1.2/docs/manual/configuration/en#identifier-quoting
You probably want your model to be named Order, but this doesn't mean that the corresponding RDBMS table must be named the same.
Order:
tableName: project_order
columns: ...
Got similar error when upgrading from MySQL 5.7 to MySQL 8.0. RANK() is a function added in MySQL 8.0 whereas one of the table in our database has rank as column name.
My Setup:
- Symfony 1.5
- Doctrine 1.2
- PHP 7.4.24
- MySQL 8.0.27
- Ubuntu 20.04.1
Here are three possible solutions.
Solution 1: Add quote_identifier: true in config/databases.yml file. Also, clear cache after change in configuration with php symfony cc or php symfony cache:clear.
all:
doctrine:
param:
attributes:
quote_identifier: true
Solution 2: Turn on Doctrine_Core::ATTR_QUOTE_IDENTIFIER in config/ProjectConfiguration.class.php file on configureDoctrine() method.
$conn = Doctrine_Manager::getInstance()->getCurrentConnection();
$conn->setAttribute(Doctrine_Core::ATTR_QUOTE_IDENTIFIER, true);
Solution 3: Turn on Doctrine_Core::ATTR_QUOTE_IDENTIFIER on specific table(s) which are potentially breaking the system.
$table = Doctrine_Core::getTable('table_name');
$table->setAttribute(Doctrine_Core::ATTR_QUOTE_IDENTIFIER, true);
Note: From Doctrine 1 docs
Just because you CAN use delimited identifiers, it doesn't mean you
SHOULD use them. In general, they end up causing way more problems
than they solve. Anyway, it may be necessary when you have a reserved
word as a field name (in this case, we suggest you to change it, if
you can).