$$ é apenas o mínimo para cotações em dólares
. Torne (muito!) menos provável de entrar em conflito com strings no literal incluído, colocando uma string entre os dólares:
CREATE OR REPLACE FUNCTION time_to_sec(timepoint timestamp with time zone)
RETURNS bigint LANGUAGE plpgsql AS
$BODY$
DECLARE
seconds bigint;
secondsFromEpoch bigint;
secondsFromMidnight bigint;
BEGIN
secondsFromEpoch = EXTRACT(EPOCH FROM timepoint)::bigint;
secondsFromMidnight = EXTRACT(EPOCH FROM CURRENT_TIMESTAMP::date)::bigint;
seconds = secondsFromEpoch - secondsFromMidnight;
return seconds;
END;
$BODY$;
Mais conselhos
-
O operador de atribuição em plpgsql é:=.=não está documentado e pode desaparecer em versões futuras. Mais nesta pergunta relacionada .
-
UseCURRENT_DATEem vez deCURRENT_TIMESTAMP::date.
-
É permitido, mas eu aconselharia não usar nomes de parâmetros de maiúsculas e minúsculas em plpgsql. Eles não diferenciam maiúsculas de minúsculas.
-
Mais importante ainda, simplifique :
CREATE OR REPLACE FUNCTION time_to_sec2(timepoint timestamp with time zone) RETURNS bigint LANGUAGE plpgsql STABLE AS $BODY$ BEGIN RETURN EXTRACT(EPOCH FROM timepoint - current_date)::bigint; END; $BODY$;
Ou ainda:
CREATE OR REPLACE FUNCTION time_to_sec3(timepoint timestamp with time zone) RETURNS bigint LANGUAGE sql AS $BODY$ SELECT EXTRACT(EPOCH FROM timepoint - current_date)::bigint; $BODY$; -
Pode ser declaradoSTABLE!
- Há também a função intimamente relacionada
age()no PostgreSQL fazendo quase, mas não exatamente, o mesmo:ele retorna um resultado "simbólico" com anos e meses padrão. Portanto, expressão comage()pode gerar resultados diferentes por períodos mais longos.
Estes são todos equivalentes - exceto os dois últimos que se desviam com períodos de tempo mais longos:
WITH x(t) AS (VALUES ('2012-07-20 03:51:26+02'::timestamptz))
SELECT time_to_sec(t) AS t1
,time_to_sec2(t) AS t2
,time_to_sec3(t) AS t3
,EXTRACT(EPOCH FROM t - current_date)::bigint AS t4
,EXTRACT(EPOCH FROM age(t, current_date))::bigint AS t5 -- deviates
,EXTRACT(EPOCH FROM age(t))::bigint * -1 AS t6 -- deviates
FROM x;
Quanto à pergunta original:esta mensagem de erro do PostgreSQL não significa necessariamente que o problema é com o cifrão:
Na maioria das vezes está faltando um
; antes dessa linha. Ou talvez um caractere especial sem escape em XML, como < > & ? O cifrão $ deve estar bem. Mas não sou especialista em formigas. Deve haver mais contexto no log do PostgreSQL.