-
-
Notifications
You must be signed in to change notification settings - Fork 18
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
support for cross joins. don't error on joins of subqueries #569
Conversation
changes look good to me, but require test-cases which fail without the actual code changes |
yea, I will try to add some |
@@ -365,4 +365,18 @@ public function joinSelectOutsideCondition(PDO $pdo): void | |||
assertType('PDOStatement<array{adaid: int<-32768, 32767>, 0: int<-32768, 32767>, eadavk: numeric-string|null, 1: numeric-string|null}>', $stmt); | |||
} | |||
|
|||
public function multipleJoins(PDO $pdo): void | |||
{ | |||
$stmt = $pdo->query('SELECT adaid from ada join ak on adaid = eladaid inner join typemix on adaid = c_int'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please also select columns from within the join condition, make sure these are narrowed properly and make sure columns from joined tables not part of the condition are also narrowed properly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried, please check, is that you you had in mind?
src/SqlAst/ParserInference.php
Outdated
if ($from->getRight() instanceof TableReferenceSubquery || $from->getLeft() instanceof TableReferenceSubquery) { | ||
if (QueryReflection::getRuntimeConfiguration()->isDebugEnabled()) { | ||
throw new UnresolvableQueryMixedTypeException('Cannot narrow down types for SQLs with subqueries: ' . $queryString); | ||
} | ||
|
||
return $resultType; | ||
} | ||
|
||
if ($from instanceof InnerJoin && $from->isCrossJoin()) { | ||
if (QueryReflection::getRuntimeConfiguration()->isDebugEnabled()) { | ||
throw new UnresolvableQueryMixedTypeException('Cannot narrow down types for cross joins: ' . $queryString); | ||
} | ||
|
||
return $resultType; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we need these early returns?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it cannot collect proper data about joins and the columns hence it gives up on narrowing down the type
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but would it make a difference for the added test-cases if we just drop it here. wouldn't it give up after the loop then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
without the early return, it wouldnt work, the tests would fail
1) Error
The data provider specified for staabm\PHPStanDba\Tests\DbaInferenceTest::testFileAsserts is invalid.
Error: Call to undefined method SqlFtw\Sql\Dml\TableReference\TableReferenceSubquery::getTable()
/Users/jakubvojacek/Sites/phpstan-dba/src/SqlAst/ParserInference.php:96
/Users/jakubvojacek/Sites/phpstan-dba/src/QueryReflection/QueryReflection.php:135
/Users/jakubvojacek/Sites/phpstan-dba/src/PdoReflection/PdoStatementReflection.php:88
/Users/jakubvojacek/Sites/phpstan-dba/src/Extensions/PdoQueryDynamicReturnTypeExtension.php:106
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ahh I see.
lets keep it then, but add a new exception type to use instead of UnresolvableQueryMixedTypeException
here.
the tip for the exception should make the user aware that he triggered a case not yet supported and that it would be awesome if a repro can be reported to our issue tracker
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but that will trigger phpstan internal error and the analysis will fail and phpstan cache wont be saved,right?I originally had the exception there but it was so annoying when running on my codebase that I decided to hide it behind debug flag.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it should work when we create a new subclass of UnresolvableQueryException
similar to how we did with https://github.com/staabm/phpstan-dba/blob/main/src/UnresolvableQueryMixedTypeException.php which seems to work for you atm
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
e.g. UnresolvableAstInQueryException
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so you want me to rename UnresolvableQueryMixedTypeException
to UnresolvableAstInQueryException
on those three places that it thrown in ParserInference right?
I checked where UnresolvableQueryMixedTypeException was used and its only on one place and its after the QueryReflection::getRuntimeConfiguration()->isDebugEnabled()
condition as well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nope, I want you to create a new exception class and use it here in this few places of this PR, but leave UnresolvableQueryMixedTypeException
as is across the codebase
UnresolvableQueryMixedTypeException
signals that a query cannot be resolved - meaning we are not able to figure out the query string at all.
in our scenario here, we already know the query string but are not (yet?) able to analyse it with AST properly (since we did not yet implement everything you can express with sql)
|
||
public function ignoredAstQueries(PDO $pdo): void | ||
{ | ||
$pdo->query('SELECT adaid from ada inner join (select akid from ak) on akid = adaid'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we are missing a assertion for this line
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
because it has a different output for pdo-mysql
and mysqli
reflectors (but that is unrelated to AST analysis since we give up on that due to the subquery)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
without an assertion this line does not have value. what is the difference between the reflectors regarding this statement?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
my bad, must have been doing something wrong back then when i was testing. I just pushed a new assertion, hopefully CI will be green
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thank you
The changes works fine for my codebase