Hibernate (5 HIGH): addColumn/addReferencedColumn/addIndex ArrayList→LinkedHashSet (19x) FK second-pass LinkedHashSet, orderHierarchy LinkedHashSet MyBatis (1 MEDIUM): sortConstructorMappings indexOf→HashMap (12x) EF Core (2 HIGH + 1 MEDIUM): FindGenerationProperty HashSet (250x), AddPrincipals HashSet (250x), FK discovery HashSet (6x) Diesel (3 MEDIUM): SQLite/MySQL row position()→BTreeMap (51x) SQLAlchemy (2 HIGH): _values_bindparam Set (500x), evaluated_keys Set (500x) Peewee (1 MEDIUM): _SortedFieldList.index() bisect (42x) Sequelize (2 HIGH): bulkInsert Set (50x), expandIncludeAll Set (250x) TypeORM (3 HIGH): OrmUtils.uniq Map (500x), diffColumns Set (125x), updatedColumns Set (100x) Doctrine ORM (1 HIGH + 2 MEDIUM): hydrator discriminator (26x), addSubClass (250x), SqlWalker partial (130x) GORM (1 MEDIUM): sortCallbacks getRIndex→map (194x) SQLite: SqliteTest unit proof 4/4 PASS (101x) Unit tests: all PASS — Hibernate/MyBatis/EfCore/Diesel/SQLAlchemy/Peewee/ Sequelize/TypeORM/Doctrine/GORM Whitepaper: 157 sites, 62 ecosystems; PDF 752K
34 lines
1.6 KiB
Diff
34 lines
1.6 KiB
Diff
Fixes doctrine-0003: SqlWalker::walkObjectExpression in_array per field.
|
||
|
||
--- a/src/Doctrine/ORM/Query/SqlWalker.php
|
||
+++ b/src/Doctrine/ORM/Query/SqlWalker.php
|
||
|
||
@@ DEFECT doctrine-0003: SqlWalker.php:1405,1445 walkObjectExpression()
|
||
|
||
private function walkObjectExpression(...): string
|
||
{
|
||
+ // FIX doctrine-0003: convert partialFieldSet from array to set for O(1) lookup.
|
||
+ // Previously: in_array($fieldName, $partialFieldSet) is O(|partialFieldSet|) per field.
|
||
+ // Called for every fieldMapping in every class/subclass in the DQL result.
|
||
+ $partialFieldSetFlip = $partialFieldSet !== null ? array_flip($partialFieldSet) : null;
|
||
|
||
foreach ($class->fieldMappings as $fieldName => $mapping) {
|
||
- if ($partialFieldSet && ! in_array($fieldName, $partialFieldSet, true)) {
|
||
+ if ($partialFieldSetFlip !== null && ! isset($partialFieldSetFlip[$fieldName])) {
|
||
continue;
|
||
}
|
||
// ... build SQL
|
||
}
|
||
|
||
foreach ($subClass->fieldMappings as $fieldName => $mapping) {
|
||
- if (isset($mapping->inherited) || ($partialFieldSet && ! in_array($fieldName, $partialFieldSet, true))) {
|
||
+ if (isset($mapping->inherited) || ($partialFieldSetFlip !== null && ! isset($partialFieldSetFlip[$fieldName]))) {
|
||
continue;
|
||
}
|
||
}
|
||
}
|
||
|
||
# BEFORE: in_array($field, $partialFieldSet) — O(P) per field across all mappings.
|
||
# Total: O(F × P) for F field mappings, P partial field set size.
|
||
# AFTER: isset($partialFieldSetFlip[$field]) — O(1).
|
||
# Triggered by: any DQL query using SELECT PARTIAL entity.{field1,field2,...}.
|