Repository: duckdb/duckdb
File: tools/pythonpkg/tests/fast/pandas/test_df_object_resolution.py (Python)

Code before:
        converted_col = duckdb.query_df(x, "x", "select * from x").df()
        float64 = np.dtype('float64')
        assert isinstance(converted_col['0'].dtype, float64.__class__) == True

    def test_double_object_conversion(self, duckdb_cursor):
        data = [18446744073709551616, 0]
        x = pd.DataFrame({'0': pd.Series(data=data, dtype='object')})
        converted_col = duckdb.query_df(x, "x", "select * from x").df()
        double_dtype = np.dtype('float64')
        assert isinstance(converted_col['0'].dtype, double_dtype.__class__) == True

    def test_integer_conversion_fail(self, duckdb_cursor):
        data = [2**10000, 0]
        x = pd.DataFrame({'0': pd.Series(data=data, dtype='object')})
        converted_col = duckdb.query_df(x, "x", "select * from x").df()
        print(converted_col['0'])
        double_dtype = np.dtype('object')
        assert isinstance(converted_col['0'].dtype, double_dtype.__class__) == True

    # numpy.datetime64 is just a wrapper around a datetime.datetime object, because reasons..
    def test_numpy_datetime(self):
        numpy = pytest.importorskip("numpy")

        standard_vector_size = 2048
        data = []
        data += [numpy.datetime64('2022-12-10T21:38:24.578696') for x in range(standard_vector_size)]
        data += [numpy.datetime64('2022-02-21T06:59:23.324812') for x in range(standard_vector_size)]
        data += [numpy.datetime64('1974-06-05T13:12:01.000000') for x in range(standard_vector_size)]
        data += [numpy.datetime64('2049-01-13T00:24:31.999999') for x in range(standard_vector_size)]
        #print(numpy.datetime64('2021-11-01T21:01:38').tolist().__class__)
        x = pd.DataFrame({'dates': pd.Series(data=data, dtype='object')})
        res = duckdb.query_df(x, "x", "select distinct * from x").df()
        assert(len(res['dates'].__array__()) == 4)

    def test_fallthrough_object_conversion(self, duckdb_cursor):
        x = pd.DataFrame(
            [
                [IntString(4)],
                [IntString(2)],
                [IntString(0)],
            ]
        )
        duckdb_col = duckdb.query_df(x, "x", "select * from x").df()
        df_expected_res = pd.DataFrame({'0': pd.Series(['4','2','0'])})
        pd.testing.assert_frame_equal(duckdb_col, df_expected_res)

    def test_numeric_decimal(self):
        duckdb_conn = duckdb.connect()

        # DuckDB uses DECIMAL where possible, so all the 'float' types here are actually DECIMAL
        reference_query = """

Review comment (suggestion):
```suggestion
        data += [numpy.datetime64('2022-12-10T21:38:24.578696')] * standard_vector_size
```
Small nitpick, can be applied to the other sites as well :)


Code after:
        # So this instead becomes a DOUBLE
        data = [18446744073709551615, 0]
        x = pd.DataFrame({'0': pd.Series(data=data, dtype='object')})
        converted_col = duckdb.query_df(x, "x", "select * from x").df()
        float64 = np.dtype('float64')
        assert isinstance(converted_col['0'].dtype, float64.__class__) == True

    def test_double_object_conversion(self):
        data = [18446744073709551616, 0]
        x = pd.DataFrame({'0': pd.Series(data=data, dtype='object')})
        converted_col = duckdb.query_df(x, "x", "select * from x").df()
        double_dtype = np.dtype('float64')
        assert isinstance(converted_col['0'].dtype, double_dtype.__class__) == True

    def test_integer_conversion_fail(self):
        data = [2**10000, 0]
        x = pd.DataFrame({'0': pd.Series(data=data, dtype='object')})
        converted_col = duckdb.query_df(x, "x", "select * from x").df()
        print(converted_col['0'])
        double_dtype = np.dtype('object')
        assert isinstance(converted_col['0'].dtype, double_dtype.__class__) == True

    # Most of the time numpy.datetime64 is just a wrapper around a datetime.datetime object
    # But to support arbitrary precision, it can fall back to using an `int` internally
    # Which we don't support yet
    def test_numpy_datetime(self):
        numpy = pytest.importorskip("numpy")

        data = []
        data += [numpy.datetime64('2022-12-10T21:38:24.578696')] * standard_vector_size
        data += [numpy.datetime64('2022-02-21T06:59:23.324812')] * standard_vector_size
        data += [numpy.datetime64('1974-06-05T13:12:01.000000')] * standard_vector_size
        data += [numpy.datetime64('2049-01-13T00:24:31.999999')] * standard_vector_size
        x = pd.DataFrame({'dates': pd.Series(data=data, dtype='object')})
        res = duckdb.query_df(x, "x", "select distinct * from x").df()
        assert(len(res['dates'].__array__()) == 4)

    def test_numpy_datetime_int_internally(self):
        numpy = pytest.importorskip("numpy")

        data = [numpy.datetime64('2022-12-10T21:38:24.0000000000001')]
        x = pd.DataFrame({'dates': pd.Series(data=data, dtype='object')})
        with pytest.raises(duckdb.ConversionException, match=re.escape("Conversion Error: Unimplemented type for cast (BIGINT -> TIMESTAMP)")):
            rel = duckdb.query_df(x, "x", "create table dates as select dates::TIMESTAMP WITHOUT TIME ZONE from x")

    def test_fallthrough_object_conversion(self):
        x = pd.DataFrame(
            [
                [IntString(4)],
                [IntString(2)],
                [IntString(0)],