yii2/db/Schema uses getSlavePdo() to quote a value - which errors when fallbackToMaster is set to false
I believe
($value = $this->db->getSlavePdo()->quote($str))
should simply be
($value = $this->db->quote($str))
Why do we have to use the slave to quote a value?
What steps will reproduce the problem?
set $fallbackToMaster to false
public function getSlavePdo($fallbackToMaster = false)
public function quoteValue($str)
{
if (!is_string($str)) {
return $str;
}
if (mb_stripos($this->db->dsn, 'odbc:') === false && ($value = $this->db->getSlavePdo()->quote($str)) !== false) {
return $value;
}
// the driver doesn't support quote (e.g. oci)
return "'" . addcslashes(str_replace("'", "''", $str), "\000\n\r\\\032") . "'";
}
What is the expected result?
quoteValue should return the quotedValue
What do you get instead?
Call to a member function quote() on null

Additional info
| Q | A |
|---|---|
| Yii version | 2.0.47 |
| PHP version | 8.1 |
| Operating system | RHEL |
I can open the merge request to fix this, but I wanted to check why we call $this->db->getSlavePdo()->quote($str) when not using odbc?
if (mb_stripos($this->db->dsn, 'odbc:') === false && ($value = $this->db->getSlavePdo()->quote($str)) !== false) {
return $value;
}
@developedsoftware the logic here is:
- Always try to use replica database for quoting since using primary for that isn't great for performance.
- If it is ODBC, do not try quoting since the driver doesn't support that.
That works fine, but if you have fallbackToMaster set to false (we have overridden it in db/Connection) you get a database exception.
So I think whenever you call getSlavePdo for the purpose of quoting we should pass in fallBackToMaster as true?
We have overridden db/Connection because we want to explicitly connect to a slave and "not" fallback to the master. But as soon as we do that the framework falls over.
Have created a merge request.
The pull request looks weird to me.
$fallbackToMasteris true by default for connection.- You pass
trueexplicitly which matches the default so technically exactly the same value is passed.
How does that fix anything?
$fallbackToMaster is true by default, and when its true everything works fine.
However, if you set this to false (we do this so we can try to connec to a slave and issue a notifcation if all the slaves are offline) then you get the error above if the slave is offline.
So I thought it was best to change getSlavePdo() to pass in true when doing quoting so that we can change it in our connection class without any knock on effect.
You are right though, this should not change ANYTHING until somebody overrides the getSlavePdo method in db/Connection
Alright. That's rare case but I see now how it could be possible. Thanks for explaining.