# Dynamic filtering of a query in a dynamic schema

**URL:** <https://discourse.diesel.rs/t/dynamic-filtering-of-a-query-in-a-dynamic-schema/134>\
**Category:** Uncategorized\
**Created:** [January 27, 2020, 5:15pm UTC](https://discourse.diesel.rs/t/dynamic-filtering-of-a-query-in-a-dynamic-schema/134 "2020-01-27T17:15:36Z")\
**Posts on this page:** 1\
**Showing post:** 3

<div class="post-metadata">

**Author:** ![Razican](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.diesel.rs/razican/32/67_2.png) [@Razican](https://discourse.diesel.rs/u/Razican)\
**Post date:** [January 28, 2020, 8:19pm UTC](https://discourse.diesel.rs/t/dynamic-filtering-of-a-query-in-a-dynamic-schema/134/3 "2020-01-28T20:19:27Z")

</div>

The idea of returning a ` BoxableExpression` is actually pretty good!

I implemented an `expression()` method:

```auto
fn expression(&self, table: &DynTable) -> Option<DynExpr> {
    use diesel::BoolExpressionMethods;

    let mut or_expr = None::<DynExpr>;
    for and_filter in &self.inner {
        if let Some(new_expr) = Self::and_expression(table, &and_filter) {
            or_expr = Some(if let Some(cur_expr) = or_expr {
                Box::new(cur_expr.or(new_expr))
            } else {
                new_expr
            });
        }
    }

    or_expr
}

fn and_expression(table: &DynTable, list: &[FilterClause]) -> Option<DynExpr> {
    use diesel::BoolExpressionMethods;

    let mut and_expr = None::<DynExpr>;

    for clause in list {
        if let Ok(new_expr) = clause.expression(table) {
            and_expr = Some(if let Some(cur_expr) = and_expr {
                Box::new(cur_expr.and(new_expr))
            } else {
                new_expr
            });
        }
    }

    and_expr
}

```

For that, I implemented an `expression()` method in `FilterClause`, that generates an expression depending on the type of the column. In order to no repeate code, this function will call to `expression_ty()` a typed version of the function:

```auto
fn expression_ty<T, E, V>(&self, table: &DynTable) -> Result<DynExpr, Error>
where
    T: FromStr<Err = E> + diesel::expression::AsExpression<V> + std::fmt::Display,
    E: std::error::Error + Send + Sync + 'static,
    V: diesel::sql_types::SingleValue,
    <T as diesel::expression::AsExpression<V>>::Expression:
        diesel::expression::NonAggregate + QueryFragment<Pg> + SelectableExpression<DynTable>,
{
    
    use diesel::{ExpressionMethods, PgTextExpressionMethods};

    let field = table.column::<V, _>(self.field);

    let res: DynExpr = match o {
        Operator::Contains => Box::new(field.ilike(format!("%{}%", value))),
        Operator::DoesNotContain => {
            Box::new(field.not_ilike(format!("%{}%", value)))
        }
        Operator::StartsWith => Box::new(field.ilike(format!("{}%", value))),
        Operator::EndsWith => Box::new(field.ilike(format!("%{}", value))),
    };

    Ok(res)
}

```

But I’m getting some errors in that last function:

```auto
error[E0599]: no method named `ilike` found for struct `diesel_dynamic_schema::column::Column<diesel_dynamic_schema::table::Table<std::string::String>, std::string::String, V>` in the current scope
   --> api_server/src/db.rs:853:66
    |
853 | ... Operator::Contains => Box::new(field.ilike(format!("%{}%", value))),
    | ^^^^^ method not found in `diesel_dynamic_schema::column::Column<diesel_dynamic_schema::table::Table<std::string::String>, std::string::String, V>`
    |
    = note: the method `ilike` exists but the following trait bounds were not satisfied:
            `&diesel_dynamic_schema::column::Column<diesel_dynamic_schema::table::Table<std::string::String>, std::string::String, V> : diesel::PgTextExpressionMethods`
            `&mut diesel_dynamic_schema::column::Column<diesel_dynamic_schema::table::Table<std::string::String>, std::string::String, V> : diesel::PgTextExpressionMethods`
            `diesel_dynamic_schema::column::Column<diesel_dynamic_schema::table::Table<std::string::String>, std::string::String, V> : diesel::PgTextExpressionMethods`

```

So, it seems that the `table.column()` method is not creating a `PgTextExpressionMethods`. Probably I’m missing some bounds in the header of the function, do you have an idea of what could it be?

Also, do you think this looks performant enough? It seems like it’s boxing a bunch of stuff.

---

_[View the full topic](https://discourse.diesel.rs/t/dynamic-filtering-of-a-query-in-a-dynamic-schema/134)._
