Skip to content

Commit 66092a2

Browse files
authored
Fix getMetaData error for queries containing TOP (#2287)
1 parent 9a3e471 commit 66092a2

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

src/main/java/com/microsoft/sqlserver/jdbc/SQLServerStatement.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,11 @@ public String toString() {
541541
/** Generate the statement's logging ID */
542542
private static final AtomicInteger lastStatementID = new AtomicInteger(0);
543543

544+
/*
545+
* T-SQL TOP syntax regex
546+
*/
547+
private final static Pattern TOP_SYNTAX = Pattern.compile("\\bTOP\\s*\\(\\s*\\?\\s*\\)", Pattern.CASE_INSENSITIVE);
548+
544549
private static int nextStatementID() {
545550
return lastStatementID.incrementAndGet();
546551
}
@@ -1098,6 +1103,11 @@ static String replaceParameterWithString(String str, char marker, String replace
10981103
* @return the result
10991104
*/
11001105
static String replaceMarkerWithNull(String sql) {
1106+
// replace all top(?) to top(1) as null is not valid
1107+
if (TOP_SYNTAX.matcher(sql).find()) {
1108+
sql = TOP_SYNTAX.matcher(sql).replaceAll("TOP(1)");
1109+
}
1110+
11011111
if (!sql.contains("'")) {
11021112
return replaceParameterWithString(sql, '?', "null");
11031113
} else {

src/test/java/com/microsoft/sqlserver/jdbc/fmtOnly/ParameterMetaDataTest.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import java.sql.Connection;
88
import java.sql.ParameterMetaData;
99
import java.sql.PreparedStatement;
10+
import java.sql.ResultSetMetaData;
1011
import java.sql.SQLException;
1112
import java.sql.Statement;
1213
import java.util.Arrays;
@@ -101,7 +102,7 @@ public void exceptionTest() throws SQLException {
101102
}
102103

103104
@Test
104-
public void tempTableTest() throws SQLException {
105+
public void getParameterMetaDataTest() throws SQLException {
105106
String tempTableName = "[#jdbc_temp" + UUID.randomUUID() + "]";
106107
try (Connection c = PrepUtil.getConnection(AbstractTest.connectionString + ";useFmtOnly=true;");
107108
Statement s = c.createStatement()) {
@@ -118,6 +119,29 @@ public void tempTableTest() throws SQLException {
118119
}
119120
}
120121

122+
/**
123+
* Tests sql containing TOP
124+
*
125+
* @throws SQLException
126+
*/
127+
@Test
128+
public void getMetaDataTest() throws SQLException {
129+
String tempTableName = "[#jdbc_temp" + UUID.randomUUID() + "]";
130+
try (Connection c = PrepUtil.getConnection(AbstractTest.connectionString + ";useFmtOnly=true;");
131+
Statement s = c.createStatement(); PreparedStatement p = c
132+
.prepareStatement("SELECT TOP(?) [c1] FROM " + tempTableName + " WHERE c1 = ?")) {
133+
TestUtils.dropTableIfExists(tempTableName, s);
134+
s.execute("CREATE TABLE " + tempTableName + " (c1 int)");
135+
136+
ResultSetMetaData rmd = p.getMetaData();
137+
assertTrue(rmd.getColumnCount() == 1);
138+
} finally {
139+
try (Statement s = connection.createStatement()) {
140+
TestUtils.dropTableIfExists(tempTableName, s);
141+
}
142+
}
143+
}
144+
121145
@Test
122146
public void viewTest() throws SQLException {
123147
String tempViewName = "[jdbc_view" + UUID.randomUUID() + "]";

0 commit comments

Comments
 (0)