Skip to content

Commit a236b69

Browse files
14218 - Add setObject to advice for java.sql.PreparedStatement (#14219)
Co-authored-by: Lauri Tulmin <[email protected]>
1 parent 62175ca commit a236b69

File tree

3 files changed

+96
-1
lines changed

3 files changed

+96
-1
lines changed

instrumentation/jdbc/javaagent/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ tasks {
104104

105105
tasks {
106106
withType<Test>().configureEach {
107+
systemProperty("testLatestDeps", findProperty("testLatestDeps") as Boolean)
107108
jvmArgs("-Dotel.instrumentation.jdbc.experimental.transaction.enabled=true")
108109
}
109110
}

instrumentation/jdbc/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jdbc/PreparedStatementInstrumentation.java

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ public void transform(TypeTransformer transformer) {
7777
"setTimestamp",
7878
"setURL",
7979
"setRowId",
80-
"setNString")
80+
"setNString",
81+
"setObject")
8182
.and(takesArgument(0, int.class))
8283
.and(takesArguments(2))
8384
.and(isPublic()),
@@ -89,6 +90,13 @@ public void transform(TypeTransformer transformer) {
8990
.and(takesArguments(3))
9091
.and(isPublic()),
9192
PreparedStatementInstrumentation.class.getName() + "$SetTimeParameter3Advice");
93+
transformer.applyAdviceToMethod(
94+
namedOneOf("setObject")
95+
.and(takesArgument(0, int.class))
96+
.and(takesArgument(2, int.class))
97+
.and(takesArguments(3))
98+
.and(isPublic()),
99+
PreparedStatementInstrumentation.class.getName() + "$SetParameter3Advice");
92100
transformer.applyAdviceToMethod(
93101
named("clearParameters").and(takesNoArguments()).and(isPublic()),
94102
PreparedStatementInstrumentation.class.getName() + "$ClearParametersAdvice");
@@ -192,6 +200,38 @@ public static void onExit(
192200
}
193201
}
194202

203+
@SuppressWarnings("unused")
204+
public static class SetParameter3Advice {
205+
@Advice.OnMethodExit(suppress = Throwable.class)
206+
public static void onExit(
207+
@Advice.This PreparedStatement statement,
208+
@Advice.Argument(0) int index,
209+
@Advice.Argument(1) Object value,
210+
@Advice.Argument(2) int targetSqlType) {
211+
if (!CAPTURE_QUERY_PARAMETERS) {
212+
return;
213+
}
214+
215+
String str = null;
216+
217+
if (value instanceof Boolean
218+
// Short, Int, Long, Float, Double, BigDecimal
219+
|| value instanceof Number
220+
|| value instanceof String
221+
|| value instanceof Date
222+
|| value instanceof Time
223+
|| value instanceof Timestamp
224+
|| value instanceof URL
225+
|| value instanceof RowId) {
226+
str = value.toString();
227+
}
228+
229+
if (str != null) {
230+
JdbcData.addParameter(statement, Integer.toString(index - 1), str);
231+
}
232+
}
233+
}
234+
195235
@SuppressWarnings("unused")
196236
public static class SetTimeParameter3Advice {
197237
@Advice.OnMethodExit(suppress = Throwable.class)

instrumentation/jdbc/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jdbc/test/PreparedStatementParametersTest.java

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import java.sql.SQLException;
3434
import java.sql.Time;
3535
import java.sql.Timestamp;
36+
import java.sql.Types;
3637
import java.util.Calendar;
3738
import java.util.Locale;
3839
import java.util.Map;
@@ -306,6 +307,59 @@ void testStringPreparedStatementParameter(
306307
"S");
307308
}
308309

310+
@ParameterizedTest
311+
@MethodSource("preparedStatementStream")
312+
void testObjectPreparedStatementParameter(
313+
String system,
314+
Connection connection,
315+
String username,
316+
String query,
317+
String sanitizedQuery,
318+
String spanName,
319+
String url,
320+
String table)
321+
throws SQLException {
322+
test(
323+
system,
324+
connection,
325+
username,
326+
query,
327+
sanitizedQuery,
328+
spanName,
329+
url,
330+
table,
331+
statement -> statement.setObject(1, "S"),
332+
"S");
333+
}
334+
335+
@ParameterizedTest
336+
@MethodSource("preparedStatementStream")
337+
void testObjectWithTypePreparedStatementParameter(
338+
String system,
339+
Connection connection,
340+
String username,
341+
String query,
342+
String sanitizedQuery,
343+
String spanName,
344+
String url,
345+
String table)
346+
throws SQLException {
347+
// we are using old database drivers that don't support the tested setObject method
348+
Assumptions.assumeTrue(Boolean.getBoolean("testLatestDeps"));
349+
350+
test(
351+
system,
352+
connection,
353+
username,
354+
query,
355+
sanitizedQuery,
356+
spanName,
357+
url,
358+
table,
359+
statement -> statement.setObject(1, "S", Types.CHAR),
360+
"S");
361+
}
362+
309363
@ParameterizedTest
310364
@MethodSource("preparedStatementStream")
311365
void testDate2PreparedStatementParameter(

0 commit comments

Comments
 (0)