phpstan-dba icon indicating copy to clipboard operation
phpstan-dba copied to clipboard

Support for (PDO->prepare())->execute()

Open thbley opened this issue 1 year ago • 6 comments

Currently I'm not getting any errors/hints for (PDO->prepare())->execute(). It would be nice to have support for (PDO->prepare())->execute().

e.g.

        $dsn = sprintf('mysql:host=%s;dbname=%s;port=3306;charset=utf8mb4;', 'host', 'database');
        $pdo = new PDO($dsn, 'username', 'password', []);
        $query = '... query ...';
        $statement = $pdo->prepare($query);
        $statement->execute([...bind values...]);
        $result = $statement->fetchAll();

configuration used:

$config = new RuntimeConfiguration();
$config->analyzeQueryPlans(true);
$config->utilizeSqlAst(true);

$dsn = sprintf('mysql:host=%s;dbname=%s;port=3306;charset=utf8mb4;', 'host', 'database');
$pdo = new PDO($dsn, 'username', 'password', []);

QueryReflection::setupReflector(
    new ReplayAndRecordingQueryReflector(
        ReflectionCache::create($cacheFile),
        new PdoMysqlQueryReflector($pdo),
        new SchemaHasherMysql($pdo)
    ),
    $config
);

Version tested: 0.2.72

Thanks!

thbley avatar May 25 '23 14:05 thbley

no error (but table tasks_invalid does not exist):

        $pdo = new \PDO('mysql:host=mysql;dbname=tasks;port=3306;charset=utf8mb4;', 'root', 'root');
        $query = 'SELECT id, title, duedate, completed, last_updated_by FROM tasks_invalid WHERE customer_id = ? AND completed = 1';
        $statement = $pdo->prepare($query);
        $statement->execute([123]);
        $result = $statement->fetch();

Query error: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'tasks.tasks_invalid' doesn't exist (42S02).

        $pdo = new \PDO('mysql:host=mysql;dbname=tasks;port=3306;charset=utf8mb4;', 'root', 'root');
        $query = 'SELECT id, title, duedate, completed, last_updated_by FROM tasks_invalid WHERE customer_id = 123 AND completed = 1';
        $statement = $pdo->prepare($query);
        $statement->execute([]);
        $result = $statement->fetch();

thbley avatar May 25 '23 14:05 thbley

Another example:

no error (but table task_invalid does not exist):

        $pdo = new \PDO('mysql:host=mysql;dbname=tasks;port=3306;charset=utf8mb4;', 'root', 'root');
        $ids = implode(',', array_map(intval(...), [1,2,3]));
        $query = sprintf('SELECT id, title, duedate, completed, last_updated_by FROM task_invalid WHERE id IN (%s)', $ids);
        $statement = $pdo->query($query);

Query error: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'tasks.task_invalid' doesn't exist (42S02).

        $pdo = new \PDO('mysql:host=mysql;dbname=tasks;port=3306;charset=utf8mb4;', 'root', 'root');
        $ids = '1,2,3';
        $query = sprintf('SELECT id, title, duedate, completed, last_updated_by FROM task_invalid WHERE id IN (%s)', $ids);
        $statement = $pdo->query($query);

thbley avatar May 25 '23 14:05 thbley

thanks for the report.

please try enabling debugMode and see whether you get a usefull error.

can you reproduce the error in a small repository?

staabm avatar May 25 '23 14:05 staabm

<?php

$pdo = new \PDO('mysql:host=mysql;dbname=tasks;port=3306;charset=utf8mb4;', 'root', 'root');
$ids = implode(',', array_map(intval(...), [1,2,3]));
$query = sprintf('SELECT id, title, duedate, completed, last_updated_by FROM task_invalid WHERE id IN (%s)', $ids);
$statement = $pdo->query($query);
print_r($statement->fetchAll());

$pdo = new \PDO('mysql:host=mysql;dbname=tasks;port=3306;charset=utf8mb4;', 'root', 'root');
$query = sprintf('SELECT id, title, duedate, completed, last_updated_by FROM task_invalid WHERE id IN (%s)', '1,2,3');
$statement = $pdo->query($query);
print_r($statement->fetchAll());

$pdo = new \PDO('mysql:host=mysql;dbname=tasks;port=3306;charset=utf8mb4;', 'root', 'root');
$query = 'SELECT id, title, duedate, completed, last_updated_by FROM tasks_invalid WHERE customer_id = ? AND completed = 1';
$statement = $pdo->prepare($query);
$statement->execute([123]);
$result = $statement->fetch();

$pdo = new \PDO('mysql:host=mysql;dbname=tasks;port=3306;charset=utf8mb4;', 'root', 'root');
$query = 'SELECT id, title, duedate, completed, last_updated_by FROM tasks_invalid WHERE customer_id = 123 AND completed = 1';
$statement = $pdo->prepare($query);
$statement->execute([]);
$result = $statement->fetch();

gives:

 ------ --------------------------------------------------------------------------------------------------------------------- 
  Line   test.php                                                                                                             
 ------ --------------------------------------------------------------------------------------------------------------------- 
  6      Unresolvable Query: Cannot resolve query with variable type: non-falsy-string.                                       
         💡 Consider replacing concatenated string-variables with prepared statements or @phpstandba-inference-placeholder.   
  6      Unresolvable Query: Cannot resolve query with variable type: non-falsy-string.                                       
         💡 Consider replacing concatenated string-variables with prepared statements or @phpstandba-inference-placeholder.   
  11     Query error: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'tasks.task_invalid' doesn't exist (42S02).   
  22     Query error: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'tasks.tasks_invalid' doesn't exist (42S02).  
 ------ --------------------------------------------------------------------------------------------------------------------- 

thbley avatar May 25 '23 15:05 thbley

here is the repository and the pipeline: https://github.com/thbley/phpstan_dba https://github.com/thbley/phpstan_dba/actions/runs/5081767755/jobs/9130588776

thbley avatar May 25 '23 15:05 thbley

Closing due to inactivity of project maintainer.

thbley avatar Oct 03 '23 03:10 thbley