diff --git a/.github/renovate.json b/.github/renovate.json index 6fbdba5150373..9f1d4036dfeab 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -89,7 +89,7 @@ }, { "addLabels": ["risingwave"], - "matchPackageNames": ["/psycopg2/", "/risingwave/"] + "matchPackageNames": ["/psycopg/", "/risingwave/"] }, { "addLabels": ["snowflake"], diff --git a/ibis/backends/postgres/__init__.py b/ibis/backends/postgres/__init__.py index e4e89d9faeba8..b80db746de18d 100644 --- a/ibis/backends/postgres/__init__.py +++ b/ibis/backends/postgres/__init__.py @@ -713,11 +713,11 @@ def raw_sql(self, query: str | sg.Expression, **kwargs: Any) -> Any: try: # try to load hstore - with contextlib.suppress(TypeError): - type_info = psycopg.types.TypeInfo.fetch(con, "hstore") - with contextlib.suppress(psycopg.ProgrammingError, TypeError): - psycopg.types.hstore.register_hstore(type_info, cursor) - except Exception: + psycopg.types.hstore.register_hstore( + psycopg.types.TypeInfo.fetch(con, "hstore"), + cursor, + ) + except (psycopg.InternalError, psycopg.ProgrammingError): cursor.close() raise diff --git a/ibis/backends/risingwave/__init__.py b/ibis/backends/risingwave/__init__.py index fd3400fb79a17..0020f154f9a59 100644 --- a/ibis/backends/risingwave/__init__.py +++ b/ibis/backends/risingwave/__init__.py @@ -5,10 +5,9 @@ from operator import itemgetter from typing import TYPE_CHECKING -import psycopg2 +import psycopg import sqlglot as sg import sqlglot.expressions as sge -from psycopg2 import extras import ibis import ibis.backends.sql.compilers as sc @@ -110,12 +109,12 @@ def do_connect( month int32 """ - self.con = psycopg2.connect( + self.con = psycopg.connect( host=host, port=port, user=user, password=password, - database=database, + dbname=database, options=(f"-csearch_path={schema}" * (schema is not None)) or None, ) @@ -289,7 +288,7 @@ def _register_in_memory_table(self, op: ops.InMemoryTable) -> None: ) with self.begin() as cur: cur.execute(create_stmt_sql) - extras.execute_batch(cur, sql, data, 128) + cur.executemany(sql, data) def list_databases( self, *, like: str | None = None, catalog: str | None = None diff --git a/ibis/backends/risingwave/tests/conftest.py b/ibis/backends/risingwave/tests/conftest.py index 06940a6573b6f..2832cddedab22 100644 --- a/ibis/backends/risingwave/tests/conftest.py +++ b/ibis/backends/risingwave/tests/conftest.py @@ -33,7 +33,7 @@ class TestConf(ServiceBackendTest): supports_structs = False rounding_method = "half_to_even" service_name = "risingwave" - deps = ("psycopg2",) + deps = ("psycopg",) @property def test_files(self) -> Iterable[Path]: diff --git a/ibis/backends/risingwave/tests/test_client.py b/ibis/backends/risingwave/tests/test_client.py index 1d2ce761242d1..c0533a768e172 100644 --- a/ibis/backends/risingwave/tests/test_client.py +++ b/ibis/backends/risingwave/tests/test_client.py @@ -12,7 +12,7 @@ import ibis.expr.types as ir from ibis.util import gen_name -pytest.importorskip("psycopg2") +pytest.importorskip("psycopg") RISINGWAVE_TEST_DB = os.environ.get("IBIS_TEST_RISINGWAVE_DATABASE", "dev") IBIS_RISINGWAVE_HOST = os.environ.get("IBIS_TEST_RISINGWAVE_HOST", "localhost") diff --git a/ibis/backends/risingwave/tests/test_functions.py b/ibis/backends/risingwave/tests/test_functions.py index 38be06b1281d8..dafbd315d98dc 100644 --- a/ibis/backends/risingwave/tests/test_functions.py +++ b/ibis/backends/risingwave/tests/test_functions.py @@ -14,7 +14,7 @@ import ibis.expr.datatypes as dt from ibis import literal as L -pytest.importorskip("psycopg2") +pytest.importorskip("psycopg") @pytest.mark.parametrize(("value", "expected"), [(0, None), (5.5, 5.5)]) diff --git a/ibis/backends/tests/errors.py b/ibis/backends/tests/errors.py index 53e25e90f1704..5824deec489f6 100644 --- a/ibis/backends/tests/errors.py +++ b/ibis/backends/tests/errors.py @@ -131,25 +131,6 @@ PsycoPgOperationalError ) = PsycoPgUndefinedObject = PsycoPgArraySubscriptError = None -try: - from psycopg2.errors import ArraySubscriptError as PsycoPg2ArraySubscriptError - from psycopg2.errors import DivisionByZero as PsycoPg2DivisionByZero - from psycopg2.errors import IndeterminateDatatype as PsycoPg2IndeterminateDatatype - from psycopg2.errors import InternalError_ as PsycoPg2InternalError - from psycopg2.errors import ( - InvalidTextRepresentation as PsycoPg2InvalidTextRepresentation, - ) - from psycopg2.errors import OperationalError as PsycoPg2OperationalError - from psycopg2.errors import ProgrammingError as PsycoPg2ProgrammingError - from psycopg2.errors import SyntaxError as PsycoPg2SyntaxError - from psycopg2.errors import UndefinedObject as PsycoPg2UndefinedObject -except ImportError: - PsycoPg2SyntaxError = PsycoPg2IndeterminateDatatype = ( - PsycoPg2InvalidTextRepresentation - ) = PsycoPg2DivisionByZero = PsycoPg2InternalError = PsycoPg2ProgrammingError = ( - PsycoPg2OperationalError - ) = PsycoPg2UndefinedObject = PsycoPg2ArraySubscriptError = None - try: from MySQLdb import NotSupportedError as MySQLNotSupportedError from MySQLdb import OperationalError as MySQLOperationalError diff --git a/ibis/backends/tests/test_aggregation.py b/ibis/backends/tests/test_aggregation.py index 05babb55115c3..b1d6e499c6a4b 100644 --- a/ibis/backends/tests/test_aggregation.py +++ b/ibis/backends/tests/test_aggregation.py @@ -21,7 +21,7 @@ MySQLNotSupportedError, OracleDatabaseError, PolarsInvalidOperationError, - PsycoPg2InternalError, + PsycoPgInternalError, Py4JError, Py4JJavaError, PyAthenaOperationalError, @@ -963,7 +963,7 @@ def test_approx_quantile(con, filtered, multi): ), pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="function covar_pop(integer, integer) does not exist", ), ], @@ -983,7 +983,7 @@ def test_approx_quantile(con, filtered, multi): ), pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="function covar_pop(integer, integer) does not exist", ), ], @@ -1005,7 +1005,7 @@ def test_approx_quantile(con, filtered, multi): ), pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="function covar_pop(integer, integer) does not exist", ), ], @@ -1062,7 +1062,7 @@ def test_approx_quantile(con, filtered, multi): ), pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="function covar_pop(integer, integer) does not exist", ), ], @@ -1088,7 +1088,7 @@ def test_approx_quantile(con, filtered, multi): ), pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="function covar_pop(integer, integer) does not exist", ), ], diff --git a/ibis/backends/tests/test_array.py b/ibis/backends/tests/test_array.py index d47f2d7e085af..070f885d2219c 100644 --- a/ibis/backends/tests/test_array.py +++ b/ibis/backends/tests/test_array.py @@ -22,12 +22,10 @@ GoogleBadRequest, MySQLOperationalError, PolarsComputeError, - PsycoPg2IndeterminateDatatype, - PsycoPg2InternalError, - PsycoPg2ProgrammingError, PsycoPgIndeterminateDatatype, PsycoPgInternalError, PsycoPgInvalidTextRepresentation, + PsycoPgProgrammingError, PsycoPgSyntaxError, Py4JJavaError, PyAthenaDatabaseError, @@ -506,7 +504,7 @@ def test_array_slice(backend, start, stop): ) @pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="TODO(Kexiang): seems a bug", ) @pytest.mark.notimpl(["athena"], raises=PyAthenaDatabaseError) @@ -565,7 +563,7 @@ def test_array_map(con, input, output, func): ) @pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="TODO(Kexiang): seems a bug", ) @pytest.mark.notimpl(["athena"], raises=PyAthenaDatabaseError) @@ -646,7 +644,7 @@ def test_array_map_with_index(con, input, output, func): ) @pytest.mark.notyet( "risingwave", - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="no support for not null column constraint", ) @pytest.mark.parametrize( @@ -693,7 +691,7 @@ def test_array_filter(con, input, output, predicate): ) @pytest.mark.notyet( "risingwave", - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="no support for not null column constraint", ) @pytest.mark.parametrize( @@ -740,7 +738,7 @@ def test_array_filter_with_index(con, input, output, predicate): ) @pytest.mark.notyet( "risingwave", - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="no support for not null column constraint", ) @pytest.mark.parametrize( @@ -1097,7 +1095,7 @@ def test_array_intersect(con, data): @builtin_array @pytest.mark.notimpl(["postgres"], raises=PsycoPgSyntaxError) -@pytest.mark.notimpl(["risingwave"], raises=PsycoPg2InternalError) +@pytest.mark.notimpl(["risingwave"], raises=PsycoPgInternalError) @pytest.mark.notimpl( ["trino"], reason="inserting maps into structs doesn't work", raises=TrinoUserError ) @@ -1117,7 +1115,7 @@ def test_unnest_struct(con): @builtin_array @pytest.mark.notimpl(["postgres"], raises=PsycoPgSyntaxError) -@pytest.mark.notimpl(["risingwave"], raises=PsycoPg2InternalError) +@pytest.mark.notimpl(["risingwave"], raises=PsycoPgInternalError) @pytest.mark.notimpl( ["trino"], reason="inserting maps into structs doesn't work", raises=TrinoUserError ) @@ -1208,7 +1206,7 @@ def test_zip_null(con, fn): @builtin_array @pytest.mark.notimpl(["postgres"], raises=PsycoPgSyntaxError) -@pytest.mark.notimpl(["risingwave"], raises=PsycoPg2ProgrammingError) +@pytest.mark.notimpl(["risingwave"], raises=PsycoPgProgrammingError) @pytest.mark.notimpl(["datafusion"], raises=Exception, reason="not yet supported") @pytest.mark.notimpl( ["polars"], @@ -1291,8 +1289,8 @@ def flatten_data(): reason="Risingwave doesn't truly support arrays of arrays", raises=( com.OperationNotDefinedError, - PsycoPg2IndeterminateDatatype, - PsycoPg2InternalError, + PsycoPgIndeterminateDatatype, + PsycoPgInternalError, ), ) @pytest.mark.parametrize( @@ -1399,7 +1397,7 @@ def test_range_start_stop_step(con, start, stop, step): @pytest.mark.notimpl(["flink"], raises=com.OperationNotDefinedError) @pytest.mark.never( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="Invalid parameter step: step size cannot equal zero", ) def test_range_start_stop_step_zero(con, start, stop): @@ -1432,7 +1430,7 @@ def test_unnest_empty_array(con): @pytest.mark.notimpl(["sqlite"], raises=com.UnsupportedBackendType) @pytest.mark.notyet( "risingwave", - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="no support for not null column constraint", ) @pytest.mark.notimpl(["athena"], raises=PyAthenaDatabaseError) @@ -1515,7 +1513,7 @@ def swap(token): id="pos", marks=pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="function make_interval() does not exist", ), ), @@ -1533,7 +1531,7 @@ def swap(token): ), pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="function neg(interval) does not exist", ), ], @@ -1553,7 +1551,7 @@ def swap(token): ), pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="function neg(interval) does not exist", ), ], @@ -1585,7 +1583,7 @@ def test_timestamp_range(con, start, stop, step, freq, tzinfo): pytest.mark.notyet(["polars"], raises=PolarsComputeError), pytest.mark.notyet( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="function make_interval() does not exist", ), ], @@ -1604,7 +1602,7 @@ def test_timestamp_range(con, start, stop, step, freq, tzinfo): ), pytest.mark.notyet( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="function neg(interval) does not exist", ), ], @@ -1760,7 +1758,7 @@ def test_table_unnest_with_keep_empty(con): ["datafusion", "polars", "flink"], raises=com.OperationNotDefinedError ) @pytest.mark.notyet( - ["risingwave"], raises=PsycoPg2InternalError, reason="not supported in risingwave" + ["risingwave"], raises=PsycoPgInternalError, reason="not supported in risingwave" ) @pytest.mark.notimpl( ["athena"], @@ -1781,9 +1779,9 @@ def test_table_unnest_column_expr(backend): @pytest.mark.notimpl(["trino"], raises=TrinoUserError) @pytest.mark.notimpl(["athena"], raises=PyAthenaOperationalError) @pytest.mark.notimpl(["postgres"], raises=PsycoPgSyntaxError) -@pytest.mark.notimpl(["risingwave"], raises=PsycoPg2ProgrammingError) +@pytest.mark.notimpl(["risingwave"], raises=PsycoPgProgrammingError) @pytest.mark.notyet( - ["risingwave"], raises=PsycoPg2InternalError, reason="not supported in risingwave" + ["risingwave"], raises=PsycoPgInternalError, reason="not supported in risingwave" ) def test_table_unnest_array_of_struct_of_array(con): t = ibis.memtable( diff --git a/ibis/backends/tests/test_client.py b/ibis/backends/tests/test_client.py index 10c87bcd592ad..ac89c02aaf9df 100644 --- a/ibis/backends/tests/test_client.py +++ b/ibis/backends/tests/test_client.py @@ -31,7 +31,7 @@ ExaQueryError, ImpalaHiveServer2Error, OracleDatabaseError, - PsycoPg2InternalError, + PsycoPgInternalError, PsycoPgUndefinedObject, Py4JJavaError, PyAthenaDatabaseError, @@ -415,7 +415,7 @@ def test_rename_table(con, temp_table, temp_table_orig): ) @pytest.mark.never( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason='Feature is not yet implemented: column constraints "NOT NULL"', ) def test_nullable_input_output(con, temp_table): @@ -538,7 +538,7 @@ def test_insert_no_overwrite_from_dataframe( @pytest.mark.notimpl(["polars"], reason="`insert` method not implemented") @pytest.mark.notyet( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="truncate not supported upstream", ) @pytest.mark.notyet( @@ -584,7 +584,7 @@ def test_insert_no_overwrite_from_expr( ) @pytest.mark.notyet( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="truncate not supported upstream", ) def test_insert_overwrite_from_expr( @@ -608,7 +608,7 @@ def test_insert_overwrite_from_expr( ) @pytest.mark.notyet( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="truncate not supported upstream", ) def test_insert_overwrite_from_list(con, employee_data_1_temp_table): @@ -737,7 +737,7 @@ def test_list_database_contents(con): @pytest.mark.notyet(["impala"], raises=ImpalaHiveServer2Error) @pytest.mark.notyet( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="unsigned integers are not supported", ) @pytest.mark.notimpl( diff --git a/ibis/backends/tests/test_generic.py b/ibis/backends/tests/test_generic.py index 267a0bc0e5edc..7df01e99db66a 100644 --- a/ibis/backends/tests/test_generic.py +++ b/ibis/backends/tests/test_generic.py @@ -24,7 +24,7 @@ MySQLProgrammingError, OracleDatabaseError, PolarsInvalidOperationError, - PsycoPg2InternalError, + PsycoPgInternalError, PsycoPgSyntaxError, Py4JJavaError, PyAthenaDatabaseError, @@ -1136,7 +1136,7 @@ def test_typeof(con): @pytest.mark.notyet(["exasol"], raises=ExaQueryError, reason="not supported by exasol") @pytest.mark.notyet( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="https://github.com/risingwavelabs/risingwave/issues/1343", ) @pytest.mark.notyet( @@ -1740,7 +1740,7 @@ def hash_256(col): pytest.mark.notimpl(["druid"], raises=PyDruidProgrammingError), pytest.mark.notimpl(["oracle"], raises=OracleDatabaseError), pytest.mark.notimpl(["postgres"], raises=PsycoPgSyntaxError), - pytest.mark.notimpl(["risingwave"], raises=PsycoPg2InternalError), + pytest.mark.notimpl(["risingwave"], raises=PsycoPgInternalError), pytest.mark.notimpl(["snowflake"], raises=AssertionError), pytest.mark.never( ["datafusion", "exasol", "impala", "mssql", "mysql", "sqlite"], @@ -2077,7 +2077,7 @@ def test_static_table_slice(backend, slc, expected_count_fn): ) @pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="risingwave doesn't support limit/offset", ) @pytest.mark.notyet( @@ -2178,7 +2178,7 @@ def test_dynamic_table_slice(backend, slc, expected_count_fn): ) @pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="risingwave doesn't support limit/offset", ) def test_dynamic_table_slice_with_computed_offset(backend): diff --git a/ibis/backends/tests/test_map.py b/ibis/backends/tests/test_map.py index 6c595b56b6e31..8524ab649a8d3 100644 --- a/ibis/backends/tests/test_map.py +++ b/ibis/backends/tests/test_map.py @@ -7,7 +7,7 @@ import ibis.common.exceptions as exc import ibis.expr.datatypes as dt from ibis.backends.tests.errors import ( - PsycoPg2InternalError, + PsycoPgInternalError, Py4JJavaError, PyAthenaOperationalError, ) @@ -51,7 +51,7 @@ @pytest.mark.notyet("clickhouse", reason="nested types can't be NULL") @pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="function hstore(character varying[], character varying[]) does not exist", ) @pytest.mark.parametrize( @@ -73,7 +73,7 @@ def test_map_nulls(con, k, v): @pytest.mark.notyet("clickhouse", reason="nested types can't be NULL") @pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="function hstore(character varying[], character varying[]) does not exist", ) @pytest.mark.parametrize( @@ -94,7 +94,7 @@ def test_map_keys_nulls(con, k, v): @pytest.mark.notyet("clickhouse", reason="nested types can't be NULL") @pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="function hstore(character varying[], character varying[]) does not exist", ) @pytest.mark.parametrize( @@ -123,7 +123,7 @@ def test_map_values_nulls(con, map): @pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="function hstore(character varying[], character varying[]) does not exist", ) @pytest.mark.parametrize( @@ -194,7 +194,7 @@ def test_map_get_contains_nulls(con, map, key, method): @pytest.mark.notyet("clickhouse", reason="nested types can't be NULL") @pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="function hstore(character varying[], character varying[]) does not exist", ) @pytest.mark.parametrize( diff --git a/ibis/backends/tests/test_numeric.py b/ibis/backends/tests/test_numeric.py index a8135b084122c..7c5a944e0b4e2 100644 --- a/ibis/backends/tests/test_numeric.py +++ b/ibis/backends/tests/test_numeric.py @@ -22,8 +22,8 @@ ImpalaHiveServer2Error, MySQLOperationalError, OracleDatabaseError, - PsycoPg2InternalError, PsycoPgDivisionByZero, + PsycoPgInternalError, Py4JError, Py4JJavaError, PyAthenaOperationalError, @@ -783,7 +783,7 @@ def test_isnan_isinf( pytest.mark.notimpl(["druid"], raises=PyDruidProgrammingError), pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="function log10(numeric, numeric) does not exist", ), ], @@ -802,7 +802,7 @@ def test_isnan_isinf( pytest.mark.notimpl(["druid"], raises=PyDruidProgrammingError), pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="function log10(numeric, numeric) does not exist", ), ], @@ -1001,7 +1001,7 @@ def test_floor_divide_precedence(con): pytest.mark.notimpl(["druid"], raises=PyDruidProgrammingError), pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="function log10(numeric, numeric) does not exist", ), ], @@ -1014,7 +1014,7 @@ def test_floor_divide_precedence(con): pytest.mark.notimpl(["druid"], raises=PyDruidProgrammingError), pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="function log10(numeric, numeric) does not exist", ), ], @@ -1053,7 +1053,7 @@ def test_floor_divide_precedence(con): pytest.mark.notimpl(["polars"], raises=com.UnsupportedArgumentError), pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="function log10(numeric, numeric) does not exist", ), ], diff --git a/ibis/backends/tests/test_param.py b/ibis/backends/tests/test_param.py index 27282ce8168d5..f64ac4c1b66d0 100644 --- a/ibis/backends/tests/test_param.py +++ b/ibis/backends/tests/test_param.py @@ -9,7 +9,7 @@ import ibis import ibis.expr.datatypes as dt from ibis import _ -from ibis.backends.tests.errors import OracleDatabaseError, PsycoPg2InternalError +from ibis.backends.tests.errors import OracleDatabaseError, PsycoPgInternalError np = pytest.importorskip("numpy") pd = pytest.importorskip("pandas") @@ -101,7 +101,7 @@ def test_scalar_param_struct(con): @pytest.mark.notyet(["bigquery"]) @pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="function make_date(integer, integer, integer) does not exist", ) def test_scalar_param_map(con): diff --git a/ibis/backends/tests/test_set_ops.py b/ibis/backends/tests/test_set_ops.py index c459a40553460..d1bcb534856ec 100644 --- a/ibis/backends/tests/test_set_ops.py +++ b/ibis/backends/tests/test_set_ops.py @@ -8,7 +8,7 @@ import ibis import ibis.expr.types as ir from ibis import _ -from ibis.backends.tests.errors import PsycoPg2InternalError, PyDruidProgrammingError +from ibis.backends.tests.errors import PsycoPgInternalError, PyDruidProgrammingError pd = pytest.importorskip("pandas") @@ -74,7 +74,7 @@ def test_union_mixed_distinct(backend, union_subsets): ), pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="Feature is not yet implemented: INTERSECT all", ), ], @@ -118,7 +118,7 @@ def test_intersect(backend, alltypes, df, distinct): ), pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="Feature is not yet implemented: EXCEPT all", ), ], @@ -208,7 +208,7 @@ def test_top_level_union(backend, con, alltypes, distinct, ordered): ), pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="Feature is not yet implemented: INTERSECT all", ), ], diff --git a/ibis/backends/tests/test_string.py b/ibis/backends/tests/test_string.py index 7ee55636fd051..1d4a7c3e817bd 100644 --- a/ibis/backends/tests/test_string.py +++ b/ibis/backends/tests/test_string.py @@ -14,7 +14,7 @@ ClickHouseDatabaseError, MySQLOperationalError, OracleDatabaseError, - PsycoPg2InternalError, + PsycoPgInternalError, PyODBCProgrammingError, ) from ibis.common.annotations import ValidationError @@ -70,7 +70,7 @@ ), pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason='sql parser error: Expected end of statement, found: "NG\'" at line:1, column:31 Near "SELECT \'STRI"NG\' AS "\'STRI""', ), ], @@ -100,7 +100,7 @@ ), pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason='sql parser error: Expected end of statement, found: "NG\'" at line:1, column:31 Near "SELECT \'STRI"NG\' AS "\'STRI""', ), ], @@ -879,7 +879,7 @@ def test_multiple_subs(con): ) @pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="function levenshtein(character varying, character varying) does not exist", ) @pytest.mark.parametrize( diff --git a/ibis/backends/tests/test_struct.py b/ibis/backends/tests/test_struct.py index 48e046cb3a545..ece0b5530654c 100644 --- a/ibis/backends/tests/test_struct.py +++ b/ibis/backends/tests/test_struct.py @@ -12,7 +12,7 @@ from ibis.backends.tests.errors import ( DatabricksServerOperationError, PolarsColumnNotFoundError, - PsycoPg2InternalError, + PsycoPgInternalError, PsycoPgSyntaxError, Py4JJavaError, PyAthenaDatabaseError, @@ -143,7 +143,7 @@ def test_collect_into_struct(alltypes): @pytest.mark.notimpl( ["risingwave"], reason="struct literals not implemented", - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, ) @pytest.mark.notyet(["datafusion"], raises=Exception, reason="unsupported syntax") @pytest.mark.notimpl(["flink"], raises=Py4JJavaError, reason="not implemented in ibis") @@ -181,7 +181,7 @@ def test_field_access_after_case(con): pytest.mark.notyet( ["risingwave"], reason="non-nullable struct types not implemented", - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, ), pytest.mark.notimpl( ["pyspark"], @@ -247,7 +247,7 @@ def test_keyword_fields(con, nullable): ) @pytest.mark.notyet( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="sqlglot doesn't implement structs for postgres correctly", ) @pytest.mark.notyet( diff --git a/ibis/backends/tests/test_temporal.py b/ibis/backends/tests/test_temporal.py index 11a2a3dacfbd4..270c72a8aca64 100644 --- a/ibis/backends/tests/test_temporal.py +++ b/ibis/backends/tests/test_temporal.py @@ -29,7 +29,7 @@ OracleDatabaseError, PolarsInvalidOperationError, PolarsPanicException, - PsycoPg2InternalError, + PsycoPgInternalError, Py4JJavaError, PyAthenaOperationalError, PyDruidProgrammingError, @@ -494,7 +494,7 @@ def test_date_truncate(backend, alltypes, df, unit): ), pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="Bind error: Invalid unit: week", ), sqlite_without_ymd_intervals, @@ -518,7 +518,7 @@ def test_date_truncate(backend, alltypes, df, unit): ), pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="Bind error: Invalid unit: millisecond", ), sqlite_without_hms_intervals, @@ -543,7 +543,7 @@ def test_date_truncate(backend, alltypes, df, unit): ), pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="Bind error: Invalid unit: microsecond", ), ], @@ -612,7 +612,7 @@ def convert_to_offset(offset, displacement_type=displacement_type): pytest.mark.notyet(["oracle"], raises=com.UnsupportedArgumentError), pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="Bind error: Invalid unit: week", ), pytest.mark.notimpl( @@ -1977,7 +1977,7 @@ def test_large_timestamp(con): pytest.mark.notimpl(["exasol"], raises=AssertionError), pytest.mark.notyet( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="Parse error: timestamp without time zone Can't cast string to timestamp (expected format is YYYY-MM-DD HH:MM:SS[.D+{up to 6 digits}] or YYYY-MM-DD HH:MM or YYYY-MM-DD or ISO 8601 format)", ), pytest.mark.notyet(["athena"], raises=PyAthenaOperationalError), @@ -2148,7 +2148,7 @@ def test_delta(con, start, end, unit, expected): @pytest.mark.notimpl(["exasol"], raises=com.OperationNotDefinedError) @pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="function date_bin(interval, timestamp without time zone, timestamp without time zone) does not exist", ) def test_timestamp_bucket(backend, kws, pd_freq): @@ -2182,7 +2182,7 @@ def test_timestamp_bucket(backend, kws, pd_freq): @pytest.mark.notimpl(["exasol"], raises=com.OperationNotDefinedError) @pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="function date_bin(interval, timestamp without time zone, timestamp without time zone) does not exist", ) def test_timestamp_bucket_offset(backend, offset_mins): diff --git a/ibis/backends/tests/test_window.py b/ibis/backends/tests/test_window.py index dff9331a1d269..c60753fb490d0 100644 --- a/ibis/backends/tests/test_window.py +++ b/ibis/backends/tests/test_window.py @@ -14,7 +14,7 @@ GoogleBadRequest, ImpalaHiveServer2Error, MySQLOperationalError, - PsycoPg2InternalError, + PsycoPgInternalError, Py4JJavaError, PyDruidProgrammingError, PyODBCProgrammingError, @@ -127,7 +127,7 @@ def calc_zscore(s): ), pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="Feature is not yet implemented: Unrecognized window function: percent_rank", ), pytest.mark.notimpl(["druid"], raises=PyDruidProgrammingError), @@ -143,7 +143,7 @@ def calc_zscore(s): ), pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="Feature is not yet implemented: Unrecognized window function: cume_dist", ), pytest.mark.notimpl(["druid"], raises=PyDruidProgrammingError), @@ -167,7 +167,7 @@ def calc_zscore(s): ), pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="Feature is not yet implemented: Unrecognized window function: ntile", ), pytest.mark.notimpl(["druid"], raises=PyDruidProgrammingError), @@ -199,7 +199,7 @@ def calc_zscore(s): ["impala", "mssql"], raises=com.OperationNotDefinedError ), pytest.mark.notimpl(["flink"], raises=com.OperationNotDefinedError), - pytest.mark.notimpl(["risingwave"], raises=PsycoPg2InternalError), + pytest.mark.notimpl(["risingwave"], raises=PsycoPgInternalError), pytest.mark.notimpl(["druid"], raises=PyDruidProgrammingError), ], ), @@ -342,7 +342,7 @@ def test_grouped_bounded_expanding_window( marks=[ pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="Feature is not yet implemented: Window function with empty PARTITION BY is not supported yet", ), pytest.mark.notimpl(["druid"], raises=PyDruidProgrammingError), @@ -614,7 +614,7 @@ def test_grouped_unbounded_window(backend, alltypes, df, result_fn, expected_fn) @pytest.mark.notimpl(["polars"], raises=com.OperationNotDefinedError) @pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="Feature is not yet implemented: Window function with empty PARTITION BY is not supported yet", ) @pytest.mark.notimpl(["druid"], raises=PyDruidProgrammingError) @@ -643,7 +643,7 @@ def test_simple_ungrouped_unbound_following_window( @pytest.mark.notimpl(["polars"], raises=com.OperationNotDefinedError) @pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="Feature is not yet implemented: Window function with empty PARTITION BY is not supported yet", ) def test_simple_ungrouped_window_with_scalar_order_by(alltypes): @@ -671,7 +671,7 @@ def test_simple_ungrouped_window_with_scalar_order_by(alltypes): ), pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="Feature is not yet implemented: Window function with empty PARTITION BY is not supported yet", ), pytest.mark.notimpl(["druid"], raises=PyDruidProgrammingError), @@ -692,7 +692,7 @@ def test_simple_ungrouped_window_with_scalar_order_by(alltypes): marks=[ pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="Feature is not yet implemented: Unrecognized window function: ntile", ), pytest.mark.notimpl(["druid"], raises=PyDruidProgrammingError), @@ -781,7 +781,7 @@ def test_simple_ungrouped_window_with_scalar_order_by(alltypes): marks=[ pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="Feature is not yet implemented: Window function with empty PARTITION BY is not supported yet", ), pytest.mark.notimpl(["druid"], raises=PyDruidProgrammingError), @@ -808,7 +808,7 @@ def test_simple_ungrouped_window_with_scalar_order_by(alltypes): ), pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="Feature is not yet implemented: Window function with empty PARTITION BY is not supported yet", ), pytest.mark.notimpl(["druid"], raises=PyDruidProgrammingError), @@ -822,7 +822,7 @@ def test_simple_ungrouped_window_with_scalar_order_by(alltypes): marks=[ pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="Feature is not yet implemented: Window function with empty PARTITION BY is not supported yet", ), pytest.mark.notimpl(["druid"], raises=PyDruidProgrammingError), @@ -852,7 +852,7 @@ def test_simple_ungrouped_window_with_scalar_order_by(alltypes): ), pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="Feature is not yet implemented: Window function with empty PARTITION BY is not supported yet", ), pytest.mark.notimpl(["druid"], raises=PyDruidProgrammingError), @@ -1018,7 +1018,7 @@ def gb_fn(df): ) @pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="Feature is not yet implemented: Unrecognized window function: percent_rank", ) @pytest.mark.notimpl(["druid"], raises=PyDruidProgrammingError) @@ -1070,7 +1070,7 @@ def agg(df): @pytest.mark.notimpl(["polars"], raises=com.OperationNotDefinedError) @pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="Feature is not yet implemented: Window function with empty PARTITION BY is not supported yet", ) @pytest.mark.notimpl(["druid"], raises=PyDruidProgrammingError) @@ -1140,7 +1140,7 @@ def test_first_last(backend): @pytest.mark.notyet(["flink"], raises=Py4JJavaError, reason="bug in Flink") @pytest.mark.notyet( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="sql parser error: Expected literal int, found: INTERVAL at line:1, column:99", ) @pytest.mark.notimpl(["druid"], raises=PyDruidProgrammingError) @@ -1190,7 +1190,7 @@ def test_range_expression_bounds(backend): ) @pytest.mark.notyet( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="Feature is not yet implemented: Unrecognized window function: percent_rank", ) @pytest.mark.notimpl(["druid"], raises=PyDruidProgrammingError) @@ -1222,7 +1222,7 @@ def test_rank_followed_by_over_call_merge_frames(backend, alltypes, df): @pytest.mark.notimpl(["polars"], raises=com.OperationNotDefinedError) @pytest.mark.notimpl( ["risingwave"], - raises=PsycoPg2InternalError, + raises=PsycoPgInternalError, reason="Feature is not yet implemented: Window function with empty PARTITION BY is not supported yet", ) @pytest.mark.notimpl(["druid"], raises=PyDruidProgrammingError) diff --git a/pyproject.toml b/pyproject.toml index 91f1a5918ca5e..eba25e324a99a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -196,7 +196,7 @@ sqlite = [ "rich>=12.4.4,<14", ] risingwave = [ - "psycopg2>=2.8.4,<3", + "psycopg>=3.2.0,<4", "pyarrow>=10.0.1", "pyarrow-hotfix>=0.4,<1", "numpy>=1.23.2,<3", diff --git a/requirements-dev.txt b/requirements-dev.txt index 9d41bb06c2b3e..06ca5953a7f7a 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -179,7 +179,6 @@ proto-plus==1.25.0 protobuf==5.29.2 psutil==6.1.1 psycopg==3.2.3 -psycopg2==2.9.10 psygnal==0.11.1 ptyprocess==0.7.0 ; os_name != 'nt' or (sys_platform != 'emscripten' and sys_platform != 'win32') pure-eval==0.2.3 diff --git a/uv.lock b/uv.lock index ef384bef6942c..ee4aa341ab53f 100644 --- a/uv.lock +++ b/uv.lock @@ -2159,7 +2159,7 @@ pyspark = [ risingwave = [ { name = "numpy" }, { name = "pandas" }, - { name = "psycopg2" }, + { name = "psycopg" }, { name = "pyarrow" }, { name = "pyarrow-hotfix" }, { name = "rich" }, @@ -2315,7 +2315,7 @@ requires-dist = [ { name = "pins", extras = ["gcs"], marker = "extra == 'examples'", specifier = ">=0.8.3,<1" }, { name = "polars", marker = "extra == 'polars'", specifier = ">=1,<2" }, { name = "psycopg", marker = "extra == 'postgres'", specifier = ">=3.2.0,<4" }, - { name = "psycopg2", marker = "extra == 'risingwave'", specifier = ">=2.8.4,<3" }, + { name = "psycopg", marker = "extra == 'risingwave'", specifier = ">=3.2.0,<4" }, { name = "pyarrow", marker = "extra == 'athena'", specifier = ">=10.0.1" }, { name = "pyarrow", marker = "extra == 'bigquery'", specifier = ">=10.0.1" }, { name = "pyarrow", marker = "extra == 'clickhouse'", specifier = ">=10.0.1" }, @@ -4016,21 +4016,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ce/21/534b8f5bd9734b7a2fcd3a16b1ee82ef6cad81a4796e95ebf4e0c6a24119/psycopg-3.2.3-py3-none-any.whl", hash = "sha256:644d3973fe26908c73d4be746074f6e5224b03c1101d302d9a53bf565ad64907", size = 197934 }, ] -[[package]] -name = "psycopg2" -version = "2.9.10" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/62/51/2007ea29e605957a17ac6357115d0c1a1b60c8c984951c19419b3474cdfd/psycopg2-2.9.10.tar.gz", hash = "sha256:12ec0b40b0273f95296233e8750441339298e6a572f7039da5b260e3c8b60e11", size = 385672 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0a/a9/146b6bdc0d33539a359f5e134ee6dda9173fb8121c5b96af33fa299e50c4/psycopg2-2.9.10-cp310-cp310-win32.whl", hash = "sha256:5df2b672140f95adb453af93a7d669d7a7bf0a56bcd26f1502329166f4a61716", size = 1024527 }, - { url = "https://files.pythonhosted.org/packages/47/50/c509e56f725fd2572b59b69bd964edaf064deebf1c896b2452f6b46fdfb3/psycopg2-2.9.10-cp310-cp310-win_amd64.whl", hash = "sha256:c6f7b8561225f9e711a9c47087388a97fdc948211c10a4bccbf0ba68ab7b3b5a", size = 1163735 }, - { url = "https://files.pythonhosted.org/packages/20/a2/c51ca3e667c34e7852157b665e3d49418e68182081060231d514dd823225/psycopg2-2.9.10-cp311-cp311-win32.whl", hash = "sha256:47c4f9875125344f4c2b870e41b6aad585901318068acd01de93f3677a6522c2", size = 1024538 }, - { url = "https://files.pythonhosted.org/packages/33/39/5a9a229bb5414abeb86e33b8fc8143ab0aecce5a7f698a53e31367d30caa/psycopg2-2.9.10-cp311-cp311-win_amd64.whl", hash = "sha256:0435034157049f6846e95103bd8f5a668788dd913a7c30162ca9503fdf542cb4", size = 1163736 }, - { url = "https://files.pythonhosted.org/packages/3d/16/4623fad6076448df21c1a870c93a9774ad8a7b4dd1660223b59082dd8fec/psycopg2-2.9.10-cp312-cp312-win32.whl", hash = "sha256:65a63d7ab0e067e2cdb3cf266de39663203d38d6a8ed97f5ca0cb315c73fe067", size = 1025113 }, - { url = "https://files.pythonhosted.org/packages/66/de/baed128ae0fc07460d9399d82e631ea31a1f171c0c4ae18f9808ac6759e3/psycopg2-2.9.10-cp312-cp312-win_amd64.whl", hash = "sha256:4a579d6243da40a7b3182e0430493dbd55950c493d8c68f4eec0b302f6bbf20e", size = 1163951 }, - { url = "https://files.pythonhosted.org/packages/ae/49/a6cfc94a9c483b1fa401fbcb23aca7892f60c7269c5ffa2ac408364f80dc/psycopg2-2.9.10-cp313-cp313-win_amd64.whl", hash = "sha256:91fd603a2155da8d0cfcdbf8ab24a2d54bca72795b90d2a3ed2b6da8d979dee2", size = 2569060 }, -] - [[package]] name = "psygnal" version = "0.11.1"