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

AST doubts regarding null/not-null #577

Closed
jakubvojacek opened this issue Mar 16, 2023 · 4 comments · Fixed by #579
Closed

AST doubts regarding null/not-null #577

jakubvojacek opened this issue Mar 16, 2023 · 4 comments · Fixed by #579

Comments

@jakubvojacek
Copy link
Contributor

Hello @staabm

I am not sure if the AST narrow type down of min/max/avg (and perhaps more functions) is working properly.

For example test (https://github.com/staabm/phpstan-dba/blob/main/tests/default/data/sql-ast-narrowing.php#L219)

$stmt = $pdo->query('SELECT avg(freigabe1u1) as avg from ada');
assertType('PDOStatement<array{avg: int<-128, 127>, 0: int<-128, 127>}>', $stmt);

phpstan-dba thinks that avg will never be null. But it will in case ada is an empty table (or when there'd be some where condition returning zero rows), right?

mysql> truncate ada;
Query OK, 0 rows affected (0.03 sec)

mysql> SELECT avg(freigabe1u1) as avg from ada;
+------+
| avg  |
+------+
| NULL |
+------+
1 row in set (0.01 sec)

it can return null but phpstan will think that there will never be null.

Is that correct behaviour? Am I missing here something, please?

@staabm
Copy link
Owner

staabm commented Mar 16, 2023

But it will in case ada is an empty table

this is a fact that I learned today. I think its a pretty rare scenario that tables are empty.. I don't have a idea/opinion yet on this. I am open to discussion :)

most important in the end is, what the actual DB API which is beeing used returns at this point.
so even if mysql returns a plain NULL, this might not necessarily mean that you also get that NULL from PDO/mysqli/dibi/..

or when there'd be some where condition returning zero rows

learning/narrowing types from WHERE is a open todo.

also using the correct types when result sets are empty (might be the same as when tables are empty)

@jakubvojacek
Copy link
Contributor Author

jakubvojacek commented Mar 16, 2023

well, the table can either be empty or the where/join condition will make the resulting set empty.

Either way, min/max/avg can be nullable in certain conditions that cannot be determined via AST (or can they?)

I think that the only correct solution is to make the returning type nullable?

@hemberger
Copy link
Contributor

I think that the only correct solution is to make the returning type nullable?

I agree with this. Most aggregate functions (notably: avg, max, min, std, sum, variance) return null if the result set is empty, and so if the result set can be empty, then I think the return type should be nullable.

@staabm
Copy link
Owner

staabm commented Mar 17, 2023

I agree that at AST level we should leave it null, unless we properly can detect non null result-sets

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

Successfully merging a pull request may close this issue.

3 participants