Skip to content

Inconsistent result between run #443

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

Open
noemi-salaun opened this issue Oct 19, 2022 · 8 comments
Open

Inconsistent result between run #443

noemi-salaun opened this issue Oct 19, 2022 · 8 comments

Comments

@noemi-salaun
Copy link

I can't reproduce it on demand, but it looks like sometime phpstan-dba can infer a query result type, and 5min later, it fails on the same query.

I have a phpstan error ignored in my phpstan.neon :

'#^Method .* should return array<int, array{nbTransactions: int, platform: string}> but returns array<int, array<string, mixed>>.$#'

After installing phpstan-dba and running it successfuly, nothing change for this error.

One day later, my CI fail telling me that this ignored error isn't triggered anymore. So I tried running phpstan locally and yes, phpstan know the proper type for this query. So I remove the ignored error from my phpstan.neon, commit everything, it works.

Then 5min later, my phpstan warn me about the exact same error I just remove from ignored because it wasn't necessary anymore...

I tried removing the phpstan and phpstan-dba entirely but it keeps throwing the same error and I cannot make it detect the correct return type. The generated cache for phpstan-dba seems to vary between calls :/

@staabm
Copy link
Owner

staabm commented Oct 25, 2022

the latest phpstan release fixed some result-cache issues.
https://github.com/phpstan/phpstan/releases/tag/1.8.11

could you re-validate whether this might have fixed the underlying problem?

@noemi-salaun
Copy link
Author

I think the inconsistency came from phpstorm which autorun phpstan on the current file, so phpstan-dba cache only get info about this file and its dependencies, instead of the whole project.

But that does not explain why sometime phpstan-dba successfuly get my query return type, and sometime not.
For example, my code below :

$dbal = $this->getEntityManager()->getConnection();

$sql = <<<SQL
SELECT COUNT(bt.id) AS nbTransactions, bm.key AS platform
FROM BankTransaction bt
    JOIN BankTransactionStatus bts ON bt.statusId = bts.id
    JOIN BankMethod bm ON bt.methodId = bm.id
WHERE userId = :userId
    AND bts.status = 'paymentback_done'
GROUP BY bm.id, bm.key
SQL;

return $dbal->fetchAllAssociative($sql, ['userId' => $userId]);

If I run phpstan on my whole project, I got an empty result cache, but if I run it on this specific file, or its direct parent directory it works fine.

CLICK TO EXPAND Empty result cache when running phpstan on whole project
<?php return array (
  'schemaVersion' => 'v9-put-null-when-valid',
  'schemaHash' => 'b7adec1533cb7674c8fc90d6d83e8804',
  'records' => 
  array (
    // ... other queries
    'SELECT COUNT(bt.id) AS nbTransactions, bm.key AS platform
FROM BankTransaction bt
    JOIN BankTransactionStatus bts ON bt.statusId = bts.id
    JOIN BankMethod bm ON bt.methodId = bm.id
WHERE userId = \'1\'
    AND bts.status = \'paymentback_done\'
GROUP BY bm.id, bm.key' => 
    array (
      'error' => NULL,
    ),
    // ... other queries
  ),
  'runtimeConfig' => 
  array (
    'errorMode' => 'default',
    'debugMode' => false,
    'stringifyTypes' => false,
  ),
);

Dumped type: array<int, array<string, mixed>>

CLICK TO EXPAND Good result cache when running phpstan on this specific file
<?php return array (
  'schemaVersion' => 'v9-put-null-when-valid',
  'schemaHash' => 'b7adec1533cb7674c8fc90d6d83e8804',
  'records' => 
  array (
    // ... other queries
    'SELECT COUNT(bt.id) AS nbTransactions, bm.key AS platform
FROM BankTransaction bt
    JOIN BankTransactionStatus bts ON bt.statusId = bts.id
    JOIN BankMethod bm ON bt.methodId = bm.id
WHERE userId = \'1\'
    AND bts.status = \'paymentback_done\'
GROUP BY bm.id, bm.key' => 
    array (
      'result' => 
      array (
        5 => 
        PHPStan\Type\Constant\ConstantArrayType::__set_state(array(
           'keyType' => 
          PHPStan\Type\UnionType::__set_state(array(
             'sortedTypes' => true,
             'types' => 
            array (
              0 => 
              PHPStan\Type\Constant\ConstantIntegerType::__set_state(array(
                 'value' => 0,
              )),
              1 => 
              PHPStan\Type\Constant\ConstantIntegerType::__set_state(array(
                 'value' => 1,
              )),
              2 => 
              PHPStan\Type\Constant\ConstantStringType::__set_state(array(
                 'objectType' => NULL,
                 'value' => 'nbTransactions',
                 'isClassString' => false,
              )),
              3 => 
              PHPStan\Type\Constant\ConstantStringType::__set_state(array(
                 'objectType' => NULL,
                 'value' => 'platform',
                 'isClassString' => false,
              )),
            ),
          )),
           'itemType' => 
          PHPStan\Type\UnionType::__set_state(array(
             'sortedTypes' => false,
             'types' => 
            array (
              0 => 
              PHPStan\Type\IntegerType::__set_state(array(
              )),
              1 => 
              PHPStan\Type\StringType::__set_state(array(
              )),
            ),
          )),
           'allArrays' => NULL,
           'nextAutoIndexes' => 
          array (
            0 => 2,
          ),
           'keyTypes' => 
          array (
            0 => 
            PHPStan\Type\Constant\ConstantStringType::__set_state(array(
               'objectType' => NULL,
               'value' => 'nbTransactions',
               'isClassString' => false,
            )),
            1 => 
            PHPStan\Type\Constant\ConstantIntegerType::__set_state(array(
               'value' => 0,
            )),
            2 => 
            PHPStan\Type\Constant\ConstantStringType::__set_state(array(
               'objectType' => NULL,
               'value' => 'platform',
               'isClassString' => false,
            )),
            3 => 
            PHPStan\Type\Constant\ConstantIntegerType::__set_state(array(
               'value' => 1,
            )),
          ),
           'valueTypes' => 
          array (
            0 => 
            PHPStan\Type\IntegerType::__set_state(array(
            )),
            1 => 
            PHPStan\Type\IntegerType::__set_state(array(
            )),
            2 => 
            PHPStan\Type\StringType::__set_state(array(
            )),
            3 => 
            PHPStan\Type\StringType::__set_state(array(
            )),
          ),
           'optionalKeys' => 
          array (
          ),
        )),
      ),
    ),
    // ... other queries
  ),
  'runtimeConfig' => 
  array (
    'errorMode' => 'default',
    'debugMode' => false,
    'stringifyTypes' => false,
  ),
);

Dumped type: array<int<0, max>, array{nbTransactions: int, platform: string}>

@noemi-salaun
Copy link
Author

The issue with PHPStorm is fixed

@staabm
Copy link
Owner

staabm commented Nov 12, 2022

the linked fix was not merged. is the issue still resolved?

@noemi-salaun
Copy link
Author

Oh no my bad, I wanted to clean my issues and I forgot this fix wasnt merge yet... sorry

@noemi-salaun noemi-salaun reopened this Nov 12, 2022
@staabm
Copy link
Owner

staabm commented Nov 21, 2022

But that does not explain why sometime phpstan-dba successfuly get my query return type, and sometime not.
For example, my code below :

@noemi-salaun could you try to put this into a small repo which reproduces this problem and a small readme describing how to reproduce? sounds like something we need to fix but I am currently not able to reproduce

@staabm
Copy link
Owner

staabm commented Nov 21, 2022

in the meantime I will merge the phpstorm workaround from #454, but I would love to dig into this more with a reproducer

@noemi-salaun
Copy link
Author

I think the issue was linked to #394 (comment) because ReplayAndRecordingQueryReflector works for the first query it encounter but not the others, so when running PHPStan on the whole project, some queries works and some don't, and then when PHPStorm trigger phpstan on a single file, a different set of queries works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants