AL+

Limba: RO (română) EN (English)

Scrieți-ne: paul@alplustech.com

Verificările SQLite ar trebui să compare literalii cu parametrii

SQLite 3.50.3 a reparat o optimizare AND care schimba un rezultat agregat. Comparați forma literală cu parametrii legați și verificați răspunsul așteptat.

Read this article in English

O optimizare a interogării este utilă numai dacă păstrează răspunsul. Corecția SQLite din iulie 2025 arată de ce o verificare de regresie ar trebui să compare forma literală cu cea parametrizată, inclusiv numărul rândurilor returnate. Arată și de ce merită examinat răspunsul așteptat: în raportul inițial, rezultatul care părea suspect pentru autor era cel pe care responsabilul proiectului l-a identificat drept corect.

Privind din noiembrie 2026, remedierea istorică se găsește în SQLite 3.50.3, lansat la 17 iulie 2025. Nota versiunii numește un răspuns incorect provocat de optimizarea excesivă a unui operator AND și trimite la raportul inițial din forum. Este o corecție precisă de rezultat, nu dovada că orice versiune de corecții ar trebui privită cu suspiciune.

Urmăriți raportul până la corectarea premisei

La 1 iulie 2025, ChiZhang a raportat o diferență în SQLite 3.50.2. Exemplul folosea un tabel gol și o interogare care combina MAX cu AND, cu zero transmis ca parametru legat. Autorul se aștepta să nu primească rânduri, dar primea un rând cu zero. Interogarea corespunzătoare, cu zero literal, producea rezultatul gol așteptat.

Richard Hipp a simplificat cazul la două interogări peste un tabel gol: SELECT max(x) AND 0 FROM empty și echivalentul său cu un parametru legat la zero. Răspunsul lui preciza că al doilea rezultat era corect. Aceasta este lectura decisivă a discuției primare. Repetarea așteptării autorului drept regulă SQL ar inversa lecția corecției.

Documentația SQLite pentru SELECT, folosită aici ca referință actuală, explică interogările agregate fără GROUP BY: produc un singur rând chiar dacă nu există rânduri de intrare. Documentația agregatelor definește max pentru intrare goală drept NULL; documentația expresiilor definește rezultatul lui AND cu un operand fals drept zero, inclusiv când celălalt operand este NULL. În acest caz, rezultatul este un rând care conține zero. Absența rândurilor și un rând cu zero sunt rezultate observabil diferite.

Aceste afirmații descriu semantica documentată și cazul simplificat de responsabilul proiectului. Interogările nu au fost executate pentru acest articol. Nota datată leagă discuția din 1 iulie de corecția din 17 iulie; nu cere inventarea unui rezultat de test sau deducerea unei erori fără legătură, despre îmbinări, dintr-un rezultat de căutare.

Numărați rândurile înainte să le comparați conținutul

O aplicație de afaceri ar putea interpreta lipsa unui rezultat ca absența sumarului și valoarea zero returnată ca un sumar calculat fără elemente de numărat. Este o consecință ilustrativă, nu o afirmație despre un client afectat. Diferența poate conta chiar dacă interfața ajunge să afișeze aceeași cifră în ambele situații.

Pentru o verificare de regresie propusă, păstrați forma rezultatului, nu doar valorile scalare. Verificați numărul rândurilor și valorile primite de aplicație. Dacă un adaptor înlocuiește rândurile absente sau valorile nule cu o valoare implicită, examinați separat acel punct. Valoarea implicită din aplicație poate ascunde o diferență a bazei de date, fără să demonstreze echivalența interogărilor.

Intrările goale merită incluse deliberat fiindcă verifică limita dintre rândurile care intră într-o agregare și cele returnate de ea. Un set de test cu un singur rând obișnuit poate să nu expună niciodată distincția. Adăugarea unui volum mare de date aleatorii nu este neapărat o investigație mai bună decât păstrarea micului caz cu tabel gol care clarifică dezacordul semantic.

Răspunsul așteptat ar trebui să provină din sensul interogării și din documentația aplicabilă. Testarea diferențelor poate arăta că două forme nu sunt de acord, dar nu stabilește singură care are dreptate. Dacă o versiune veche și una nouă dau răspunsuri diferite, nici votul majoritar între versiuni nu ajunge. Un rezultat vechi poate fi greșit; schimbarea răspunsului poate fi o corecție.

Păstrați delimitarea parametrilor aplicației

Înlocuirea unui parametru cu un literal ajută la comparație, dar schimbă informația cunoscută la pregătirea interogării. Scopul este să expună presupuneri despre rezultate echivalente, nu să rescrie interogarea de producție prin interpolarea șirurilor. O facilitate de diagnostic nu ar trebui să devină o politică nouă de construire a interogărilor aplicației.

Un caz minim de reproducere ar trebui să consemneze SQL-ul exact, valorile și tipurile parametrilor, schema și versiunea motorului. Includeți numai datele necesare demonstrării diferenței. Dacă problema depinde de o extensie sau de o opțiune de construire, păstrați și informația respectivă. Detaliile îi permit responsabilului proiectului să examineze afirmația fără să primească date reale ale clienților sau o copie a bazei din producție.

Precizia are un avantaj practic pentru firmă. Un caz clar poate deosebi un defect al bazei de date de o conversie a adaptorului sau de o așteptare greșită a produsului. Astfel se poate evita schimbarea comportamentului aplicației pentru a acomoda premisa greșită. Nu rezultă o garanție a timpului de răspuns și nici că orice defect este ușor de izolat.

Când este implicat un optimizator, analiza planului rămâne subordonată echivalenței rezultatelor. Planul poate explica traseele diferite ale execuțiilor, dar un plan atractiv nu justifică schimbarea răspunsului. Comparația de performanță devine utilă după stabilirea rezultatului corect. Pentru această retrospectivă nu au fost colectate planuri sau măsurători de timp.

O corecție restrânsă nu justifică blocarea tuturor actualizărilor

Contraargumentul cel mai puternic este costul extinderii verificărilor de livrare. O aplicație mică nu poate compara toate formele posibile ale interogărilor după fiecare actualizare a bazei de date. Este rezonabil. Răspunsul este păstrarea cazului relevant și adăugarea unei verificări precise în aplicație acolo unde limita semantică are importanță, nu solicitarea unei suite exhaustive pentru motorul bazei de date.

La fel, existența unui defect al optimizatorului nu arată că evitarea corecțiilor îmbunătățește fiabilitatea. Versiunea din iulie este ea însăși dovada unei remedieri. Stabiliți dacă actualizarea este relevantă pentru motorul instalat și interogările folosite, apoi păstrați dovezi suficiente pentru explicarea deciziei. Blocarea generală ar ignora costul păstrării comportamentului incorect cunoscut.

Subiectul diferă de compatibilitatea revenirii la o versiune veche de SAHPool în browser: aceea privește redeschiderea datelor printr-un anumit adaptor de persistență. Aici motorul poate deschide datele și totuși poate da un răspuns greșit pentru o anumită formă de interogare. Limita defecțiunii și verificarea utilă sunt diferite.

Pentru dezvoltare software la comandă, păstrați dovezile de corectitudine lângă interogarea care servește regula de afaceri. Comparați forma cu parametri cu cea literală când investigația o cere, verificați forma așteptată a rezultatului și rețineți cazul minim. Raportul din iulie este valoros fiindcă a restrâns dezacordul suficient pentru corectarea implementării și a așteptării inițiale.