PostgreSQL Antipatterns: Condition volutpat in SQL

SQL non est C++, nec est JavaScript. Aestimatio igitur locutionum logicalium est diversa, et hoc omnino non est idem;

WHERE fncondX() AND fncondY()

= fncondX() && fncondY()

Dum optimizing consilium exsecutionis interrogationis PostgreSQL potest ad placitum "rearrange" est equivalent conditionibusnoli ex illis in singulas tabulas computare, conditionem indicis appositi refer... Denique facillime id existimas. non potest administrare quo ordine fient, an omnino calculi. aequalis conditiones.

Si igitur prioritatem administrare adhuc vis, constitutione debes hae conditiones inaequales cum conditionali expressions ΠΈ operators.

PostgreSQL Antipatterns: Condition volutpat in SQL
Data et operans cum illis est basis nostrae VLSI complexuita magni momenti est ut in eis non solum recte, sed etiam efficaciter fiant operationes. Intueamur exempla concreta ubi errorum expressionis aestimatio fieri potest, et ubi efficaciam suam augere valet.

#0: RTFM

Satus exempli gratia ex documentis:

Ordo aestimationee cum magni momenti est, figi potest cum constructione CASE. Exempli gratia, hic modus in sententia nulla divisionem vitare WHERE vacillent;

SELECT ... WHERE x > 0 AND y/x > 1.5;

Salvus optio:

SELECT ... WHERE CASE WHEN x > 0 THEN y/x > 1.5 ELSE false END;

Constructione usus est CASE verbum ab optimizatione tuetur, ita uti debet, cum opus sit.

# I: felis conditione

BEGIN
  IF cond(NEW.fld) AND EXISTS(SELECT ...) THEN
    ...
  END IF;
  RETURN NEW;
END;

Omnia bona videntur, sed ... Nemo investituram promittit SELECT non erit faciendum, si prima conditio falsa est. Reficere cum nested IF:

BEGIN
  IF cond(NEW.fld) THEN
    IF EXISTS(SELECT ...) THEN
      ...
    END IF;
  END IF;
  RETURN NEW;
END;

Nunc diligenter inspiciamus - totum corpus functionis felis evenit ut "involvatur" in IF. Et hoc significat nihil prohibet hanc condicionem ab usu procedendi removere WHEN-conditions:

BEGIN
  IF EXISTS(SELECT ...) THEN
    ...
  END IF;
  RETURN NEW;
END;
...
CREATE TRIGGER ...
  WHEN cond(NEW.fld);

Aditus permittit ut servo cautione facultates serves, si falsa conditio est.

#2: VEL/ET catena

SELECT ... WHERE EXISTS(... A) OR EXISTS(... B)

Alioquin obtineri potest quod utrumque EXISTS verum erit, sed et voluntas supplicium.

Sed si pro certo scimus unam earum esse "verum" multo saepius (vel "falsum" - for AND- catenae) β€” possibile est aliquo modo "priorem suum augere", ut alter iterum denuo non fungatur?

Evenit ut possibile est - accedere algorithmice prope thema articuli PostgreSQL Antipatterns: Rare introitus ad medium coniungitur.

Iustus 'trudere sub CAUSA' utrumque horum condicionum est:

SELECT ...
WHERE
  CASE
    WHEN EXISTS(... A) THEN TRUE
    WHEN EXISTS(... B) THEN TRUE
  END

In hoc casu non definivimus ELSE-value, id est, si utraque res falsa est CASE reddet NULLquod interpretatur FALSE Π² WHEREβ€” Conditiones.

Hoc exemplum alio modo componi potest cum gustu et colore;

SELECT ...
WHERE
  CASE
    WHEN NOT EXISTS(... A) THEN EXISTS(... B)
    ELSE TRUE
  END

#3: quomodo [non] conditiones scribere

Duos dies consumpsimus in examinandis rationibus "alieni" excitato huius felis - videamus quare.

Source:

IF( NEW."Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚_" is null or NEW."Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚_" = (select '"ΠšΠΎΠΌΠΏΠ»Π΅ΠΊΡ‚"'::regclass::oid) or NEW."Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚_" = (select to_regclass('"Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠŸΠΎΠ—Π°Ρ€ΠΏΠ»Π°Ρ‚Π΅"')::oid)
     AND (   OLD."Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠΠ°ΡˆΠ°ΠžΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΡ" <> NEW."Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠΠ°ΡˆΠ°ΠžΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΡ"
          OR OLD."Π£Π΄Π°Π»Π΅Π½" <> NEW."Π£Π΄Π°Π»Π΅Π½"
          OR OLD."Π”Π°Ρ‚Π°" <> NEW."Π”Π°Ρ‚Π°"
          OR OLD."ВрСмя" <> NEW."ВрСмя"
          OR OLD."Π›ΠΈΡ†ΠΎΠ‘ΠΎΠ·Π΄Π°Π»" <> NEW."Π›ΠΈΡ†ΠΎΠ‘ΠΎΠ·Π΄Π°Π»" ) ) THEN ...

Quaestio # I: Inaequalitas non ideo pro NULL

Demus omnia OLD-fields referre NULL. Quæ in ea ventura?

SELECT NULL <> 1 OR NULL <> 2;
-- NULL

Et ex parte operandi conditiones NULL equivalent FALSEde quibus supra.

arbitrium: Usus operator IS DISTINCT FROM ex ROW-operator, integras tabulas statim comparans;

SELECT (NULL, NULL) IS DISTINCT FROM (1, 2);
-- TRUE

Quaestio numeri II: Exsecutio alia eiusdem functionality

Lets comparare:

NEW."Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚_" = (select '"ΠšΠΎΠΌΠΏΠ»Π΅ΠΊΡ‚"'::regclass::oid)
NEW."Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚_" = (select to_regclass('"Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠŸΠΎΠ—Π°Ρ€ΠΏΠ»Π°Ρ‚Π΅"')::oid)

Cur non extra investments SELECT? Munus to_regclass? Quid est aliud.

Sit fix:

NEW."Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚_" = '"ΠšΠΎΠΌΠΏΠ»Π΅ΠΊΡ‚"'::regclass::oid
NEW."Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚_" = '"Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠŸΠΎΠ—Π°Ρ€ΠΏΠ»Π°Ρ‚Π΅"'::regclass::oid

Quaestio III: bool praecedentia

Forma lets principium:

{... IS NULL} OR
{... ΠšΠΎΠΌΠΏΠ»Π΅ΠΊΡ‚} OR
{... Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠŸΠΎΠ—Π°Ρ€ΠΏΠ»Π°Ρ‚Π΅} AND
( {... нСравСнства} )

Oops... Quae quidem evenit ut in quibuslibet primis duabus conditionibus veritas, tota conditio convertitur. TRUEinaequalitatibus neglectis. Nec hoc omnino quod voluimus.

Sit fix:

(
  {... IS NULL} OR
  {... ΠšΠΎΠΌΠΏΠ»Π΅ΠΊΡ‚} OR
  {... Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠŸΠΎΠ—Π°Ρ€ΠΏΠ»Π°Ρ‚Π΅}
) AND
( {... нСравСнства} )

Problema #4 (small): complexus OR conditio unius agri

Profecto quaestiones habuimus in n. 3 ob id quod tres conditiones erant. Sed pro illis una acquirere potes, machinatione adhibita coalesce ... IN:

coalesce(NEW."Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚_"::text, '') IN ('', '"ΠšΠΎΠΌΠΏΠ»Π΅ΠΊΡ‚"', '"Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠŸΠΎΠ—Π°Ρ€ΠΏΠ»Π°Ρ‚Π΅"')

Ita sumus NULL "capere" et complex OR Non habes cum parenthesi.

in summa

Sit scriptor fix quod nos obtinuit:

IF (
  coalesce(NEW."Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚_"::text, '') IN ('', '"ΠšΠΎΠΌΠΏΠ»Π΅ΠΊΡ‚"', '"Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠŸΠΎΠ—Π°Ρ€ΠΏΠ»Π°Ρ‚Π΅"') AND
  (
    OLD."Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠΠ°ΡˆΠ°ΠžΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΡ"
  , OLD."Π£Π΄Π°Π»Π΅Π½"
  , OLD."Π”Π°Ρ‚Π°"
  , OLD."ВрСмя"
  , OLD."Π›ΠΈΡ†ΠΎΠ‘ΠΎΠ·Π΄Π°Π»"
  ) IS DISTINCT FROM (
    NEW."Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠΠ°ΡˆΠ°ΠžΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΡ"
  , NEW."Π£Π΄Π°Π»Π΅Π½"
  , NEW."Π”Π°Ρ‚Π°"
  , NEW."ВрСмя"
  , NEW."Π›ΠΈΡ†ΠΎΠ‘ΠΎΠ·Π΄Π°Π»"
  )
) THEN ...

Et cum haec felis functione tantum uti possit UPDATEligulae ex praesentia OLD/NEW in superiori gradu condicionem , tum haec fere accipi potest WHEN-condition ut ostensum est in # I...

Source: www.habr.com