Tharos / LeanMapper

Lean Mapper is a tiny ORM based on powerful Dibi database abstraction library for PHP.
MIT License
87 stars 35 forks source link

Result: fixed UNION for complex queries (LIMIT, ORDER BY,...) #109

Closed janpecha closed 6 years ago

janpecha commented 7 years ago

Našel jsem 2 bugy při použití UNION strategie.

1) pokud do dotazu filtrem přidám klauzuli LIMIT, rozbije se generování dotazu a použije se jen jeho první část, tj. místo dotazu

   (SELECT [book].* FROM [book] WHERE [book].[author_id] = 1 LIMIT 1)
   UNION
   (SELECT [book].* FROM [book] WHERE [book].[author_id] = 2 LIMIT 1)

se vygeneruje jen

   SELECT [book].* FROM [book] WHERE [book].[author_id] = 1 LIMIT 1

takže nedojde k načtení všech dat. Problém způsobil pravděpodobně tento commit v dibi. Pokud se výsledek nelimituje, je vygenerovaný dotaz v pořádku.

  1. druhý bug souvisí s SQLite - jednotlivé UNION části nesmí být v SQLite zabaleny do závorek - to však znemožňuje použití komplexnějších dotazů - pokud do dotazu doplníme LIMIT nebo ORDER BY vyhodí nám SQLite chybu. Řešit se to dá pomocí subselectů:
SELECT * FROM (SELECT [book].* FROM [book] WHERE [book].[author_id] = 1 ORDER BY [pubdate])
UNION
SELECT * FROM (SELECT [book].* FROM [book] WHERE [book].[author_id] = 2 ORDER BY [pubdate])
castamir commented 7 years ago

Pouziti m:filter obecne nedoporucuju - jednak kvuli samotne registraci filtru, tak kvuli pouziti v entite, zejmena pri vyskytu u vice property zaroven - vznikaji tim jen problemy (napr u 2 property je orderby, jak se to ma seradit?). Doporucuju pouzivat pristup tvorby dotazu pres QueryObject.

janpecha commented 7 years ago

Jj, m:filter taky obecně nedoporučuju, ale v některých případech se hodí anonymní filtr (objekt Filtering) a tam vznikne stejný problém - syntax error, případně špatně sestavené SQL.

BTW jak myslíš to "napr u 2 property je orderby, jak se to ma seradit?" ?

castamir commented 7 years ago

no mas 2 property (X a Y) s anotaci m:filter(#orderby) vysledny dotaz ma byt order by X nebo order by Y nebo oboje zaraz a pokud oboje, v jakem poradi?


jeste dodam, ze problem muze byt skryty v pripade dedicnosti a zejmena pak tezko upravitelny, pokud uz tam jeden takovy filtr je - dojde k ovlivneni vsech dotazu na danou entitu. To samo o sobe je duvodem, proc m:filter vubec nepouzivat

janpecha commented 7 years ago

Tak to by neměl být problém - buď přistupuješ přes $entity->x (a dotáhnou se data s ORDER BY x), nebo přes $entity->y (a dotáhnou se data s ORDER BY y). Ale rozhodně souhlasím, že filtry se většinou nevyplácí příliš kombinovat a je lepší použít query object.

janpecha commented 7 years ago

Dnes jsem na tento problém znovu narazil v souvislosti s LeanMapperQuery - https://github.com/mibk/LeanMapperQuery/pull/3