From 454449b6f3c156251d7ca323ffc7e8eb652b85cc Mon Sep 17 00:00:00 2001 From: Simon Mundy Date: Sat, 3 Oct 2026 21:47:15 +1000 Subject: [PATCH 1/2] Throw InvalidArgumentException for join names without a leading string An invalid join name array whose first element was not a string, such as an empty array or an unaliased Select, reached forInvalidJoinName() with a non-string and raised a TypeError. The message now names the element's type instead. Signed-off-by: Simon Mundy --- analyzer-baseline.toml | 4 ++-- src/Sql/Join.php | 7 ++++++- test/unit/Sql/JoinTest.php | 25 +++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/analyzer-baseline.toml b/analyzer-baseline.toml index 6a0f82f4..8a0cea35 100644 --- a/analyzer-baseline.toml +++ b/analyzer-baseline.toml @@ -3488,8 +3488,8 @@ count = 1 [[issues]] file = "src/Sql/Join.php" -code = "mixed-argument" -message = 'Invalid argument type for argument #1 of `PhpDb\Sql\Exception\InvalidArgumentException::forInvalidJoinName`: expected `string`, but found `mixed`.' +code = "mixed-assignment" +message = "Assigning `mixed` type to a variable may lead to unexpected behavior." count = 1 [[issues]] diff --git a/src/Sql/Join.php b/src/Sql/Join.php index c4bba6d3..1d967bbb 100644 --- a/src/Sql/Join.php +++ b/src/Sql/Join.php @@ -11,6 +11,7 @@ use function array_shift; use function count; +use function get_debug_type; use function is_array; use function is_string; use function key; @@ -94,7 +95,11 @@ public function join( string $type = self::JOIN_INNER, ): static { if (is_array($name) && (! is_string(key($name)) || count($name) !== 1)) { - throw Exception\InvalidArgumentException::forInvalidJoinName(array_shift($name)); + $first = array_shift($name); + + throw Exception\InvalidArgumentException::forInvalidJoinName( + is_string($first) ? $first : get_debug_type($first), + ); } if (! is_array($columns)) { diff --git a/test/unit/Sql/JoinTest.php b/test/unit/Sql/JoinTest.php index 89e3cfe2..9e004491 100644 --- a/test/unit/Sql/JoinTest.php +++ b/test/unit/Sql/JoinTest.php @@ -9,6 +9,7 @@ use PhpDb\Sql\Select; use PhpDbTest\DeprecatedAssertionsTrait; use PHPUnit\Framework\Attributes\CoversMethod; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\IgnoreDeprecations; use PHPUnit\Framework\Attributes\RequiresPhp; use PHPUnit\Framework\Attributes\Test; @@ -32,6 +33,16 @@ class JoinTest extends TestCase { use DeprecatedAssertionsTrait; + /** @return array, string}> */ + public static function invalidJoinNameWithoutStringElementProvider(): array + { + return [ + 'empty array' => [[], 'null'], + 'select without alias' => [[new Select('foo')], Select::class], + 'integer element' => [[5], 'int'], + ]; + } + #[Test] #[TestDox('unit test: Test count() returns correct count')] public function countsJoinedTables(): void @@ -91,6 +102,20 @@ public function joinFullOuter(): void static::assertSame($join, $return); } + /** + * @param array $name + */ + #[Test] + #[DataProvider('invalidJoinNameWithoutStringElementProvider')] + public function joinThrowsInvalidArgumentWhenInvalidNameHasNoLeadingString(array $name, string $described): void + { + $join = new Join(); + + self::expectException(InvalidArgumentException::class); + self::expectExceptionMessage("expects '{$described}' as a single element associative array"); + $join->join($name, 'on'); + } + #[Test] public function joinThrowsOnInvalidMultiElementArray(): void { From 2f0c6ed383a5ee1151266527c067f608eb513475 Mon Sep 17 00:00:00 2001 From: Simon Mundy Date: Thu, 8 Oct 2026 20:43:27 +1100 Subject: [PATCH 2/2] Apply mago 1.53 formatting to AbstractSource Signed-off-by: Simon Mundy --- src/Metadata/Source/AbstractSource.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Metadata/Source/AbstractSource.php b/src/Metadata/Source/AbstractSource.php index 3638d561..e91ebded 100644 --- a/src/Metadata/Source/AbstractSource.php +++ b/src/Metadata/Source/AbstractSource.php @@ -300,10 +300,8 @@ public function getConstraintKeys(string $constraint, string $table, ?string $sc foreach ($this->data['constraint_keys'][$schema] ?? [] as $constraintKeyInfo) { if ( ! ( - - $constraintKeyInfo['table_name'] === $table - && $constraintKeyInfo['constraint_name'] === $constraint - + $constraintKeyInfo['table_name'] === $table + && $constraintKeyInfo['constraint_name'] === $constraint ) ) { continue;