Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Limit is treated as a string #166

Open
jerome2710 opened this issue Jan 17, 2022 · 7 comments
Open

Limit is treated as a string #166

jerome2710 opened this issue Jan 17, 2022 · 7 comments
Assignees
Labels
Milestone

Comments

@jerome2710
Copy link

As the statement is executed as $stmt->execute($this->getValues()), any integers will be added to the parameters as strings. This results in an SQL-error for LIMIT, as this needs to be an integer.

SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''999'' at line 1
@jerome2710
Copy link
Author

Any updates regarding this matter?

@kwhat kwhat self-assigned this Jul 20, 2022
@kwhat kwhat added the bug label Jul 20, 2022
@kwhat
Copy link
Collaborator

kwhat commented Jul 20, 2022

I'll take a look this week. Please bug me if I don' get back to you by Friday.

@kwhat
Copy link
Collaborator

kwhat commented Jul 22, 2022

Can you provide code to duplicate the issue.

@jerome2710
Copy link
Author

Can you provide code to duplicate the issue.

Sure, but it is nothing special:

$result = $this->database
    ->select()
    ->from('table-name')
    ->limit(5)
    ->execute();

Results in:

SERVER_ERROR 500 - SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''5'' at line 1

Probably because executing the statement while passing parameters will treat them as:

@param array $params [optional]
* An array of values with as many elements as there are bound
* parameters in the SQL statement being executed.
* All values are treated as PDO::PARAM_STR.

While the limit should be an integer.

@kwhat
Copy link
Collaborator

kwhat commented Aug 10, 2022

I am not sure how you did this, I cannot duplicate the issue with MariaDB 10.2. Do you have a specific database configuration that is causing this error? I am going to need a lot more info about how this is happening.

$db = new Database(
    'mysql:host=127.0.0.1;dbname=testing;charset=utf8mb4',
    'root',
    null
);

var_dump(
    $db->select(['id'])
        ->from('test')
        ->limit(new Limit(10))
        ->__toString()
); 

// string(30) "SELECT id FROM tbluser LIMIT ?"

$result = $db->select(['id'])
    ->from('test')
    ->limit(new Limit(10))
    ->execute();

var_dump($result->fetchAll());

/*
array(10) {
  [0]=>
  array(1) {
    ["id"]=>
    int(31)
  }
  [1]=>
  array(1) {
    ["id"]=>
    int(90090)
  }
  [2]=>
  array(1) {
    ["id"]=>
    int(1)
  }
  [3]=>
  array(1) {
    ["id"]=>
    int(11)
  }
  [4]=>
  array(1) {
    ["id"]=>
    int(21)
  }
  [5]=>
  array(1) {
    ["id"]=>
    int(41)
  }
  [6]=>
  array(1) {
    ["id"]=>
    int(51)
  }
  [7]=>
  array(1) {
    ["id"]=>
    int(61)
  }
  [8]=>
  array(1) {
    ["id"]=>
    int(71)
  }
  [9]=>
  array(1) {
    ["id"]=>
    int(81)
  }
}
*/

@kwhat
Copy link
Collaborator

kwhat commented Aug 11, 2022

I figured it out... somehow you've managed to enable PDO::ATTR_EMULATE_PREPARES.

@kwhat kwhat added this to the 2.2.2 milestone Aug 11, 2022
@kwhat
Copy link
Collaborator

kwhat commented Aug 11, 2022

You can try this patch, I am not sure this wont cause other interesting side effects with decimal or enum types.

diff --git a/src/AbstractStatement.php b/src/AbstractStatement.php
index e644774..e4b5d64 100644
--- a/src/AbstractStatement.php
+++ b/src/AbstractStatement.php
@@ -33,7 +33,16 @@ abstract class AbstractStatement implements StatementInterface
     {
         $stmt = $this->dbh->prepare($this->__toString());
         if ($stmt !== false) {
-            $stmt->execute($this->getValues());
+            foreach ($this->getValues() as $i => $value) {
+                $type = PDO::PARAM_STR;
+                if (is_int($value)) {
+                    $type = PDO::PARAM_INT;
+                }
+
+                $stmt->bindParam($i + 1, $value, $type);
+            }
+
+            $stmt->execute();
         }
 
         return $stmt;

kwhat added a commit to kwhat/PDO that referenced this issue Aug 11, 2022
kwhat added a commit to kwhat/PDO that referenced this issue Aug 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants