internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: ibis-project/ibis

Issue:
`build_ast` in BigQuery backend missing
It looks like the `build_ast` function in the BigQuery backend is missing. It causes an error when `.compile()` is called. Here is a repro:

```
import ibis
from ibis.expr.types import TableExpr
import ibis.expr.operations as ops

def _get_ibis_client():
    ibis_client = ibis.backends.bigquery.BigQueryClient
    ibis_client = ibis_client()
    return ibis_client

def _get_test_table(ibis_client):
    names = ['Class',                  
  'end_of_period',          
  'M_Total_Dollars_Total',
            ]
    types = ['string', "date", 'float64']
    schema = ibis.Schema(names, types)
    t = TableExpr(ops.SQLQueryResult("select * from t", schema, ibis_client))
    return t

def test_window_compile():
    ibis_client = _get_ibis_client()
    t = _get_test_table(ibis_client)
    key_cols = ['Class', 'end_of_period']
    order_col = 'end_of_period'
    window = ibis.range_window(
        preceding=ibis.interval(days=62),
        order_by=t[order_col],
        group_by=[t['Class']],
    )
    t = t.mutate(window=t["M_Total_Dollars_Total"].sum().over(window))
    t.compile()
    return t

test_window_compile()
```
```
AttributeError: module 'ibis.backends.bigquery.compiler' has no attribute 'build_ast'
```

Here is a trace of how `.compile()` depends on `build_ast`:
* `SQLClient.compile` calls `SQLClient._build_ast_ensure_limit` ([ibis/client.py#L255](https://github.com/ibis-project/ibis/blob/07f0016abed82be1df5278c29833fd7ab41de0e4/ibis/client.py#L255))
* `SQLClient._build_ast_ensure_limit` calls `SQLClient._build_ast` ([ibis/client.py#L261](https://github.com/ibis-project/ibis/blob/07f0016abed82be1df5278c29833fd7ab41de0e4/ibis/client.py#L261))
* `BigQueryClient._build_ast` tries to call `build_ast` from `ibis/backends/bigquery/compiler.py` ([bigquery/client.py#L439](https://github.com/ibis-project/ibis/blob/165f78de8f4f0121ba2c601b5c9f89bc0f65a593/ibis/backends/bigquery/client.py#L439)) but it doesn't exist

I believe it may have been inadvertently removed in #2661 ([diff](https://github.com/ibis-project/ibis/pull/2661/files#diff-d7c2d45959c2baa00df6631a8818c081adecd87626c52ab82b7560933609e91cL79-L81))


Discussion:
Thanks for the heads up @timothydijamco 

I'm going to have a look at the bigquery tests, which run after PRs are merged. I received the notification that they failed, but they've been always broken, so didn't pay attention. @tswast can we xfail all broken bigquery tests, so we have a green build and we detect when things break.

Resolving patch:
diff --git a/ibis/backends/bigquery/compiler.py b/ibis/backends/bigquery/compiler.py
--- a/ibis/backends/bigquery/compiler.py
+++ b/ibis/backends/bigquery/compiler.py
@@ -25,6 +25,11 @@
 from .datatypes import ibis_type_to_bigquery_type
 
 
+def build_ast(expr, context):
+    builder = BigQueryQueryBuilder(expr, context=context)
+    return builder.get_result()
+
+
 class BigQueryUDFNode(ops.ValueOp):
     pass
 


Test patch:
Repository: ibis-project/ibis

Issue:
BUG: File pseudo-backends failing for missing pandas option
The next code is failing in master since #2833:

```python
>>> import ibis
>>> con = ibis.csv.connect('/home/mgarcia/src/ibis/ci/ibis-testing-data/')
>>> expr = con.table('functional_alltypes')['double_col'] * 2
>>> print(expr.execute())
OptionError: "No such keys(s): 'pandas.enable_trace'"
```

The problem is when the `csv` backend  (or other file backends) are loaded, but the pandas backend is not. This is because `ibis.pandas` loads the pandas options, which looks like they are needed by the file pseudo-backends.

The CI is not failing, I guess because we test pandas and the file backends are tested together, and pandas is loaded when the file backends are tested.


Discussion:
This also fails when trying to run pandas individual tests themselves. 

Resolving patch:
diff --git a/ibis/backends/base/file/__init__.py b/ibis/backends/base/file/__init__.py
--- a/ibis/backends/base/file/__init__.py
+++ b/ibis/backends/base/file/__init__.py
@@ -1,9 +1,13 @@
 from pathlib import Path
 
+import ibis
 import ibis.expr.types as ir
 from ibis.backends.base import BaseBackend, Client, Database
 from ibis.backends.pandas.core import execute_and_reset
 
+# Load options of pandas backend
+ibis.pandas
+
 
 class FileClient(Client):
     def __init__(self, backend, root):


Test patch:
Repository: ibis-project/ibis

Issue:
bug: isolated dask backend tests fail due to removed imports
For some reason lines 6 and 8 here: https://github.com/ibis-project/ibis/commit/a1262410310bb4d638a73e1cdfbe93c2b4089905#diff-96d84d9b6e9e84a2be7a046dc9853df1ca5fc6e894307339b02cd61e666c0149L6-L8

were removed.

This causes dasks tests to fail when they are run in isolation from other tests that (transitively) import from the pandas backend.

This is both a ci bug and a bug in the code, since we're not testing backends independently. Perhaps unsurprisingly I discovered the bug in #2937, which fixes the CI part of this problem.


Discussion:

Resolving patch:
diff --git a/ibis/backends/dask/__init__.py b/ibis/backends/dask/__init__.py
--- a/ibis/backends/dask/__init__.py
+++ b/ibis/backends/dask/__init__.py
@@ -6,6 +6,9 @@
 import toolz
 from dask.base import DaskMethodsMixin
 
+# import the pandas execution module to register dispatched implementations of
+# execute_node that the dask backend will later override
+import ibis.backends.pandas.execution  # noqa: F401
 import ibis.common.exceptions as com
 import ibis.config
 import ibis.expr.schema as sch
@@ -15,8 +18,7 @@
 from .client import DaskDatabase, DaskTable, ibis_schema_to_dask
 from .core import execute_and_reset
 
-# Make sure that the pandas backend is loaded, dispatching has been
-# executed, and options have been loaded
+# Make sure that the pandas backend options have been loaded
 ibis.pandas
 
 


Test patch:
Repository: ibis-project/ibis

Issue:
BUG: Binary literals' type is not inferred
Is there any reason not to infer `bytes` literals as `binary`?

```
>>> import ibis
>>> ibis.literal(b"abc")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/cloud/src/ibis/ibis/expr/types.py", line 1288, in literal
    raise TypeError(
TypeError: The datatype of value b'abc' cannot be inferred, try passing it explicitly with the `type` keyword.
```


Discussion:
this seems reasonable 

Resolving patch:
diff --git a/ibis/expr/datatypes.py b/ibis/expr/datatypes.py
--- a/ibis/expr/datatypes.py
+++ b/ibis/expr/datatypes.py
@@ -1232,6 +1232,11 @@ def infer_string(value: str) -> String:
     return string
 
 
+@infer.register(bytes)
+def infer_bytes(value: bytes) -> Binary:
+    return binary
+
+
 @infer.register(builtins.float)
 def infer_floating(value: builtins.float) -> Double:
     return double


Test patch:
diff --git a/ibis/tests/expr/test_datatypes.py b/ibis/tests/expr/test_datatypes.py
--- a/ibis/tests/expr/test_datatypes.py
+++ b/ibis/tests/expr/test_datatypes.py
@@ -379,6 +379,7 @@ class Foo(enum.Enum):
         (False, dt.boolean),
         (True, dt.boolean),
         ('foo', dt.string),
+        (b'fooblob', dt.binary),
         (datetime.date.today(), dt.date),
         (datetime.datetime.now(), dt.timestamp),
         (datetime.timedelta(days=3), dt.Interval(unit='D')),
diff --git a/ibis/tests/expr/test_value_exprs.py b/ibis/tests/expr/test_value_exprs.py
--- a/ibis/tests/expr/test_value_exprs.py
+++ b/ibis/tests/expr/test_value_exprs.py
@@ -63,6 +63,7 @@ def test_unicode():
         (-2147483649, 'int64'),
         (1.5, 'double'),
         ('foo', 'string'),
+        (b'fooblob', 'binary'),
         ([1, 2, 3], 'array<int8>'),
     ],
 )
Repository: ibis-project/ibis

Issue:
bug: uuid.UUID values are no longer accepted in ibis.literal
```
In [12]: import ibis

In [13]: ibis.literal(uuid.uuid4(), type='uuid')
IbisTypeError: argument passes none of the following rules: instance_of((<class 'shapely.geometry.base.BaseGeometry'>, <class 'bytes'>, <class 'datetime.date'>, <class 'datetime.datetime'>, <class 'datetime.time'>, <class 'datetime.timedelta'>, <class 'dict'>, <enum 'Enum'>, <class 'float'>, <class 'frozenset'>, <class 'int'>, <class 'list'>, <class 'numpy.generic'>, <class 'numpy.ndarray'>, <class 'pandas._libs.tslibs.timedeltas.Timedelta'>, <class 'pandas._libs.tslibs.timestamps.Timestamp'>, <class 'set'>, <class 'str'>, <class 'tuple'>, <class 'NoneType'>),), is_computable_input()
```

This was introduced in 3dbbce84c85.

The fix is pretty straightforward: add `uuid.UUID` to the big `one_of` list in `ibis/expr/operations/generic.py` and include a test in `ibis/tests/expr/test_value_exprs.py`.


Discussion:

Resolving patch:
diff --git a/ibis/expr/operations/generic.py b/ibis/expr/operations/generic.py
--- a/ibis/expr/operations/generic.py
+++ b/ibis/expr/operations/generic.py
@@ -2,6 +2,7 @@
 import enum
 import functools
 import itertools
+import uuid
 
 import numpy as np
 import pandas as pd
@@ -247,6 +248,7 @@ class Literal(ValueOp):
                         str,
                         tuple,
                         type(None),
+                        uuid.UUID,
                     )
                 ),
                 rlz.is_computable_input,


Test patch:
diff --git a/ibis/tests/expr/test_value_exprs.py b/ibis/tests/expr/test_value_exprs.py
--- a/ibis/tests/expr/test_value_exprs.py
+++ b/ibis/tests/expr/test_value_exprs.py
@@ -1,6 +1,7 @@
 import functools
 import operator
 import os
+import uuid
 from collections import OrderedDict
 from datetime import date, datetime, time
 from operator import methodcaller
@@ -118,6 +119,8 @@ def test_literal_with_implicit_type(value, expected_type):
         (tuple(multipoint), 'multipoint'),
         (list(multipolygon1), 'multipolygon'),
         (tuple(multipolygon1), 'multipolygon'),
+        (uuid.uuid4(), 'uuid'),
+        (str(uuid.uuid4()), 'uuid'),
     ],
 )
 def test_literal_with_explicit_type(value, expected_type):
Repository: ibis-project/ibis

Issue:
bug: UUID type is a subclass of String
UUIDs are not strings, they are really byte blobs with various representations, one of which is a string.

We should remove the String superclass.

I don't think UUID should have any parent class other than DataType.

_Originally posted by @cpcloud in https://github.com/ibis-project/ibis/pull/3133#r755252233_


Discussion:

Resolving patch:
diff --git a/ibis/expr/datatypes.py b/ibis/expr/datatypes.py
--- a/ibis/expr/datatypes.py
+++ b/ibis/expr/datatypes.py
@@ -802,7 +802,7 @@ class MultiPolygon(GeoSpatial):
     __slots__ = ()
 
 
-class UUID(String):
+class UUID(DataType):
     """A universally unique identifier (UUID) is a 128-bit number used to
     identify information in computer systems.
     """
@@ -1451,6 +1451,8 @@ def can_cast_geospatial(source, target, **kwargs):
 
 
 @castable.register(UUID, UUID)
+@castable.register(UUID, String)
+@castable.register(String, UUID)
 @castable.register(MACADDR, MACADDR)
 @castable.register(INET, INET)
 def can_cast_special_string(source, target, **kwargs):
@@ -1569,10 +1571,3 @@ def _str_to_uuid(typ: UUID, value: str) -> _uuid.UUID:
 @_normalize.register(String, _uuid.UUID)
 def _uuid_to_str(typ: String, value: _uuid.UUID) -> str:
     return str(value)
-
-
-@_normalize.register(UUID, _uuid.UUID)
-def _uuid_to_uuid(typ: UUID, value: _uuid.UUID) -> _uuid.UUID:
-    """Need this to override _uuid_to_str since dt.UUID is a child of
-    dt.String"""
-    return value


Test patch:
diff --git a/ibis/tests/expr/test_datatypes.py b/ibis/tests/expr/test_datatypes.py
--- a/ibis/tests/expr/test_datatypes.py
+++ b/ibis/tests/expr/test_datatypes.py
@@ -497,6 +497,8 @@ def test_infer_dtype(value, expected_dtype):
     ('source', 'target'),
     [
         (dt.any, dt.string),
+        (dt.string, dt.uuid),
+        (dt.uuid, dt.string),
         (dt.null, dt.date),
         (dt.null, dt.any),
         (dt.int8, dt.int64),
Repository: ibis-project/ibis

Issue:
docs: add blurb about the datafusion backend
After #2918 lands, we need to mention it in the docs.


Discussion:

Resolving patch:
diff --git a/ibis/backends/datafusion/__init__.py b/ibis/backends/datafusion/__init__.py
--- a/ibis/backends/datafusion/__init__.py
+++ b/ibis/backends/datafusion/__init__.py
@@ -83,6 +83,20 @@ def list_tables(self, like: str = None, database: str = None) -> list[str]:
         return tables
 
     def table(self, name, schema=None):
+        """Get an ibis expression representing a DataFusion table.
+
+        Parameters
+        ---------
+        name
+            The name of the table to retreive
+        schema
+            An optional schema
+
+        Returns
+        -------
+        ibis.expr.types.TableExpr
+            A table expression
+        """
         catalog = self._context.catalog()
         database = catalog.database('public')
         table = database.table(name)
@@ -90,9 +104,31 @@ def table(self, name, schema=None):
         return self.table_class(name, schema, self).to_expr()
 
     def register_csv(self, name, path, schema=None):
+        """Register a CSV file with with `name` located at `path`.
+
+        Parameters
+        ----------
+        name
+            The name of the table
+        path
+            The path to the CSV file
+        schema
+            An optional schema
+        """
         self._context.register_csv(name, path, schema=schema)
 
     def register_parquet(self, name, path, schema=None):
+        """Register a parquet file with with `name` located at `path`.
+
+        Parameters
+        ----------
+        name
+            The name of the table
+        path
+            The path to the parquet file
+        schema
+            An optional schema
+        """
         self._context.register_parquet(name, path, schema=schema)
 
     def execute(


Test patch:
Repository: ibis-project/ibis

Issue:
bug: 'PostgreSQLCompiler' has no attribute 'add_operation'
As turned out during my local refactor, the postgres udf tests are not running, there should be a `test_udf.py` [here](https://github.com/ibis-project/ibis/runs/4808027717?check_suite_focus=true#step:13:43). 

There is a valid error, since the `.add_operation()` method has been moved to the `ExpressionTranslator` base class:

```py
        def _translate_udf(t, expr):
            func_obj = sa.func
            if schema is not None:
                func_obj = getattr(func_obj, schema)
            func_obj = getattr(func_obj, name)

            sa_args = [t.translate(arg) for arg in expr.op().args]

            return func_obj(*sa_args)

>       PostgreSQLCompiler.add_operation(udf_node, _translate_udf)
E       AttributeError: type object 'PostgreSQLCompiler' has no attribute 'add_operation'

ibis/backends/postgres/udf.py:124: AttributeError
```


Discussion:

Resolving patch:
diff --git a/ibis/backends/postgres/__init__.py b/ibis/backends/postgres/__init__.py
--- a/ibis/backends/postgres/__init__.py
+++ b/ibis/backends/postgres/__init__.py
@@ -5,8 +5,8 @@
 
 from ibis.backends.base.sql.alchemy import BaseAlchemyBackend
 
-from . import udf
 from .compiler import PostgreSQLCompiler
+from .udf import udf
 
 
 class Backend(BaseAlchemyBackend):
diff --git a/ibis/backends/postgres/udf.py b/ibis/backends/postgres/udf.py
--- a/ibis/backends/postgres/udf.py
+++ b/ibis/backends/postgres/udf.py
@@ -12,7 +12,6 @@
 from ibis import IbisError
 from ibis.backends.base.sql.alchemy import to_sqla_type
 from ibis.backends.postgres.compiler import (
-    PostgreSQLCompiler,
     PostgreSQLExprTranslator,
     PostgresUDFNode,
 )
@@ -121,7 +120,7 @@ def _translate_udf(t, expr):
 
         return func_obj(*sa_args)
 
-    PostgreSQLCompiler.add_operation(udf_node, _translate_udf)
+    PostgreSQLExprTranslator.add_operation(udf_node, _translate_udf)
 
     def wrapped(*args, **kwargs):
         node = udf_node(*args, **kwargs)


Test patch:
Repository: ibis-project/ibis

Issue:
refactor: remove __del__ methods
We seem to be depending on destructor-like behavior of `__del__` which is a mistake. `__del__` is not guaranteed to be called, basically ever: https://docs.python.org/3/reference/datamodel.html#object.__del__

We should find alternatives to these methods (often a context manager works, but not always) and then remove them from the library.


Discussion:

Resolving patch:
diff --git a/ibis/backends/base/sql/alchemy/__init__.py b/ibis/backends/base/sql/alchemy/__init__.py
--- a/ibis/backends/base/sql/alchemy/__init__.py
+++ b/ibis/backends/base/sql/alchemy/__init__.py
@@ -52,28 +52,6 @@
 )
 
 
-class _AutoCloseCursor:
-    """
-    Wraps a SQLAlchemy ResultProxy and ensures that .close() is called on
-    garbage collection
-    """
-
-    def __init__(self, original_cursor):
-        self.original_cursor = original_cursor
-
-    def __del__(self):
-        self.original_cursor.close()
-
-    def __enter__(self):
-        return self
-
-    def __exit__(self, type, value, tb):
-        self.original_cursor.close()
-
-    def fetchall(self):
-        return self.original_cursor.fetchall()
-
-
 class BaseAlchemyBackend(BaseSQLBackend):
     """
     Base backend class for backends that compile to SQL with SQLAlchemy.
@@ -151,8 +129,8 @@ def to_shapely(row, name):
 
     def fetch_from_cursor(self, cursor, schema):
         df = pd.DataFrame.from_records(
-            cursor.original_cursor.fetchall(),
-            columns=cursor.original_cursor.keys(),
+            cursor.fetchall(),
+            columns=cursor.keys(),
             coerce_float=True,
         )
         df = schema.apply_to(df)
@@ -326,9 +304,6 @@ def current_database(self):
     def list_schemas(self):
         return self.list_databases()
 
-    def raw_sql(self, query: str, results=False):
-        return _AutoCloseCursor(super().raw_sql(query))
-
     def _log(self, sql):
         try:
             query_str = str(sql)


Test patch:
Repository: ibis-project/ibis

Issue:
refactor: use ibis.schema() to coerce the schema argument of ibis.table()
The schema coercion is slightly different between

https://github.com/ibis-project/ibis/blob/430b79213979a8ef80f681f94b25690b3bfd194a/ibis/expr/api.py#L289-L293

and

https://github.com/ibis-project/ibis/blob/430b79213979a8ef80f681f94b25690b3bfd194a/ibis/expr/api.py#L265-L269

We should unify the behavior.

See [TODO note](https://github.com/ibis-project/ibis/pull/3025/files#diff-8f6e03b936fae42459cef36d6bb2691392fb1ed9bd03c9846152ac6ebb6da892R281) for reference.


Discussion:
/take

Resolving patch:
diff --git a/ibis/expr/api.py b/ibis/expr/api.py
--- a/ibis/expr/api.py
+++ b/ibis/expr/api.py
@@ -7,7 +7,7 @@
 import functools
 import numbers
 import operator
-from typing import Any, Iterable
+from typing import Any, Iterable, Mapping
 
 import dateutil.parser
 import pandas as pd
@@ -258,7 +258,9 @@ def sequence(values):
 
 
 def schema(
-    pairs: Iterable[tuple[str, dt.DataType]] | None = None,
+    pairs: Iterable[tuple[str, dt.DataType]]
+    | Mapping[str, dt.DataType]
+    | None = None,
     names: Iterable[str] | None = None,
     types: Iterable[str | dt.DataType] | None = None,
 ) -> sch.Schema:
@@ -267,7 +269,8 @@ def schema(
     Parameters
     ----------
     pairs
-        List of name, type pairs. Mutually exclusive with `names` and `types`.
+        List or dictionary of name, type pairs. Mutually exclusive with `names`
+        and `types`.
     names
         Field names. Mutually exclusive with `pairs`.
     types
@@ -283,11 +286,14 @@ def schema(
     ...              types=['string', 'int64', 'boolean'])
     """
     if pairs is not None:
-        return Schema.from_tuples(pairs)
+        return Schema.from_dict(dict(pairs))
     else:
         return Schema(names, types)
 
 
+_schema = schema
+
+
 def table(schema, name=None):
     """
     Create an unbound Ibis table for creating expressions. Cannot be executed
@@ -306,10 +312,7 @@ def table(schema, name=None):
     table : TableExpr
     """
     if not isinstance(schema, Schema):
-        if isinstance(schema, dict):
-            schema = Schema.from_dict(schema)
-        else:
-            schema = Schema.from_tuples(schema)
+        schema = _schema(pairs=schema)
 
     node = ops.UnboundTable(schema, name=name)
     return node.to_expr()
diff --git a/ibis/expr/schema.py b/ibis/expr/schema.py
--- a/ibis/expr/schema.py
+++ b/ibis/expr/schema.py
@@ -123,7 +123,8 @@ def from_tuples(cls, values):
 
     @classmethod
     def from_dict(cls, dictionary):
-        return Schema(*zip(*dictionary.items()))
+        names, types = zip(*dictionary.items()) if dictionary else ([], [])
+        return Schema(names, types)
 
     def equals(self, other, cache=None):
         return self.names == other.names and self.types == other.types


Test patch:
Repository: ibis-project/ibis

Issue:
test: verify sqlite histogram translation rule works



Discussion:

Resolving patch:
diff --git a/ibis/backends/base/sql/alchemy/query_builder.py b/ibis/backends/base/sql/alchemy/query_builder.py
--- a/ibis/backends/base/sql/alchemy/query_builder.py
+++ b/ibis/backends/base/sql/alchemy/query_builder.py
@@ -40,8 +40,10 @@ def get_result(self):
             else:
                 onclause = None
 
-            if jtype in (ops.InnerJoin, ops.CrossJoin):
+            if jtype is ops.InnerJoin:
                 result = result.join(table, onclause)
+            elif jtype is ops.CrossJoin:
+                result = result.join(table, sa.literal(True))
             elif jtype is ops.LeftJoin:
                 result = result.join(table, onclause, isouter=True)
             elif jtype is ops.RightJoin:


Test patch:
diff --git a/ibis/backends/tests/test_numeric.py b/ibis/backends/tests/test_numeric.py
--- a/ibis/backends/tests/test_numeric.py
+++ b/ibis/backends/tests/test_numeric.py
@@ -452,3 +452,21 @@ def test_clip(alltypes, df, ibis_func, pandas_func):
     # Names won't match in the Pyspark backend since Pyspark
     # gives 'tmp' name when executing a ColumnExpr
     tm.assert_series_equal(result, expected, check_names=False)
+
+
+@pytest.mark.skip_backends(
+    [
+        'pandas',
+        'dask',
+        'csv',
+        'parquet',
+        'hdf5',
+        'datafusion',
+        'pyspark',
+        'clickhouse',
+    ]
+)
+def test_histogram(con, alltypes):
+    n = 10
+    results = con.execute(alltypes.int_col.histogram(n))
+    assert len(results.value_counts()) == n