Happyr/Doctrine-Specification

Always use a unique aliases to prevent cases in which we have auto-joining and reserved keywords as context

thexpand opened this issue · 4 comments

I have a specific case in which I want to benefit from the auto-joining feature, but my field in the entity is called group, which when used as a context for an Equals will put the alias group which expects to have by after it because of GROUP BY. My idea is to replace this part of the code:
https://github.com/Happyr/Doctrine-Specification/blob/2.x/src/DQLContextResolver.php#L173-L182

With something like this, so that we always have a unique and non-conflicting alias:

private static function getUniqueAlias(QueryBuilder $qb, string $dqlAlias): string
{
    if (! self::$conflictProtection) {
        return $dqlAlias;
    }
    
    do {
        $newAlias = uniqid($dqlAlias);
    } while (in_array($newAlias, $qb->getAllAliases(), true));

    return $newAlias;
}

We can even take this one step further and make it optional, like this:

private static function getUniqueAlias(QueryBuilder $qb, string $dqlAlias): string
{
    if (! self::$conflictProtection) {
        return $dqlAlias;
    }
    
    if (! self::$alwaysUnique && ! in_array($dqlAlias, $qb->getAllAliases(), true)) {
        return $dqlAlias;
    }
    
    do {
        $newAlias = uniqid($dqlAlias);
    } while (in_array($newAlias, $qb->getAllAliases(), true));

    return $newAlias;
}

Right now the only possiblity (as a workaround) that I have is to completely rename my field so that it's not a conflicting keyword or to explicitly add the join to my specification, but then I won't be able to re-use it with other specifications, which also have a join. What do you think?

Can you show the DQL you are getting? It seems to me that something is wrong here. You must have a DQL that must contain e.group and group.name, not group.

@thexpand can you check PR #303?

@peter-gribanov Hey, Peter. Sorry, I missed your first message. The DQL that I'm getting looks like this:

SELECT root FROM MyEntity root INNER JOIN root.group group WHERE group.company = ...

The problem is that alias group after the INNER JOIN root.group is causing the error. The error actually happens when the DQL is converted to SQL.
I looked into the PR and don't see anything unusual - LGTM.

Update: Btw, do we need to reach a certain amount of resolved issues until releasing a milestone version?

@thexpand fix was released in 2.0.1.