From 2e437e7160eda9a210837aa409163a15da59ba00 Mon Sep 17 00:00:00 2001 From: hwxy233 Date: Wed, 17 Jun 2026 19:38:48 +0800 Subject: [PATCH 01/12] Fix MSSQL JDBC "database=" parameter not extracting db.name The Microsoft SQL Server JDBC driver supports both 'databaseName' and 'database' as connection property names for specifying the database name. However, the URL parser only checked for 'databasename' (after lowercasing), causing jdbc:sqlserver://...;database=xxx URLs to not extract the db.name attribute. This commit adds 'database' as a fallback key in: - ParseContext.applyCommonParams() - used by MssqlUrlParser - JtdsUrlParser.parse() - used by jTDS driver Additional test cases cover the 'database=' parameter for both sqlserver and jtds URL formats. --- .../jdbc/internal/parser/JtdsUrlParser.java | 10 +++-- .../jdbc/internal/parser/ParseContext.java | 3 ++ .../internal/JdbcConnectionUrlParserTest.java | 40 +++++++++++++++++++ 3 files changed, 50 insertions(+), 3 deletions(-) diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/JtdsUrlParser.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/JtdsUrlParser.java index cebb3aa71bb9..5cb860cabe2e 100644 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/JtdsUrlParser.java +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/JtdsUrlParser.java @@ -66,9 +66,13 @@ public void parse(String jdbcUrl, ParseContext ctx) { instanceName = urlParams.get("instance"); } - // If no path, use databasename param as fallback for database - if (ctx.databaseName() == null && urlParams.containsKey("databasename")) { - ctx.databaseName(urlParams.get("databasename")); + // If no path, use databasename or database param as fallback for database + if (ctx.databaseName() == null) { + if (urlParams.containsKey("databasename")) { + ctx.databaseName(urlParams.get("databasename")); + } else if (urlParams.containsKey("database")) { + ctx.databaseName(urlParams.get("database")); + } } } diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/ParseContext.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/ParseContext.java index a88fe3550304..9b00b3bd3d34 100644 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/ParseContext.java +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/ParseContext.java @@ -191,6 +191,9 @@ public void applyCommonParams(String jdbcUrl, String startDelimiter, String spli this.port = port; } String databaseName = params.get("databasename"); + if (databaseName == null || databaseName.isEmpty()) { + databaseName = params.get("database"); + } if (databaseName != null && !databaseName.isEmpty()) { this.databaseName = databaseName; } diff --git a/instrumentation/jdbc/library/src/test/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcConnectionUrlParserTest.java b/instrumentation/jdbc/library/src/test/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcConnectionUrlParserTest.java index 7b180beb992d..fd2a66a16770 100644 --- a/instrumentation/jdbc/library/src/test/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcConnectionUrlParserTest.java +++ b/instrumentation/jdbc/library/src/test/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcConnectionUrlParserTest.java @@ -557,6 +557,25 @@ private static Stream sqlServerArguments() { .setPort(1433) .setName("ssdb") .build(), + // database= alias (shorthand for databaseName) + arg("jdbc:sqlserver://ss.host;database=ssdb;") + .setShortUrl("sqlserver://ss.host:1433") + .setSystem("microsoft.sql_server") + .setOldSystem("mssql") + .setHost("ss.host") + .setPort(1433) + .setName("ssdb") + .build(), + arg("jdbc:sqlserver://ss.host\\ssinstance:44;database=ssdb;user=ssuser") + .setShortUrl("sqlserver://ss.host:44") + .setSystem("microsoft.sql_server") + .setOldSystem("mssql") + .setUser("ssuser") + .setHost("ss.host") + .setPort(44) + .setNamespace("ssinstance|ssdb") + .setName("ssinstance") + .build(), arg("jdbc:microsoft:sqlserver://ss.host:44;DatabaseName=ssdb;user=ssuser;password=pw;user=ssuser2;") .setShortUrl("microsoft:sqlserver://ss.host:44") .setSystem("microsoft.sql_server") @@ -659,6 +678,27 @@ private static Stream sqlServerArguments() { .setNamespace("ssinstance") .setName("ssinstance") .build(), + // database= alias (shorthand for databaseName) in jTDS URLs + arg("jdbc:jtds:sqlserver://ss.host/ssdb;instance=ssinstance;database=otherdb") + .setShortUrl("jtds:sqlserver://ss.host:1433") + .setSystem("microsoft.sql_server") + .setOldSystem("mssql") + .setSubtype("sqlserver") + .setHost("ss.host") + .setPort(1433) + .setNamespace("ssinstance|ssdb") + .setName("ssinstance") + .build(), + // database= param provides database name when there's no URL path + arg("jdbc:jtds:sqlserver://ss.host;instance=ssinstance;database=ssdb") + .setShortUrl("jtds:sqlserver://ss.host:1433") + .setSystem("microsoft.sql_server") + .setOldSystem("mssql") + .setHost("ss.host") + .setPort(1433) + .setNamespace("ssinstance|ssdb") + .setName("ssinstance") + .build(), arg("jdbc:jtds:sqlserver://ss.host:1444/urldb") .setProperties(stdProps()) .setShortUrl("jtds:sqlserver://stdServerName:9999") From 56ff1e0e5c55336a39f93d156785518e264dbc9c Mon Sep 17 00:00:00 2001 From: hwxy233 Date: Wed, 17 Jun 2026 19:50:55 +0800 Subject: [PATCH 02/12] Fix JtdsUrlParser to handle empty databasename values consistently with ParseContext Previously JtdsUrlParser used containsKey() which would accept an empty 'databasename=' value and not fall through to the 'database' fallback. Now uses the same null/empty check pattern as ParseContext.applyCommonParams: if databasename is absent or empty, fall through to the database parameter. --- .../jdbc/internal/parser/JtdsUrlParser.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/JtdsUrlParser.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/JtdsUrlParser.java index 5cb860cabe2e..3a57df58cc10 100644 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/JtdsUrlParser.java +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/JtdsUrlParser.java @@ -68,10 +68,12 @@ public void parse(String jdbcUrl, ParseContext ctx) { // If no path, use databasename or database param as fallback for database if (ctx.databaseName() == null) { - if (urlParams.containsKey("databasename")) { - ctx.databaseName(urlParams.get("databasename")); - } else if (urlParams.containsKey("database")) { - ctx.databaseName(urlParams.get("database")); + String databaseName = urlParams.get("databasename"); + if (databaseName == null || databaseName.isEmpty()) { + databaseName = urlParams.get("database"); + } + if (databaseName != null && !databaseName.isEmpty()) { + ctx.databaseName(databaseName); } } } From feec3eb31337038cd26a907a7198ed34b0270f98 Mon Sep 17 00:00:00 2001 From: hwxy233 Date: Wed, 17 Jun 2026 21:22:01 +0800 Subject: [PATCH 03/12] Extract databaseName/database fallback resolution into shared helper method Replace duplicated resolution logic in both ParseContext.applyCommonParams() and JtdsUrlParser.parse() with a single ParseContext.applyDatabaseNameParam(Map) method that resolves the database name from URL parameters, trying 'databasename' first and falling back to 'database'. --- .../jdbc/internal/parser/JtdsUrlParser.java | 8 +----- .../jdbc/internal/parser/ParseContext.java | 25 +++++++++++++------ 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/JtdsUrlParser.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/JtdsUrlParser.java index 3a57df58cc10..ee8945609957 100644 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/JtdsUrlParser.java +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/JtdsUrlParser.java @@ -68,13 +68,7 @@ public void parse(String jdbcUrl, ParseContext ctx) { // If no path, use databasename or database param as fallback for database if (ctx.databaseName() == null) { - String databaseName = urlParams.get("databasename"); - if (databaseName == null || databaseName.isEmpty()) { - databaseName = urlParams.get("database"); - } - if (databaseName != null && !databaseName.isEmpty()) { - ctx.databaseName(databaseName); - } + ctx.applyDatabaseNameParam(urlParams); } } diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/ParseContext.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/ParseContext.java index 9b00b3bd3d34..3945bd92a9f2 100644 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/ParseContext.java +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/ParseContext.java @@ -166,6 +166,23 @@ public Properties props() { return props; } + /** + * Resolve the database name from URL parameters, trying {@code databasename} first and falling + * back to {@code database}. This is used by URL-based parsers ({@link #applyCommonParams}) and + * by parsers that handle params separately (e.g., {@code JtdsUrlParser}). + * + * @param params the URL parameter map + */ + public void applyDatabaseNameParam(Map params) { + String databaseName = params.get("databasename"); + if (databaseName == null || databaseName.isEmpty()) { + databaseName = params.get("database"); + } + if (databaseName != null && !databaseName.isEmpty()) { + this.databaseName = databaseName; + } + } + /** * Apply common parameters from URL parameters to the context. * @@ -190,13 +207,7 @@ public void applyCommonParams(String jdbcUrl, String startDelimiter, String spli if (port != null) { this.port = port; } - String databaseName = params.get("databasename"); - if (databaseName == null || databaseName.isEmpty()) { - databaseName = params.get("database"); - } - if (databaseName != null && !databaseName.isEmpty()) { - this.databaseName = databaseName; - } + applyDatabaseNameParam(params); if (params.containsKey("user")) { this.user = params.get("user"); } From 2ada733a867a2e2618cb7ba2432a1eb786f0be41 Mon Sep 17 00:00:00 2001 From: hwxy233 Date: Wed, 17 Jun 2026 21:30:15 +0800 Subject: [PATCH 04/12] Fix spotless format violation in Javadoc comment --- .../instrumentation/jdbc/internal/parser/ParseContext.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/ParseContext.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/ParseContext.java index 3945bd92a9f2..c48a5b2e30d4 100644 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/ParseContext.java +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/ParseContext.java @@ -168,8 +168,8 @@ public Properties props() { /** * Resolve the database name from URL parameters, trying {@code databasename} first and falling - * back to {@code database}. This is used by URL-based parsers ({@link #applyCommonParams}) and - * by parsers that handle params separately (e.g., {@code JtdsUrlParser}). + * back to {@code database}. Used by URL-based parsers ({@link #applyCommonParams}) and by + * parsers that handle params separately (e.g., {@code JtdsUrlParser}). * * @param params the URL parameter map */ From 4b19dbcc7f2b6ca213fdf99325c888de55d5716e Mon Sep 17 00:00:00 2001 From: hwxy233 Date: Wed, 17 Jun 2026 21:36:15 +0800 Subject: [PATCH 05/12] Fix spotless format violation (attempt 2) --- .../instrumentation/jdbc/internal/parser/ParseContext.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/ParseContext.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/ParseContext.java index c48a5b2e30d4..c72c40d6295f 100644 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/ParseContext.java +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/ParseContext.java @@ -168,8 +168,8 @@ public Properties props() { /** * Resolve the database name from URL parameters, trying {@code databasename} first and falling - * back to {@code database}. Used by URL-based parsers ({@link #applyCommonParams}) and by - * parsers that handle params separately (e.g., {@code JtdsUrlParser}). + * back to {@code database}. Used by URL-based parsers ({@link #applyCommonParams}) and by parsers + * that handle params separately (e.g., {@code JtdsUrlParser}). * * @param params the URL parameter map */ From e1ba6bd4fffe0b16897416f083a934c638160d54 Mon Sep 17 00:00:00 2001 From: hwxy233 Date: Wed, 17 Jun 2026 21:46:44 +0800 Subject: [PATCH 06/12] Add missing .setSubtype("sqlserver") for consistency with other jTDS test cases --- .../jdbc/internal/JdbcConnectionUrlParserTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/instrumentation/jdbc/library/src/test/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcConnectionUrlParserTest.java b/instrumentation/jdbc/library/src/test/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcConnectionUrlParserTest.java index fd2a66a16770..8cd9ca5126d0 100644 --- a/instrumentation/jdbc/library/src/test/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcConnectionUrlParserTest.java +++ b/instrumentation/jdbc/library/src/test/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcConnectionUrlParserTest.java @@ -694,6 +694,7 @@ private static Stream sqlServerArguments() { .setShortUrl("jtds:sqlserver://ss.host:1433") .setSystem("microsoft.sql_server") .setOldSystem("mssql") + .setSubtype("sqlserver") .setHost("ss.host") .setPort(1433) .setNamespace("ssinstance|ssdb") From 04e33808d4f8e137aa03ad1d328f5d9ddef565fc Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Wed, 17 Jun 2026 16:23:31 -0700 Subject: [PATCH 07/12] refactor --- .../jdbc/internal/parser/JtdsUrlParser.java | 12 +++++++++- .../jdbc/internal/parser/MssqlUrlParser.java | 23 +++++++++++++++++++ .../jdbc/internal/parser/ParseContext.java | 22 ++++-------------- 3 files changed, 38 insertions(+), 19 deletions(-) diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/JtdsUrlParser.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/JtdsUrlParser.java index ee8945609957..63d9656122c8 100644 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/JtdsUrlParser.java +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/JtdsUrlParser.java @@ -8,6 +8,7 @@ import static io.opentelemetry.instrumentation.jdbc.internal.parser.UrlParsingUtils.splitQuery; import java.util.Map; +import javax.annotation.Nullable; /** * Parser for jTDS SQL Server JDBC URLs. @@ -68,7 +69,7 @@ public void parse(String jdbcUrl, ParseContext ctx) { // If no path, use databasename or database param as fallback for database if (ctx.databaseName() == null) { - ctx.applyDatabaseNameParam(urlParams); + ctx.databaseName(getDatabaseNameParam(urlParams)); } } @@ -86,4 +87,13 @@ public void parse(String jdbcUrl, ParseContext ctx) { } } } + + @Nullable + private static String getDatabaseNameParam(Map params) { + String databaseName = params.get("databasename"); + if (databaseName == null || databaseName.isEmpty()) { + databaseName = params.get("database"); + } + return databaseName == null || databaseName.isEmpty() ? null : databaseName; + } } diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/MssqlUrlParser.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/MssqlUrlParser.java index 2c4718d7e00a..1d566b8d2f4b 100644 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/MssqlUrlParser.java +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/MssqlUrlParser.java @@ -6,6 +6,8 @@ package io.opentelemetry.instrumentation.jdbc.internal.parser; import io.opentelemetry.instrumentation.jdbc.internal.parser.UrlParsingUtils.HostPort; +import java.util.Map; +import javax.annotation.Nullable; /** * Parser for Microsoft SQL Server JDBC URLs. @@ -54,6 +56,7 @@ public void parse(String jdbcUrl, ParseContext ctx) { // Layer 3: URL params (SQL Server-specific: servername) ctx.applyCommonParams(jdbcUrl, ";", ";"); + applyDatabaseAliasParam(jdbcUrl, ctx); // Layer 4: Parse URL structure (host:port/path) String instanceName = parseUrlWithInstance(jdbcUrl, ctx); @@ -143,6 +146,26 @@ private static String parseUrlWithInstance(String jdbcUrl, ParseContext ctx) { return instanceName; } + private static void applyDatabaseAliasParam(String jdbcUrl, ParseContext ctx) { + if (ctx.databaseName() != null) { + return; + } + Map params = UrlParsingUtils.extractSemicolonParams(jdbcUrl); + String databaseName = getDatabaseNameParam(params); + if (databaseName != null) { + ctx.databaseName(databaseName); + } + } + + @Nullable + private static String getDatabaseNameParam(Map params) { + String databaseName = params.get("databasename"); + if (databaseName == null || databaseName.isEmpty()) { + databaseName = params.get("database"); + } + return databaseName == null || databaseName.isEmpty() ? null : databaseName; + } + /** * Sets the namespace after parsing completes. * diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/ParseContext.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/ParseContext.java index c72c40d6295f..a88fe3550304 100644 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/ParseContext.java +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/ParseContext.java @@ -166,23 +166,6 @@ public Properties props() { return props; } - /** - * Resolve the database name from URL parameters, trying {@code databasename} first and falling - * back to {@code database}. Used by URL-based parsers ({@link #applyCommonParams}) and by parsers - * that handle params separately (e.g., {@code JtdsUrlParser}). - * - * @param params the URL parameter map - */ - public void applyDatabaseNameParam(Map params) { - String databaseName = params.get("databasename"); - if (databaseName == null || databaseName.isEmpty()) { - databaseName = params.get("database"); - } - if (databaseName != null && !databaseName.isEmpty()) { - this.databaseName = databaseName; - } - } - /** * Apply common parameters from URL parameters to the context. * @@ -207,7 +190,10 @@ public void applyCommonParams(String jdbcUrl, String startDelimiter, String spli if (port != null) { this.port = port; } - applyDatabaseNameParam(params); + String databaseName = params.get("databasename"); + if (databaseName != null && !databaseName.isEmpty()) { + this.databaseName = databaseName; + } if (params.containsKey("user")) { this.user = params.get("user"); } From 3d3648c6b1f74d2999c86d17faa92b5a545ce4ad Mon Sep 17 00:00:00 2001 From: hwxy233 Date: Thu, 18 Jun 2026 11:25:04 +0800 Subject: [PATCH 08/12] Move getDatabaseNameParam to UrlParsingUtils and eliminate double URL parsing in MssqlUrlParser MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses two review comments: 1. Deduplicate getDatabaseNameParam: The method was copied verbatim in both MssqlUrlParser and JtdsUrlParser. Moved to UrlParsingUtils as a shared static helper, consistent with other utilities like extractSubtype and splitQuery already in that class. 2. Eliminate redundant URL parsing: MssqlUrlParser was parsing semicolon parameters twice — once in applyCommonParams and again in applyDatabaseAliasParam. Now extract the params map once in parse(), then pass it to both applyCommonParams (new map-based overload) and applyDatabaseAliasParam. Additionally, applyDatabaseAliasParam no longer re-extracts params from the URL string. --- .../jdbc/internal/parser/JtdsUrlParser.java | 13 ++--- .../jdbc/internal/parser/MssqlUrlParser.java | 48 ++++++++++++++----- .../jdbc/internal/parser/UrlParsingUtils.java | 16 +++++++ 3 files changed, 55 insertions(+), 22 deletions(-) diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/JtdsUrlParser.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/JtdsUrlParser.java index 63d9656122c8..20e7b7e9b01c 100644 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/JtdsUrlParser.java +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/JtdsUrlParser.java @@ -69,7 +69,10 @@ public void parse(String jdbcUrl, ParseContext ctx) { // If no path, use databasename or database param as fallback for database if (ctx.databaseName() == null) { - ctx.databaseName(getDatabaseNameParam(urlParams)); + String databaseName = UrlParsingUtils.getDatabaseNameParam(urlParams); + if (databaseName != null) { + ctx.databaseName(databaseName); + } } } @@ -88,12 +91,4 @@ public void parse(String jdbcUrl, ParseContext ctx) { } } - @Nullable - private static String getDatabaseNameParam(Map params) { - String databaseName = params.get("databasename"); - if (databaseName == null || databaseName.isEmpty()) { - databaseName = params.get("database"); - } - return databaseName == null || databaseName.isEmpty() ? null : databaseName; - } } diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/MssqlUrlParser.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/MssqlUrlParser.java index 1d566b8d2f4b..616d79b58979 100644 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/MssqlUrlParser.java +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/MssqlUrlParser.java @@ -55,8 +55,11 @@ public void parse(String jdbcUrl, ParseContext ctx) { } // Layer 3: URL params (SQL Server-specific: servername) - ctx.applyCommonParams(jdbcUrl, ";", ";"); - applyDatabaseAliasParam(jdbcUrl, ctx); + // Parse semicolon-delimited parameters once and apply both standard and + // MSSQL-specific properties from the same map to avoid re-parsing the URL. + Map urlParams = UrlParsingUtils.extractSemicolonParams(jdbcUrl); + applyCommonParams(ctx, urlParams); + applyDatabaseAliasParam(ctx, urlParams); // Layer 4: Parse URL structure (host:port/path) String instanceName = parseUrlWithInstance(jdbcUrl, ctx); @@ -146,24 +149,43 @@ private static String parseUrlWithInstance(String jdbcUrl, ParseContext ctx) { return instanceName; } - private static void applyDatabaseAliasParam(String jdbcUrl, ParseContext ctx) { - if (ctx.databaseName() != null) { + /** + * Apply standard URL parameters from a pre-parsed map. Equivalent to {@link + * ParseContext#applyCommonParams} but operates on an already-extracted parameter map to avoid + * re-parsing the URL string. + */ + private static void applyCommonParams(ParseContext ctx, Map params) { + if (params.isEmpty()) { return; } - Map params = UrlParsingUtils.extractSemicolonParams(jdbcUrl); - String databaseName = getDatabaseNameParam(params); - if (databaseName != null) { + if (params.containsKey("servername")) { + ctx.host(params.get("servername")); + } + Integer port = UrlParsingUtils.parsePort(params.get("portnumber")); + if (port != null) { + ctx.port(port); + } + String databaseName = params.get("databasename"); + if (databaseName != null && !databaseName.isEmpty()) { ctx.databaseName(databaseName); } + if (params.containsKey("user")) { + ctx.user(params.get("user")); + } } - @Nullable - private static String getDatabaseNameParam(Map params) { - String databaseName = params.get("databasename"); - if (databaseName == null || databaseName.isEmpty()) { - databaseName = params.get("database"); + /** + * Apply the {@code database} URL parameter alias when {@code databasename} has not already been + * set by {@link #applyCommonParams(ParseContext, Map)}. + */ + private static void applyDatabaseAliasParam(ParseContext ctx, Map params) { + if (ctx.databaseName() != null) { + return; + } + String databaseName = UrlParsingUtils.getDatabaseNameParam(params); + if (databaseName != null) { + ctx.databaseName(databaseName); } - return databaseName == null || databaseName.isEmpty() ? null : databaseName; } /** diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/UrlParsingUtils.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/UrlParsingUtils.java index 3552882abbae..d68d7c14505e 100644 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/UrlParsingUtils.java +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/UrlParsingUtils.java @@ -278,6 +278,22 @@ public static HostPort extractHostPort(String serverName) { return new HostPort(serverName, port, ipv6Address); } + /** + * Resolve the database name from URL parameters, trying {@code databasename} first and falling + * back to {@code database}. Returns {@code null} if neither key has a non-empty value. + * + * @param params the URL parameter map (keys must be lowercase) + * @return the resolved database name, or {@code null} + */ + @Nullable + public static String getDatabaseNameParam(Map params) { + String databaseName = params.get("databasename"); + if (databaseName == null || databaseName.isEmpty()) { + databaseName = params.get("database"); + } + return databaseName == null || databaseName.isEmpty() ? null : databaseName; + } + /** * Lightweight wrapper for URL parameters that provides cleaner access patterns. * From 89d9d53fa9c2587f204392eb079da707175a4284 Mon Sep 17 00:00:00 2001 From: hwxy233 Date: Thu, 18 Jun 2026 11:31:05 +0800 Subject: [PATCH 09/12] Remove unused @Nullable imports after moving getDatabaseNameParam to UrlParsingUtils --- .../instrumentation/jdbc/internal/parser/JtdsUrlParser.java | 2 -- .../instrumentation/jdbc/internal/parser/MssqlUrlParser.java | 1 - 2 files changed, 3 deletions(-) diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/JtdsUrlParser.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/JtdsUrlParser.java index 20e7b7e9b01c..a1c39eb5f6f4 100644 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/JtdsUrlParser.java +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/JtdsUrlParser.java @@ -8,7 +8,6 @@ import static io.opentelemetry.instrumentation.jdbc.internal.parser.UrlParsingUtils.splitQuery; import java.util.Map; -import javax.annotation.Nullable; /** * Parser for jTDS SQL Server JDBC URLs. @@ -91,4 +90,3 @@ public void parse(String jdbcUrl, ParseContext ctx) { } } -} diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/MssqlUrlParser.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/MssqlUrlParser.java index 616d79b58979..9fb78533ad0a 100644 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/MssqlUrlParser.java +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/MssqlUrlParser.java @@ -7,7 +7,6 @@ import io.opentelemetry.instrumentation.jdbc.internal.parser.UrlParsingUtils.HostPort; import java.util.Map; -import javax.annotation.Nullable; /** * Parser for Microsoft SQL Server JDBC URLs. From 2a83168521227e680abf018b11e589b1489c7306 Mon Sep 17 00:00:00 2001 From: hwxy233 Date: Thu, 18 Jun 2026 11:36:29 +0800 Subject: [PATCH 10/12] Fix missing closing brace in JtdsUrlParser --- .../instrumentation/jdbc/internal/parser/JtdsUrlParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/JtdsUrlParser.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/JtdsUrlParser.java index a1c39eb5f6f4..73d5a395f5ac 100644 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/JtdsUrlParser.java +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/JtdsUrlParser.java @@ -89,4 +89,4 @@ public void parse(String jdbcUrl, ParseContext ctx) { } } } - +} From ef4fa3317eff379f36ca801b881392485e6e66be Mon Sep 17 00:00:00 2001 From: hwxy233 Date: Thu, 18 Jun 2026 11:56:41 +0800 Subject: [PATCH 11/12] Move applyCommonParams(Map) overload to ParseContext, remove duplicate from MssqlUrlParser Refactor suggested by review comment: instead of duplicating the applyCommonParams logic as a private method in MssqlUrlParser, add a public overload ParseContext.applyCommonParams(Map) that accepts a pre-parsed parameter map. MssqlUrlParser now calls ctx.applyCommonParams(urlParams) directly, eliminating the near-copy. The original applyCommonParams(String, String, String) now delegates to the new map-based overload to ensure both versions stay in sync. --- .../jdbc/internal/parser/MssqlUrlParser.java | 29 ++----------------- .../jdbc/internal/parser/ParseContext.java | 12 ++++++-- 2 files changed, 12 insertions(+), 29 deletions(-) diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/MssqlUrlParser.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/MssqlUrlParser.java index 9fb78533ad0a..8da5d9100ed7 100644 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/MssqlUrlParser.java +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/MssqlUrlParser.java @@ -57,7 +57,7 @@ public void parse(String jdbcUrl, ParseContext ctx) { // Parse semicolon-delimited parameters once and apply both standard and // MSSQL-specific properties from the same map to avoid re-parsing the URL. Map urlParams = UrlParsingUtils.extractSemicolonParams(jdbcUrl); - applyCommonParams(ctx, urlParams); + ctx.applyCommonParams(urlParams); applyDatabaseAliasParam(ctx, urlParams); // Layer 4: Parse URL structure (host:port/path) @@ -148,34 +148,9 @@ private static String parseUrlWithInstance(String jdbcUrl, ParseContext ctx) { return instanceName; } - /** - * Apply standard URL parameters from a pre-parsed map. Equivalent to {@link - * ParseContext#applyCommonParams} but operates on an already-extracted parameter map to avoid - * re-parsing the URL string. - */ - private static void applyCommonParams(ParseContext ctx, Map params) { - if (params.isEmpty()) { - return; - } - if (params.containsKey("servername")) { - ctx.host(params.get("servername")); - } - Integer port = UrlParsingUtils.parsePort(params.get("portnumber")); - if (port != null) { - ctx.port(port); - } - String databaseName = params.get("databasename"); - if (databaseName != null && !databaseName.isEmpty()) { - ctx.databaseName(databaseName); - } - if (params.containsKey("user")) { - ctx.user(params.get("user")); - } - } - /** * Apply the {@code database} URL parameter alias when {@code databasename} has not already been - * set by {@link #applyCommonParams(ParseContext, Map)}. + * set by {@link ParseContext#applyCommonParams(Map)}. */ private static void applyDatabaseAliasParam(ParseContext ctx, Map params) { if (ctx.databaseName() != null) { diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/ParseContext.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/ParseContext.java index a88fe3550304..b66f4f7bba3d 100644 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/ParseContext.java +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/ParseContext.java @@ -177,9 +177,17 @@ public Properties props() { * @param splitSeparator the separator between individual parameters (";" or "&") */ public void applyCommonParams(String jdbcUrl, String startDelimiter, String splitSeparator) { - Map params = - UrlParsingUtils.extractParams(jdbcUrl, startDelimiter, splitSeparator); + applyCommonParams(UrlParsingUtils.extractParams(jdbcUrl, startDelimiter, splitSeparator)); + } + /** + * Apply common parameters from a pre-parsed parameter map. Equivalent to {@link + * #applyCommonParams(String, String, String)} but avoids re-parsing the URL when the caller has + * already extracted the parameters. + * + * @param params the parameter map (keys must be lowercase) + */ + public void applyCommonParams(Map params) { if (params.isEmpty()) { return; } From 1397e5fc60971e2a31eef3cb1c2259afe0c37ba1 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Fri, 19 Jun 2026 14:49:15 -0700 Subject: [PATCH 12/12] move getDatabaseNameParam --- .../jdbc/internal/parser/JtdsUrlParser.java | 2 +- .../jdbc/internal/parser/MssqlUrlParser.java | 16 +++++++++++++++- .../jdbc/internal/parser/UrlParsingUtils.java | 16 ---------------- 3 files changed, 16 insertions(+), 18 deletions(-) diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/JtdsUrlParser.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/JtdsUrlParser.java index 73d5a395f5ac..45cc17221e58 100644 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/JtdsUrlParser.java +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/JtdsUrlParser.java @@ -68,7 +68,7 @@ public void parse(String jdbcUrl, ParseContext ctx) { // If no path, use databasename or database param as fallback for database if (ctx.databaseName() == null) { - String databaseName = UrlParsingUtils.getDatabaseNameParam(urlParams); + String databaseName = MssqlUrlParser.getDatabaseNameParam(urlParams); if (databaseName != null) { ctx.databaseName(databaseName); } diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/MssqlUrlParser.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/MssqlUrlParser.java index 8da5d9100ed7..d2c8b29b2f89 100644 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/MssqlUrlParser.java +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/MssqlUrlParser.java @@ -7,6 +7,7 @@ import io.opentelemetry.instrumentation.jdbc.internal.parser.UrlParsingUtils.HostPort; import java.util.Map; +import javax.annotation.Nullable; /** * Parser for Microsoft SQL Server JDBC URLs. @@ -156,12 +157,25 @@ private static void applyDatabaseAliasParam(ParseContext ctx, Map params) { + String databaseName = params.get("databasename"); + if (databaseName == null || databaseName.isEmpty()) { + databaseName = params.get("database"); + } + return databaseName == null || databaseName.isEmpty() ? null : databaseName; + } + /** * Sets the namespace after parsing completes. * diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/UrlParsingUtils.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/UrlParsingUtils.java index d68d7c14505e..3552882abbae 100644 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/UrlParsingUtils.java +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/parser/UrlParsingUtils.java @@ -278,22 +278,6 @@ public static HostPort extractHostPort(String serverName) { return new HostPort(serverName, port, ipv6Address); } - /** - * Resolve the database name from URL parameters, trying {@code databasename} first and falling - * back to {@code database}. Returns {@code null} if neither key has a non-empty value. - * - * @param params the URL parameter map (keys must be lowercase) - * @return the resolved database name, or {@code null} - */ - @Nullable - public static String getDatabaseNameParam(Map params) { - String databaseName = params.get("databasename"); - if (databaseName == null || databaseName.isEmpty()) { - databaseName = params.get("database"); - } - return databaseName == null || databaseName.isEmpty() ? null : databaseName; - } - /** * Lightweight wrapper for URL parameters that provides cleaner access patterns. *