Compare commits

...

16 Commits
3.6.1 ... 3.6.x

Author SHA1 Message Date
Alexander M. Turek
27c33cf88d Merge branch '2.20.x' into 3.6.x
* 2.20.x:
  Make the data provider static
  Raise proper exception for invalid arguments in Base::add() (#12394)
2026-03-12 09:31:56 +01:00
Alexander M. Turek
6068b61a0d Make the data provider static 2026-03-12 09:24:03 +01:00
Alexander M. Turek
00024f7d88 Raise proper exception for invalid arguments in Base::add() (#12394) 2026-03-12 09:05:27 +01:00
Alexander M. Turek
331f8b52cb Merge branch '2.20.x' into 3.6.x
* 2.20.x:
  Fix code style (#12395)
  Bump actions/upload-artifact from 6 to 7 (#12387)
  Bump actions/download-artifact from 7 to 8 (#12386)
2026-03-11 16:55:13 +01:00
Alexander M. Turek
b2faba62b7 Fix code style (#12395) 2026-03-11 16:51:15 +01:00
dependabot[bot]
da426a0036 Bump actions/upload-artifact from 6 to 7 (#12387)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 6 to 7.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-05 00:34:23 +01:00
dependabot[bot]
1891a76f13 Bump actions/download-artifact from 7 to 8 (#12386)
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 7 to 8.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v7...v8)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '8'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-05 00:33:50 +01:00
vvaswani
4262eb495b fix: update index to be serialized in __sleep() (#12366)
Signed-off-by: Vikram Vaswani <2571660+vvaswani@users.noreply.github.com`>
2026-01-30 22:41:41 +01:00
Grégoire Paris
d3b47d2cbb Merge pull request #12355 from doctrine/2.20.x
Merge 2.20.x up into 3.6.x
2026-01-25 12:48:28 +01:00
Grégoire Paris
026f5bfe1b Merge pull request #12350 from greg0ire/missing-order-by
Add missing ORDER BY clause
2026-01-18 10:41:46 +01:00
Grégoire Paris
0b0f2f4d86 Add missing ORDER BY clause
This causes transient failures with PostgreSQL. Order is not guaranteed.
2026-01-17 13:39:44 +01:00
Grégoire Paris
0bd839a720 Merge pull request #12345 from greg0ire/3.6.x
Merge 2.20.x up into 3.6.x
2026-01-16 18:27:03 +01:00
Grégoire Paris
b65004fc26 Merge remote-tracking branch 'origin/2.20.x' into 3.6.x 2026-01-16 18:24:38 +01:00
Grégoire Paris
d2418ab074 Merge pull request #12344 from greg0ire/update-baseline
Update PHPStan baseline
2026-01-15 23:38:15 +01:00
Grégoire Paris
39a05e31c9 Update PHPStan baseline
This is caused by the release of doctrine/collections 2.7.0. The error
message is a bit shorter now.
2026-01-15 20:13:05 +01:00
sasezaki
ab156a551c Update phpstan-dbal2 to phpstan-dbal3 in .gitattributes (#12343) 2026-01-12 12:53:04 +01:00
12 changed files with 44 additions and 34 deletions

2
.gitattributes vendored
View File

@@ -15,6 +15,6 @@ phpcs.xml.dist export-ignore
phpbench.json export-ignore
phpstan.neon export-ignore
phpstan-baseline.neon export-ignore
phpstan-dbal2.neon export-ignore
phpstan-dbal3.neon export-ignore
phpstan-params.neon export-ignore
phpstan-persistence2.neon export-ignore

View File

@@ -150,7 +150,7 @@ jobs:
ENABLE_NATIVE_LAZY_OBJECTS: ${{ matrix.native_lazy }}
- name: "Upload coverage file"
uses: "actions/upload-artifact@v6"
uses: "actions/upload-artifact@v7"
with:
name: "phpunit-${{ matrix.extension }}-${{ matrix.php-version }}-${{ matrix.dbal-version }}-${{ matrix.deps }}-${{ matrix.stability }}-${{ matrix.native_lazy }}-coverage"
path: "coverage*.xml"
@@ -265,7 +265,7 @@ jobs:
run: "vendor/bin/phpunit -c ci/github/phpunit/pdo_pgsql.xml --coverage-clover=coverage.xml"
- name: "Upload coverage file"
uses: "actions/upload-artifact@v6"
uses: "actions/upload-artifact@v7"
with:
name: "${{ github.job }}-${{ matrix.postgres-version }}-${{ matrix.php-version }}-${{ matrix.dbal-version }}-${{ matrix.extension }}-coverage"
path: "coverage.xml"
@@ -339,7 +339,7 @@ jobs:
run: "vendor/bin/phpunit -c ci/github/phpunit/${{ matrix.extension }}.xml --coverage-clover=coverage.xml"
- name: "Upload coverage file"
uses: "actions/upload-artifact@v6"
uses: "actions/upload-artifact@v7"
with:
name: "${{ github.job }}-${{ matrix.mariadb-version }}-${{ matrix.extension }}-${{ matrix.php-version }}-${{ matrix.dbal-version }}-coverage"
path: "coverage.xml"
@@ -442,7 +442,7 @@ jobs:
ENABLE_SECOND_LEVEL_CACHE: 1
- name: "Upload coverage files"
uses: "actions/upload-artifact@v6"
uses: "actions/upload-artifact@v7"
with:
name: "${{ github.job }}-${{ matrix.mysql-version }}-${{ matrix.extension }}-${{ matrix.php-version }}-${{ matrix.dbal-version }}-coverage"
path: "coverage*.xml"
@@ -465,7 +465,7 @@ jobs:
fetch-depth: 2
- name: "Download coverage files"
uses: "actions/download-artifact@v7"
uses: "actions/download-artifact@v8"
with:
path: "reports"

View File

@@ -619,7 +619,7 @@ parameters:
path: src/EntityRepository.php
-
message: '#^Method Doctrine\\ORM\\EntityRepository\:\:matching\(\) should return Doctrine\\Common\\Collections\\AbstractLazyCollection\<int, T of object\>&Doctrine\\Common\\Collections\\Selectable\<int, T of object\> but returns Doctrine\\ORM\\LazyCriteriaCollection\<\(int\|string\), object\>\.$#'
message: '#^Method Doctrine\\ORM\\EntityRepository\:\:matching\(\) should return Doctrine\\Common\\Collections\\AbstractLazyCollection\<int, T of object\> but returns Doctrine\\ORM\\LazyCriteriaCollection\<\(int\|string\), object\>\.$#'
identifier: return.type
count: 1
path: src/EntityRepository.php
@@ -2580,30 +2580,12 @@ parameters:
count: 1
path: src/Query/Exec/SingleTableDeleteUpdateExecutor.php
-
message: '#^PHPDoc type array\<string\> of property Doctrine\\ORM\\Query\\Expr\\Andx\:\:\$allowedClasses is not covariant with PHPDoc type list\<class\-string\> of overridden property Doctrine\\ORM\\Query\\Expr\\Base\:\:\$allowedClasses\.$#'
identifier: property.phpDocType
count: 1
path: src/Query/Expr/Andx.php
-
message: '#^Method Doctrine\\ORM\\Query\\Expr\\Func\:\:getArguments\(\) should return list\<mixed\> but returns array\<mixed\>\.$#'
identifier: return.type
count: 1
path: src/Query/Expr/Func.php
-
message: '#^PHPDoc type array\<string\> of property Doctrine\\ORM\\Query\\Expr\\Orx\:\:\$allowedClasses is not covariant with PHPDoc type list\<class\-string\> of overridden property Doctrine\\ORM\\Query\\Expr\\Base\:\:\$allowedClasses\.$#'
identifier: property.phpDocType
count: 1
path: src/Query/Expr/Orx.php
-
message: '#^PHPDoc type array\<string\> of property Doctrine\\ORM\\Query\\Expr\\Select\:\:\$allowedClasses is not covariant with PHPDoc type list\<class\-string\> of overridden property Doctrine\\ORM\\Query\\Expr\\Base\:\:\$allowedClasses\.$#'
identifier: property.phpDocType
count: 1
path: src/Query/Expr/Select.php
-
message: '#^Method Doctrine\\ORM\\Query\\ParameterTypeInferer\:\:inferType\(\) never returns int so it can be removed from the return type\.$#'
identifier: return.unusedType

View File

@@ -142,7 +142,7 @@ final class FieldMapping implements ArrayAccess
{
$serialized = ['type', 'fieldName', 'columnName'];
foreach (['nullable', 'notInsertable', 'notUpdatable', 'id', 'unique', 'version', 'quoted'] as $boolKey) {
foreach (['nullable', 'notInsertable', 'notUpdatable', 'id', 'unique', 'version', 'quoted', 'index'] as $boolKey) {
if ($this->$boolKey) {
$serialized[] = $boolKey;
}

View File

@@ -4,6 +4,8 @@ declare(strict_types=1);
namespace Doctrine\ORM\Query\Expr;
use Stringable;
/**
* Expression class for building DQL and parts.
*
@@ -13,7 +15,7 @@ class Andx extends Composite
{
protected string $separator = ' AND ';
/** @var string[] */
/** @var list<class-string<Stringable>> */
protected array $allowedClasses = [
Comparison::class,
Func::class,

View File

@@ -13,6 +13,7 @@ use function get_debug_type;
use function implode;
use function in_array;
use function is_array;
use function is_object;
use function is_string;
use function sprintf;
@@ -27,7 +28,7 @@ abstract class Base implements Stringable
protected string $separator = ', ';
protected string $postSeparator = ')';
/** @var list<class-string> */
/** @var list<class-string<Stringable>> */
protected array $allowedClasses = [];
/** @var list<string|Stringable> */
@@ -58,6 +59,8 @@ abstract class Base implements Stringable
}
/**
* @param string|Stringable|null $arg
*
* @return $this
*
* @throws InvalidArgumentException
@@ -66,7 +69,8 @@ abstract class Base implements Stringable
{
if ($arg !== null && (! $arg instanceof self || $arg->count() > 0)) {
// If we decide to keep Expr\Base instances, we can use this check
if (! is_string($arg) && ! in_array($arg::class, $this->allowedClasses, true)) {
// @phpstan-ignore function.alreadyNarrowedType (input validation)
if (! is_string($arg) && ! (is_object($arg) && in_array($arg::class, $this->allowedClasses, true))) {
throw new InvalidArgumentException(sprintf(
"Expression of type '%s' not allowed in this context.",
get_debug_type($arg),

View File

@@ -4,6 +4,8 @@ declare(strict_types=1);
namespace Doctrine\ORM\Query\Expr;
use Stringable;
/**
* Expression class for building DQL OR clauses.
*
@@ -13,7 +15,7 @@ class Orx extends Composite
{
protected string $separator = ' OR ';
/** @var string[] */
/** @var list<class-string<Stringable>> */
protected array $allowedClasses = [
Comparison::class,
Func::class,

View File

@@ -4,6 +4,8 @@ declare(strict_types=1);
namespace Doctrine\ORM\Query\Expr;
use Stringable;
/**
* Expression class for building DQL select statements.
*
@@ -14,7 +16,7 @@ class Select extends Base
protected string $preSeparator = '';
protected string $postSeparator = '';
/** @var string[] */
/** @var list<class-string<Stringable>> */
protected array $allowedClasses = [Func::class];
/** @phpstan-var list<string|Func> */

View File

@@ -678,7 +678,7 @@ SQL,
public function testDifferentResultLengthsDoNotRequireExtraQueryCacheEntries(): void
{
$dql = 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id >= :id';
$dql = 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id >= :id ORDER BY u.id';
$query = $this->_em->createQuery($dql);
$query->setMaxResults(10);

View File

@@ -50,7 +50,7 @@ class DDC1452Test extends OrmFunctionalTestCase
$this->_em->flush();
$this->_em->clear();
$dql = 'SELECT a, b, ba FROM ' . __NAMESPACE__ . '\DDC1452EntityA AS a LEFT JOIN a.entitiesB AS b LEFT JOIN b.entityATo AS ba';
$dql = 'SELECT a, b, ba FROM ' . __NAMESPACE__ . '\DDC1452EntityA AS a LEFT JOIN a.entitiesB AS b LEFT JOIN b.entityATo AS ba ORDER BY a.id';
$results = $this->_em->createQuery($dql)->setMaxResults(1)->getResult();
self::assertSame($results[0], $results[0]->entitiesB[0]->entityAFrom);

View File

@@ -33,6 +33,7 @@ final class FieldMappingTest extends TestCase
$mapping->precision = 10;
$mapping->scale = 2;
$mapping->unique = true;
$mapping->index = true;
$mapping->inherited = self::class;
$mapping->originalClass = self::class;
$mapping->originalField = 'id';
@@ -57,6 +58,7 @@ final class FieldMappingTest extends TestCase
self::assertSame(10, $resurrectedMapping->precision);
self::assertSame(2, $resurrectedMapping->scale);
self::assertTrue($resurrectedMapping->unique);
self::assertTrue($resurrectedMapping->index);
self::assertSame(self::class, $resurrectedMapping->inherited);
self::assertSame(self::class, $resurrectedMapping->originalClass);
self::assertSame('id', $resurrectedMapping->originalField);

View File

@@ -374,11 +374,27 @@ class ExprTest extends OrmTestCase
public function testAddThrowsException(): void
{
$this->expectException(InvalidArgumentException::class);
$orExpr = $this->expr->orX();
$this->expectException(InvalidArgumentException::class);
$orExpr->add($this->expr->quot(5, 2));
}
#[DataProvider('provideInvalidTypesForAdd')]
public function testAddThrowsExceptionOnInvalidType(mixed $arg): void
{
$orExpr = $this->expr->orX();
$this->expectException(InvalidArgumentException::class);
$orExpr->add($arg);
}
/** @return Generator<string, array{mixed}> */
public static function provideInvalidTypesForAdd(): Generator
{
yield 'integer 1' => [1];
yield 'object' => [(object) ['foo' => 'bar']];
yield 'array' => [['foo' => 'bar']];
}
#[Group('DDC-1683')]
public function testBooleanLiteral(): void
{