Dibi fluent použití limit způsobuje exception
- milanb
- Člen | 64
Ahoj,
když v dotazu Dibi použiji ve fluent zápisu limit(1), způsobí to
exception:
$reminder = $this->db
->select('t.task_id, created, title, user_id as executorId')
->select('concat(lastname, " ", firstname) as executor')
->select('e.success')
->select(
'(%sql) as sponsor',
(string) $this->db->select('concat(user_id, "-", lastname, " ", firstname)')
->from('task_executor ee')->join('user eu')->using('(user_id)')
->where('t.task_id = ee.task_id')
->where('executor = 0')
)
->from('task t')
->join('task_executor e')->on('t.task_id = e.task_id and executor = 1')
->join('user u')->using('(user_id)')
->where(
'(e.user_id = %u or (%sql) = %u) and (%sql) = 0',
$user_id,
(string) $this->db->select('user_id')
->from('task_executor se')
->where('t.task_id = se.task_id')
->where('executor = 0')
->limit(1), //způsobuje exception
$user_id,
(string) $this->db->select('success')->from('task_executor ss')
->where('user_id = %u and ss.task_id = t.task_id', $user_id)
)
->orderBy('created')
->fetchAll();
Konfigurace: Nette 2.4/2.5 a Dibi 3.2.4.
Díky.
Editoval milanb (3. 3. 14:56)
- nightfish
- Člen | 474
@milanb
- Hodilo by se vědět, o jakou výjimku jde – jestli selže skládání dotazu nebo až výsledný dotaz při poslání do databáze. Poskytnutím dostatečného kontextu zvýšíš šanci, že se tvým problémem bude někdo chtít zabývat.
- Nejrychlejší řešení je přepsat to z fluent zápisu na normální SQL dotaz, protože tím vyloučíš jakékoliv problémy, které do toho Dibi fluent může zanést při parsování syntaxe.
- Dibi 3.0.4 je staré skoro 8 let. Pokud máš PHP 8.0, chceš se ideálně dostat na Dibi 5.
- milanb
- Člen | 64
Je to ve Fluent.php:466
:
Trying to access array offset on value of type null
461: protected function _export($clause = null, $args = [])
462: {
463: if ($clause === null) {
464: $data = $this->clauses;
465: if ($this->command === 'SELECT' && ($data['LIMIT'] || $data['OFFSET'])) {
466: $args = array_merge(['%lmt %ofs', $data['LIMIT'][0], $data['OFFSET'][0]], $args);
467: unset($data['LIMIT'], $data['OFFSET']);
468: }
Jde o to, že ($data['LIMIT']
existuje, ale
($data['OFFSET']
ne. Ale v podmínce je ||
, takže to
projde až na tu adresaci pole a tam to selže.
Editoval milanb (3. 3. 14:59)
- nightfish
- Člen | 474
@milanb Ano, bylo to zřejmě opraveno ve verzi 4.1.1 – https://github.com/…2c81aeef8dfa
Předpokládám, že pro starší verzi Dibi by prostě stačilo za
->limit(1)
přidat ->offset(0)
.
- milanb
- Člen | 64
nightfish napsal(a):
@milanb Ano, bylo to zřejmě opraveno ve verzi 4.1.1 – https://github.com/…2c81aeef8dfa
Předpokládám, že pro starší verzi Dibi by prostě stačilo za->limit(1)
přidat->offset(0)
.
Bože, tak triviální a mě to nenapadlo. Je nějaká emotikona pro tohle? Díky.
- Marek Bartoš
- Nette Blogger | 1177
@dms Nejrychlejší by bylo udělat ten one line fix i ve starší
verzi https://github.com/…c1dd42dbe695
Udělat PR by zabralo chviličku a do přijetí nebo i v případě
nepřijetí se dá použít patch https://github.com/…hes/tree/1.x
Proč vám brání přechod na DateTimeImmutable? Před pár týdny jsem update na v4 dělal na hodně staré, velké a ne moc dobře napsané aplikaci a změnit datumy (a zkontrolovat return typy, false se změnilo na null) zabralo jeden den. Když si zapnete phpstan s maximálním levelem a vygenerujete baseline před přechodem, tak můžete při aktualizaci pozorovat z velké části, kde se co změnilo.
- dms
- Člen | 87
Ano řešení přes vendor patch je také možné. Ale snažím se tomu vyhýbat pokus je jiná cesta.
Problém DateTimeImmutable je v naší apce bohužel komplikovaný. Je tam např spousty generovaných tříd z xsd které mají jako vstupní parametr DateTime a ten generátor je už taky pěkně legacy a nikdo do toho nechce moc hrabat (to je ale jen jedna z x částí, která by asi šla vyřešit nějakým massreplacem). Aplikace však hodně pracuje s datumem a časem a DateTime se chová jinak než DateTimeImmutable a to je asi ten hlavní problém. Změna by pak mohla vyloženě upravit chování některých funkcí, které spoléhají na modify.
Apka už nás trochu přerostla, ale snažím se ji dostat nyní na php 8.2 a s tím bylo potřeba přejít na dibi alespon verze 3. Nemít phpstan a rector tak je to úplně pasé a s apkou prakticky nehnu.
Jinak david tady psal https://github.com/…s/tag/v3.2.4 že to je poslední release tak proto ani nějaký PR s opravou neřeším a beru to jako již mrtvou verzi.