spring-projects / spring-projects/spring-framework
`ScriptUtils` fails to correctly parse string literal ending with backslash with H2 database
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 60.2k
- Forks
- 38.8k
- Avg merge
- 5d 2h
- Merged PRs (30d)
- 27
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 '|'
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ScriptUtils.java at splitSQLScript, then reproduce the provided schema.sql and data.sql example with H2. Done means a quoted string ending in a backslash no longer causes the semicolon in the following quoted value to split the SQL statement incorrectly.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, spring, sql
- Domain
- backend, databases
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100