Repository: narwhals-dev/narwhals

Issue:
test: add Marimo to downstream tests
Here we test some downstream libraries: https://github.com/narwhals-dev/narwhals/blob/main/.github/workflows/downstream_tests.yml

Marimo have added support, so it's probably a good idea to test against them too

The task is:
- check Marimo's CI
- find the testing command, and test it here too (similarly to how we do for Altair / scikit-lego / shiny)
- if they do any type checking (mypy / pyright), test that too

Discussion:

Patch:
diff --git a/.github/workflows/bump-version.yml b/.github/workflows/bump-version.yml
new file mode 100644
index 00000000..3577fd0e
--- /dev/null
+++ b/.github/workflows/bump-version.yml
@@ -0,0 +1,48 @@
+name: Bump version
+
+on:
+  workflow_dispatch:
+    inputs:
+      release_type:     
+        description: 'Type of version bump: patch, minor, or major'
+        required: true
+        default: 'patch'
+        type: choice
+        options: 
+        - patch
+        - minor
+        - major
+
+jobs:
+  bump-version:
+    runs-on: ubuntu-latest
+    steps:
+
+    - uses: actions/checkout@v4
+
+    - uses: actions/setup-python@v5
+      with:
+        python-version: "3.11"
+
+    - name: bump version
+      run: |
+        git config user.name "github-actions[bot]"
+        git config user.email "github-actions[bot]@users.noreply.github.com"
+        git checkout -b bump-version
+        git remote rename origin upstream
+        python utils/bump_version.py ${{ github.event.inputs.release_type }}
+
+    - name: Create pull request
+      uses: actions/github-script@v6
+      if: github.actor == 'MarcoGorelli' || github.actor == 'FBruzzesi'
+      with:
+        script: |
+          const branch = `bump-version`
+          github.pulls.create({
+            owner: context.repo.owner,
+            repo: context.repo.repo,
+            head: branch,
+            base: 'main',
+            body: 'Bumping the version to reflect the latest release type.',
+          })
+        
diff --git a/docs/api-reference/narwhals.md b/docs/api-reference/narwhals.md
index 39afb8e8..044b20e0 100644
--- a/docs/api-reference/narwhals.md
+++ b/docs/api-reference/narwhals.md
@@ -20,6 +20,7 @@ Here are the top-level functions available in Narwhals.
         - len
         - lit
         - max
+        - max_horizontal
         - maybe_align_index
         - maybe_convert_dtypes
         - maybe_get_index
@@ -28,6 +29,7 @@ Here are the top-level functions available in Narwhals.
         - mean
         - mean_horizontal
         - min
+        - min_horizontal
         - narwhalify
         - new_series
         - nth
diff --git a/narwhals/__init__.py b/narwhals/__init__.py
index 4f0b6ae8..124f10c4 100644
--- a/narwhals/__init__.py
+++ b/narwhals/__init__.py
@@ -34,9 +34,11 @@ from narwhals.expr import concat_str
 from narwhals.expr import len_ as len
 from narwhals.expr import lit
 from narwhals.expr import max
+from narwhals.expr import max_horizontal
 from narwhals.expr import mean
 from narwhals.expr import mean_horizontal
 from narwhals.expr import min
+from narwhals.expr import min_horizontal
 from narwhals.expr import nth
 from narwhals.expr import sum
 from narwhals.expr import sum_horizontal
@@ -84,10 +86,12 @@ __all__ = [
     "concat_str",
     "len",
     "lit",
-    "min",
     "max",
+    "max_horizontal",
     "mean",
     "mean_horizontal",
+    "min",
+    "min_horizontal",
     "nth",
     "sum",
     "sum_horizontal",
diff --git a/narwhals/_arrow/namespace.py b/narwhals/_arrow/namespace.py
index c514110f..5eae258f 100644
--- a/narwhals/_arrow/namespace.py
+++ b/narwhals/_arrow/namespace.py
@@ -237,6 +237,62 @@ class ArrowNamespace:
             output_names=reduce_output_names(parsed_exprs),
         )
 
+    def min_horizontal(self, *exprs: IntoArrowExpr) -> ArrowExpr:
+        import pyarrow.compute as pc  # ignore-banned-import
+
+        parsed_exprs = parse_into_exprs(*exprs, namespace=self)
+
+        def func(df: ArrowDataFrame) -> list[ArrowSeries]:
+            init_series, *series = [s for _expr in parsed_exprs for s in _expr._call(df)]
+            return [
+                ArrowSeries(
+                    native_series=reduce(
+                        lambda x, y: pc.min_element_wise(x, y),
+                        [s._native_series for s in series],
+                        init_series._native_series,
+                    ),
+                    name=init_series.name,
+                    backend_version=self._backend_version,
+                    dtypes=self._dtypes,
+                )
+            ]
+
+        return self._create_expr_from_callable(
+            func=func,
+            depth=max(x._depth for x in parsed_exprs) + 1,
+            function_name="min_horizontal",
+            root_names=combine_root_names(parsed_exprs),
+            output_names=reduce_output_names(parsed_exprs),
+        )
+
+    def max_horizontal(self, *exprs: IntoArrowExpr) -> ArrowExpr:
+        import pyarrow.compute as pc  # ignore-banned-import
+
+        parsed_exprs = parse_into_exprs(*exprs, namespace=self)
+
+        def func(df: ArrowDataFrame) -> list[ArrowSeries]:
+            init_series, *series = [s for _expr in parsed_exprs for s in _expr._call(df)]
+            return [
+                ArrowSeries(
+                    native_series=reduce(
+                        lambda x, y: pc.max_element_wise(x, y),
+                        [s._native_series for s in series],
+                        init_series._native_series,
+                    ),
+                    name=init_series.name,
+                    backend_version=self._backend_version,
+                    dtypes=self._dtypes,
+                )
+            ]
+
+        return self._create_expr_from_callable(
+            func=func,
+            depth=max(x._depth for x in parsed_exprs) + 1,
+            function_name="max_horizontal",
+            root_names=combine_root_names(parsed_exprs),
+            output_names=reduce_output_names(parsed_exprs),
+        )
+
     def concat(
         self,
         items: Iterable[ArrowDataFrame],
diff --git a/narwhals/_dask/namespace.py b/narwhals/_dask/namespace.py
index e0f2bbbd..23c133a1 100644
--- a/narwhals/_dask/namespace.py
+++ b/narwhals/_dask/namespace.py
@@ -232,7 +232,7 @@ class DaskNamespace:
             )
         raise NotImplementedError
 
-    def mean_horizontal(self, *exprs: IntoDaskExpr) -> IntoDaskExpr:
+    def mean_horizontal(self, *exprs: IntoDaskExpr) -> DaskExpr:
         parsed_exprs = parse_into_exprs(*exprs, namespace=self)
 
         def func(df: DaskLazyFrame) -> list[dask_expr.Series]:
@@ -256,6 +256,48 @@ class DaskNamespace:
             dtypes=self._dtypes,
         )
 
+    def min_horizontal(self, *exprs: IntoDaskExpr) -> DaskExpr:
+        import dask.dataframe as dd  # ignore-banned-import
+
+        parsed_exprs = parse_into_exprs(*exprs, namespace=self)
+
+        def func(df: DaskLazyFrame) -> list[dask_expr.Series]:
+            series = [s for _expr in parsed_exprs for s in _expr._call(df)]
+
+            return [dd.concat(series, axis=1).min(axis=1).rename(series[0].name)]
+
+        return DaskExpr(
+            call=func,
+            depth=max(x._depth for x in parsed_exprs) + 1,
+            function_name="min_horizontal",
+            root_names=combine_root_names(parsed_exprs),
+            output_names=reduce_output_names(parsed_exprs),
+            returns_scalar=False,
+            backend_version=self._backend_version,
+            dtypes=self._dtypes,
+        )
+
+    def max_horizontal(self, *exprs: IntoDaskExpr) -> DaskExpr:
+        import dask.dataframe as dd  # ignore-banned-import
+
+        parsed_exprs = parse_into_exprs(*exprs, namespace=self)
+
+        def func(df: DaskLazyFrame) -> list[dask_expr.Series]:
+            series = [s for _expr in parsed_exprs for s in _expr._call(df)]
+
+            return [dd.concat(series, axis=1).max(axis=1).rename(series[0].name)]
+
+        return DaskExpr(
+            call=func,
+            depth=max(x._depth for x in parsed_exprs) + 1,
+            function_name="max_horizontal",
+            root_names=combine_root_names(parsed_exprs),
+            output_names=reduce_output_names(parsed_exprs),
+            returns_scalar=False,
+            backend_version=self._backend_version,
+            dtypes=self._dtypes,
+        )
+
     def _create_expr_from_series(self, _: Any) -> NoReturn:
         msg = "`_create_expr_from_series` for DaskNamespace exists only for compatibility"
         raise NotImplementedError(msg)
diff --git a/narwhals/_duckdb/dataframe.py b/narwhals/_duckdb/dataframe.py
index 555555d4..5877ed51 100644
--- a/narwhals/_duckdb/dataframe.py
+++ b/narwhals/_duckdb/dataframe.py
@@ -4,9 +4,12 @@ import re
 from typing import TYPE_CHECKING
 from typing import Any
 
+from narwhals.dependencies import get_duckdb
 from narwhals.utils import parse_version
 
 if TYPE_CHECKING:
+    from types import ModuleType
+
     import pandas as pd
     import pyarrow as pa
     from typing_extensions import Self
@@ -68,6 +71,9 @@ class DuckDBInterchangeFrame:
     def __narwhals_dataframe__(self) -> Any:
         return self
 
+    def __native_namespace__(self: Self) -> ModuleType:
+        return get_duckdb()  # type: ignore[no-any-return]
+
     def __getitem__(self, item: str) -> DuckDBInterchangeSeries:
         from narwhals._duckdb.series import DuckDBInterchangeSeries
 
diff --git a/narwhals/_duckdb/series.py b/narwhals/_duckdb/series.py
index a7dbdd54..e30b14ac 100644
--- a/narwhals/_duckdb/series.py
+++ b/narwhals/_duckdb/series.py
@@ -4,8 +4,11 @@ from typing import TYPE_CHECKING
 from typing import Any
 
 from narwhals._duckdb.dataframe import map_duckdb_dtype_to_narwhals_dtype
+from narwhals.dependencies import get_duckdb
 
 if TYPE_CHECKING:
+    from types import ModuleType
+
     from narwhals.typing import DTypes
 
 
@@ -17,6 +20,9 @@ class DuckDBInterchangeSeries:
     def __narwhals_series__(self) -> Any:
         return self
 
+    def __native_namespace__(self) -> ModuleType:
+        return get_duckdb()  # type: ignore[no-any-return]
+
     def __getattr__(self, attr: str) -> Any:
         if attr == "dtype":
             return map_duckdb_dtype_to_narwhals_dtype(
diff --git a/narwhals/_ibis/dataframe.py b/narwhals/_ibis/dataframe.py
index 8ee01e78..9d7ebefb 100644
--- a/narwhals/_ibis/dataframe.py
+++ b/narwhals/_ibis/dataframe.py
@@ -3,7 +3,11 @@ from __future__ import annotations
 from typing import TYPE_CHECKING
 from typing import Any
 
+from narwhals.dependencies import get_ibis
+
 if TYPE_CHECKING:
+    from types import ModuleType
+
     import pandas as pd
     import pyarrow as pa
     from typing_extensions import Self
@@ -59,6 +63,9 @@ class IbisInterchangeFrame:
     def __narwhals_dataframe__(self) -> Any:
         return self
 
+    def __native_namespace__(self: Self) -> ModuleType:
+        return get_ibis()  # type: ignore[no-any-return]
+
     def __getitem__(self, item: str) -> IbisInterchangeSeries:
         from narwhals._ibis.series import IbisInterchangeSeries
 
diff --git a/narwhals/_ibis/series.py b/narwhals/_ibis/series.py
index 2f6cd6fa..e2c31369 100644
--- a/narwhals/_ibis/series.py
+++ b/narwhals/_ibis/series.py
@@ -4,8 +4,11 @@ from typing import TYPE_CHECKING
 from typing import Any
 
 from narwhals._ibis.dataframe import map_ibis_dtype_to_narwhals_dtype
+from narwhals.dependencies import get_ibis
 
 if TYPE_CHECKING:
+    from types import ModuleType
+
     from narwhals.typing import DTypes
 
 
@@ -17,6 +20,9 @@ class IbisInterchangeSeries:
     def __narwhals_series__(self) -> Any:
         return self
 
+    def __native_namespace__(self) -> ModuleType:
+        return get_ibis()  # type: ignore[no-any-return]
+
     def __getattr__(self, attr: str) -> Any:
         if attr == "dtype":
             return map_ibis_dtype_to_narwhals_dtype(
diff --git a/narwhals/_interchange/dataframe.py b/narwhals/_interchange/dataframe.py
index 1dc671dc..4e8e542e 100644
--- a/narwhals/_interchange/dataframe.py
+++ b/narwhals/_interchange/dataframe.py
@@ -82,6 +82,14 @@ class InterchangeFrame:
     def __narwhals_dataframe__(self) -> Any:
         return self
 
+    def __native_namespace__(self: Self) -> NoReturn:
+        msg = (
+            "Cannot access native namespace for metadata-only dataframes with unknown backend."
+            "If you would like to see this kind of object supported in Narwhals, please "
+            "open a feature request at https://github.com/narwhals-dev/narwhals/issues."
+        )
+        raise NotImplementedError(msg)
+
     def __getitem__(self, item: str) -> InterchangeSeries:
         from narwhals._interchange.series import InterchangeSeries
 
diff --git a/narwhals/_interchange/series.py b/narwhals/_interchange/series.py
index 00426e6c..a9cf41f0 100644
--- a/narwhals/_interchange/series.py
+++ b/narwhals/_interchange/series.py
@@ -2,6 +2,7 @@ from __future__ import annotations
 
 from typing import TYPE_CHECKING
 from typing import Any
+from typing import NoReturn
 
 from narwhals._interchange.dataframe import map_interchange_dtype_to_narwhals_dtype
 
@@ -17,6 +18,14 @@ class InterchangeSeries:
     def __narwhals_series__(self) -> Any:
         return self
 
+    def __native_namespace__(self) -> NoReturn:
+        msg = (
+            "Cannot access native namespace for metadata-only series with unknown backend. "
+            "If you would like to see this kind of object supported in Narwhals, please "
+            "open a feature request at https://github.com/narwhals-dev/narwhals/issues."
+        )
+        raise NotImplementedError(msg)
+
     def __getattr__(self, attr: str) -> Any:
         if attr == "dtype":
             return map_interchange_dtype_to_narwhals_dtype(
diff --git a/narwhals/_pandas_like/namespace.py b/narwhals/_pandas_like/namespace.py
index 8f6e1751..63d3454a 100644
--- a/narwhals/_pandas_like/namespace.py
+++ b/narwhals/_pandas_like/namespace.py
@@ -278,6 +278,60 @@ class PandasLikeNamespace:
             output_names=reduce_output_names(parsed_exprs),
         )
 
+    def min_horizontal(self, *exprs: IntoPandasLikeExpr) -> PandasLikeExpr:
+        parsed_exprs = parse_into_exprs(*exprs, namespace=self)
+
+        def func(df: PandasLikeDataFrame) -> list[PandasLikeSeries]:
+            series = [s for _expr in parsed_exprs for s in _expr._call(df)]
+
+            return [
+                PandasLikeSeries(
+                    native_series=self.concat(
+                        (s.to_frame() for s in series), how="horizontal"
+                    )
+                    ._native_frame.min(axis=1)
+                    .rename(series[0].name),
+                    implementation=self._implementation,
+                    backend_version=self._backend_version,
+                    dtypes=self._dtypes,
+                )
+            ]
+
+        return self._create_expr_from_callable(
+            func=func,
+            depth=max(x._depth for x in parsed_exprs) + 1,
+            function_name="min_horizontal",
+            root_names=combine_root_names(parsed_exprs),
+            output_names=reduce_output_names(parsed_exprs),
+        )
+
+    def max_horizontal(self, *exprs: IntoPandasLikeExpr) -> PandasLikeExpr:
+        parsed_exprs = parse_into_exprs(*exprs, namespace=self)
+
+        def func(df: PandasLikeDataFrame) -> list[PandasLikeSeries]:
+            series = [s for _expr in parsed_exprs for s in _expr._call(df)]
+
+            return [
+                PandasLikeSeries(
+                    native_series=self.concat(
+                        (s.to_frame() for s in series), how="horizontal"
+                    )
+                    ._native_frame.max(axis=1)
+                    .rename(series[0].name),
+                    implementation=self._implementation,
+                    backend_version=self._backend_version,
+                    dtypes=self._dtypes,
+                )
+            ]
+
+        return self._create_expr_from_callable(
+            func=func,
+            depth=max(x._depth for x in parsed_exprs) + 1,
+            function_name="max_horizontal",
+            root_names=combine_root_names(parsed_exprs),
+            output_names=reduce_output_names(parsed_exprs),
+        )
+
     def concat(
         self,
         items: Iterable[PandasLikeDataFrame],
diff --git a/narwhals/expr.py b/narwhals/expr.py
index abf9c104..edd52b30 100644
--- a/narwhals/expr.py
+++ b/narwhals/expr.py
@@ -4221,6 +4221,132 @@ def sum_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr:
     )
 
 
+def min_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr:
+    """
+    Get the minimum value horizontally across columns.
+
+    Notes:
+        We support `min_horizontal` over numeric columns only.
+
+    Arguments:
+        exprs: Name(s) of the columns to use in the aggregation function. Accepts
+            expression input.
+
+    Examples:
+        >>> import narwhals as nw
+        >>> import pandas as pd
+        >>> import polars as pl
+        >>> import pyarrow as pa
+        >>> data = {
+        ...     "a": [1, 8, 3],
+        ...     "b": [4, 5, None],
+        ...     "c": ["x", "y", "z"],
+        ... }
+
+        We define a dataframe-agnostic function that computes the horizontal min of "a"
+        and "b" columns:
+
+        >>> @nw.narwhalify
+        ... def func(df):
+        ...     return df.select(nw.min_horizontal("a", "b"))
+
+        We can then pass either pandas, polars or pyarrow to `func`:
+
+        >>> func(pd.DataFrame(data))
+             a
+        0  1.0
+        1  5.0
+        2  3.0
+        >>> func(pl.DataFrame(data))
+        shape: (3, 1)
+        ┌─────┐
+        │ a   │
+        │ --- │
+        │ i64 │
+        ╞═════╡
+        │ 1   │
+        │ 5   │
+        │ 3   │
+        └─────┘
+        >>> func(pa.table(data))
+        pyarrow.Table
+        a: int64
+        ----
+        a: [[1,5,3]]
+    """
+    if not exprs:
+        msg = "At least one expression must be passed to `min_horizontal`"
+        raise ValueError(msg)
+    return Expr(
+        lambda plx: plx.min_horizontal(
+            *[extract_compliant(plx, v) for v in flatten(exprs)]
+        )
+    )
+
+
+def max_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr:
+    """
+    Get the maximum value horizontally across columns.
+
+    Notes:
+        We support `max_horizontal` over numeric columns only.
+
+    Arguments:
+        exprs: Name(s) of the columns to use in the aggregation function. Accepts
+            expression input.
+
+    Examples:
+        >>> import narwhals as nw
+        >>> import pandas as pd
+        >>> import polars as pl
+        >>> import pyarrow as pa
+        >>> data = {
+        ...     "a": [1, 8, 3],
+        ...     "b": [4, 5, None],
+        ...     "c": ["x", "y", "z"],
+        ... }
+
+        We define a dataframe-agnostic function that computes the horizontal max of "a"
+        and "b" columns:
+
+        >>> @nw.narwhalify
+        ... def func(df):
+        ...     return df.select(nw.max_horizontal("a", "b"))
+
+        We can then pass either pandas, polars or pyarrow to `func`:
+
+        >>> func(pd.DataFrame(data))
+             a
+        0  4.0
+        1  8.0
+        2  3.0
+        >>> func(pl.DataFrame(data))
+        shape: (3, 1)
+        ┌─────┐
+        │ a   │
+        │ --- │
+        │ i64 │
+        ╞═════╡
+        │ 4   │
+        │ 8   │
+        │ 3   │
+        └─────┘
+        >>> func(pa.table(data))
+        pyarrow.Table
+        a: int64
+        ----
+        a: [[4,8,3]]
+    """
+    if not exprs:
+        msg = "At least one expression must be passed to `max_horizontal`"
+        raise ValueError(msg)
+    return Expr(
+        lambda plx: plx.max_horizontal(
+            *[extract_compliant(plx, v) for v in flatten(exprs)]
+        )
+    )
+
+
 class When:
     def __init__(self, *predicates: IntoExpr | Iterable[IntoExpr]) -> None:
         self._predicates = flatten([predicates])
diff --git a/narwhals/stable/v1/__init__.py b/narwhals/stable/v1/__init__.py
index 1c3a3bd1..e9aac4cf 100644
--- a/narwhals/stable/v1/__init__.py
+++ b/narwhals/stable/v1/__init__.py
@@ -1527,6 +1527,118 @@ def mean_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr:
     return _stableify(nw.mean_horizontal(*exprs))
 
 
+def min_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr:
+    """
+    Get the minimum value horizontally across columns.
+
+    Notes:
+        We support `min_horizontal` over numeric columns only.
+
+    Arguments:
+        exprs: Name(s) of the columns to use in the aggregation function. Accepts
+            expression input.
+
+    Examples:
+        >>> import narwhals.stable.v1 as nw
+        >>> import pandas as pd
+        >>> import polars as pl
+        >>> import pyarrow as pa
+        >>> data = {
+        ...     "a": [1, 8, 3],
+        ...     "b": [4, 5, None],
+        ...     "c": ["x", "y", "z"],
+        ... }
+
+        We define a dataframe-agnostic function that computes the horizontal min of "a"
+        and "b" columns:
+
+        >>> @nw.narwhalify
+        ... def func(df):
+        ...     return df.select(nw.min_horizontal("a", "b"))
+
+        We can then pass either pandas, polars or pyarrow to `func`:
+
+        >>> func(pd.DataFrame(data))
+             a
+        0  1.0
+        1  5.0
+        2  3.0
+        >>> func(pl.DataFrame(data))
+        shape: (3, 1)
+        ┌─────┐
+        │ a   │
+        │ --- │
+        │ i64 │
+        ╞═════╡
+        │ 1   │
+        │ 5   │
+        │ 3   │
+        └─────┘
+        >>> func(pa.table(data))
+        pyarrow.Table
+        a: int64
+        ----
+        a: [[1,5,3]]
+    """
+    return _stableify(nw.min_horizontal(*exprs))
+
+
+def max_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr:
+    """
+    Get the maximum value horizontally across columns.
+
+    Notes:
+        We support `max_horizontal` over numeric columns only.
+
+    Arguments:
+        exprs: Name(s) of the columns to use in the aggregation function. Accepts
+            expression input.
+
+    Examples:
+        >>> import narwhals.stable.v1 as nw
+        >>> import pandas as pd
+        >>> import polars as pl
+        >>> import pyarrow as pa
+        >>> data = {
+        ...     "a": [1, 8, 3],
+        ...     "b": [4, 5, None],
+        ...     "c": ["x", "y", "z"],
+        ... }
+
+        We define a dataframe-agnostic function that computes the horizontal max of "a"
+        and "b" columns:
+
+        >>> @nw.narwhalify
+        ... def func(df):
+        ...     return df.select(nw.max_horizontal("a", "b"))
+
+        We can then pass either pandas, polars or pyarrow to `func`:
+
+        >>> func(pd.DataFrame(data))
+             a
+        0  4.0
+        1  8.0
+        2  3.0
+        >>> func(pl.DataFrame(data))
+        shape: (3, 1)
+        ┌─────┐
+        │ a   │
+        │ --- │
+        │ i64 │
+        ╞═════╡
+        │ 4   │
+        │ 8   │
+        │ 3   │
+        └─────┘
+        >>> func(pa.table(data))
+        pyarrow.Table
+        a: int64
+        ----
+        a: [[4,8,3]]
+    """
+    return _stableify(nw.max_horizontal(*exprs))
+
+
 @overload
 def concat(
     items: Iterable[DataFrame[Any]],
@@ -2153,10 +2265,12 @@ __all__ = [
     "nth",
     "len",
     "lit",
-    "min",
     "max",
+    "max_horizontal",
     "mean",
     "mean_horizontal",
+    "min",
+    "min_horizontal",
     "sum",
     "sum_horizontal",
     "when",
diff --git a/narwhals/this.py b/narwhals/this.py
new file mode 100644
index 00000000..541ee770
--- /dev/null
+++ b/narwhals/this.py
@@ -0,0 +1,17 @@
+# ruff: noqa
+ZEN = """\
+⣿⣿⣿⣿⣿⠘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ THE ZEN OF NARWHALS
+⣿⣿⣿⣿⣿⠠⢹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ Keep it simple
+⣿⣿⣿⣿⣿⡀⡄⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ Move slowly and keep things working
+⣿⣿⣿⣿⣿⡇⡼⡘⠛⠿⠿⠿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ A good API is an honest one
+⣿⣿⣿⡿⣫⡄⠾⣣⠹⣿⣿⣿⣶⣮⣙⠻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ Yes, that needs documenting
+⣿⣿⢋⣴⣿⣷⣬⣭⣾⣿⣿⣿⣿⣿⣿⣿⣦⡙⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ People learn better from examples
+⣿⢃⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡌⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ than from explanations⠀
+⡏⠀⢰⠄⢻⣿⣿⣿⣿⡿⠋⢉⠻⣿⣿⣿⣿⣿⣿⡜⣿⣿⡿⢁⢻⣿⣿⣿⣿⣿ If in doubt, say 'no'⠀
+⡇⣌⣀⣠⣾⣿⣿⣿⣿⣇⠶⠉⢁⣿⣿⣿⣿⣿⣿⣧⡹⣿⡇⣿⣧⠻⠿⠿⠿⠿ you can always reconsider⠀
+⡧⢹⣿⣿⣿⣜⣟⣸⣿⣿⣷⣶⣿⡿⣿⣿⣝⢿⣿⣿⣷⣬⣥⣿⣿⣿⣿⣿⡟⣰ Yes, we need a test for that
+⢡⣆⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⡙⣿⣿⡇⣿⣿⣿⣿⠟⣋⣭⣛⠻⣋⣴⣿ If you want users  
+⣶⣤⣤⣙⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣦⣍⣡⣿⡿⢋⣴⣿⣿⣿⣿⣿⣿⣿⣿ you need good docs⠀
+⣿⣿⣿⣿⣿⣶⣬⣙⣛⠻⠿⠿⠿⠿⠿⠟⣛⣩⣥⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ Our code is not irreplaceable"""
+
+print(ZEN)
diff --git a/pyproject.toml b/pyproject.toml
index 5c1e6f96..c4974d8c 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -130,6 +130,7 @@ plugins = ["covdefaults"]
 omit = [
   'narwhals/typing.py',
   'narwhals/stable/v1/typing.py',
+  'narwhals/this.py',
   # we can run this in every environment that we measure coverage on due to upper-bound constraits
   'narwhals/_ibis/*',
 ]
diff --git a/tpch/notebooks/q1/execute.ipynb b/tpch/notebooks/q1/execute.ipynb
deleted file mode 100755
index de9c52ba..00000000
--- a/tpch/notebooks/q1/execute.ipynb
+++ /dev/null
@@ -1,441 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "0",
-   "metadata": {
-    "papermill": {
-     "duration": 33.390992,
-     "end_time": "2024-03-22T17:24:15.601719",
-     "exception": false,
-     "start_time": "2024-03-22T17:23:42.210727",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "!pip uninstall apache-beam -y && pip install -U pandas polars pyarrow narwhals dask[dataframe]"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "1",
-   "metadata": {
-    "papermill": {
-     "duration": 0.907754,
-     "end_time": "2024-03-22T17:24:39.053873",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:38.146119",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "import pandas as pd\n",
-    "import polars as pl\n",
-    "\n",
-    "pd.options.mode.copy_on_write = True\n",
-    "pd.options.future.infer_string = True"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "2",
-   "metadata": {
-    "papermill": {
-     "duration": 0.021725,
-     "end_time": "2024-03-22T17:24:39.080999",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.059274",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "from datetime import datetime\n",
-    "from typing import Any\n",
-    "\n",
-    "import narwhals as nw\n",
-    "\n",
-    "\n",
-    "@nw.narwhalify\n",
-    "def q1(lineitem_ds: Any) -> Any:\n",
-    "    var_1 = datetime(1998, 9, 2)\n",
-    "    return (\n",
-    "        lineitem_ds.filter(nw.col(\"l_shipdate\") <= var_1)\n",
-    "        .with_columns(\n",
-    "            disc_price=nw.col(\"l_extendedprice\") * (1 - nw.col(\"l_discount\")),\n",
-    "            charge=(\n",
-    "                nw.col(\"l_extendedprice\")\n",
-    "                * (1.0 - nw.col(\"l_discount\"))\n",
-    "                * (1.0 + nw.col(\"l_tax\"))\n",
-    "            ),\n",
-    "        )\n",
-    "        .group_by(\"l_returnflag\", \"l_linestatus\")\n",
-    "        .agg(\n",
-    "            nw.col(\"l_quantity\").sum().alias(\"sum_qty\"),\n",
-    "            nw.col(\"l_extendedprice\").sum().alias(\"sum_base_price\"),\n",
-    "            nw.col(\"disc_price\").sum().alias(\"sum_disc_price\"),\n",
-    "            nw.col(\"charge\").sum().alias(\"sum_charge\"),\n",
-    "            nw.col(\"l_quantity\").mean().alias(\"avg_qty\"),\n",
-    "            nw.col(\"l_extendedprice\").mean().alias(\"avg_price\"),\n",
-    "            nw.col(\"l_discount\").mean().alias(\"avg_disc\"),\n",
-    "            nw.len().alias(\"count_order\"),\n",
-    "        )\n",
-    "        .sort(\"l_returnflag\", \"l_linestatus\")\n",
-    "    )"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "3",
-   "metadata": {
-    "papermill": {
-     "duration": 0.013325,
-     "end_time": "2024-03-22T17:24:39.099766",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.086441",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "dir_ = \"/kaggle/input/tpc-h-data-parquet-s-2/\"\n",
-    "region = dir_ + \"region.parquet\"\n",
-    "nation = dir_ + \"nation.parquet\"\n",
-    "customer = dir_ + \"customer.parquet\"\n",
-    "lineitem = dir_ + \"lineitem.parquet\"\n",
-    "orders = dir_ + \"orders.parquet\"\n",
-    "supplier = dir_ + \"supplier.parquet\"\n",
-    "part = dir_ + \"part.parquet\"\n",
-    "partsupp = dir_ + \"partsupp.parquet\""
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "4",
-   "metadata": {
-    "papermill": {
-     "duration": 0.014284,
-     "end_time": "2024-03-22T17:24:39.119737",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.105453",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "import dask.dataframe as dd\n",
-    "import pyarrow.parquet as pq\n",
-    "\n",
-    "IO_FUNCS = {\n",
-    "    \"pandas\": lambda x: pd.read_parquet(x, engine=\"pyarrow\"),\n",
-    "    \"pandas[pyarrow]\": lambda x: pd.read_parquet(\n",
-    "        x, engine=\"pyarrow\", dtype_backend=\"pyarrow\"\n",
-    "    ),\n",
-    "    \"polars[eager]\": lambda x: pl.read_parquet(x),\n",
-    "    \"polars[lazy]\": lambda x: pl.scan_parquet(x),\n",
-    "    \"pyarrow\": lambda x: pq.read_table(x),\n",
-    "    \"dask\": lambda x: dd.read_parquet(x, engine=\"pyarrow\", dtype_backend=\"pyarrow\"),\n",
-    "}"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "5",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "results = {}"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "6",
-   "metadata": {},
-   "source": [
-    "## PyArrow.table"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "7",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "tool = \"pyarrow\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q1(fn(lineitem))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "8",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005113,
-     "end_time": "2024-03-22T17:24:39.130472",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.125359",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## pandas"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "9",
-   "metadata": {
-    "papermill": {
-     "duration": 196.786925,
-     "end_time": "2024-03-22T17:27:55.922832",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.135907",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"pandas\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q1(lineitem_ds=fn(lineitem))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "10",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005184,
-     "end_time": "2024-03-22T17:27:55.933407",
-     "exception": false,
-     "start_time": "2024-03-22T17:27:55.928223",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## pandas, pyarrow dtypes"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "11",
-   "metadata": {
-    "papermill": {
-     "duration": 158.748353,
-     "end_time": "2024-03-22T17:30:34.688289",
-     "exception": false,
-     "start_time": "2024-03-22T17:27:55.939936",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"pandas[pyarrow]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q1(fn(lineitem))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "12",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005773,
-     "end_time": "2024-03-22T17:30:34.700300",
-     "exception": false,
-     "start_time": "2024-03-22T17:30:34.694527",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## Polars read_parquet"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "13",
-   "metadata": {
-    "papermill": {
-     "duration": 37.821116,
-     "end_time": "2024-03-22T17:31:12.527466",
-     "exception": false,
-     "start_time": "2024-03-22T17:30:34.706350",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"polars[eager]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q1(fn(lineitem))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "14",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005515,
-     "end_time": "2024-03-22T17:31:12.539068",
-     "exception": false,
-     "start_time": "2024-03-22T17:31:12.533553",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## Polars scan_parquet"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "15",
-   "metadata": {
-    "papermill": {
-     "duration": 4.800698,
-     "end_time": "2024-03-22T17:31:17.346813",
-     "exception": false,
-     "start_time": "2024-03-22T17:31:12.546115",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"polars[lazy]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q1(fn(lineitem)).collect()\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "16",
-   "metadata": {},
-   "source": [
-    "## Dask Dataframe"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "17",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "tool = \"dask\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q1(fn(lineitem)).collect()\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "18",
-   "metadata": {},
-   "source": [
-    "## Save"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "19",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "import json\n",
-    "\n",
-    "with open(\"results.json\", \"w\") as fd:\n",
-    "    json.dump(results, fd)"
-   ]
-  }
- ],
- "metadata": {
-  "kaggle": {
-   "accelerator": "none",
-   "dataSources": [
-    {
-     "sourceId": 167796716,
-     "sourceType": "kernelVersion"
-    },
-    {
-     "sourceId": 167796934,
-     "sourceType": "kernelVersion"
-    },
-    {
-     "sourceId": 167796952,
-     "sourceType": "kernelVersion"
-    },
-    {
-     "sourceId": 167796969,
-     "sourceType": "kernelVersion"
-    }
-   ],
-   "isGpuEnabled": false,
-   "isInternetEnabled": true,
-   "language": "python",
-   "sourceType": "notebook"
-  },
-  "kernelspec": {
-   "display_name": "Python 3",
-   "language": "python",
-   "name": "python3"
-  },
-  "language_info": {
-   "codemirror_mode": {
-    "name": "ipython",
-    "version": 3
-   },
-   "file_extension": ".py",
-   "mimetype": "text/x-python",
-   "name": "python",
-   "nbconvert_exporter": "python",
-   "pygments_lexer": "ipython3",
-   "version": "3.11.9"
-  },
-  "papermill": {
-   "default_parameters": {},
-   "duration": 458.423327,
-   "end_time": "2024-03-22T17:31:18.077306",
-   "environment_variables": {},
-   "exception": null,
-   "input_path": "__notebook__.ipynb",
-   "output_path": "__notebook__.ipynb",
-   "parameters": {},
-   "start_time": "2024-03-22T17:23:39.653979",
-   "version": "2.5.0"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 5
-}
diff --git a/tpch/notebooks/q1/kernel-metadata.json b/tpch/notebooks/q1/kernel-metadata.json
deleted file mode 100644
index 6aa41f66..00000000
--- a/tpch/notebooks/q1/kernel-metadata.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "id": "marcogorelli/narwhals-tpch-q1-s2",
-  "title": "Narwhals TPCH Q1 S2",
-  "code_file": "execute.ipynb",
-  "language": "python",
-  "kernel_type": "notebook",
-  "is_private": "false",
-  "enable_gpu": "false",
-  "enable_tpu": "false",
-  "enable_internet": "true",
-  "dataset_sources": [],
-  "competition_sources": [],
-  "kernel_sources": ["marcogorelli/tpc-h-data-parquet-s-2"],
-  "model_sources": []
-}
\ No newline at end of file
diff --git a/tpch/notebooks/q10/execute.ipynb b/tpch/notebooks/q10/execute.ipynb
deleted file mode 100644
index 9ff21177..00000000
--- a/tpch/notebooks/q10/execute.ipynb
+++ /dev/null
@@ -1,385 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 33.390992,
-     "end_time": "2024-03-22T17:24:15.601719",
-     "exception": false,
-     "start_time": "2024-03-22T17:23:42.210727",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "!pip uninstall apache-beam -y && pip install -U pandas polars pyarrow narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 0.907754,
-     "end_time": "2024-03-22T17:24:39.053873",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:38.146119",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "import pandas as pd\n",
-    "import polars as pl\n",
-    "\n",
-    "pd.options.mode.copy_on_write = True\n",
-    "pd.options.future.infer_string = True"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 0.021725,
-     "end_time": "2024-03-22T17:24:39.080999",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.059274",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "from datetime import datetime\n",
-    "from typing import Any\n",
-    "\n",
-    "import narwhals as nw\n",
-    "\n",
-    "\n",
-    "def q10(\n",
-    "    customer_ds_raw: Any,\n",
-    "    nation_ds_raw: Any,\n",
-    "    lineitem_ds_raw: Any,\n",
-    "    orders_ds_raw: Any,\n",
-    ") -> Any:\n",
-    "    nation_ds = nw.from_native(nation_ds_raw)\n",
-    "    line_item_ds = nw.from_native(lineitem_ds_raw)\n",
-    "    orders_ds = nw.from_native(orders_ds_raw)\n",
-    "    customer_ds = nw.from_native(customer_ds_raw)\n",
-    "\n",
-    "    var1 = datetime(1993, 10, 1)\n",
-    "    var2 = datetime(1994, 1, 1)\n",
-    "\n",
-    "    result = (\n",
-    "        customer_ds.join(orders_ds, left_on=\"c_custkey\", right_on=\"o_custkey\")\n",
-    "        .join(line_item_ds, left_on=\"o_orderkey\", right_on=\"l_orderkey\")\n",
-    "        .join(nation_ds, left_on=\"c_nationkey\", right_on=\"n_nationkey\")\n",
-    "        .filter(nw.col(\"o_orderdate\").is_between(var1, var2, closed=\"left\"))\n",
-    "        .filter(nw.col(\"l_returnflag\") == \"R\")\n",
-    "        .with_columns(\n",
-    "            (nw.col(\"l_extendedprice\") * (1 - nw.col(\"l_discount\"))).alias(\"revenue\")\n",
-    "        )\n",
-    "        .group_by(\n",
-    "            \"c_custkey\",\n",
-    "            \"c_name\",\n",
-    "            \"c_acctbal\",\n",
-    "            \"c_phone\",\n",
-    "            \"n_name\",\n",
-    "            \"c_address\",\n",
-    "            \"c_comment\",\n",
-    "        )\n",
-    "        .agg(nw.sum(\"revenue\"))\n",
-    "        .select(\n",
-    "            \"c_custkey\",\n",
-    "            \"c_name\",\n",
-    "            \"revenue\",\n",
-    "            \"c_acctbal\",\n",
-    "            \"n_name\",\n",
-    "            \"c_address\",\n",
-    "            \"c_phone\",\n",
-    "            \"c_comment\",\n",
-    "        )\n",
-    "        .sort(by=\"revenue\", descending=True)\n",
-    "        .head(20)\n",
-    "    )\n",
-    "\n",
-    "    return nw.to_native(result)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 0.013325,
-     "end_time": "2024-03-22T17:24:39.099766",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.086441",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "dir_ = \"/kaggle/input/tpc-h-data-parquet-s-2/\"\n",
-    "nation = dir_ + \"nation.parquet\"\n",
-    "lineitem = dir_ + \"lineitem.parquet\"\n",
-    "orders = dir_ + \"orders.parquet\"\n",
-    "customer = dir_ + \"customer.parquet\""
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 0.014284,
-     "end_time": "2024-03-22T17:24:39.119737",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.105453",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "IO_FUNCS = {\n",
-    "    \"pandas\": lambda x: pd.read_parquet(x, engine=\"pyarrow\"),\n",
-    "    \"pandas[pyarrow]\": lambda x: pd.read_parquet(\n",
-    "        x, engine=\"pyarrow\", dtype_backend=\"pyarrow\"\n",
-    "    ),\n",
-    "    \"polars[eager]\": lambda x: pl.read_parquet(x),\n",
-    "    \"polars[lazy]\": lambda x: pl.scan_parquet(x),\n",
-    "}"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "results = {}"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005113,
-     "end_time": "2024-03-22T17:24:39.130472",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.125359",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## pandas via Narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 196.786925,
-     "end_time": "2024-03-22T17:27:55.922832",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.135907",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"pandas\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q10(fn(customer), fn(nation), fn(lineitem), fn(orders))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005184,
-     "end_time": "2024-03-22T17:27:55.933407",
-     "exception": false,
-     "start_time": "2024-03-22T17:27:55.928223",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## pandas, pyarrow dtypes, via Narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 158.748353,
-     "end_time": "2024-03-22T17:30:34.688289",
-     "exception": false,
-     "start_time": "2024-03-22T17:27:55.939936",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"pandas[pyarrow]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q10(fn(customer), fn(nation), fn(lineitem), fn(orders))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005773,
-     "end_time": "2024-03-22T17:30:34.7003",
-     "exception": false,
-     "start_time": "2024-03-22T17:30:34.694527",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## Polars read_parquet"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 37.821116,
-     "end_time": "2024-03-22T17:31:12.527466",
-     "exception": false,
-     "start_time": "2024-03-22T17:30:34.70635",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"polars[eager]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q10(fn(customer), fn(nation), fn(lineitem), fn(orders))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005515,
-     "end_time": "2024-03-22T17:31:12.539068",
-     "exception": false,
-     "start_time": "2024-03-22T17:31:12.533553",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## Polars scan_parquet"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 4.800698,
-     "end_time": "2024-03-22T17:31:17.346813",
-     "exception": false,
-     "start_time": "2024-03-22T17:31:12.546115",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"polars[lazy]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q10(fn(customer), fn(nation), fn(lineitem), fn(orders)).collect()\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## Save"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "import json\n",
-    "\n",
-    "with open(\"results.json\", \"w\") as fd:\n",
-    "    json.dump(results, fd)"
-   ]
-  }
- ],
- "metadata": {
-  "kaggle": {
-   "accelerator": "none",
-   "dataSources": [
-    {
-     "sourceId": 167796934,
-     "sourceType": "kernelVersion"
-    }
-   ],
-   "dockerImageVersionId": 30673,
-   "isGpuEnabled": false,
-   "isInternetEnabled": true,
-   "language": "python",
-   "sourceType": "notebook"
-  },
-  "kernelspec": {
-   "display_name": "Python 3",
-   "language": "python",
-   "name": "python3"
-  },
-  "language_info": {
-   "codemirror_mode": {
-    "name": "ipython",
-    "version": 3
-   },
-   "file_extension": ".py",
-   "mimetype": "text/x-python",
-   "name": "python",
-   "nbconvert_exporter": "python",
-   "pygments_lexer": "ipython3",
-   "version": "3.10.13"
-  },
-  "papermill": {
-   "default_parameters": {},
-   "duration": 458.423327,
-   "end_time": "2024-03-22T17:31:18.077306",
-   "environment_variables": {},
-   "exception": null,
-   "input_path": "__notebook__.ipynb",
-   "output_path": "__notebook__.ipynb",
-   "parameters": {},
-   "start_time": "2024-03-22T17:23:39.653979",
-   "version": "2.5.0"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/tpch/notebooks/q10/kernel-metadata.json b/tpch/notebooks/q10/kernel-metadata.json
deleted file mode 100644
index 5fa48ff5..00000000
--- a/tpch/notebooks/q10/kernel-metadata.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "id": "marcogorelli/narwhals-tpch-q10-s2",
-  "title": "Narwhals TPCH Q10 S2",
-  "code_file": "execute.ipynb",
-  "language": "python",
-  "kernel_type": "notebook",
-  "is_private": "false",
-  "enable_gpu": "false",
-  "enable_tpu": "false",
-  "enable_internet": "true",
-  "dataset_sources": [],
-  "competition_sources": [],
-  "kernel_sources": ["marcogorelli/tpc-h-data-parquet-s-2"],
-  "model_sources": []
-}
\ No newline at end of file
diff --git a/tpch/notebooks/q11/execute.ipynb b/tpch/notebooks/q11/execute.ipynb
deleted file mode 100644
index f5bbc0f9..00000000
--- a/tpch/notebooks/q11/execute.ipynb
+++ /dev/null
@@ -1,379 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 33.390992,
-     "end_time": "2024-03-22T17:24:15.601719",
-     "exception": false,
-     "start_time": "2024-03-22T17:23:42.210727",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "!pip uninstall apache-beam -y && pip install -U pandas polars pyarrow narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 0.907754,
-     "end_time": "2024-03-22T17:24:39.053873",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:38.146119",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "import pandas as pd\n",
-    "import polars as pl\n",
-    "\n",
-    "pd.options.mode.copy_on_write = True\n",
-    "pd.options.future.infer_string = True"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 0.021725,
-     "end_time": "2024-03-22T17:24:39.080999",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.059274",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "from typing import Any\n",
-    "\n",
-    "import narwhals as nw\n",
-    "\n",
-    "\n",
-    "def q11(\n",
-    "    partsupp_ds_raw: Any,\n",
-    "    nation_ds_raw: Any,\n",
-    "    supplier_ds_raw: Any,\n",
-    ") -> Any:\n",
-    "    nation_ds = nw.from_native(nation_ds_raw)\n",
-    "    partsupp_ds = nw.from_native(partsupp_ds_raw)\n",
-    "    supplier_ds = nw.from_native(supplier_ds_raw)\n",
-    "\n",
-    "    var1 = \"GERMANY\"\n",
-    "    var2 = 0.0001\n",
-    "\n",
-    "    q1 = (\n",
-    "        partsupp_ds.join(supplier_ds, left_on=\"ps_suppkey\", right_on=\"s_suppkey\")\n",
-    "        .join(nation_ds, left_on=\"s_nationkey\", right_on=\"n_nationkey\")\n",
-    "        .filter(nw.col(\"n_name\") == var1)\n",
-    "    )\n",
-    "    q2 = q1.select(\n",
-    "        (nw.col(\"ps_supplycost\") * nw.col(\"ps_availqty\")).sum().round(2).alias(\"tmp\")\n",
-    "        * var2\n",
-    "    )\n",
-    "\n",
-    "    q_final = (\n",
-    "        q1.with_columns((nw.col(\"ps_supplycost\") * nw.col(\"ps_availqty\")).alias(\"value\"))\n",
-    "        .group_by(\"ps_partkey\")\n",
-    "        .agg(nw.sum(\"value\"))\n",
-    "        .join(q2, how=\"cross\")\n",
-    "        .filter(nw.col(\"value\") > nw.col(\"tmp\"))\n",
-    "        .select(\"ps_partkey\", \"value\")\n",
-    "        .sort(\"value\", descending=True)\n",
-    "    )\n",
-    "\n",
-    "    return nw.to_native(q_final)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 0.013325,
-     "end_time": "2024-03-22T17:24:39.099766",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.086441",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "dir_ = \"/kaggle/input/tpc-h-data-parquet-s-2/\"\n",
-    "nation = dir_ + \"nation.parquet\"\n",
-    "supplier = dir_ + \"supplier.parquet\"\n",
-    "partsupp = dir_ + \"partsupp.parquet\""
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 0.014284,
-     "end_time": "2024-03-22T17:24:39.119737",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.105453",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "IO_FUNCS = {\n",
-    "    \"pandas\": lambda x: pd.read_parquet(x, engine=\"pyarrow\"),\n",
-    "    \"pandas[pyarrow]\": lambda x: pd.read_parquet(\n",
-    "        x, engine=\"pyarrow\", dtype_backend=\"pyarrow\"\n",
-    "    ),\n",
-    "    \"polars[eager]\": lambda x: pl.read_parquet(x),\n",
-    "    \"polars[lazy]\": lambda x: pl.scan_parquet(x),\n",
-    "}"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "results = {}"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005113,
-     "end_time": "2024-03-22T17:24:39.130472",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.125359",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## pandas via Narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 196.786925,
-     "end_time": "2024-03-22T17:27:55.922832",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.135907",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"pandas\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q11(fn(partsupp), fn(nation), fn(supplier))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005184,
-     "end_time": "2024-03-22T17:27:55.933407",
-     "exception": false,
-     "start_time": "2024-03-22T17:27:55.928223",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## pandas, pyarrow dtypes, via Narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 158.748353,
-     "end_time": "2024-03-22T17:30:34.688289",
-     "exception": false,
-     "start_time": "2024-03-22T17:27:55.939936",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"pandas[pyarrow]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q11(fn(partsupp), fn(nation), fn(supplier))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005773,
-     "end_time": "2024-03-22T17:30:34.7003",
-     "exception": false,
-     "start_time": "2024-03-22T17:30:34.694527",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## Polars read_parquet"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 37.821116,
-     "end_time": "2024-03-22T17:31:12.527466",
-     "exception": false,
-     "start_time": "2024-03-22T17:30:34.70635",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"polars[eager]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q11(fn(partsupp), fn(nation), fn(supplier))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005515,
-     "end_time": "2024-03-22T17:31:12.539068",
-     "exception": false,
-     "start_time": "2024-03-22T17:31:12.533553",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## Polars scan_parquet"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 4.800698,
-     "end_time": "2024-03-22T17:31:17.346813",
-     "exception": false,
-     "start_time": "2024-03-22T17:31:12.546115",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"polars[lazy]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q11(fn(partsupp), fn(nation), fn(supplier)).collect()\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## Save"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "import json\n",
-    "\n",
-    "with open(\"results.json\", \"w\") as fd:\n",
-    "    json.dump(results, fd)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "from pprint import pprint\n",
-    "\n",
-    "pprint(results)"
-   ]
-  }
- ],
- "metadata": {
-  "kaggle": {
-   "accelerator": "none",
-   "dataSources": [
-    {
-     "sourceId": 167796934,
-     "sourceType": "kernelVersion"
-    }
-   ],
-   "dockerImageVersionId": 30673,
-   "isGpuEnabled": false,
-   "isInternetEnabled": true,
-   "language": "python",
-   "sourceType": "notebook"
-  },
-  "kernelspec": {
-   "display_name": "Python 3",
-   "language": "python",
-   "name": "python3"
-  },
-  "language_info": {
-   "codemirror_mode": {
-    "name": "ipython",
-    "version": 3
-   },
-   "file_extension": ".py",
-   "mimetype": "text/x-python",
-   "name": "python",
-   "nbconvert_exporter": "python",
-   "pygments_lexer": "ipython3",
-   "version": "3.10.13"
-  },
-  "papermill": {
-   "default_parameters": {},
-   "duration": 458.423327,
-   "end_time": "2024-03-22T17:31:18.077306",
-   "environment_variables": {},
-   "exception": null,
-   "input_path": "__notebook__.ipynb",
-   "output_path": "__notebook__.ipynb",
-   "parameters": {},
-   "start_time": "2024-03-22T17:23:39.653979",
-   "version": "2.5.0"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/tpch/notebooks/q11/kernel-metadata.json b/tpch/notebooks/q11/kernel-metadata.json
deleted file mode 100644
index 2aa47c6c..00000000
--- a/tpch/notebooks/q11/kernel-metadata.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "id": "marcogorelli/narwhals-tpch-q11-s2",
-  "title": "Narwhals TPCH Q11 S2",
-  "code_file": "execute.ipynb",
-  "language": "python",
-  "kernel_type": "notebook",
-  "is_private": "false",
-  "enable_gpu": "false",
-  "enable_tpu": "false",
-  "enable_internet": "true",
-  "dataset_sources": [],
-  "competition_sources": [],
-  "kernel_sources": ["marcogorelli/tpc-h-data-parquet-s-2"],
-  "model_sources": []
-}
\ No newline at end of file
diff --git a/tpch/notebooks/q15/execute.ipynb b/tpch/notebooks/q15/execute.ipynb
deleted file mode 100644
index d108a719..00000000
--- a/tpch/notebooks/q15/execute.ipynb
+++ /dev/null
@@ -1,366 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 33.390992,
-     "end_time": "2024-03-22T17:24:15.601719",
-     "exception": false,
-     "start_time": "2024-03-22T17:23:42.210727",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "!pip uninstall apache-beam -y && pip install -U pandas polars pyarrow narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 0.907754,
-     "end_time": "2024-03-22T17:24:39.053873",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:38.146119",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "import pandas as pd\n",
-    "import polars as pl\n",
-    "\n",
-    "pd.options.mode.copy_on_write = True\n",
-    "pd.options.future.infer_string = True"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 0.021725,
-     "end_time": "2024-03-22T17:24:39.080999",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.059274",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "from datetime import datetime\n",
-    "from typing import Any\n",
-    "\n",
-    "import narwhals as nw\n",
-    "\n",
-    "\n",
-    "def q15(\n",
-    "    lineitem_ds_raw: Any,\n",
-    "    supplier_ds_raw: Any,\n",
-    ") -> Any:\n",
-    "    lineitem_ds = nw.from_native(lineitem_ds_raw)\n",
-    "    supplier_ds = nw.from_native(supplier_ds_raw)\n",
-    "\n",
-    "    var1 = datetime(1996, 1, 1)\n",
-    "    var2 = datetime(1996, 4, 1)\n",
-    "\n",
-    "    revenue = (\n",
-    "        lineitem_ds.filter(nw.col(\"l_shipdate\").is_between(var1, var2, closed=\"left\"))\n",
-    "        .with_columns(\n",
-    "            (nw.col(\"l_extendedprice\") * (1 - nw.col(\"l_discount\"))).alias(\n",
-    "                \"total_revenue\"\n",
-    "            )\n",
-    "        )\n",
-    "        .group_by(\"l_suppkey\")\n",
-    "        .agg(nw.sum(\"total_revenue\"))\n",
-    "        .select(nw.col(\"l_suppkey\").alias(\"supplier_no\"), nw.col(\"total_revenue\"))\n",
-    "    )\n",
-    "\n",
-    "    result = (\n",
-    "        supplier_ds.join(revenue, left_on=\"s_suppkey\", right_on=\"supplier_no\")\n",
-    "        .filter(nw.col(\"total_revenue\") == nw.col(\"total_revenue\").max())\n",
-    "        .with_columns(nw.col(\"total_revenue\").round(2))\n",
-    "        .select(\"s_suppkey\", \"s_name\", \"s_address\", \"s_phone\", \"total_revenue\")\n",
-    "        .sort(\"s_suppkey\")\n",
-    "    )\n",
-    "\n",
-    "    return nw.to_native(result)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 0.013325,
-     "end_time": "2024-03-22T17:24:39.099766",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.086441",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "dir_ = \"/kaggle/input/tpc-h-data-parquet-s-2/\"\n",
-    "lineitem = dir_ + \"lineitem.parquet\"\n",
-    "supplier = dir_ + \"supplier.parquet\""
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 0.014284,
-     "end_time": "2024-03-22T17:24:39.119737",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.105453",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "IO_FUNCS = {\n",
-    "    \"pandas\": lambda x: pd.read_parquet(x, engine=\"pyarrow\"),\n",
-    "    \"pandas[pyarrow]\": lambda x: pd.read_parquet(\n",
-    "        x, engine=\"pyarrow\", dtype_backend=\"pyarrow\"\n",
-    "    ),\n",
-    "    \"polars[eager]\": lambda x: pl.read_parquet(x),\n",
-    "    \"polars[lazy]\": lambda x: pl.scan_parquet(x),\n",
-    "}"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "results = {}"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005113,
-     "end_time": "2024-03-22T17:24:39.130472",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.125359",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## pandas via Narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 196.786925,
-     "end_time": "2024-03-22T17:27:55.922832",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.135907",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"pandas\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q15(fn(lineitem), fn(supplier))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005184,
-     "end_time": "2024-03-22T17:27:55.933407",
-     "exception": false,
-     "start_time": "2024-03-22T17:27:55.928223",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## pandas, pyarrow dtypes, via Narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 158.748353,
-     "end_time": "2024-03-22T17:30:34.688289",
-     "exception": false,
-     "start_time": "2024-03-22T17:27:55.939936",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"pandas[pyarrow]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q15(fn(lineitem), fn(supplier))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005773,
-     "end_time": "2024-03-22T17:30:34.7003",
-     "exception": false,
-     "start_time": "2024-03-22T17:30:34.694527",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## Polars read_parquet"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 37.821116,
-     "end_time": "2024-03-22T17:31:12.527466",
-     "exception": false,
-     "start_time": "2024-03-22T17:30:34.70635",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"polars[eager]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q15(fn(lineitem), fn(supplier))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005515,
-     "end_time": "2024-03-22T17:31:12.539068",
-     "exception": false,
-     "start_time": "2024-03-22T17:31:12.533553",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## Polars scan_parquet"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 4.800698,
-     "end_time": "2024-03-22T17:31:17.346813",
-     "exception": false,
-     "start_time": "2024-03-22T17:31:12.546115",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"polars[lazy]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q15(fn(lineitem), fn(supplier)).collect()\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## Save"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "import json\n",
-    "\n",
-    "with open(\"results.json\", \"w\") as fd:\n",
-    "    json.dump(results, fd)"
-   ]
-  }
- ],
- "metadata": {
-  "kaggle": {
-   "accelerator": "none",
-   "dataSources": [
-    {
-     "sourceId": 167796934,
-     "sourceType": "kernelVersion"
-    }
-   ],
-   "dockerImageVersionId": 30673,
-   "isGpuEnabled": false,
-   "isInternetEnabled": true,
-   "language": "python",
-   "sourceType": "notebook"
-  },
-  "kernelspec": {
-   "display_name": "Python 3",
-   "language": "python",
-   "name": "python3"
-  },
-  "language_info": {
-   "codemirror_mode": {
-    "name": "ipython",
-    "version": 3
-   },
-   "file_extension": ".py",
-   "mimetype": "text/x-python",
-   "name": "python",
-   "nbconvert_exporter": "python",
-   "pygments_lexer": "ipython3",
-   "version": "3.10.13"
-  },
-  "papermill": {
-   "default_parameters": {},
-   "duration": 458.423327,
-   "end_time": "2024-03-22T17:31:18.077306",
-   "environment_variables": {},
-   "exception": null,
-   "input_path": "__notebook__.ipynb",
-   "output_path": "__notebook__.ipynb",
-   "parameters": {},
-   "start_time": "2024-03-22T17:23:39.653979",
-   "version": "2.5.0"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/tpch/notebooks/q15/kernel-metadata.json b/tpch/notebooks/q15/kernel-metadata.json
deleted file mode 100644
index e552c947..00000000
--- a/tpch/notebooks/q15/kernel-metadata.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "id": "marcogorelli/narwhals-tpch-q15-s2",
-  "title": "Narwhals TPCH Q15 S2",
-  "code_file": "execute.ipynb",
-  "language": "python",
-  "kernel_type": "notebook",
-  "is_private": "false",
-  "enable_gpu": "false",
-  "enable_tpu": "false",
-  "enable_internet": "true",
-  "dataset_sources": [],
-  "competition_sources": [],
-  "kernel_sources": ["marcogorelli/tpc-h-data-parquet-s-2"],
-  "model_sources": []
-}
\ No newline at end of file
diff --git a/tpch/notebooks/q17/execute.ipynb b/tpch/notebooks/q17/execute.ipynb
deleted file mode 100644
index 4d012f08..00000000
--- a/tpch/notebooks/q17/execute.ipynb
+++ /dev/null
@@ -1,357 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 33.390992,
-     "end_time": "2024-03-22T17:24:15.601719",
-     "exception": false,
-     "start_time": "2024-03-22T17:23:42.210727",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "!pip uninstall apache-beam -y && pip install -U pandas polars pyarrow narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 0.907754,
-     "end_time": "2024-03-22T17:24:39.053873",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:38.146119",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "import pandas as pd\n",
-    "import polars as pl\n",
-    "\n",
-    "pd.options.mode.copy_on_write = True\n",
-    "pd.options.future.infer_string = True"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 0.021725,
-     "end_time": "2024-03-22T17:24:39.080999",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.059274",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "from typing import Any\n",
-    "\n",
-    "import narwhals as nw\n",
-    "\n",
-    "\n",
-    "def q17(lineitem_ds_raw: Any, part_ds_raw: Any) -> Any:\n",
-    "    lineitem_ds = nw.from_native(lineitem_ds_raw)\n",
-    "    part_ds = nw.from_native(part_ds_raw)\n",
-    "\n",
-    "    var1 = \"Brand#23\"\n",
-    "    var2 = \"MED BOX\"\n",
-    "\n",
-    "    query1 = (\n",
-    "        part_ds.filter(nw.col(\"p_brand\") == var1)\n",
-    "        .filter(nw.col(\"p_container\") == var2)\n",
-    "        .join(lineitem_ds, how=\"left\", left_on=\"p_partkey\", right_on=\"l_partkey\")\n",
-    "    )\n",
-    "\n",
-    "    final_query = (\n",
-    "        query1.group_by(\"p_partkey\")\n",
-    "        .agg((0.2 * nw.col(\"l_quantity\").mean()).alias(\"avg_quantity\"))\n",
-    "        .select(nw.col(\"p_partkey\").alias(\"key\"), nw.col(\"avg_quantity\"))\n",
-    "        .join(query1, left_on=\"key\", right_on=\"p_partkey\")\n",
-    "        .filter(nw.col(\"l_quantity\") < nw.col(\"avg_quantity\"))\n",
-    "        .select((nw.col(\"l_extendedprice\").sum() / 7.0).round(2).alias(\"avg_yearly\"))\n",
-    "    )\n",
-    "\n",
-    "    return nw.to_native(final_query)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 0.013325,
-     "end_time": "2024-03-22T17:24:39.099766",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.086441",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "dir_ = \"/kaggle/input/tpc-h-data-parquet-s-2/\"\n",
-    "lineitem = dir_ + \"lineitem.parquet\"\n",
-    "part = dir_ + \"part.parquet\""
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 0.014284,
-     "end_time": "2024-03-22T17:24:39.119737",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.105453",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "IO_FUNCS = {\n",
-    "    \"pandas\": lambda x: pd.read_parquet(x, engine=\"pyarrow\"),\n",
-    "    \"pandas[pyarrow]\": lambda x: pd.read_parquet(\n",
-    "        x, engine=\"pyarrow\", dtype_backend=\"pyarrow\"\n",
-    "    ),\n",
-    "    \"polars[eager]\": lambda x: pl.read_parquet(x),\n",
-    "    \"polars[lazy]\": lambda x: pl.scan_parquet(x),\n",
-    "}"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "results = {}"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005113,
-     "end_time": "2024-03-22T17:24:39.130472",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.125359",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## pandas via Narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 196.786925,
-     "end_time": "2024-03-22T17:27:55.922832",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.135907",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"pandas\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q17(fn(lineitem), fn(part))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005184,
-     "end_time": "2024-03-22T17:27:55.933407",
-     "exception": false,
-     "start_time": "2024-03-22T17:27:55.928223",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## pandas, pyarrow dtypes, via Narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 158.748353,
-     "end_time": "2024-03-22T17:30:34.688289",
-     "exception": false,
-     "start_time": "2024-03-22T17:27:55.939936",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"pandas[pyarrow]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q17(fn(lineitem), fn(part))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005773,
-     "end_time": "2024-03-22T17:30:34.7003",
-     "exception": false,
-     "start_time": "2024-03-22T17:30:34.694527",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## Polars read_parquet"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 37.821116,
-     "end_time": "2024-03-22T17:31:12.527466",
-     "exception": false,
-     "start_time": "2024-03-22T17:30:34.70635",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"polars[eager]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q17(fn(lineitem), fn(part))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005515,
-     "end_time": "2024-03-22T17:31:12.539068",
-     "exception": false,
-     "start_time": "2024-03-22T17:31:12.533553",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## Polars scan_parquet"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 4.800698,
-     "end_time": "2024-03-22T17:31:17.346813",
-     "exception": false,
-     "start_time": "2024-03-22T17:31:12.546115",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"polars[lazy]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q17(fn(lineitem), fn(part)).collect()\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## Save"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "import json\n",
-    "\n",
-    "with open(\"results.json\", \"w\") as fd:\n",
-    "    json.dump(results, fd)"
-   ]
-  }
- ],
- "metadata": {
-  "kaggle": {
-   "accelerator": "none",
-   "dataSources": [
-    {
-     "sourceId": 167796934,
-     "sourceType": "kernelVersion"
-    }
-   ],
-   "dockerImageVersionId": 30673,
-   "isGpuEnabled": false,
-   "isInternetEnabled": true,
-   "language": "python",
-   "sourceType": "notebook"
-  },
-  "kernelspec": {
-   "display_name": "Python 3",
-   "language": "python",
-   "name": "python3"
-  },
-  "language_info": {
-   "codemirror_mode": {
-    "name": "ipython",
-    "version": 3
-   },
-   "file_extension": ".py",
-   "mimetype": "text/x-python",
-   "name": "python",
-   "nbconvert_exporter": "python",
-   "pygments_lexer": "ipython3",
-   "version": "3.10.13"
-  },
-  "papermill": {
-   "default_parameters": {},
-   "duration": 458.423327,
-   "end_time": "2024-03-22T17:31:18.077306",
-   "environment_variables": {},
-   "exception": null,
-   "input_path": "__notebook__.ipynb",
-   "output_path": "__notebook__.ipynb",
-   "parameters": {},
-   "start_time": "2024-03-22T17:23:39.653979",
-   "version": "2.5.0"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/tpch/notebooks/q17/kernel-metadata.json b/tpch/notebooks/q17/kernel-metadata.json
deleted file mode 100644
index 0fd73368..00000000
--- a/tpch/notebooks/q17/kernel-metadata.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "id": "marcogorelli/narwhals-tpch-q17-s2",
-  "title": "Narwhals TPCH Q17 S2",
-  "code_file": "execute.ipynb",
-  "language": "python",
-  "kernel_type": "notebook",
-  "is_private": "false",
-  "enable_gpu": "false",
-  "enable_tpu": "false",
-  "enable_internet": "true",
-  "dataset_sources": [],
-  "competition_sources": [],
-  "kernel_sources": ["marcogorelli/tpc-h-data-parquet-s-2"],
-  "model_sources": []
-}
\ No newline at end of file
diff --git a/tpch/notebooks/q18/execute.ipynb b/tpch/notebooks/q18/execute.ipynb
deleted file mode 100644
index edf635d9..00000000
--- a/tpch/notebooks/q18/execute.ipynb
+++ /dev/null
@@ -1,210 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "!pip uninstall apache-beam -y && pip install -U pandas polars pyarrow narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "import pandas as pd\n",
-    "import polars as pl\n",
-    "\n",
-    "pd.options.mode.copy_on_write = True\n",
-    "pd.options.future.infer_string = True"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "from typing import Any\n",
-    "\n",
-    "import narwhals as nw\n",
-    "\n",
-    "\n",
-    "def q18(customer_ds_raw: Any, lineitem_ds_raw: Any, orders_ds_raw: Any) -> Any:\n",
-    "    customer_ds = nw.from_native(customer_ds_raw)\n",
-    "    lineitem_ds = nw.from_native(lineitem_ds_raw)\n",
-    "    orders_ds = nw.from_native(orders_ds_raw)\n",
-    "\n",
-    "    var1 = 300\n",
-    "\n",
-    "    query1 = (\n",
-    "        lineitem_ds.group_by(\"l_orderkey\")\n",
-    "        .agg(nw.col(\"l_quantity\").sum().alias(\"sum_quantity\"))\n",
-    "        .filter(nw.col(\"sum_quantity\") > var1)\n",
-    "    )\n",
-    "\n",
-    "    q_final = (\n",
-    "        orders_ds.join(query1, left_on=\"o_orderkey\", right_on=\"l_orderkey\", how=\"semi\")\n",
-    "        .join(lineitem_ds, left_on=\"o_orderkey\", right_on=\"l_orderkey\")\n",
-    "        .join(customer_ds, left_on=\"o_custkey\", right_on=\"c_custkey\")\n",
-    "        .group_by(\"c_name\", \"o_custkey\", \"o_orderkey\", \"o_orderdate\", \"o_totalprice\")\n",
-    "        .agg(nw.col(\"l_quantity\").sum().alias(\"col6\"))\n",
-    "        .select(\n",
-    "            nw.col(\"c_name\"),\n",
-    "            nw.col(\"o_custkey\").alias(\"c_custkey\"),\n",
-    "            nw.col(\"o_orderkey\"),\n",
-    "            nw.col(\"o_orderdate\").alias(\"o_orderdat\"),\n",
-    "            nw.col(\"o_totalprice\"),\n",
-    "            nw.col(\"col6\"),\n",
-    "        )\n",
-    "        .sort(by=[\"o_totalprice\", \"o_orderdat\"], descending=[True, False])\n",
-    "        .head(100)\n",
-    "    )\n",
-    "\n",
-    "    return nw.to_native(q_final)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "dir_ = \"/kaggle/input/tpc-h-data-parquet-s-2/\"\n",
-    "customer = dir_ + \"customer.parquet\"\n",
-    "lineitem = dir_ + \"lineitem.parquet\"\n",
-    "orders = dir_ + \"orders.parquet\""
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "IO_FUNCS = {\n",
-    "    \"pandas\": lambda x: pd.read_parquet(x, engine=\"pyarrow\"),\n",
-    "    \"pandas[pyarrow]\": lambda x: pd.read_parquet(\n",
-    "        x, engine=\"pyarrow\", dtype_backend=\"pyarrow\"\n",
-    "    ),\n",
-    "    \"polars[eager]\": lambda x: pl.read_parquet(x),\n",
-    "    \"polars[lazy]\": lambda x: pl.scan_parquet(x),\n",
-    "}"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "results = {}"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## pandas via Narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "tool = \"pandas\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q19(fn(lineitem), fn(part))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## pandas, pyarrow dtypes, via Narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "tool = \"pandas[pyarrow]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q18(fn(customer), fn(lineitem), fn(orders))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## Polars read_parquet"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "tool = \"polars[eager]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q18(fn(customer), fn(lineitem), fn(orders))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## Polars scan_parquet"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "tool = \"polars[lazy]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q18(fn(customer), fn(lineitem), fn(orders)).collect()\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## Save"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "import json\n",
-    "\n",
-    "with open(\"results.json\", \"w\") as fd:\n",
-    "    json.dump(results, fd)"
-   ]
-  }
- ],
- "metadata": {
-  "language_info": {
-   "name": "python"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 2
-}
diff --git a/tpch/notebooks/q18/kernel-metadata.json b/tpch/notebooks/q18/kernel-metadata.json
deleted file mode 100644
index e1c11e53..00000000
--- a/tpch/notebooks/q18/kernel-metadata.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "id": "marcogorelli/narwhals-tpch-q18-s2",
-  "title": "Narwhals TPCH Q18 S2",
-  "code_file": "execute.ipynb",
-  "language": "python",
-  "kernel_type": "notebook",
-  "is_private": "false",
-  "enable_gpu": "false",
-  "enable_tpu": "false",
-  "enable_internet": "true",
-  "dataset_sources": [],
-  "competition_sources": [],
-  "kernel_sources": ["marcogorelli/tpc-h-data-parquet-s-2"],
-  "model_sources": []
-}
\ No newline at end of file
diff --git a/tpch/notebooks/q19/execute.ipynb b/tpch/notebooks/q19/execute.ipynb
deleted file mode 100644
index 8860cc77..00000000
--- a/tpch/notebooks/q19/execute.ipynb
+++ /dev/null
@@ -1,373 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 33.390992,
-     "end_time": "2024-03-22T17:24:15.601719",
-     "exception": false,
-     "start_time": "2024-03-22T17:23:42.210727",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "!pip uninstall apache-beam -y && pip install -U pandas polars pyarrow narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 0.907754,
-     "end_time": "2024-03-22T17:24:39.053873",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:38.146119",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "import pandas as pd\n",
-    "import polars as pl\n",
-    "\n",
-    "pd.options.mode.copy_on_write = True\n",
-    "pd.options.future.infer_string = True"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 0.021725,
-     "end_time": "2024-03-22T17:24:39.080999",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.059274",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "from typing import Any\n",
-    "\n",
-    "import narwhals as nw\n",
-    "\n",
-    "\n",
-    "def q19(lineitem_ds_raw: Any, part_ds_raw: Any) -> Any:\n",
-    "    lineitem_ds = nw.from_native(lineitem_ds_raw)\n",
-    "    part_ds = nw.from_native(part_ds_raw)\n",
-    "\n",
-    "    result = (\n",
-    "        part_ds.join(lineitem_ds, left_on=\"p_partkey\", right_on=\"l_partkey\")\n",
-    "        .filter(nw.col(\"l_shipmode\").is_in([\"AIR\", \"AIR REG\"]))\n",
-    "        .filter(nw.col(\"l_shipinstruct\") == \"DELIVER IN PERSON\")\n",
-    "        .filter(\n",
-    "            (\n",
-    "                (nw.col(\"p_brand\") == \"Brand#12\")\n",
-    "                & nw.col(\"p_container\").is_in([\"SM CASE\", \"SM BOX\", \"SM PACK\", \"SM PKG\"])\n",
-    "                & (nw.col(\"l_quantity\").is_between(1, 11))\n",
-    "                & (nw.col(\"p_size\").is_between(1, 5))\n",
-    "            )\n",
-    "            | (\n",
-    "                (nw.col(\"p_brand\") == \"Brand#23\")\n",
-    "                & nw.col(\"p_container\").is_in(\n",
-    "                    [\"MED BAG\", \"MED BOX\", \"MED PKG\", \"MED PACK\"]\n",
-    "                )\n",
-    "                & (nw.col(\"l_quantity\").is_between(10, 20))\n",
-    "                & (nw.col(\"p_size\").is_between(1, 10))\n",
-    "            )\n",
-    "            | (\n",
-    "                (nw.col(\"p_brand\") == \"Brand#34\")\n",
-    "                & nw.col(\"p_container\").is_in([\"LG CASE\", \"LG BOX\", \"LG PACK\", \"LG PKG\"])\n",
-    "                & (nw.col(\"l_quantity\").is_between(20, 30))\n",
-    "                & (nw.col(\"p_size\").is_between(1, 15))\n",
-    "            )\n",
-    "        )\n",
-    "        .select(\n",
-    "            (nw.col(\"l_extendedprice\") * (1 - nw.col(\"l_discount\")))\n",
-    "            .sum()\n",
-    "            .round(2)\n",
-    "            .alias(\"revenue\")\n",
-    "        )\n",
-    "    )\n",
-    "\n",
-    "    return nw.to_native(result)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 0.013325,
-     "end_time": "2024-03-22T17:24:39.099766",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.086441",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "dir_ = \"/kaggle/input/tpc-h-data-parquet-s-2/\"\n",
-    "lineitem = dir_ + \"lineitem.parquet\"\n",
-    "part = dir_ + \"part.parquet\""
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 0.014284,
-     "end_time": "2024-03-22T17:24:39.119737",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.105453",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "IO_FUNCS = {\n",
-    "    \"pandas\": lambda x: pd.read_parquet(x, engine=\"pyarrow\"),\n",
-    "    \"pandas[pyarrow]\": lambda x: pd.read_parquet(\n",
-    "        x, engine=\"pyarrow\", dtype_backend=\"pyarrow\"\n",
-    "    ),\n",
-    "    \"polars[eager]\": lambda x: pl.read_parquet(x),\n",
-    "    \"polars[lazy]\": lambda x: pl.scan_parquet(x),\n",
-    "}"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "results = {}"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005113,
-     "end_time": "2024-03-22T17:24:39.130472",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.125359",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## pandas via Narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 196.786925,
-     "end_time": "2024-03-22T17:27:55.922832",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.135907",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"pandas\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q19(fn(lineitem), fn(part))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005184,
-     "end_time": "2024-03-22T17:27:55.933407",
-     "exception": false,
-     "start_time": "2024-03-22T17:27:55.928223",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## pandas, pyarrow dtypes, via Narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 158.748353,
-     "end_time": "2024-03-22T17:30:34.688289",
-     "exception": false,
-     "start_time": "2024-03-22T17:27:55.939936",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"pandas[pyarrow]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q19(fn(lineitem), fn(part))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005773,
-     "end_time": "2024-03-22T17:30:34.7003",
-     "exception": false,
-     "start_time": "2024-03-22T17:30:34.694527",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## Polars read_parquet"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 37.821116,
-     "end_time": "2024-03-22T17:31:12.527466",
-     "exception": false,
-     "start_time": "2024-03-22T17:30:34.70635",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"polars[eager]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q19(fn(lineitem), fn(part))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005515,
-     "end_time": "2024-03-22T17:31:12.539068",
-     "exception": false,
-     "start_time": "2024-03-22T17:31:12.533553",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## Polars scan_parquet"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 4.800698,
-     "end_time": "2024-03-22T17:31:17.346813",
-     "exception": false,
-     "start_time": "2024-03-22T17:31:12.546115",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"polars[lazy]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q19(fn(lineitem), fn(part)).collect()\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## Save"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "import json\n",
-    "\n",
-    "with open(\"results.json\", \"w\") as fd:\n",
-    "    json.dump(results, fd)"
-   ]
-  }
- ],
- "metadata": {
-  "kaggle": {
-   "accelerator": "none",
-   "dataSources": [
-    {
-     "sourceId": 167796934,
-     "sourceType": "kernelVersion"
-    }
-   ],
-   "dockerImageVersionId": 30673,
-   "isGpuEnabled": false,
-   "isInternetEnabled": true,
-   "language": "python",
-   "sourceType": "notebook"
-  },
-  "kernelspec": {
-   "display_name": "Python 3",
-   "language": "python",
-   "name": "python3"
-  },
-  "language_info": {
-   "codemirror_mode": {
-    "name": "ipython",
-    "version": 3
-   },
-   "file_extension": ".py",
-   "mimetype": "text/x-python",
-   "name": "python",
-   "nbconvert_exporter": "python",
-   "pygments_lexer": "ipython3",
-   "version": "3.10.13"
-  },
-  "papermill": {
-   "default_parameters": {},
-   "duration": 458.423327,
-   "end_time": "2024-03-22T17:31:18.077306",
-   "environment_variables": {},
-   "exception": null,
-   "input_path": "__notebook__.ipynb",
-   "output_path": "__notebook__.ipynb",
-   "parameters": {},
-   "start_time": "2024-03-22T17:23:39.653979",
-   "version": "2.5.0"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/tpch/notebooks/q19/kernel-metadata.json b/tpch/notebooks/q19/kernel-metadata.json
deleted file mode 100644
index b250ac0a..00000000
--- a/tpch/notebooks/q19/kernel-metadata.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "id": "marcogorelli/narwhals-tpch-q19-s2",
-  "title": "Narwhals TPCH Q19 S2",
-  "code_file": "execute.ipynb",
-  "language": "python",
-  "kernel_type": "notebook",
-  "is_private": "false",
-  "enable_gpu": "false",
-  "enable_tpu": "false",
-  "enable_internet": "true",
-  "dataset_sources": [],
-  "competition_sources": [],
-  "kernel_sources": ["marcogorelli/tpc-h-data-parquet-s-2"],
-  "model_sources": []
-}
\ No newline at end of file
diff --git a/tpch/notebooks/q2/execute.ipynb b/tpch/notebooks/q2/execute.ipynb
deleted file mode 100755
index 74ba50f2..00000000
--- a/tpch/notebooks/q2/execute.ipynb
+++ /dev/null
@@ -1,474 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "0",
-   "metadata": {
-    "papermill": {
-     "duration": 33.390992,
-     "end_time": "2024-03-22T17:24:15.601719",
-     "exception": false,
-     "start_time": "2024-03-22T17:23:42.210727",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "!pip uninstall apache-beam -y && pip install -U pandas polars pyarrow dask[dataframe]"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "1",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "!pip install git+https://github.com/MarcoGorelli/narwhals.git@more-dask-tpch"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "2",
-   "metadata": {
-    "papermill": {
-     "duration": 0.907754,
-     "end_time": "2024-03-22T17:24:39.053873",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:38.146119",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "import pandas as pd\n",
-    "import polars as pl\n",
-    "\n",
-    "pd.options.mode.copy_on_write = True\n",
-    "pd.options.future.infer_string = True"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "3",
-   "metadata": {
-    "papermill": {
-     "duration": 0.021725,
-     "end_time": "2024-03-22T17:24:39.080999",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.059274",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "from typing import Any\n",
-    "\n",
-    "import narwhals as nw\n",
-    "\n",
-    "\n",
-    "@nw.narwhalify\n",
-    "def q2(\n",
-    "    region_ds: Any,\n",
-    "    nation_ds: Any,\n",
-    "    supplier_ds: Any,\n",
-    "    part_ds: Any,\n",
-    "    part_supp_ds: Any,\n",
-    ") -> Any:\n",
-    "    var_1 = 15\n",
-    "    var_2 = \"BRASS\"\n",
-    "    var_3 = \"EUROPE\"\n",
-    "\n",
-    "    result_q2 = (\n",
-    "        part_ds.join(part_supp_ds, left_on=\"p_partkey\", right_on=\"ps_partkey\")\n",
-    "        .join(supplier_ds, left_on=\"ps_suppkey\", right_on=\"s_suppkey\")\n",
-    "        .join(nation_ds, left_on=\"s_nationkey\", right_on=\"n_nationkey\")\n",
-    "        .join(region_ds, left_on=\"n_regionkey\", right_on=\"r_regionkey\")\n",
-    "        .filter(\n",
-    "            nw.col(\"p_size\") == var_1,\n",
-    "            nw.col(\"p_type\").str.ends_with(var_2),\n",
-    "            nw.col(\"r_name\") == var_3,\n",
-    "        )\n",
-    "    )\n",
-    "\n",
-    "    final_cols = [\n",
-    "        \"s_acctbal\",\n",
-    "        \"s_name\",\n",
-    "        \"n_name\",\n",
-    "        \"p_partkey\",\n",
-    "        \"p_mfgr\",\n",
-    "        \"s_address\",\n",
-    "        \"s_phone\",\n",
-    "        \"s_comment\",\n",
-    "    ]\n",
-    "\n",
-    "    return (\n",
-    "        result_q2.group_by(\"p_partkey\")\n",
-    "        .agg(nw.col(\"ps_supplycost\").min().alias(\"ps_supplycost\"))\n",
-    "        .join(\n",
-    "            result_q2,\n",
-    "            left_on=[\"p_partkey\", \"ps_supplycost\"],\n",
-    "            right_on=[\"p_partkey\", \"ps_supplycost\"],\n",
-    "        )\n",
-    "        .select(final_cols)\n",
-    "        .sort(\n",
-    "            [\"s_acctbal\", \"n_name\", \"s_name\", \"p_partkey\"],\n",
-    "            descending=[True, False, False, False],\n",
-    "        )\n",
-    "        .head(100)\n",
-    "    )"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "4",
-   "metadata": {
-    "papermill": {
-     "duration": 0.013325,
-     "end_time": "2024-03-22T17:24:39.099766",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.086441",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "dir_ = \"/kaggle/input/tpc-h-data-parquet-s-2/\"\n",
-    "region = dir_ + \"region.parquet\"\n",
-    "nation = dir_ + \"nation.parquet\"\n",
-    "customer = dir_ + \"customer.parquet\"\n",
-    "lineitem = dir_ + \"lineitem.parquet\"\n",
-    "orders = dir_ + \"orders.parquet\"\n",
-    "supplier = dir_ + \"supplier.parquet\"\n",
-    "part = dir_ + \"part.parquet\"\n",
-    "partsupp = dir_ + \"partsupp.parquet\""
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "5",
-   "metadata": {
-    "papermill": {
-     "duration": 0.014284,
-     "end_time": "2024-03-22T17:24:39.119737",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.105453",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "import dask.dataframe as dd\n",
-    "import pyarrow.parquet as pq\n",
-    "\n",
-    "IO_FUNCS = {\n",
-    "    \"pandas\": lambda x: pd.read_parquet(x, engine=\"pyarrow\"),\n",
-    "    \"pandas[pyarrow]\": lambda x: pd.read_parquet(\n",
-    "        x, engine=\"pyarrow\", dtype_backend=\"pyarrow\"\n",
-    "    ),\n",
-    "    \"polars[eager]\": lambda x: pl.read_parquet(x),\n",
-    "    \"polars[lazy]\": lambda x: pl.scan_parquet(x),\n",
-    "    \"pyarrow\": lambda x: pq.read_table(x),\n",
-    "    \"dask\": lambda x: dd.read_parquet(x, engine=\"pyarrow\", dtype_backend=\"pyarrow\"),\n",
-    "}"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "6",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "results = {}"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "7",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005113,
-     "end_time": "2024-03-22T17:24:39.130472",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.125359",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## pandas"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "8",
-   "metadata": {
-    "papermill": {
-     "duration": 196.786925,
-     "end_time": "2024-03-22T17:27:55.922832",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.135907",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"pandas\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q2(fn(region), fn(nation), fn(supplier), fn(part), fn(partsupp))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "9",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005184,
-     "end_time": "2024-03-22T17:27:55.933407",
-     "exception": false,
-     "start_time": "2024-03-22T17:27:55.928223",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## pandas, pyarrow dtypes"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "10",
-   "metadata": {
-    "papermill": {
-     "duration": 158.748353,
-     "end_time": "2024-03-22T17:30:34.688289",
-     "exception": false,
-     "start_time": "2024-03-22T17:27:55.939936",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"pandas[pyarrow]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q2(fn(region), fn(nation), fn(supplier), fn(part), fn(partsupp))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "11",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005773,
-     "end_time": "2024-03-22T17:30:34.700300",
-     "exception": false,
-     "start_time": "2024-03-22T17:30:34.694527",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## Polars read_parquet"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "12",
-   "metadata": {
-    "papermill": {
-     "duration": 37.821116,
-     "end_time": "2024-03-22T17:31:12.527466",
-     "exception": false,
-     "start_time": "2024-03-22T17:30:34.706350",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"polars[eager]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q2(fn(region), fn(nation), fn(supplier), fn(part), fn(partsupp))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "13",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005515,
-     "end_time": "2024-03-22T17:31:12.539068",
-     "exception": false,
-     "start_time": "2024-03-22T17:31:12.533553",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## Polars scan_parquet"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "14",
-   "metadata": {
-    "papermill": {
-     "duration": 4.800698,
-     "end_time": "2024-03-22T17:31:17.346813",
-     "exception": false,
-     "start_time": "2024-03-22T17:31:12.546115",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"polars[lazy]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q2(fn(region), fn(nation), fn(supplier), fn(part), fn(partsupp)).collect()\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "15",
-   "metadata": {},
-   "source": [
-    "## PyArrow"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "16",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "tool = \"pyarrow\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q2(fn(region), fn(nation), fn(supplier), fn(part), fn(partsupp))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "17",
-   "metadata": {},
-   "source": [
-    "## Dask"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "18",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "tool = \"dask\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q2(fn(region), fn(nation), fn(supplier), fn(part), fn(partsupp)).compute()\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "19",
-   "metadata": {},
-   "source": [
-    "## Save"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "20",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "import json\n",
-    "\n",
-    "with open(\"results.json\", \"w\") as fd:\n",
-    "    json.dump(results, fd)"
-   ]
-  }
- ],
- "metadata": {
-  "kaggle": {
-   "accelerator": "none",
-   "dataSources": [
-    {
-     "sourceId": 167796716,
-     "sourceType": "kernelVersion"
-    },
-    {
-     "sourceId": 167796934,
-     "sourceType": "kernelVersion"
-    },
-    {
-     "sourceId": 167796952,
-     "sourceType": "kernelVersion"
-    },
-    {
-     "sourceId": 167796969,
-     "sourceType": "kernelVersion"
-    }
-   ],
-   "isGpuEnabled": false,
-   "isInternetEnabled": true,
-   "language": "python",
-   "sourceType": "notebook"
-  },
-  "kernelspec": {
-   "display_name": "Python 3",
-   "language": "python",
-   "name": "python3"
-  },
-  "language_info": {
-   "codemirror_mode": {
-    "name": "ipython",
-    "version": 3
-   },
-   "file_extension": ".py",
-   "mimetype": "text/x-python",
-   "name": "python",
-   "nbconvert_exporter": "python",
-   "pygments_lexer": "ipython3",
-   "version": "3.11.9"
-  },
-  "papermill": {
-   "default_parameters": {},
-   "duration": 458.423327,
-   "end_time": "2024-03-22T17:31:18.077306",
-   "environment_variables": {},
-   "exception": null,
-   "input_path": "__notebook__.ipynb",
-   "output_path": "__notebook__.ipynb",
-   "parameters": {},
-   "start_time": "2024-03-22T17:23:39.653979",
-   "version": "2.5.0"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 5
-}
diff --git a/tpch/notebooks/q2/kernel-metadata.json b/tpch/notebooks/q2/kernel-metadata.json
deleted file mode 100644
index 96386cbf..00000000
--- a/tpch/notebooks/q2/kernel-metadata.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "id": "marcogorelli/narwhals-tpch-q2-s2",
-  "title": "Narwhals TPCH Q2 S2",
-  "code_file": "execute.ipynb",
-  "language": "python",
-  "kernel_type": "notebook",
-  "is_private": "false",
-  "enable_gpu": "false",
-  "enable_tpu": "false",
-  "enable_internet": "true",
-  "dataset_sources": [],
-  "competition_sources": [],
-  "kernel_sources": ["marcogorelli/tpc-h-data-parquet-s-2"],
-  "model_sources": []
-}
\ No newline at end of file
diff --git a/tpch/notebooks/q20/execute.ipynb b/tpch/notebooks/q20/execute.ipynb
deleted file mode 100644
index a9698c1a..00000000
--- a/tpch/notebooks/q20/execute.ipynb
+++ /dev/null
@@ -1,382 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 33.390992,
-     "end_time": "2024-03-22T17:24:15.601719",
-     "exception": false,
-     "start_time": "2024-03-22T17:23:42.210727",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "!pip uninstall apache-beam -y && pip install -U pandas polars pyarrow narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 0.907754,
-     "end_time": "2024-03-22T17:24:39.053873",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:38.146119",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "import pandas as pd\n",
-    "import polars as pl\n",
-    "\n",
-    "pd.options.mode.copy_on_write = True\n",
-    "pd.options.future.infer_string = True"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 0.021725,
-     "end_time": "2024-03-22T17:24:39.080999",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.059274",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "from datetime import datetime\n",
-    "from typing import Any\n",
-    "\n",
-    "import narwhals as nw\n",
-    "\n",
-    "\n",
-    "def q20(\n",
-    "    part_ds_raw: Any,\n",
-    "    partsupp_ds_raw: Any,\n",
-    "    nation_ds_raw: Any,\n",
-    "    lineitem_ds_raw: Any,\n",
-    "    supplier_ds_raw: Any,\n",
-    ") -> Any:\n",
-    "    part_ds = nw.from_native(part_ds_raw)\n",
-    "    nation_ds = nw.from_native(nation_ds_raw)\n",
-    "    partsupp_ds = nw.from_native(partsupp_ds_raw)\n",
-    "    lineitem_ds = nw.from_native(lineitem_ds_raw)\n",
-    "    supplier_ds = nw.from_native(supplier_ds_raw)\n",
-    "\n",
-    "    var1 = datetime(1994, 1, 1)\n",
-    "    var2 = datetime(1995, 1, 1)\n",
-    "    var3 = \"CANADA\"\n",
-    "    var4 = \"forest\"\n",
-    "\n",
-    "    query1 = (\n",
-    "        lineitem_ds.filter(nw.col(\"l_shipdate\").is_between(var1, var2, closed=\"left\"))\n",
-    "        .group_by(\"l_partkey\", \"l_suppkey\")\n",
-    "        .agg((nw.col(\"l_quantity\").sum()).alias(\"sum_quantity\"))\n",
-    "        .with_columns(sum_quantity=nw.col(\"sum_quantity\") * 0.5)\n",
-    "    )\n",
-    "    query2 = nation_ds.filter(nw.col(\"n_name\") == var3)\n",
-    "    query3 = supplier_ds.join(query2, left_on=\"s_nationkey\", right_on=\"n_nationkey\")\n",
-    "\n",
-    "    result = (\n",
-    "        part_ds.filter(nw.col(\"p_name\").str.starts_with(var4))\n",
-    "        .select(nw.col(\"p_partkey\").unique())\n",
-    "        .join(partsupp_ds, left_on=\"p_partkey\", right_on=\"ps_partkey\")\n",
-    "        .join(\n",
-    "            query1,\n",
-    "            left_on=[\"ps_suppkey\", \"p_partkey\"],\n",
-    "            right_on=[\"l_suppkey\", \"l_partkey\"],\n",
-    "        )\n",
-    "        .filter(nw.col(\"ps_availqty\") > nw.col(\"sum_quantity\"))\n",
-    "        .select(nw.col(\"ps_suppkey\").unique())\n",
-    "        .join(query3, left_on=\"ps_suppkey\", right_on=\"s_suppkey\")\n",
-    "        .select(\"s_name\", \"s_address\")\n",
-    "        .sort(\"s_name\")\n",
-    "    )\n",
-    "\n",
-    "    return nw.to_native(result)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 0.013325,
-     "end_time": "2024-03-22T17:24:39.099766",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.086441",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "dir_ = \"/kaggle/input/tpc-h-data-parquet-s-2/\"\n",
-    "nation = dir_ + \"nation.parquet\"\n",
-    "lineitem = dir_ + \"lineitem.parquet\"\n",
-    "supplier = dir_ + \"supplier.parquet\"\n",
-    "part = dir_ + \"part.parquet\"\n",
-    "partsupp = dir_ + \"partsupp.parquet\""
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 0.014284,
-     "end_time": "2024-03-22T17:24:39.119737",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.105453",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "IO_FUNCS = {\n",
-    "    \"pandas\": lambda x: pd.read_parquet(x, engine=\"pyarrow\"),\n",
-    "    \"pandas[pyarrow]\": lambda x: pd.read_parquet(\n",
-    "        x, engine=\"pyarrow\", dtype_backend=\"pyarrow\"\n",
-    "    ),\n",
-    "    \"polars[eager]\": lambda x: pl.read_parquet(x),\n",
-    "    \"polars[lazy]\": lambda x: pl.scan_parquet(x),\n",
-    "}"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "results = {}"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005113,
-     "end_time": "2024-03-22T17:24:39.130472",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.125359",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## pandas via Narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 196.786925,
-     "end_time": "2024-03-22T17:27:55.922832",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.135907",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"pandas\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q20(fn(part), fn(partsupp), fn(nation), fn(lineitem), fn(supplier))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005184,
-     "end_time": "2024-03-22T17:27:55.933407",
-     "exception": false,
-     "start_time": "2024-03-22T17:27:55.928223",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## pandas, pyarrow dtypes, via Narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 158.748353,
-     "end_time": "2024-03-22T17:30:34.688289",
-     "exception": false,
-     "start_time": "2024-03-22T17:27:55.939936",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"pandas[pyarrow]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q20(fn(part), fn(partsupp), fn(nation), fn(lineitem), fn(supplier))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005773,
-     "end_time": "2024-03-22T17:30:34.7003",
-     "exception": false,
-     "start_time": "2024-03-22T17:30:34.694527",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## Polars read_parquet"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 37.821116,
-     "end_time": "2024-03-22T17:31:12.527466",
-     "exception": false,
-     "start_time": "2024-03-22T17:30:34.70635",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"polars[eager]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q20(fn(part), fn(partsupp), fn(nation), fn(lineitem), fn(supplier))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005515,
-     "end_time": "2024-03-22T17:31:12.539068",
-     "exception": false,
-     "start_time": "2024-03-22T17:31:12.533553",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## Polars scan_parquet"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 4.800698,
-     "end_time": "2024-03-22T17:31:17.346813",
-     "exception": false,
-     "start_time": "2024-03-22T17:31:12.546115",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"polars[lazy]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q20(fn(part), fn(partsupp), fn(nation), fn(lineitem), fn(supplier)).collect()\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## Save"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "import json\n",
-    "\n",
-    "with open(\"results.json\", \"w\") as fd:\n",
-    "    json.dump(results, fd)"
-   ]
-  }
- ],
- "metadata": {
-  "kaggle": {
-   "accelerator": "none",
-   "dataSources": [
-    {
-     "sourceId": 167796934,
-     "sourceType": "kernelVersion"
-    }
-   ],
-   "dockerImageVersionId": 30673,
-   "isGpuEnabled": false,
-   "isInternetEnabled": true,
-   "language": "python",
-   "sourceType": "notebook"
-  },
-  "kernelspec": {
-   "display_name": "Python 3",
-   "language": "python",
-   "name": "python3"
-  },
-  "language_info": {
-   "codemirror_mode": {
-    "name": "ipython",
-    "version": 3
-   },
-   "file_extension": ".py",
-   "mimetype": "text/x-python",
-   "name": "python",
-   "nbconvert_exporter": "python",
-   "pygments_lexer": "ipython3",
-   "version": "3.10.13"
-  },
-  "papermill": {
-   "default_parameters": {},
-   "duration": 458.423327,
-   "end_time": "2024-03-22T17:31:18.077306",
-   "environment_variables": {},
-   "exception": null,
-   "input_path": "__notebook__.ipynb",
-   "output_path": "__notebook__.ipynb",
-   "parameters": {},
-   "start_time": "2024-03-22T17:23:39.653979",
-   "version": "2.5.0"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/tpch/notebooks/q20/kernel-metadata.json b/tpch/notebooks/q20/kernel-metadata.json
deleted file mode 100644
index e6733375..00000000
--- a/tpch/notebooks/q20/kernel-metadata.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "id": "marcogorelli/narwhals-tpch-q20-s2",
-  "title": "Narwhals TPCH Q20 S2",
-  "code_file": "execute.ipynb",
-  "language": "python",
-  "kernel_type": "notebook",
-  "is_private": "false",
-  "enable_gpu": "false",
-  "enable_tpu": "false",
-  "enable_internet": "true",
-  "dataset_sources": [],
-  "competition_sources": [],
-  "kernel_sources": ["marcogorelli/tpc-h-data-parquet-s-2"],
-  "model_sources": []
-}
\ No newline at end of file
diff --git a/tpch/notebooks/q21/execute.ipynb b/tpch/notebooks/q21/execute.ipynb
deleted file mode 100755
index af12a424..00000000
--- a/tpch/notebooks/q21/execute.ipynb
+++ /dev/null
@@ -1,450 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "0",
-   "metadata": {
-    "papermill": {
-     "duration": 56.056574,
-     "end_time": "2024-06-20T09:39:32.181310",
-     "exception": false,
-     "start_time": "2024-06-20T09:38:36.124736",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "!pip uninstall apache-beam -y && pip install -U pandas polars pyarrow narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "1",
-   "metadata": {
-    "papermill": {
-     "duration": 0.710694,
-     "end_time": "2024-06-20T09:39:32.905246",
-     "exception": false,
-     "start_time": "2024-06-20T09:39:32.194552",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "from typing import Any\n",
-    "\n",
-    "import pandas as pd\n",
-    "import polars as pl\n",
-    "\n",
-    "import narwhals as nw\n",
-    "\n",
-    "pd.options.mode.copy_on_write = True\n",
-    "pd.options.future.infer_string = True"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "2",
-   "metadata": {
-    "papermill": {
-     "duration": 0.024919,
-     "end_time": "2024-06-20T09:39:32.942659",
-     "exception": false,
-     "start_time": "2024-06-20T09:39:32.917740",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "Q_NUM = 21\n",
-    "\n",
-    "IO_FUNCS = {\n",
-    "    \"pandas\": lambda x: pd.read_parquet(x, engine=\"pyarrow\"),\n",
-    "    \"pandas[pyarrow]\": lambda x: pd.read_parquet(\n",
-    "        x, engine=\"pyarrow\", dtype_backend=\"pyarrow\"\n",
-    "    ),\n",
-    "    \"polars[eager]\": lambda x: pl.read_parquet(x),\n",
-    "    \"polars[lazy]\": lambda x: pl.scan_parquet(x),\n",
-    "}"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "3",
-   "metadata": {
-    "papermill": {
-     "duration": 0.034054,
-     "end_time": "2024-06-20T09:39:32.990409",
-     "exception": false,
-     "start_time": "2024-06-20T09:39:32.956355",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def q21(\n",
-    "    lineitem_raw: Any,\n",
-    "    nation_raw: Any,\n",
-    "    orders_raw: Any,\n",
-    "    supplier_raw: Any,\n",
-    ") -> Any:\n",
-    "    lineitem = nw.from_native(lineitem_raw)\n",
-    "    nation = nw.from_native(nation_raw)\n",
-    "    orders = nw.from_native(orders_raw)\n",
-    "    supplier = nw.from_native(supplier_raw)\n",
-    "\n",
-    "    var1 = \"SAUDI ARABIA\"\n",
-    "\n",
-    "    q1 = (\n",
-    "        lineitem.group_by(\"l_orderkey\")\n",
-    "        .agg(nw.len().alias(\"n_supp_by_order\"))\n",
-    "        .filter(nw.col(\"n_supp_by_order\") > 1)\n",
-    "        .join(\n",
-    "            lineitem.filter(nw.col(\"l_receiptdate\") > nw.col(\"l_commitdate\")),\n",
-    "            left_on=\"l_orderkey\",\n",
-    "            right_on=\"l_orderkey\",\n",
-    "        )\n",
-    "    )\n",
-    "\n",
-    "    q_final = (\n",
-    "        q1.group_by(\"l_orderkey\")\n",
-    "        .agg(nw.len().alias(\"n_supp_by_order\"))\n",
-    "        .join(q1, left_on=\"l_orderkey\", right_on=\"l_orderkey\")\n",
-    "        .join(supplier, left_on=\"l_suppkey\", right_on=\"s_suppkey\")\n",
-    "        .join(nation, left_on=\"s_nationkey\", right_on=\"n_nationkey\")\n",
-    "        .join(orders, left_on=\"l_orderkey\", right_on=\"o_orderkey\")\n",
-    "        .filter(nw.col(\"n_supp_by_order\") == 1)\n",
-    "        .filter(nw.col(\"n_name\") == var1)\n",
-    "        .filter(nw.col(\"o_orderstatus\") == \"F\")\n",
-    "        .group_by(\"s_name\")\n",
-    "        .agg(nw.len().alias(\"numwait\"))\n",
-    "        .sort(by=[\"numwait\", \"s_name\"], descending=[True, False])\n",
-    "        .head(100)\n",
-    "    )\n",
-    "    return nw.to_native(q_final)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "4",
-   "metadata": {
-    "papermill": {
-     "duration": 0.023895,
-     "end_time": "2024-06-20T09:39:33.027127",
-     "exception": false,
-     "start_time": "2024-06-20T09:39:33.003232",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "dir_ = \"/kaggle/input/tpc-h-data-parquet-s-2/\"\n",
-    "\n",
-    "lineitem = dir_ + \"lineitem.parquet\"\n",
-    "nation = dir_ + \"nation.parquet\"\n",
-    "orders = dir_ + \"orders.parquet\"\n",
-    "supplier = dir_ + \"supplier.parquet\""
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "5",
-   "metadata": {
-    "papermill": {
-     "duration": 0.023307,
-     "end_time": "2024-06-20T09:39:33.064042",
-     "exception": false,
-     "start_time": "2024-06-20T09:39:33.040735",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "results = {}"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "6",
-   "metadata": {
-    "papermill": {
-     "duration": 0.013315,
-     "end_time": "2024-06-20T09:39:33.090039",
-     "exception": false,
-     "start_time": "2024-06-20T09:39:33.076724",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## pandas via Narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "7",
-   "metadata": {
-    "papermill": {
-     "duration": 153.948657,
-     "end_time": "2024-06-20T09:42:07.051286",
-     "exception": false,
-     "start_time": "2024-06-20T09:39:33.102629",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"pandas\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "\n",
-    "lineitem_raw, nation_raw, orders_raw, supplier_raw = (\n",
-    "    fn(lineitem),\n",
-    "    fn(nation),\n",
-    "    fn(orders),\n",
-    "    fn(supplier),\n",
-    ")\n",
-    "\n",
-    "timings = %timeit -o -q q21(lineitem_raw, nation_raw, orders_raw, supplier_raw)\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "8",
-   "metadata": {
-    "papermill": {
-     "duration": 0.012282,
-     "end_time": "2024-06-20T09:42:07.077095",
-     "exception": false,
-     "start_time": "2024-06-20T09:42:07.064813",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## pandas, pyarrow dtypes, via Narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "9",
-   "metadata": {
-    "papermill": {
-     "duration": 138.36459,
-     "end_time": "2024-06-20T09:44:25.454188",
-     "exception": false,
-     "start_time": "2024-06-20T09:42:07.089598",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"pandas[pyarrow]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "lineitem_raw, nation_raw, orders_raw, supplier_raw = (\n",
-    "    fn(lineitem),\n",
-    "    fn(nation),\n",
-    "    fn(orders),\n",
-    "    fn(supplier),\n",
-    ")\n",
-    "\n",
-    "timings = %timeit -o -q q21(lineitem_raw, nation_raw, orders_raw, supplier_raw)\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "10",
-   "metadata": {
-    "papermill": {
-     "duration": 0.012075,
-     "end_time": "2024-06-20T09:44:25.478725",
-     "exception": false,
-     "start_time": "2024-06-20T09:44:25.466650",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## Polars read_parquet"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "11",
-   "metadata": {
-    "papermill": {
-     "duration": 89.487638,
-     "end_time": "2024-06-20T09:45:54.978758",
-     "exception": false,
-     "start_time": "2024-06-20T09:44:25.491120",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"polars[eager]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "\n",
-    "lineitem_raw, nation_raw, orders_raw, supplier_raw = (\n",
-    "    fn(lineitem),\n",
-    "    fn(nation),\n",
-    "    fn(orders),\n",
-    "    fn(supplier),\n",
-    ")\n",
-    "timings = %timeit -o -q q21(lineitem_raw, nation_raw, orders_raw, supplier_raw)\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "12",
-   "metadata": {
-    "papermill": {
-     "duration": 0.011745,
-     "end_time": "2024-06-20T09:45:55.002962",
-     "exception": false,
-     "start_time": "2024-06-20T09:45:54.991217",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## Polars scan_parquet"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "13",
-   "metadata": {
-    "papermill": {
-     "duration": 23.550631,
-     "end_time": "2024-06-20T09:46:18.566271",
-     "exception": false,
-     "start_time": "2024-06-20T09:45:55.015640",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"polars[lazy]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "\n",
-    "lineitem_raw, nation_raw, orders_raw, supplier_raw = (\n",
-    "    fn(lineitem),\n",
-    "    fn(nation),\n",
-    "    fn(orders),\n",
-    "    fn(supplier),\n",
-    ")\n",
-    "timings = %timeit -o -q q21(lineitem_raw, nation_raw, orders_raw, supplier_raw).collect()\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "14",
-   "metadata": {
-    "papermill": {
-     "duration": 0.012321,
-     "end_time": "2024-06-20T09:46:18.591255",
-     "exception": false,
-     "start_time": "2024-06-20T09:46:18.578934",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## Save"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "15",
-   "metadata": {
-    "papermill": {
-     "duration": 0.023933,
-     "end_time": "2024-06-20T09:46:18.627709",
-     "exception": false,
-     "start_time": "2024-06-20T09:46:18.603776",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "import json\n",
-    "\n",
-    "with open(\"results.json\", \"w\") as fd:\n",
-    "    json.dump(results, fd)"
-   ]
-  }
- ],
- "metadata": {
-  "kaggle": {
-   "accelerator": "none",
-   "dataSources": [
-    {
-     "sourceId": 167796934,
-     "sourceType": "kernelVersion"
-    }
-   ],
-   "dockerImageVersionId": 30673,
-   "isGpuEnabled": false,
-   "isInternetEnabled": true,
-   "language": "python",
-   "sourceType": "notebook"
-  },
-  "kernelspec": {
-   "display_name": "Python 3",
-   "language": "python",
-   "name": "python3"
-  },
-  "language_info": {
-   "codemirror_mode": {
-    "name": "ipython",
-    "version": 3
-   },
-   "file_extension": ".py",
-   "mimetype": "text/x-python",
-   "name": "python",
-   "nbconvert_exporter": "python",
-   "pygments_lexer": "ipython3",
-   "version": "3.10.13"
-  },
-  "papermill": {
-   "default_parameters": {},
-   "duration": 466.953302,
-   "end_time": "2024-06-20T09:46:19.507794",
-   "environment_variables": {},
-   "exception": null,
-   "input_path": "__notebook__.ipynb",
-   "output_path": "__notebook__.ipynb",
-   "parameters": {},
-   "start_time": "2024-06-20T09:38:32.554492",
-   "version": "2.5.0"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 5
-}
diff --git a/tpch/notebooks/q21/kernel-metadata.json b/tpch/notebooks/q21/kernel-metadata.json
deleted file mode 100644
index b9e230e4..00000000
--- a/tpch/notebooks/q21/kernel-metadata.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "id": "marcogorelli/narwhals-tpch-q21-s2",
-  "title": "Narwhals TPCH Q21 S2",
-  "code_file": "execute.ipynb",
-  "language": "python",
-  "kernel_type": "notebook",
-  "is_private": "false",
-  "enable_gpu": "false",
-  "enable_tpu": "false",
-  "enable_internet": "true",
-  "dataset_sources": [],
-  "competition_sources": [],
-  "kernel_sources": ["marcogorelli/tpc-h-data-parquet-s-2"],
-  "model_sources": []
-}
\ No newline at end of file
diff --git a/tpch/notebooks/q3/execute.ipynb b/tpch/notebooks/q3/execute.ipynb
deleted file mode 100755
index b81135fc..00000000
--- a/tpch/notebooks/q3/execute.ipynb
+++ /dev/null
@@ -1,566 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "0",
-   "metadata": {
-    "papermill": {
-     "duration": 33.390992,
-     "end_time": "2024-03-22T17:24:15.601719",
-     "exception": false,
-     "start_time": "2024-03-22T17:23:42.210727",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "!pip uninstall apache-beam -y && pip install -U pandas polars pyarrow narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "1",
-   "metadata": {
-    "papermill": {
-     "duration": 0.907754,
-     "end_time": "2024-03-22T17:24:39.053873",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:38.146119",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "import pandas as pd\n",
-    "import polars as pl\n",
-    "\n",
-    "pd.options.mode.copy_on_write = True\n",
-    "pd.options.future.infer_string = True"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "2",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "from datetime import date\n",
-    "from typing import Any\n",
-    "\n",
-    "\n",
-    "def q3_pandas_native(\n",
-    "    customer_ds: Any,\n",
-    "    line_item_ds: Any,\n",
-    "    orders_ds: Any,\n",
-    ") -> Any:\n",
-    "    var1 = \"BUILDING\"\n",
-    "    var2 = date(1995, 3, 15)\n",
-    "\n",
-    "    fcustomer = customer_ds[customer_ds[\"c_mktsegment\"] == var1]\n",
-    "\n",
-    "    jn1 = fcustomer.merge(orders_ds, left_on=\"c_custkey\", right_on=\"o_custkey\")\n",
-    "    jn2 = jn1.merge(line_item_ds, left_on=\"o_orderkey\", right_on=\"l_orderkey\")\n",
-    "\n",
-    "    jn2 = jn2[jn2[\"o_orderdate\"] < var2]\n",
-    "    jn2 = jn2[jn2[\"l_shipdate\"] > var2]\n",
-    "    jn2[\"revenue\"] = jn2.l_extendedprice * (1 - jn2.l_discount)\n",
-    "\n",
-    "    gb = jn2.groupby([\"o_orderkey\", \"o_orderdate\", \"o_shippriority\"], as_index=False)\n",
-    "    agg = gb[\"revenue\"].sum()\n",
-    "\n",
-    "    sel = agg.loc[:, [\"o_orderkey\", \"revenue\", \"o_orderdate\", \"o_shippriority\"]]\n",
-    "    sel = sel.rename({\"o_orderkey\": \"l_orderkey\"}, axis=\"columns\")\n",
-    "\n",
-    "    sorted = sel.sort_values(by=[\"revenue\", \"o_orderdate\"], ascending=[False, True])\n",
-    "\n",
-    "    return sorted.head(10)  # type: ignore[no-any-return]"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "3",
-   "metadata": {
-    "papermill": {
-     "duration": 0.021725,
-     "end_time": "2024-03-22T17:24:39.080999",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.059274",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "from datetime import datetime\n",
-    "from typing import Any\n",
-    "\n",
-    "import narwhals as nw\n",
-    "\n",
-    "\n",
-    "def q3(\n",
-    "    customer_ds_raw: Any,\n",
-    "    line_item_ds_raw: Any,\n",
-    "    orders_ds_raw: Any,\n",
-    ") -> Any:\n",
-    "    var_1 = var_2 = datetime(1995, 3, 15)\n",
-    "    var_3 = \"BUILDING\"\n",
-    "\n",
-    "    customer_ds = nw.from_native(customer_ds_raw)\n",
-    "    line_item_ds = nw.from_native(line_item_ds_raw)\n",
-    "    orders_ds = nw.from_native(orders_ds_raw)\n",
-    "\n",
-    "    q_final = (\n",
-    "        customer_ds.filter(nw.col(\"c_mktsegment\") == var_3)\n",
-    "        .join(orders_ds, left_on=\"c_custkey\", right_on=\"o_custkey\")\n",
-    "        .join(line_item_ds, left_on=\"o_orderkey\", right_on=\"l_orderkey\")\n",
-    "        .filter(\n",
-    "            nw.col(\"o_orderdate\") < var_2,\n",
-    "            nw.col(\"l_shipdate\") > var_1,\n",
-    "        )\n",
-    "        .with_columns(\n",
-    "            (nw.col(\"l_extendedprice\") * (1 - nw.col(\"l_discount\"))).alias(\"revenue\")\n",
-    "        )\n",
-    "        .group_by([\"o_orderkey\", \"o_orderdate\", \"o_shippriority\"])\n",
-    "        .agg([nw.sum(\"revenue\")])\n",
-    "        .select(\n",
-    "            [\n",
-    "                nw.col(\"o_orderkey\").alias(\"l_orderkey\"),\n",
-    "                \"revenue\",\n",
-    "                \"o_orderdate\",\n",
-    "                \"o_shippriority\",\n",
-    "            ]\n",
-    "        )\n",
-    "        .sort(by=[\"revenue\", \"o_orderdate\"], descending=[True, False])\n",
-    "        .head(10)\n",
-    "    )\n",
-    "\n",
-    "    return nw.to_native(q_final)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "4",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "from typing import Any\n",
-    "\n",
-    "import ibis\n",
-    "\n",
-    "\n",
-    "def q3_ibis(\n",
-    "    customer: Any,\n",
-    "    lineitem: Any,\n",
-    "    orders: Any,\n",
-    "    *,\n",
-    "    tool: str,\n",
-    ") -> Any:\n",
-    "    var1 = \"BUILDING\"\n",
-    "    var2 = date(1995, 3, 15)\n",
-    "\n",
-    "    q_final = (\n",
-    "        customer.filter(customer[\"c_mktsegment\"] == var1)\n",
-    "        .join(orders, customer[\"c_custkey\"] == orders[\"o_custkey\"])\n",
-    "        .join(lineitem, orders[\"o_orderkey\"] == lineitem[\"l_orderkey\"])\n",
-    "        .filter(ibis._[\"o_orderdate\"] < var2)\n",
-    "        .filter(ibis._[\"l_shipdate\"] > var2)\n",
-    "        .mutate(revenue=(lineitem[\"l_extendedprice\"] * (1 - lineitem[\"l_discount\"])))\n",
-    "        .group_by(\n",
-    "            \"o_orderkey\",\n",
-    "            \"o_orderdate\",\n",
-    "            \"o_shippriority\",\n",
-    "        )\n",
-    "        .agg(revenue=ibis._[\"revenue\"].sum())\n",
-    "        .select(\n",
-    "            ibis._[\"o_orderkey\"].name(\"o_orderkey\"),\n",
-    "            \"revenue\",\n",
-    "            \"o_orderdate\",\n",
-    "            \"o_shippriority\",\n",
-    "        )\n",
-    "        .order_by(ibis.desc(\"revenue\"), \"o_orderdate\")\n",
-    "        .limit(10)\n",
-    "    )\n",
-    "    if tool == \"pandas\":\n",
-    "        return q_final.to_pandas()\n",
-    "    if tool == \"polars\":\n",
-    "        return q_final.to_polars()\n",
-    "    raise ValueError(\"expected pandas or polars\")"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "5",
-   "metadata": {
-    "papermill": {
-     "duration": 0.013325,
-     "end_time": "2024-03-22T17:24:39.099766",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.086441",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "dir_ = \"/kaggle/input/tpc-h-data-parquet-s-2/\"\n",
-    "region = dir_ + \"region.parquet\"\n",
-    "nation = dir_ + \"nation.parquet\"\n",
-    "customer = dir_ + \"customer.parquet\"\n",
-    "lineitem = dir_ + \"lineitem.parquet\"\n",
-    "orders = dir_ + \"orders.parquet\"\n",
-    "supplier = dir_ + \"supplier.parquet\"\n",
-    "part = dir_ + \"part.parquet\"\n",
-    "partsupp = dir_ + \"partsupp.parquet\""
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "6",
-   "metadata": {
-    "papermill": {
-     "duration": 0.014284,
-     "end_time": "2024-03-22T17:24:39.119737",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.105453",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "con_pd = ibis.pandas.connect()\n",
-    "con_pl = ibis.polars.connect()\n",
-    "\n",
-    "IO_FUNCS = {\n",
-    "    \"pandas\": lambda x: pd.read_parquet(x, engine=\"pyarrow\"),\n",
-    "    \"pandas[pyarrow]\": lambda x: pd.read_parquet(\n",
-    "        x, engine=\"pyarrow\", dtype_backend=\"pyarrow\"\n",
-    "    ),\n",
-    "    \"pandas[pyarrow][ibis]\": lambda x: con_pd.read_parquet(\n",
-    "        x, engine=\"pyarrow\", dtype_backend=\"pyarrow\"\n",
-    "    ),\n",
-    "    \"polars[eager]\": lambda x: pl.read_parquet(x),\n",
-    "    \"polars[lazy]\": lambda x: pl.scan_parquet(x),\n",
-    "    \"polars[lazy][ibis]\": lambda x: con_pl.read_parquet(x),\n",
-    "}"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "7",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "results = {}"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "8",
-   "metadata": {},
-   "source": [
-    "## pandas, pyarrow dtypes, via ibis"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "9",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "tool = \"pandas[pyarrow][ibis]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q3_ibis(fn(customer), fn(lineitem), fn(orders), tool='pandas')\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "10",
-   "metadata": {},
-   "source": [
-    "## Polars, lazy, via ibis"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "11",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "tool = \"polars[lazy][ibis]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q3_ibis(fn(customer), fn(lineitem), fn(orders), tool='polars')\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "12",
-   "metadata": {},
-   "source": [
-    "## pandas, pyarrow dtypes, native"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "13",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "tool = \"pandas[pyarrow]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q3_pandas_native(fn(customer), fn(lineitem), fn(orders))\n",
-    "results[tool + \"[native]\"] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "14",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005113,
-     "end_time": "2024-03-22T17:24:39.130472",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.125359",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## pandas via Narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "15",
-   "metadata": {
-    "papermill": {
-     "duration": 196.786925,
-     "end_time": "2024-03-22T17:27:55.922832",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.135907",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"pandas\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q3(fn(customer), fn(lineitem), fn(orders))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "16",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005184,
-     "end_time": "2024-03-22T17:27:55.933407",
-     "exception": false,
-     "start_time": "2024-03-22T17:27:55.928223",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## pandas, pyarrow dtypes, via Narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "17",
-   "metadata": {
-    "papermill": {
-     "duration": 158.748353,
-     "end_time": "2024-03-22T17:30:34.688289",
-     "exception": false,
-     "start_time": "2024-03-22T17:27:55.939936",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"pandas[pyarrow]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q3(fn(customer), fn(lineitem), fn(orders))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "18",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005773,
-     "end_time": "2024-03-22T17:30:34.700300",
-     "exception": false,
-     "start_time": "2024-03-22T17:30:34.694527",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## Polars read_parquet"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "19",
-   "metadata": {
-    "papermill": {
-     "duration": 37.821116,
-     "end_time": "2024-03-22T17:31:12.527466",
-     "exception": false,
-     "start_time": "2024-03-22T17:30:34.706350",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"polars[eager]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q3(fn(customer), fn(lineitem), fn(orders))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "20",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005515,
-     "end_time": "2024-03-22T17:31:12.539068",
-     "exception": false,
-     "start_time": "2024-03-22T17:31:12.533553",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## Polars scan_parquet"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "21",
-   "metadata": {
-    "papermill": {
-     "duration": 4.800698,
-     "end_time": "2024-03-22T17:31:17.346813",
-     "exception": false,
-     "start_time": "2024-03-22T17:31:12.546115",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"polars[lazy]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q3(fn(customer), fn(lineitem), fn(orders)).collect()\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "22",
-   "metadata": {},
-   "source": [
-    "## Save"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "23",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "import json\n",
-    "\n",
-    "with open(\"results.json\", \"w\") as fd:\n",
-    "    json.dump(results, fd)"
-   ]
-  }
- ],
- "metadata": {
-  "kaggle": {
-   "accelerator": "none",
-   "dataSources": [
-    {
-     "sourceId": 167796716,
-     "sourceType": "kernelVersion"
-    },
-    {
-     "sourceId": 167796934,
-     "sourceType": "kernelVersion"
-    },
-    {
-     "sourceId": 167796952,
-     "sourceType": "kernelVersion"
-    },
-    {
-     "sourceId": 167796969,
-     "sourceType": "kernelVersion"
-    }
-   ],
-   "isGpuEnabled": false,
-   "isInternetEnabled": true,
-   "language": "python",
-   "sourceType": "notebook"
-  },
-  "kernelspec": {
-   "display_name": "Python 3",
-   "language": "python",
-   "name": "python3"
-  },
-  "language_info": {
-   "codemirror_mode": {
-    "name": "ipython",
-    "version": 3
-   },
-   "file_extension": ".py",
-   "mimetype": "text/x-python",
-   "name": "python",
-   "nbconvert_exporter": "python",
-   "pygments_lexer": "ipython3",
-   "version": "3.10.13"
-  },
-  "papermill": {
-   "default_parameters": {},
-   "duration": 458.423327,
-   "end_time": "2024-03-22T17:31:18.077306",
-   "environment_variables": {},
-   "exception": null,
-   "input_path": "__notebook__.ipynb",
-   "output_path": "__notebook__.ipynb",
-   "parameters": {},
-   "start_time": "2024-03-22T17:23:39.653979",
-   "version": "2.5.0"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 5
-}
diff --git a/tpch/notebooks/q3/kernel-metadata.json b/tpch/notebooks/q3/kernel-metadata.json
deleted file mode 100644
index cd028810..00000000
--- a/tpch/notebooks/q3/kernel-metadata.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "id": "marcogorelli/narwhals-tpch-q3-s2",
-  "title": "Narwhals TPCH Q3 S2",
-  "code_file": "execute.ipynb",
-  "language": "python",
-  "kernel_type": "notebook",
-  "is_private": "false",
-  "enable_gpu": "false",
-  "enable_tpu": "false",
-  "enable_internet": "true",
-  "dataset_sources": [],
-  "competition_sources": [],
-  "kernel_sources": ["marcogorelli/tpc-h-data-parquet-s-2"],
-  "model_sources": []
-}
\ No newline at end of file
diff --git a/tpch/notebooks/q4/execute.ipynb b/tpch/notebooks/q4/execute.ipynb
deleted file mode 100755
index b0a55e34..00000000
--- a/tpch/notebooks/q4/execute.ipynb
+++ /dev/null
@@ -1,507 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "0",
-   "metadata": {
-    "papermill": {
-     "duration": 33.390992,
-     "end_time": "2024-03-22T17:24:15.601719",
-     "exception": false,
-     "start_time": "2024-03-22T17:23:42.210727",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "!pip uninstall apache-beam -y && pip install -U pandas polars pyarrow narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "1",
-   "metadata": {
-    "papermill": {
-     "duration": 0.907754,
-     "end_time": "2024-03-22T17:24:39.053873",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:38.146119",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "import pandas as pd\n",
-    "import polars as pl\n",
-    "\n",
-    "pd.options.mode.copy_on_write = True\n",
-    "pd.options.future.infer_string = True"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "2",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "from datetime import date\n",
-    "from typing import Any\n",
-    "\n",
-    "\n",
-    "def q4_pandas_native(\n",
-    "    line_item_ds: Any,\n",
-    "    orders_ds: Any,\n",
-    "):\n",
-    "    var1 = date(1993, 7, 1)\n",
-    "    var2 = date(1993, 10, 1)\n",
-    "\n",
-    "    jn = line_item_ds.merge(orders_ds, left_on=\"l_orderkey\", right_on=\"o_orderkey\")\n",
-    "\n",
-    "    jn = jn[\n",
-    "        (jn[\"o_orderdate\"] < var2)\n",
-    "        & (jn[\"o_orderdate\"] >= var1)\n",
-    "        & (jn[\"l_commitdate\"] < jn[\"l_receiptdate\"])\n",
-    "    ]\n",
-    "\n",
-    "    jn = jn.drop_duplicates(subset=[\"o_orderpriority\", \"l_orderkey\"])\n",
-    "\n",
-    "    gb = jn.groupby(\"o_orderpriority\", as_index=False)\n",
-    "    agg = gb.agg(order_count=pd.NamedAgg(column=\"o_orderkey\", aggfunc=\"count\"))\n",
-    "\n",
-    "    return agg.sort_values([\"o_orderpriority\"])  # type: ignore[no-any-return]"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "3",
-   "metadata": {
-    "papermill": {
-     "duration": 0.021725,
-     "end_time": "2024-03-22T17:24:39.080999",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.059274",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "from datetime import datetime\n",
-    "from typing import Any\n",
-    "\n",
-    "import narwhals as nw\n",
-    "\n",
-    "\n",
-    "def q4(\n",
-    "    lineitem_ds_raw: Any,\n",
-    "    orders_ds_raw: Any,\n",
-    ") -> Any:\n",
-    "    var_1 = datetime(1993, 7, 1)\n",
-    "    var_2 = datetime(1993, 10, 1)\n",
-    "\n",
-    "    line_item_ds = nw.from_native(lineitem_ds_raw)\n",
-    "    orders_ds = nw.from_native(orders_ds_raw)\n",
-    "\n",
-    "    result = (\n",
-    "        line_item_ds.join(orders_ds, left_on=\"l_orderkey\", right_on=\"o_orderkey\")\n",
-    "        .filter(\n",
-    "            nw.col(\"o_orderdate\").is_between(var_1, var_2, closed=\"left\"),\n",
-    "            nw.col(\"l_commitdate\") < nw.col(\"l_receiptdate\"),\n",
-    "        )\n",
-    "        .unique(subset=[\"o_orderpriority\", \"l_orderkey\"])\n",
-    "        .group_by(\"o_orderpriority\")\n",
-    "        .agg(nw.len().alias(\"order_count\"))\n",
-    "        .sort(by=\"o_orderpriority\")\n",
-    "        .with_columns(nw.col(\"order_count\").cast(nw.Int64))\n",
-    "    )\n",
-    "\n",
-    "    return nw.to_native(result)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "4",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "from typing import Any\n",
-    "\n",
-    "import ibis\n",
-    "\n",
-    "\n",
-    "def q4_ibis(lineitem: Any, orders: Any, *, tool: str) -> Any:\n",
-    "    var1 = datetime(1993, 7, 1)\n",
-    "    var2 = datetime(1993, 10, 1)\n",
-    "\n",
-    "    q_final = (\n",
-    "        lineitem.join(orders, lineitem[\"l_orderkey\"] == orders[\"o_orderkey\"])\n",
-    "        .filter((orders[\"o_orderdate\"] >= var1) & (orders[\"o_orderdate\"] < var2))\n",
-    "        .filter(lineitem[\"l_commitdate\"] < lineitem[\"l_receiptdate\"])\n",
-    "        .distinct(on=[\"o_orderpriority\", \"l_orderkey\"])\n",
-    "        .group_by(\"o_orderpriority\")\n",
-    "        .agg(order_count=ibis._.count())\n",
-    "        .order_by(\"o_orderpriority\")\n",
-    "    )\n",
-    "    if tool == \"pandas\":\n",
-    "        return q_final.to_pandas()\n",
-    "    if tool == \"polars\":\n",
-    "        return q_final.to_polars()\n",
-    "    raise ValueError(\"expected pandas or polars\")"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "5",
-   "metadata": {
-    "papermill": {
-     "duration": 0.013325,
-     "end_time": "2024-03-22T17:24:39.099766",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.086441",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "dir_ = \"/kaggle/input/tpc-h-data-parquet-s-2/\"\n",
-    "region = dir_ + \"region.parquet\"\n",
-    "nation = dir_ + \"nation.parquet\"\n",
-    "customer = dir_ + \"customer.parquet\"\n",
-    "lineitem = dir_ + \"lineitem.parquet\"\n",
-    "orders = dir_ + \"orders.parquet\"\n",
-    "supplier = dir_ + \"supplier.parquet\"\n",
-    "part = dir_ + \"part.parquet\"\n",
-    "partsupp = dir_ + \"partsupp.parquet\""
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "6",
-   "metadata": {
-    "papermill": {
-     "duration": 0.014284,
-     "end_time": "2024-03-22T17:24:39.119737",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.105453",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "con_pd = ibis.pandas.connect()\n",
-    "con_pl = ibis.polars.connect()\n",
-    "\n",
-    "IO_FUNCS = {\n",
-    "    \"pandas\": lambda x: pd.read_parquet(x, engine=\"pyarrow\"),\n",
-    "    \"pandas[pyarrow]\": lambda x: pd.read_parquet(\n",
-    "        x, engine=\"pyarrow\", dtype_backend=\"pyarrow\"\n",
-    "    ),\n",
-    "    \"pandas[pyarrow][ibis]\": lambda x: con_pd.read_parquet(\n",
-    "        x, engine=\"pyarrow\", dtype_backend=\"pyarrow\"\n",
-    "    ),\n",
-    "    \"polars[eager]\": lambda x: pl.read_parquet(x),\n",
-    "    \"polars[lazy]\": lambda x: pl.scan_parquet(x),\n",
-    "    \"polars[lazy][ibis]\": lambda x: con_pl.read_parquet(x),\n",
-    "}"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "7",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "results = {}"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "8",
-   "metadata": {},
-   "source": [
-    "## polars, lazy, via ibis"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "9",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "tool = \"polars[lazy][ibis]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q4_ibis(fn(lineitem), fn(orders), tool='polars')\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "10",
-   "metadata": {},
-   "source": [
-    "## pandas, pyarrow dtype, via Narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "11",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "tool = \"pandas[pyarrow]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q4_pandas_native(fn(lineitem), fn(orders))\n",
-    "results[tool + \"[native]\"] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "12",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005113,
-     "end_time": "2024-03-22T17:24:39.130472",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.125359",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## pandas via Narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "13",
-   "metadata": {
-    "papermill": {
-     "duration": 196.786925,
-     "end_time": "2024-03-22T17:27:55.922832",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.135907",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"pandas\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q4(fn(lineitem), fn(orders))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "14",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005184,
-     "end_time": "2024-03-22T17:27:55.933407",
-     "exception": false,
-     "start_time": "2024-03-22T17:27:55.928223",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## pandas, pyarrow dtypes, via Narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "15",
-   "metadata": {
-    "papermill": {
-     "duration": 158.748353,
-     "end_time": "2024-03-22T17:30:34.688289",
-     "exception": false,
-     "start_time": "2024-03-22T17:27:55.939936",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"pandas[pyarrow]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q4(fn(lineitem), fn(orders))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "16",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005773,
-     "end_time": "2024-03-22T17:30:34.700300",
-     "exception": false,
-     "start_time": "2024-03-22T17:30:34.694527",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## Polars read_parquet"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "17",
-   "metadata": {
-    "papermill": {
-     "duration": 37.821116,
-     "end_time": "2024-03-22T17:31:12.527466",
-     "exception": false,
-     "start_time": "2024-03-22T17:30:34.706350",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"polars[eager]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q4(fn(lineitem), fn(orders))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "18",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005515,
-     "end_time": "2024-03-22T17:31:12.539068",
-     "exception": false,
-     "start_time": "2024-03-22T17:31:12.533553",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## Polars scan_parquet"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "19",
-   "metadata": {
-    "papermill": {
-     "duration": 4.800698,
-     "end_time": "2024-03-22T17:31:17.346813",
-     "exception": false,
-     "start_time": "2024-03-22T17:31:12.546115",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"polars[lazy]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q4(fn(lineitem), fn(orders)).collect()\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "20",
-   "metadata": {},
-   "source": [
-    "## Save"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "21",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "import json\n",
-    "\n",
-    "with open(\"results.json\", \"w\") as fd:\n",
-    "    json.dump(results, fd)"
-   ]
-  }
- ],
- "metadata": {
-  "kaggle": {
-   "accelerator": "none",
-   "dataSources": [
-    {
-     "sourceId": 167796716,
-     "sourceType": "kernelVersion"
-    },
-    {
-     "sourceId": 167796934,
-     "sourceType": "kernelVersion"
-    },
-    {
-     "sourceId": 167796952,
-     "sourceType": "kernelVersion"
-    },
-    {
-     "sourceId": 167796969,
-     "sourceType": "kernelVersion"
-    }
-   ],
-   "isGpuEnabled": false,
-   "isInternetEnabled": true,
-   "language": "python",
-   "sourceType": "notebook"
-  },
-  "kernelspec": {
-   "display_name": "Python 3",
-   "language": "python",
-   "name": "python3"
-  },
-  "language_info": {
-   "codemirror_mode": {
-    "name": "ipython",
-    "version": 3
-   },
-   "file_extension": ".py",
-   "mimetype": "text/x-python",
-   "name": "python",
-   "nbconvert_exporter": "python",
-   "pygments_lexer": "ipython3",
-   "version": "3.10.13"
-  },
-  "papermill": {
-   "default_parameters": {},
-   "duration": 458.423327,
-   "end_time": "2024-03-22T17:31:18.077306",
-   "environment_variables": {},
-   "exception": null,
-   "input_path": "__notebook__.ipynb",
-   "output_path": "__notebook__.ipynb",
-   "parameters": {},
-   "start_time": "2024-03-22T17:23:39.653979",
-   "version": "2.5.0"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 5
-}
diff --git a/tpch/notebooks/q4/kernel-metadata.json b/tpch/notebooks/q4/kernel-metadata.json
deleted file mode 100644
index 4e3936fb..00000000
--- a/tpch/notebooks/q4/kernel-metadata.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "id": "marcogorelli/narwhals-tpch-q4-s2",
-  "title": "Narwhals TPCH Q4 S2",
-  "code_file": "execute.ipynb",
-  "language": "python",
-  "kernel_type": "notebook",
-  "is_private": "false",
-  "enable_gpu": "false",
-  "enable_tpu": "false",
-  "enable_internet": "true",
-  "dataset_sources": [],
-  "competition_sources": [],
-  "kernel_sources": ["marcogorelli/tpc-h-data-parquet-s-2"],
-  "model_sources": []
-}
\ No newline at end of file
diff --git a/tpch/notebooks/q5/execute.ipynb b/tpch/notebooks/q5/execute.ipynb
deleted file mode 100755
index da0cae78..00000000
--- a/tpch/notebooks/q5/execute.ipynb
+++ /dev/null
@@ -1,543 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "0",
-   "metadata": {
-    "papermill": {
-     "duration": 33.390992,
-     "end_time": "2024-03-22T17:24:15.601719",
-     "exception": false,
-     "start_time": "2024-03-22T17:23:42.210727",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "!pip uninstall apache-beam -y && pip install -U pandas polars pyarrow narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "1",
-   "metadata": {
-    "papermill": {
-     "duration": 0.907754,
-     "end_time": "2024-03-22T17:24:39.053873",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:38.146119",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "import pandas as pd\n",
-    "import polars as pl\n",
-    "\n",
-    "pd.options.mode.copy_on_write = True\n",
-    "pd.options.future.infer_string = True"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "2",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "from datetime import date\n",
-    "from typing import Any\n",
-    "\n",
-    "\n",
-    "def q5_pandas_native(\n",
-    "    region_ds: Any,\n",
-    "    nation_ds: Any,\n",
-    "    customer_ds: Any,\n",
-    "    line_item_ds: Any,\n",
-    "    orders_ds: Any,\n",
-    "    supplier_ds: Any,\n",
-    "):\n",
-    "    var1 = \"ASIA\"\n",
-    "    var2 = date(1994, 1, 1)\n",
-    "    var3 = date(1995, 1, 1)\n",
-    "\n",
-    "    jn1 = region_ds.merge(nation_ds, left_on=\"r_regionkey\", right_on=\"n_regionkey\")\n",
-    "    jn2 = jn1.merge(customer_ds, left_on=\"n_nationkey\", right_on=\"c_nationkey\")\n",
-    "    jn3 = jn2.merge(orders_ds, left_on=\"c_custkey\", right_on=\"o_custkey\")\n",
-    "    jn4 = jn3.merge(line_item_ds, left_on=\"o_orderkey\", right_on=\"l_orderkey\")\n",
-    "    jn5 = jn4.merge(\n",
-    "        supplier_ds,\n",
-    "        left_on=[\"l_suppkey\", \"n_nationkey\"],\n",
-    "        right_on=[\"s_suppkey\", \"s_nationkey\"],\n",
-    "    )\n",
-    "\n",
-    "    jn5 = jn5[jn5[\"r_name\"] == var1]\n",
-    "    jn5 = jn5[(jn5[\"o_orderdate\"] >= var2) & (jn5[\"o_orderdate\"] < var3)]\n",
-    "    jn5[\"revenue\"] = jn5.l_extendedprice * (1.0 - jn5.l_discount)\n",
-    "\n",
-    "    gb = jn5.groupby(\"n_name\", as_index=False)[\"revenue\"].sum()\n",
-    "\n",
-    "    return gb.sort_values(\"revenue\", ascending=False)  # type: ignore[no-any-return]"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "3",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "from datetime import datetime\n",
-    "from typing import Any\n",
-    "\n",
-    "import narwhals as nw\n",
-    "\n",
-    "\n",
-    "def q5(\n",
-    "    region_ds_raw: Any,\n",
-    "    nation_ds_raw: Any,\n",
-    "    customer_ds_raw: Any,\n",
-    "    lineitem_ds_raw: Any,\n",
-    "    orders_ds_raw: Any,\n",
-    "    supplier_ds_raw: Any,\n",
-    ") -> Any:\n",
-    "    var_1 = \"ASIA\"\n",
-    "    var_2 = datetime(1994, 1, 1)\n",
-    "    var_3 = datetime(1995, 1, 1)\n",
-    "\n",
-    "    region_ds = nw.from_native(region_ds_raw)\n",
-    "    nation_ds = nw.from_native(nation_ds_raw)\n",
-    "    customer_ds = nw.from_native(customer_ds_raw)\n",
-    "    line_item_ds = nw.from_native(lineitem_ds_raw)\n",
-    "    orders_ds = nw.from_native(orders_ds_raw)\n",
-    "    supplier_ds = nw.from_native(supplier_ds_raw)\n",
-    "\n",
-    "    result = (\n",
-    "        region_ds.join(nation_ds, left_on=\"r_regionkey\", right_on=\"n_regionkey\")\n",
-    "        .join(customer_ds, left_on=\"n_nationkey\", right_on=\"c_nationkey\")\n",
-    "        .join(orders_ds, left_on=\"c_custkey\", right_on=\"o_custkey\")\n",
-    "        .join(line_item_ds, left_on=\"o_orderkey\", right_on=\"l_orderkey\")\n",
-    "        .join(\n",
-    "            supplier_ds,\n",
-    "            left_on=[\"l_suppkey\", \"n_nationkey\"],\n",
-    "            right_on=[\"s_suppkey\", \"s_nationkey\"],\n",
-    "        )\n",
-    "        .filter(\n",
-    "            nw.col(\"r_name\") == var_1,\n",
-    "            nw.col(\"o_orderdate\").is_between(var_2, var_3, closed=\"left\"),\n",
-    "        )\n",
-    "        .with_columns(\n",
-    "            (nw.col(\"l_extendedprice\") * (1 - nw.col(\"l_discount\"))).alias(\"revenue\")\n",
-    "        )\n",
-    "        .group_by(\"n_name\")\n",
-    "        .agg([nw.sum(\"revenue\")])\n",
-    "        .sort(by=\"revenue\", descending=True)\n",
-    "    )\n",
-    "\n",
-    "    return nw.to_native(result)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "4",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "from typing import Any\n",
-    "\n",
-    "import ibis\n",
-    "\n",
-    "\n",
-    "def q5_ibis(\n",
-    "    region: Any,\n",
-    "    nation: Any,\n",
-    "    customer: Any,\n",
-    "    lineitem: Any,\n",
-    "    orders: Any,\n",
-    "    supplier: Any,\n",
-    "    *,\n",
-    "    tool: str,\n",
-    ") -> Any:\n",
-    "    var1 = \"ASIA\"\n",
-    "    var2 = datetime(1994, 1, 1)\n",
-    "    var3 = datetime(1995, 1, 1)\n",
-    "\n",
-    "    q_final = (\n",
-    "        region.join(nation, region[\"r_regionkey\"] == nation[\"n_regionkey\"])\n",
-    "        .join(customer, ibis._[\"n_nationkey\"] == customer[\"c_nationkey\"])\n",
-    "        .join(orders, ibis._[\"c_custkey\"] == orders[\"o_custkey\"])\n",
-    "        .join(lineitem, ibis._[\"o_orderkey\"] == lineitem[\"l_orderkey\"])\n",
-    "        .join(\n",
-    "            supplier,\n",
-    "            (ibis._[\"l_suppkey\"] == supplier[\"s_suppkey\"])\n",
-    "            & (ibis._[\"n_nationkey\"] == supplier[\"s_nationkey\"]),\n",
-    "        )\n",
-    "        .filter(ibis._[\"r_name\"] == var1)\n",
-    "        .filter((ibis._[\"o_orderdate\"] >= var2) & (ibis._[\"o_orderdate\"] < var3))\n",
-    "        .mutate(revenue=(lineitem[\"l_extendedprice\"] * (1 - lineitem[\"l_discount\"])))\n",
-    "        .group_by(\"n_name\")\n",
-    "        .agg(revenue=ibis._[\"revenue\"].sum())\n",
-    "        .order_by(ibis.desc(\"revenue\"))\n",
-    "    )\n",
-    "\n",
-    "    if tool == \"pandas\":\n",
-    "        return q_final.to_pandas()\n",
-    "    if tool == \"polars\":\n",
-    "        return q_final.to_polars()\n",
-    "    raise ValueError(\"expected pandas or polars\")"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "5",
-   "metadata": {
-    "papermill": {
-     "duration": 0.013325,
-     "end_time": "2024-03-22T17:24:39.099766",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.086441",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "dir_ = \"/kaggle/input/tpc-h-data-parquet-s-2/\"\n",
-    "region = dir_ + \"region.parquet\"\n",
-    "nation = dir_ + \"nation.parquet\"\n",
-    "customer = dir_ + \"customer.parquet\"\n",
-    "lineitem = dir_ + \"lineitem.parquet\"\n",
-    "orders = dir_ + \"orders.parquet\"\n",
-    "supplier = dir_ + \"supplier.parquet\"\n",
-    "part = dir_ + \"part.parquet\"\n",
-    "partsupp = dir_ + \"partsupp.parquet\""
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "6",
-   "metadata": {
-    "papermill": {
-     "duration": 0.014284,
-     "end_time": "2024-03-22T17:24:39.119737",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.105453",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "con_pd = ibis.pandas.connect()\n",
-    "con_pl = ibis.polars.connect()\n",
-    "\n",
-    "IO_FUNCS = {\n",
-    "    \"pandas\": lambda x: pd.read_parquet(x, engine=\"pyarrow\"),\n",
-    "    \"pandas[pyarrow]\": lambda x: pd.read_parquet(\n",
-    "        x, engine=\"pyarrow\", dtype_backend=\"pyarrow\"\n",
-    "    ),\n",
-    "    \"pandas[pyarrow][ibis]\": lambda x: con_pd.read_parquet(\n",
-    "        x, engine=\"pyarrow\", dtype_backend=\"pyarrow\"\n",
-    "    ),\n",
-    "    \"polars[eager]\": lambda x: pl.read_parquet(x),\n",
-    "    \"polars[lazy]\": lambda x: pl.scan_parquet(x),\n",
-    "    \"polars[lazy][ibis]\": lambda x: con_pl.read_parquet(x),\n",
-    "}"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "7",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "results = {}"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "8",
-   "metadata": {},
-   "source": [
-    "## Polars, lazy, via ibis"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "9",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "tool = \"polars[lazy][ibis]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q5_ibis(fn(region), fn(nation), fn(customer), fn(lineitem), fn(orders), fn(supplier), tool='polars')\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "10",
-   "metadata": {},
-   "source": [
-    "## pandas, pyarrow dtypes, native"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "11",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "tool = \"pandas[pyarrow]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q5_pandas_native(fn(region), fn(nation), fn(customer), fn(lineitem), fn(orders), fn(supplier))\n",
-    "results[tool + \"[native]\"] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "12",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005113,
-     "end_time": "2024-03-22T17:24:39.130472",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.125359",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## pandas via Narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "13",
-   "metadata": {
-    "papermill": {
-     "duration": 196.786925,
-     "end_time": "2024-03-22T17:27:55.922832",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.135907",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"pandas\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q5(fn(region), fn(nation), fn(customer), fn(lineitem), fn(orders), fn(supplier))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "14",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005184,
-     "end_time": "2024-03-22T17:27:55.933407",
-     "exception": false,
-     "start_time": "2024-03-22T17:27:55.928223",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## pandas, pyarrow dtypes, via Narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "15",
-   "metadata": {
-    "papermill": {
-     "duration": 158.748353,
-     "end_time": "2024-03-22T17:30:34.688289",
-     "exception": false,
-     "start_time": "2024-03-22T17:27:55.939936",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"pandas[pyarrow]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q5(fn(region), fn(nation), fn(customer), fn(lineitem), fn(orders), fn(supplier))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "16",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005773,
-     "end_time": "2024-03-22T17:30:34.700300",
-     "exception": false,
-     "start_time": "2024-03-22T17:30:34.694527",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## Polars read_parquet"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "17",
-   "metadata": {
-    "papermill": {
-     "duration": 37.821116,
-     "end_time": "2024-03-22T17:31:12.527466",
-     "exception": false,
-     "start_time": "2024-03-22T17:30:34.706350",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"polars[eager]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q5(fn(region), fn(nation), fn(customer), fn(lineitem), fn(orders), fn(supplier))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "18",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005515,
-     "end_time": "2024-03-22T17:31:12.539068",
-     "exception": false,
-     "start_time": "2024-03-22T17:31:12.533553",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## Polars scan_parquet"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "19",
-   "metadata": {
-    "papermill": {
-     "duration": 4.800698,
-     "end_time": "2024-03-22T17:31:17.346813",
-     "exception": false,
-     "start_time": "2024-03-22T17:31:12.546115",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"polars[lazy]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q5(fn(region), fn(nation), fn(customer), fn(lineitem), fn(orders), fn(supplier)).collect()\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "20",
-   "metadata": {},
-   "source": [
-    "## Save"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "21",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "import json\n",
-    "\n",
-    "with open(\"results.json\", \"w\") as fd:\n",
-    "    json.dump(results, fd)"
-   ]
-  }
- ],
- "metadata": {
-  "kaggle": {
-   "accelerator": "none",
-   "dataSources": [
-    {
-     "sourceId": 167796716,
-     "sourceType": "kernelVersion"
-    },
-    {
-     "sourceId": 167796934,
-     "sourceType": "kernelVersion"
-    },
-    {
-     "sourceId": 167796952,
-     "sourceType": "kernelVersion"
-    },
-    {
-     "sourceId": 167796969,
-     "sourceType": "kernelVersion"
-    }
-   ],
-   "isGpuEnabled": false,
-   "isInternetEnabled": true,
-   "language": "python",
-   "sourceType": "notebook"
-  },
-  "kernelspec": {
-   "display_name": "Python 3",
-   "language": "python",
-   "name": "python3"
-  },
-  "language_info": {
-   "codemirror_mode": {
-    "name": "ipython",
-    "version": 3
-   },
-   "file_extension": ".py",
-   "mimetype": "text/x-python",
-   "name": "python",
-   "nbconvert_exporter": "python",
-   "pygments_lexer": "ipython3",
-   "version": "3.10.13"
-  },
-  "papermill": {
-   "default_parameters": {},
-   "duration": 458.423327,
-   "end_time": "2024-03-22T17:31:18.077306",
-   "environment_variables": {},
-   "exception": null,
-   "input_path": "__notebook__.ipynb",
-   "output_path": "__notebook__.ipynb",
-   "parameters": {},
-   "start_time": "2024-03-22T17:23:39.653979",
-   "version": "2.5.0"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 5
-}
diff --git a/tpch/notebooks/q5/kernel-metadata.json b/tpch/notebooks/q5/kernel-metadata.json
deleted file mode 100644
index fe2fecc9..00000000
--- a/tpch/notebooks/q5/kernel-metadata.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "id": "marcogorelli/narwhals-tpch-q5-s2",
-  "title": "Narwhals TPCH Q5 S2",
-  "code_file": "execute.ipynb",
-  "language": "python",
-  "kernel_type": "notebook",
-  "is_private": "false",
-  "enable_gpu": "false",
-  "enable_tpu": "false",
-  "enable_internet": "true",
-  "dataset_sources": [],
-  "competition_sources": [],
-  "kernel_sources": ["marcogorelli/tpc-h-data-parquet-s-2"],
-  "model_sources": []
-}
\ No newline at end of file
diff --git a/tpch/notebooks/q6/execute.ipynb b/tpch/notebooks/q6/execute.ipynb
deleted file mode 100755
index 5abcb65f..00000000
--- a/tpch/notebooks/q6/execute.ipynb
+++ /dev/null
@@ -1,516 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "0",
-   "metadata": {
-    "papermill": {
-     "duration": 33.390992,
-     "end_time": "2024-03-22T17:24:15.601719",
-     "exception": false,
-     "start_time": "2024-03-22T17:23:42.210727",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "!pip uninstall apache-beam -y && pip install -U pandas polars pyarrow narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "1",
-   "metadata": {
-    "papermill": {
-     "duration": 0.907754,
-     "end_time": "2024-03-22T17:24:39.053873",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:38.146119",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "import pandas as pd\n",
-    "import polars as pl\n",
-    "\n",
-    "pd.options.mode.copy_on_write = True"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "2",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "from datetime import date\n",
-    "\n",
-    "\n",
-    "def q6_pandas_native(line_item_ds):\n",
-    "    var1 = date(1994, 1, 1)\n",
-    "    var2 = date(1995, 1, 1)\n",
-    "    var3 = 0.05\n",
-    "    var4 = 0.07\n",
-    "    var5 = 24\n",
-    "\n",
-    "    flineitem = line_item_ds[\n",
-    "        (line_item_ds[\"l_shipdate\"] >= var1)\n",
-    "        & (line_item_ds[\"l_shipdate\"] < var2)\n",
-    "        & (line_item_ds[\"l_discount\"] >= var3)\n",
-    "        & (line_item_ds[\"l_discount\"] <= var4)\n",
-    "        & (line_item_ds[\"l_quantity\"] < var5)\n",
-    "    ]\n",
-    "\n",
-    "    result_value = (flineitem[\"l_extendedprice\"] * flineitem[\"l_discount\"]).sum()\n",
-    "\n",
-    "    return pd.DataFrame({\"revenue\": [result_value]})"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "3",
-   "metadata": {
-    "papermill": {
-     "duration": 0.021725,
-     "end_time": "2024-03-22T17:24:39.080999",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.059274",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "from datetime import datetime\n",
-    "\n",
-    "import narwhals as nw\n",
-    "\n",
-    "\n",
-    "def q6(line_item_raw) -> None:\n",
-    "    var_1 = datetime(1994, 1, 1)\n",
-    "    var_2 = datetime(1995, 1, 1)\n",
-    "    var_3 = 24\n",
-    "\n",
-    "    line_item_ds = nw.from_native(line_item_raw)\n",
-    "\n",
-    "    result = (\n",
-    "        line_item_ds.filter(\n",
-    "            nw.col(\"l_shipdate\").is_between(var_1, var_2, closed=\"left\"),\n",
-    "            nw.col(\"l_discount\").is_between(0.05, 0.07),\n",
-    "            nw.col(\"l_quantity\") < var_3,\n",
-    "        )\n",
-    "        .with_columns((nw.col(\"l_extendedprice\") * nw.col(\"l_discount\")).alias(\"revenue\"))\n",
-    "        .select(nw.sum(\"revenue\"))\n",
-    "    )\n",
-    "    return nw.to_native(result)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "4",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "def q6_ibis(lineitem, *, tool: str) -> None:\n",
-    "    var1 = datetime(1994, 1, 1)\n",
-    "    var2 = datetime(1995, 1, 1)\n",
-    "    var3 = 0.05\n",
-    "    var4 = 0.07\n",
-    "    var5 = 24\n",
-    "\n",
-    "    q_final = (\n",
-    "        lineitem.filter(\n",
-    "            (lineitem[\"l_shipdate\"] >= var1) & (lineitem[\"l_shipdate\"] < var2)\n",
-    "        )\n",
-    "        .filter((lineitem[\"l_discount\"] >= var3) & (lineitem[\"l_discount\"] <= var4))\n",
-    "        .filter(lineitem[\"l_quantity\"] < var5)\n",
-    "        .mutate(revenue=ibis._[\"l_extendedprice\"] * (ibis._[\"l_discount\"]))\n",
-    "        .agg(revenue=ibis._[\"revenue\"].sum())\n",
-    "    )\n",
-    "\n",
-    "    if tool == \"pandas\":\n",
-    "        return q_final.to_pandas()\n",
-    "    if tool == \"polars\":\n",
-    "        return q_final.to_polars()\n",
-    "    raise ValueError(\"expected pandas or polars\")"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "5",
-   "metadata": {
-    "papermill": {
-     "duration": 0.013325,
-     "end_time": "2024-03-22T17:24:39.099766",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.086441",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "dir_ = \"/kaggle/input/tpc-h-data-parquet-s-2/\"\n",
-    "region = dir_ + \"region.parquet\"\n",
-    "nation = dir_ + \"nation.parquet\"\n",
-    "customer = dir_ + \"customer.parquet\"\n",
-    "lineitem = dir_ + \"lineitem.parquet\"\n",
-    "orders = dir_ + \"orders.parquet\"\n",
-    "supplier = dir_ + \"supplier.parquet\"\n",
-    "part = dir_ + \"part.parquet\"\n",
-    "partsupp = dir_ + \"partsupp.parquet\""
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "6",
-   "metadata": {
-    "papermill": {
-     "duration": 0.014284,
-     "end_time": "2024-03-22T17:24:39.119737",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.105453",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "import ibis\n",
-    "\n",
-    "con_pd = ibis.pandas.connect()\n",
-    "con_pl = ibis.polars.connect()\n",
-    "\n",
-    "IO_FUNCS = {\n",
-    "    \"pandas\": lambda x: pd.read_parquet(x, engine=\"pyarrow\"),\n",
-    "    \"pandas[pyarrow]\": lambda x: pd.read_parquet(\n",
-    "        x, engine=\"pyarrow\", dtype_backend=\"pyarrow\"\n",
-    "    ),\n",
-    "    \"pandas[pyarrow][ibis]\": lambda x: con_pd.read_parquet(\n",
-    "        x, engine=\"pyarrow\", dtype_backend=\"pyarrow\"\n",
-    "    ),\n",
-    "    \"polars[eager]\": lambda x: pl.read_parquet(x),\n",
-    "    \"polars[lazy]\": lambda x: pl.scan_parquet(x),\n",
-    "    \"polars[lazy][ibis]\": lambda x: con_pl.read_parquet(x),\n",
-    "}"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "7",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "results = {}"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "8",
-   "metadata": {},
-   "source": [
-    "## pandas, pyarrow dtypes, via ibis"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "9",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "tool = \"pandas[pyarrow][ibis]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q6_ibis(fn(lineitem), tool='pandas')\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "10",
-   "metadata": {},
-   "source": [
-    "## polars, lazy, via ibis"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "11",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "tool = \"polars[lazy][ibis]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q6_ibis(fn(lineitem), tool='polars')\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "12",
-   "metadata": {},
-   "source": [
-    "## pandas, pyarrow dtypes, native"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "13",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "tool = \"pandas[pyarrow]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q6_pandas_native(fn(lineitem))\n",
-    "results[tool + \"[native]\"] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "14",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005113,
-     "end_time": "2024-03-22T17:24:39.130472",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.125359",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## pandas via Narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "15",
-   "metadata": {
-    "papermill": {
-     "duration": 196.786925,
-     "end_time": "2024-03-22T17:27:55.922832",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.135907",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"pandas\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q6(fn(lineitem))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "16",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005184,
-     "end_time": "2024-03-22T17:27:55.933407",
-     "exception": false,
-     "start_time": "2024-03-22T17:27:55.928223",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## pandas, pyarrow dtypes, via Narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "17",
-   "metadata": {
-    "papermill": {
-     "duration": 158.748353,
-     "end_time": "2024-03-22T17:30:34.688289",
-     "exception": false,
-     "start_time": "2024-03-22T17:27:55.939936",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"pandas[pyarrow]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q6(fn(lineitem))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "18",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005773,
-     "end_time": "2024-03-22T17:30:34.700300",
-     "exception": false,
-     "start_time": "2024-03-22T17:30:34.694527",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## Polars read_parquet"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "19",
-   "metadata": {
-    "papermill": {
-     "duration": 37.821116,
-     "end_time": "2024-03-22T17:31:12.527466",
-     "exception": false,
-     "start_time": "2024-03-22T17:30:34.706350",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"polars[eager]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q6(fn(lineitem))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "20",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005515,
-     "end_time": "2024-03-22T17:31:12.539068",
-     "exception": false,
-     "start_time": "2024-03-22T17:31:12.533553",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## Polars scan_parquet"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "21",
-   "metadata": {
-    "papermill": {
-     "duration": 4.800698,
-     "end_time": "2024-03-22T17:31:17.346813",
-     "exception": false,
-     "start_time": "2024-03-22T17:31:12.546115",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"polars[lazy]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q6(fn(lineitem)).collect()\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "22",
-   "metadata": {},
-   "source": [
-    "## Save"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "23",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "import json\n",
-    "\n",
-    "with open(\"results.json\", \"w\") as fd:\n",
-    "    json.dump(results, fd)"
-   ]
-  }
- ],
- "metadata": {
-  "kaggle": {
-   "accelerator": "none",
-   "dataSources": [
-    {
-     "sourceId": 167796716,
-     "sourceType": "kernelVersion"
-    },
-    {
-     "sourceId": 167796934,
-     "sourceType": "kernelVersion"
-    },
-    {
-     "sourceId": 167796952,
-     "sourceType": "kernelVersion"
-    },
-    {
-     "sourceId": 167796969,
-     "sourceType": "kernelVersion"
-    }
-   ],
-   "isGpuEnabled": false,
-   "isInternetEnabled": true,
-   "language": "python",
-   "sourceType": "notebook"
-  },
-  "kernelspec": {
-   "display_name": "Python 3",
-   "language": "python",
-   "name": "python3"
-  },
-  "language_info": {
-   "codemirror_mode": {
-    "name": "ipython",
-    "version": 3
-   },
-   "file_extension": ".py",
-   "mimetype": "text/x-python",
-   "name": "python",
-   "nbconvert_exporter": "python",
-   "pygments_lexer": "ipython3",
-   "version": "3.10.13"
-  },
-  "papermill": {
-   "default_parameters": {},
-   "duration": 458.423327,
-   "end_time": "2024-03-22T17:31:18.077306",
-   "environment_variables": {},
-   "exception": null,
-   "input_path": "__notebook__.ipynb",
-   "output_path": "__notebook__.ipynb",
-   "parameters": {},
-   "start_time": "2024-03-22T17:23:39.653979",
-   "version": "2.5.0"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 5
-}
diff --git a/tpch/notebooks/q6/kernel-metadata.json b/tpch/notebooks/q6/kernel-metadata.json
deleted file mode 100644
index d653fd2e..00000000
--- a/tpch/notebooks/q6/kernel-metadata.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "id": "marcogorelli/narwhals-tpch-q6-s2",
-  "title": "Narwhals TPCH Q6 S2",
-  "code_file": "execute.ipynb",
-  "language": "python",
-  "kernel_type": "notebook",
-  "is_private": "false",
-  "enable_gpu": "false",
-  "enable_tpu": "false",
-  "enable_internet": "true",
-  "dataset_sources": [],
-  "competition_sources": [],
-  "kernel_sources": ["marcogorelli/tpc-h-data-parquet-s-2"],
-  "model_sources": []
-}
\ No newline at end of file
diff --git a/tpch/notebooks/q7/execute.ipynb b/tpch/notebooks/q7/execute.ipynb
deleted file mode 100755
index 8711d750..00000000
--- a/tpch/notebooks/q7/execute.ipynb
+++ /dev/null
@@ -1,603 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "0",
-   "metadata": {
-    "papermill": {
-     "duration": 33.390992,
-     "end_time": "2024-03-22T17:24:15.601719",
-     "exception": false,
-     "start_time": "2024-03-22T17:23:42.210727",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "!pip uninstall apache-beam -y && pip install -U pandas polars pyarrow narwhals ibis-framework"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "1",
-   "metadata": {
-    "papermill": {
-     "duration": 0.907754,
-     "end_time": "2024-03-22T17:24:39.053873",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:38.146119",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "import pandas as pd\n",
-    "import polars as pl\n",
-    "\n",
-    "pd.options.mode.copy_on_write = True\n",
-    "pd.options.future.infer_string = True"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "2",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "from datetime import date\n",
-    "from datetime import datetime\n",
-    "from typing import Any\n",
-    "\n",
-    "import narwhals as nw\n",
-    "\n",
-    "\n",
-    "def q7_pandas_native(\n",
-    "    nation_ds,\n",
-    "    customer_ds,\n",
-    "    line_item_ds,\n",
-    "    orders_ds,\n",
-    "    supplier_ds,\n",
-    ") -> None:\n",
-    "    var1 = \"FRANCE\"\n",
-    "    var2 = \"GERMANY\"\n",
-    "    var3 = date(1995, 1, 1)\n",
-    "    var4 = date(1996, 12, 31)\n",
-    "\n",
-    "    n1 = nation_ds[(nation_ds[\"n_name\"] == var1)]\n",
-    "    n2 = nation_ds[(nation_ds[\"n_name\"] == var2)]\n",
-    "\n",
-    "    # Part 1\n",
-    "    jn1 = customer_ds.merge(n1, left_on=\"c_nationkey\", right_on=\"n_nationkey\")\n",
-    "    jn2 = jn1.merge(orders_ds, left_on=\"c_custkey\", right_on=\"o_custkey\")\n",
-    "    jn2 = jn2.rename({\"n_name\": \"cust_nation\"}, axis=\"columns\")\n",
-    "    jn3 = jn2.merge(line_item_ds, left_on=\"o_orderkey\", right_on=\"l_orderkey\")\n",
-    "    jn4 = jn3.merge(supplier_ds, left_on=\"l_suppkey\", right_on=\"s_suppkey\")\n",
-    "    jn5 = jn4.merge(n2, left_on=\"s_nationkey\", right_on=\"n_nationkey\")\n",
-    "    df1 = jn5.rename({\"n_name\": \"supp_nation\"}, axis=\"columns\")\n",
-    "\n",
-    "    # Part 2\n",
-    "    jn1 = customer_ds.merge(n2, left_on=\"c_nationkey\", right_on=\"n_nationkey\")\n",
-    "    jn2 = jn1.merge(orders_ds, left_on=\"c_custkey\", right_on=\"o_custkey\")\n",
-    "    jn2 = jn2.rename({\"n_name\": \"cust_nation\"}, axis=\"columns\")\n",
-    "    jn3 = jn2.merge(line_item_ds, left_on=\"o_orderkey\", right_on=\"l_orderkey\")\n",
-    "    jn4 = jn3.merge(supplier_ds, left_on=\"l_suppkey\", right_on=\"s_suppkey\")\n",
-    "    jn5 = jn4.merge(n1, left_on=\"s_nationkey\", right_on=\"n_nationkey\")\n",
-    "    df2 = jn5.rename({\"n_name\": \"supp_nation\"}, axis=\"columns\")\n",
-    "\n",
-    "    # Combine\n",
-    "    total = pd.concat([df1, df2])\n",
-    "\n",
-    "    total = total[(total[\"l_shipdate\"] >= var3) & (total[\"l_shipdate\"] <= var4)]\n",
-    "    total[\"volume\"] = total[\"l_extendedprice\"] * (1.0 - total[\"l_discount\"])\n",
-    "    total[\"l_year\"] = total[\"l_shipdate\"].dt.year\n",
-    "\n",
-    "    gb = total.groupby([\"supp_nation\", \"cust_nation\", \"l_year\"], as_index=False)\n",
-    "    agg = gb.agg(revenue=pd.NamedAgg(column=\"volume\", aggfunc=\"sum\"))\n",
-    "\n",
-    "    return agg.sort_values(by=[\"supp_nation\", \"cust_nation\", \"l_year\"])  # type: ignore[no-any-return]"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "3",
-   "metadata": {
-    "papermill": {
-     "duration": 0.021725,
-     "end_time": "2024-03-22T17:24:39.080999",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.059274",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def q7(\n",
-    "    nation_ds,\n",
-    "    customer_ds,\n",
-    "    line_item_ds,\n",
-    "    orders_ds,\n",
-    "    supplier_ds,\n",
-    ") -> None:\n",
-    "    nation_ds = nw.from_native(nation_ds)\n",
-    "    customer_ds = nw.from_native(customer_ds)\n",
-    "    line_item_ds = nw.from_native(line_item_ds)\n",
-    "    orders_ds = nw.from_native(orders_ds)\n",
-    "    supplier_ds = nw.from_native(supplier_ds)\n",
-    "\n",
-    "    n1 = nation_ds.filter(nw.col(\"n_name\") == \"FRANCE\")\n",
-    "    n2 = nation_ds.filter(nw.col(\"n_name\") == \"GERMANY\")\n",
-    "\n",
-    "    var_1 = datetime(1995, 1, 1)\n",
-    "    var_2 = datetime(1996, 12, 31)\n",
-    "\n",
-    "    df1 = (\n",
-    "        customer_ds.join(n1, left_on=\"c_nationkey\", right_on=\"n_nationkey\")\n",
-    "        .join(orders_ds, left_on=\"c_custkey\", right_on=\"o_custkey\")\n",
-    "        .rename({\"n_name\": \"cust_nation\"})\n",
-    "        .join(line_item_ds, left_on=\"o_orderkey\", right_on=\"l_orderkey\")\n",
-    "        .join(supplier_ds, left_on=\"l_suppkey\", right_on=\"s_suppkey\")\n",
-    "        .join(n2, left_on=\"s_nationkey\", right_on=\"n_nationkey\")\n",
-    "        .rename({\"n_name\": \"supp_nation\"})\n",
-    "    )\n",
-    "\n",
-    "    df2 = (\n",
-    "        customer_ds.join(n2, left_on=\"c_nationkey\", right_on=\"n_nationkey\")\n",
-    "        .join(orders_ds, left_on=\"c_custkey\", right_on=\"o_custkey\")\n",
-    "        .rename({\"n_name\": \"cust_nation\"})\n",
-    "        .join(line_item_ds, left_on=\"o_orderkey\", right_on=\"l_orderkey\")\n",
-    "        .join(supplier_ds, left_on=\"l_suppkey\", right_on=\"s_suppkey\")\n",
-    "        .join(n1, left_on=\"s_nationkey\", right_on=\"n_nationkey\")\n",
-    "        .rename({\"n_name\": \"supp_nation\"})\n",
-    "    )\n",
-    "\n",
-    "    result = (\n",
-    "        nw.concat([df1, df2])\n",
-    "        .filter(nw.col(\"l_shipdate\").is_between(var_1, var_2))\n",
-    "        .with_columns(\n",
-    "            (nw.col(\"l_extendedprice\") * (1 - nw.col(\"l_discount\"))).alias(\"volume\")\n",
-    "        )\n",
-    "        .with_columns(nw.col(\"l_shipdate\").dt.year().alias(\"l_year\"))\n",
-    "        .group_by(\"supp_nation\", \"cust_nation\", \"l_year\")\n",
-    "        .agg(nw.sum(\"volume\").alias(\"revenue\"))\n",
-    "        .sort(by=[\"supp_nation\", \"cust_nation\", \"l_year\"])\n",
-    "    )\n",
-    "    return nw.to_native(result)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "4",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "import ibis\n",
-    "\n",
-    "\n",
-    "def q7_ibis(\n",
-    "    nation: Any, customer: Any, lineitem: Any, orders: Any, supplier: Any, *, tool: str\n",
-    ") -> None:\n",
-    "    var1 = \"FRANCE\"\n",
-    "    var2 = \"GERMANY\"\n",
-    "    var3 = datetime(1995, 1, 1)\n",
-    "    var4 = datetime(1996, 12, 31)\n",
-    "\n",
-    "    n1 = nation.filter(nation[\"n_name\"] == var1)\n",
-    "    n2 = nation.filter(nation[\"n_name\"] == var2)\n",
-    "\n",
-    "    q1 = (\n",
-    "        customer.join(n1, customer[\"c_nationkey\"] == n1[\"n_nationkey\"])\n",
-    "        .join(orders, customer[\"c_custkey\"] == orders[\"o_custkey\"])\n",
-    "        .rename({\"cust_nation\": \"n_name\"})\n",
-    "        .join(lineitem, orders[\"o_orderkey\"] == lineitem[\"l_orderkey\"])\n",
-    "        .join(supplier, lineitem[\"l_suppkey\"] == supplier[\"s_suppkey\"])\n",
-    "        .join(n2, supplier[\"s_nationkey\"] == n2[\"n_nationkey\"])\n",
-    "        .rename({\"supp_nation\": \"n_name\"})\n",
-    "    )\n",
-    "\n",
-    "    q2 = (\n",
-    "        customer.join(n2, customer[\"c_nationkey\"] == n2[\"n_nationkey\"])\n",
-    "        .join(orders, customer[\"c_custkey\"] == orders[\"o_custkey\"])\n",
-    "        .rename({\"cust_nation\": \"n_name\"})\n",
-    "        .join(lineitem, orders[\"o_orderkey\"] == lineitem[\"l_orderkey\"])\n",
-    "        .join(supplier, lineitem[\"l_suppkey\"] == supplier[\"s_suppkey\"])\n",
-    "        .join(n1, supplier[\"s_nationkey\"] == n1[\"n_nationkey\"])\n",
-    "        .rename({\"supp_nation\": \"n_name\"})\n",
-    "    )\n",
-    "\n",
-    "    q_final = (\n",
-    "        q1.union(q2)\n",
-    "        .filter((ibis._[\"l_shipdate\"] >= var3) & (ibis._[\"l_shipdate\"] <= var4))\n",
-    "        .mutate(\n",
-    "            volume=(ibis._[\"l_extendedprice\"] * (1 - ibis._[\"l_discount\"])),\n",
-    "            l_year=ibis._[\"l_shipdate\"].year(),\n",
-    "        )\n",
-    "        .group_by(\"supp_nation\", \"cust_nation\", \"l_year\")\n",
-    "        .agg(revenue=ibis._[\"volume\"].sum())\n",
-    "        .order_by(\"supp_nation\", \"cust_nation\", \"l_year\")\n",
-    "    )\n",
-    "\n",
-    "    if tool == \"pandas\":\n",
-    "        return q_final.to_pandas()\n",
-    "    if tool == \"polars\":\n",
-    "        return q_final.to_polars()\n",
-    "    raise ValueError(\"expected pandas or polars\")"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "5",
-   "metadata": {
-    "papermill": {
-     "duration": 0.013325,
-     "end_time": "2024-03-22T17:24:39.099766",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.086441",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "dir_ = \"/kaggle/input/tpc-h-data-parquet-s-2/\"\n",
-    "region = dir_ + \"region.parquet\"\n",
-    "nation = dir_ + \"nation.parquet\"\n",
-    "customer = dir_ + \"customer.parquet\"\n",
-    "lineitem = dir_ + \"lineitem.parquet\"\n",
-    "orders = dir_ + \"orders.parquet\"\n",
-    "supplier = dir_ + \"supplier.parquet\"\n",
-    "part = dir_ + \"part.parquet\"\n",
-    "partsupp = dir_ + \"partsupp.parquet\""
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "6",
-   "metadata": {
-    "papermill": {
-     "duration": 0.014284,
-     "end_time": "2024-03-22T17:24:39.119737",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.105453",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "con_pd = ibis.pandas.connect()\n",
-    "con_pl = ibis.polars.connect()\n",
-    "\n",
-    "IO_FUNCS = {\n",
-    "    \"pandas\": lambda x: pd.read_parquet(x, engine=\"pyarrow\"),\n",
-    "    \"pandas[pyarrow]\": lambda x: pd.read_parquet(\n",
-    "        x, engine=\"pyarrow\", dtype_backend=\"pyarrow\"\n",
-    "    ),\n",
-    "    \"pandas[pyarrow][ibis]\": lambda x: con_pd.read_parquet(\n",
-    "        x, engine=\"pyarrow\", dtype_backend=\"pyarrow\"\n",
-    "    ),\n",
-    "    \"polars[eager]\": lambda x: pl.read_parquet(x),\n",
-    "    \"polars[lazy]\": lambda x: pl.scan_parquet(x),\n",
-    "    \"polars[lazy][ibis]\": lambda x: con_pl.read_parquet(x),\n",
-    "}"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "7",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "results = {}"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "8",
-   "metadata": {},
-   "source": [
-    "## pandas, pyarrow dtypes, via ibis"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "9",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "tool = \"pandas[pyarrow][ibis]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q7_ibis(fn(nation), fn(customer), fn(lineitem), fn(orders), fn(supplier), tool='pandas')\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "10",
-   "metadata": {},
-   "source": [
-    "## polars, lazy, via ibis"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "11",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "tool = \"polars[lazy][ibis]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q7_ibis(fn(nation), fn(customer), fn(lineitem), fn(orders), fn(supplier), tool='polars')\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "12",
-   "metadata": {},
-   "source": [
-    "## pandas, pyarrow dtypes, native"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "13",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "tool = \"pandas[pyarrow]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q7_pandas_native(fn(nation), fn(customer), fn(lineitem), fn(orders), fn(supplier))\n",
-    "results[tool + \"[native]\"] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "14",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005113,
-     "end_time": "2024-03-22T17:24:39.130472",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.125359",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## pandas via Narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "15",
-   "metadata": {
-    "papermill": {
-     "duration": 196.786925,
-     "end_time": "2024-03-22T17:27:55.922832",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.135907",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"pandas\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q7(fn(nation), fn(customer), fn(lineitem), fn(orders), fn(supplier))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "16",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005184,
-     "end_time": "2024-03-22T17:27:55.933407",
-     "exception": false,
-     "start_time": "2024-03-22T17:27:55.928223",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## pandas, pyarrow dtypes, via Narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "17",
-   "metadata": {
-    "papermill": {
-     "duration": 158.748353,
-     "end_time": "2024-03-22T17:30:34.688289",
-     "exception": false,
-     "start_time": "2024-03-22T17:27:55.939936",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"pandas[pyarrow]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q7(fn(nation), fn(customer), fn(lineitem), fn(orders), fn(supplier))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "18",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005773,
-     "end_time": "2024-03-22T17:30:34.700300",
-     "exception": false,
-     "start_time": "2024-03-22T17:30:34.694527",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## Polars read_parquet"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "19",
-   "metadata": {
-    "papermill": {
-     "duration": 37.821116,
-     "end_time": "2024-03-22T17:31:12.527466",
-     "exception": false,
-     "start_time": "2024-03-22T17:30:34.706350",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"polars[eager]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q7(fn(nation), fn(customer), fn(lineitem), fn(orders), fn(supplier))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "20",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005515,
-     "end_time": "2024-03-22T17:31:12.539068",
-     "exception": false,
-     "start_time": "2024-03-22T17:31:12.533553",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## Polars scan_parquet"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "21",
-   "metadata": {
-    "papermill": {
-     "duration": 4.800698,
-     "end_time": "2024-03-22T17:31:17.346813",
-     "exception": false,
-     "start_time": "2024-03-22T17:31:12.546115",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"polars[lazy]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q7(fn(nation), fn(customer), fn(lineitem), fn(orders), fn(supplier)).collect()\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "22",
-   "metadata": {},
-   "source": [
-    "## Save"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "23",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "import json\n",
-    "\n",
-    "with open(\"results.json\", \"w\") as fd:\n",
-    "    json.dump(results, fd)"
-   ]
-  }
- ],
- "metadata": {
-  "kaggle": {
-   "accelerator": "none",
-   "dataSources": [
-    {
-     "sourceId": 167796716,
-     "sourceType": "kernelVersion"
-    },
-    {
-     "sourceId": 167796934,
-     "sourceType": "kernelVersion"
-    },
-    {
-     "sourceId": 167796952,
-     "sourceType": "kernelVersion"
-    },
-    {
-     "sourceId": 167796969,
-     "sourceType": "kernelVersion"
-    }
-   ],
-   "isGpuEnabled": false,
-   "isInternetEnabled": true,
-   "language": "python",
-   "sourceType": "notebook"
-  },
-  "kernelspec": {
-   "display_name": "Python 3",
-   "language": "python",
-   "name": "python3"
-  },
-  "language_info": {
-   "codemirror_mode": {
-    "name": "ipython",
-    "version": 3
-   },
-   "file_extension": ".py",
-   "mimetype": "text/x-python",
-   "name": "python",
-   "nbconvert_exporter": "python",
-   "pygments_lexer": "ipython3",
-   "version": "3.8.19"
-  },
-  "papermill": {
-   "default_parameters": {},
-   "duration": 458.423327,
-   "end_time": "2024-03-22T17:31:18.077306",
-   "environment_variables": {},
-   "exception": null,
-   "input_path": "__notebook__.ipynb",
-   "output_path": "__notebook__.ipynb",
-   "parameters": {},
-   "start_time": "2024-03-22T17:23:39.653979",
-   "version": "2.5.0"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 5
-}
diff --git a/tpch/notebooks/q7/kernel-metadata.json b/tpch/notebooks/q7/kernel-metadata.json
deleted file mode 100644
index 65997e8a..00000000
--- a/tpch/notebooks/q7/kernel-metadata.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "id": "marcogorelli/narwhals-tpch-q7-s2",
-  "title": "Narwhals TPCH Q7 S2",
-  "code_file": "execute.ipynb",
-  "language": "python",
-  "kernel_type": "notebook",
-  "is_private": "false",
-  "enable_gpu": "false",
-  "enable_tpu": "false",
-  "enable_internet": "true",
-  "dataset_sources": [],
-  "competition_sources": [],
-  "kernel_sources": ["marcogorelli/tpc-h-data-parquet-s-2"],
-  "model_sources": []
-}
\ No newline at end of file
diff --git a/tpch/notebooks/q9/execute.ipynb b/tpch/notebooks/q9/execute.ipynb
deleted file mode 100644
index 802799a0..00000000
--- a/tpch/notebooks/q9/execute.ipynb
+++ /dev/null
@@ -1,378 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 33.390992,
-     "end_time": "2024-03-22T17:24:15.601719",
-     "exception": false,
-     "start_time": "2024-03-22T17:23:42.210727",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "!pip uninstall apache-beam -y && pip install -U pandas polars pyarrow narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 0.907754,
-     "end_time": "2024-03-22T17:24:39.053873",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:38.146119",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "import pandas as pd\n",
-    "import polars as pl\n",
-    "\n",
-    "pd.options.mode.copy_on_write = True\n",
-    "pd.options.future.infer_string = True"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 0.021725,
-     "end_time": "2024-03-22T17:24:39.080999",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.059274",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "from typing import Any\n",
-    "\n",
-    "import narwhals as nw\n",
-    "\n",
-    "\n",
-    "def q9(\n",
-    "    part_ds_raw: Any,\n",
-    "    partsupp_ds_raw: Any,\n",
-    "    nation_ds_raw: Any,\n",
-    "    lineitem_ds_raw: Any,\n",
-    "    orders_ds_raw: Any,\n",
-    "    supplier_ds_raw: Any,\n",
-    ") -> Any:\n",
-    "    part_ds = nw.from_native(part_ds_raw)\n",
-    "    nation_ds = nw.from_native(nation_ds_raw)\n",
-    "    partsupp_ds = nw.from_native(partsupp_ds_raw)\n",
-    "    lineitem_ds = nw.from_native(lineitem_ds_raw)\n",
-    "    orders_ds = nw.from_native(orders_ds_raw)\n",
-    "    supplier_ds = nw.from_native(supplier_ds_raw)\n",
-    "\n",
-    "    result = (\n",
-    "        part_ds.join(partsupp_ds, left_on=\"p_partkey\", right_on=\"ps_partkey\")\n",
-    "        .join(supplier_ds, left_on=\"ps_suppkey\", right_on=\"s_suppkey\")\n",
-    "        .join(\n",
-    "            lineitem_ds,\n",
-    "            left_on=[\"p_partkey\", \"ps_suppkey\"],\n",
-    "            right_on=[\"l_partkey\", \"l_suppkey\"],\n",
-    "        )\n",
-    "        .join(orders_ds, left_on=\"l_orderkey\", right_on=\"o_orderkey\")\n",
-    "        .join(nation_ds, left_on=\"s_nationkey\", right_on=\"n_nationkey\")\n",
-    "        .filter(nw.col(\"p_name\").str.contains(\"green\"))\n",
-    "        .select(\n",
-    "            nw.col(\"n_name\").alias(\"nation\"),\n",
-    "            nw.col(\"o_orderdate\").dt.year().alias(\"o_year\"),\n",
-    "            (\n",
-    "                nw.col(\"l_extendedprice\") * (1 - nw.col(\"l_discount\"))\n",
-    "                - nw.col(\"ps_supplycost\") * nw.col(\"l_quantity\")\n",
-    "            ).alias(\"amount\"),\n",
-    "        )\n",
-    "        .group_by(\"nation\", \"o_year\")\n",
-    "        .agg(nw.sum(\"amount\").alias(\"sum_profit\"))\n",
-    "        .sort(by=[\"nation\", \"o_year\"], descending=[False, True])\n",
-    "    )\n",
-    "\n",
-    "    return nw.to_native(result)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 0.013325,
-     "end_time": "2024-03-22T17:24:39.099766",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.086441",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "dir_ = \"/kaggle/input/tpc-h-data-parquet-s-2/\"\n",
-    "nation = dir_ + \"nation.parquet\"\n",
-    "lineitem = dir_ + \"lineitem.parquet\"\n",
-    "orders = dir_ + \"orders.parquet\"\n",
-    "supplier = dir_ + \"supplier.parquet\"\n",
-    "part = dir_ + \"part.parquet\"\n",
-    "partsupp = dir_ + \"partsupp.parquet\""
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 0.014284,
-     "end_time": "2024-03-22T17:24:39.119737",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.105453",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "IO_FUNCS = {\n",
-    "    \"pandas\": lambda x: pd.read_parquet(x, engine=\"pyarrow\"),\n",
-    "    \"pandas[pyarrow]\": lambda x: pd.read_parquet(\n",
-    "        x, engine=\"pyarrow\", dtype_backend=\"pyarrow\"\n",
-    "    ),\n",
-    "    \"polars[eager]\": lambda x: pl.read_parquet(x),\n",
-    "    \"polars[lazy]\": lambda x: pl.scan_parquet(x),\n",
-    "}"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "results = {}"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005113,
-     "end_time": "2024-03-22T17:24:39.130472",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.125359",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## pandas via Narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 196.786925,
-     "end_time": "2024-03-22T17:27:55.922832",
-     "exception": false,
-     "start_time": "2024-03-22T17:24:39.135907",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"pandas\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q9(fn(part), fn(partsupp), fn(nation), fn(lineitem), fn(orders), fn(supplier))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005184,
-     "end_time": "2024-03-22T17:27:55.933407",
-     "exception": false,
-     "start_time": "2024-03-22T17:27:55.928223",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## pandas, pyarrow dtypes, via Narwhals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 158.748353,
-     "end_time": "2024-03-22T17:30:34.688289",
-     "exception": false,
-     "start_time": "2024-03-22T17:27:55.939936",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"pandas[pyarrow]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q9(fn(part), fn(partsupp), fn(nation), fn(lineitem), fn(orders), fn(supplier))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005773,
-     "end_time": "2024-03-22T17:30:34.7003",
-     "exception": false,
-     "start_time": "2024-03-22T17:30:34.694527",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## Polars read_parquet"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 37.821116,
-     "end_time": "2024-03-22T17:31:12.527466",
-     "exception": false,
-     "start_time": "2024-03-22T17:30:34.70635",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"polars[eager]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q9(fn(part), fn(partsupp), fn(nation), fn(lineitem), fn(orders), fn(supplier))\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {
-    "papermill": {
-     "duration": 0.005515,
-     "end_time": "2024-03-22T17:31:12.539068",
-     "exception": false,
-     "start_time": "2024-03-22T17:31:12.533553",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "source": [
-    "## Polars scan_parquet"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "papermill": {
-     "duration": 4.800698,
-     "end_time": "2024-03-22T17:31:17.346813",
-     "exception": false,
-     "start_time": "2024-03-22T17:31:12.546115",
-     "status": "completed"
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "tool = \"polars[lazy]\"\n",
-    "fn = IO_FUNCS[tool]\n",
-    "timings = %timeit -o -q q9(fn(part), fn(partsupp), fn(nation), fn(lineitem), fn(orders), fn(supplier)).collect()\n",
-    "results[tool] = timings.all_runs"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## Save"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "import json\n",
-    "\n",
-    "with open(\"results.json\", \"w\") as fd:\n",
-    "    json.dump(results, fd)"
-   ]
-  }
- ],
- "metadata": {
-  "kaggle": {
-   "accelerator": "none",
-   "dataSources": [
-    {
-     "sourceId": 167796934,
-     "sourceType": "kernelVersion"
-    }
-   ],
-   "dockerImageVersionId": 30673,
-   "isGpuEnabled": false,
-   "isInternetEnabled": true,
-   "language": "python",
-   "sourceType": "notebook"
-  },
-  "kernelspec": {
-   "display_name": "Python 3",
-   "language": "python",
-   "name": "python3"
-  },
-  "language_info": {
-   "codemirror_mode": {
-    "name": "ipython",
-    "version": 3
-   },
-   "file_extension": ".py",
-   "mimetype": "text/x-python",
-   "name": "python",
-   "nbconvert_exporter": "python",
-   "pygments_lexer": "ipython3",
-   "version": "3.10.13"
-  },
-  "papermill": {
-   "default_parameters": {},
-   "duration": 458.423327,
-   "end_time": "2024-03-22T17:31:18.077306",
-   "environment_variables": {},
-   "exception": null,
-   "input_path": "__notebook__.ipynb",
-   "output_path": "__notebook__.ipynb",
-   "parameters": {},
-   "start_time": "2024-03-22T17:23:39.653979",
-   "version": "2.5.0"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/tpch/notebooks/q9/kernel-metadata.json b/tpch/notebooks/q9/kernel-metadata.json
deleted file mode 100644
index bdbebcfe..00000000
--- a/tpch/notebooks/q9/kernel-metadata.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "id": "marcogorelli/narwhals-tpch-q9-s2",
-  "title": "Narwhals TPCH Q9 S2",
-  "code_file": "execute.ipynb",
-  "language": "python",
-  "kernel_type": "notebook",
-  "is_private": "false",
-  "enable_gpu": "false",
-  "enable_tpu": "false",
-  "enable_internet": "true",
-  "dataset_sources": [],
-  "competition_sources": [],
-  "kernel_sources": ["marcogorelli/tpc-h-data-parquet-s-2"],
-  "model_sources": []
-}
\ No newline at end of file


Test patch:
diff --git a/.github/workflows/downstream_tests.yml b/.github/workflows/downstream_tests.yml
index 12f7f95b..542dacbb 100644
--- a/.github/workflows/downstream_tests.yml
+++ b/.github/workflows/downstream_tests.yml
@@ -50,6 +50,64 @@ jobs:
             cd altair
             mypy altair tests
 
+  marimo:
+    strategy:
+      matrix:
+        python-version: ["3.12"]
+        os: [ubuntu-latest]
+        dependencies: ["core", "core,optional"]
+
+    runs-on: ${{ matrix.os }}
+    steps:
+      - uses: actions/checkout@v4
+      - uses: actions/setup-python@v5
+        with:
+          python-version: ${{ matrix.python-version }}
+      - name: Install uv
+        uses: astral-sh/setup-uv@v3
+        with:
+          enable-cache: "true"
+          cache-suffix: ${{ matrix.python-version }}
+          cache-dependency-glob: "**requirements*.txt"
+      - name: clone-marimo
+        run: |
+            git clone https://github.com/marimo-team/marimo.git --depth=1
+            cd marimo
+            git log
+      - name: install-basics
+        run: uv pip install --upgrade tox virtualenv setuptools hatch --system
+      - name: install-marimo-dev
+        run: |
+            cd marimo
+            uv pip install -e ".[dev]" --system
+      - name: install-narwhals-dev
+        run: |
+            uv pip uninstall narwhals --system
+            uv pip install -e . --system
+      - name: show-deps
+        run: uv pip freeze
+      - name: Create assets directory, copy over index.html
+        run: |
+            mkdir -p marimo/marimo/_static/assets
+            cp marimo/frontend/index.html marimo/marimo/_static/index.html
+            cp marimo/frontend/public/favicon.ico marimo/marimo/_static/favicon.ico
+      - name: Run tests with minimal dependencies
+        if: ${{ matrix.dependencies == 'core' }}
+        run: |
+            cd marimo
+            hatch run +py=${{ matrix.python-version }} test:test -v tests/ -k "not test_cli"
+        timeout-minutes: 15
+      - name: Run tests with optional dependencies
+        if: ${{ matrix.dependencies == 'core,optional' }}
+        run: |
+            cd marimo
+            hatch run +py=${{ matrix.python-version }} test-optional:test -v tests/ -k "not test_cli"
+        timeout-minutes: 15
+      - name: Run typechecks
+        run: |
+            cd marimo
+            hatch run typecheck:check
+
   scikit-lego:
     strategy:
       matrix:
@@ -113,22 +171,18 @@ jobs:
       - name: install-basics
         run: uv pip install --upgrade tox virtualenv setuptools --system
       - name: install-shiny-dev
+        env:
+          UV_SYSTEM_PYTHON: 1
         run: |
             cd py-shiny
-            uv pip install -e ".[dev,test]" --system
+            make narwhals-install-shiny
       - name: install-narwhals-dev
         run: |
             uv pip uninstall narwhals --system
             uv pip install -e . --system
       - name: show-deps
         run: uv pip freeze
-      - name: Run pytest
-        run: |
-            cd py-shiny
-            python tests/pytest/asyncio_prevent.py
-            pytest
-      - name: Run mypy
+      - name: Run `make narwhals-test-integration`
         run: |
             cd py-shiny
-            uv pip install mypy --system
-            mypy shiny
+            make narwhals-test-integration
diff --git a/tests/expr_and_series/all_horizontal_test.py b/tests/expr_and_series/all_horizontal_test.py
index 98dc9f9f..01d53fe6 100644
--- a/tests/expr_and_series/all_horizontal_test.py
+++ b/tests/expr_and_series/all_horizontal_test.py
@@ -87,3 +87,13 @@ def test_horizontal_expressions_emtpy(constructor: Constructor) -> None:
         ValueError, match=r"At least one expression must be passed.*sum_horizontal"
     ):
         df.select(nw.sum_horizontal())
+
+    with pytest.raises(
+        ValueError, match=r"At least one expression must be passed.*max_horizontal"
+    ):
+        df.select(nw.max_horizontal())
+
+    with pytest.raises(
+        ValueError, match=r"At least one expression must be passed.*min_horizontal"
+    ):
+        df.select(nw.min_horizontal())
diff --git a/tests/expr_and_series/max_horizontal_test.py b/tests/expr_and_series/max_horizontal_test.py
new file mode 100644
index 00000000..711ce4e0
--- /dev/null
+++ b/tests/expr_and_series/max_horizontal_test.py
@@ -0,0 +1,25 @@
+from typing import Any
+
+import pytest
+
+import narwhals.stable.v1 as nw
+from tests.utils import Constructor
+from tests.utils import compare_dicts
+
+data = {"a": [1, 3, None, None], "b": [4, None, 6, None], "z": [3, 1, None, None]}
+expected_values = [4, 3, 6, float("nan")]
+
+
+@pytest.mark.parametrize("col_expr", [nw.col("a"), "a"])
+def test_maxh(constructor: Constructor, col_expr: Any) -> None:
+    df = nw.from_native(constructor(data))
+    result = df.select(horizontal_max=nw.max_horizontal(col_expr, nw.col("b"), "z"))
+    expected = {"horizontal_max": expected_values}
+    compare_dicts(result, expected)
+
+
+def test_maxh_all(constructor: Constructor) -> None:
+    df = nw.from_native(constructor(data))
+    result = df.select(nw.max_horizontal(nw.all()), c=nw.max_horizontal(nw.all()))
+    expected = {"a": expected_values, "c": expected_values}
+    compare_dicts(result, expected)
diff --git a/tests/expr_and_series/min_horizontal_test.py b/tests/expr_and_series/min_horizontal_test.py
new file mode 100644
index 00000000..ca34d440
--- /dev/null
+++ b/tests/expr_and_series/min_horizontal_test.py
@@ -0,0 +1,25 @@
+from typing import Any
+
+import pytest
+
+import narwhals.stable.v1 as nw
+from tests.utils import Constructor
+from tests.utils import compare_dicts
+
+data = {"a": [1, 3, None, None], "b": [4, None, 6, None], "z": [3, 1, None, None]}
+expcted_values = [1, 1, 6, float("nan")]
+
+
+@pytest.mark.parametrize("col_expr", [nw.col("a"), "a"])
+def test_minh(constructor: Constructor, col_expr: Any) -> None:
+    df = nw.from_native(constructor(data))
+    result = df.select(horizontal_min=nw.min_horizontal(col_expr, nw.col("b"), "z"))
+    expected = {"horizontal_min": expcted_values}
+    compare_dicts(result, expected)
+
+
+def test_minh_all(constructor: Constructor) -> None:
+    df = nw.from_native(constructor(data))
+    result = df.select(nw.min_horizontal(nw.all()), c=nw.min_horizontal(nw.all()))
+    expected = {"a": expcted_values, "c": expcted_values}
+    compare_dicts(result, expected)
diff --git a/tests/expr_and_series/unary_test.py b/tests/expr_and_series/unary_test.py
index dabab0c0..66afd22a 100644
--- a/tests/expr_and_series/unary_test.py
+++ b/tests/expr_and_series/unary_test.py
@@ -1,15 +1,11 @@
 from typing import Any
 
-import pytest
-
 import narwhals.stable.v1 as nw
 from tests.utils import Constructor
 from tests.utils import compare_dicts
 
 
-def test_unary(constructor: Constructor, request: pytest.FixtureRequest) -> None:
-    if "dask" in str(constructor):
-        request.applymarker(pytest.mark.xfail)
+def test_unary(constructor: Constructor) -> None:
     data = {"a": [1, 3, 2], "b": [4, 4, 6], "z": [7.0, 8, 9]}
     result = (
         nw.from_native(constructor(data))
@@ -20,7 +16,8 @@ def test_unary(constructor: Constructor, request: pytest.FixtureRequest) -> None
             z_min=nw.col("z").min(),
             z_max=nw.col("z").max(),
         )
-        .select(nw.col("a_mean", "a_sum", "b_nunique", "z_min", "z_max").unique())
+        .unique(["a_mean", "a_sum", "b_nunique", "z_min", "z_max"])
+        .select(["a_mean", "a_sum", "b_nunique", "z_min", "z_max"])
     )
     expected = {
         "a_mean": [2],
diff --git a/tests/frame/interchange_native_namespace_test.py b/tests/frame/interchange_native_namespace_test.py
new file mode 100644
index 00000000..8a67d07b
--- /dev/null
+++ b/tests/frame/interchange_native_namespace_test.py
@@ -0,0 +1,52 @@
+import duckdb
+import polars as pl
+import pytest
+
+import narwhals.stable.v1 as nw
+
+data = {"a": [1, 2, 3], "b": [4.5, 6.7, 8.9], "z": ["x", "y", "w"]}
+
+
+def test_interchange() -> None:
+    df_pl = pl.DataFrame(data)
+    df = nw.from_native(df_pl.__dataframe__(), eager_or_interchange_only=True)
+    series = df["a"]
+
+    with pytest.raises(
+        NotImplementedError,
+        match="Cannot access native namespace for metadata-only dataframes with unknown backend",
+    ):
+        df.__native_namespace__()
+
+    with pytest.raises(
+        NotImplementedError,
+        match="Cannot access native namespace for metadata-only series with unknown backend",
+    ):
+        series.__native_namespace__()
+
+
+def test_ibis(
+    tmpdir: pytest.TempdirFactory,
+) -> None:  # pragma: no cover
+    ibis = pytest.importorskip("ibis")
+    df_pl = pl.DataFrame(data)
+
+    filepath = str(tmpdir / "file.parquet")  # type: ignore[operator]
+    df_pl.write_parquet(filepath)
+    tbl = ibis.read_parquet(filepath)
+    df = nw.from_native(tbl, eager_or_interchange_only=True)
+    series = df["a"]
+
+    assert df.__native_namespace__() == ibis
+    assert series.__native_namespace__() == ibis
+
+
+def test_duckdb() -> None:
+    df_pl = pl.DataFrame(data)  # noqa: F841
+
+    rel = duckdb.sql("select * from df_pl")
+    df = nw.from_native(rel, eager_or_interchange_only=True)
+    series = df["a"]
+
+    assert df.__native_namespace__() == duckdb
+    assert series.__native_namespace__() == duckdb