UPDATE FOR dans postgres

Si vous voulez participer au développement de Gestinux, et que vous ne maîtrisez pas l'anglais, écrivez vos questions ou remarques ici.

Il reste préférable, dans la mesure du possible, d'utiliser le forum anglais.
Post Reply
talexone
Posts: 12
Joined: 20 Feb 2014, 08:58

UPDATE FOR dans postgres

Post by talexone »

Erreur dans TGQuery.Select acec WITH_LOCK

Requête:

Code: Select all

SELECT J.Code, J.Name, J.ManualEntry, J.JournalClass, AC.Id, AC.Account, J.CloseDate
FROM Journals J
LEFT JOIN Accounts AC ON AC.Id=J.LinkedAccountId
WHERE J.Id = 1
FOR UPDATE
Valeur J.LinkedAccountId est 0

Message d'erreur:
"ERREUR: FOR UPDATE ne peut être appliqué sur le côté possiblement NULL d'une jointure externe"

Solution:
Ajouter OF [Tablename]

Exemple:

Code: Select all

SELECT J.Code, J.Name, J.ManualEntry, J.JournalClass, AC.Id, AC.Account, J.CloseDate
FROM Journals J
LEFT JOIN Accounts AC ON AC.Id=J.LinkedAccountId
WHERE J.Id = 1
FOR UPDATE OF J
tintinux
Site Admin
Posts: 169
Joined: 21 Jun 2012, 19:07
Location: Blois (France)
Contact:

Re: UPDATE FOR dans postgres

Post by tintinux »

C'est un oubli fâcheux, non détecté faute de tests suffisants sur postgreSQL.
Je vais corriger dès que possible pour une prochaine version.
Merci pour votre indulgence et votre aide dans les tests !

Tintinux
Cordialement,

Tintinux
talexone
Posts: 12
Joined: 20 Feb 2014, 08:58

Re: UPDATE FOR dans postgres

Post by talexone »

Pour ne pas trop modifier votre code j'ai créé une fonctionne en attendant votre mise à jour.

Code: Select all

function TableNameFromQuery(Query: string): string;
var
  TempStr: string;
  offset, i: integer;
  KeyWords: array[0..6] of string = ('FROM','LEFT','RIGHT','INNER','WHERE',',',' ');
  Direction: array [0..6] of integer = (0,1,1,1,1,1,0); // 0 - Right Part , 1 - Left Part
begin
  TempStr := UpperCase(Query);
  for i := 0 to 6 do begin
    offset := Pos(KeyWords[i], TempStr);
    if offset > 0 then
      case Direction[i] of
        0: TempStr := Trim(RightStr(TempStr, Length(TempStr) - offset - (Length(KeyWords[i])-1)));
        1: TempStr := Trim(LeftStr(TempStr, offset - 1));
      end;
  end;
  result := TempStr;
end;
et modifié le TGQuery.Create:

Code: Select all

Select(aDbConnection, aSql + ' FOR UPDATE OF ' + TableNameFromQuery(aSql));
Le parser est très simple mais suffisant dans ce cas.

talexone
tintinux
Site Admin
Posts: 169
Joined: 21 Jun 2012, 19:07
Location: Blois (France)
Contact:

Re: UPDATE FOR dans postgres

Post by tintinux »

Bonjour

C'est une bonne idée que j'aurais suivie si j'avais plus de temps. Si vous l'avez testé avec succès, vous pouvez mettre à jour ce code vous-même, je vous ai donné les droits "Développeur" sur le SVN de SourceForge (je suppose que c'est le même pseudo !).

Il faut modifier uniquement le trunk, car on va laisser la V 1.0 comme cela, je préciserai qu'elle a certains problèmes sous Postgresql.

Et, attention, cet ajout de "OF table" ne doit se faire que sous PostgreSql, car MySql n'admet pas cette syntaxe. Il y a une fonction et des types énumérés pour faire la distinction, et idéalement on regroupe ce qui est spécifique à certains SGBD dans des méthodes suffixées par leur nom.

Cordialement,

Tintinux
Cordialement,

Tintinux
talexone
Posts: 12
Joined: 20 Feb 2014, 08:58

Re: UPDATE FOR dans postgres

Post by talexone »

Bonsoir,

J'ai ajouté la vérification de dbmstype dans mon code. Avez vous parametré mon compte pour commit? J'ai vu que sur sourceforge le ticket a été créé pour ce bug.

Cdt,

talexone
tintinux
Site Admin
Posts: 169
Joined: 21 Jun 2012, 19:07
Location: Blois (France)
Contact:

Re: UPDATE FOR dans postgres

Post by tintinux »

Oui, le compte SourceForge a été paramétré et apparemment vous avez pu publier...
J'avais ajouté le bug pour ne pas oublier et je vais vous l'assigner asap.
Je ferai des tests complémentaires ce soir.
Cordialement,
Tintinux
Cordialement,

Tintinux
tintinux
Site Admin
Posts: 169
Joined: 21 Jun 2012, 19:07
Location: Blois (France)
Contact:

Re: UPDATE FOR dans postgres

Post by tintinux »

Hello,

J'ai vérifié que le commit 949 fonctionne bien avec MySQL.

Par contre, je vois un problème potentiel avec PostgreSql si quelqu'un écrit dans le futur une requête avec JOIN non précédé de INNER
Ce mot clé étant facultatif sous SQL, sauf spécificité que j'ignorerais. La jointure INNER est faite par défaut.
D'autre part, je ne crois pas que la 1ère table sera trouvée, si elle est immédiatement suivie d'un retour à la ligne.

Normalement ça n'arrivera pas dans Gestinux actuellement, et la correction peut attendre, mais je suggère quand même une vérification, avec une base avec PostgreSql, de toutes les options de menu affichant un DbGrid.

Cordialement,
Cordialement,

Tintinux
talexone
Posts: 12
Joined: 20 Feb 2014, 08:58

Re: UPDATE FOR dans postgres

Post by talexone »

Bonjour,
tintinux wrote:Par contre, je vois un problème potentiel avec PostgreSql si quelqu'un écrit dans le futur une requête avec JOIN non précédé de INNER
Ce mot clé étant facultatif sous SQL, sauf spécificité que j'ignorerais. La jointure INNER est faite par défaut.
Ce n'est pas vraiment un problème car on peux facilement ajouter les mots clés à vérifier dans la liste. Je suis parti sur la base des requêtes existant dans gestinux qui pour la plus part n'utilise que LEFT JOIN (sauf erreur je n'ai pas vraiment scruté chaque requête existante).
tintinux wrote:D'autre part, je ne crois pas que la 1ère table sera trouvée, si elle est immédiatement suivie d'un retour à la ligne.
Pour le moment j'ai créé la fonction pour palier les erreur des fonctionnement de base, plus tard je pourrai faire des testes plus poussé et l'améliorer s'il faut.
tintinux wrote:je suggère quand même une vérification, avec une base avec PostgreSql, de toutes les options de menu affichant un DbGrid
J'ai essayé de tester dans chaque menu affichant une liste. Pour le moment sans problèmes.

A+

talexone
Post Reply