plpgsql syntax error prochází na nových postgresech

18 views
Skip to first unread message

David Turoň

unread,
Jun 27, 2024, 4:41:14 AMJun 27
to PostgreSQL-cz
Ahoj,


narzil jsem na blbou syntax chybu plpgsql, která ale kupodivu na novém postgresu projde - v IF podmínce bylo navíc AND THEN na konci podmínky bez další proměnné a IF se i přes chybu vykoná:


chování ve pg14+
postgres@pg14:test=# DO $$ BEGIN IF True AND THEN RAISE NOTICE 'test'; END IF; END; $$;
NOTICE: test
DO
Čas: 3,144 ms

ve starém pg96 byla chyba odhalena:
postgres@pg96:test=# DO $$ BEGIN IF True AND THEN RAISE NOTICE 'test'; END IF; END; $$;
ERROR:  syntax error at end of input
ŘÁDKA 1: DO $$ BEGIN IF True AND THEN RAISE NOTICE 'test'; END IF; EN...
                                                        ^
Čas: 3,589 ms

Nevíte je to nová vlastnost nebo spíše chyba co by se měla nahlásit?

David

Pavel Stehule

unread,
Jun 27, 2024, 4:47:14 AMJun 27
to postgr...@googlegroups.com


čt 27. 6. 2024 v 10:41 odesílatel David Turoň <turon...@gmail.com> napsal:
tohle je vlastnost :-)

ale klidne to nahlas, jelikoz to bude voda na muj mlyn 


jakykoliv vyraz v plpgsql je v podstate sql vyraz 

driv neslo rezervovana slova pouzit jako label, v novych verzich uz to mozne je

postgres=# select true and;
 and
-----
 t
(1 řádka)

 

David

--
Tuto zprávu jste obdrželi, protože jste přihlášeni k odběru skupiny „PostgreSQL-cz“ ve Skupinách Google.
Chcete-li zrušit odběr skupiny a přestat dostávat e‑maily ze skupiny, zašlete e-mail na adresu postgresql-c...@googlegroups.com.
Chcete-li tuto diskusi zobrazit na webu, navštivte https://groups.google.com/d/msgid/postgresql-cz/d4eec888-a295-4bb7-b0d0-617529dd6df4n%40googlegroups.com.

David Turoň

unread,
Jun 27, 2024, 5:22:16 AMJun 27
to postgr...@googlegroups.com
Aha, diky moc - no to by me ani ve snu nenapadlo ze ten AND se pouzije jako label ..., jelikoz ja radeji vsude se snazim pouzivat AS. Az budu mit chvilku nahlasim to, treba to uspisi tvuj patch:)

David 

čt 27. 6. 2024 v 10:47 odesílatel Pavel Stehule <pavel....@gmail.com> napsal:

Pavel Stehule

unread,
Jun 27, 2024, 5:51:24 AMJun 27
to postgr...@googlegroups.com
čt 27. 6. 2024 v 11:22 odesílatel David Turoň <turon...@gmail.com> napsal:
Aha, diky moc - no to by me ani ve snu nenapadlo ze ten AND se pouzije jako label ..., jelikoz ja radeji vsude se snazim pouzivat AS. Az budu mit chvilku nahlasim to, treba to uspisi tvuj patch:)

ono to umoznuje, bohuzel, jeste vetsi zversva

DO $$
DECLARE
l_cnt int;
BEGIN
l_cnt := 1
DELETE FROM foo3 WHERE id=1;
END; $$

je validni - nezahlasi to syntax error, a nastasti to ani nic neudela, ani spatnyho ani dobryho (a samozrejme, bezny uzivatel na to kouka jak puk)
 

David Turoň

unread,
Jun 27, 2024, 6:05:23 AMJun 27
to PostgreSQL-cz
Nevim jestli to byl krok dobrym smerem .... prece kdyby nekdo chtel label nejaky podivny s klicovym slovem... stacilo by:

SELECT true AS "AND";
 AND
-----
 t

David
Dne čtvrtek 27. června 2024 v 11:51:24 UTC+2 uživatel pavel....@gmail.com napsal:

Pavel Stehule

unread,
Jun 27, 2024, 6:38:10 AMJun 27
to postgr...@googlegroups.com


čt 27. 6. 2024 v 12:05 odesílatel David Turoň <turon...@gmail.com> napsal:
Nevim jestli to byl krok dobrym smerem .... prece kdyby nekdo chtel label nejaky podivny s klicovym slovem... stacilo by:

SELECT true AS "AND";
 AND
-----
 t

zakladni problem je v navrhu SQL, ktery je user friendly, ale v urcitych ohledech nebezpecny, diky tomu, ze "AS" je volitelne klicove slovo. "AND" asi nikdo bezne jako label pouzivat nebude, ale jde o relativne casta slova jako "user", "desc" atd ktere se driv nedaly pouzit, nebo jen za AS, a pak bylo matouci, proc to slo za AS a ne bez nej.

Tady motivaci byla prenositelnost z Oracle, ktery jako label dovoluje pouzit cokoliv (ma rucne psany parser, takze tam neni moc omezeni), a pokud se identifikatory daji do uvozovek, tak zase jsou case sensitive. A to cele umocnuje historicke dedictvi plpgsql, ktere neumoznovalo nejak sofistikovaneji pracovat s SQL parserem. Do toho vyvojari objevili a nekteri radi pouzivaji patvar var := xxx FROM tab, ktery neumoznuje tenhle problem jakkoliv fixnout.


Michal Bartak

unread,
Jun 27, 2024, 7:21:58 AMJun 27
to postgr...@googlegroups.com
Ahoj,
a proto, pokud uz takove veci musi byt zavedene, pak bych pg vybavil prepinacem strict, ktery by takove benevolenci branil.

Jinak fakt nechapu, proc kvuli nejake skupine lidi, kteri maji problem s omezenimi (jako nektere nazvy az po keywordu AS) pg communita je ochotna obetovat jazikovou konzistenci jazyka. Prip otevrit pg na vetsi mnozstvi  potencialnich chyb.

Michal Bartak

27. 6. 2024 v 12:38, Pavel Stehule <pavel....@gmail.com>:



Pavel Stehule

unread,
Jun 27, 2024, 2:38:57 PMJun 27
to postgr...@googlegroups.com


čt 27. 6. 2024 v 13:21 odesílatel Michal Bartak <maxym...@gmail.com> napsal:
Ahoj,
a proto, pokud uz takove veci musi byt zavedene, pak bych pg vybavil prepinacem strict, ktery by takove benevolenci branil.

Jinak fakt nechapu, proc kvuli nejake skupine lidi, kteri maji problem s omezenimi (jako nektere nazvy az po keywordu AS) pg communita je ochotna obetovat jazikovou konzistenci jazyka. Prip otevrit pg na vetsi mnozstvi  potencialnich chyb.

jako vždy je to složitější

a) pro EDB a další firmy, které vývoj Postgresu ve výsledku živí je velkou motivací zjednodušení migrace z Oracle. A řady apek se Oracle úplně neopouští, nechceš se nebo nemůžeš úplně přizpůsobit Postgresu. A pak tu máš samozřejmě ANSI/SQL, který některé věci definuje, dost jich nechává implementačně závislých, atd. V postgresu řada omezení byla implementační, a s tím jak se rozvíjí možnosti v Bizonu, a znalosti vývojářů, tak lze některá omezení eliminovat - protože některá omezení byla (jsou) matoucí. Je výrazně víc aplikací bez PL/SQL (PL/pgSQL) než s ním.

b) Problém o kterém se bavíme je primárně problémem PL/pgSQL. V běžných dotazech to taková past není, tam je jasně vidět, co z dotazu leze, a pokud se ti chytne něco, co jsi nečekal jako label, tak je to vidět. Případně ti popada apka, protože máš neočekávaný label. Interně ale se pro přístup k výsledkům dotazu používají pořadová čísla sloupců, a label je ignorovaný, takže PL/pgSQL perfektně zamaskuje chybu, což je špatně - a vychází to z technologie - PostgreSQL používá jak pro SQL, tak pro PL/pgSQL generovaný parser https://en.wikipedia.org/wiki/GNU_Bison .

To má svoje výhody - i pro relativně komplexní jazyk jako je SQL máš docela čitelnou gramatiku. Gramatiku můžeš snadno udržovat, snadno rozšiřovat, a téměř se ti nestane, že by ti parser sežral něco, co neměl nebo naopak nesežral něco, co měl. Navíc, kód který je vygenerovaný Bisonem je velice rychlý. V PL/pgSQL se používají dvě gramatiky - PL/pgSQL a SQL, no a velkou nevýhodou je, že gramatiky téměř nejdou propojit. Nějak to jde, ale než se přišlo na nějaký jednoduchý způsob, tak to trvalo přes 20 let. Integrace PL/pgSQL a SQL se děje až při exekuci, což je na identifikaci některých chyb pozdě, a ještě poměrně nedávno nebyla jakákoliv podpora pro PL/pgSQL v SQL parseru. Kdyby se používaly ručně psané parsery, tak by to byla brnkačka (ale už není brnkačka napsal ručně parser pro SQL (zkoušel jsem to)). Jelikož ta integrace gramatik nešla, tak PL/pgSQL, když pracoval s SQL, tak používal dost primitivní metody, jak převést něco na SQL výraz, a díky tomu je to náchylné na některé chyby.

c) Vývoji engine PL/pgSQL se věnují možná 2-3 lidi na planetě. (ono je to maličké) Naštěstí je mezi nimi Tom Lane. Lidi, kteří řeší kompatibilitu s Oraclem, standardem, to nejsou. Není moc lidí, kterým by sepnulo, že díky větší toleranci začnou v PL/pgSQL procházet nějaké chyby. Navíc i kdyby jim to docvaklo, tak asi by se s tím stejně naučili žít. Chyba musí být na vstupu, a ještě do jisté míry je to chyba PL/pgSQL - a uložené procedury se možná používají v 1-5% (spíš méně).

d) Bohužel parsery generované z gramatik nejdou parametrizovat - podle mne nemůžeš napsat něco ve stylu, pokud je nastavená nějaká proměnná, tak požaduj použití AS a jindy to nepožaduj. Mohl bys mít několik různých gramatik, a přepínat mezi nimi - každá gramatika znamená cca 2MB kódu, což třeba dneska už moc není, ale Tom Lane a další jsou chlapi, ze staré školy a 2MB redundantního kódu by rozhodně neskousli. U ručně psaného parseru by to asi nebyl problém. Komerční forky Postgresu tuhle techniku používají, tipoval bych, že to dělá i MSSQL. Oracle má ručně psaný parser.

e) V postgresu je neskutečná averze proti jakýmkoliv volbám, které by umožňovaly výběr mezi různým chováním čehokoliv. Stačil třeba jen výběr chování stringu - mezi Postgresovým stringem a ANSI/SQL stringem - podobně problémový byl přechod výstupního formátu z base64 na hexacode. Uživatelé pak měli problémy s obnovou z backapů nebo s migracema, když si něco takového nastavili jinak. Konfigurace v Postgresu nastavují alokace, nastavují nějaké výchozí formáty, ale téměř nikdy, jak se něco chová. To je absolutní tabu. A teď v takovém prostředí a s použitýma technologiema něco výmýšlej.


Reply all
Reply to author
Forward
0 new messages