Exemple #1
0
def test_mixed_array_types(conn, fmt_out):
    conn.execute("create table testmix (a daterange[], b tstzrange[])")
    r1 = Range(dt.date(2000, 1, 1), dt.date(2001, 1, 1), "[)")
    r2 = Range(
        dt.datetime(2000, 1, 1, tzinfo=dt.timezone.utc),
        dt.datetime(2001, 1, 1, tzinfo=dt.timezone.utc),
        "[)",
    )
    conn.execute("insert into testmix values (%s, %s)", [[r1], [r2]])
    got = conn.execute("select * from testmix").fetchone()
    assert got == ([r1], [r2])
Exemple #2
0
def test_copy_in_empty_set_type(conn, bounds, pgtype, format):
    cur = conn.cursor()
    cur.execute(f"create table copyrange (id serial primary key, r {pgtype})")

    r = Range(empty=True) if bounds == "empty" else Range(None, None, bounds)

    with cur.copy(
        f"copy copyrange (r) from stdin (format {format.name})"
    ) as copy:
        copy.set_types([pgtype])
        copy.write_row([r])

    rec = cur.execute("select r from copyrange order by id").fetchone()
    assert rec[0] == r
Exemple #3
0
def test_dump_custom_empty(conn, testrange):
    info = RangeInfo.fetch(conn, "testrange")
    register_range(info, conn)

    r = Range(empty=True)
    cur = conn.execute("select 'empty'::testrange = %s", (r,))
    assert cur.fetchone()[0] is True
Exemple #4
0
def test_dump_builtin_array_wrapper(conn, wrapper, fmt_in):
    wrapper = getattr(multirange, wrapper)
    mr1 = Multirange()  # type: ignore[var-annotated]
    mr2 = Multirange([Range(bounds="()")])  # type: ignore[var-annotated]
    cur = conn.execute(f"""select '{{"{{}}","{{(,)}}"}}' = %{fmt_in}""",
                       ([mr1, mr2], ))
    assert cur.fetchone()[0] is True
Exemple #5
0
def test_copy_in(conn, min, max, bounds, format):
    cur = conn.cursor()
    cur.execute(
        "create table copymr (id serial primary key, mr datemultirange)")

    if bounds != "empty":
        min = dt.date(*map(int, min.split(","))) if min else None
        max = dt.date(*map(int, max.split(","))) if max else None
        r = Range[dt.date](min, max, bounds)
    else:
        r = Range(empty=True)

    mr = Multirange([r])
    try:
        with cur.copy(
                f"copy copymr (mr) from stdin (format {format.name})") as copy:
            copy.write_row([mr])
    except e.InternalError_:
        if not min and not max and format == pq.Format.BINARY:
            pytest.xfail(
                "TODO: add annotation to dump multirange with no type info")
        else:
            raise

    rec = cur.execute("select mr from copymr order by id").fetchone()
    if not r.isempty:
        assert rec[0] == mr
    else:
        assert rec[0] == Multirange()
Exemple #6
0
def test_load_builtin_array(conn, pgtype, fmt_out):
    mr1 = Multirange()  # type: ignore[var-annotated]
    mr2 = Multirange([Range(bounds="()")])  # type: ignore[var-annotated]
    cur = conn.cursor(binary=fmt_out)
    (got, ) = cur.execute(
        f"select array['{{}}'::{pgtype}, '{{(,)}}'::{pgtype}]").fetchone()
    assert got == [mr1, mr2]
Exemple #7
0
    def test_exclude_inf_bounds(self):
        r = Range(None, 10, "[]")
        assert r.lower is None
        assert not r.lower_inc
        assert r.bounds == "(]"

        r = Range(10, None, "[]")
        assert r.upper is None
        assert not r.upper_inc
        assert r.bounds == "[)"

        r = Range(None, None, "[]")
        assert r.lower is None
        assert not r.lower_inc
        assert r.upper is None
        assert not r.upper_inc
        assert r.bounds == "()"
Exemple #8
0
def test_dump_builtin_array(conn, pgtype, fmt_in):
    mr1 = Multirange()  # type: ignore[var-annotated]
    mr2 = Multirange([Range(bounds="()")])  # type: ignore[var-annotated]
    cur = conn.execute(
        f"select array['{{}}'::{pgtype}, '{{(,)}}'::{pgtype}] = %{fmt_in}",
        ([mr1, mr2], ),
    )
    assert cur.fetchone()[0] is True
Exemple #9
0
def test_load_builtin_empty(conn, pgtype, fmt_out):
    r = Range(empty=True)  # type: ignore[var-annotated]
    cur = conn.cursor(binary=fmt_out)
    (got, ) = cur.execute(f"select 'empty'::{pgtype}").fetchone()
    assert type(got) is Range
    assert got == r
    assert not got
    assert got.isempty
Exemple #10
0
def test_dump_builtin_range(conn, pgtype, min, max, bounds, fmt_in):
    r = Range(min, max, bounds)  # type: ignore[var-annotated]
    sub = type2sub[pgtype]
    cur = conn.execute(
        f"select {pgtype}(%s::{sub}, %s::{sub}, %s) = %{fmt_in}",
        (min, max, bounds, r),
    )
    assert cur.fetchone()[0] is True
Exemple #11
0
    def test_in(self):
        r = Range(empty=True)
        assert 10 not in r

        r = Range()
        assert 10 in r

        r = Range(lower=10, bounds="[)")
        assert 9 not in r
        assert 10 in r
        assert 11 in r

        r = Range(lower=10, bounds="()")
        assert 9 not in r
        assert 10 not in r
        assert 11 in r

        r = Range(upper=20, bounds="()")
        assert 19 in r
        assert 20 not in r
        assert 21 not in r

        r = Range(upper=20, bounds="(]")
        assert 19 in r
        assert 20 in r
        assert 21 not in r

        r = Range(10, 20)
        assert 9 not in r
        assert 10 in r
        assert 11 in r
        assert 19 in r
        assert 20 not in r
        assert 21 not in r

        r = Range(10, 20, "(]")
        assert 9 not in r
        assert 10 not in r
        assert 11 in r
        assert 19 in r
        assert 20 in r
        assert 21 not in r

        r = Range(20, 10)
        assert 9 not in r
        assert 10 not in r
        assert 11 not in r
        assert 19 not in r
        assert 20 not in r
        assert 21 not in r
Exemple #12
0
 def test_nobounds(self):
     r = Range(10, 20)
     assert r.lower == 10
     assert r.upper == 20
     assert not r.isempty
     assert not r.lower_inf
     assert not r.upper_inf
     assert r.lower_inc
     assert not r.upper_inc
Exemple #13
0
    def test_keywords(self):
        r = Range(upper=20)
        r.lower is None
        r.upper == 20
        assert not r.isempty
        assert r.lower_inf
        assert not r.upper_inf
        assert not r.lower_inc
        assert not r.upper_inc

        r = Range(lower=10, bounds="(]")
        r.lower == 10
        r.upper is None
        assert not r.isempty
        assert not r.lower_inf
        assert r.upper_inf
        assert not r.lower_inc
        assert not r.upper_inc
Exemple #14
0
    def test_empty(self):
        r = Range(empty=True)

        assert r.isempty
        assert r.lower is None
        assert r.upper is None
        assert not r.lower_inf
        assert not r.upper_inf
        assert not r.lower_inc
        assert not r.upper_inc
Exemple #15
0
    def test_noparam(self):
        r = Range()

        assert not r.isempty
        assert r.lower is None
        assert r.upper is None
        assert r.lower_inf
        assert r.upper_inf
        assert not r.lower_inc
        assert not r.upper_inc
Exemple #16
0
def test_load_builtin_inf(conn, pgtype, fmt_out):
    r = Range(bounds="()")  # type: ignore[var-annotated]
    cur = conn.cursor(binary=fmt_out)
    (got, ) = cur.execute(f"select '(,)'::{pgtype}").fetchone()
    assert type(got) is Range
    assert got == r
    assert got
    assert not got.isempty
    assert got.lower_inf
    assert got.upper_inf
Exemple #17
0
    def test_noparam(self):
        r = Range()  # type: ignore[var-annotated]

        assert not r.isempty
        assert r.lower is None
        assert r.upper is None
        assert r.lower_inf
        assert r.upper_inf
        assert not r.lower_inc
        assert not r.upper_inc
Exemple #18
0
    def test_empty(self):
        r = Range(empty=True)  # type: ignore[var-annotated]

        assert r.isempty
        assert r.lower is None
        assert r.upper is None
        assert not r.lower_inf
        assert not r.upper_inf
        assert not r.lower_inc
        assert not r.upper_inc
Exemple #19
0
    def test_str(self):
        """
        Range types should have a short and readable ``str`` implementation.
        """
        expected = [
            "(0, 4)",
            "[0, 4]",
            "(0, 4]",
            "[0, 4)",
            "empty",
        ]
        results = []

        for bounds in ("()", "[]", "(]", "[)"):
            r = Range(0, 4, bounds=bounds)
            results.append(str(r))

        r = Range(empty=True)
        results.append(str(r))
        assert results == expected
Exemple #20
0
def test_load_builtin_range(conn, pgtype, min, max, bounds, fmt_out):
    r = Range(min, max, bounds)  # type: ignore[var-annotated]
    sub = type2sub[pgtype]
    cur = conn.cursor(binary=fmt_out)
    cur.execute(f"select {pgtype}(%s::{sub}, %s::{sub}, %s)",
                (min, max, bounds))
    # normalise discrete ranges
    if r.upper_inc and isinstance(r.upper, int):
        bounds = "[)" if r.lower_inc else "()"
        r = type(r)(r.lower, r.upper + 1, bounds)
    assert cur.fetchone()[0] == r
Exemple #21
0
    def test_bad_type(self):
        with pytest.raises(TypeError):
            Multirange(Range(10, 20))  # type: ignore[arg-type]

        with pytest.raises(TypeError):
            Multirange([10])  # type: ignore[arg-type]

        mr = Multirange([Range(10, 20), Range(30, 40), Range(50, 60)])

        with pytest.raises(TypeError):
            mr[0] = "foo"  # type: ignore[call-overload]

        with pytest.raises(TypeError):
            mr[0:1] = "foo"  # type: ignore[assignment]

        with pytest.raises(TypeError):
            mr[0:1] = ["foo"]  # type: ignore[list-item]

        with pytest.raises(TypeError):
            mr.insert(0, "foo")  # type: ignore[arg-type]
Exemple #22
0
    def test_in(self):
        r = Range[int](empty=True)
        assert 10 not in r
        assert "x" not in r  # type: ignore[operator]

        r = Range()
        assert 10 in r

        r = Range(lower=10, bounds="[)")
        assert 9 not in r
        assert 10 in r
        assert 11 in r

        r = Range(lower=10, bounds="()")
        assert 9 not in r
        assert 10 not in r
        assert 11 in r

        r = Range(upper=20, bounds="()")
        assert 19 in r
        assert 20 not in r
        assert 21 not in r

        r = Range(upper=20, bounds="(]")
        assert 19 in r
        assert 20 in r
        assert 21 not in r

        r = Range(10, 20)
        assert 9 not in r
        assert 10 in r
        assert 11 in r
        assert 19 in r
        assert 20 not in r
        assert 21 not in r

        r = Range(10, 20, "(]")
        assert 9 not in r
        assert 10 not in r
        assert 11 in r
        assert 19 in r
        assert 20 in r
        assert 21 not in r

        r = Range(20, 10)
        assert 9 not in r
        assert 10 not in r
        assert 11 not in r
        assert 19 not in r
        assert 20 not in r
        assert 21 not in r
Exemple #23
0
        def to_range(value):
            if isinstance(value, (str, NoneType)):
                return value

            return Multirange([
                Range(
                    element.lower,
                    element.upper,
                    element.bounds,
                    element.empty,
                ) for element in cast("Iterable[ranges.Range]", value)
            ])
Exemple #24
0
    def test_delitem(self):
        mr = Multirange([Range(10, 20), Range(30, 40), Range(50, 60)])
        del mr[1]
        assert mr == Multirange([Range(10, 20), Range(50, 60)])

        del mr[-2]
        assert mr == Multirange([Range(50, 60)])
Exemple #25
0
def test_dump_builtin_empty_range(conn, fmt_in):
    conn.execute("""
        drop type if exists tmptype;
        create type tmptype as (num integer, range daterange, nums integer[])
        """)
    info = CompositeInfo.fetch(conn, "tmptype")
    register_composite(info, conn)

    cur = conn.execute(
        f"select pg_typeof(%{fmt_in})",
        [info.python_type(10, Range(empty=True), [])],
    )
    assert cur.fetchone()[0] == "tmptype"
Exemple #26
0
 def test_str_datetime(self):
     """
     Date-Time ranges should return a human-readable string as well on
     string conversion.
     """
     tz = dt.timezone(dt.timedelta(hours=-5))
     r = Range(
         dt.datetime(2010, 1, 1, tzinfo=tz),
         dt.datetime(2011, 1, 1, tzinfo=tz),
     )
     expected = "[2010-01-01 00:00:00-05:00, 2011-01-01 00:00:00-05:00)"
     result = str(r)
     assert result == expected
Exemple #27
0
def test_dump_quoting(conn, testrange):
    info = RangeInfo.fetch(conn, "testrange")
    register_range(info, conn)
    cur = conn.cursor()
    for i in range(1, 254):
        cur.execute(
            """
            select ascii(lower(%(r)s)) = %(low)s
                and ascii(upper(%(r)s)) = %(up)s
            """,
            {"r": Range(chr(i), chr(i + 1)), "low": i, "up": i + 1},
        )
        assert cur.fetchone()[0] is True
Exemple #28
0
def test_copy_in_empty(conn, min, max, bounds, format):
    cur = conn.cursor()
    cur.execute("create table copyrange (id serial primary key, r daterange)")

    if bounds != "empty":
        min = dt.date(*map(int, min.split(","))) if min else None
        max = dt.date(*map(int, max.split(","))) if max else None
        r = Range(min, max, bounds)
    else:
        r = Range(empty=True)

    try:
        with cur.copy(f"copy copyrange (r) from stdin (format {format.name})"
                      ) as copy:
            copy.write_row([r])
    except psycopg.errors.ProtocolViolation:
        if not min and not max and format == pq.Format.BINARY:
            pytest.xfail(
                "TODO: add annotation to dump array with no type info")
        else:
            raise

    rec = cur.execute("select r from copyrange order by id").fetchone()
    assert rec[0] == r
Exemple #29
0
 def test_bounds(self):
     for bounds, lower_inc, upper_inc in [
         ("[)", True, False),
         ("(]", False, True),
         ("()", False, False),
         ("[]", True, True),
     ]:
         r = Range(10, 20, bounds)
         assert r.bounds == bounds
         assert r.lower == 10
         assert r.upper == 20
         assert not r.isempty
         assert not r.lower_inf
         assert not r.upper_inf
         assert r.lower_inc == lower_inc
         assert r.upper_inc == upper_inc
Exemple #30
0
 def test_relations(self):
     mr1 = Multirange([Range(10, 20), Range(30, 40)])
     mr2 = Multirange([Range(11, 20), Range(30, 40)])
     mr3 = Multirange([Range(9, 20), Range(30, 40)])
     assert mr1 <= mr1
     assert not mr1 < mr1
     assert mr1 >= mr1
     assert not mr1 > mr1
     assert mr1 < mr2
     assert mr1 <= mr2
     assert mr1 > mr3
     assert mr1 >= mr3
     assert mr1 != mr2
     assert not mr1 == mr2