cycle / annotated

Schema generation using annotated entities and mappers
MIT License
23 stars 12 forks source link

Primary Keys are resolving to arrays even when they're not, which makes select->count() not work properly🐛 #58

Open longshadowdev opened 1 year ago

longshadowdev commented 1 year ago

No duplicates 🥲.

What happened?

When I generate my schema using annotations I have noticed that it will set an integer auto-increment primary key with name $id to an array.

Entity PK definition:

#[Column(type: "primary")]
private int $id;

After persisting the schema to a json file:

        "7": [
            "id"
        ],

It looks like Cycle\Schema\Compiler is the culprit. Line 90 is Schema::PRIMARY_KEY => $entity->getPrimaryFields()->getNames(), and this always returns an array.

The IMPACT of this (at least the one I've seen), is seen in Cycle\ORM\Select::count(). If the $column parameter isn't set, it looks at the primary key definition instead as follows:

        if ($column === null) {
            // @tuneyourserver solves the issue with counting on queries with joins.
            $pk = $this->loader->getPK();
            $column = \is_array($pk)
                ? '*'
                : \sprintf('DISTINCT(%s)', $pk);
        }

        return (int) $this->__call('count', [$column]);

because it's always an array, it always puts in * instead of the DISTINCT() call. In a left join it will then show an incorrect count. It'll be showing the number of results in the SQL instead of the number of results in the SQL for the left/primary table.

I've confirmed this by changing the schema to not be an array, and then the count works accurately. I've also tried select->count('DISTINCT(table.id)'); and this works too (as it emulates what would happen if this was working correctly).

Version

    "cycle/orm": "^2.2",
    "cycle/annotated": "^3.2",
    "cycle/schema-builder": "^2.1",
    "cycle/entity-behavior": "^1.1",

php 8.0.16

ORM Schema

No response