7

z ramami Gra 2,1Jak utworzyć funkcję w PostgreSQL przy użyciu ewolucji w strukturze Play?

Mam następujące SQL zdefiniowanego w mojej ewolucji:

CREATE OR REPLACE FUNCTION idx(myArray anyarray, myElement anyelement) RETURNS int AS $$ 
SELECT i FROM (
    SELECT generate_series(array_lower(myArray,1),array_upper(myArray,1)) 
) g(i) 
WHERE myArray[i] = anyElement 
LIMIT 1; $$ LANGUAGE sql IMMUTABLE; 

Kiedy wykonać ewolucję, pojawia się następujący błąd:

We got the following error: ERROR: unterminated dollar-quoted string at or near 
"$$ SELECT i FROM (SELECT generate_series(array_lower(myArray,1), 
array_upper(myArray,1))) g(i) WHERE myArray[i] = anyElement LIMIT 1" Position: 
87 [ERROR:0, SQLSTATE:42601], while trying to run this SQL script: 

I używasz sterownika PostgreSQL w wersji 9.1-901.jdbc4.

Spojrzałem na dziennikach postgres zapytań i okazało się, że Play próbuje wykonać następujące czynności:

LOG: execute <unnamed>: insert into play_evolutions values($1, $2, $3, $4, $5, $6, $7) 
PST DETAIL: parameters: $1 = '1', 
         $2 = 'c834d463ebd9916b0a3388040300a0926514faef', 
         $3 = '2013-03-05 00:00:00', 
         $4 = '-- THE EVOLUTION UP STATEMENTS GO HERE', 
         $5 = '-- THE EVOLUTION DOWN STATEMENTS GO HERE', 
         $6 = 'applying_up', 
         $7 = '' 

Więc dla niektórych powodem Play próbuje wstawić SQL w kolumnie tekstowej bez właściwie ucieczki. Czy ktoś inny znalazł dla tego jakieś zadanie? Czy uważasz, że jest to problem JDBC, a nie Play? Czy ktoś ma Liquibase współpracujące z Play 2.1?

Również zmiana wartości $$ na "nie działa. W takim przypadku otrzymujemy inny błąd, ale wciąż nie możemy wykonać ewolucji.

Edytuj: Dodałem przykład z zupełnie nowego projektu gry. Proszę pobrać pod adresem: http://elijah.zupancic.name/files/play_evolution_problem.tar.gz

Aby uzyskać przykład działania, należy utworzyć nową bazę danych, jak pokazano w pierwszym komentarzu do ewolucji 1.sql. Następnie musisz skonfigurować plik conf/application.conf, aby połączyć się z postgres na właściwym porcie i z właściwym użytkownikiem.

Właśnie przeprowadziłem eksperyment, w którym próbuję wstawić funkcję create sql całkowicie poza strukturą gry. Przykład jest tutaj: http://elijah.zupancic.name/files/PgCreateFunction.tar.gz <

Okazuje się, że jest bardzo powtarzalny.

EDYCJA: Okazuje się, że nie mogę odtworzyć go w Javie.

+0

Co widzisz jest wyjście debugowania z Pg pokazując parametryzowany zapytanie i jej argumenty. Każdy parametr jest wysyłany osobno w protokole fe/be i nie musi być przechwytywany przez klienta. Kwestia, którą tu widzisz, prawie na pewno jest tylko wtedy, gdy parametry debugowania Pg parametrów są bezwarunkowe za pomocą '' '; Rzeczywisty parametr będzie w porządku. Jeśli nie udało się uciec, zobaczysz jedną dużą kwerendę SQL z podstawionymi zamiast niej wszystkimi parametrami. –

+0

Wydaje się bardziej prawdopodobne, że napotkasz problem PgJDBC z analizą kwotowań w dolarach podczas separacji wielostopniowej. Pomocny byłby samodzielny kompilowany przykład. http://sscce.org/. Jeśli dodasz szczegóły w edycji, skomentuj tutaj, aby otrzymywać powiadomienia. –

+0

Witam Craig, dodałem SSCCE zgodnie z Twoją prośbą. Graj, spójrz.Odtwarza się w najprostszej konfiguracji gry, jaką mogłem stworzyć. – Elijah

Odpowiedz

18

Jest to artefakt, w jaki sposób Play analizuje ewolucje. Ponieważ analizuje każdą instrukcję na średnikach, nie może obsługiwać definicji procedur składowanych. Problem został rozwiązany w Play 2.1, umożliwiając określenie osadzonych średników poprzez podwojenie ich. Patrz na przykład https://github.com/playframework/Play20/pull/649.

Rozwiązywanie podobnego problemu dla mnie za pomocą Play 2.1. Sugeruję, aby przedefiniować swoją ewolucję w następujący sposób, a następnie spróbuj ponownie:

CREATE OR REPLACE FUNCTION idx(myArray anyarray, myElement anyelement) RETURNS int AS $$ 
SELECT i FROM (
    SELECT generate_series(array_lower(myArray,1),array_upper(myArray,1)) 
) g(i) 
WHERE myArray[i] = anyElement 
LIMIT 1;; $$ LANGUAGE sql IMMUTABLE;