Skip to content

Commit df83eaa

Browse files
authored
Fix missing db.operation for CREATE/DROP/ALTER SQL statement (#10020)
1 parent 0029332 commit df83eaa

File tree

7 files changed

+204
-70
lines changed

7 files changed

+204
-70
lines changed

instrumentation-api-incubator/src/main/jflex/SqlSanitizer.jflex

Lines changed: 91 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,13 +128,56 @@ WHITESPACE = [ \t\r\n]+
128128
/** @return true if all statement info is gathered */
129129
boolean handleNext() {
130130
return false;
131-
}
131+
}
132+
133+
/** @return true if all statement info is gathered */
134+
boolean handleOperationTarget(String target) {
135+
return false;
136+
}
137+
138+
boolean expectingOperationTarget() {
139+
return false;
140+
}
132141

133142
SqlStatementInfo getResult(String fullStatement) {
134143
return SqlStatementInfo.create(fullStatement, getClass().getSimpleName().toUpperCase(java.util.Locale.ROOT), mainIdentifier);
135144
}
136145
}
137146

147+
private abstract class DdlOperation extends Operation {
148+
private String operationTarget = "";
149+
private boolean expectingOperationTarget = true;
150+
151+
boolean expectingOperationTarget() {
152+
return expectingOperationTarget;
153+
}
154+
155+
boolean handleOperationTarget(String target) {
156+
operationTarget = target;
157+
expectingOperationTarget = false;
158+
return false;
159+
}
160+
161+
boolean shouldHandleIdentifier() {
162+
// Return true only if the provided value corresponds to a table, as it will be used to set the attribute `db.sql.table`.
163+
return "TABLE".equals(operationTarget);
164+
}
165+
166+
boolean handleIdentifier() {
167+
if (shouldHandleIdentifier()) {
168+
mainIdentifier = readIdentifierName();
169+
}
170+
return true;
171+
}
172+
173+
SqlStatementInfo getResult(String fullStatement) {
174+
if (!"".equals(operationTarget)) {
175+
return SqlStatementInfo.create(fullStatement, getClass().getSimpleName().toUpperCase(java.util.Locale.ROOT) + " " + operationTarget, mainIdentifier);
176+
}
177+
return super.getResult(fullStatement);
178+
}
179+
}
180+
138181
private static class NoOp extends Operation {
139182
static final Operation INSTANCE = new NoOp();
140183

@@ -279,6 +322,15 @@ WHITESPACE = [ \t\r\n]+
279322
}
280323
}
281324

325+
private class Create extends DdlOperation {
326+
}
327+
328+
private class Drop extends DdlOperation {
329+
}
330+
331+
private class Alter extends DdlOperation {
332+
}
333+
282334
private SqlStatementInfo getResult() {
283335
if (builder.length() > LIMIT) {
284336
builder.delete(LIMIT, builder.length());
@@ -339,6 +391,27 @@ WHITESPACE = [ \t\r\n]+
339391
appendCurrentFragment();
340392
if (isOverLimit()) return YYEOF;
341393
}
394+
"CREATE" {
395+
if (!insideComment) {
396+
setOperation(new Create());
397+
}
398+
appendCurrentFragment();
399+
if (isOverLimit()) return YYEOF;
400+
}
401+
"DROP" {
402+
if (!insideComment) {
403+
setOperation(new Drop());
404+
}
405+
appendCurrentFragment();
406+
if (isOverLimit()) return YYEOF;
407+
}
408+
"ALTER" {
409+
if (!insideComment) {
410+
setOperation(new Alter());
411+
}
412+
appendCurrentFragment();
413+
if (isOverLimit()) return YYEOF;
414+
}
342415
"FROM" {
343416
if (!insideComment && !extractionDone) {
344417
if (operation == NoOp.INSTANCE) {
@@ -367,11 +440,27 @@ WHITESPACE = [ \t\r\n]+
367440
}
368441
"NEXT" {
369442
if (!insideComment && !extractionDone) {
370-
extractionDone = operation.handleNext();
443+
extractionDone = operation.handleNext();
444+
}
445+
appendCurrentFragment();
446+
if (isOverLimit()) return YYEOF;
447+
}
448+
"IF" | "NOT" | "EXISTS" {
449+
appendCurrentFragment();
450+
if (isOverLimit()) return YYEOF;
451+
}
452+
"TABLE" | "INDEX" | "DATABASE" | "PROCEDURE" | "VIEW" {
453+
if (!insideComment && !extractionDone) {
454+
if (operation.expectingOperationTarget()) {
455+
extractionDone = operation.handleOperationTarget(yytext());
456+
} else {
457+
extractionDone = operation.handleIdentifier();
371458
}
459+
}
372460
appendCurrentFragment();
373461
if (isOverLimit()) return YYEOF;
374462
}
463+
375464
{COMMA} {
376465
if (!insideComment && !extractionDone) {
377466
extractionDone = operation.handleComma();

instrumentation-api-incubator/src/test/java/io/opentelemetry/instrumentation/api/incubator/semconv/db/SqlStatementSanitizerTest.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,17 @@ void veryLongSelectStatementsAreOk() {
6060
assertThat(result).isEqualTo(expected);
6161
}
6262

63+
@ParameterizedTest
64+
@ArgumentsSource(DdlArgs.class)
65+
void checkDdlOperationStatementsAreOk(
66+
String actual, Function<String, SqlStatementInfo> expectFunc) {
67+
SqlStatementInfo result = SqlStatementSanitizer.create(true).sanitize(actual);
68+
SqlStatementInfo expected = expectFunc.apply(actual);
69+
assertThat(result.getFullStatement()).isEqualTo(expected.getFullStatement());
70+
assertThat(result.getOperation()).isEqualTo(expected.getOperation());
71+
assertThat(result.getMainIdentifier()).isEqualTo(expected.getMainIdentifier());
72+
}
73+
6374
@Test
6475
void lotsOfTicksDontCauseStackOverflowOrLongRuntimes() {
6576
String s = "'";
@@ -357,4 +368,34 @@ public Stream<? extends Arguments> provideArguments(ExtensionContext context) th
357368
Arguments.of(null, expect(null, null)));
358369
}
359370
}
371+
372+
static class DdlArgs implements ArgumentsProvider {
373+
374+
static Function<String, SqlStatementInfo> expect(String operation, String identifier) {
375+
return sql -> SqlStatementInfo.create(sql, operation, identifier);
376+
}
377+
378+
static Function<String, SqlStatementInfo> expect(
379+
String sql, String operation, String identifier) {
380+
return ignored -> SqlStatementInfo.create(sql, operation, identifier);
381+
}
382+
383+
@Override
384+
public Stream<? extends Arguments> provideArguments(ExtensionContext context) throws Exception {
385+
return Stream.of(
386+
Arguments.of("CREATE TABLE `table`", expect("CREATE TABLE", "table")),
387+
Arguments.of("CREATE TABLE IF NOT EXISTS table", expect("CREATE TABLE", "table")),
388+
Arguments.of("DROP TABLE `if`", expect("DROP TABLE", "if")),
389+
Arguments.of(
390+
"ALTER TABLE table ADD CONSTRAINT c FOREIGN KEY (foreign_id) REFERENCES ref (id)",
391+
expect("ALTER TABLE", "table")),
392+
Arguments.of("CREATE INDEX types_name ON types (name)", expect("CREATE INDEX", null)),
393+
Arguments.of("DROP INDEX types_name ON types (name)", expect("DROP INDEX", null)),
394+
Arguments.of(
395+
"CREATE VIEW tmp AS SELECT type FROM table WHERE id = ?",
396+
expect("CREATE VIEW", null)),
397+
Arguments.of(
398+
"CREATE PROCEDURE p AS SELECT * FROM table GO", expect("CREATE PROCEDURE", null)));
399+
}
400+
}
360401
}

instrumentation/cassandra/cassandra-3.0/javaagent/src/test/java/CassandraClientTest.java

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -225,8 +225,8 @@ private static Stream<Arguments> provideSyncParameters() {
225225
null,
226226
"DROP KEYSPACE IF EXISTS sync_test",
227227
"DROP KEYSPACE IF EXISTS sync_test",
228-
"DB Query",
229-
null,
228+
"DROP",
229+
"DROP",
230230
null))),
231231
Arguments.of(
232232
named(
@@ -235,8 +235,8 @@ private static Stream<Arguments> provideSyncParameters() {
235235
null,
236236
"CREATE KEYSPACE sync_test WITH REPLICATION = {'class':'SimpleStrategy', 'replication_factor':3}",
237237
"CREATE KEYSPACE sync_test WITH REPLICATION = {?:?, ?:?}",
238-
"DB Query",
239-
null,
238+
"CREATE",
239+
"CREATE",
240240
null))),
241241
Arguments.of(
242242
named(
@@ -245,9 +245,9 @@ private static Stream<Arguments> provideSyncParameters() {
245245
"sync_test",
246246
"CREATE TABLE sync_test.users ( id UUID PRIMARY KEY, name text )",
247247
"CREATE TABLE sync_test.users ( id UUID PRIMARY KEY, name text )",
248-
"sync_test",
249-
null,
250-
null))),
248+
"CREATE TABLE sync_test.users",
249+
"CREATE TABLE",
250+
"sync_test.users"))),
251251
Arguments.of(
252252
named(
253253
"Insert data",
@@ -279,8 +279,8 @@ private static Stream<Arguments> provideAsyncParameters() {
279279
null,
280280
"DROP KEYSPACE IF EXISTS async_test",
281281
"DROP KEYSPACE IF EXISTS async_test",
282-
"DB Query",
283-
null,
282+
"DROP",
283+
"DROP",
284284
null))),
285285
Arguments.of(
286286
named(
@@ -289,8 +289,8 @@ private static Stream<Arguments> provideAsyncParameters() {
289289
null,
290290
"CREATE KEYSPACE async_test WITH REPLICATION = {'class':'SimpleStrategy', 'replication_factor':3}",
291291
"CREATE KEYSPACE async_test WITH REPLICATION = {?:?, ?:?}",
292-
"DB Query",
293-
null,
292+
"CREATE",
293+
"CREATE",
294294
null))),
295295
Arguments.of(
296296
named(
@@ -299,9 +299,9 @@ private static Stream<Arguments> provideAsyncParameters() {
299299
"async_test",
300300
"CREATE TABLE async_test.users ( id UUID PRIMARY KEY, name text )",
301301
"CREATE TABLE async_test.users ( id UUID PRIMARY KEY, name text )",
302-
"async_test",
303-
null,
304-
null))),
302+
"CREATE TABLE async_test.users",
303+
"CREATE TABLE",
304+
"async_test.users"))),
305305
Arguments.of(
306306
named(
307307
"Insert data",

instrumentation/cassandra/cassandra-4-common/testing/src/main/java/io/opentelemetry/cassandra/v4/common/AbstractCassandraTest.java

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,8 @@ private static Stream<Arguments> provideSyncParameters() {
200200
null,
201201
"DROP KEYSPACE IF EXISTS sync_test",
202202
"DROP KEYSPACE IF EXISTS sync_test",
203-
"DB Query",
204-
null,
203+
"DROP",
204+
"DROP",
205205
null))),
206206
Arguments.of(
207207
named(
@@ -210,8 +210,8 @@ private static Stream<Arguments> provideSyncParameters() {
210210
null,
211211
"CREATE KEYSPACE sync_test WITH REPLICATION = {'class':'SimpleStrategy', 'replication_factor':3}",
212212
"CREATE KEYSPACE sync_test WITH REPLICATION = {?:?, ?:?}",
213-
"DB Query",
214-
null,
213+
"CREATE",
214+
"CREATE",
215215
null))),
216216
Arguments.of(
217217
named(
@@ -220,9 +220,9 @@ private static Stream<Arguments> provideSyncParameters() {
220220
"sync_test",
221221
"CREATE TABLE sync_test.users ( id UUID PRIMARY KEY, name text )",
222222
"CREATE TABLE sync_test.users ( id UUID PRIMARY KEY, name text )",
223-
"sync_test",
224-
null,
225-
null))),
223+
"CREATE TABLE sync_test.users",
224+
"CREATE TABLE",
225+
"sync_test.users"))),
226226
Arguments.of(
227227
named(
228228
"Insert data",
@@ -254,8 +254,8 @@ private static Stream<Arguments> provideAsyncParameters() {
254254
null,
255255
"DROP KEYSPACE IF EXISTS async_test",
256256
"DROP KEYSPACE IF EXISTS async_test",
257-
"DB Query",
258-
null,
257+
"DROP",
258+
"DROP",
259259
null))),
260260
Arguments.of(
261261
named(
@@ -264,8 +264,8 @@ private static Stream<Arguments> provideAsyncParameters() {
264264
null,
265265
"CREATE KEYSPACE async_test WITH REPLICATION = {'class':'SimpleStrategy', 'replication_factor':3}",
266266
"CREATE KEYSPACE async_test WITH REPLICATION = {?:?, ?:?}",
267-
"DB Query",
268-
null,
267+
"CREATE",
268+
"CREATE",
269269
null))),
270270
Arguments.of(
271271
named(
@@ -274,9 +274,9 @@ private static Stream<Arguments> provideAsyncParameters() {
274274
"async_test",
275275
"CREATE TABLE async_test.users ( id UUID PRIMARY KEY, name text )",
276276
"CREATE TABLE async_test.users ( id UUID PRIMARY KEY, name text )",
277-
"async_test",
278-
null,
279-
null))),
277+
"CREATE TABLE async_test.users",
278+
"CREATE TABLE",
279+
"async_test.users"))),
280280
Arguments.of(
281281
named(
282282
"Insert data",

instrumentation/cassandra/cassandra-4.4/testing/src/main/java/io/opentelemetry/testing/cassandra/v4_4/AbstractCassandra44Test.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,8 @@ private static Stream<Arguments> provideReactiveParameters() {
106106
null,
107107
"DROP KEYSPACE IF EXISTS reactive_test",
108108
"DROP KEYSPACE IF EXISTS reactive_test",
109-
"DB Query",
110-
null,
109+
"DROP",
110+
"DROP",
111111
null))),
112112
Arguments.of(
113113
named(
@@ -116,8 +116,8 @@ private static Stream<Arguments> provideReactiveParameters() {
116116
null,
117117
"CREATE KEYSPACE reactive_test WITH REPLICATION = {'class':'SimpleStrategy', 'replication_factor':3}",
118118
"CREATE KEYSPACE reactive_test WITH REPLICATION = {?:?, ?:?}",
119-
"DB Query",
120-
null,
119+
"CREATE",
120+
"CREATE",
121121
null))),
122122
Arguments.of(
123123
named(
@@ -126,9 +126,9 @@ private static Stream<Arguments> provideReactiveParameters() {
126126
"reactive_test",
127127
"CREATE TABLE reactive_test.users ( id UUID PRIMARY KEY, name text )",
128128
"CREATE TABLE reactive_test.users ( id UUID PRIMARY KEY, name text )",
129-
"reactive_test",
130-
null,
131-
null))),
129+
"CREATE TABLE reactive_test.users",
130+
"CREATE TABLE",
131+
"reactive_test.users"))),
132132
Arguments.of(
133133
named(
134134
"Insert data",

0 commit comments

Comments
 (0)