Skip to content

Optimize PDOIntegration::parseDsn()#3430

Merged
bwoebi merged 3 commits into
masterfrom
bob/bob-optimize-parseDsn
Sep 30, 2025
Merged

Optimize PDOIntegration::parseDsn()#3430
bwoebi merged 3 commits into
masterfrom
bob/bob-optimize-parseDsn

Conversation

@bwoebi

@bwoebi bwoebi commented Sep 23, 2025

Copy link
Copy Markdown
Collaborator

Avoid manual string parsing in a loop, just use a single regex.

And remove some redundant empty branch.

@bwoebi
bwoebi requested a review from a team as a code owner September 23, 2025 13:36
@codecov-commenter

codecov-commenter commented Sep 23, 2025

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 61.74%. Comparing base (c70ff24) to head (83fd76c).
⚠️ Report is 8 commits behind head on master.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #3430      +/-   ##
==========================================
- Coverage   61.85%   61.74%   -0.12%     
==========================================
  Files         141      141              
  Lines       12481    12481              
  Branches     1630     1630              
==========================================
- Hits         7720     7706      -14     
- Misses       4041     4054      +13     
- Partials      720      721       +1     

see 2 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c70ff24...83fd76c. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@pr-commenter

pr-commenter Bot commented Sep 23, 2025

Copy link
Copy Markdown

Benchmarks [ tracer ]

Benchmark execution time: 2025-09-29 19:24:10

Comparing candidate commit 67c6467 in PR branch bob/bob-optimize-parseDsn with baseline commit c70ff24 in branch master.

Found 3 performance improvements and 0 performance regressions! Performance is the same for 191 metrics, 0 unstable metrics.

scenario:MessagePackSerializationBench/benchMessagePackSerialization

  • 🟩 execution_time [-7.979µs; -7.081µs] or [-7.005%; -6.217%]

scenario:MessagePackSerializationBench/benchMessagePackSerialization-opcache

  • 🟩 execution_time [-9.493µs; -8.607µs] or [-7.890%; -7.154%]

scenario:TraceSerializationBench/benchSerializeTrace

  • 🟩 execution_time [-45.769µs; -31.231µs] or [-10.308%; -7.034%]

{
$engine = substr($dsn, 0, strpos($dsn, ':'));
$tags = ['db.engine' => $engine];
\preg_match('(\A(?<engine>[^:]++)(?::(?:(?:charset=(?<charset>[^;]++)|(?:database|dbname)=(?<db>[^;]++)|(?:server|unix_socket|host(?:name)?)=(?<host>[^;]++)|port=(?<port>[^;]++)|driver=(?<driver>[^;]++)|[^;]*+)(?:;|\Z))++)?)i', $dsn, $m);

@cataphract cataphract Sep 23, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks very limited:

  • does not support DSNs without colon (ini lookup for pdo.dsn.{value}
  • does not support uri:
  • the driver specific part does not support colon escapes with ;; (on the generic path for mysql, oci, etc.) and does not properly parse sqlite or psql (sqlite:/path sqlite::memory: , psql:host=localhost port=5432 dbname=foo)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, (?:;|\Z) should be ;*+\Z instead.
Everything else was not supported in the existing code though. I'll have a look.

Comment on lines +241 to +246
} else {
// There's technically also uri: but we don't support it and it's anyway deprecated
$tags = [
Tag::DB_SYSTEM => 'other_sql',
Tag::DB_TYPE => 'other_sql',
];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the fallback where the DSN can't be parsed (and there's no ini_get("pdo.dsn.$dsn") hit), we currently return only db.system/db.type.
Previously, we also set db.engine from the prefix (substring before the first :). Shouldn't we keep db.engine to avoid a tagging regression in metrics & dashboards that key off db.engine?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only case where the DSN cannot be parsed is if there's no colon in the dsn. So actually the case when you use a plain name, but the ini doesn't exist.

foreach ($valStrings as $valString) {
if (!strpos($valString, '=')) {
continue;
if (\preg_match('(\A(?<engine>[^:]++)(?::(?:(?:(?:server|unix_socket|host(?:name)?)=(?<host>(?:[^;]*+(?:;;)?)++)|port=(?<port>(?&host))|charset=(?<charset>(?&host))|(?:database|dbname)=(?<db>(?&host))|driver=(?<driver>(?&host))|(?&host))(?:;|\Z))++)?)i', $dsn, $m)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the regex tail (?:;|\Z) is a bit too string, as in that it only handles one trailing ;. If the DSN (for whatever reason) ends with multiples semicolons, like:

mysql:host=127.0.0.1;port=3306;dbname=foo;;

then I believe the match would either fail (or backtrack a bunch). Perhaps the easiest fix would be to just allow "zero or more" trailing semicolons?

- ... (?:;|\Z)
+ ... ;*+\z

PS: a nit of mine would be to put the a top-level constant (e.g., DSN_REGEX), and make it multiline... Just for readability.

@bwoebi bwoebi Sep 30, 2025

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also trailing semicolons are supported thanks to (?&host), but it's not obvious. Made multiline and added a comment.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

much clearer, thanks!

@bwoebi
bwoebi force-pushed the bob/bob-optimize-parseDsn branch from 62d08c8 to b0f6933 Compare September 30, 2025 11:47
@bwoebi
bwoebi force-pushed the bob/bob-optimize-parseDsn branch from b0f6933 to 83fd76c Compare September 30, 2025 11:49
@bwoebi
bwoebi merged commit 21e1a31 into master Sep 30, 2025
1542 of 1608 checks passed
@bwoebi
bwoebi deleted the bob/bob-optimize-parseDsn branch September 30, 2025 12:03
@github-actions github-actions Bot added this to the 1.13.0 milestone Sep 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants