Diesel: Provide a better "raw sql" escape hatch for full queries that we don't support in the query builder

Created on 9 Feb 2017  路  1Comment  路  Source: diesel-rs/diesel

Today we have some form of an escape hatch in the form of the sql function. However, it's meant for use with small fragments, not full queries. It's limited because it requires specifying the full SQL type of the output, and cannot handle bind parameters. I'd like to introduce a new function that is a more ergonomic API for raw SQL as an escape hatch for queries we don't support in the query builder yet.

Ultimately I've resisted introducing this, as we want to support all possible safe queries in the query builder eventually, but I think we need a proper escape hatch for us to go 1.0.

I'd like this API to be fully untyped, and named to make it clear that no verification of the query is occurring. For deserialization, it should not go through Queryable, as I do not think enforcing column order is ergonomic when writing raw SQL (and Queryable needs a SQL type to work). Instead I'd like to introduce an UntypedQueryable, which takes a row directly, and is able to fetch fields by name. I'm fine with the API requiring specifying the SQL type on this call if type inference can't pick it up. e.g. let updated_at: NaiveDateTime = row.get::<Timestamp>("updated_at")?. I suspect for most types which only implement FromSql for a single DB type type inference will handle it, but we should explore our options here and see what feels best.

I'm less clear what we should do with bind parameters. I do know that I don't want to go the route that the postgres crate went where we take &[&UntypedToSql], as constructing that value is painful, it forces dynamic dispatch (which then usually also forces boxing), and requires &[] for queries with no bind parameters. We could potentially still pass tuples here as long as type inference does what we want. I also think conn.raw_query("SELECT * FROM users WHERE id = $1").bind(id) could work (as an aside, I think we will likely need to pass the connection in before the bind parameters for this to work, which will lead to a semi-weird api of conn.raw_query().bind().execute()). I'm fine with also sometimes requiring giving a SQL type for the bind here as long as type inference is able to handle the most common cases.

discussion desired help wanted

Most helpful comment

I'm new to Rust and Diesel. but what I love is type safety and all great things LoadDsl does. That's why I'd prefer "better sql" instead of new untyped API.
Nice ORMs like ActiveRecord and Django's ORM allows to put bits of SQL but keep the rest of code working with typed models.

I'm playing with Diesel and see a lot of limitations (like inability to make multiple joins or multiple belongs_to) and that's ok. Even with raw SQL Diesel is still great.

I created couple workarounds to solve issues with raw sql queries.
First is obvious -- no binds so I just use PQescapeString.
Second one is unpredictable order of columns in queries with *, so this ugliness was born https://gist.github.com/andy128k/b3cae82d13e38f51c4c5bf56f5d6540a

>All comments

I'm new to Rust and Diesel. but what I love is type safety and all great things LoadDsl does. That's why I'd prefer "better sql" instead of new untyped API.
Nice ORMs like ActiveRecord and Django's ORM allows to put bits of SQL but keep the rest of code working with typed models.

I'm playing with Diesel and see a lot of limitations (like inability to make multiple joins or multiple belongs_to) and that's ok. Even with raw SQL Diesel is still great.

I created couple workarounds to solve issues with raw sql queries.
First is obvious -- no binds so I just use PQescapeString.
Second one is unpredictable order of columns in queries with *, so this ugliness was born https://gist.github.com/andy128k/b3cae82d13e38f51c4c5bf56f5d6540a

Was this page helpful?
0 / 5 - 0 ratings

Related issues

astraw picture astraw  路  4Comments

jimmycuadra picture jimmycuadra  路  4Comments

killercup picture killercup  路  3Comments

Fuckoffee picture Fuckoffee  路  3Comments

orionz picture orionz  路  3Comments