Commits

Will Glozer committed fcf8a3b

implement support for integer_datetimes

Comments (0)

Files changed (8)

 	@rm -rf $(NAME)-$(VERSION) $(NAME)-*.tar.gz
 
 test: $(TESTS:test_src/%.erl=test_ebin/%.beam) $(BEAMS)
-	dialyzer --src -c src
+	@dialyzer --src -c src
 	$(ERL) -pa ebin/ -pa test_ebin/ -noshell -s pgsql_tests run_tests -s init stop
 
 # ------------------------------------------------------------------------

src/pgsql_binary.erl

 -export([encode/2, decode/2, supports/1]).
 
 -define(int32, 1/big-signed-unit:32).
+-define(datetime, (get(datetime_mod))).
 
 encode(_Any, null)  -> <<-1:?int32>>;
 encode(bool, true)  -> <<1:?int32, 1:1/big-signed-unit:8>>;
 encode(int8, N)     -> <<8:?int32, N:1/big-signed-unit:64>>;
 encode(float4, N)   -> <<4:?int32, N:1/big-float-unit:32>>;
 encode(float8, N)   -> <<8:?int32, N:1/big-float-unit:64>>;
-encode(Type, B) when Type == time; Type == timetz          -> pgsql_datetime:encode(Type, B);
-encode(Type, B) when Type == date; Type == timestamp       -> pgsql_datetime:encode(Type, B);
-encode(Type, B) when Type == timestamptz; Type == interval -> pgsql_datetime:encode(Type, B);
+encode(Type, B) when Type == time; Type == timetz          -> ?datetime:encode(Type, B);
+encode(Type, B) when Type == date; Type == timestamp       -> ?datetime:encode(Type, B);
+encode(Type, B) when Type == timestamptz; Type == interval -> ?datetime:encode(Type, B);
 encode(bytea, B) when is_binary(B)   -> <<(byte_size(B)):?int32, B/binary>>;
 encode(text, B) when is_binary(B)    -> <<(byte_size(B)):?int32, B/binary>>;
 encode(varchar, B) when is_binary(B) -> <<(byte_size(B)):?int32, B/binary>>;
 decode(float4, <<N:1/big-float-unit:32>>)   -> N;
 decode(float8, <<N:1/big-float-unit:64>>)   -> N;
 decode(record, <<_:?int32, Rest/binary>>)   -> list_to_tuple(decode_record(Rest, []));
-decode(Type, B) when Type == time; Type == timetz          -> pgsql_datetime:decode(Type, B);
-decode(Type, B) when Type == date; Type == timestamp       -> pgsql_datetime:decode(Type, B);
-decode(Type, B) when Type == timestamptz; Type == interval -> pgsql_datetime:decode(Type, B);
+decode(Type, B) when Type == time; Type == timetz          -> ?datetime:decode(Type, B);
+decode(Type, B) when Type == date; Type == timestamp       -> ?datetime:decode(Type, B);
+decode(Type, B) when Type == timestamptz; Type == interval -> ?datetime:decode(Type, B);
 decode(_Other, Bin) -> Bin.
 
 decode_record(<<>>, Acc) ->

src/pgsql_connection.erl

 
 %% ReadyForQuery
 initializing({$Z, <<Status:8>>}, State) ->
+    #state{parameters = Parameters, reply_to = Reply_To} = State,
     erase(username),
     erase(password),
-    gen_fsm:reply(State#state.reply_to, {ok, self()}),
+    case lists:keysearch(<<"integer_datetimes">>, 1, Parameters) of
+        {value, {_, <<"on">>}}  -> put(datetime_mod, pgsql_idatetime);
+        {value, {_, <<"off">>}} -> put(datetime_mod, pgsql_fdatetime)
+    end,
+    gen_fsm:reply(Reply_To, {ok, self()}),
     {next_state, ready, State#state{txstatus = Status}}.
 
 ready(_Msg, State) ->

src/pgsql_datetime.erl

-%%% Copyright (C) 2008 - Will Glozer.  All rights reserved.
-
--module(pgsql_datetime).
-
--export([decode/2, encode/2]).
-
--define(int16, 1/big-signed-unit:16).
--define(int32, 1/big-signed-unit:32).
-
--define(postgres_epoc_jdate, 2451545).
-
--define(mins_per_hour, 60).
--define(secs_per_day, 86400.0).
--define(secs_per_hour, 3600.0).
--define(secs_per_minute, 60.0).
-
-decode(date, <<J:1/big-signed-unit:32>>)             -> j2date(?postgres_epoc_jdate + J);
-decode(time, <<N:1/big-float-unit:64>>)              -> f2time(N);
-decode(timetz, <<N:1/big-float-unit:64, TZ:?int32>>) -> {f2time(N), TZ};
-decode(timestamp, <<N:1/big-float-unit:64>>)         -> f2timestamp(N);
-decode(timestamptz, <<N:1/big-float-unit:64>>)       -> f2timestamp(N);
-decode(interval, <<N:1/big-float-unit:64, D:?int32, M:?int32>>) -> {f2time(N), D, M}.
-
-encode(date, D)         -> <<4:?int32, (date2j(D) - ?postgres_epoc_jdate):1/big-signed-unit:32>>;
-encode(time, T)         -> <<8:?int32, (time2f(T)):1/big-float-unit:64>>;
-encode(timetz, {T, TZ}) -> <<12:?int32, (time2f(T)):1/big-float-unit:64, TZ:?int32>>;
-encode(timestamp, TS)   -> <<8:?int32, (timestamp2f(TS)):1/big-float-unit:64>>;
-encode(timestamptz, TS) -> <<8:?int32, (timestamp2f(TS)):1/big-float-unit:64>>;
-encode(interval, {T, D, M}) -> <<16:?int32, (time2f(T)):1/big-float-unit:64, D:?int32, M:?int32>>.
-
-j2date(N) ->
-    J = N + 32044,
-    Q1 = J div 146097,
-    Extra = (J - Q1 * 146097) * 4 + 3,
-    J2 = J + 60 + Q1 * 3 + Extra div 146097,
-    Q2 = J2 div 1461,
-    J3 = J2 - Q2 * 1461,
-    Y = J3 * 4 div 1461,
-    case Y of
-        0 -> J4 = ((J3 + 306) rem 366) + 123;
-        _ -> J4 = ((J3 + 305) rem 365) + 123
-    end,
-    Year = (Y + Q2 * 4) - 4800,
-    Q3 = J4 * 2141 div 65536,
-    Day = J4 - 7834 * Q3 div 256,
-    Month = (Q3 + 10) rem 12 + 1,
-    {Year, Month, Day}.
-
-date2j({Y, M, D}) ->
-    case M > 2 of
-        true ->
-            M2 = M + 1,
-            Y2 = Y + 4800;
-        false ->
-            M2 = M + 13,
-            Y2 = Y + 4799
-    end,
-    C = Y2 div 100,
-    J1 = Y2 * 365 - 32167,
-    J2 = J1 + (Y2 div 4 - C + C div 4),
-    J2 + 7834 * M2 div 256 + D.
-
-f2time(N) ->
-    {R1, Hour} = tmodulo(N, ?secs_per_hour),
-    {R2, Min}  = tmodulo(R1, ?secs_per_minute),
-    {R3, Sec}  = tmodulo(R2, 1.0),
-    case timeround(R3) of
-        US when US >= 1.0 -> f2time(ceiling(N));
-        US                -> {Hour, Min, Sec + US}
-    end.
-
-time2f({H, M, S}) ->
-    ((H * ?mins_per_hour + M) * ?secs_per_minute) + S.
-
-f2timestamp(N) ->
-    case tmodulo(N, ?secs_per_day) of
-        {T, D} when T < 0 -> f2timestamp2(D - 1 + ?postgres_epoc_jdate, T + ?secs_per_day);
-        {T, D}            -> f2timestamp2(D + ?postgres_epoc_jdate, T)
-    end.
-
-f2timestamp2(D, T) ->
-    {_H, _M, S} = Time = f2time(T),
-    Date = j2date(D),
-    case tsround(S - trunc(S)) of
-        N when N >= 1.0 ->
-            case ceiling(T) of
-                T2 when T2 > ?secs_per_day -> f2timestamp2(D + 1, 0.0);
-                T2                         -> f2timestamp2(T2, D)
-            end;
-        _ -> ok
-    end,
-    {Date, Time}.
-
-timestamp2f({Date, Time}) ->
-    D = date2j(Date) - ?postgres_epoc_jdate,
-    D * ?secs_per_day + time2f(Time).
-
-tmodulo(T, U) ->
-    case T < 0 of
-        true  -> Q = ceiling(T / U);
-        false -> Q = floor(T / U)
-    end,
-    case Q of
-        0 -> {T, Q};
-        _ -> {T - rint(Q * U), Q}
-    end.
-
-rint(N)      -> round(N) * 1.0.
-timeround(J) -> rint(J * 10000000000.0) / 10000000000.0.
-tsround(J)   -> rint(J * 1000000.0) / 1000000.0.
-
-floor(X) ->
-    T = erlang:trunc(X),
-    case (X - T) of
-        N when N < 0 -> T - 1;
-        N when N > 0 -> T;
-        _            -> T
-    end.
-
-ceiling(X) ->
-    T = erlang:trunc(X),
-    case (X - T) of
-        N when N < 0 -> T;
-        N when N > 0 -> T + 1;
-        _            -> T
-    end.

src/pgsql_fdatetime.erl

+%%% Copyright (C) 2008 - Will Glozer.  All rights reserved.
+
+-module(pgsql_fdatetime).
+
+-export([decode/2, encode/2]).
+
+-define(int32, 1/big-signed-unit:32).
+
+-define(postgres_epoc_jdate, 2451545).
+
+-define(mins_per_hour, 60).
+-define(secs_per_day, 86400.0).
+-define(secs_per_hour, 3600.0).
+-define(secs_per_minute, 60.0).
+
+decode(date, <<J:1/big-signed-unit:32>>)             -> j2date(?postgres_epoc_jdate + J);
+decode(time, <<N:1/big-float-unit:64>>)              -> f2time(N);
+decode(timetz, <<N:1/big-float-unit:64, TZ:?int32>>) -> {f2time(N), TZ};
+decode(timestamp, <<N:1/big-float-unit:64>>)         -> f2timestamp(N);
+decode(timestamptz, <<N:1/big-float-unit:64>>)       -> f2timestamp(N);
+decode(interval, <<N:1/big-float-unit:64, D:?int32, M:?int32>>) -> {f2time(N), D, M}.
+
+encode(date, D)         -> <<4:?int32, (date2j(D) - ?postgres_epoc_jdate):1/big-signed-unit:32>>;
+encode(time, T)         -> <<8:?int32, (time2f(T)):1/big-float-unit:64>>;
+encode(timetz, {T, TZ}) -> <<12:?int32, (time2f(T)):1/big-float-unit:64, TZ:?int32>>;
+encode(timestamp, TS)   -> <<8:?int32, (timestamp2f(TS)):1/big-float-unit:64>>;
+encode(timestamptz, TS) -> <<8:?int32, (timestamp2f(TS)):1/big-float-unit:64>>;
+encode(interval, {T, D, M}) -> <<16:?int32, (time2f(T)):1/big-float-unit:64, D:?int32, M:?int32>>.
+
+j2date(N) ->
+    J = N + 32044,
+    Q1 = J div 146097,
+    Extra = (J - Q1 * 146097) * 4 + 3,
+    J2 = J + 60 + Q1 * 3 + Extra div 146097,
+    Q2 = J2 div 1461,
+    J3 = J2 - Q2 * 1461,
+    Y = J3 * 4 div 1461,
+    case Y of
+        0 -> J4 = ((J3 + 306) rem 366) + 123;
+        _ -> J4 = ((J3 + 305) rem 365) + 123
+    end,
+    Year = (Y + Q2 * 4) - 4800,
+    Q3 = J4 * 2141 div 65536,
+    Day = J4 - 7834 * Q3 div 256,
+    Month = (Q3 + 10) rem 12 + 1,
+    {Year, Month, Day}.
+
+date2j({Y, M, D}) ->
+    case M > 2 of
+        true ->
+            M2 = M + 1,
+            Y2 = Y + 4800;
+        false ->
+            M2 = M + 13,
+            Y2 = Y + 4799
+    end,
+    C = Y2 div 100,
+    J1 = Y2 * 365 - 32167,
+    J2 = J1 + (Y2 div 4 - C + C div 4),
+    J2 + 7834 * M2 div 256 + D.
+
+f2time(N) ->
+    {R1, Hour} = tmodulo(N, ?secs_per_hour),
+    {R2, Min}  = tmodulo(R1, ?secs_per_minute),
+    {R3, Sec}  = tmodulo(R2, 1.0),
+    case timeround(R3) of
+        US when US >= 1.0 -> f2time(ceiling(N));
+        US                -> {Hour, Min, Sec + US}
+    end.
+
+time2f({H, M, S}) ->
+    ((H * ?mins_per_hour + M) * ?secs_per_minute) + S.
+
+f2timestamp(N) ->
+    case tmodulo(N, ?secs_per_day) of
+        {T, D} when T < 0 -> f2timestamp2(D - 1 + ?postgres_epoc_jdate, T + ?secs_per_day);
+        {T, D}            -> f2timestamp2(D + ?postgres_epoc_jdate, T)
+    end.
+
+f2timestamp2(D, T) ->
+    {_H, _M, S} = Time = f2time(T),
+    Date = j2date(D),
+    case tsround(S - trunc(S)) of
+        N when N >= 1.0 ->
+            case ceiling(T) of
+                T2 when T2 > ?secs_per_day -> f2timestamp2(D + 1, 0.0);
+                T2                         -> f2timestamp2(T2, D)
+            end;
+        _ -> ok
+    end,
+    {Date, Time}.
+
+timestamp2f({Date, Time}) ->
+    D = date2j(Date) - ?postgres_epoc_jdate,
+    D * ?secs_per_day + time2f(Time).
+
+tmodulo(T, U) ->
+    case T < 0 of
+        true  -> Q = ceiling(T / U);
+        false -> Q = floor(T / U)
+    end,
+    case Q of
+        0 -> {T, Q};
+        _ -> {T - rint(Q * U), Q}
+    end.
+
+rint(N)      -> round(N) * 1.0.
+timeround(J) -> rint(J * 10000000000.0) / 10000000000.0.
+tsround(J)   -> rint(J * 1000000.0) / 1000000.0.
+
+floor(X) ->
+    T = erlang:trunc(X),
+    case (X - T) of
+        N when N < 0 -> T - 1;
+        N when N > 0 -> T;
+        _            -> T
+    end.
+
+ceiling(X) ->
+    T = erlang:trunc(X),
+    case (X - T) of
+        N when N < 0 -> T;
+        N when N > 0 -> T + 1;
+        _            -> T
+    end.

src/pgsql_idatetime.erl

+%%% Copyright (C) 2008 - Will Glozer.  All rights reserved.
+
+-module(pgsql_idatetime).
+
+-export([decode/2, encode/2]).
+
+-define(int32, 1/big-signed-unit:32).
+-define(int64, 1/big-signed-unit:64).
+
+-define(postgres_epoc_jdate, 2451545).
+
+-define(mins_per_hour, 60).
+-define(secs_per_minute, 60).
+
+-define(usecs_per_day, 86400000000).
+-define(usecs_per_hour, 3600000000).
+-define(usecs_per_minute, 60000000).
+-define(usecs_per_sec, 1000000).
+
+decode(date, <<J:?int32>>)                         -> j2date(?postgres_epoc_jdate + J);
+decode(time, <<N:?int64>>)                         -> i2time(N);
+decode(timetz, <<N:?int64, TZ:?int32>>)            -> {i2time(N), TZ};
+decode(timestamp, <<N:?int64>>)                    -> i2timestamp(N);
+decode(timestamptz, <<N:?int64>>)                  -> i2timestamp(N);
+decode(interval, <<N:?int64, D:?int32, M:?int32>>) -> {i2time(N), D, M}.
+
+encode(date, D)         -> <<4:?int32, (date2j(D) - ?postgres_epoc_jdate):?int32>>;
+encode(time, T)         -> <<8:?int32, (time2i(T)):?int64>>;
+encode(timetz, {T, TZ}) -> <<12:?int32, (time2i(T)):?int64, TZ:?int32>>;
+encode(timestamp, TS)   -> <<8:?int32, (timestamp2i(TS)):?int64>>;
+encode(timestamptz, TS) -> <<8:?int32, (timestamp2i(TS)):?int64>>;
+encode(interval, {T, D, M}) -> <<16:?int32, (time2i(T)):?int64, D:?int32, M:?int32>>.
+
+j2date(N) ->
+    J = N + 32044,
+    Q1 = J div 146097,
+    Extra = (J - Q1 * 146097) * 4 + 3,
+    J2 = J + 60 + Q1 * 3 + Extra div 146097,
+    Q2 = J2 div 1461,
+    J3 = J2 - Q2 * 1461,
+    Y = J3 * 4 div 1461,
+    case Y of
+        0 -> J4 = ((J3 + 306) rem 366) + 123;
+        _ -> J4 = ((J3 + 305) rem 365) + 123
+    end,
+    Year = (Y + Q2 * 4) - 4800,
+    Q3 = J4 * 2141 div 65536,
+    Day = J4 - 7834 * Q3 div 256,
+    Month = (Q3 + 10) rem 12 + 1,
+    {Year, Month, Day}.
+
+date2j({Y, M, D}) ->
+    case M > 2 of
+        true ->
+            M2 = M + 1,
+            Y2 = Y + 4800;
+        false ->
+            M2 = M + 13,
+            Y2 = Y + 4799
+    end,
+    C = Y2 div 100,
+    J1 = Y2 * 365 - 32167,
+    J2 = J1 + (Y2 div 4 - C + C div 4),
+    J2 + 7834 * M2 div 256 + D.
+
+i2time(N) ->
+    Hour = N div ?usecs_per_hour,
+    R1 = N - Hour * ?usecs_per_hour,
+    Min = R1 div ?usecs_per_minute,
+    R2 = R1 - Min * ?usecs_per_minute,
+    Sec = R2 div ?usecs_per_sec,
+    US = R2 - Sec * ?usecs_per_sec,
+    {Hour, Min, Sec + US / ?usecs_per_sec}.
+
+time2i({H, M, S}) ->
+    US = trunc(round(S * ?usecs_per_sec)),
+    ((H * ?mins_per_hour + M) * ?secs_per_minute) * ?usecs_per_sec + US.
+
+i2timestamp(N) ->
+    case tmodulo(N, ?usecs_per_day) of
+        {T, D} when T < 0 -> i2timestamp2(D - 1 + ?postgres_epoc_jdate, T + ?usecs_per_day);
+        {T, D}            -> i2timestamp2(D + ?postgres_epoc_jdate, T)
+    end.
+
+i2timestamp2(D, T) ->
+    {j2date(D), i2time(T)}.
+
+timestamp2i({Date, Time}) ->
+    D = date2j(Date) - ?postgres_epoc_jdate,
+    D * ?usecs_per_day + time2i(Time).
+
+tmodulo(T, U) ->
+    case T div U of
+        0 -> {T, 0};
+        Q -> {T - (Q * U), Q}
+    end.

test_src/pgsql_tests.erl

 -include("pgsql.hrl").
 
 -define(host, "localhost").
+-define(port, 5432).
 
 connect_test() ->
     connect_only([[]]).
     connect_only([[{database, "epgsql_test_db1"}]]).
 
 connect_as_test() ->
-    connect_only(["epgsql_test1", [{database, "epgsql_test_db1"}]]).
+    connect_only(["epgsql_test", [{database, "epgsql_test_db1"}]]).
 
 connect_with_cleartext_test() ->
     connect_only(["epgsql_test_cleartext",
         pgsql:connect(?host,
                       "epgsql_test_md5",
                       "epgsql_test_sha1",
-                      [{database, "epgsql_test_db1"}]).
+                      [{port, ?port}, {database, "epgsql_test_db1"}]).
 
 select_test() ->
     with_connection(
 parameter_get_test() ->
     with_connection(
       fun(C) ->
-              {ok, <<"off">>} = pgsql:get_parameter(C, "integer_datetimes")
+              {ok, <<"off">>} = pgsql:get_parameter(C, "is_superuser")
       end).
 
 parameter_set_test() ->
               {ok, _Cols, [{<<"02.01.2000">>}]} = pgsql:squery(C, "select '2000-01-02'::date")
       end).
 
-type_test() ->
-    check_type(bool, "true", true, [true, false]),
-    check_type(bpchar, "'A'", $A, [1, $1, 255], "c_char"),
+numeric_type_test() ->
     check_type(int2, "1", 1, [0, 256, -32768, +32767]),
     check_type(int4, "1", 1, [0, 512, -2147483648, +2147483647]),
     check_type(int8, "1", 1, [0, 1024, -9223372036854775808, +9223372036854775807]),
     check_type(float4, "1.0", 1.0, [0.0, 1.23456, -1.23456]),
-    check_type(float8, "1.0", 1.0, [0.0, 1.23456789012345, -1.23456789012345]),
-    check_type(bytea, "E'\001\002'", <<1,2>>, [<<>>, <<0,128,255>>]),
+    check_type(float8, "1.0", 1.0, [0.0, 1.23456789012345, -1.23456789012345]).
+
+character_type_test() ->
+    check_type(bpchar, "'A'", $A, [1, $1, 255], "c_char"),
     check_type(text, "'hi'", <<"hi">>, [<<"">>, <<"hi">>]),
-    check_type(varchar, "'hi'", <<"hi">>, [<<"">>, <<"hi">>]),
-    check_type(date, "'2008-01-02'", {2008,1,2}, [{-4712,1,1}, {5874897,1,1}]),
-    check_type(time, "'00:01:02'", {0,1,2.0}, [{0,0,0.0}, {24,0,0.0}]),
-    check_type(timetz, "'00:01:02-01'", {{0,1,2.0},1*60*60}, [{{0,0,0.0},0}, {{24,0,0.0},-13*60*60}]),
-    check_type(timestamp, "'2008-01-02 03:04:05'", {{2008,1,2},{3,4,5.0}},
-               [{{-4712,1,1},{0,0,0.0}}, {{5874897,12,31}, {23,59,59.0}}]),
-    check_type(interval, "'1 hour 2 minutes 3.1 seconds'", {{1,2,3.1},0,0},
-               [{{0,0,0.0},0,-178000000 * 12}, {{0,0,0.0},0,178000000 * 12}]).
+    check_type(varchar, "'hi'", <<"hi">>, [<<"">>, <<"hi">>]).
+
+date_time_type_test() ->
+    with_connection(
+      fun(C) ->
+              case pgsql:get_parameter(C, "integer_datetimes") of
+                  {ok, <<"on">>}  -> MaxTsDate = 294276;
+                  {ok, <<"off">>} -> MaxTsDate = 5874897
+              end,
+
+              check_type(date, "'2008-01-02'", {2008,1,2}, [{-4712,1,1}, {5874897,1,1}]),
+              check_type(time, "'00:01:02'", {0,1,2.0}, [{0,0,0.0}, {24,0,0.0}]),
+              check_type(timetz, "'00:01:02-01'", {{0,1,2.0},1*60*60},
+                         [{{0,0,0.0},0}, {{24,0,0.0},-13*60*60}]),
+              check_type(timestamp, "'2008-01-02 03:04:05'", {{2008,1,2},{3,4,5.0}},
+                         [{{-4712,1,1},{0,0,0.0}}, {{MaxTsDate,12,31}, {23,59,59.0}}]),
+              check_type(interval, "'1 hour 2 minutes 3.1 seconds'", {{1,2,3.1},0,0},
+                         [{{0,0,0.0},0,-178000000 * 12}, {{0,0,0.0},0,178000000 * 12}])
+      end).
+
+misc_type_test() ->
+    check_type(bool, "true", true, [true, false]),
+    check_type(bytea, "E'\001\002'", <<1,2>>, [<<>>, <<0,128,255>>]).
 
 text_format_test() ->
     with_connection(
 %% -- internal functions --
 
 connect_only(Args) ->
-    {ok, C} = apply(pgsql, connect, [?host | Args]),
+    {ok, C} = apply(pgsql, connect, [?host, [{port, ?port} | Args]]),
     pgsql:close(C),
     flush().
 
 with_connection(F) ->
-    {ok, C} = pgsql:connect(?host, "epgsql_test1", [{database, "epgsql_test_db1"}]),
+    Args = [{port, ?port}, {database, "epgsql_test_db1"}],
+    {ok, C} = pgsql:connect(?host, "epgsql_test", Args),
     try
         F(C)
     after
     end,
     flush().
 
-
 with_rollback(F) ->
     with_connection(
       fun(C) ->

test_src/test_schema.sql

 -- this script should be run as the same user the tests will be run as,
 -- so that the test for connecting as the 'current user' succeeds
 --
--- the following lines must be added to pg_hba.conf for the relevant
--- auth tests to succeed:
+-- the following lines must be added to pg_hba.conf for all tests to
+-- succeed:
 --
+-- host    epgsql_test_db1 epgsql_test             127.0.0.1/32    trust
 -- host    epgsql_test_db1 epgsql_test_md5         127.0.0.1/32    md5
 -- host    epgsql_test_db1 epgsql_test_cleartext   127.0.0.1/32    password
+--
+-- any 'trust all' must be commented out for the invalid password test
+-- to succeed.
 
 
 CREATE USER epgsql_test;
 end
 $$ language plpgsql;
 
-GRANT ALL ON TABLE test_table1 TO epgsql_test1;
-GRANT ALL ON TABLE test_table2 TO epgsql_test1;
-GRANT ALL ON FUNCTION insert_test1(integer, text) TO epgsql_test1;
-GRANT ALL ON FUNCTION do_nothing() TO epgsql_test1;
+GRANT ALL ON TABLE test_table1 TO epgsql_test;
+GRANT ALL ON TABLE test_table2 TO epgsql_test;
+GRANT ALL ON FUNCTION insert_test1(integer, text) TO epgsql_test;
+GRANT ALL ON FUNCTION do_nothing() TO epgsql_test;