spring-projects / spring-projects/spring-framework

`ScriptUtils` fails to correctly parse string literal ending with backslash with H2 database

Open
#30,098 7 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

in: data status: pending-design-work type: enhancement
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.