-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Description
Bug Report
| Q | A |
|---|---|
| BC Break | no |
| Version | 2.6.3 |
Summary
As previously reported by @flaushi in #7471 (comment), we discovered that binding a parameter causes a ClassMetadataFactory#getClassMetadata() call, which in turn leads to large performance regression when using any object type as parameter.
Current behavior
Following two snippets lead to an internal ClassMetadataFactory#getClassMetadata() call, which in turn leads to an exception being thrown and garbage collected, plus multiple associated performance implications:
$query->setParameter('foo', new DateTime());
$query->getResult();$query->setParameter('foo', new DateTime(), DateTimeType::NAME);
$query->getResult();This is due to following portion of code:
Notice how $value = $this->processParameterValue($value); happens before attempting to infer the type for the parameter value.
That call leads to this segment being reached, which leads to the regression:
Expected behavior
Assuming the bound parameter type is provided, we can completely skip attempting to introspect the given object:
$query->setParameter('foo', new DateTime(), DateTimeType::NAME);
$query->getResult();Processing the parameter value is not needed in this case, so we can safely skip that logic for all known parameters. In order to not introduce a BC break or change the AbstractQuery#processParameterValue() implementation, we could filter out all parameters for which the type is given upfront, and later on merge them back in instead.
The test expectation to be set is for UnitOfWork#getSingleIdentifierValue() to never be called.