in apm-agent-plugin-sdk/src/main/java/co/elastic/apm/agent/sdk/internal/db/signature/SignatureParser.java [72:173]
private void parse(Scanner scanner, String query, StringBuilder signature, @Nullable StringBuilder dbLink) {
final Scanner.Token firstToken = scanner.scanWhile(Scanner.Token.COMMENT);
switch (firstToken) {
case CALL:
signature.append("CALL");
if (scanner.scanUntil(Scanner.Token.IDENT)) {
appendIdentifiers(scanner, signature, dbLink);
}
return;
case DELETE:
signature.append("DELETE");
if (scanner.scanUntil(Scanner.Token.FROM) && scanner.scanUntil(Scanner.Token.IDENT)) {
signature.append(" FROM");
appendIdentifiers(scanner, signature, dbLink);
}
return;
case INSERT:
case REPLACE:
signature.append(firstToken.name());
if (scanner.scanUntil(Scanner.Token.INTO) && scanner.scanUntil(Scanner.Token.IDENT)) {
signature.append(" INTO");
appendIdentifiers(scanner, signature, dbLink);
}
return;
case SELECT:
signature.append("SELECT");
int level = 0;
for (Scanner.Token t = scanner.scan(); t != Scanner.Token.EOF; t = scanner.scan()) {
if (t == Scanner.Token.LPAREN) {
level++;
} else if (t == Scanner.Token.RPAREN) {
level--;
} else if (t == Scanner.Token.FROM) {
if (level == 0) {
if (scanner.scanToken(Scanner.Token.IDENT)) {
signature.append(" FROM");
appendIdentifiers(scanner, signature, dbLink);
} else {
return;
}
}
}
}
return;
case UPDATE:
signature.append("UPDATE");
// Scan for the table name
boolean hasPeriod = false, hasFirstPeriod = false, isDbLink = false;
if (scanner.scanToken(Scanner.Token.IDENT)) {
signature.append(' ');
scanner.appendCurrentTokenText(signature);
for (Scanner.Token t = scanner.scan(); t != Scanner.Token.EOF; t = scanner.scan()) {
switch (t) {
case IDENT:
if (hasPeriod) {
scanner.appendCurrentTokenText(signature);
hasPeriod = false;
}
if (!hasFirstPeriod) {
// Some dialects allow option keywords before the table name
// example: UPDATE IGNORE foo.bar
signature.setLength(0);
signature.append("UPDATE ");
scanner.appendCurrentTokenText(signature);
} else if (isDbLink) {
if (dbLink != null) {
scanner.appendCurrentTokenText(dbLink);
}
isDbLink = false;
}
// Two adjacent identifiers found after the first period.
// Ignore the secondary ones, in case they are unknown keywords.
break;
case PERIOD:
hasFirstPeriod = true;
hasPeriod = true;
signature.append('.');
break;
default:
if ("@".equals(scanner.text())) {
isDbLink = true;
break;
} else {
return;
}
}
}
}
return;
case MERGE:
signature.append("MERGE");
if (scanner.scanToken(Scanner.Token.INTO) && scanner.scanUntil(Scanner.Token.IDENT)) {
signature.append(" INTO");
appendIdentifiers(scanner, signature, dbLink);
}
return;
default:
query = query.trim();
final int indexOfWhitespace = query.indexOf(' ');
signature.append(query, 0, indexOfWhitespace > 0 ? indexOfWhitespace : query.length());
}
}