Page 1 of 1

UPDATE FOR dans postgres

Posted: 20 Feb 2014, 13:08
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

Re: UPDATE FOR dans postgres

Posted: 20 Feb 2014, 14:51
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

Re: UPDATE FOR dans postgres

Posted: 22 Feb 2014, 14:02
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

Re: UPDATE FOR dans postgres

Posted: 22 Feb 2014, 21:53
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

Re: UPDATE FOR dans postgres

Posted: 24 Feb 2014, 20:34
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

Re: UPDATE FOR dans postgres

Posted: 25 Feb 2014, 09:33
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

Re: UPDATE FOR dans postgres

Posted: 26 Feb 2014, 17:40
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,

Re: UPDATE FOR dans postgres

Posted: 26 Feb 2014, 19:28
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