-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix offset needing a limit clause (on sqlite) #2029
Conversation
@@ -33,6 +33,72 @@ use query_source::joins::{AppendSelection, Inner, Join}; | |||
use query_source::*; | |||
use result::QueryResult; | |||
|
|||
#[doc(hidden)] | |||
#[derive(Debug, Clone, Copy, QueryId)] | |||
pub struct LimitOffsetClause<Limit, Offset> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That needs to be move to somewhere else
Box::new(self.offset), | ||
Box::new(self.group_by), | ||
) | ||
unimplemented!() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've just want to get the normal SelectStatement
working before I will fix that.
Only other approach I can think of would be this:
Honestly though, having pub struct LimitOffsetClause<LimitClause, OffsetClause> {
pub limit_clause: LimitClause,
pub offset_clause: OffsetClause,
}
impl<Lim, Off> QueryFragment<Pg> for LimitOffsetClause<Lim, Off>
where
Lim: QueryFragment<Pg>,
Off: QueryFragment<Pg>,
{
fn walk_ast(...) -> ... {
self.limit_clause.walk_ast(out.reborrow())?;
self.offset_clause.walk_ast(out.reborrow())?;
Ok(())
}
}
// Identical impl for MySQL
impl<Off> QueryFragment<Sqlite> for LimitOffsetClause<NoLimitClause, OffsetClause<Off>>
where
OffsetClause<Off>: QueryFragment<Sqlite>,
{
fn walk_ast(...) -> ... {
out.push_sql(" LIMIT -1 ");
self.offset_clause.walk_ast(out.reborrow())?;
Ok(())
}
}
// explicit impls for `LimitClause<Lim>, AnyOffsetClause` and `NoLimitClause, NoOffsetClause` |
ff76f79
to
70f9fc1
Compare
Turns out that mysql does also not support offset without a preceding limit clause. Their "workaround" is even more horrible:
|
Uh... I guess we can just not support this on MySQL?
…On Tue, Apr 9, 2019, 11:43 AM Georg Semmler ***@***.***> wrote:
Turns out that mysql does also not support offset without a preceding
limit clause <https://dev.mysql.com/doc/refman/8.0/en/select.html>. Their
"workaround" is even more horrible:
To retrieve all rows from a certain offset up to the end of the result
set, you can use some large number for the second parameter.
—
You are receiving this because your review was requested.
Reply to this email directly, view it on GitHub
<#2029 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ABdWK2ZvuRK5hktzJ0sRdvfsoM85OEI6ks5vfMNDgaJpZM4cdwiW>
.
|
That would be a solution. |
9d699be
to
8cf3422
Compare
e80e7c6
to
9bbfa1d
Compare
9bbfa1d
to
5e9ae34
Compare
@diesel-rs/contributors This could need a final review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I've tried to port the diesel-oci backend to the latest diesel master branch (including this PR). It turns out that some changes are required to make this work: Basically third party backends need to see things and need to be able to implement certain traits.
where | ||
Self: AsQuery, | ||
DB: Backend, | ||
S: QueryFragment<DB> + SelectableExpression<F> + 'a, | ||
D: QueryFragment<DB> + 'a, | ||
W: Into<BoxedWhereClause<'a, DB>>, | ||
O: Into<Option<Box<dyn QueryFragment<DB> + 'a>>>, | ||
L: QueryFragment<DB> + 'a, | ||
Of: QueryFragment<DB> + 'a, | ||
LOf: IntoBoxedClause<'a, DB, BoxedClause = BoxedLimitOffsetClause<'a, DB>>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We may want to use this trait for the other conversations as well in a future change, but not sure about that
da3f459
to
765dbcd
Compare
MySQL also does not accept an offset clause without limit clause. Additionally they don't have any workaround for this, instead they suggest to just use "a large number" as limit clause. I've choosen `u64::MAX` as "large number". As far as I'm aware that does not resul in any limitations because mysql only supports up to 64TB of data per table. Assuming 1 bit per row (which is a crazy low minimum guess) this means 1024 * 1024 * 1024 * 1024 * 8 = 562.949.953.421.312 rows which is smaller than 2^64 = 18.446.744.073.709.551.615
implement stuff here
For third party backends it was not possible to implement `From<LimitOffsetClause<_,_>> for BoxedLimitOffsetClause` and also `Into<BoxedLimitOffsetClause> for LimitOffsetClause<_,_>` because of coherence rules. This commit introduces a new trait third party implementable trait used in place of `From`/`Into`.
* After the rebase the import syntax needed to be changed to rust2018
765dbcd
to
66146da
Compare
* Clarify changelog about potential breakage * Add some internal comment why things are implemented as they are * More tests for different cases
53dad55
to
eb00d5a
Compare
That's a pg only function, so we can just use a concrete connection type there and skip those big where clause
Just opening this one to get some feedback on the chosen approach
This should ~work but has one downside: Every code that is generic over connection types/backends now requires bounds like
SelectStatement<…>: QueryFragment<DB>
(For concrete examples see the change indiesel_migrations
). That's quite unfortunate in my opinion, but I've found no better way to solve this without falling back to unstable features likespecialization