Skip to content

Conversation

@timacdonald
Copy link
Member

@timacdonald timacdonald commented Dec 18, 2025

This PR exposes the read / write type to the query executed event and query exceptions for better debugging and logging.

I've found there isn't a bulletproof way to determine this with what Laravel already exposes. You can get it right in 95% of cases, but there are certain scenarios where it is impossible to know for sure if a query was against the read or write connection.

This method of tracking the last resolved PDO, although feeling a little weird, is the best way I can see of making this correct in all cases.

@github-actions
Copy link

Thanks for submitting a PR!

Note that draft PR's are not reviewed. If you would like a review, please mark your pull request as ready for review in the GitHub user interface.

Pull requests that are abandoned in draft may be closed due to inactivity.

Comment on lines -50 to +58
public function __construct($sql, $bindings, $time, $connection)
public function __construct($sql, $bindings, $time, $connection, $readWriteType = null)
Copy link
Member Author

@timacdonald timacdonald Dec 18, 2025

Choose a reason for hiding this comment

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

Constructor remains backwards compatible.

@timacdonald
Copy link
Member Author

cc @avosalmon 👀

*/
protected function latestPdoTypeUsed()
{
return $this->readWriteType ?? $this->latestPdoTypeUsed;
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this always return $this->latestPdoTypeUsed if we want to know the actual PDO that was used to run the query?

$this->readWriteType does not tell the real read/write type that was actually used.
If you run the following query, it sets the readWriteType to write, but it still uses the read connection as it's a select query.

DB::connection('pgsql::write')->table('users')->count();

Copy link
Member Author

Choose a reason for hiding this comment

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

@avosalmon, when using the explicit ::write or ::read connection, although both the read and write PDO properties are populated, they contain the same PDO instance once both resolved, for example:

// file: config/database.php

    'connections' => [
        'sqlite' => [
            // ...
            'write' => [
                'database' => env('DB_DATABASE', database_path('database.write.sqlite')),
            ],
            'read' => [
                'database' => env('DB_DATABASE', database_path('database.read.sqlite')),
            ],
            // ...
        ],
Artisan::command('dev', function () {
    DB::connection('sqlite')->select('select 1');
    DB::connection('sqlite')->statement('select 1');
    dump(DB::connection('sqlite')->getRawReadPdo() === DB::connection('sqlite')->getRawPdo());

    DB::connection('sqlite::read')->select('select 1');
    DB::connection('sqlite::read')->statement('select 1');
    dump(DB::connection('sqlite::read')->getRawReadPdo() === DB::connection('sqlite::read')->getRawPdo());

    DB::connection('sqlite::write')->select('select 1');
    DB::connection('sqlite::write')->statement('select 1');
    dump(DB::connection('sqlite::write')->getRawReadPdo() === DB::connection('sqlite::write')->getRawPdo());
});
Screenshot 2025-12-18 at 19 28 55

If we don't respect the readWriteType value, then it could incorrectly say you are using the write PDO when you are using the read PDO. Keep in mind that we are talking about the actual configured PDO regardless of what property it is attached to.

In your example, DB::connection('pgsql::write')->table('users')->count(); is using the configured write connection, which is what we care about as a consumer of the read / write type.

@timacdonald timacdonald force-pushed the read-write-connections branch from d3e3cda to ce55981 Compare December 19, 2025 02:28
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.

2 participants