Browse Source

Merge pull request #204 from SIfoxDevTeam/timerange_fix

fix range codecs
Sergey Prokhorov 5 years ago
parent
commit
c494efdd8d

+ 5 - 1
src/datatypes/epgsql_codec_intrange.erl

@@ -16,7 +16,7 @@
 
 -export_type([data/0]).
 
--type data() :: {left(), right()}.
+-type data() :: {left(), right()} | empty.
 
 -type left() :: minus_infinity | integer().
 -type right() :: plus_infinity | integer().
@@ -27,11 +27,15 @@ init(_, _) -> [].
 names() ->
     [int4range, int8range].
 
+encode(empty, _, _) ->
+    <<1>>;
 encode(Range, int4range, _) ->
     encode_int4range(Range);
 encode(Range, int8range, _) ->
     encode_int8range(Range).
 
+decode(<<1>>, _, _) ->
+    empty;
 decode(Bin, int4range, _) ->
     decode_int4range(Bin);
 decode(Bin, int8range, _) ->

+ 23 - 4
src/datatypes/epgsql_codec_timerange.erl

@@ -16,7 +16,10 @@
 
 -export_type([data/0]).
 
--type data() :: {epgsql_codec_datetime:data(), epgsql_codec_datetime:data()} | empty.
+-type data() :: {left(), right()} | empty.
+
+-type left() :: minus_infinity | epgsql_codec_datetime:data().
+-type right() :: plus_infinity | epgsql_codec_datetime:data().
 
 init(_, Sock) ->
     case epgsql_sock:get_parameter_internal(<<"integer_datetimes">>, Sock) of
@@ -29,6 +32,14 @@ names() ->
 
 encode(empty, _T, _CM) ->
     <<1>>;
+encode({minus_infinity, plus_infinity}, _T, _CM) ->
+    <<24:1/big-signed-unit:8>>;
+encode({From, plus_infinity}, Type, EncMod) ->
+    FromBin = encode_member(Type, From, EncMod),
+    <<18:1/big-signed-unit:8, (byte_size(FromBin)):?int32, FromBin/binary>>;
+encode({minus_infinity, To}, Type, EncMod) ->
+    ToBin = encode_member(Type, To, EncMod),
+    <<8:1/big-signed-unit:8, (byte_size(ToBin)):?int32, ToBin/binary>>;
 encode({From, To}, Type, EncMod) ->
     FromBin = encode_member(Type, From, EncMod),
     ToBin = encode_member(Type, To, EncMod),
@@ -38,11 +49,19 @@ encode({From, To}, Type, EncMod) ->
 
 decode(<<1>>, _, _) ->
     empty;
-decode(<<2:1/big-signed-unit:8,
+decode(<<Flag:1/big-signed-unit:8,
          FromLen:?int32, FromBin:FromLen/binary,
          ToLen:?int32, ToBin:ToLen/binary>>,
-       Type, EncMod) ->
-    {decode_member(Type, FromBin, EncMod), decode_member(Type, ToBin, EncMod)}.
+       Type, EncMod) when Flag =:= 0; Flag =:= 2; Flag =:= 4; Flag =:= 6 -> %% () [) (] []
+    {decode_member(Type, FromBin, EncMod), decode_member(Type, ToBin, EncMod)};
+decode(<<Flag:1/big-signed-unit:8, ToLen:?int32, ToBin:ToLen/binary>>,
+    Type, EncMod) when Flag =:= 8; Flag =:= 12 -> %% (] ()
+    {minus_infinity, decode_member(Type, ToBin, EncMod)};
+decode(<<Flag:1/big-signed-unit:8, FromLen:?int32, FromBin:FromLen/binary>>,
+    Type, EncMod) when Flag =:= 16; Flag =:= 18 -> %% [) ()
+    {decode_member(Type, FromBin, EncMod), plus_infinity};
+decode(<<24:1/big-signed-unit:8>>, _, _) ->
+    {minus_infinity, plus_infinity}.
 
 decode_text(V, _, _) -> V.
 

+ 17 - 7
test/epgsql_SUITE.erl

@@ -1186,7 +1186,8 @@ range_type(Config) ->
         check_type(Config, int4range, "int4range(10, 20)", {10, 20}, [
             {1, 58}, {-1, 12}, {-985521, 5412687}, {minus_infinity, 0},
             {984655, plus_infinity}, {minus_infinity, plus_infinity}
-        ])
+        ]),
+        check_type(Config, int4range, "int4range(10, 10)", empty, [])
    end, []).
 
 range8_type(Config) ->
@@ -1195,17 +1196,26 @@ range8_type(Config) ->
             {1, 58}, {-1, 12}, {-9223372036854775808, 5412687},
             {minus_infinity, 9223372036854775807},
             {984655, plus_infinity}, {minus_infinity, plus_infinity}
-        ])
+        ]),
+        check_type(Config, int8range, "int8range(10, 10)", empty, [])
     end, []).
 
 date_time_range_type(Config) ->
     epgsql_ct:with_min_version(Config, [9, 2], fun(_C) ->
         check_type(Config, tsrange, "tsrange('2008-01-02 03:04:05', '2008-02-02 03:04:05')", {{{2008,1,2},{3,4,5.0}}, {{2008,2,2},{3,4,5.0}}}, []),
-       check_type(Config, tsrange, "tsrange('2008-01-02 03:04:05', '2008-01-02 03:04:05')", empty, []),
-
-       check_type(Config, daterange, "daterange('2008-01-02', '2008-02-02')", {{2008,1,2}, {2008, 2, 2}}, [{{-4712,1,1}, {5874897,1,1}}
-]),
-      check_type(Config, tstzrange, "tstzrange('2011-01-02 03:04:05+3', '2011-01-02 04:04:05+3')", {{{2011, 1, 2}, {0, 4, 5.0}}, {{2011, 1, 2}, {1, 4, 5.0}}}, [{{{2011, 1, 2}, {0, 4, 5.0}}, {{2011, 1, 2}, {1, 4, 5.0}}}])
+        check_type(Config, tsrange, "tsrange('2008-01-02 03:04:05', '2008-02-02 03:04:05', '[]')", {{{2008,1,2},{3,4,5.0}}, {{2008,2,2},{3,4,5.0}}}, []),
+        check_type(Config, tsrange, "tsrange('2008-01-02 03:04:05', '2008-02-02 03:04:05', '()')", {{{2008,1,2},{3,4,5.0}}, {{2008,2,2},{3,4,5.0}}}, []),
+        check_type(Config, tsrange, "tsrange('2008-01-02 03:04:05', '2008-02-02 03:04:05', '[)')", {{{2008,1,2},{3,4,5.0}}, {{2008,2,2},{3,4,5.0}}}, []),
+        check_type(Config, tsrange, "tsrange('2008-01-02 03:04:05', '2008-02-02 03:04:05', '(]')", {{{2008,1,2},{3,4,5.0}}, {{2008,2,2},{3,4,5.0}}}, []),
+        check_type(Config, tsrange, "tsrange('2008-01-02 03:04:05', '2008-01-02 03:04:05')", empty, []),
+        check_type(Config, daterange, "daterange('2008-01-02', '2008-02-02')", {{2008,1,2}, {2008, 2, 2}}, [{{-4712,1,1}, {5874897,1,1}}]),
+        check_type(Config, tstzrange, "tstzrange('2011-01-02 03:04:05+3', '2011-01-02 04:04:05+3')", {{{2011, 1, 2}, {0, 4, 5.0}}, {{2011, 1, 2}, {1, 4, 5.0}}}, [{{{2011, 1, 2}, {0, 4, 5.0}}, {{2011, 1, 2}, {1, 4, 5.0}}}]),
+        check_type(Config, tstzrange, "tstzrange('2008-01-02 03:04:05', null)", {{{2008,1,2},{3,4,5.0}}, plus_infinity}, []),
+        check_type(Config, tstzrange, "tstzrange('2008-01-02 03:04:05', null, '[]')", {{{2008,1,2},{3,4,5.0}}, plus_infinity}, []),
+        check_type(Config, tstzrange, "tstzrange('2008-01-02 03:04:05', null, '()')", {{{2008,1,2},{3,4,5.0}}, plus_infinity}, []),
+        check_type(Config, tstzrange, "tstzrange(null, '2008-01-02 03:04:05')", {minus_infinity, {{2008,1,2},{3,4,5.0}}}, []),
+        check_type(Config, tstzrange, "tstzrange(null, '2008-01-02 03:04:05', '[]')", {minus_infinity, {{2008,1,2},{3,4,5.0}}}, []),
+        check_type(Config, tstzrange, "tstzrange(null, '2008-01-02 03:04:05', '()')", {minus_infinity, {{2008,1,2},{3,4,5.0}}}, [])
 
    end, []).