Skip to content

Conversation

@zelenomodrypes
Copy link
Contributor

Source: https://nextras.org/orm/docs/main/collection-functions -> Dbal Implementation

This example code doesn't work for me - there is something wrong when processing modifier %ex and it cannot handle even a simple column name:

$expression = $helper->processExpression($builder, $args[0], $aggregator);
return new DbalExpressionResult('SUBSTRING(%ex, 0, %i) = %s', [$expression->args, \strlen($args[1]), $args[1]]);

This works (modifier %ex replaced with %column):

$expression = $helper->processExpression($builder, $args[0], $aggregator);
return new DbalExpressionResult('SUBSTRING(%column, 0, %i) = %s', [$expression->args[0], \strlen($args[1]), $args[1]]);

But still you can't reference column in another table (eg. address->zipcode) and I'm not sure if DbalQueryBuilderHelper can even solve this, i.e., automatically add the necessary joins to the query builder.

I noticed that FetchPropertyFunction contains all the necessary methods to build a complete query, so I created an example code for this that might inspire others.

What do you think?

@hrach
Copy link
Member

hrach commented Nov 7, 2025

I noticed that FetchPropertyFunction contains all the necessary methods to build a complete query, so I created an example code for this that might inspire others.

I believe this goes against the "nature" of the API -> to compose expressions via the "composition over inheritance" pattern.

This example code doesn't work for me - there is something wrong when processing modifier %ex and it cannot handle even a simple column name:

Ideally, please add what's wrong to your issues.


The documentation has a bug, Nextras 5.0 should be using $expression->getArgsForExpansion(). I'm fixing this :)

@hrach
Copy link
Member

hrach commented Nov 7, 2025

Thx for repoting!

@hrach hrach closed this in d353b47 Nov 7, 2025
@zelenomodrypes
Copy link
Contributor Author

zelenomodrypes commented Nov 10, 2025

Ah, my mistake, I obviously got a little confused. The problem was that the %ex modifier requires a parameter in a different format.

After calling this:

$expression = $helper->processExpression($builder, 'devices->model', $aggregator);

You will get in $expression->args[0] the following value:

Nextras\Dbal\Platforms\Data\Fqn('devices_any', 'model')

Which will throw an exception Modifier %ex expects value to be array, Nextras\Dbal\Platforms\Data\Fqn given. if you use it for the %ex modifier.

What you need is this:

['%column', Nextras\Dbal\Platforms\Data\Fqn('devices_any', 'model')]

Which is what the $expression->getArgsForExpansion() method you mentioned returns and then it works correctly. It is also necessary to pass the joins property from $expression to the new DbalExpressionResult instance. So thank you for the clarification :-)

But I have another question: Why don't you automatically pass all properties from $expression to the new DbalExpressionResult instance? It seems to me that you basically always want to preserve generated context, because you don't know what was added to the query builder. Then it might be useful to create a method like append() that would clone DbalExpressionResult, just with a different expression and args parameters. Or is it just not that common a scenario or it just not make sense for another reason?

@hrach
Copy link
Member

hrach commented Nov 10, 2025

That's exactly what the docs mention

image (now and before updates as well)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants