Consistent support for square brackets around named parameter
See gh-27716
This commit is contained in:
parent
86eda279c8
commit
64b6beed5b
|
|
@ -55,7 +55,7 @@ public abstract class NamedParameterUtils {
|
|||
* Set of characters that qualify as parameter separators,
|
||||
* indicating that a parameter name in an SQL String has ended.
|
||||
*/
|
||||
private static final String PARAMETER_SEPARATORS = "\"':&,;()|=+-*%/\\<>^";
|
||||
private static final String PARAMETER_SEPARATORS = "\"':&,;()|=+-*%/\\<>^[]";
|
||||
|
||||
/**
|
||||
* An index with separator flags per character code.
|
||||
|
|
|
|||
|
|
@ -319,4 +319,12 @@ public class NamedParameterUtilsTests {
|
|||
assertThat(psql2.getParameterNames().get(0)).isEqualTo("xxx");
|
||||
}
|
||||
|
||||
@Test // gh-27716
|
||||
public void parseSqlStatementWithSquareBracket() {
|
||||
String sql = "SELECT ARRAY[:ext]";
|
||||
ParsedSql psql = NamedParameterUtils.parseSqlStatement(sql);
|
||||
assertThat(psql.getNamedParameterCount()).isEqualTo(1);
|
||||
assertThat(psql.getParameterNames()).containsExactly("ext");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
|
|
@ -37,8 +37,7 @@ import org.springframework.util.Assert;
|
|||
/**
|
||||
* Helper methods for named parameter parsing.
|
||||
*
|
||||
* <p>Only intended for internal use within Spring's R2DBC
|
||||
* framework.
|
||||
* <p>Only intended for internal use within Spring's R2DBC framework.
|
||||
*
|
||||
* <p>References to the same parameter name are substituted with
|
||||
* the same bind marker placeholder if a {@link BindMarkersFactory} uses
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
|
|
@ -44,6 +44,7 @@ public class NamedParameterUtilsUnitTests {
|
|||
|
||||
private final BindMarkersFactory BIND_MARKERS = BindMarkersFactory.indexed("$", 1);
|
||||
|
||||
|
||||
@Test
|
||||
public void shouldParseSql() {
|
||||
String sql = "xxx :a yyyy :b :c :a zzzzz";
|
||||
|
|
@ -146,7 +147,6 @@ public class NamedParameterUtilsUnitTests {
|
|||
String sql = "select 'first name' from artists where info->'stat'->'albums' = ?? :album and '[\"1\",\"2\",\"3\"]'::jsonb ?? '4'";
|
||||
|
||||
ParsedSql parsedSql = NamedParameterUtils.parseSqlStatement(sql);
|
||||
|
||||
assertThat(parsedSql.getTotalParameterCount()).isEqualTo(1);
|
||||
assertThat(expand(parsedSql)).isEqualTo(expectedSql);
|
||||
}
|
||||
|
|
@ -157,7 +157,6 @@ public class NamedParameterUtilsUnitTests {
|
|||
String sql = "select '[\"3\", \"11\"]'::jsonb ?| '{1,3,11,12,17}'::text[]";
|
||||
|
||||
ParsedSql parsedSql = NamedParameterUtils.parseSqlStatement(sql);
|
||||
|
||||
assertThat(parsedSql.getTotalParameterCount()).isEqualTo(0);
|
||||
assertThat(expand(parsedSql)).isEqualTo(expectedSql);
|
||||
}
|
||||
|
|
@ -178,7 +177,6 @@ public class NamedParameterUtilsUnitTests {
|
|||
String sql = "select '0\\:0' as a, foo from bar where baz < DATE(:p1 23\\:59\\:59) and baz = :p2";
|
||||
|
||||
ParsedSql parsedSql = NamedParameterUtils.parseSqlStatement(sql);
|
||||
|
||||
assertThat(parsedSql.getParameterNames()).containsExactly("p1", "p2");
|
||||
assertThat(expand(parsedSql)).isEqualTo(expectedSql);
|
||||
}
|
||||
|
|
@ -199,7 +197,6 @@ public class NamedParameterUtilsUnitTests {
|
|||
String sql = "select foo from bar where baz = b:{}z";
|
||||
|
||||
ParsedSql parsedSql = NamedParameterUtils.parseSqlStatement(sql);
|
||||
|
||||
assertThat(parsedSql.getParameterNames()).isEmpty();
|
||||
assertThat(expand(parsedSql)).isEqualTo(expectedSql);
|
||||
|
||||
|
|
@ -226,13 +223,11 @@ public class NamedParameterUtilsUnitTests {
|
|||
String expectedSql = "xxx & yyyy";
|
||||
|
||||
ParsedSql parsedSql = NamedParameterUtils.parseSqlStatement(expectedSql);
|
||||
|
||||
assertThat(expand(parsedSql)).isEqualTo(expectedSql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void substituteNamedParametersWithLogicalAnd() {
|
||||
|
||||
String expectedSql = "xxx & yyyy";
|
||||
|
||||
assertThat(expand(expectedSql)).isEqualTo(expectedSql);
|
||||
|
|
@ -250,7 +245,6 @@ public class NamedParameterUtilsUnitTests {
|
|||
String sql = "SELECT ':foo'':doo', :xxx FROM DUAL";
|
||||
|
||||
ParsedSql psql = NamedParameterUtils.parseSqlStatement(sql);
|
||||
|
||||
assertThat(psql.getTotalParameterCount()).isEqualTo(1);
|
||||
assertThat(psql.getParameterNames()).containsExactly("xxx");
|
||||
}
|
||||
|
|
@ -260,7 +254,6 @@ public class NamedParameterUtilsUnitTests {
|
|||
String sql = "SELECT /*:doo*/':foo', :xxx FROM DUAL";
|
||||
|
||||
ParsedSql psql = NamedParameterUtils.parseSqlStatement(sql);
|
||||
|
||||
assertThat(psql.getTotalParameterCount()).isEqualTo(1);
|
||||
assertThat(psql.getParameterNames()).containsExactly("xxx");
|
||||
}
|
||||
|
|
@ -270,30 +263,24 @@ public class NamedParameterUtilsUnitTests {
|
|||
String sql2 = "SELECT ':foo'/*:doo*/, :xxx FROM DUAL";
|
||||
|
||||
ParsedSql psql2 = NamedParameterUtils.parseSqlStatement(sql2);
|
||||
|
||||
assertThat(psql2.getTotalParameterCount()).isEqualTo(1);
|
||||
assertThat(psql2.getParameterNames()).containsExactly("xxx");
|
||||
}
|
||||
|
||||
@Test public void parseSqlStatementWithSquareBracket() {
|
||||
// given
|
||||
@Test // gh-27716
|
||||
public void parseSqlStatementWithSquareBracket() {
|
||||
String sql = "SELECT ARRAY[:ext]";
|
||||
|
||||
// when
|
||||
ParsedSql psql = NamedParameterUtils.parseSqlStatement(sql);
|
||||
|
||||
//then
|
||||
assertThat(psql.getNamedParameterCount()).isEqualTo(1);
|
||||
assertThat(psql.getParameterNames()).containsExactly("ext");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldAllowParsingMultipleUseOfParameter() {
|
||||
|
||||
String sql = "SELECT * FROM person where name = :id or lastname = :id";
|
||||
|
||||
ParsedSql parsed = NamedParameterUtils.parseSqlStatement(sql);
|
||||
|
||||
assertThat(parsed.getTotalParameterCount()).isEqualTo(2);
|
||||
assertThat(parsed.getNamedParameterCount()).isEqualTo(1);
|
||||
assertThat(parsed.getParameterNames()).containsExactly("id", "id");
|
||||
|
|
@ -313,23 +300,19 @@ public class NamedParameterUtilsUnitTests {
|
|||
"SELECT * FROM person where name = $0 or lastname = $0");
|
||||
|
||||
operation.bindTo(new BindTarget() {
|
||||
|
||||
@Override
|
||||
public void bind(String identifier, Object value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(int index, Object value) {
|
||||
assertThat(index).isEqualTo(0);
|
||||
assertThat(value).isEqualTo("foo");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindNull(String identifier, Class<?> type) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindNull(int index, Class<?> type) {
|
||||
throw new UnsupportedOperationException();
|
||||
|
|
@ -353,25 +336,20 @@ public class NamedParameterUtilsUnitTests {
|
|||
"SELECT * FROM person where name IN ($0, $1, $2) or lastname IN ($0, $1, $2)");
|
||||
|
||||
operation.bindTo(new BindTarget() {
|
||||
|
||||
@Override
|
||||
public void bind(String identifier, Object value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(int index, Object value) {
|
||||
assertThat(index).isIn(0, 1, 2);
|
||||
assertThat(value).isIn("foo", "bar", "baz");
|
||||
|
||||
bindings.add(index, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindNull(String identifier, Class<?> type) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindNull(int index, Class<?> type) {
|
||||
throw new UnsupportedOperationException();
|
||||
|
|
@ -399,22 +377,18 @@ public class NamedParameterUtilsUnitTests {
|
|||
Map<Integer, Object> bindValues = new LinkedHashMap<>();
|
||||
|
||||
operation.bindTo(new BindTarget() {
|
||||
|
||||
@Override
|
||||
public void bind(String identifier, Object value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(int index, Object value) {
|
||||
bindValues.put(index, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindNull(String identifier, Class<?> type) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindNull(int index, Class<?> type) {
|
||||
throw new UnsupportedOperationException();
|
||||
|
|
@ -438,22 +412,18 @@ public class NamedParameterUtilsUnitTests {
|
|||
"SELECT * FROM person where name = $0 or lastname = $0");
|
||||
|
||||
operation.bindTo(new BindTarget() {
|
||||
|
||||
@Override
|
||||
public void bind(String identifier, Object value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(int index, Object value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindNull(String identifier, Class<?> type) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindNull(int index, Class<?> type) {
|
||||
assertThat(index).isEqualTo(0);
|
||||
|
|
@ -462,6 +432,7 @@ public class NamedParameterUtilsUnitTests {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
private String expand(ParsedSql sql) {
|
||||
return NamedParameterUtils.substituteNamedParameters(sql, BIND_MARKERS,
|
||||
new MapBindParameterSource()).toQuery();
|
||||
|
|
|
|||
Loading…
Reference in New Issue