Skip to content

Commit 6edaa0d

Browse files
authored
Improve handling of quoted table names (#13612)
1 parent 818f73f commit 6edaa0d

File tree

2 files changed

+32
-4
lines changed

2 files changed

+32
-4
lines changed

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

+28-4
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,12 @@ OPEN_PAREN = "("
2323
CLOSE_PAREN = ")"
2424
OPEN_COMMENT = "/*"
2525
CLOSE_COMMENT = "*/"
26-
IDENTIFIER = ([:letter:] | "_") ([:letter:] | [0-9] | [_.])*
26+
UNQUOTED_IDENTIFIER = ([:letter:] | "_") ([:letter:] | [0-9] | "_")*
27+
IDENTIFIER_PART = {UNQUOTED_IDENTIFIER} | {DOUBLE_QUOTED_STR} | {BACKTICK_QUOTED_STR}
28+
// We are using {UNQUOTED_IDENTIFIER} instead of {IDENTIFIER_PART} here because DOUBLE_QUOTED_STR
29+
// and BACKTICK_QUOTED_STR are handled separately. Depending on the context they appear in they will
30+
// either be recorded as the identifier or replaced with ?.
31+
IDENTIFIER = {UNQUOTED_IDENTIFIER} | ({IDENTIFIER_PART} ("." {IDENTIFIER_PART})+)
2732
BASIC_NUM = [.+-]* [0-9] ([0-9] | [eE.+-])*
2833
HEX_NUM = "0x" ([a-f] | [A-F] | [0-9])+
2934
QUOTED_STR = "'" ("''" | [^'])* "'"
@@ -69,12 +74,31 @@ WHITESPACE = [ \t\r\n]+
6974
return builder.length() > LIMIT;
7075
}
7176

77+
private String removeQuotes(String identifierName, String quote) {
78+
// remove quotes from the start and end of the identifier ("table" is transformed to table), if
79+
// identifier contains quote anywhere else besides start and end leave it as is (quotes are not
80+
// removed from "schema"."table")
81+
if (identifierName.startsWith(quote) && identifierName.endsWith(quote)) {
82+
String s = identifierName.substring(1, identifierName.length() - 1);
83+
if (!s.contains(quote)) {
84+
return s;
85+
}
86+
}
87+
return identifierName;
88+
}
89+
7290
/** @return text matched by current token without enclosing double quotes or backticks */
7391
private String readIdentifierName() {
7492
String identifierName = yytext();
75-
if (identifierName != null && ((identifierName.startsWith("\"") && identifierName.endsWith("\""))
76-
|| (identifierName.startsWith("`") && identifierName.endsWith("`")))) {
77-
identifierName = identifierName.substring(1, identifierName.length() - 1);
93+
if (identifierName != null) {
94+
String result = removeQuotes(identifierName, "\"");
95+
if (!result.equals(identifierName)) {
96+
return result;
97+
}
98+
result = removeQuotes(identifierName, "`");
99+
if (!result.equals(identifierName)) {
100+
return result;
101+
}
78102
}
79103
return identifierName;
80104
}

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

+4
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,11 @@ public Stream<? extends Arguments> provideArguments(ExtensionContext context) {
277277
// Select
278278
Arguments.of("SELECT x, y, z FROM schema.table", expect("SELECT", "schema.table")),
279279
Arguments.of("SELECT x, y, z FROM `schema table`", expect("SELECT", "schema table")),
280+
Arguments.of(
281+
"SELECT x, y, z FROM `schema`.`table`", expect("SELECT", "`schema`.`table`")),
280282
Arguments.of("SELECT x, y, z FROM \"schema table\"", expect("SELECT", "schema table")),
283+
Arguments.of(
284+
"SELECT x, y, z FROM \"schema\".\"table\"", expect("SELECT", "\"schema\".\"table\"")),
281285
Arguments.of(
282286
"WITH subquery as (select a from b) SELECT x, y, z FROM table",
283287
expect("SELECT", null)),

0 commit comments

Comments
 (0)