Skip to content

Annotations are selected in sql despite not being specified in .values_list fields list #2058

@RuslanUC

Description

@RuslanUC

Describe the bug
In tortoise-orm >0.21.7, when .values_list is used after .annotate, generated sql selects annotations even if they were not specified in values_list (and even if flat=True is passed). In regular queries that use values_list, everything works fine (because, if i understand correctly, ValuesListQuery only selects first field when flat=True, ignoring everything else), but if such query is used inside Subquery - it throws exception tortoise.exceptions.OperationalError: sub-select returns 2 columns - expected 1.

To Reproduce

from tortoise import fields, run_async
from tortoise.contrib.test import init_memory_sqlite
from tortoise.expressions import Subquery
from tortoise.functions import Length
from tortoise.models import Model

class SomeModel(Model):
    id: int = fields.BigIntField(pk=True)
    name: str = fields.TextField()


@init_memory_sqlite
async def run() -> None:
    await SomeModel.create(name="asdqwe")
    await SomeModel.create(name="asdqweasd")
    await SomeModel.create(name="asdqweasd123")

    subquery = SomeModel.annotate(
        name_length=Length("name"),
    ).filter(
        name_length__gt=6,
    ).values_list(
        "id", flat=True,
    )

    subquery_result = await subquery
    print(f"Subquery result: {subquery_result}")
    print(f"Subquery sql: {subquery.sql()}")

    query = SomeModel.filter(id__in=Subquery(subquery))
    print(f"Query sql: {query.sql()}")

    await query

if __name__ == "__main__":
    run_async(run())

If code above is run with tortoise-orm 0.21.7, everything works, subquery sql is SELECT "id" "0" FROM "somemodel" WHERE LENGTH("name")>6. But on 0.22.0+, name_length is being added to SELECT clause (SELECT "id" "0",LENGTH("name") "name_length" FROM "somemodel" WHERE LENGTH("name")>6).

Expected behavior
ValuesListQuery selects only specified fields.

Additional context
After bisecting, i found out that bug was introduced in this commit. If i understand correctly - bug is caused by overwriting annotations dict with extra annotations dict in FieldSelectQuery on line 1341.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions