Description
It looks like inserting a row which has a string with a backslash at the end causes Spring's splitting of SQL files into statements to behave erratically.
Minimal example.
Setup : Spring Boot test suite with schema.sql
and data.sql
given below :
schema.sql
CREATE SCHEMA IF NOT EXISTS TEST;
CREATE TABLE TEST.ONE (
IDENTIFIER BIGINT AUTO_INCREMENT PRIMARY KEY,
NAME VARCHAR(500)
);
CREATE TABLE TEST.TWO (
IDENTIFIER BIGINT AUTO_INCREMENT PRIMARY KEY,
NAME VARCHAR(500)
);
data.sql
INSERT INTO TEST.ONE(IDENTIFIER,NAME) VALUES
(1,'\1\3\');
INSERT INTO TEST.TWO(IDENTIFIER,NAME) VALUES
(1,'test;test');
This fails at my end because Spring splits the second inserted row around the semicolon inside 'test;test'
.
The cause is Spring's ScriptUtils
class in its splitSQLScript method. It's a method that splits the data.sql
script into queries with the semicolon as the default delimiter. Whilst scanning the script, it keeps track of whether or not it's within a statement surrounded by single or double quotes. When it encounters a backslash, it enters a sort of escape mode. The character after this backslash as well as the backslash itself are left as-is, but if the character after the backslash is a single or double quote it's effectively treated as if that quote were to be escaped.
Since I'm using the H2 driver I could fix it via unicode formatting (I wasn't able to make this work with just U&'\1\005c'
) :
U&'\1|005c' UESCAPE '|'