Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/contributing/native.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ pub trait ForeignDataWrapper {
fn delete(...);
fn end_modify(...);

// functions for aggregate pushdown (optional)
fn supported_aggregates(...) -> Vec<AggregateKind>;
fn supports_group_by(...) -> bool;
fn get_aggregate_rel_size(...) -> (i64, i32);
fn begin_aggregate_scan(...);

// other optional functions
...
}
Expand Down
67 changes: 66 additions & 1 deletion docs/guides/query-pushdown.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Query pushdown is a technique that enhances query performance by executing parts

### Using Query Pushdown

In Wrappers, the pushdown logic is integrated into each FDW. You dont need to modify your queries to benefit from this feature. For example, the [Stripe FDW](https://supabase.com/docs/guides/database/extensions/wrappers/stripe) automatically applies query pushdown for `id` within the `customer` object:
In Wrappers, the pushdown logic is integrated into each FDW. You don't need to modify your queries to benefit from this feature. For example, the [Stripe FDW](https://supabase.com/docs/guides/database/extensions/wrappers/stripe) automatically applies query pushdown for `id` within the `customer` object:

```sql
select *
Expand All @@ -34,3 +34,68 @@ limit 20;
```

This query executes `order by name limit 20` on ClickHouse before transferring the result to Postgres.

### Aggregate Pushdown

Aggregate pushdown allows aggregate functions like `COUNT`, `SUM`, `AVG`, `MIN`, and `MAX` to be executed directly on the foreign data source. This is especially valuable for analytics queries where you only need summary statistics rather than raw data.

```sql
select count(*), sum(amount), avg(amount)
from foreign_table
where status = 'active';
```

Instead of fetching all matching rows and computing aggregates locally, the FDW can push the entire aggregation to the remote source. This dramatically reduces data transfer - returning just a single row with the computed values.

#### GROUP BY Support

FDWs that support aggregate pushdown can also support `GROUP BY` pushdown:

```sql
select department, count(*), avg(salary)
from employees
group by department;
```

This executes the grouping and aggregation on the remote server, returning only the grouped results.

#### Supported Aggregate Functions

The Wrappers framework supports pushing down these aggregate functions:

| Function | Description |
|----------|-------------|
| `COUNT(*)` | Count all rows |
| `COUNT(column)` | Count non-null values |
| `COUNT(DISTINCT column)` | Count unique non-null values |
| `SUM(column)` | Sum of values |
| `AVG(column)` | Average of values |
| `MIN(column)` | Minimum value |
| `MAX(column)` | Maximum value |

#### Implementing Aggregate Pushdown

FDW developers can enable aggregate pushdown by implementing these trait methods:

```rust
fn supported_aggregates(&self) -> Vec<AggregateKind> {
vec![AggregateKind::Count, AggregateKind::Sum, AggregateKind::Avg]
}

fn supports_group_by(&self) -> bool {
true
}

fn begin_aggregate_scan(
&mut self,
aggregates: &[Aggregate],
group_by: &[Column],
quals: &[Qual],
options: &HashMap<String, String>,
) -> Result<(), Error> {
// Build and execute remote aggregate query
Ok(())
}
```

See the [API documentation](https://docs.rs/supabase-wrappers/latest/supabase_wrappers/) for detailed information on implementing aggregate pushdown.
Loading
Loading