From d86af57e0f4fef37d662c5fed1f774f05a8c685b Mon Sep 17 00:00:00 2001 From: Sam Brannen <104798+sbrannen@users.noreply.github.com> Date: Sat, 17 Feb 2024 16:00:58 +0100 Subject: [PATCH] Polishing --- .../core/namedparam/NamedParameterUtils.java | 8 +-- .../namedparam/NamedParameterUtilsTests.java | 26 ++++----- .../r2dbc/core/NamedParameterUtils.java | 10 ++-- .../r2dbc/core/NamedParameterUtilsTests.java | 54 ++++++++++--------- 4 files changed, 50 insertions(+), 48 deletions(-) diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/NamedParameterUtils.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/NamedParameterUtils.java index ef7a801906..8677dc1dc4 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/NamedParameterUtils.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/NamedParameterUtils.java @@ -42,14 +42,14 @@ import org.springframework.util.Assert; public abstract class NamedParameterUtils { /** - * Set of characters that qualify as comment or quotes starting characters. + * Set of characters that qualify as comment or quote starting characters. */ - private static final String[] START_SKIP = new String[] {"'", "\"", "--", "/*", "`"}; + private static final String[] START_SKIP = {"'", "\"", "--", "/*", "`"}; /** - * Set of characters that at are the corresponding comment or quotes ending characters. + * Set of characters that are the corresponding comment or quote ending characters. */ - private static final String[] STOP_SKIP = new String[] {"'", "\"", "\n", "*/", "`"}; + private static final String[] STOP_SKIP = {"'", "\"", "\n", "*/", "`"}; /** * Set of characters that qualify as parameter separators, diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/core/namedparam/NamedParameterUtilsTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/core/namedparam/NamedParameterUtilsTests.java index f020350a26..ec80265bed 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/core/namedparam/NamedParameterUtilsTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/core/namedparam/NamedParameterUtilsTests.java @@ -153,7 +153,7 @@ class NamedParameterUtilsTests { } @Test // SPR-4789 - public void parseSqlContainingComments() { + void parseSqlContainingComments() { String sql1 = "/*+ HINT */ xxx /* comment ? */ :a yyyy :b :c :a zzzzz -- :xx XX\n"; ParsedSql parsedSql1 = NamedParameterUtils.parseSqlStatement(sql1); assertThat(NamedParameterUtils.substituteNamedParameters(parsedSql1, null)).isEqualTo("/*+ HINT */ xxx /* comment ? */ ? yyyy ? ? ? zzzzz -- :xx XX\n"); @@ -179,7 +179,7 @@ class NamedParameterUtilsTests { } @Test // SPR-4612 - public void parseSqlStatementWithPostgresCasting() { + void parseSqlStatementWithPostgresCasting() { String expectedSql = "select 'first name' from artists where id = ? and birth_date=?::timestamp"; String sql = "select 'first name' from artists where id = :id and birth_date=:birthDate::timestamp"; ParsedSql parsedSql = NamedParameterUtils.parseSqlStatement(sql); @@ -187,7 +187,7 @@ class NamedParameterUtilsTests { } @Test // SPR-13582 - public void parseSqlStatementWithPostgresContainedOperator() { + void parseSqlStatementWithPostgresContainedOperator() { String expectedSql = "select 'first name' from artists where info->'stat'->'albums' = ?? ? and '[\"1\",\"2\",\"3\"]'::jsonb ?? '4'"; String sql = "select 'first name' from artists where info->'stat'->'albums' = ?? :album and '[\"1\",\"2\",\"3\"]'::jsonb ?? '4'"; ParsedSql parsedSql = NamedParameterUtils.parseSqlStatement(sql); @@ -196,7 +196,7 @@ class NamedParameterUtilsTests { } @Test // SPR-15382 - public void parseSqlStatementWithPostgresAnyArrayStringsExistsOperator() { + void parseSqlStatementWithPostgresAnyArrayStringsExistsOperator() { String expectedSql = "select '[\"3\", \"11\"]'::jsonb ?| '{1,3,11,12,17}'::text[]"; String sql = "select '[\"3\", \"11\"]'::jsonb ?| '{1,3,11,12,17}'::text[]"; @@ -206,7 +206,7 @@ class NamedParameterUtilsTests { } @Test // SPR-15382 - public void parseSqlStatementWithPostgresAllArrayStringsExistsOperator() { + void parseSqlStatementWithPostgresAllArrayStringsExistsOperator() { String expectedSql = "select '[\"3\", \"11\"]'::jsonb ?& '{1,3,11,12,17}'::text[] AND ? = 'Back in Black'"; String sql = "select '[\"3\", \"11\"]'::jsonb ?& '{1,3,11,12,17}'::text[] AND :album = 'Back in Black'"; @@ -216,7 +216,7 @@ class NamedParameterUtilsTests { } @Test // SPR-7476 - public void parseSqlStatementWithEscapedColon() { + void parseSqlStatementWithEscapedColon() { String expectedSql = "select '0\\:0' as a, foo from bar where baz < DATE(? 23:59:59) and baz = ?"; String sql = "select '0\\:0' as a, foo from bar where baz < DATE(:p1 23\\:59\\:59) and baz = :p2"; @@ -227,7 +227,7 @@ class NamedParameterUtilsTests { } @Test // SPR-7476 - public void parseSqlStatementWithBracketDelimitedParameterNames() { + void parseSqlStatementWithBracketDelimitedParameterNames() { String expectedSql = "select foo from bar where baz = b??z"; String sql = "select foo from bar where baz = b:{p1}:{p2}z"; @@ -238,7 +238,7 @@ class NamedParameterUtilsTests { } @Test // SPR-7476 - public void parseSqlStatementWithEmptyBracketsOrBracketsInQuotes() { + void parseSqlStatementWithEmptyBracketsOrBracketsInQuotes() { String expectedSql = "select foo from bar where baz = b:{}z"; String sql = "select foo from bar where baz = b:{}z"; ParsedSql parsedSql = NamedParameterUtils.parseSqlStatement(sql); @@ -267,21 +267,21 @@ class NamedParameterUtilsTests { } @Test // SPR-2544 - public void parseSqlStatementWithLogicalAnd() { + void parseSqlStatementWithLogicalAnd() { String expectedSql = "xxx & yyyy"; ParsedSql parsedSql = NamedParameterUtils.parseSqlStatement(expectedSql); assertThat(substituteNamedParameters(parsedSql)).isEqualTo(expectedSql); } @Test // SPR-2544 - public void substituteNamedParametersWithLogicalAnd() { + void substituteNamedParametersWithLogicalAnd() { String expectedSql = "xxx & yyyy"; String newSql = NamedParameterUtils.substituteNamedParameters(expectedSql, new MapSqlParameterSource()); assertThat(newSql).isEqualTo(expectedSql); } @Test // SPR-3173 - public void variableAssignmentOperator() { + void variableAssignmentOperator() { String expectedSql = "x := 1"; String newSql = NamedParameterUtils.substituteNamedParameters(expectedSql, new MapSqlParameterSource()); assertThat(newSql).isEqualTo(expectedSql); @@ -295,14 +295,14 @@ class NamedParameterUtilsTests { "SELECT \":foo\"\":doo\", :xxx FROM DUAL", "SELECT `:foo``:doo`, :xxx FROM DUAL" }) - void parseSqlStatementWithParametersInsideQuote(String sql) { + void parseSqlStatementWithParametersInsideQuotesAndComments(String sql) { ParsedSql parsedSql = NamedParameterUtils.parseSqlStatement(sql); assertThat(parsedSql.getTotalParameterCount()).isEqualTo(1); assertThat(parsedSql.getParameterNames()).containsExactly("xxx"); } @Test // gh-27716 - public void parseSqlStatementWithSquareBracket() { + void parseSqlStatementWithSquareBracket() { String sql = "SELECT ARRAY[:ext]"; ParsedSql parsedSql = NamedParameterUtils.parseSqlStatement(sql); assertThat(parsedSql.getNamedParameterCount()).isEqualTo(1); diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/NamedParameterUtils.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/NamedParameterUtils.java index 306de12f87..dc6717f591 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/NamedParameterUtils.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/NamedParameterUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,14 +54,14 @@ import org.springframework.util.Assert; abstract class NamedParameterUtils { /** - * Set of characters that qualify as comment or quotes starting characters. + * Set of characters that qualify as comment or quote starting characters. */ - private static final String[] START_SKIP = new String[] {"'", "\"", "--", "/*"}; + private static final String[] START_SKIP = {"'", "\"", "--", "/*"}; /** - * Set of characters that at are the corresponding comment or quotes ending characters. + * Set of characters that are the corresponding comment or quote ending characters. */ - private static final String[] STOP_SKIP = new String[] {"'", "\"", "\n", "*/"}; + private static final String[] STOP_SKIP = {"'", "\"", "\n", "*/"}; /** * Set of characters that qualify as parameter separators, diff --git a/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/NamedParameterUtilsTests.java b/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/NamedParameterUtilsTests.java index 139291ce91..e0c224292a 100644 --- a/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/NamedParameterUtilsTests.java +++ b/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/NamedParameterUtilsTests.java @@ -24,6 +24,8 @@ import java.util.Map; import io.r2dbc.spi.Parameters; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import org.springframework.r2dbc.core.binding.BindMarkersFactory; import org.springframework.r2dbc.core.binding.BindTarget; @@ -243,40 +245,40 @@ class NamedParameterUtilsTests { assertThat(expand(expectedSql)).isEqualTo(expectedSql); } - @Test - void parseSqlStatementWithQuotedSingleQuote() { - String sql = "SELECT ':foo'':doo', :xxx FROM DUAL"; - - ParsedSql psql = NamedParameterUtils.parseSqlStatement(sql); - assertThat(psql.getTotalParameterCount()).isEqualTo(1); - assertThat(psql.getParameterNames()).containsExactly("xxx"); - } - - @Test - void parseSqlStatementWithQuotesAndCommentBefore() { - String sql = "SELECT /*:doo*/':foo', :xxx FROM DUAL"; - - ParsedSql psql = NamedParameterUtils.parseSqlStatement(sql); - assertThat(psql.getTotalParameterCount()).isEqualTo(1); - assertThat(psql.getParameterNames()).containsExactly("xxx"); - } - - @Test - void parseSqlStatementWithQuotesAndCommentAfter() { - String sql2 = "SELECT ':foo'/*:doo*/, :xxx FROM DUAL"; - - ParsedSql psql2 = NamedParameterUtils.parseSqlStatement(sql2); - assertThat(psql2.getTotalParameterCount()).isEqualTo(1); - assertThat(psql2.getParameterNames()).containsExactly("xxx"); + @ParameterizedTest // SPR-8280 and others + @ValueSource(strings = { + "SELECT ':foo'':doo', :xxx FROM DUAL", + "SELECT /*:doo*/':foo', :xxx FROM DUAL", + "SELECT ':foo'/*:doo*/, :xxx FROM DUAL", + "SELECT \":foo\"\":doo\", :xxx FROM DUAL", + }) + void parseSqlStatementWithParametersInsideQuotesAndComments(String sql) { + ParsedSql parsedSql = NamedParameterUtils.parseSqlStatement(sql); + assertThat(parsedSql.getTotalParameterCount()).isEqualTo(1); + assertThat(parsedSql.getParameterNames()).containsExactly("xxx"); } @Test // gh-27716 - public void parseSqlStatementWithSquareBracket() { + void parseSqlStatementWithSquareBracket() { String sql = "SELECT ARRAY[:ext]"; ParsedSql psql = NamedParameterUtils.parseSqlStatement(sql); assertThat(psql.getNamedParameterCount()).isEqualTo(1); assertThat(psql.getParameterNames()).containsExactly("ext"); + + assertThat(expand(psql)).isEqualTo("SELECT ARRAY[$1]"); + } + + @Test // gh-31596 + void paramNameWithNestedSquareBrackets() { + String sql = "insert into GeneratedAlways (id, first_name, last_name) values " + + "(:records[0].id, :records[0].firstName, :records[0].lastName), " + + "(:records[1].id, :records[1].firstName, :records[1].lastName)"; + + ParsedSql parsedSql = NamedParameterUtils.parseSqlStatement(sql); + assertThat(parsedSql.getParameterNames()).containsOnly( + "records[0].id", "records[0].firstName", "records[0].lastName", + "records[1].id", "records[1].firstName", "records[1].lastName"); } @Test // gh-27925