From 4b7dbe2437f64881dae861692ec27d17c6fda177 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B8=D1=82=D1=80=D0=BE=D1=84=D0=B0=D0=BD=D0=BE?= =?UTF-8?q?=D0=B2=20=D0=9D=D0=B8=D0=BA=D0=BE=D0=BB=D0=B0=D0=B9?= Date: Thu, 21 Jun 2018 10:41:13 +0300 Subject: [PATCH] fix process of inserting string with a question mark --- src/ClickHouseStatement.php | 27 ++++++++++++++++++++------- tests/InsertTest.php | 14 ++++++++++++++ 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/ClickHouseStatement.php b/src/ClickHouseStatement.php index dc019c4..8f3a65f 100644 --- a/src/ClickHouseStatement.php +++ b/src/ClickHouseStatement.php @@ -264,18 +264,31 @@ public function errorInfo() */ public function execute($params = null) { + $hasZeroIndex = false; if (\is_array($params)) { $this->values = array_replace($this->values, $params);//TODO array keys must be all strings or all integers? + $hasZeroIndex = array_key_exists(0, $params); } $sql = $this->statement; - foreach (array_keys($this->values) as $key) { - $sql = preg_replace( - '/(' . (\is_int($key) ? '\?' : ':' . $key) . ')/i', - $this->getTypedParam($key), - $sql, - 1 - ); + + if ($hasZeroIndex) { + $statementParts = explode('?', $sql); + array_walk($statementParts, function (&$part, $key) { + if (array_key_exists($key, $this->values)) { + $part .= $this->getTypedParam($key); + } + }); + $sql = implode('', $statementParts); + } else { + foreach (array_keys($this->values) as $key) { + $sql = preg_replace( + '/(' . (\is_int($key) ? '\?' : ':' . $key) . ')/i', + $this->getTypedParam($key), + $sql, + 1 + ); + } } $this->processViaSMI2($sql); diff --git a/tests/InsertTest.php b/tests/InsertTest.php index 01b7d7a..59be336 100644 --- a/tests/InsertTest.php +++ b/tests/InsertTest.php @@ -80,4 +80,18 @@ public function testInsertViaQueryBuilder() $this->assertEquals([['payload' => 'v5'], ['payload' => 'v6']], $this->connection->fetchAll("SELECT payload from test_insert_table WHERE id IN (5, 6) ORDER BY id")); } + + public function testStatementInsertWithoutKeyName() + { + $statement = $this->connection->prepare('INSERT INTO test_insert_table(id, payload) VALUES (?, ?), (?, ?)'); + $statement->execute([7, 'v?7', 8, 'v8']); + $this->assertEquals([['payload' => 'v?7'], ['payload' => 'v8']], $this->connection->fetchAll("SELECT payload from test_insert_table WHERE id IN (7, 8) ORDER BY id")); + } + + public function testStatementInsertWithKeyName() + { + $statement = $this->connection->prepare('INSERT INTO test_insert_table(id, payload) VALUES (:v0, :v1), (:v2, :v3)'); + $statement->execute(['v0' => 9, 'v1' => 'v?9', 'v2' => 10, 'v3' => 'v10']); + $this->assertEquals([['payload' => 'v?9'], ['payload' => 'v10']], $this->connection->fetchAll("SELECT payload from test_insert_table WHERE id IN (9, 10) ORDER BY id")); + } }