Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.Sign up
Error while binding short string with slash suffix #177
Get error syntax exception, when mixing short (with suffix ) and long string parameters binding to INSERT or UPDATE query (maybe there are probably more scenarios to get this error).
Steps To Reproduce
I have tested this with PostqreSQL. Let's create this simple table:
CREATE TABLE test ( col1 text, col2 text, col3 text );
Then run this command:
/** @var \Nette\Database\Context $context */ $context->table('test')->insert([ 'col1' => 'some text \\', // shorter than 20 'col2' => 'some text longer than 20 characters', 'col3' => 'some text', // shorter than 20 ]);
This exception is thrown:
This behavior is probably fixed in 3.0.0-alpha with commit 644b587. To fix this in 2.4 branch it is possible to change SqlPreprocessor->formatValue to bind all strings as variable, not only strings longer than 20 characters. Bud I don't why this logic is there, maybe this update could be BC?
According to the PostqreSQL documentation, everything is ok: https://www.postgresql.org/docs/8.2/static/sql-syntax-lexical.html#SQL-SYNTAX-STRINGS
There are a mention switches
This is some bug in PDO parameters binding. The
IMHO the bug is in internal PDO values binding code when they are looking for
Focus on the
Code to reproduce:
$pdo = new PDO('pgsql:host=localhost;dbname=test', 'test', 'test'); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $pdo->query('SET standard_conforming_strings TO on'); $stmt = $pdo->prepare("INSERT INTO test (col1, col2, col3) VALUES ('\\', ?, '')"); $stmt->bindValue(1, 'x', PDO::PARAM_STR); $stmt->execute();
If you don't, I'll report PHP bug in the evening.
We have solved it by workaround because sending all strings as parameters causes incompatibility in PostgreSQL:
On the other hand, this behavior relies on the 20-character limit, so maybe a BC break could be done in 2.4.
I don't think so. With ATTR_EMULATE_PREPARES = false it uses PostgreSQL
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, true); # PG log # LOG: statement: INSERT INTO test (col1, col2, col3) VALUES ('a', 'x', ' ') $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); # PG log # LOG: execute pdo_stmt_00000001: INSERT INTO test (col1, col2, col3) VALUES ('a', $1, ' ') # DETAIL: parameters: $1 = 'x'
But with buggy query from this issue, it fails in the same way in both cases:
It seems to me that issue appears only when some string ends with
$stmt = $pdo->prepare("INSERT INTO test (col1, col2, col3) VALUES ('\\', ?, ' ')"); # BUGGY $stmt = $pdo->prepare("INSERT INTO test (col1, col2, col3) VALUES ('\\ ', ?, ' ')"); # OK $stmt = $pdo->prepare("INSERT INTO test (col1, col2) VALUES ('\\', ?)"); # OK