Double paren causes SQL error when using `IN` operator
Closed this issue · 3 comments
Description
Values used by IN
operator get double wrapped in parens. Example code that reproduces the error:
use sea_query::{BinOper, Expr, Iden, MysqlQueryBuilder, Query, SimpleExpr};
#[derive(Iden)]
enum Char {
Table,
Character,
}
fn main() {
let condition = Expr::col((Char::Table, Char::Character)).binary(
BinOper::In,
SimpleExpr::Values(vec![sea_query::Value::from(1), sea_query::Value::from(2)]),
);
let query = Query::select()
.column(Char::Character)
.from(Char::Table)
.and_where(condition)
.to_string(MysqlQueryBuilder);
println!("{}", query);
}
When sea-query 0.30.1
is used, I get this output:
SELECT `character` FROM `char` WHERE `char`.`character` IN ((1, 2))
We get a runtime error (using mariadb 10.6.14
):
4078 (HY000): Illegal parameter data types bigint and row for operation '='
Removing the double paren makes the error go away. I'll try to minimize the expression that causes the error.
EDIT: Using 2 values triggers the error (MRE code updated).
When sea-query 0.30.0
is used, I get this output:
SELECT `character` FROM `char` WHERE `char`.`character` IN (1, 2)
And no runtime error.
Could be a regression related to #675 because this error started to happen in 0.30.1
. Version 0.30.0
does not have this error.
Reproduces How Often
Always
Versions
0.30.1
I'd suggest to yank 0.30.1
version,because it's a breaking change that causes queries to fail.
I can confirm this should be a consequence of 675, however I'd suggest you to use SimpleExpr::Tuple
instead of Values
. Since it was changed quite a long time ago in
Expr::is_in
,Expr::is_not_in
now acceptsInto<SimpleExpr>
instead ofInto<Value>
and convert it toSimpleExpr::Tuple
instead ofSimpleExpr::Values
#476
Lines 1515 to 1523 in 5922d6f
If you also look at in_tuples
, it should explain the semantic of SimpleExpr::Values
. SimpleExpr::Values
is always wrapped in parens.
SimpleExpr::Values
is only being used in in_tuples
, but I am not sure whether we can change the current behaviour without breaking some other things.