Skip to content

Commit

Permalink
Disallow queries which mix aggregate and non-aggregate expressions
Browse files Browse the repository at this point in the history
This query would result in an error on PG (I believe MySQL allows it,
but it's a nonsense query). This should only be allowed if the column
appears in the group by statement, and I believe I'll be able to reflect
that in the type system once I get to that point.
  • Loading branch information
sgrif committed Oct 1, 2015
1 parent c5ebe30 commit c66d96f
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 5 deletions.
3 changes: 3 additions & 0 deletions src/expression/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,6 @@ pub trait SelectableExpression<
Type: NativeSqlType = <Self as Expression>::SqlType,
>: Expression {
}

pub trait NonAggregate: Expression {
}
5 changes: 4 additions & 1 deletion src/query_source/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
mod joins;
mod select;

use expression::{Expression, SelectableExpression, count_star};
use expression::{Expression, SelectableExpression, NonAggregate, count_star};
pub use self::joins::{InnerJoinSource, LeftOuterJoinSource};
use self::select::SelectSqlQuerySource;
use std::convert::Into;
Expand Down Expand Up @@ -67,6 +67,9 @@ impl<C: Column> Expression for C {
impl<C: Column> SelectableExpression<C::Table> for C {
}

impl<C: Column> NonAggregate for C {
}

pub trait Table: QuerySource {
type PrimaryKey: Column<Table=Self>;
fn name(&self) -> &str;
Expand Down
11 changes: 7 additions & 4 deletions src/types/impls/tuples.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use expression::{Expression, SelectableExpression};
use expression::{Expression, SelectableExpression, NonAggregate};
use persistable::{AsBindParam, InsertableColumns};
use row::Row;
use std::error::Error;
Expand Down Expand Up @@ -62,7 +62,7 @@ macro_rules! tuple_impls {
}
}

impl<$($T: Expression),+> Expression for ($($T),+) {
impl<$($T: Expression + NonAggregate),+> Expression for ($($T),+) {
type SqlType = ($(<$T as Expression>::SqlType),+);

fn to_sql(&self) -> String {
Expand All @@ -71,6 +71,9 @@ macro_rules! tuple_impls {
}
}

impl<$($T: Expression + NonAggregate),+> NonAggregate for ($($T),+) {
}

impl<$($T: Column<Table=T>),+, T: Table> InsertableColumns for ($($T),+) {
type Table = T;
type SqlType = ($(<$T as Column>::SqlType),+);
Expand All @@ -85,7 +88,7 @@ macro_rules! tuple_impls {
SelectableExpression<QS, ($($ST),+)>
for ($($T),+) where
$($ST: NativeSqlType),+,
$($T: SelectableExpression<QS, $ST>),+,
$($T: SelectableExpression<QS, $ST> + NonAggregate),+,
QS: QuerySource,
{
}
Expand All @@ -94,7 +97,7 @@ macro_rules! tuple_impls {
SelectableExpression<QS, Nullable<($($ST),+)>>
for ($($T),+) where
$($ST: NativeSqlType),+,
$($T: SelectableExpression<QS, Nullable<$ST>>),+,
$($T: SelectableExpression<QS, Nullable<$ST>> + NonAggregate),+,
QS: QuerySource,
{
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#[macro_use]
extern crate yaqb;

use yaqb::*;
use yaqb::expression::count;

table! {
users {
id -> Serial,
}
}

fn main() {
use self::users::columns::*;
use self::users::table as users;

let connection = Connection::establish("").unwrap();
let source = users.select((id, count(star)));
//~^ ERROR E0277
}

0 comments on commit c66d96f

Please sign in to comment.