From d114a7aad5e0602880cd438b239af337d9c7cb75 Mon Sep 17 00:00:00 2001 From: Chase Willden Date: Mon, 21 Oct 2024 14:52:16 -0600 Subject: [PATCH] resolves #159 - Added mysql subquery support. Added alias to subquery --- njord/src/column.rs | 25 +-- njord/src/keys.rs | 4 +- njord/src/mysql/select.rs | 8 +- njord/src/sqlite/select.rs | 8 +- njord/tests/mysql/mod.rs | 26 ++- njord/tests/mysql/select_joins_test.rs | 247 +++++++++++++++++-------- njord/tests/mysql/select_test.rs | 219 ++++++++++++++-------- njord/tests/sqlite/delete_test.rs | 2 +- njord/tests/sqlite/insert_test.rs | 6 +- njord/tests/sqlite/mod.rs | 2 +- njord/tests/sqlite/select_test.rs | 2 +- 11 files changed, 359 insertions(+), 190 deletions(-) diff --git a/njord/src/column.rs b/njord/src/column.rs index 2873e609..0147f0ff 100644 --- a/njord/src/column.rs +++ b/njord/src/column.rs @@ -1,53 +1,56 @@ -use crate::{sqlite::select::SelectQueryBuilder, table::Table}; +use crate::query::QueryBuilder; /// Define the enum to represent a column as either a String or SelectQueryBuilder #[derive(Clone)] -pub enum Column<'a, T: Table + Default> { +pub enum Column<'a> { Text(String), - SubQuery(SelectQueryBuilder<'a, T>), + // Subquery with alias + SubQuery(Box + 'a>, String), } // Implement the build method to convert the enum to a string -impl<'a, T: Table + Default> Column<'a, T> { +impl<'a> Column<'a> { /// Helper function to convert the columns to a string pub fn build(&self) -> String { match self { Column::Text(text) => text.clone(), - Column::SubQuery(sub_query) => "(".to_string() + &sub_query.build_query() + ")", + Column::SubQuery(sub_query, alias) => { + "(".to_string() + &sub_query.to_sql() + ") AS " + alias + } } } } // Implementation of fmt::Display for Column -impl<'a, T: Table + Default> std::fmt::Display for Column<'a, T> { +impl<'a> std::fmt::Display for Column<'a> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.build()) } } // Implementation of PartialEq for Column -impl<'a, T: Table + Default> PartialEq for Column<'a, T> { +impl<'a> PartialEq for Column<'a> { fn eq(&self, other: &Self) -> bool { self.build() == other.build() } } // Implementation of PartialEq for Column -impl<'a, T: Table + Default> PartialEq for Column<'a, T> { +impl<'a> PartialEq for Column<'a> { fn eq(&self, other: &String) -> bool { match self { Column::Text(text) => text == other, - Column::SubQuery(sub_query) => sub_query.build_query() == *other, + Column::SubQuery(sub_query, _) => sub_query.to_sql() == *other, } } } // Implementation of PartialEq<&str> for Column -impl<'a, T: Table + Default> PartialEq<&str> for Column<'a, T> { +impl<'a> PartialEq<&str> for Column<'a> { fn eq(&self, other: &&str) -> bool { match self { Column::Text(text) => text == other, - Column::SubQuery(sub_query) => sub_query.build_query() == *other, + Column::SubQuery(sub_query, _) => sub_query.to_sql() == *other, } } } diff --git a/njord/src/keys.rs b/njord/src/keys.rs index aa5a0c3c..e0543386 100644 --- a/njord/src/keys.rs +++ b/njord/src/keys.rs @@ -43,7 +43,7 @@ use serde::{Deserialize, Deserializer}; /// # Type Parameters /// /// * `T` - The type of the primary key value, which can be any type. -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct PrimaryKey(T); impl PrimaryKey { @@ -216,4 +216,4 @@ impl PartialEq for AutoIncrementPrimaryKey { fn eq(&self, other: &Self) -> bool { self.0 == other.0 } -} \ No newline at end of file +} diff --git a/njord/src/mysql/select.rs b/njord/src/mysql/select.rs index 98e167e8..dcd85f44 100644 --- a/njord/src/mysql/select.rs +++ b/njord/src/mysql/select.rs @@ -57,7 +57,7 @@ use crate::util::{Join, JoinType}; /// # Returns /// /// A `SelectQueryBuilder` instance. -pub fn select(columns: Vec>) -> SelectQueryBuilder { +pub fn select(columns: Vec) -> SelectQueryBuilder { SelectQueryBuilder::new(columns) } @@ -65,7 +65,7 @@ pub fn select(columns: Vec>) -> SelectQueryBuilder #[derive(Clone)] pub struct SelectQueryBuilder<'a, T: Table + Default> { table: Option, - columns: Vec>, + columns: Vec>, where_condition: Option>, distinct: bool, group_by: Option>, @@ -85,7 +85,7 @@ impl<'a, T: Table + Default> SelectQueryBuilder<'a, T> { /// /// * `conn` - A `PooledConn` to the MySql database. /// * `columns` - A vector of strings representing the columns to be selected. - pub fn new(columns: Vec>) -> Self { + pub fn new(columns: Vec>) -> Self { SelectQueryBuilder { table: None, columns, @@ -107,7 +107,7 @@ impl<'a, T: Table + Default> SelectQueryBuilder<'a, T> { /// # Arguments /// /// * `columns` - A vector of strings representing the columns to be selected. - pub fn select(mut self, columns: Vec>) -> Self { + pub fn select(mut self, columns: Vec>) -> Self { self.columns = columns; self } diff --git a/njord/src/sqlite/select.rs b/njord/src/sqlite/select.rs index 4afc5992..4d8aacc2 100644 --- a/njord/src/sqlite/select.rs +++ b/njord/src/sqlite/select.rs @@ -57,7 +57,7 @@ use crate::util::{Join, JoinType}; /// A `SelectQueryBuilder` instance. pub fn select<'a, T: Table + Default>( conn: &'a Connection, - columns: Vec>, + columns: Vec>, ) -> SelectQueryBuilder<'a, T> { SelectQueryBuilder::new(conn, columns) } @@ -67,7 +67,7 @@ pub fn select<'a, T: Table + Default>( pub struct SelectQueryBuilder<'a, T: Table + Default> { conn: &'a Connection, table: Option, - columns: Vec>, + columns: Vec>, where_condition: Option>, distinct: bool, group_by: Option>, @@ -87,7 +87,7 @@ impl<'a, T: Table + Default> SelectQueryBuilder<'a, T> { /// /// * `conn` - A `rusqlite::Connection` to the SQLite database. /// * `columns` - A vector of strings representing the columns to be selected. - pub fn new(conn: &'a Connection, columns: Vec>) -> Self { + pub fn new(conn: &'a Connection, columns: Vec>) -> Self { SelectQueryBuilder { conn, table: None, @@ -110,7 +110,7 @@ impl<'a, T: Table + Default> SelectQueryBuilder<'a, T> { /// # Arguments /// /// * `columns` - A vector of strings representing the columns to be selected. - pub fn select(mut self, columns: Vec>) -> Self { + pub fn select(mut self, columns: Vec>) -> Self { self.columns = columns; self } diff --git a/njord/tests/mysql/mod.rs b/njord/tests/mysql/mod.rs index a8a49f93..e1e2f5b4 100644 --- a/njord/tests/mysql/mod.rs +++ b/njord/tests/mysql/mod.rs @@ -5,7 +5,7 @@ mod select_joins_test; mod select_test; mod update_test; -use njord::keys::{AutoIncrementPrimaryKey, PrimaryKey}; +use njord::keys::AutoIncrementPrimaryKey; use njord::table::Table; use njord_derive::Table; @@ -18,7 +18,7 @@ pub struct User { pub address: String, } -#[derive(Table)] +#[derive(Table, Clone)] #[table_name = "users"] pub struct UserWithSubQuery { pub id: AutoIncrementPrimaryKey, @@ -28,22 +28,23 @@ pub struct UserWithSubQuery { pub additional_address: String, } -#[derive(Table)] +#[derive(Table, Clone)] #[table_name = "categories"] pub struct Category { - pub id: PrimaryKey, + pub id: AutoIncrementPrimaryKey, pub name: String, } -#[derive(Table)] +#[derive(Table, Clone)] #[table_name = "products"] pub struct Product { - pub id: PrimaryKey, + pub id: AutoIncrementPrimaryKey, pub name: String, pub description: String, pub price: f64, pub stock_quantity: usize, - pub category: Category, // one-to-one relationship + // pub category: Category, // one-to-one relationship + pub category_id: usize, pub discount: f64, } @@ -54,3 +55,14 @@ pub struct UsersWithJoin { price: f64, name: String, } + +#[derive(Table)] +#[table_name = "categories"] +pub struct CategoryWithJoin { + name: String, + description: String, + price: f64, + stock_quantity: usize, + discount: f64, + category_name: String, +} diff --git a/njord/tests/mysql/select_joins_test.rs b/njord/tests/mysql/select_joins_test.rs index d2b11f9e..ec2945a6 100644 --- a/njord/tests/mysql/select_joins_test.rs +++ b/njord/tests/mysql/select_joins_test.rs @@ -1,85 +1,174 @@ use njord::condition::Condition; +use njord::keys::AutoIncrementPrimaryKey; use njord::mysql; +use njord::table::Table; use njord::util::JoinType; use njord::{column::Column, condition::Value}; use std::sync::Arc; -use crate::{Product, UsersWithJoin}; - -// FIXME -// #[test] -// fn select_inner_join() { -// let url = "mysql://njord_user:njord_password@localhost:3306/njord_db"; -// let mut conn = mysql::open(url); - -// // Assume we have pre-inserted some data into the users and products tables -// let columns = vec![ -// Column::Text("users.username".to_string()), -// Column::Text("products.name".to_string()), -// Column::Text("products.price".to_string()), -// ]; - -// // Assuming a hypothetical join condition: users.id = products.user_id -// let join_condition = Condition::Eq( -// "users.id".to_string(), -// Value::Literal("products.user_id".to_string()), -// ); -// match conn { -// Ok(ref mut c) => { -// let result = mysql::select(c, columns) -// .from(UsersWithJoin::default()) -// .join( -// JoinType::Inner, -// Arc::new(Product::default()), -// join_condition, -// ) -// .build(); -// match result { -// Ok(r) => { -// // Check the number of results and assert against expected values -// assert!(!r.is_empty(), "Expected results, but got none."); -// // Further assertions on expected data can be made here based on inserted data -// } -// Err(e) => panic!("Failed to SELECT with JOIN: {:?}", e), -// }; -// } -// Err(e) => panic!("Failed to SELECT: {:?}", e), -// } -// } - -// #[test] -// fn select_left_join() { -// let url = "mysql://njord_user:njord_password@localhost:3306/njord_db"; -// let mut conn = mysql::open(url); - -// // Assume we have pre-inserted some data into the users and products tables -// let columns = vec![ -// Column::Text("users.username".to_string()), -// Column::Text("products.name".to_string()), -// Column::Text("products.price".to_string()), -// ]; - -// // Assuming a hypothetical join condition: users.id = products.user_id -// let join_condition = Condition::Eq( -// "users.id".to_string(), -// Value::Literal("products.user_id".to_string()), -// ); -// match conn { -// Ok(ref mut c) => { -// let result = mysql::select(c, columns) -// .from(UsersWithJoin::default()) -// .join(JoinType::Left, Arc::new(Product::default()), join_condition) -// .build(); -// match result { -// Ok(r) => { -// // Check the number of results and assert against expected values -// assert!(!r.is_empty(), "Expected results, but got none."); -// assert_eq!(r.len(), 2, "Expected 2 results from the LEFT JOIN query."); -// // Further assertions on expected data can be made here based on inserted data -// } -// Err(e) => panic!("Failed to SELECT with JOIN: {:?}", e), -// }; -// } -// Err(e) => panic!("Failed to SELECT: {:?}", e), -// } -// } +use crate::{Category, CategoryWithJoin, Product}; + +fn insert_mock_data(table_rows: Vec) { + let url = "mysql://njord_user:njord_password@localhost:3306/njord_db"; + let mut conn = mysql::open(url); + + match conn { + Ok(ref mut c) => { + let result = mysql::insert(c, table_rows); + assert!(result.is_ok()); + } + Err(e) => { + panic!("Failed to INSERT: {:?}", e); + } + } +} + +fn delete_mock_data(names: Vec, column: String) { + let url = "mysql://njord_user:njord_password@localhost:3306/njord_db"; + let mut conn = mysql::open(url); + + match conn { + Ok(ref mut c) => { + // Transform Vec into Vec + let value_list: Vec = names + .into_iter() + .map(Value::Literal) // Wrap each username as a Value::Literal + .collect(); + + let result = mysql::delete(c) + .from(T::default()) + .where_clause(Condition::In(column, value_list)) + .build(); + assert!(result.is_ok()); + } + Err(e) => { + panic!("Failed to DELETE: {:?}", e); + } + } +} + +#[test] +fn select_inner_join() { + insert_mock_data(vec![Category { + id: AutoIncrementPrimaryKey::new(Some(1)), + name: "select_inner_join_test".to_string(), + }]); + + insert_mock_data(vec![Product { + id: AutoIncrementPrimaryKey::new(Some(1)), + name: "select_inner_join_test".to_string(), + description: "select_inner_join_test".to_string(), + price: 10.0, + stock_quantity: 10, + discount: 0.0, + category_id: 1, + }]); + + let url = "mysql://njord_user:njord_password@localhost:3306/njord_db"; + let mut conn = mysql::open(url); + + // Assume we have pre-inserted some data into the users and products tables + let columns = vec![ + Column::Text("categories.name".to_string()), + Column::Text("products.name".to_string()), + Column::Text("products.price".to_string()), + ]; + + // Assuming a hypothetical join condition: users.id = products.user_id + let join_condition = Condition::Eq( + "categories.id".to_string(), + Value::Literal("products.category_id".to_string()), + ); + match conn { + Ok(ref mut c) => { + let result = mysql::select(columns) + .from(CategoryWithJoin::default()) + .join( + JoinType::Inner, + Arc::new(Product::default()), + join_condition, + ) + .build(c); + match result { + Ok(r) => { + // Check the number of results and assert against expected values + assert!(!r.is_empty(), "Expected results, but got none."); + // Further assertions on expected data can be made here based on inserted data + } + Err(e) => panic!("Failed to SELECT with JOIN: {:?}", e), + }; + } + Err(e) => panic!("Failed to SELECT: {:?}", e), + } + + delete_mock_data::( + vec!["select_inner_join_test".to_string()], + "name".to_string(), + ); + + delete_mock_data::( + vec!["select_inner_join_test".to_string()], + "name".to_string(), + ); +} + +#[test] +fn select_left_join() { + insert_mock_data(vec![Category { + id: AutoIncrementPrimaryKey::new(Some(1)), + name: "select_inner_join_test".to_string(), + }]); + + insert_mock_data(vec![Product { + id: AutoIncrementPrimaryKey::new(Some(1)), + name: "select_inner_join_test".to_string(), + description: "select_inner_join_test".to_string(), + price: 10.0, + stock_quantity: 10, + discount: 0.0, + category_id: 1, + }]); + + let url = "mysql://njord_user:njord_password@localhost:3306/njord_db"; + let mut conn = mysql::open(url); + + // Assume we have pre-inserted some data into the users and products tables + let columns = vec![ + Column::Text("categories.name".to_string()), + Column::Text("products.name".to_string()), + Column::Text("products.price".to_string()), + ]; + + // Assuming a hypothetical join condition: users.id = products.user_id + let join_condition = Condition::Eq( + "categories.id".to_string(), + Value::Literal("products.category_id".to_string()), + ); + match conn { + Ok(ref mut c) => { + let result = mysql::select(columns) + .from(CategoryWithJoin::default()) + .join(JoinType::Left, Arc::new(Product::default()), join_condition) + .build(c); + match result { + Ok(r) => { + // Check the number of results and assert against expected values + assert!(!r.is_empty(), "Expected results, but got none."); + // Further assertions on expected data can be made here based on inserted data + } + Err(e) => panic!("Failed to SELECT with JOIN: {:?}", e), + }; + } + Err(e) => panic!("Failed to SELECT: {:?}", e), + } + + delete_mock_data::( + vec!["select_inner_join_test".to_string()], + "name".to_string(), + ); + + delete_mock_data::( + vec!["select_inner_join_test".to_string()], + "name".to_string(), + ); +} diff --git a/njord/tests/mysql/select_test.rs b/njord/tests/mysql/select_test.rs index ff6bc087..a3991e95 100644 --- a/njord/tests/mysql/select_test.rs +++ b/njord/tests/mysql/select_test.rs @@ -1,8 +1,7 @@ use njord::condition::Condition; use njord::keys::AutoIncrementPrimaryKey; -use njord::mysql::{self, insert}; +use njord::mysql::{self}; use njord::{column::Column, condition::Value}; -use serde::de::value; use std::collections::HashMap; use crate::{User, UserWithSubQuery}; @@ -628,78 +627,144 @@ fn select_union() { ]); } -// #[test] -// fn select_sub_queries() { -// let url = "mysql://njord_user:njord_password@localhost:3306/njord_db"; -// let mut conn = mysql::open(url); - -// match conn { -// Ok(ref mut c) => { -// let sub_query = mysql::select(vec![Column::Text("username".to_string())]) -// .from(UserWithSubQuery::default()); - -// let columns = vec![ -// Column::Text("id".to_string()), -// Column::Text("username".to_string()), -// Column::Text("email".to_string()), -// Column::Text("address".to_string()), -// Column::SubQuery(sub_query), -// ]; - -// let result = mysql::select(columns) -// .from(UserWithSubQuery::default()) -// .build(c); - -// match result { -// Ok(r) => { -// assert_eq!(r.len(), 2); -// assert_eq!(r[0].additional_address, "mjovanc"); -// } -// Err(e) => panic!("Failed to SELECT: {:?}", e), -// }; -// } -// Err(e) => panic!("Failed to SELECT: {:?}", e), -// }; -// } - -// #[test] -// fn select_in() { -// let url = "mysql://njord_user:njord_password@localhost:3306/njord_db"; -// let mut conn = mysql::open(url); - -// let columns = vec![ -// Column::Text("id".to_string()), -// Column::Text("username".to_string()), -// Column::Text("email".to_string()), -// Column::Text("address".to_string()), -// ]; - -// let condition = Condition::And( -// Box::new(Condition::In( -// "username".to_string(), -// vec![ -// Value::Literal("mjovanc".to_string()), -// Value::Literal("otheruser".to_string()), -// ], -// )), -// Box::new(Condition::NotIn( -// "username".to_string(), -// vec![Value::Literal("chasewillden".to_string())], -// )), -// ); - -// match conn { -// Ok(ref mut c) => { -// let result = mysql::select(c, columns) -// .from(User::default()) -// .where_clause(condition) -// .build(); - -// match result { -// Ok(r) => assert_eq!(r.len(), 2), -// Err(e) => panic!("Failed to SELECT: {:?}", e), -// }; -// } -// Err(e) => panic!("Failed to SELECT: {:?}", e), -// }; -// } +#[test] +fn select_sub_queries() { + insert_mock_data(vec![ + User { + id: AutoIncrementPrimaryKey::default(), + username: "select_sub_queries_test".to_string(), + email: "select_sub_queries_test@example.com".to_string(), + address: "Some Random Address 1".to_string(), + }, + User { + id: AutoIncrementPrimaryKey::default(), + username: "select_sub_queries_test2".to_string(), + email: "select_sub_queries_test2@example.com".to_string(), + address: "Some Random Address 1".to_string(), + }, + User { + id: AutoIncrementPrimaryKey::default(), + username: "select_sub_queries_test3".to_string(), + email: "select_sub_queries_test3@example.com".to_string(), + address: "SubQuery".to_string(), + }, + ]); + + let url = "mysql://njord_user:njord_password@localhost:3306/njord_db"; + let mut conn = mysql::open(url); + + match conn { + Ok(ref mut c) => { + let sub_query = mysql::select(vec![Column::Text("address".to_string())]) + .from(UserWithSubQuery::default()) + .where_clause(Condition::Eq( + "username".to_string(), + Value::Literal("select_sub_queries_test3".to_string()), + )) + .limit(1); + + let columns = vec![ + Column::Text("id".to_string()), + Column::Text("username".to_string()), + Column::Text("email".to_string()), + Column::Text("address".to_string()), + Column::SubQuery(Box::new(sub_query), "additional_address".to_string()), + ]; + + let result = mysql::select(columns) + .from(UserWithSubQuery::default()) + .where_clause(Condition::In( + "username".to_string(), + vec![ + Value::Literal("select_sub_queries_test".to_string()), + Value::Literal("select_sub_queries_test2".to_string()), + ], + )) + .build(c); + + match result { + Ok(r) => { + assert!(r.len() > 0); + assert_eq!(r[0].additional_address, "SubQuery"); + } + Err(e) => panic!("Failed to SELECT: {:?}", e), + }; + } + Err(e) => panic!("Failed to SELECT: {:?}", e), + }; + + delete_mock_data(vec![ + "select_sub_queries_test".to_string(), + "select_sub_queries_test2".to_string(), + "select_sub_queries_test3".to_string(), + ]); +} + +#[test] +fn select_in() { + insert_mock_data(vec![ + User { + id: AutoIncrementPrimaryKey::default(), + username: "select_in_test".to_string(), + email: "select_in_test@example.com".to_string(), + address: "Some Random Address 1".to_string(), + }, + User { + id: AutoIncrementPrimaryKey::default(), + username: "select_in_test2".to_string(), + email: "select_in_test2@example.com".to_string(), + address: "Some Random Address 1".to_string(), + }, + User { + id: AutoIncrementPrimaryKey::default(), + username: "select_in_test3".to_string(), + email: "select_in_test3@example.com".to_string(), + address: "Some Random Address 1".to_string(), + }, + ]); + + let url = "mysql://njord_user:njord_password@localhost:3306/njord_db"; + let mut conn = mysql::open(url); + + let columns = vec![ + Column::Text("id".to_string()), + Column::Text("username".to_string()), + Column::Text("email".to_string()), + Column::Text("address".to_string()), + ]; + + let condition = Condition::And( + Box::new(Condition::In( + "username".to_string(), + vec![ + Value::Literal("select_in_test".to_string()), + Value::Literal("select_in_test2".to_string()), + ], + )), + Box::new(Condition::NotIn( + "username".to_string(), + vec![Value::Literal("select_in_test3".to_string())], + )), + ); + + match conn { + Ok(ref mut c) => { + let result = mysql::select(columns) + .from(User::default()) + .where_clause(condition) + .build(c); + + match result { + Ok(r) => assert_eq!(r.len(), 2), + Err(e) => panic!("Failed to SELECT: {:?}", e), + }; + } + Err(e) => panic!("Failed to SELECT: {:?}", e), + }; + + delete_mock_data(vec![ + "select_in_test".to_string(), + "select_in_test2".to_string(), + "select_in_test3".to_string(), + ]); +} diff --git a/njord/tests/sqlite/delete_test.rs b/njord/tests/sqlite/delete_test.rs index 0d6cf30f..a14650c9 100644 --- a/njord/tests/sqlite/delete_test.rs +++ b/njord/tests/sqlite/delete_test.rs @@ -50,7 +50,7 @@ fn delete_with_subquery() { match conn { Ok(ref c) => { let sub_query = - SelectQueryBuilder::new(c, vec![Column::::Text("username".to_string())]) + SelectQueryBuilder::::new(c, vec![Column::Text("username".to_string())]) .where_clause(Condition::Eq( "id".to_string(), Value::Literal(1.to_string()), diff --git a/njord/tests/sqlite/insert_test.rs b/njord/tests/sqlite/insert_test.rs index 94af17a0..130d5340 100644 --- a/njord/tests/sqlite/insert_test.rs +++ b/njord/tests/sqlite/insert_test.rs @@ -41,9 +41,9 @@ fn insert_with_sub_query() { let subquery = sqlite::select( c, vec![ - Column::::Text("username".to_string()), - Column::::Text("email".to_string()), - Column::::Text("address".to_string()), + Column::Text("username".to_string()), + Column::Text("email".to_string()), + Column::Text("address".to_string()), ], ) .from(User::default()) diff --git a/njord/tests/sqlite/mod.rs b/njord/tests/sqlite/mod.rs index a8a49f93..011b9ce4 100644 --- a/njord/tests/sqlite/mod.rs +++ b/njord/tests/sqlite/mod.rs @@ -18,7 +18,7 @@ pub struct User { pub address: String, } -#[derive(Table)] +#[derive(Table, Clone)] #[table_name = "users"] pub struct UserWithSubQuery { pub id: AutoIncrementPrimaryKey, diff --git a/njord/tests/sqlite/select_test.rs b/njord/tests/sqlite/select_test.rs index 8d07289c..d358fc9c 100644 --- a/njord/tests/sqlite/select_test.rs +++ b/njord/tests/sqlite/select_test.rs @@ -464,7 +464,7 @@ fn select_sub_queries() { Column::Text("username".to_string()), Column::Text("email".to_string()), Column::Text("address".to_string()), - Column::SubQuery(sub_query), + Column::SubQuery(Box::new(sub_query), "additional_address".to_string()), ]; let result = sqlite::select(&c, columns)