Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

error constructing query from stored subqueries #707

Open
ne555 opened this issue Mar 14, 2024 · 1 comment
Open

error constructing query from stored subqueries #707

ne555 opened this issue Mar 14, 2024 · 1 comment

Comments

@ne555
Copy link

ne555 commented Mar 14, 2024

from pony import orm

db = orm.Database()

class Person(db.Entity):
    name = orm.Optional(str)
    vehicles = orm.Set('Car')

class Person_fts(db.Entity):
    rowid = orm.Optional(int)

class Car(db.Entity):
    model = orm.Optional(str)
    owner = orm.Optional('Person')

class Car_fts(db.Entity):
    rowid = orm.Optional(int)


db.bind('sqlite', ':memory:')
db.generate_mapping(create_tables=True)

with orm.db_session:
    person_sql = orm.select(
        x
        for x in Person
        for fts in Person_fts
        if x.id == fts.rowid
    )
    car_sql = orm.select(
        x
        for x in Car
        for fts in Car_fts
        if x.id == fts.rowid
    )

    query = orm.select(
        (person, car)
        for person in person_sql
        for car in car_sql
        if car.owner == person
    )
Traceback (most recent call last):
  File "complex_join.py", line 36, in <module>
    query_small = orm.select(
                  ^^^^^^^^^^^
  File "lib/python3.11/site-packages/pony/orm/core.py", line 5560, in select
    return make_query(args, frame_depth=cut_traceback_depth+1)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "lib/python3.11/site-packages/pony/orm/core.py", line 5556, in make_query
    return Query(code_key, tree, globals, locals, cells, left_join)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "lib/python3.11/site-packages/pony/orm/core.py", line 5717, in __init__
    translator = translator_cls(tree_copy, None, code_key, filter_num, extractors, vars, vartypes.copy(), left_join=left_join)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "lib/python3.11/site-packages/pony/orm/sqltranslation.py", line 242, in __init__
    translator.init(tree, parent_translator, code_key, filter_num, extractors, vars, vartypes, left_join, optimize)
  File "lib/python3.11/site-packages/pony/orm/sqltranslation.py", line 357, in init
    translator.process_query_qual(prev_translator, prev_limit, prev_offset,
  File "lib/python3.11/site-packages/pony/orm/sqltranslation.py", line 613, in process_query_qual
    subquery_ast = prev_translator.construct_subquery_ast(prev_limit, prev_offset, aliases=aliases)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "lib/python3.11/site-packages/pony/orm/sqltranslation.py", line 640, in construct_subquery_ast
    assert not star and len(aliases) == len(select_ast) - 1
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError

if replace the person_sql and car_sql queries by their content it builds the query correctly

query = orm.select(
    (person, car)
    for person in orm.select(
        x
        for x in Person
        for fts in Person_fts
        if x.id == fts.rowid
    )
    for car in orm.select(
        x
        for x in Car
        for fts in Car_fts
        if x.id == fts.rowid
    )
    if car.owner == person
)
SELECT DISTINCT "x"."id", "car"."id"
FROM "Person" "x", "Person_fts" "fts", (
    SELECT DISTINCT "x-2"."id" AS "car-id"
    FROM "Car" "x-2", "Car_fts" "fts-2"
    WHERE "x-2"."id" = "fts-2"."rowid"
    ) "t-1", "Car" "car"
WHERE "x"."id" = "fts"."rowid"
  AND "car"."owner" = "x"."id"
  AND "t-1"."car-id" = "car"."id"

Python 3.11.6
pony 0.7.17

@ne555
Copy link
Author

ne555 commented Mar 14, 2024

weird «solution», ask for an extra field

    person_sql = orm.select(
        (1, x)
        for x in Person
        for fts in Person_fts
        if x.id == fts.rowid
    )
    car_sql = orm.select(
        (1, x)
        for x in Car
        for fts in Car_fts
        if x.id == fts.rowid
    )

    query = orm.select(
        (person, car)
        for a, person in person_sql # it must have a name, can't use _
        for b, car in car_sql
        if car.owner == person
    )
SELECT DISTINCT "x"."id", "car"."id"
FROM "Person" "x", "Person_fts" "fts", (
    SELECT DISTINCT 1 AS "b", "x"."id" AS "car-id"
    FROM "Car" "x", "Car_fts" "fts"
    WHERE "x"."id" = "fts"."rowid"
    ) "t-1", "Car" "car"
WHERE "x"."id" = "fts"."rowid"
  AND "car"."owner" = "x"."id"
  AND "t-1"."car-id" = "car"."id"

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

No branches or pull requests

1 participant