diff --git a/packages/cubejs-schema-compiler/test/unit/views.test.ts b/packages/cubejs-schema-compiler/test/unit/views.test.ts index b5b0b95e09054..41e9b08e92025 100644 --- a/packages/cubejs-schema-compiler/test/unit/views.test.ts +++ b/packages/cubejs-schema-compiler/test/unit/views.test.ts @@ -391,6 +391,175 @@ describe('Views YAML', () => { }); }); + it('explicit includes + prefix a,b', async () => { + const { cubeEvaluator } = await schemaCompile([{ + name: 'simple_view', + cubes: [ + { + join_path: 'CubeA', + prefix: true, + includes: ['id', 'count_a'] + }, + { + join_path: 'CubeB', + prefix: true, + includes: ['id', 'count_b'] + }, + ] + }]); + + expect(cubeEvaluator.getCubeDefinition('simple_view').dimensions).toEqual({ + CubeA_id: dimensionFixtureForCube('CubeA.id'), + CubeB_id: dimensionFixtureForCube('CubeB.id'), + }); + + expect(cubeEvaluator.getCubeDefinition('simple_view').measures).toEqual({ + CubeA_count_a: measuresFixtureForCube('CubeA.count_a'), + CubeB_count_b: measuresFixtureForCube('CubeB.count_b'), + }); + }); + + it('explicit includes + prefix on b only', async () => { + const { cubeEvaluator } = await schemaCompile([{ + name: 'simple_view', + cubes: [ + { + join_path: 'CubeA', + includes: ['id', 'count_a'] + }, + { + join_path: 'CubeB', + prefix: true, + includes: ['id', 'count_b'] + }, + ] + }]); + + expect(cubeEvaluator.getCubeDefinition('simple_view').dimensions).toEqual({ + id: dimensionFixtureForCube('CubeA.id'), + CubeB_id: dimensionFixtureForCube('CubeB.id'), + }); + + expect(cubeEvaluator.getCubeDefinition('simple_view').measures).toEqual({ + count_a: measuresFixtureForCube('CubeA.count_a'), + CubeB_count_b: measuresFixtureForCube('CubeB.count_b'), + }); + }); + + it('explicit includes + prefix b,c with overlapping names', async () => { + const { cubeEvaluator } = await schemaCompile([{ + name: 'simple_view', + cubes: [ + { + join_path: 'CubeA', + includes: ['count_a'] + }, + { + join_path: 'CubeB', + prefix: true, + includes: ['id'] + }, + { + join_path: 'CubeA.CubeC', + prefix: true, + includes: ['id'] + }, + ] + }]); + + expect(cubeEvaluator.getCubeDefinition('simple_view').dimensions).toEqual({ + CubeB_id: dimensionFixtureForCube('CubeB.id'), + CubeC_id: dimensionFixtureForCube('CubeC.id'), + }); + + expect(cubeEvaluator.getCubeDefinition('simple_view').measures).toEqual({ + count_a: measuresFixtureForCube('CubeA.count_a'), + }); + }); + + it('explicit includes + prefix with overlapping names across cubes (issue #10520)', async () => { + const { compiler, cubeEvaluator } = prepareYamlCompiler(` + cubes: + - name: orders + sql_table: orders + measures: + - name: count + type: count + dimensions: + - name: id + sql: id + type: number + primary_key: true + - name: status + sql: status + type: string + joins: + - name: customers + relationship: many_to_one + sql: "{CUBE}.customer_id = {customers}.id" + + - name: customers + sql_table: customers + measures: + - name: count + type: count + dimensions: + - name: id + sql: id + type: number + primary_key: true + - name: name + sql: name + type: string + + - name: products + sql_table: products + measures: + - name: count + type: count + dimensions: + - name: id + sql: id + type: number + primary_key: true + - name: name + sql: name + type: string + + views: + - name: sales_overview + cubes: + - join_path: orders + includes: + - count + - status + + - join_path: orders.customers + prefix: true + includes: + - count + - name + + - join_path: orders.products + prefix: true + includes: + - count + - name +`); + + await compiler.compile(); + + const viewDef = cubeEvaluator.getCubeDefinition('sales_overview'); + + expect(Object.keys(viewDef.dimensions!).sort()).toEqual([ + 'customers_name', 'products_name', 'status' + ]); + + expect(Object.keys(viewDef.measures!).sort()).toEqual([ + 'count', 'customers_count', 'products_count' + ]); + }); + it('throws error for unresolved members', async () => { const { compiler } = prepareYamlCompiler(` cubes: diff --git a/rust/cubestore/cubestore-sql-tests/src/tests.rs b/rust/cubestore/cubestore-sql-tests/src/tests.rs index a48ab65237706..f22d4542bfec0 100644 --- a/rust/cubestore/cubestore-sql-tests/src/tests.rs +++ b/rust/cubestore/cubestore-sql-tests/src/tests.rs @@ -28,7 +28,7 @@ use tokio::io::{AsyncWriteExt, BufWriter}; use tokio::join; pub type TestFn = Box< - dyn Fn(Box) -> Pin + Send>> + dyn Fn(Box) -> Pin> + Send>> + Send + Sync + RefUnwindSafe, @@ -317,7 +317,7 @@ pub fn sql_tests(prefix: &str) -> Vec<(&'static str, TestFn)> { fn t(name: &'static str, f: fn(Box) -> F) -> (&'static str, TestFn) where - F: Future + Send + 'static, + F: Future> + Send + 'static, { (name, Box::new(move |c| Box::pin(f(c)))) } @@ -374,8 +374,8 @@ fn excluded_from_migration_test(name: &str) -> bool { MIGRATION_TEST_EXCLUSION_SET.contains(name) } -async fn insert(service: Box) { - let _ = service.exec_query("CREATE SCHEMA Foo").await.unwrap(); +async fn insert(service: Box) -> Result<(), CubeError> { + let _ = service.exec_query("CREATE SCHEMA Foo").await?; let _ = service .exec_query( "CREATE TABLE Foo.Persons ( @@ -386,8 +386,7 @@ async fn insert(service: Box) { City varchar(255) )", ) - .await - .unwrap(); + .await?; service.exec_query( "INSERT INTO Foo.Persons @@ -408,15 +407,16 @@ async fn insert(service: Box) { (28, 'LastName 7', 'FirstName 1', 'Address 1', 'City 1'), (33, 'LastName 26', 'FirstName 2', 'Address 2', 'City 2'), (29, 'LastName 8', 'FirstName 1', 'Address 1', 'City 1'), (32, 'LastName 27', 'FirstName 2', 'Address 2', 'City 2'), (30, 'LastName 9', 'FirstName 1', 'Address 1', 'City 1'), (31, 'LastName 28', 'FirstName 2', 'Address 2', 'City 2')" - ).await.unwrap(); + ).await?; service.exec_query("INSERT INTO Foo.Persons (LastName, PersonID, FirstName, Address, City) VALUES - ('LastName 1', 23, 'FirstName 1', 'Address 1', 'City 1'), ('LastName 2', 22, 'FirstName 2', 'Address 2', 'City 2');").await.unwrap(); + ('LastName 1', 23, 'FirstName 1', 'Address 1', 'City 1'), ('LastName 2', 22, 'FirstName 2', 'Address 2', 'City 2');").await?; + Ok(()) } -async fn refresh_selects(service: Box) { +async fn refresh_selects(service: Box) -> Result<(), CubeError> { let t = SystemTime::now() .duration_since(SystemTime::UNIX_EPOCH) .unwrap() @@ -424,8 +424,7 @@ async fn refresh_selects(service: Box) { let result = service .exec_query("SELECT FLOOR((UNIX_TIMESTAMP()) / 10)") - .await - .unwrap(); + .await?; assert_eq!( result.get_rows(), @@ -434,24 +433,22 @@ async fn refresh_selects(service: Box) { let result = service .exec_query("SELECT ((3600 * 24 - 28800) / 86400)") - .await - .unwrap(); + .await?; assert_eq!(result.get_rows(), &vec![Row::new(vec![TableValue::Int(0)])]); let result = service .exec_query("SELECT ((3600 * (24 + 8) - 28800) / 86400)") - .await - .unwrap(); + .await?; assert_eq!(result.get_rows(), &vec![Row::new(vec![TableValue::Int(1)])]); let result = service .exec_query("SELECT ((3600 * (48 + 8) - 28800) / 86400)") - .await - .unwrap(); + .await?; assert_eq!(result.get_rows(), &vec![Row::new(vec![TableValue::Int(2)])]); + Ok(()) } -async fn select_test(service: Box) { - let _ = service.exec_query("CREATE SCHEMA Foo").await.unwrap(); +async fn select_test(service: Box) -> Result<(), CubeError> { + let _ = service.exec_query("CREATE SCHEMA Foo").await?; let _ = service .exec_query( @@ -463,8 +460,7 @@ async fn select_test(service: Box) { City varchar(255) );", ) - .await - .unwrap(); + .await?; service .exec_query( @@ -474,56 +470,46 @@ async fn select_test(service: Box) { ('LastName 1', 23, 'FirstName 1', 'Address 1', 'City 1'), ('LastName 2', 22, 'FirstName 2', 'Address 2', 'City 2');", ) - .await - .unwrap(); + .await?; let result = service .exec_query("SELECT PersonID person_id from Foo.Persons") - .await - .unwrap(); + .await?; assert_eq!(result.get_rows()[0], Row::new(vec![TableValue::Int(22)])); assert_eq!(result.get_rows()[1], Row::new(vec![TableValue::Int(23)])); + Ok(()) } -async fn negative_numbers(service: Box) { - let _ = service.exec_query("CREATE SCHEMA foo").await.unwrap(); +async fn negative_numbers(service: Box) -> Result<(), CubeError> { + let _ = service.exec_query("CREATE SCHEMA foo").await?; let _ = service .exec_query("CREATE TABLE foo.values (int_value int)") - .await - .unwrap(); + .await?; service .exec_query("INSERT INTO foo.values (int_value) VALUES (-153)") - .await - .unwrap(); + .await?; - let result = service - .exec_query("SELECT * from foo.values") - .await - .unwrap(); + let result = service.exec_query("SELECT * from foo.values").await?; assert_eq!(result.get_rows()[0], Row::new(vec![TableValue::Int(-153)])); + Ok(()) } -async fn negative_decimal(service: Box) { - let _ = service.exec_query("CREATE SCHEMA foo").await.unwrap(); +async fn negative_decimal(service: Box) -> Result<(), CubeError> { + let _ = service.exec_query("CREATE SCHEMA foo").await?; let _ = service .exec_query("CREATE TABLE foo.values (decimal_value decimal)") - .await - .unwrap(); + .await?; service .exec_query("INSERT INTO foo.values (decimal_value) VALUES (-0.12345)") - .await - .unwrap(); + .await?; - let result = service - .exec_query("SELECT * from foo.values") - .await - .unwrap(); + let result = service.exec_query("SELECT * from foo.values").await?; assert_eq!( match &result.get_rows()[0].values()[0] { @@ -532,19 +518,18 @@ async fn negative_decimal(service: Box) { }, "-0.12345" ); + Ok(()) } -async fn decimal_math(service: Box) { - service.exec_query("CREATE SCHEMA foo").await.unwrap(); +async fn decimal_math(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA foo").await?; service .exec_query("CREATE TABLE foo.test_decimal (value Decimal(5, 10))") - .await - .unwrap(); - service.exec_query("INSERT INTO foo.test_decimal (value) VALUES (10), (20), (30), (40), (100), (200), (300)").await.unwrap(); + .await?; + service.exec_query("INSERT INTO foo.test_decimal (value) VALUES (10), (20), (30), (40), (100), (200), (300)").await?; let r: Arc = service .exec_query("SELECT value, value / 3 FROM foo.test_decimal") - .await - .unwrap(); + .await?; let columns: &Vec = r.get_columns(); assert_eq!(columns.len(), 2); assert_eq!( @@ -576,63 +561,58 @@ async fn decimal_math(service: Box) { .map(mk_row) .collect::>() ); + Ok(()) } -async fn custom_types(service: Box) { - service.exec_query("CREATE SCHEMA foo").await.unwrap(); +async fn custom_types(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA foo").await?; service .exec_query("CREATE TABLE foo.values (int_value mediumint, b1 bytes, b2 varbinary)") - .await - .unwrap(); + .await?; service .exec_query("INSERT INTO foo.values (int_value, b1, b2) VALUES (-153, X'0a', X'0b')") - .await - .unwrap(); + .await?; + Ok(()) } -async fn group_by_boolean(service: Box) { - let _ = service.exec_query("CREATE SCHEMA foo").await.unwrap(); +async fn group_by_boolean(service: Box) -> Result<(), CubeError> { + let _ = service.exec_query("CREATE SCHEMA foo").await?; let _ = service .exec_query("CREATE TABLE foo.bool_group (bool_value boolean)") - .await - .unwrap(); + .await?; service.exec_query( "INSERT INTO foo.bool_group (bool_value) VALUES (true), (false), (true), (false), (false)" - ).await.unwrap(); + ).await?; // TODO compaction fails the test in between? // service.exec_query( // "INSERT INTO foo.bool_group (bool_value) VALUES (true), (false), (true), (false), (false)" - // ).await.unwrap(); + // ).await?; let result = service .exec_query("SELECT count(*) from foo.bool_group") - .await - .unwrap(); + .await?; assert_eq!(result.get_rows()[0], Row::new(vec![TableValue::Int(5)])); let result = service .exec_query("SELECT count(*) from foo.bool_group where bool_value = true") - .await - .unwrap(); + .await?; assert_eq!(result.get_rows()[0], Row::new(vec![TableValue::Int(2)])); let result = service .exec_query("SELECT count(*) from foo.bool_group where bool_value = 'true'") - .await - .unwrap(); + .await?; assert_eq!(result.get_rows()[0], Row::new(vec![TableValue::Int(2)])); let result = service .exec_query( "SELECT g.bool_value, count(*) from foo.bool_group g GROUP BY 1 ORDER BY 2 DESC", ) - .await - .unwrap(); + .await?; assert_eq!( result.get_rows()[0], @@ -642,38 +622,35 @@ async fn group_by_boolean(service: Box) { result.get_rows()[1], Row::new(vec![TableValue::Boolean(true), TableValue::Int(2)]) ); + Ok(()) } -async fn group_by_decimal(service: Box) { - let _ = service.exec_query("CREATE SCHEMA foo").await.unwrap(); +async fn group_by_decimal(service: Box) -> Result<(), CubeError> { + let _ = service.exec_query("CREATE SCHEMA foo").await?; let _ = service .exec_query("CREATE TABLE foo.decimal_group (id INT, decimal_value DECIMAL)") - .await - .unwrap(); + .await?; service.exec_query( "INSERT INTO foo.decimal_group (id, decimal_value) VALUES (1, 100), (2, 200), (3, 100), (4, 100), (5, 200)" - ).await.unwrap(); + ).await?; let result = service .exec_query("SELECT count(*) from foo.decimal_group") - .await - .unwrap(); + .await?; assert_eq!(result.get_rows()[0], Row::new(vec![TableValue::Int(5)])); let result = service .exec_query("SELECT count(*) from foo.decimal_group where decimal_value = 200") - .await - .unwrap(); + .await?; assert_eq!(result.get_rows()[0], Row::new(vec![TableValue::Int(2)])); let result = service .exec_query( "SELECT g.decimal_value, count(*) from foo.decimal_group g GROUP BY 1 ORDER BY 2 DESC", ) - .await - .unwrap(); + .await?; assert_eq!( result.get_rows(), @@ -688,93 +665,81 @@ async fn group_by_decimal(service: Box) { ]) ] ); + Ok(()) } -async fn group_by_nulls(service: Box) { - let _ = service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn group_by_nulls(service: Box) -> Result<(), CubeError> { + let _ = service.exec_query("CREATE SCHEMA s").await?; let _ = service .exec_query("CREATE TABLE s.data (id int, n int)") - .await - .unwrap(); + .await?; service .exec_query( "INSERT INTO s.data (id, n) VALUES (NULL, 1), (NULL, 2), (NULL, 3), (1, 1), (2, 2)", ) - .await - .unwrap(); + .await?; let result = service .exec_query("SELECT id, sum(n) from s.data group by 1 order by 1") - .await - .unwrap(); + .await?; assert_eq!( to_rows(&result), rows(&[(Some(1), 1), (Some(2), 2), (None, 6)]) ); + Ok(()) } -async fn logical_alias(service: Box) { - let _ = service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn logical_alias(service: Box) -> Result<(), CubeError> { + let _ = service.exec_query("CREATE SCHEMA s").await?; let _ = service .exec_query("CREATE TABLE s.logical (id int, n int)") - .await - .unwrap(); + .await?; service .exec_query("INSERT INTO s.logical (id, n) VALUES (1, 1), (2, 2), (3, 3), (1, 1), (2, 2)") - .await - .unwrap(); + .await?; let result = service .exec_query("SELECT sum(n) from (select id, sum(n) n from s.logical group by 1) `test` ") - .await - .unwrap(); + .await?; assert_eq!(to_rows(&result), rows(&[(9)])); + Ok(()) } -async fn float_decimal_scale(service: Box) { - service.exec_query("CREATE SCHEMA foo").await.unwrap(); +async fn float_decimal_scale(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA foo").await?; service .exec_query("CREATE TABLE foo.decimal_group (id INT, decimal_value FLOAT)") - .await - .unwrap(); + .await?; service.exec_query( "INSERT INTO foo.decimal_group (id, decimal_value) VALUES (1, 677863988852), (2, 677863988852.123e-10), (3, 6778639882.123e+3)" - ).await.unwrap(); + ).await?; let result = service .exec_query("SELECT SUM(decimal_value) FROM foo.decimal_group") - .await - .unwrap(); + .await?; assert_eq!( result.get_rows(), &vec![Row::new(vec![TableValue::Float(7456503871042.786.into())])] ); + Ok(()) } -async fn float_merge(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); - service - .exec_query("CREATE TABLE s.f1 (n float)") - .await - .unwrap(); +async fn float_merge(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; + service.exec_query("CREATE TABLE s.f1 (n float)").await?; service .exec_query("INSERT INTO s.f1 (n) VALUES (1.0), (2.0)") - .await - .unwrap(); - service - .exec_query("CREATE TABLE s.f2 (n float)") - .await - .unwrap(); + .await?; + service.exec_query("CREATE TABLE s.f2 (n float)").await?; service .exec_query("INSERT INTO s.f2 (n) VALUES (1.0), (3.0)") - .await - .unwrap(); + .await?; let r = service .exec_query( "SELECT n \ @@ -782,8 +747,7 @@ async fn float_merge(service: Box) { GROUP BY 1 \ ORDER BY 1", ) - .await - .unwrap(); + .await?; assert_eq!( to_rows(&r), @@ -793,32 +757,30 @@ async fn float_merge(service: Box) { vec![TableValue::Float(3.0.into())], ] ); + Ok(()) } -async fn join(service: Box) { - let _ = service.exec_query("CREATE SCHEMA foo").await.unwrap(); +async fn join(service: Box) -> Result<(), CubeError> { + let _ = service.exec_query("CREATE SCHEMA foo").await?; let _ = service .exec_query("CREATE TABLE foo.orders (customer_id text, amount int)") - .await - .unwrap(); + .await?; let _ = service .exec_query("CREATE TABLE foo.customers (id text, city text, state text)") - .await - .unwrap(); + .await?; service .exec_query( "INSERT INTO foo.orders (customer_id, amount) VALUES ('a', 10), ('b', 2), ('b', 3)", ) - .await - .unwrap(); + .await?; service.exec_query( "INSERT INTO foo.customers (id, city, state) VALUES ('a', 'San Francisco', 'CA'), ('b', 'New York', 'NY')" - ).await.unwrap(); + ).await?; - let result = service.exec_query("SELECT c.city, sum(o.amount) from foo.orders o JOIN foo.customers c ON o.customer_id = c.id GROUP BY 1 ORDER BY 2 DESC").await.unwrap(); + let result = service.exec_query("SELECT c.city, sum(o.amount) from foo.orders o JOIN foo.customers c ON o.customer_id = c.id GROUP BY 1 ORDER BY 2 DESC").await?; assert_eq!( to_rows(&result), @@ -835,7 +797,7 @@ async fn join(service: Box) { ); // Same query, reverse comparison order. - let result2 = service.exec_query("SELECT c.city, sum(o.amount) from foo.orders o JOIN foo.customers c ON c.id = o.customer_id GROUP BY 1 ORDER BY 2 DESC").await.unwrap(); + let result2 = service.exec_query("SELECT c.city, sum(o.amount) from foo.orders o JOIN foo.customers c ON c.id = o.customer_id GROUP BY 1 ORDER BY 2 DESC").await?; assert_eq!(result.get_rows(), result2.get_rows()); // Join on non-existing field. @@ -849,34 +811,32 @@ async fn join(service: Box) { .exec_query( "SELECT c.id, k.id FROM foo.customers c JOIN foo.customers k ON c.id = k.id ORDER BY 1", ) - .await - .unwrap(); + .await?; assert_eq!(to_rows(&result), rows(&[("a", "a"), ("b", "b")])); + Ok(()) } -async fn filtered_join(service: Box) { - let _ = service.exec_query("CREATE SCHEMA foo").await.unwrap(); +async fn filtered_join(service: Box) -> Result<(), CubeError> { + let _ = service.exec_query("CREATE SCHEMA foo").await?; let _ = service .exec_query("CREATE TABLE foo.employee (name varchar) INDEX employee_name (name)") - .await - .unwrap(); + .await?; let _ = service .exec_query("CREATE TABLE foo.employee_department_bridge (employee_name text, department_name text) INDEX employee_department_bridge_name (employee_name)") .await - .unwrap(); + ?; service .exec_query("INSERT INTO foo.employee (name) VALUES ('John'), ('Jim')") - .await - .unwrap(); + .await?; service .exec_query("INSERT INTO foo.employee_department_bridge (employee_name, department_name) VALUES ('John','Marketing'), ('Jim','Marketing')") .await - .unwrap(); + ?; - let result = service.exec_query("select * from foo.employee AS e LEFT JOIN foo.employee_department_bridge b on b.employee_name = e.name where b.department_name = 'Non existing'").await.unwrap(); + let result = service.exec_query("select * from foo.employee AS e LEFT JOIN foo.employee_department_bridge b on b.employee_name = e.name where b.department_name = 'Non existing'").await?; assert_eq!(result.len(), 0); @@ -885,65 +845,61 @@ async fn filtered_join(service: Box) { "EXPLAIN ANALYZE select e.name from foo.employee AS e LEFT JOIN foo.employee_department_bridge b on b.employee_name=e.name where b.department_name = 'Marketing' GROUP BY 1 LIMIT 10000", ) .await - .unwrap()); + ?); let result = service .exec_query( "select e.name from foo.employee AS e LEFT JOIN foo.employee_department_bridge b on b.employee_name=e.name where b.department_name = 'Marketing' GROUP BY 1 ORDER BY 1 LIMIT 10000", ) .await - .unwrap(); + ?; assert_eq!(to_rows(&result), rows(&[("Jim"), ("John")])); + Ok(()) } -async fn three_tables_join(service: Box) { - service.exec_query("CREATE SCHEMA foo").await.unwrap(); +async fn three_tables_join(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA foo").await?; service .exec_query( "CREATE TABLE foo.orders (orders_customer_id text, orders_product_id int, amount int)", ) - .await - .unwrap(); + .await?; service .exec_query("CREATE INDEX orders_by_product ON foo.orders (orders_product_id)") - .await - .unwrap(); + .await?; service .exec_query("CREATE TABLE foo.customers (customer_id text, city text, state text)") - .await - .unwrap(); + .await?; service .exec_query("CREATE TABLE foo.products (product_id int, name text)") - .await - .unwrap(); + .await?; service.exec_query( "INSERT INTO foo.orders (orders_customer_id, orders_product_id, amount) VALUES ('a', 1, 10), ('b', 2, 2), ('b', 2, 3)" - ).await.unwrap(); + ).await?; service.exec_query( "INSERT INTO foo.orders (orders_customer_id, orders_product_id, amount) VALUES ('b', 1, 10), ('c', 2, 2), ('c', 2, 3)" - ).await.unwrap(); + ).await?; service.exec_query( "INSERT INTO foo.orders (orders_customer_id, orders_product_id, amount) VALUES ('c', 1, 10), ('d', 2, 2), ('d', 2, 3)" - ).await.unwrap(); + ).await?; service.exec_query( "INSERT INTO foo.customers (customer_id, city, state) VALUES ('a', 'San Francisco', 'CA'), ('b', 'New York', 'NY')" - ).await.unwrap(); + ).await?; service.exec_query( "INSERT INTO foo.customers (customer_id, city, state) VALUES ('c', 'San Francisco', 'CA'), ('d', 'New York', 'NY')" - ).await.unwrap(); + ).await?; service .exec_query( "INSERT INTO foo.products (product_id, name) VALUES (1, 'Potato'), (2, 'Tomato')", ) - .await - .unwrap(); + .await?; let result = service .exec_query( @@ -952,8 +908,7 @@ async fn three_tables_join(service: Box) { LEFT JOIN foo.products p ON orders_product_id = product_id \ GROUP BY 1, 2 ORDER BY 3 DESC, 1 ASC, 2 ASC", ) - .await - .unwrap(); + .await?; let expected = vec![ Row::new(vec![ @@ -988,8 +943,7 @@ async fn three_tables_join(service: Box) { WHERE customer_id = 'b' AND product_id IN ('2') GROUP BY 1, 2 ORDER BY 3 DESC, 1 ASC, 2 ASC", ) - .await - .unwrap(); + .await?; let expected = vec![Row::new(vec![ TableValue::String("New York".to_string()), @@ -998,56 +952,52 @@ async fn three_tables_join(service: Box) { ])]; assert_eq!(result.get_rows(), &expected); + Ok(()) } -async fn three_tables_join_with_filter(service: Box) { - service.exec_query("CREATE SCHEMA foo").await.unwrap(); +async fn three_tables_join_with_filter(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA foo").await?; service .exec_query( "CREATE TABLE foo.orders (orders_customer_id text, orders_product_id int, amount int)", ) - .await - .unwrap(); + .await?; service .exec_query("CREATE INDEX orders_by_product ON foo.orders (orders_product_id)") - .await - .unwrap(); + .await?; service .exec_query("CREATE TABLE foo.customers (customer_id text, city text, state text)") - .await - .unwrap(); + .await?; service .exec_query("CREATE TABLE foo.products (product_id int, name text)") - .await - .unwrap(); + .await?; service.exec_query( "INSERT INTO foo.orders (orders_customer_id, orders_product_id, amount) VALUES ('a', 1, 10), ('b', 2, 2), ('b', 2, 3)" - ).await.unwrap(); + ).await?; service.exec_query( "INSERT INTO foo.orders (orders_customer_id, orders_product_id, amount) VALUES ('b', 1, 10), ('c', 2, 2), ('c', 2, 3)" - ).await.unwrap(); + ).await?; service.exec_query( "INSERT INTO foo.orders (orders_customer_id, orders_product_id, amount) VALUES ('c', 1, 10), ('d', 2, 2), ('d', 2, 3)" - ).await.unwrap(); + ).await?; service.exec_query( "INSERT INTO foo.customers (customer_id, city, state) VALUES ('a', 'San Francisco', 'CA'), ('b', 'New York', 'NY')" - ).await.unwrap(); + ).await?; service.exec_query( "INSERT INTO foo.customers (customer_id, city, state) VALUES ('c', 'San Francisco', 'CA'), ('d', 'New York', 'NY')" - ).await.unwrap(); + ).await?; service .exec_query( "INSERT INTO foo.products (product_id, name) VALUES (1, 'Potato'), (2, 'Tomato')", ) - .await - .unwrap(); + .await?; let result = service .exec_query( @@ -1057,8 +1007,7 @@ async fn three_tables_join_with_filter(service: Box) { WHERE customer_id = 'a' \ GROUP BY 1, 2 ORDER BY 3 DESC, 1 ASC, 2 ASC", ) - .await - .unwrap(); + .await?; let expected = vec![Row::new(vec![ TableValue::String("San Francisco".to_string()), @@ -1067,56 +1016,52 @@ async fn three_tables_join_with_filter(service: Box) { ])]; assert_eq!(result.get_rows(), &expected); + Ok(()) } -async fn three_tables_join_with_union(service: Box) { - service.exec_query("CREATE SCHEMA foo").await.unwrap(); +async fn three_tables_join_with_union(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA foo").await?; - service.exec_query("CREATE TABLE foo.orders_1 (orders_customer_id text, orders_product_id int, amount int)").await.unwrap(); - service.exec_query("CREATE TABLE foo.orders_2 (orders_customer_id text, orders_product_id int, amount int)").await.unwrap(); + service.exec_query("CREATE TABLE foo.orders_1 (orders_customer_id text, orders_product_id int, amount int)").await?; + service.exec_query("CREATE TABLE foo.orders_2 (orders_customer_id text, orders_product_id int, amount int)").await?; service .exec_query("CREATE INDEX orders_by_product_1 ON foo.orders_1 (orders_product_id)") - .await - .unwrap(); + .await?; service .exec_query("CREATE INDEX orders_by_product_2 ON foo.orders_2 (orders_product_id)") - .await - .unwrap(); + .await?; service .exec_query("CREATE TABLE foo.customers (customer_id text, city text, state text)") - .await - .unwrap(); + .await?; service .exec_query("CREATE TABLE foo.products (product_id int, name text)") - .await - .unwrap(); + .await?; service.exec_query( "INSERT INTO foo.orders_1 (orders_customer_id, orders_product_id, amount) VALUES ('a', 1, 10), ('b', 2, 2), ('b', 2, 3)" - ).await.unwrap(); + ).await?; service.exec_query( "INSERT INTO foo.orders_1 (orders_customer_id, orders_product_id, amount) VALUES ('b', 1, 10), ('c', 2, 2), ('c', 2, 3)" - ).await.unwrap(); + ).await?; service.exec_query( "INSERT INTO foo.orders_2 (orders_customer_id, orders_product_id, amount) VALUES ('c', 1, 10), ('d', 2, 2), ('d', 2, 3)" - ).await.unwrap(); + ).await?; service.exec_query( "INSERT INTO foo.customers (customer_id, city, state) VALUES ('a', 'San Francisco', 'CA'), ('b', 'New York', 'NY')" - ).await.unwrap(); + ).await?; service.exec_query( "INSERT INTO foo.customers (customer_id, city, state) VALUES ('c', 'San Francisco', 'CA'), ('d', 'New York', 'NY')" - ).await.unwrap(); + ).await?; service .exec_query( "INSERT INTO foo.products (product_id, name) VALUES (1, 'Potato'), (2, 'Tomato')", ) - .await - .unwrap(); + .await?; let result = service.exec_query( "SELECT city, name, sum(amount) FROM (SELECT * FROM foo.orders_1 UNION ALL SELECT * FROM foo.orders_2) o \ @@ -1124,7 +1069,7 @@ async fn three_tables_join_with_union(service: Box) { LEFT JOIN foo.products p ON orders_product_id = product_id \ WHERE customer_id = 'a' \ GROUP BY 1, 2 ORDER BY 3 DESC, 1 ASC, 2 ASC" - ).await.unwrap(); + ).await?; let expected = vec![Row::new(vec![ TableValue::String("San Francisco".to_string()), @@ -1133,85 +1078,84 @@ async fn three_tables_join_with_union(service: Box) { ])]; assert_eq!(result.get_rows(), &expected); + Ok(()) } -async fn in_list(service: Box) { - service.exec_query("CREATE SCHEMA foo").await.unwrap(); +async fn in_list(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA foo").await?; service .exec_query("CREATE TABLE foo.customers (id text, city text, state text)") - .await - .unwrap(); + .await?; service.exec_query( "INSERT INTO foo.customers (id, city, state) VALUES ('a', 'San Francisco', 'CA'), ('b', 'New York', 'NY'), ('c', 'San Diego', 'CA'), ('d', 'Austin', 'TX')" - ).await.unwrap(); + ).await?; let result = service .exec_query("SELECT count(*) from foo.customers WHERE state in ('CA', 'TX')") - .await - .unwrap(); + .await?; assert_eq!(result.get_rows()[0], Row::new(vec![TableValue::Int(3)])); + Ok(()) } -async fn in_list_with_union(service: Box) { - service.exec_query("CREATE SCHEMA foo").await.unwrap(); +async fn in_list_with_union(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA foo").await?; service .exec_query("CREATE TABLE foo.customers_1 (id text, city text, state text)") - .await - .unwrap(); + .await?; service .exec_query("CREATE TABLE foo.customers_2 (id text, city text, state text)") - .await - .unwrap(); + .await?; service.exec_query( "INSERT INTO foo.customers_1 (id, city, state) VALUES ('a1', 'San Francisco', 'CA'), ('b1', 'New York', 'NY'), ('c1', 'San Diego', 'CA'), ('d1', 'Austin', 'TX')" - ).await.unwrap(); + ).await?; service.exec_query( "INSERT INTO foo.customers_2 (id, city, state) VALUES ('a2', 'San Francisco', 'CA'), ('b2', 'New York', 'NY'), ('c2', 'San Diego', 'CA'), ('d2', 'Austin', 'TX')" - ).await.unwrap(); + ).await?; let result = service .exec_query("SELECT count(*) from (SELECT * FROM foo.customers_1 UNION ALL SELECT * FROM foo.customers_2) AS `customers` WHERE state in ('CA', 'TX')") .await - .unwrap(); + ?; assert_eq!(result.get_rows()[0], Row::new(vec![TableValue::Int(6)])); + Ok(()) } -async fn numeric_cast_setup(service: &dyn SqlClient) -> &'static str { - service.exec_query("CREATE SCHEMA foo").await.unwrap(); +async fn numeric_cast_setup(service: &dyn SqlClient) -> Result<&'static str, CubeError> { + service.exec_query("CREATE SCHEMA foo").await?; service .exec_query("CREATE TABLE foo.managers (id text, department_id int)") - .await - .unwrap(); + .await?; service.exec_query( "INSERT INTO foo.managers (id, department_id) VALUES ('a', 1), ('b', 3), ('c', 3), ('d', 5)" - ).await.unwrap(); + ).await?; - ("SELECT count(*) from foo.managers WHERE department_id in ('3', '5')") as _ + Ok(("SELECT count(*) from foo.managers WHERE department_id in ('3', '5')") as _) } -async fn numeric_cast(service: Box) { - let query = numeric_cast_setup(service.as_ref()).await; +async fn numeric_cast(service: Box) -> Result<(), CubeError> { + let query = numeric_cast_setup(service.as_ref()).await?; - let result = service.exec_query(query).await.unwrap(); + let result = service.exec_query(query).await?; assert_eq!(result.get_rows()[0], Row::new(vec![TableValue::Int(3)])); + Ok(()) } -async fn planning_numeric_cast(service: Box) { - let query = numeric_cast_setup(service.as_ref()).await; +async fn planning_numeric_cast(service: Box) -> Result<(), CubeError> { + let query = numeric_cast_setup(service.as_ref()).await?; // Check that we're casting '3' to int and not department_id to Utf8, with our Cube-specific type_coercion changes in DF. - let plans = service.plan_query(query).await.unwrap(); + let plans = service.plan_query(query).await?; let expected = "Projection, [count(Int64(1))@0:count(*)]\ \n LinearFinalAggregate\ @@ -1234,55 +1178,51 @@ async fn planning_numeric_cast(service: Box) { } ), ); + Ok(()) } -async fn cast_timestamp_to_utf8(service: Box) { - service.exec_query("CREATE SCHEMA foo").await.unwrap(); +async fn cast_timestamp_to_utf8(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA foo").await?; service .exec_query("CREATE TABLE foo.timestamps (id text, created timestamp)") - .await - .unwrap(); + .await?; service.exec_query( "INSERT INTO foo.timestamps (id, created) VALUES ('a', '2022-01-01T00:00:00Z'), ('b', '2021-01-01T00:00:00Z')" - ).await.unwrap(); + ).await?; let r = service .exec_query("SELECT id, CAST(created AS VARCHAR) from foo.timestamps ORDER BY id ASC") - .await - .unwrap(); + .await?; assert_eq!( to_rows(&r), rows(&[("a", "2022-01-01T00:00:00"), ("b", "2021-01-01T00:00:00"),]) ); + Ok(()) } -async fn numbers_to_bool(service: Box) { +async fn numbers_to_bool(service: Box) -> Result<(), CubeError> { let r = service .exec_query("SELECT 1 = TRUE, FALSE = 0, -1 = TRUE, 123 = TRUE") - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&[(true, true, true, true)])); - service.exec_query("CREATE SCHEMA s").await.unwrap(); + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.bools (b boolean, i int)") - .await - .unwrap(); + .await?; service .exec_query( "INSERT INTO s.bools(b, i) VALUES (true, 0), (false, 0), (true, 123), (false, 123)", ) - .await - .unwrap(); + .await?; // Compare array with constant. let r = service .exec_query("SELECT b, b = 1, b = 0, b = 123 FROM s.bools GROUP BY 1, 2, 3 ORDER BY 1") - .await - .unwrap(); + .await?; assert_eq!( to_rows(&r), rows(&[(false, false, true, false), (true, true, false, true)]) @@ -1291,8 +1231,7 @@ async fn numbers_to_bool(service: Box) { // Compare array with array. let r = service .exec_query("SELECT b, i, b = i FROM s.bools ORDER BY 1, 2") - .await - .unwrap(); + .await?; assert_eq!( to_rows(&r), rows(&[ @@ -1306,36 +1245,32 @@ async fn numbers_to_bool(service: Box) { // Other types work fine. let r = service .exec_query("SELECT 1 = 1, '1' = 1, 'foo' = 'foo'") - .await - .unwrap(); - assert_eq!(to_rows(&r), rows(&[(true, true, true)])) + .await?; + assert_eq!(to_rows(&r), rows(&[(true, true, true)])); + Ok(()) } -async fn union(service: Box) { - let _ = service.exec_query("CREATE SCHEMA foo").await.unwrap(); +async fn union(service: Box) -> Result<(), CubeError> { + let _ = service.exec_query("CREATE SCHEMA foo").await?; let _ = service .exec_query("CREATE TABLE foo.orders1 (customer_id text, amount int)") - .await - .unwrap(); + .await?; let _ = service .exec_query("CREATE TABLE foo.orders2 (customer_id text, amount int)") - .await - .unwrap(); + .await?; service .exec_query( "INSERT INTO foo.orders1 (customer_id, amount) VALUES ('a', 10), ('b', 2), ('b', 3)", ) - .await - .unwrap(); + .await?; service .exec_query( "INSERT INTO foo.orders2 (customer_id, amount) VALUES ('b', 20), ('c', 20), ('b', 30)", ) - .await - .unwrap(); + .await?; let result = service .exec_query( @@ -1343,8 +1278,7 @@ async fn union(service: Box) { (select * from foo.orders1 union all select * from foo.orders2) `u` \ WHERE `u`.customer_id like '%' GROUP BY 1 ORDER BY 2 DESC", ) - .await - .unwrap(); + .await?; assert_eq!( result.get_rows()[0], @@ -1367,25 +1301,23 @@ async fn union(service: Box) { TableValue::Int(10) ]) ); + Ok(()) } -async fn nested_union_empty_tables(service: Box) { - let _ = service.exec_query("CREATE SCHEMA foo").await.unwrap(); +async fn nested_union_empty_tables(service: Box) -> Result<(), CubeError> { + let _ = service.exec_query("CREATE SCHEMA foo").await?; let _ = service .exec_query("CREATE TABLE foo.un_1 (a int, b int, c int)") - .await - .unwrap(); + .await?; let _ = service .exec_query("CREATE TABLE foo.un (a int, b int, c int)") - .await - .unwrap(); + .await?; let _ = service .exec_query("CREATE TABLE foo.un_2 (a int, b int, c int)") - .await - .unwrap(); + .await?; service .exec_query( @@ -1395,8 +1327,7 @@ async fn nested_union_empty_tables(service: Box) { (5, 6, 7), (8, 9, 10)", ) - .await - .unwrap(); + .await?; let result = service .exec_query( @@ -1424,8 +1355,7 @@ async fn nested_union_empty_tables(service: Box) { GROUP BY 1, 2 ORDER BY 2 LIMIT 2 ", ) - .await - .unwrap(); + .await?; assert_eq!(result.get_rows().len(), 2); assert_eq!( @@ -1437,30 +1367,31 @@ async fn nested_union_empty_tables(service: Box) { result.get_rows()[1], Row::new(vec![TableValue::Int(2), TableValue::Int(3),]) ); + Ok(()) } -async fn timestamp_select(service: Box) { - let _ = service.exec_query("CREATE SCHEMA foo").await.unwrap(); +async fn timestamp_select(service: Box) -> Result<(), CubeError> { + let _ = service.exec_query("CREATE SCHEMA foo").await?; let _ = service .exec_query("CREATE TABLE foo.timestamps (t timestamp)") - .await - .unwrap(); + .await?; service.exec_query( "INSERT INTO foo.timestamps (t) VALUES ('2020-01-01T00:00:00.000Z'), ('2020-01-02T00:00:00.000Z'), ('2020-01-03T00:00:00.000Z')" - ).await.unwrap(); + ).await?; service.exec_query( "INSERT INTO foo.timestamps (t) VALUES ('2020-01-01T00:00:00.000Z'), ('2020-01-02T00:00:00.000Z'), ('2020-01-03T00:00:00.000Z')" - ).await.unwrap(); + ).await?; - let result = service.exec_query("SELECT count(*) from foo.timestamps WHERE t >= to_timestamp('2020-01-02T00:00:00.000Z')").await.unwrap(); + let result = service.exec_query("SELECT count(*) from foo.timestamps WHERE t >= to_timestamp('2020-01-02T00:00:00.000Z')").await?; assert_eq!(result.get_rows()[0], Row::new(vec![TableValue::Int(4)])); + Ok(()) } -async fn timestamp_seconds_frac(service: Box) { +async fn timestamp_seconds_frac(service: Box) -> Result<(), CubeError> { for s in &[ "1970-01-01T00:00:00.123Z", "1970-01-01T00:00:00.123", @@ -1479,19 +1410,18 @@ async fn timestamp_seconds_frac(service: Box) { } let r = service .exec_query(&format!("SELECT to_timestamp('{}')", s)) - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&[TimestampValue::new(123000000)])); } + Ok(()) } -async fn column_escaping(service: Box) { - service.exec_query("CREATE SCHEMA foo").await.unwrap(); +async fn column_escaping(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA foo").await?; service .exec_query("CREATE TABLE foo.timestamps (t timestamp, amount int)") - .await - .unwrap(); + .await?; service .exec_query( @@ -1500,8 +1430,7 @@ async fn column_escaping(service: Box) { ('2020-01-01T00:01:00.000Z', 2), \ ('2020-01-02T00:10:00.000Z', 3)", ) - .await - .unwrap(); + .await?; let result = service .exec_query( @@ -1509,8 +1438,7 @@ async fn column_escaping(service: Box) { FROM foo.timestamps `timestamp` \ WHERE `timestamp`.t >= to_timestamp('2020-01-02T00:00:00.000Z') GROUP BY 1", ) - .await - .unwrap(); + .await?; assert_eq!( result.get_rows()[0], @@ -1519,20 +1447,19 @@ async fn column_escaping(service: Box) { TableValue::Int(3) ]) ); + Ok(()) } -async fn information_schema(service: Box) { - service.exec_query("CREATE SCHEMA foo").await.unwrap(); +async fn information_schema(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA foo").await?; service .exec_query("CREATE TABLE foo.timestamps (t timestamp, amount int)") - .await - .unwrap(); + .await?; let result = service .exec_query("SELECT schema_name FROM information_schema.schemata") - .await - .unwrap(); + .await?; assert_eq!( result.get_rows(), @@ -1541,55 +1468,50 @@ async fn information_schema(service: Box) { let result = service .exec_query("SELECT table_name FROM information_schema.tables") - .await - .unwrap(); + .await?; assert_eq!( result.get_rows(), &vec![Row::new(vec![TableValue::String("timestamps".to_string())])] ); + Ok(()) } -async fn system_query_cache(service: Box) { - service.exec_query("CREATE SCHEMA foo").await.unwrap(); +async fn system_query_cache(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA foo").await?; service .exec_query("CREATE TABLE foo.timestamps (t timestamp, amount int)") - .await - .unwrap(); + .await?; - service - .exec_query("SELECT * FROM foo.timestamps") - .await - .unwrap(); + service.exec_query("SELECT * FROM foo.timestamps").await?; service .exec_query("SELECT * FROM system.query_cache") - .await - .unwrap(); + .await?; + Ok(()) } -async fn metastore_rocksdb_tables(service: Box) { +async fn metastore_rocksdb_tables(service: Box) -> Result<(), CubeError> { service .exec_query("SELECT * FROM metastore.rocksdb_properties") - .await - .unwrap(); + .await?; + Ok(()) } -async fn cachestore_rocksdb_tables(service: Box) { +async fn cachestore_rocksdb_tables(service: Box) -> Result<(), CubeError> { service .exec_query("SELECT * FROM cachestore.rocksdb_properties") - .await - .unwrap(); + .await?; + Ok(()) } -async fn case_column_escaping(service: Box) { - service.exec_query("CREATE SCHEMA foo").await.unwrap(); +async fn case_column_escaping(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA foo").await?; service .exec_query("CREATE TABLE foo.timestamps (t timestamp, amount int)") - .await - .unwrap(); + .await?; service .exec_query( @@ -1598,14 +1520,13 @@ async fn case_column_escaping(service: Box) { ('2020-01-01T00:01:00.000Z', 2), \ ('2020-01-02T00:10:00.000Z', 3)", ) - .await - .unwrap(); + .await?; let result = service.exec_query( "SELECT date_trunc('day', `timestamp`.t) `day`, sum(CASE WHEN `timestamp`.t > to_timestamp('2020-01-02T00:01:00.000Z') THEN `timestamp`.amount END) \ FROM foo.timestamps `timestamp` \ WHERE `timestamp`.t >= to_timestamp('2020-01-02T00:00:00.000Z') GROUP BY 1" - ).await.unwrap(); + ).await?; assert_eq!( result.get_rows()[0], @@ -1614,15 +1535,15 @@ async fn case_column_escaping(service: Box) { TableValue::Int(3) ]) ); + Ok(()) } -async fn inner_column_escaping(service: Box) { - service.exec_query("CREATE SCHEMA foo").await.unwrap(); +async fn inner_column_escaping(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA foo").await?; service .exec_query("CREATE TABLE foo.timestamps (t timestamp, amount int)") - .await - .unwrap(); + .await?; service .exec_query( @@ -1631,8 +1552,7 @@ async fn inner_column_escaping(service: Box) { ('2020-01-01T00:01:00.000Z', 2), \ ('2020-01-02T00:10:00.000Z', 3)", ) - .await - .unwrap(); + .await?; let result = service .exec_query( @@ -1640,8 +1560,7 @@ async fn inner_column_escaping(service: Box) { FROM foo.timestamps `timestamp` \ WHERE `t` >= to_timestamp('2020-01-02T00:00:00.000Z') GROUP BY 1", ) - .await - .unwrap(); + .await?; assert_eq!( result.get_rows()[0], @@ -1650,15 +1569,15 @@ async fn inner_column_escaping(service: Box) { TableValue::Int(3) ]) ); + Ok(()) } -async fn convert_tz(service: Box) { - service.exec_query("CREATE SCHEMA foo").await.unwrap(); +async fn convert_tz(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA foo").await?; service .exec_query("CREATE TABLE foo.timestamps (t timestamp, amount int)") - .await - .unwrap(); + .await?; service .exec_query( @@ -1667,8 +1586,7 @@ async fn convert_tz(service: Box) { ('2020-01-01T00:01:00.000Z', 2), \ ('2020-01-02T00:10:00.000Z', 3)", ) - .await - .unwrap(); + .await?; let result = service .exec_query( @@ -1676,8 +1594,7 @@ async fn convert_tz(service: Box) { FROM foo.timestamps `timestamp` \ WHERE `t` >= convert_tz(to_timestamp('2020-01-02T08:00:00.000Z'), '-08:00') GROUP BY 1", ) - .await - .unwrap(); + .await?; assert_eq!( result.get_rows(), @@ -1686,15 +1603,15 @@ async fn convert_tz(service: Box) { TableValue::Int(3) ])] ); + Ok(()) } -async fn date_trunc(service: Box) { - service.exec_query("CREATE SCHEMA foo").await.unwrap(); +async fn date_trunc(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA foo").await?; service .exec_query("CREATE TABLE foo.timestamps (t timestamp)") - .await - .unwrap(); + .await?; service .exec_query( @@ -1705,16 +1622,14 @@ async fn date_trunc(service: Box) { ('2020-07-01T00:00:00.000Z'), \ ('2020-09-01T00:00:00.000Z')", ) - .await - .unwrap(); + .await?; let result = service .exec_query( "SELECT date_trunc('quarter', `t`) `quarter` \ FROM foo.timestamps `timestamp`", ) - .await - .unwrap(); + .await?; assert_eq!( result.get_rows(), @@ -1736,14 +1651,14 @@ async fn date_trunc(service: Box) { )),]) ] ); + Ok(()) } -async fn ilike(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn ilike(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.strings(t text, pat text)") - .await - .unwrap(); + .await?; service .exec_query( "INSERT INTO s.strings(t, pat) \ @@ -1758,29 +1673,25 @@ async fn ilike(service: Box) { ) .await - .unwrap(); + ?; let r = service .exec_query("SELECT t FROM s.strings WHERE t ILIKE '%aBA%' ORDER BY t") - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&["ABa", "CABA", "ZABA", "aba"])); let r = service .exec_query("SELECT t FROM s.strings WHERE t ILIKE 'aBA%' ORDER BY t") - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&["ABa", "aba"])); let r = service .exec_query("SELECT t FROM s.strings WHERE t ILIKE '%aBA' ORDER BY t") - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&["ABa", "CABA", "ZABA", "aba"])); let r = service .exec_query("SELECT t FROM s.strings WHERE t ILIKE 'aBA' ORDER BY t") - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&["ABa", "aba"])); let r = service @@ -1788,13 +1699,12 @@ async fn ilike(service: Box) { "SELECT t FROM s.strings WHERE t ILIKE CONCAT('%', 'some\\\\_underscore', '%') ORDER BY t", ) .await - .unwrap(); + ?; assert_eq!(to_rows(&r), rows(&["some_underscore"])); let r = service .exec_query("SELECT t FROM s.strings WHERE t ILIKE CONCAT('%', '(', '%') ORDER BY t") - .await - .unwrap(); + .await?; assert_eq!( to_rows(&r), rows(&["test ( special 2", "test2 -[]{}()*+?.,^$|# 2"]) @@ -1802,37 +1712,32 @@ async fn ilike(service: Box) { let r = service .exec_query("SELECT t FROM s.strings WHERE t ILIKE CONCAT('%', '?*|+', '%') ORDER BY t") - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&["111 test {)?*|+aaa"])); let r = service .exec_query( "SELECT t FROM s.strings WHERE t ILIKE CONCAT('%', '-[]{}()*+?.,^', '%') ORDER BY t", ) - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&["test2 -[]{}()*+?.,^$|# 2"])); // Compare constant string with a bunch of patterns. // Inputs are: ('aba', '%ABA'), ('ABa', '%aba%'), ('CABA', 'aba%'), ('ZABA', '%a%b%a%'), // ('ZZZ', 'zzz'), ('TTT', 'TTT'). let r = service .exec_query("SELECT pat FROM s.strings WHERE 'aba' ILIKE pat ORDER BY pat") - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&["%ABA", "%a%b%a%", "%aba%", "aba%"])); let r = service .exec_query("SELECT pat FROM s.strings WHERE 'ggggtest (fjfj)' ILIKE pat ORDER BY pat") - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&["%test (%"])); // Compare array against array. let r = service .exec_query("SELECT t, pat FROM s.strings WHERE t ILIKE pat ORDER BY t") - .await - .unwrap(); + .await?; assert_eq!( to_rows(&r), rows(&[ @@ -1853,18 +1758,17 @@ async fn ilike(service: Box) { // Check NOT ILIKE also works. let r = service .exec_query("SELECT t, pat FROM s.strings WHERE t NOT ILIKE pat ORDER BY t") - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&[("CABA", "aba%")])); + Ok(()) } -async fn coalesce(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn coalesce(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.Data (n int, v int, s text)") - .await - .unwrap(); + .await?; service .exec_query( @@ -1874,28 +1778,19 @@ async fn coalesce(service: Box) { (null, null, 'baz'),\ (null, null, null)", ) - .await - .unwrap(); + .await?; - let r = service - .exec_query("SELECT coalesce(1, 2, 3)") - .await - .unwrap(); + let r = service.exec_query("SELECT coalesce(1, 2, 3)").await?; assert_eq!(to_rows(&r), vec![vec![TableValue::Int(1)]]); - let r = service - .exec_query("SELECT coalesce(NULL, 2, 3)") - .await - .unwrap(); + let r = service.exec_query("SELECT coalesce(NULL, 2, 3)").await?; assert_eq!(to_rows(&r), vec![vec![TableValue::Int(2)]]); let r = service .exec_query("SELECT coalesce(NULL, NULL, NULL)") - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), vec![vec![TableValue::Null]]); let r = service .exec_query("SELECT coalesce(n, v) FROM s.Data ORDER BY 1") - .await - .unwrap(); + .await?; assert_eq!( to_rows(&r), vec![ @@ -1913,8 +1808,7 @@ async fn coalesce(service: Box) { let r = service .exec_query("SELECT coalesce(n+1,v+1,0) FROM s.Data ORDER BY 1") - .await - .unwrap(); + .await?; assert_eq!( to_rows(&r), vec![ @@ -1929,51 +1823,42 @@ async fn coalesce(service: Box) { .exec_query("SELECT n, coalesce() FROM s.Data ORDER BY 1") .await .unwrap_err(); + Ok(()) } -async fn count_distinct_crash(service: Box) { +async fn count_distinct_crash(service: Box) -> Result<(), CubeError> { if !service.is_migration() { - service.exec_query("CREATE SCHEMA s").await.unwrap(); - service - .exec_query("CREATE TABLE s.Data (n int)") - .await - .unwrap(); + service.exec_query("CREATE SCHEMA s").await?; + service.exec_query("CREATE TABLE s.Data (n int)").await?; let r = service .exec_query("SELECT COUNT(DISTINCT n) FROM s.Data") - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), vec![vec![TableValue::Int(0)]]); service .exec_query("INSERT INTO s.Data(n) VALUES (1), (2), (3), (3), (4), (4), (4)") - .await - .unwrap(); + .await?; } let r = service .exec_query("SELECT COUNT(DISTINCT n) FROM s.Data WHERE n > 4") - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), vec![vec![TableValue::Int(0)]]); let r = service .exec_query("SELECT COUNT(DISTINCT CASE WHEN n > 4 THEN n END) FROM s.Data") - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), vec![vec![TableValue::Int(0)]]); + Ok(()) } -async fn count_distinct_group_by_crash(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); - service - .exec_query("CREATE TABLE s.Data (n string)") - .await - .unwrap(); +async fn count_distinct_group_by_crash(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; + service.exec_query("CREATE TABLE s.Data (n string)").await?; service .exec_query("INSERT INTO s.Data (n) VALUES ('a'), ('b'), ('c'), ('b'), ('c')") - .await - .unwrap(); + .await?; let r = service .exec_query( @@ -1982,8 +1867,7 @@ async fn count_distinct_group_by_crash(service: Box) { GROUP BY 1 \ ORDER BY 1", ) - .await - .unwrap(); + .await?; assert_eq!( to_rows(&r), vec![ @@ -2004,140 +1888,131 @@ async fn count_distinct_group_by_crash(service: Box) { ], ] ); + Ok(()) } -async fn count_distinct_take_crash(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn count_distinct_take_crash(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.data(id int, n int)") - .await - .unwrap(); + .await?; service .exec_query("INSERT INTO s.data(id, n) VALUES (1, 1)") - .await - .unwrap(); + .await?; // This used to crash because `take` on empty list returned null. The implementation can easily // change with time, though, so test is not robust. let r = service .exec_query("SELECT n, COUNT(DISTINCT CASE WHEN id = 2 THEN 2 END) FROM s.data GROUP BY n") - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&[(1, 0)])); + Ok(()) } -async fn create_schema_if_not_exists(service: Box) { +async fn create_schema_if_not_exists(service: Box) -> Result<(), CubeError> { let _ = service .exec_query("CREATE SCHEMA IF NOT EXISTS Foo") - .await - .unwrap(); + .await?; let _ = service .exec_query("CREATE SCHEMA IF NOT EXISTS Foo") - .await - .unwrap(); + .await?; + Ok(()) } -async fn create_index_before_ingestion(service: Box) { - service.exec_query("CREATE SCHEMA foo").await.unwrap(); +async fn create_index_before_ingestion(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA foo").await?; service .exec_query("CREATE TABLE foo.timestamps (id int, t timestamp)") - .await - .unwrap(); + .await?; service .exec_query("CREATE INDEX by_timestamp ON foo.timestamps (`t`)") - .await - .unwrap(); + .await?; service.exec_query( "INSERT INTO foo.timestamps (id, t) VALUES (1, '2020-01-01T00:00:00.000Z'), (2, '2020-01-02T00:00:00.000Z'), (3, '2020-01-03T00:00:00.000Z')" - ).await.unwrap(); + ).await?; - let result = service.exec_query("SELECT count(*) from foo.timestamps WHERE t >= to_timestamp('2020-01-02T00:00:00.000Z')").await.unwrap(); + let result = service.exec_query("SELECT count(*) from foo.timestamps WHERE t >= to_timestamp('2020-01-02T00:00:00.000Z')").await?; assert_eq!(result.get_rows()[0], Row::new(vec![TableValue::Int(2)])); + Ok(()) } -async fn ambiguous_join_sort(service: Box) { - service.exec_query("CREATE SCHEMA foo").await.unwrap(); +async fn ambiguous_join_sort(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA foo").await?; service .exec_query("CREATE TABLE foo.sessions (t timestamp, id int)") - .await - .unwrap(); + .await?; service .exec_query("CREATE TABLE foo.page_views (session_id int, page_view_count int)") - .await - .unwrap(); + .await?; service .exec_query("CREATE INDEX by_id ON foo.sessions (id)") - .await - .unwrap(); + .await?; service.exec_query( "INSERT INTO foo.sessions (t, id) VALUES ('2020-01-01T00:00:00.000Z', 1), ('2020-01-02T00:00:00.000Z', 2), ('2020-01-03T00:00:00.000Z', 3)" - ).await.unwrap(); + ).await?; service.exec_query( "INSERT INTO foo.page_views (session_id, page_view_count) VALUES (1, 10), (2, 20), (3, 30)" - ).await.unwrap(); + ).await?; - let result = service.exec_query("SELECT sum(p.page_view_count) from foo.sessions s JOIN foo.page_views p ON s.id = p.session_id WHERE s.t >= to_timestamp('2020-01-02T00:00:00.000Z')").await.unwrap(); + let result = service.exec_query("SELECT sum(p.page_view_count) from foo.sessions s JOIN foo.page_views p ON s.id = p.session_id WHERE s.t >= to_timestamp('2020-01-02T00:00:00.000Z')").await?; assert_eq!(result.get_rows()[0], Row::new(vec![TableValue::Int(50)])); + Ok(()) } -async fn join_with_aliases(service: Box) { - service.exec_query("CREATE SCHEMA foo").await.unwrap(); +async fn join_with_aliases(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA foo").await?; service .exec_query("CREATE TABLE foo.sessions (t timestamp, id int)") - .await - .unwrap(); + .await?; service .exec_query("CREATE TABLE foo.page_views (session_id int, page_view_count int)") - .await - .unwrap(); + .await?; service .exec_query("CREATE INDEX by_id ON foo.sessions (id)") - .await - .unwrap(); + .await?; service.exec_query( "INSERT INTO foo.sessions (t, id) VALUES ('2020-01-01T00:00:00.000Z', 1), ('2020-01-02T00:00:00.000Z', 2), ('2020-01-03T00:00:00.000Z', 3)" - ).await.unwrap(); + ).await?; service.exec_query( "INSERT INTO foo.page_views (session_id, page_view_count) VALUES (1, 10), (2, 20), (3, 30)" - ).await.unwrap(); + ).await?; - let result = service.exec_query("SELECT sum(`page_view_count`) from foo.sessions `sessions` JOIN foo.page_views `page_views` ON `id` = `session_id` WHERE `t` >= to_timestamp('2020-01-02T00:00:00.000Z')").await.unwrap(); + let result = service.exec_query("SELECT sum(`page_view_count`) from foo.sessions `sessions` JOIN foo.page_views `page_views` ON `id` = `session_id` WHERE `t` >= to_timestamp('2020-01-02T00:00:00.000Z')").await?; assert_eq!(result.get_rows()[0], Row::new(vec![TableValue::Int(50)])); + Ok(()) } -async fn group_by_without_aggregates(service: Box) { - service.exec_query("CREATE SCHEMA foo").await.unwrap(); +async fn group_by_without_aggregates(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA foo").await?; service .exec_query( "CREATE TABLE foo.sessions (id int, company_id int, location_id int, t timestamp)", ) - .await - .unwrap(); + .await?; service .exec_query("CREATE INDEX by_company ON foo.sessions (company_id, location_id, id)") - .await - .unwrap(); + .await?; service.exec_query( "INSERT INTO foo.sessions (company_id, location_id, t, id) VALUES (1, 1, '2020-01-01T00:00:00.000Z', 1), (1, 2, '2020-01-02T00:00:00.000Z', 2), (2, 1, '2020-01-03T00:00:00.000Z', 3)" - ).await.unwrap(); + ).await?; - let result = service.exec_query("SELECT `sessions`.location_id, `sessions`.id FROM foo.sessions `sessions` GROUP BY 1, 2 ORDER BY 2").await.unwrap(); + let result = service.exec_query("SELECT `sessions`.location_id, `sessions`.id FROM foo.sessions `sessions` GROUP BY 1, 2 ORDER BY 2").await?; assert_eq!( result.get_rows(), @@ -2147,60 +2022,53 @@ async fn group_by_without_aggregates(service: Box) { Row::new(vec![TableValue::Int(1), TableValue::Int(3)]), ] ); + Ok(()) } -async fn create_table_with_location(service: Box) { +async fn create_table_with_location(service: Box) -> Result<(), CubeError> { let paths = { let dir = env::temp_dir(); let path_1 = dir.clone().join("foo-1.csv"); let path_2 = dir.clone().join("foo-2.csv.gz"); - let mut file = File::create(path_1.clone()).unwrap(); + let mut file = File::create(path_1.clone())?; - file.write_all("id,city,arr,t\n".as_bytes()).unwrap(); - file.write_all("1,San Francisco,\"[\"\"Foo\n\n\"\",\"\"Bar\"\",\"\"FooBar\"\"]\",\"2021-01-24 12:12:23 UTC\"\n".as_bytes()).unwrap(); - file.write_all("2,\"New York\",\"[\"\"\"\"]\",2021-01-24 19:12:23.123 UTC\n".as_bytes()) - .unwrap(); - file.write_all("3,New York,\"de Comunicación\",2021-01-25 19:12:23 UTC\n".as_bytes()) - .unwrap(); + file.write_all("id,city,arr,t\n".as_bytes())?; + file.write_all("1,San Francisco,\"[\"\"Foo\n\n\"\",\"\"Bar\"\",\"\"FooBar\"\"]\",\"2021-01-24 12:12:23 UTC\"\n".as_bytes())?; + file.write_all("2,\"New York\",\"[\"\"\"\"]\",2021-01-24 19:12:23.123 UTC\n".as_bytes())?; + file.write_all("3,New York,\"de Comunicación\",2021-01-25 19:12:23 UTC\n".as_bytes())?; let mut file = GzipEncoder::new(BufWriter::new( - tokio::fs::File::create(path_2.clone()).await.unwrap(), + tokio::fs::File::create(path_2.clone()).await?, )); - file.write_all("id,city,arr,t\n".as_bytes()).await.unwrap(); - file.write_all("1,San Francisco,\"[\"\"Foo\"\",\"\"Bar\"\",\"\"FooBar\"\"]\",\"2021-01-24 12:12:23 UTC\"\n".as_bytes()).await.unwrap(); + file.write_all("id,city,arr,t\n".as_bytes()).await?; + file.write_all("1,San Francisco,\"[\"\"Foo\"\",\"\"Bar\"\",\"\"FooBar\"\"]\",\"2021-01-24 12:12:23 UTC\"\n".as_bytes()).await?; file.write_all("2,\"New York\",\"[\"\"\"\"]\",2021-01-24 19:12:23 UTC\n".as_bytes()) - .await - .unwrap(); + .await?; file.write_all("3,New York,,2021-01-25 19:12:23 UTC\n".as_bytes()) - .await - .unwrap(); + .await?; file.write_all("4,New York,\"\",2021-01-25 19:12:23 UTC\n".as_bytes()) - .await - .unwrap(); + .await?; file.write_all("5,New York,\"\",2021-01-25 19:12:23 UTC\n".as_bytes()) - .await - .unwrap(); + .await?; file.write_all("6,New York,\\\\N,\"\\N\"\n".as_bytes()) - .await - .unwrap(); + .await?; - file.shutdown().await.unwrap(); + file.shutdown().await?; vec![path_1, path_2] }; let _ = service .exec_query("CREATE SCHEMA IF NOT EXISTS Foo") - .await - .unwrap(); + .await?; let _ = service.exec_query( &format!( "CREATE TABLE Foo.Persons (id int, city text, t timestamp, arr text) INDEX persons_city (`city`, `id`) LOCATION {}", paths.into_iter().map(|p| format!("'{}'", p.to_string_lossy())).join(",") ) - ).await.unwrap(); + ).await?; service.migration_hardcode_next_query(Err(CubeError::user("... has data ...".to_owned()))); let res = service .exec_query("CREATE INDEX by_city ON Foo.Persons (city)") @@ -2210,66 +2078,66 @@ async fn create_table_with_location(service: Box) { let result = service .exec_query("SELECT count(*) as cnt from Foo.Persons") - .await - .unwrap(); + .await?; assert_eq!(result.get_rows(), &vec![Row::new(vec![TableValue::Int(9)])]); - let result = service.exec_query("SELECT count(*) as cnt from Foo.Persons WHERE arr = '[\"Foo\",\"Bar\",\"FooBar\"]' or arr = '[\"\"]' or arr is null").await.unwrap(); + let result = service.exec_query("SELECT count(*) as cnt from Foo.Persons WHERE arr = '[\"Foo\",\"Bar\",\"FooBar\"]' or arr = '[\"\"]' or arr is null").await?; assert_eq!(result.get_rows(), &vec![Row::new(vec![TableValue::Int(7)])]); + Ok(()) } -async fn create_table_with_location_messed_order(service: Box) { +async fn create_table_with_location_messed_order( + service: Box, +) -> Result<(), CubeError> { let paths = { let dir = env::temp_dir(); let path_1 = dir.clone().join("messed-order.csv"); - let mut file = File::create(path_1.clone()).unwrap(); + let mut file = File::create(path_1.clone())?; - file.write_all("c6,c11,c10,c5,c9,c4,c2,c8,c1,c3,c7,c12\n".as_bytes()) - .unwrap(); + file.write_all("c6,c11,c10,c5,c9,c4,c2,c8,c1,c3,c7,c12\n".as_bytes())?; file.write_all( "123,0,0.5,193,0.5,2,2021-11-01,0.5,foo,42,0,2021-01-01 00:00:00\n".as_bytes(), - ) - .unwrap(); + )?; vec![path_1] }; let _ = service .exec_query("CREATE SCHEMA IF NOT EXISTS test") - .await - .unwrap(); + .await?; let _ = service.exec_query( &format!( "CREATE TABLE test.main (`c1` varchar(255), `c2` date, `c3` bigint, `c4` bigint, `c5` bigint, `c6` bigint, `c7` double, `c8` double, `c9` double, `c10` double, `c11` double, `c12` timestamp) LOCATION {}", paths.into_iter().map(|p| format!("'{}'", p.to_string_lossy())).join(",") ) - ).await.unwrap(); + ).await?; let result = service .exec_query("SELECT count(*) as cnt from test.main") - .await - .unwrap(); + .await?; assert_eq!(result.get_rows(), &vec![Row::new(vec![TableValue::Int(1)])]); + Ok(()) } -async fn create_table_with_location_invalid_digit(service: Box) { +async fn create_table_with_location_invalid_digit( + service: Box, +) -> Result<(), CubeError> { let paths = { let dir = env::temp_dir(); let path_1 = dir.clone().join("invalid_digit.csv"); - let mut file = File::create(path_1.clone()).unwrap(); + let mut file = File::create(path_1.clone())?; - file.write_all("c1,c3\n".as_bytes()).unwrap(); - file.write_all("foo,1a23\n".as_bytes()).unwrap(); + file.write_all("c1,c3\n".as_bytes())?; + file.write_all("foo,1a23\n".as_bytes())?; vec![path_1] }; let _ = service .exec_query("CREATE SCHEMA IF NOT EXISTS test") - .await - .unwrap(); + .await?; let res = service .exec_query(&format!( "CREATE TABLE test.main (`c1` text, `c3` decimal) LOCATION {}", @@ -2287,28 +2155,24 @@ async fn create_table_with_location_invalid_digit(service: Box) { "Expected invalid digit error but got {:?}", res ); + Ok(()) } -async fn create_table_with_csv(service: Box) { +async fn create_table_with_csv(service: Box) -> Result<(), CubeError> { let file = write_tmp_file(indoc! {" fruit,number apple,2 banana,3 - "}) - .unwrap(); + "})?; let path = file.path().to_string_lossy(); let _ = service .exec_query("CREATE SCHEMA IF NOT EXISTS test") - .await - .unwrap(); + .await?; let _ = service .exec_query(format!("CREATE TABLE test.table (`fruit` text, `number` int) WITH (input_format = 'csv') LOCATION '{}'", path).as_str()) .await - .unwrap(); - let result = service - .exec_query("SELECT * FROM test.table") - .await - .unwrap(); + ?; + let result = service.exec_query("SELECT * FROM test.table").await?; assert_eq!( to_rows(&result), vec![ @@ -2316,28 +2180,24 @@ async fn create_table_with_csv(service: Box) { vec![TableValue::String("banana".to_string()), TableValue::Int(3)] ] ); + Ok(()) } -async fn create_table_with_csv_and_index(service: Box) { +async fn create_table_with_csv_and_index(service: Box) -> Result<(), CubeError> { let file = write_tmp_file(indoc! {" fruit,number apple,2 banana,3 - "}) - .unwrap(); + "})?; let path = file.path().to_string_lossy(); let _ = service .exec_query("CREATE SCHEMA IF NOT EXISTS test") - .await - .unwrap(); + .await?; let _ = service .exec_query(format!("CREATE TABLE test.table (`fruit` text, `number` int) WITH (input_format = 'csv') INDEX by_number (`number`) LOCATION '{}'", path).as_str()) .await - .unwrap(); - let result = service - .exec_query("SELECT * FROM test.table") - .await - .unwrap(); + ?; + let result = service.exec_query("SELECT * FROM test.table").await?; assert_eq!( to_rows(&result), vec![ @@ -2345,27 +2205,23 @@ async fn create_table_with_csv_and_index(service: Box) { vec![TableValue::String("banana".to_string()), TableValue::Int(3)] ] ); + Ok(()) } -async fn create_table_with_csv_no_header(service: Box) { +async fn create_table_with_csv_no_header(service: Box) -> Result<(), CubeError> { let file = write_tmp_file(indoc! {" apple,2 banana,3 - "}) - .unwrap(); + "})?; let path = file.path().to_string_lossy(); let _ = service .exec_query("CREATE SCHEMA IF NOT EXISTS test") - .await - .unwrap(); + .await?; let _ = service .exec_query(format!("CREATE TABLE test.table (`fruit` text, `number` int) WITH (input_format = 'csv_no_header') LOCATION '{}'", path).as_str()) .await - .unwrap(); - let result = service - .exec_query("SELECT * FROM test.table") - .await - .unwrap(); + ?; + let result = service.exec_query("SELECT * FROM test.table").await?; assert_eq!( to_rows(&result), vec![ @@ -2373,9 +2229,12 @@ async fn create_table_with_csv_no_header(service: Box) { vec![TableValue::String("banana".to_string()), TableValue::Int(3)] ] ); + Ok(()) } -async fn create_table_with_csv_no_header_and_delimiter(service: Box) { +async fn create_table_with_csv_no_header_and_delimiter( + service: Box, +) -> Result<(), CubeError> { let file = write_tmp_file(indoc! {" \"apple\u{0001}31 a\"pple\u{0001}32 @@ -2383,21 +2242,16 @@ async fn create_table_with_csv_no_header_and_delimiter(service: Box) { +async fn create_table_with_csv_no_header_and_quotes( + service: Box, +) -> Result<(), CubeError> { let file = write_tmp_file(indoc! {" \"\"\"apple\",31 \"a\"\"pple\",32 @@ -2431,21 +2288,16 @@ async fn create_table_with_csv_no_header_and_quotes(service: Box) apple,2 banana,3 \"\"\"orange\"\" orange\",4 - "}) - .unwrap(); + "})?; let path = file.path().to_string_lossy(); let _ = service .exec_query("CREATE SCHEMA IF NOT EXISTS test") - .await - .unwrap(); + .await?; let _ = service .exec_query(format!("CREATE TABLE test.table (`fruit` text, `number` int) WITH (input_format = 'csv_no_header', delimiter = ',', disable_quoting = false) LOCATION '{}'", path).as_str()) .await - .unwrap(); - let result = service - .exec_query("SELECT * FROM test.table") - .await - .unwrap(); + ?; + let result = service.exec_query("SELECT * FROM test.table").await?; assert_eq!( to_rows(&result), vec![ @@ -2469,16 +2321,16 @@ async fn create_table_with_csv_no_header_and_quotes(service: Box) vec![TableValue::String("banana".to_string()), TableValue::Int(3)], ] ); + Ok(()) } -async fn create_table_with_url(service: Box) { +async fn create_table_with_url(service: Box) -> Result<(), CubeError> { // TODO serve this data ourselves let url = "https://data.wprdc.org/dataset/0b584c84-7e35-4f4d-a5a2-b01697470c0f/resource/e95dd941-8e47-4460-9bd8-1e51c194370b/download/bikepghpublic.csv"; service .exec_query("CREATE SCHEMA IF NOT EXISTS foo") - .await - .unwrap(); + .await?; let create_table_sql = format!("CREATE TABLE foo.bikes (`Response ID` int, `Start Date` text, `End Date` text) WITH (input_format = 'csv') LOCATION '{}'", url); let (_, query_result) = tokio::join!( service.exec_query(&create_table_sql), @@ -2490,18 +2342,16 @@ async fn create_table_with_url(service: Box) { query_result ); - let result = service - .exec_query("SELECT count(*) from foo.bikes") - .await - .unwrap(); + let result = service.exec_query("SELECT count(*) from foo.bikes").await?; assert_eq!( result.get_rows(), &vec![Row::new(vec![TableValue::Int(813)])] ); + Ok(()) } -async fn create_table_fail_and_retry(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn create_table_fail_and_retry(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service.migration_hardcode_generic_err(); service .exec_query( @@ -2511,66 +2361,53 @@ async fn create_table_fail_and_retry(service: Box) { .unwrap_err(); service .exec_query("CREATE TABLE s.Data(n int, v int) INDEX reverse (v,n)") - .await - .unwrap(); + .await?; service .exec_query("INSERT INTO s.Data(n, v) VALUES (1, -1), (2, -2)") - .await - .unwrap(); + .await?; let rows = service .exec_query("SELECT n FROM s.Data ORDER BY n") - .await - .unwrap(); + .await?; assert_eq!( to_rows(&rows), vec![vec![TableValue::Int(1)], vec![TableValue::Int(2)]] ); + Ok(()) } -async fn empty_crash(service: Box) { - let _ = service - .exec_query("CREATE SCHEMA IF NOT EXISTS s") - .await - .unwrap(); +async fn empty_crash(service: Box) -> Result<(), CubeError> { + let _ = service.exec_query("CREATE SCHEMA IF NOT EXISTS s").await?; let _ = service .exec_query("CREATE TABLE s.Table (id int, s int)") - .await - .unwrap(); + .await?; let _ = service .exec_query("INSERT INTO s.Table(id, s) VALUES (1, 10);") - .await - .unwrap(); + .await?; let r = service .exec_query("SELECT * from s.Table WHERE id = 1 AND s = 15") - .await - .unwrap(); + .await?; assert_eq!(r.get_rows(), &vec![]); let r = service .exec_query("SELECT id, sum(s) from s.Table WHERE id = 1 AND s = 15 GROUP BY 1") - .await - .unwrap(); + .await?; assert_eq!(r.get_rows(), &vec![]); + Ok(()) } -async fn bytes(service: Box) { - let _ = service - .exec_query("CREATE SCHEMA IF NOT EXISTS s") - .await - .unwrap(); +async fn bytes(service: Box) -> Result<(), CubeError> { + let _ = service.exec_query("CREATE SCHEMA IF NOT EXISTS s").await?; let _ = service .exec_query("CREATE TABLE s.Bytes (id int, data bytea)") - .await - .unwrap(); + .await?; let _ = service .exec_query( "INSERT INTO s.Bytes(id, data) VALUES (1, '01 ff 1a'), (2, X'deADbeef'), (3, 456)", ) - .await - .unwrap(); + .await?; - let result = service.exec_query("SELECT * from s.Bytes").await.unwrap(); + let result = service.exec_query("SELECT * from s.Bytes").await?; let r = result.get_rows(); assert_eq!(r.len(), 3); assert_eq!(r[0].values()[1], TableValue::Bytes(vec![0x01, 0xff, 0x1a])); @@ -2582,17 +2419,16 @@ async fn bytes(service: Box) { r[2].values()[1], TableValue::Bytes("456".as_bytes().to_vec()) ); + Ok(()) } -async fn hyperloglog(service: Box) { +async fn hyperloglog(service: Box) -> Result<(), CubeError> { let _ = service .exec_query("CREATE SCHEMA IF NOT EXISTS hll") - .await - .unwrap(); + .await?; let _ = service .exec_query("CREATE TABLE hll.sketches (id int, hll varbinary)") - .await - .unwrap(); + .await?; let sparse = "X'020C0200C02FF58941D5F0C6'"; let dense = "X'030C004020000001000000000000000000000000000000000000050020000001030100000410000000004102100000000000000051000020000020003220000003102000000000001200042000000001000200000002000000100000030040000000010040003010000000000100002000000000000000000031000020000000000000000000100000200302000000000000000000001002000000000002204000000001000001000200400000000000001000020031100000000080000000002003000000100000000100110000000000000000000010000000000000000000000020000001320205000100000612000000000004100020100000000000000000001000000002200000100000001000001020000000000020000000000000001000010300060000010000000000070100003000000000000020000000000001000010000104000000000000000000101000100000001401000000000000000000000000000100010000000000000000000000000400020000000002002300010000000000040000041000200005100000000000001000000000100000203010000000000000000000000000001006000100000000000000300100001000100254200000000000101100040000000020000010000050000000501000000000101020000000010000000003000000000200000102100000000204007000000200010000033000000000061000000000000000000000000000000000100001000001000000013000000003000000000002000000000000010001000000000000000000020010000020000000100001000000000000001000103000000000000000000020020000001000000000100001000000000000000020220200200000001001000010100000000200000000000001000002000000011000000000101200000000000000000000000000000000000000100130000000000000000000100000120000300040000000002000000000000000000000100000000070000100000000301000000401200002020000000000601030001510000000000000110100000000000000000050000000010000100000000000000000100022000100000101054010001000000000000001000001000000002000000000100000000000021000001000002000000000100000000000000000000951000000100000000000000000000000000102000200000000000000010000010000000000100002000000000000000000010000000000000010000000010000000102010000000010520100000021010100000030000000000000000100000001000000022000330051000000100000000000040003020000010000020000100000013000000102020000000050000000020010000000000000000101200C000100000001200400000000010000001000000000100010000000001000001000000100000000010000000004000000002000013102000100000000000000000000000600000010000000000000020000000000001000000000030000000000000020000000001000001000000000010000003002000003000200070001001003030010000000003000000000000020000006000000000000000011000000010000200000000000500000000000000020500000000003000000000000000004000030000100000000103000001000000000000200002004200000020000000030000000000000000000000002000100000000000000002000000000000000010020101000000005250000010000000000023010000001000000000000500002001000123100030011000020001310600000000000021000023000003000000000000000001000000000000220200000000004040000020201000000010201000000000020000400010000050000000000000000000000010000020000000000000000000000000000000000102000010000000000000000000000002010000200200000000000000000000000000100000000000000000200400000000010000000000000000000000000000000010000200300000000000100110000000000000000000000000010000030000001000000000010000010200013000000000000200000001000001200010000000010000000000001000000000000100000000410000040000001000100010000100000002001010000000000000000001000000000000010000000000000000000000002000000000001100001000000001010000000000000002200000000004000000000000100010000000000600000000100300000000000000000000010000003000000000000000000310000010100006000010001000000000000001010101000100000000000000000000000000000201000000000000000700010000030000000000000021000000000000000001020000000030000100001000000000000000000000004010100000000000000000000004000000040100000040100100001000000000300000100000000010010000300000200000000000001302000000000000000000100100000400030000001001000100100002300000004030000002010000220100000000000002000000010010000000003010500000000300000000005020102000200000000000000020100000000000000000000000011000000023000000000010000101000000000000010020040200040000020000004000020000000001000000000100000200000010000000000030100010001000000100000000000600400000000002000000000000132000000900010000000030021400000000004100006000304000000000000010000106000001300020000'"; @@ -2603,14 +2439,12 @@ async fn hyperloglog(service: Box) { s = sparse, d = dense )) - .await - .unwrap(); + .await?; // Check cardinality. let result = service .exec_query("SELECT id, cardinality(hll) as cnt from hll.sketches WHERE id < 3 ORDER BY 1") - .await - .unwrap(); + .await?; assert_eq!( to_rows(&result), vec![ @@ -2621,69 +2455,61 @@ async fn hyperloglog(service: Box) { // Check merge and cardinality. let result = service .exec_query("SELECT cardinality(merge(hll)) from hll.sketches WHERE id < 3") - .await - .unwrap(); + .await?; assert_eq!(to_rows(&result), vec![vec![TableValue::Int(657)]]); // Now merge all 4 HLLs, results should stay the same. let result = service .exec_query("SELECT cardinality(merge(hll)) from hll.sketches") - .await - .unwrap(); + .await?; assert_eq!(to_rows(&result), vec![vec![TableValue::Int(657)]]); // TODO: add format checks on insert and test invalid inputs. + Ok(()) } -async fn hyperloglog_empty_inputs(service: Box) { +async fn hyperloglog_empty_inputs(service: Box) -> Result<(), CubeError> { let _ = service .exec_query("CREATE SCHEMA IF NOT EXISTS hll") - .await - .unwrap(); + .await?; let _ = service .exec_query("CREATE TABLE hll.sketches (id int, hll varbinary)") - .await - .unwrap(); + .await?; let result = service .exec_query("SELECT cardinality(merge(hll)) from hll.sketches") - .await - .unwrap(); + .await?; assert_eq!(to_rows(&result), vec![vec![TableValue::Int(0)]]); let result = service .exec_query("SELECT merge(hll) from hll.sketches") - .await - .unwrap(); + .await?; assert_eq!(to_rows(&result), vec![vec![TableValue::Bytes(vec![])]]); + Ok(()) } -async fn hyperloglog_empty_group_by(service: Box) { +async fn hyperloglog_empty_group_by(service: Box) -> Result<(), CubeError> { let _ = service .exec_query("CREATE SCHEMA IF NOT EXISTS hll") - .await - .unwrap(); + .await?; let _ = service .exec_query("CREATE TABLE hll.sketches (id int, key int, hll varbinary)") - .await - .unwrap(); + .await?; let result = service .exec_query("SELECT key, cardinality(merge(hll)) from hll.sketches group by key") - .await - .unwrap(); + .await?; assert_eq!(to_rows(&result), Vec::>::new()); + Ok(()) } -async fn hyperloglog_inserts(service: Box) { +async fn hyperloglog_inserts(service: Box) -> Result<(), CubeError> { let _ = service .exec_query("CREATE SCHEMA IF NOT EXISTS hll") - .await - .unwrap(); + .await?; let _ = service .exec_query("CREATE TABLE hll.sketches (id int, hll hyperloglog)") - .await - .unwrap(); + .await?; service .exec_query("INSERT INTO hll.sketches(id, hll) VALUES (0, X'')") @@ -2697,16 +2523,19 @@ async fn hyperloglog_inserts(service: Box) { .exec_query("INSERT INTO hll.sketches(id, hll) VALUES (0, X'020C0200C02FF58941D5F0C6123')") .await .expect_err("should not allow invalid HLL (with extra bytes)"); + Ok(()) } -async fn create_table_with_location_and_hyperloglog(service: Box) { +async fn create_table_with_location_and_hyperloglog( + service: Box, +) -> Result<(), CubeError> { let paths = { let dir = env::temp_dir(); let path_1 = dir.clone().join("hyperloglog.csv"); - let mut file = File::create(path_1.clone()).unwrap(); + let mut file = File::create(path_1.clone())?; - file.write_all("id,hll,hll_base\n".as_bytes()).unwrap(); + file.write_all("id,hll,hll_base\n".as_bytes())?; file.write_all( format!( @@ -2714,8 +2543,7 @@ async fn create_table_with_location_and_hyperloglog(service: Box) base64::encode(vec![0x02, 0x0c, 0x01, 0x00, 0x80, 0xa5, 0x90, 0x34]) ) .as_bytes(), - ) - .unwrap(); + )?; file.write_all( format!( "1,02 0C 02 00 C0 2F F5 89 41 D5 F0 C6,{}\n", @@ -2724,15 +2552,13 @@ async fn create_table_with_location_and_hyperloglog(service: Box) ]) ) .as_bytes(), - ) - .unwrap(); + )?; vec![path_1] }; let _ = service .exec_query("CREATE SCHEMA IF NOT EXISTS hll") - .await - .unwrap(); + .await?; let _ = service .exec_query(&format!("CREATE TABLE hll.locations (id int, hll hyperloglog, hll_base hyperloglog) LOCATION {}", paths @@ -2741,12 +2567,12 @@ async fn create_table_with_location_and_hyperloglog(service: Box) .join(",") )) .await - .unwrap(); + ?; let res = service .exec_query("SELECT cardinality(merge(hll)) = cardinality(merge(hll_base)) FROM hll.locations GROUP BY id") .await - .unwrap(); + ?; assert_eq!( to_rows(&res), vec![ @@ -2754,20 +2580,22 @@ async fn create_table_with_location_and_hyperloglog(service: Box) vec![TableValue::Boolean(true)], ] ); + Ok(()) } -async fn create_table_with_location_and_hyperloglog_postgress(service: Box) { +async fn create_table_with_location_and_hyperloglog_postgress( + service: Box, +) -> Result<(), CubeError> { let paths = { let dir = env::temp_dir(); let path_1 = dir.clone().join("hyperloglog-pg.csv"); - let mut file = File::create(path_1.clone()).unwrap(); + let mut file = File::create(path_1.clone())?; - file.write_all("id,hll,hll_base\n".as_bytes()).unwrap(); + file.write_all("id,hll,hll_base\n".as_bytes())?; file.write_all( format!("0,11 8b 7f,{}\n", base64::encode(vec![0x11, 0x8b, 0x7f])).as_bytes(), - ) - .unwrap(); + )?; file.write_all( format!( "1,12 8b 7f ee 22 c4 70 69 1a 81 34,{}\n", @@ -2776,15 +2604,13 @@ async fn create_table_with_location_and_hyperloglog_postgress(service: Box) { +async fn create_table_with_location_and_hyperloglog_space_separated( + service: Box, +) -> Result<(), CubeError> { let paths = { let dir = env::temp_dir(); let path_1 = dir.clone().join("hyperloglog-ssep.csv"); - let mut file = File::create(path_1.clone()).unwrap(); + let mut file = File::create(path_1.clone())?; - file.write_all("id,hll,hll_base\n".as_bytes()).unwrap(); + file.write_all("id,hll,hll_base\n".as_bytes())?; file.write_all( format!( @@ -2823,23 +2652,20 @@ async fn create_table_with_location_and_hyperloglog_space_separated(service: Box base64::encode(vec![0x02, 0x0c, 0x01, 0x00, 0x05, 0x05, 0x7b, 0xcf]) ) .as_bytes(), - ) - .unwrap(); + )?; file.write_all( format!( "1,02 0c 01 00 15 15 7b ff,{}\n", base64::encode(vec![0x02, 0x0c, 0x01, 0x00, 0x15, 0x15, 0x7b, 0xff]) ) .as_bytes(), - ) - .unwrap(); + )?; vec![path_1] }; let _ = service .exec_query("CREATE SCHEMA IF NOT EXISTS hll") - .await - .unwrap(); + .await?; let _ = service .exec_query(&format!("CREATE TABLE hll.locations_ssep (id int, hll varbinary, hll_base varbinary) LOCATION {}", paths @@ -2848,12 +2674,12 @@ async fn create_table_with_location_and_hyperloglog_space_separated(service: Box .join(",") )) .await - .unwrap(); + ?; let res = service .exec_query("SELECT cardinality(merge(hll)) = cardinality(merge(hll_base)) FROM hll.locations_ssep GROUP BY id") .await - .unwrap(); + ?; assert_eq!( to_rows(&res), vec![ @@ -2863,26 +2689,23 @@ async fn create_table_with_location_and_hyperloglog_space_separated(service: Box ); let res = service .exec_query("SELECT hll, hll_base FROM hll.locations_ssep") - .await - .unwrap(); + .await?; for r in to_rows(&res).iter() { assert_eq!(r[0], r[1]); } println!("res {:?}", res); + Ok(()) } -async fn hyperloglog_inplace_group_by(service: Box) { +async fn hyperloglog_inplace_group_by(service: Box) -> Result<(), CubeError> { let _ = service .exec_query("CREATE SCHEMA IF NOT EXISTS hll") - .await - .unwrap(); + .await?; let _ = service .exec_query("CREATE TABLE hll.sketches1(id int, hll hyperloglog)") - .await - .unwrap(); + .await?; let _ = service .exec_query("CREATE TABLE hll.sketches2(id int, hll hyperloglog)") - .await - .unwrap(); + .await?; service .exec_query( @@ -2890,16 +2713,14 @@ async fn hyperloglog_inplace_group_by(service: Box) { VALUES (0, X'020C0200C02FF58941D5F0C6'), \ (1, X'020C0200C02FF58941D5F0C6')", ) - .await - .unwrap(); + .await?; service .exec_query( "INSERT INTO hll.sketches2(id, hll) \ VALUES (1, X'020C0200C02FF58941D5F0C6'), \ (2, X'020C0200C02FF58941D5F0C6')", ) - .await - .unwrap(); + .await?; // Case expression should handle binary results. service @@ -2908,8 +2729,7 @@ async fn hyperloglog_inplace_group_by(service: Box) { FROM hll.sketches1 \ GROUP BY 1", ) - .await - .unwrap(); + .await?; // Without the ELSE branch. service .exec_query( @@ -2917,15 +2737,14 @@ async fn hyperloglog_inplace_group_by(service: Box) { FROM hll.sketches1 \ GROUP BY 1", ) - .await - .unwrap(); + .await?; // Binary type in condition. For completeness, probably not very useful in practice. // TODO: this fails for unrelated reasons, binary support is ad-hoc at this point. // uncomment when fixed. // service.exec_query( // "SELECT id, CASE hll WHEN '' THEN NULL else hll END \ // FROM hll.sketches1", - // ).await.unwrap(); + // ).await?; // MergeSortExec uses the same code as case expression internally. let rows = service @@ -2937,8 +2756,7 @@ async fn hyperloglog_inplace_group_by(service: Box) { SELECT * FROM hll.sketches2) \ GROUP BY 1 ORDER BY 1", ) - .await - .unwrap(); + .await?; assert_eq!( to_rows(&rows), vec![ @@ -2946,47 +2764,45 @@ async fn hyperloglog_inplace_group_by(service: Box) { vec![TableValue::Int(1), TableValue::Int(2)], vec![TableValue::Int(2), TableValue::Int(2)], ] - ) + ); + Ok(()) } -async fn hyperloglog_postgres(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn hyperloglog_postgres(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.hlls(id int, hll HLL_POSTGRES)") - .await - .unwrap(); + .await?; service.exec_query("INSERT INTO s.hlls(id, hll) VALUES \ (1, X'118b7f'),\ (2, X'128b7fee22c470691a8134'),\ (3, X'138b7f04a10642078507c308e309230a420ac10c2510a2114511611363138116811848188218a119411a821ae11f0122e223a125a126632685276327a328e2296129e52b812fe23081320132c133e335a53641368236a23721374237e1382138e13a813c243e6140e341854304434148a24a034f8150c1520152e254e155a1564157e158e35ac25b265b615c615fc1620166a368226a416a626c016c816d677163728275817a637a817ac37b617c247c427d677f6180e18101826382e1846184e18541858287e1880189218a418b818bc38e018ea290a19244938295e4988198c299e29b239b419c419ce49da1a1e1a321a381a4c1aa61acc2ae01b0a1b101b142b161b443b801bd02bd61bf61c263c4a3c501c7a1caa1cb03cd03cf03cf42d123d4c3d662d744d901dd01df81e001e0a2e641e7e3edc1f0a2f1c1f203f484f5c4f763fc84fdc1fe02fea1'),\ (4, X'148b7f21083288a4320a12086719c65108c1088422884511063388232904418c8520484184862886528c65198832106328c83114e6214831108518d03208851948511884188441908119083388661842818c43190c320ce4210a50948221083084a421c8328c632104221c4120d01284e20902318ca5214641942319101294641906228483184e128c43188e308882204a538c8328903288642102220c64094631086330c832106320c46118443886329062118a230c63108a320c23204a11852419c6528c85210a318c6308c41088842086308ce7110a418864190650884210ca631064108642a1022186518c8509862109020a0a4318671144150842400e5090631a0811848320c821888120c81114a220880290622906310d0220c83090a118c433106128c221902210cc23106029044114841104409862190c43188111063104c310c6728c8618c62290441102310c23214440882438ca2110a32908548c432110329462188a43946328842114640944320884190c928c442084228863318a2190a318c6618ca3114651886618c44190c5108e2110612144319062284641908428882314862106419883310421988619ca420cc511442104633888218c4428465288651910730c81118821088218c6418c45108452106519ce410d841904218863308622086211483198c710c83104a328c620906218864118623086418c8711423094632186420c4620c41104620a441108e40882628c6311c212046428c8319021104672888428ca320c431984418c4209043084451886510c641108310c4c20c66188472146310ca71084820c621946218c8228822190e2410861904411c27288621144328c6440c6311063190813086228ca710c2218c4718865188c2114850888608864404a3194e22882310ce53088619ca31904519503188e1118c4214cb2948110c6119c2818c843108520c43188c5204821186528c871908311086214c630c4218c8418cc3298a31888210c63110a121042198622886531082098c419c4210c6210c8338c25294610944518c442104610884104424206310c8311462288873102308c2440c451082228824310440982220c4240c622084310c642850118c641148430d0128c8228c2120c221884428863208c21a0a4190a4404c21186548865204633906308ca32086211c8319ce22146520c6120803318a518c840084519461208c21908538cc428c2110844384e40906320c44014a3204e62042408c8328c632146318c812004310c41318e3208a5308a511827104a4188c51048421446090a7088631102231484104473084318c41210860906919083190652906129c4628c45310652848221443114420084500865184a618c81198c32906418c63190e320c231882728484184671888309465188a320c83208632144318c6331c642988108c61218812144328d022844021022184a31908328c6218c2328c4528cc541428190641046418c84108443146230c6419483214232184411863290a210824318c220868194631106618c43188821048230c4128c6310c0330462094241106330c42188c321043118863046438823110a041464108e3190e4209a11902439c43188631104321008090441106218c6419064294a229463594622244320cc71184510902924421908218c62308641044328ca328882111012884120ca52882428c62184442086718c4221c8211082208a321023115270086218c4218c6528ce400482310a520c43104a520c44210811884118c4310864198263942331822')" - ).await.unwrap(); + ).await?; let r = service .exec_query("SELECT id, cardinality(hll) FROM s.hlls ORDER BY id") - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&[(1, 0), (2, 1), (3, 164), (4, 9722)])); + Ok(()) } -async fn hyperloglog_snowflake(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn hyperloglog_snowflake(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.Data(id int, hll HLL_SNOWFLAKE) ") - .await - .unwrap(); + .await?; service.exec_query(r#"INSERT INTO s.Data(id, hll) VALUES (1, '{"precision": 12, "sparse": { "indices": [223,736,976,1041,1256,1563,1811,2227,2327,2434,2525,2656,2946,2974,3256,3745,3771,4066], "maxLzCounts": [1,2,1,4,2,2,3,1,1,2,4,2,1,1,2,3,2,1] }, "version": 4 - }')"#).await.unwrap(); + }')"#).await?; let r = service .exec_query("SELECT id, cardinality(hll) FROM s.Data") - .await - .unwrap(); + .await?; assert_eq!( to_rows(&r), vec![vec![TableValue::Int(1), TableValue::Int(18)]] @@ -2998,29 +2814,29 @@ async fn hyperloglog_snowflake(service: Box) { .exec_query("INSERT INTO s.Data(id, hll) VALUES(2, X'020C0200C02FF58941D5F0C6')") .await .unwrap_err(); + Ok(()) } -async fn hyperloglog_databricks(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn hyperloglog_databricks(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.hlls(id int, hll HLL_DATASKETCHES)") - .await - .unwrap(); + .await?; service.exec_query("INSERT INTO s.hlls(id, hll) VALUES \ (1, X'0201070c03000408067365047b65c3a608c39b17c29a0ac383c2b0380400000000000000000000000000000000'), \ (2, X'0201070c03000408c39b17c29a0ac383c2b03804067365047b65c3a60800000000000000000000000000000000'), \ (3, X'0301070c05000009140000000000000021c3b23905c2a1c38d490ac283c2b711071bc2a1c3961200000000000000000000000008c29bc39904497ac39908000000002bc3b2c3bb062c45670ac3adc29e24074bc298c2a6086f2c7f050000000000000000c392c295c2900dc3b3c28bc38106c38dc3884607c2b50dc3b70600000000c3b762c28207c398c393350f00000000000000001b27c2b20b00000000c29dc28a7210000000003fc3b95b0f')" - ).await.unwrap(); + ).await?; let r = service .exec_query("SELECT id, cardinality(hll) FROM s.hlls ORDER BY id") - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&[(1, 4), (2, 4), (3, 20)])); + Ok(()) } -async fn xirr(service: Box) { +async fn xirr(service: Box) -> Result<(), CubeError> { // XIRR result may differ between platforms, so we truncate the results with LEFT(_, 10). let r = service .exec_query( @@ -3039,8 +2855,7 @@ async fn xirr(service: Box) { ) AS "t" "#, ) - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&["0.37485859"])); @@ -3095,8 +2910,7 @@ async fn xirr(service: Box) { ) AS "t" "#, ) - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&["0.37485859"])); @@ -3123,8 +2937,7 @@ async fn xirr(service: Box) { ) AS "t" "#, ) - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&[()])); let r = service @@ -3136,13 +2949,13 @@ async fn xirr(service: Box) { ) AS "t" "#, ) - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&["12345.0"])); + Ok(()) } -async fn aggregate_index_hll_databricks(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn aggregate_index_hll_databricks(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query( "CREATE TABLE s.Orders(a int, b int, a_hll HLL_DATASKETCHES) @@ -3150,8 +2963,7 @@ async fn aggregate_index_hll_databricks(service: Box) { AGGREGATE INDEX aggr_index (a, b) ", ) - .await - .unwrap(); + .await?; service .exec_query( "INSERT INTO s.Orders (a, b, a_hll) VALUES \ @@ -3162,12 +2974,12 @@ async fn aggregate_index_hll_databricks(service: Box) { ", ) .await - .unwrap(); + ?; let res = service .exec_query("SELECT a, b, cardinality(merge(a_hll)) as hll FROM s.Orders GROUP BY 1, 2 ORDER BY 1, 2") .await - .unwrap(); + ?; assert_eq!( to_rows(&res), [ @@ -3179,31 +2991,29 @@ async fn aggregate_index_hll_databricks(service: Box) { let res = service .exec_query("SELECT a, cardinality(merge(a_hll)) as hll FROM s.Orders WHERE b = 20 GROUP BY 1 ORDER BY 1") .await - .unwrap(); + ?; assert_eq!(to_rows(&res), [[TableValue::Int(1), TableValue::Int(4)],]); let res = service .exec_query( "SELECT a, cardinality(merge(a_hll)) as hll FROM s.Orders GROUP BY 1 ORDER BY 1", ) - .await - .unwrap(); + .await?; assert_eq!(to_rows(&res), [[TableValue::Int(1), TableValue::Int(4)],]); + Ok(()) } -async fn physical_plan_flags(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn physical_plan_flags(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE PARTITIONED INDEX s.ind(url text, day text, category text)") - .await - .unwrap(); + .await?; service .exec_query( "CREATE TABLE s.Data(url text, day text, category text, hits int, clicks int) \ ADD TO PARTITIONED INDEX s.ind(url, day, category)", ) - .await - .unwrap(); + .await?; // (query, is_optimal) let cases = vec![ @@ -3232,7 +3042,7 @@ async fn physical_plan_flags(service: Box) { ]; for (query, expected_optimal) in cases { - let p = service.plan_query(query).await.unwrap(); + let p = service.plan_query(query).await?; let flags = PhysicalPlanFlags::with_execution_plan(p.router.as_ref()); assert_eq!( flags.is_suboptimal_query(), @@ -3241,19 +3051,18 @@ async fn physical_plan_flags(service: Box) { query ); } + Ok(()) } -async fn planning_inplace_aggregate(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn planning_inplace_aggregate(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.Data(url text, day int, hits int)") - .await - .unwrap(); + .await?; let p = service .plan_query("SELECT url, SUM(hits) FROM s.Data GROUP BY 1") - .await - .unwrap(); + .await?; let pp_opts = PPOptions { show_partitions: true, ..PPOptions::none() @@ -3276,8 +3085,7 @@ async fn planning_inplace_aggregate(service: Box) { // When there is no index, we fallback to inplace aggregates. let p = service .plan_query("SELECT day, SUM(hits) FROM s.Data GROUP BY 1") - .await - .unwrap(); + .await?; // TODO: Can we not have CoalescePartitions? We don't want. assert_eq!( pp_phys_plan_ext(p.router.as_ref(), &pp_opts), @@ -3298,15 +3106,13 @@ async fn planning_inplace_aggregate(service: Box) { service .exec_query("CREATE TABLE s.DataBool(url text, segment boolean, day int, hits int)") - .await - .unwrap(); + .await?; let p = service .plan_query( "SELECT url, day, SUM(hits) FROM s.DataBool where segment = true GROUP BY 1, 2", ) - .await - .unwrap(); + .await?; let phys_plan = pp_phys_plan_ext(p.worker.as_ref(), &pp_opts); assert_eq!( phys_plan, @@ -3322,8 +3128,7 @@ async fn planning_inplace_aggregate(service: Box) { .plan_query( "SELECT url, day, SUM(hits) FROM s.DataBool where segment = false GROUP BY 1, 2", ) - .await - .unwrap(); + .await?; let phys_plan = pp_phys_plan_ext(p.worker.as_ref(), &pp_opts); assert_eq!( phys_plan, @@ -3335,23 +3140,20 @@ async fn planning_inplace_aggregate(service: Box) { \n Sort, partitions: 1\ \n Empty, partitions: 1" ); + Ok(()) } -async fn planning_hints(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn planning_hints(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.Data(id1 int, id2 int, id3 int)") - .await - .unwrap(); + .await?; let mut show_hints = PPOptions::default(); show_hints.show_output_hints = true; // Merge produces a sort order because there is only single partition. - let p = service - .plan_query("SELECT id1, id2 FROM s.Data") - .await - .unwrap(); + let p = service.plan_query("SELECT id1, id2 FROM s.Data").await?; assert_eq!( pp_phys_plan_ext(p.worker.as_ref(), &show_hints), "Worker, sort_order: [0, 1]\ @@ -3360,10 +3162,7 @@ async fn planning_hints(service: Box) { \n Empty" ); - let p = service - .plan_query("SELECT id2, id1 FROM s.Data") - .await - .unwrap(); + let p = service.plan_query("SELECT id2, id1 FROM s.Data").await?; assert_eq!( pp_phys_plan_ext(p.worker.as_ref(), &show_hints), "Worker, sort_order: [1, 0]\ @@ -3374,10 +3173,7 @@ async fn planning_hints(service: Box) { ); // Unsorted when skips columns from sort prefix. - let p = service - .plan_query("SELECT id2, id3 FROM s.Data") - .await - .unwrap(); + let p = service.plan_query("SELECT id2, id3 FROM s.Data").await?; assert_eq!( pp_phys_plan_ext(p.worker.as_ref(), &show_hints), "CoalescePartitions\ @@ -3388,10 +3184,7 @@ async fn planning_hints(service: Box) { ); // The prefix columns are still sorted. - let p = service - .plan_query("SELECT id1, id3 FROM s.Data") - .await - .unwrap(); + let p = service.plan_query("SELECT id1, id3 FROM s.Data").await?; assert_eq!( pp_phys_plan_ext(p.worker.as_ref(), &show_hints), "Worker, sort_order: [0]\ @@ -3403,8 +3196,7 @@ async fn planning_hints(service: Box) { // Single value hints. let p = service .plan_query("SELECT id3, id2 FROM s.Data WHERE id2 = 234") - .await - .unwrap(); + .await?; assert_eq!( pp_phys_plan_ext(p.worker.as_ref(), &show_hints), "CoalescePartitions, single_vals: [1]\ @@ -3419,8 +3211,7 @@ async fn planning_hints(service: Box) { // Removing single value columns should keep the sort order of the rest. let p = service .plan_query("SELECT id3 FROM s.Data WHERE id1 = 123 AND id2 = 234") - .await - .unwrap(); + .await?; assert_eq!( pp_phys_plan_ext(p.worker.as_ref(), &show_hints), "Worker, sort_order: [0]\ @@ -3431,8 +3222,7 @@ async fn planning_hints(service: Box) { ); let p = service .plan_query("SELECT id1, id3 FROM s.Data WHERE id2 = 234") - .await - .unwrap(); + .await?; assert_eq!( pp_phys_plan_ext(p.worker.as_ref(), &show_hints), "Worker, sort_order: [0, 1]\ @@ -3441,22 +3231,21 @@ async fn planning_hints(service: Box) { \n Sort, sort_order: [0, 1, 2]\ \n Empty" ); + Ok(()) } -async fn planning_inplace_aggregate2(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn planning_inplace_aggregate2(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query( "CREATE TABLE s.Data1(allowed boolean, site_id int, url text, day timestamp, hits int)", ) - .await - .unwrap(); + .await?; service .exec_query( "CREATE TABLE s.Data2(allowed boolean, site_id int, url text, day timestamp, hits int)", ) - .await - .unwrap(); + .await?; let p = service .plan_query( @@ -3471,8 +3260,7 @@ async fn planning_inplace_aggregate2(service: Box) { ORDER BY 2 DESC NULLS LAST \ LIMIT 10", ) - .await - .unwrap(); + .await?; let mut verbose = PPOptions::default(); verbose.show_output_hints = true; @@ -3502,39 +3290,36 @@ async fn planning_inplace_aggregate2(service: Box) { \n Sort, by: [allowed@0, site_id@1, url@2, day@3, hits@4], sort_order: [0, 1, 2, 3, 4]\ \n Empty" ); + Ok(()) } -async fn partitioned_index(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn partitioned_index(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE PARTITIONED INDEX s.ind(id int, url text)") - .await - .unwrap(); + .await?; service .exec_query( "CREATE TABLE s.Data1(id int, url text, hits int) \ ADD TO PARTITIONED INDEX s.ind(id, url)", ) - .await - .unwrap(); + .await?; service .exec_query( "CREATE TABLE s.Data2(id2 int, url2 text, location text) \ ADD TO PARTITIONED INDEX s.ind(id2, url2)", ) - .await - .unwrap(); + .await?; service .exec_query( "INSERT INTO s.Data1(id, url, hits) VALUES (0, 'a', 10), (1, 'a', 20), (2, 'c', 30)", ) - .await - .unwrap(); + .await?; service .exec_query("INSERT INTO s.Data2(id2, url2, location) VALUES (0, 'a', 'Mars'), (1, 'c', 'Earth'), (2, 'c', 'Moon')") .await - .unwrap(); + ?; let r = service .exec_query( @@ -3542,46 +3327,40 @@ async fn partitioned_index(service: Box) { FROM s.Data1 `l` JOIN s.Data2 `r` ON l.id = r.id2 AND l.url = r.url2 \ ORDER BY 1, 2", ) - .await - .unwrap(); + .await?; assert_eq!( to_rows(&r), rows(&[(0, "a", 10, "Mars"), (2, "c", 30, "Moon")]) ); + Ok(()) } -async fn partitioned_index_if_not_exists(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn partitioned_index_if_not_exists(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE PARTITIONED INDEX s.ind(id int, url text)") - .await - .unwrap(); + .await?; service .exec_query("CREATE PARTITIONED INDEX s.ind(id int, url text)") .await .unwrap_err(); service .exec_query("CREATE PARTITIONED INDEX IF NOT EXISTS s.ind(id int, url text)") - .await - .unwrap(); + .await?; service .exec_query("CREATE PARTITIONED INDEX IF NOT EXISTS s.other_ind(id int, url text)") - .await - .unwrap(); + .await?; + Ok(()) } -async fn drop_partitioned_index(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn drop_partitioned_index(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE PARTITIONED INDEX s.ind(url text, some_column int)") - .await - .unwrap(); + .await?; // DROP without any data. - service - .exec_query("DROP PARTITIONED INDEX s.ind") - .await - .unwrap(); + service.exec_query("DROP PARTITIONED INDEX s.ind").await?; // Another drop fails as index does not exist. service .exec_query("DROP PARTITIONED INDEX s.ind") @@ -3590,32 +3369,28 @@ async fn drop_partitioned_index(service: Box) { // Note columns are different. service .exec_query("CREATE PARTITIONED INDEX s.ind(id int, url text)") - .await - .unwrap(); + .await?; service .exec_query( "CREATE TABLE s.Data1(id int, url text, hits int) \ ADD TO PARTITIONED INDEX s.ind(id, url)", ) - .await - .unwrap(); + .await?; service .exec_query( "CREATE TABLE s.Data2(id2 int, url2 text, location text) \ ADD TO PARTITIONED INDEX s.ind(id2, url2)", ) - .await - .unwrap(); + .await?; service .exec_query( "INSERT INTO s.Data1(id, url, hits) VALUES (0, 'a', 10), (1, 'a', 20), (2, 'c', 30)", ) - .await - .unwrap(); + .await?; service .exec_query("INSERT INTO s.Data2(id2, url2, location) VALUES (0, 'a', 'Mars'), (1, 'c', 'Earth'), (2, 'c', 'Moon')") .await - .unwrap(); + ?; let r = service .exec_query( @@ -3623,17 +3398,13 @@ async fn drop_partitioned_index(service: Box) { FROM s.Data1 `l` JOIN s.Data2 `r` ON l.id = r.id2 AND l.url = r.url2 \ ORDER BY 1, 2", ) - .await - .unwrap(); + .await?; assert_eq!( to_rows(&r), rows(&[(0, "a", 10, "Mars"), (2, "c", 30, "Moon")]) ); - service - .exec_query("DROP PARTITIONED INDEX s.ind") - .await - .unwrap(); + service.exec_query("DROP PARTITIONED INDEX s.ind").await?; service .exec_query( "CREATE TABLE s.Data3(id3 int, url3 text, location text) \ @@ -3649,24 +3420,22 @@ async fn drop_partitioned_index(service: Box) { FROM s.Data1 `l` JOIN s.Data2 `r` ON l.id = r.id2 AND l.url = r.url2 \ ORDER BY 1, 2", ) - .await - .unwrap(); + .await?; assert_eq!( to_rows(&r), rows(&[(0, "a", 10, "Mars"), (2, "c", 30, "Moon")]) ); + Ok(()) } -async fn topk_large_inputs(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn topk_large_inputs(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.Data1(url text, hits int)") - .await - .unwrap(); + .await?; service .exec_query("CREATE TABLE s.Data2(url text, hits int)") - .await - .unwrap(); + .await?; const NUM_ROWS: i64 = 5 + MIN_TOPK_STREAM_ROWS as i64; @@ -3702,7 +3471,7 @@ async fn topk_large_inputs(service: Box) { ORDER BY 2 DESC \ LIMIT 10"; - let rows = service.exec_query(query).await.unwrap().get_rows().clone(); + let rows = service.exec_query(query).await?.get_rows().clone(); assert_eq!(rows.len(), 10); for i in 0..10 { match &rows[i].values()[0] { @@ -3716,19 +3485,18 @@ async fn topk_large_inputs(service: Box) { i ); } + Ok(()) } -async fn planning_simple(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn planning_simple(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.Orders(id int, customer_id int, city text, amount int)") - .await - .unwrap(); + .await?; let p = service .plan_query("SELECT id, amount FROM s.Orders") - .await - .unwrap(); + .await?; assert_eq!( pp_phys_plan(p.router.as_ref()), "ClusterSend, partitions: [[1]]" @@ -3743,8 +3511,7 @@ async fn planning_simple(service: Box) { let p = service .plan_query("SELECT id, amount FROM s.Orders WHERE id > 10") - .await - .unwrap(); + .await?; assert_eq!( pp_phys_plan(p.router.as_ref()), "ClusterSend, partitions: [[1]]" @@ -3765,8 +3532,7 @@ async fn planning_simple(service: Box) { WHERE id > 10\ ORDER BY 2", ) - .await - .unwrap(); + .await?; assert_eq!( pp_phys_plan(p.router.as_ref()), "Sort\ @@ -3789,8 +3555,7 @@ async fn planning_simple(service: Box) { WHERE id > 10 \ LIMIT 10", ) - .await - .unwrap(); + .await?; assert_eq!( pp_phys_plan(p.router.as_ref()), "GlobalLimit, n: 10\ @@ -3812,8 +3577,7 @@ async fn planning_simple(service: Box) { FROM s.Orders \ GROUP BY 1", ) - .await - .unwrap(); + .await?; assert_eq!( pp_phys_plan(p.router.as_ref()), "InlineFinalAggregate\ @@ -3837,8 +3601,7 @@ async fn planning_simple(service: Box) { SELECT * FROM s.Orders)\ GROUP BY 1", ) - .await - .unwrap(); + .await?; assert_eq!( pp_phys_plan(p.router.as_ref()), "InlineFinalAggregate\ @@ -3858,29 +3621,26 @@ async fn planning_simple(service: Box) { \n Sort\ \n Empty" ); + Ok(()) } -async fn planning_filter_index_selection(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn planning_filter_index_selection(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.Orders(a int, b int, c int, d int, amount int)") - .await - .unwrap(); + .await?; service .exec_query("CREATE INDEX cb ON s.Orders(c, b)") - .await - .unwrap(); + .await?; service .exec_query("CREATE INDEX bcd ON s.Orders(d, b, c)") - .await - .unwrap(); + .await?; let p = service .plan_query("SELECT b, SUM(amount) FROM s.Orders WHERE c = 5 GROUP BY 1") - .await - .unwrap(); + .await?; assert_eq!( pp_phys_plan(p.router.as_ref()), "InlineFinalAggregate\ @@ -3899,8 +3659,7 @@ async fn planning_filter_index_selection(service: Box) { let p = service .plan_query("SELECT b, SUM(amount) FROM s.Orders WHERE c in (5, 6) GROUP BY 1") - .await - .unwrap(); + .await?; assert_eq!( pp_phys_plan(p.router.as_ref()), "LinearFinalAggregate\ @@ -3924,8 +3683,7 @@ async fn planning_filter_index_selection(service: Box) { .plan_query( "SELECT b, SUM(amount) FROM s.Orders WHERE c = 5 and a > 5 and a < 10 GROUP BY 1", ) - .await - .unwrap(); + .await?; assert_eq!( pp_phys_plan(p.router.as_ref()), @@ -3943,22 +3701,20 @@ async fn planning_filter_index_selection(service: Box) { \n Sort\ \n Empty" ); + Ok(()) } -async fn planning_joins(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn planning_joins(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.Orders(order_id int, customer_id int, amount int)") - .await - .unwrap(); + .await?; service .exec_query("CREATE INDEX by_customer ON s.Orders(customer_id)") - .await - .unwrap(); + .await?; service .exec_query("CREATE TABLE s.Customers(customer_id int, customer_name text)") - .await - .unwrap(); + .await?; let p = service .plan_query( @@ -3966,8 +3722,7 @@ async fn planning_joins(service: Box) { FROM s.Orders `o`\ JOIN s.Customers `c` ON o.customer_id = c.customer_id", ) - .await - .unwrap(); + .await?; assert_eq!( pp_phys_plan(p.router.as_ref()), "CoalescePartitions\ @@ -3996,8 +3751,7 @@ async fn planning_joins(service: Box) { GROUP BY 1, 2 \ ORDER BY 3 DESC", ) - .await - .unwrap(); + .await?; assert_eq!( pp_phys_plan(p.router.as_ref()), "Sort\ @@ -4022,32 +3776,28 @@ async fn planning_joins(service: Box) { \n Sort\ \n Empty" ); + Ok(()) } -async fn planning_3_table_joins(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn planning_3_table_joins(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query( "CREATE TABLE s.Orders(order_id int, customer_id int, product_id int, amount int)", ) - .await - .unwrap(); + .await?; service .exec_query("CREATE INDEX by_customer ON s.Orders(customer_id)") - .await - .unwrap(); + .await?; service .exec_query("CREATE INDEX by_product_customer ON s.Orders(product_id, customer_id)") - .await - .unwrap(); + .await?; service .exec_query("CREATE TABLE s.Customers(customer_id int, customer_name text)") - .await - .unwrap(); + .await?; service .exec_query("CREATE TABLE s.Products(product_id int, product_name text)") - .await - .unwrap(); + .await?; let p = service .plan_query( @@ -4056,8 +3806,7 @@ async fn planning_3_table_joins(service: Box) { JOIN s.Customers `c` ON o.customer_id = c.customer_id \ JOIN s.Products `p` ON o.product_id = p.product_id", ) - .await - .unwrap(); + .await?; assert_eq!( pp_phys_plan(p.router.as_ref()), "CoalescePartitions\ @@ -4092,8 +3841,7 @@ async fn planning_3_table_joins(service: Box) { JOIN s.Products `p` ON o.product_id = p.product_id \ WHERE p.product_id = 125", ) - .await - .unwrap(); + .await?; // Check filter pushdown properly mirrors the filters on joins. let mut show_filters = PPOptions::default(); @@ -4119,29 +3867,29 @@ async fn planning_3_table_joins(service: Box) { \n Sort\ \n Empty", ); + Ok(()) } -async fn planning_join_with_partitioned_index(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn planning_join_with_partitioned_index( + service: Box, +) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE PARTITIONED INDEX s.by_customer(customer_id int)") - .await - .unwrap(); + .await?; service .exec_query( "CREATE TABLE s.Orders(order_id int, customer_id int, product_id int, amount int) \ ADD TO PARTITIONED INDEX s.by_customer(customer_id)", ) - .await - .unwrap(); + .await?; service .exec_query( "CREATE TABLE s.Customers(customer_id int, customer_name text) \ ADD TO PARTITIONED INDEX s.by_customer(customer_id)", ) - .await - .unwrap(); + .await?; let p = service .plan_query( @@ -4149,8 +3897,7 @@ async fn planning_join_with_partitioned_index(service: Box) { FROM s.Orders `o`\ JOIN s.Customers `c` ON o.customer_id = c.customer_id", ) - .await - .unwrap(); + .await?; assert_eq!( pp_phys_plan(p.router.as_ref()), "CoalescePartitions\ @@ -4170,26 +3917,25 @@ async fn planning_join_with_partitioned_index(service: Box) { \n Sort\ \n Empty" ); + Ok(()) } -async fn topk_query(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn topk_query(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.Data1(url text, hits int)") - .await - .unwrap(); + .await?; service .exec_query("INSERT INTO s.Data1(url, hits) VALUES ('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('z', 100)") .await - .unwrap(); + ?; service .exec_query("CREATE TABLE s.Data2(url text, hits int)") - .await - .unwrap(); + .await?; service .exec_query("INSERT INTO s.Data2(url, hits) VALUES ('b', 50), ('c', 45), ('d', 40), ('e', 35), ('y', 80)") .await - .unwrap(); + ?; // A typical top-k query. let r = service @@ -4202,8 +3948,7 @@ async fn topk_query(service: Box) { ORDER BY 2 DESC \ LIMIT 3", ) - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&[("z", 100), ("y", 80), ("b", 52)])); // Same query, ascending order. @@ -4217,8 +3962,7 @@ async fn topk_query(service: Box) { ORDER BY 2 ASC \ LIMIT 3", ) - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&[("a", 1), ("e", 40), ("d", 44)])); // Min, descending. @@ -4232,8 +3976,7 @@ async fn topk_query(service: Box) { ORDER BY 2 DESC \ LIMIT 3", ) - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&[("z", 100), ("y", 80), ("e", 5)])); // Min, ascending. @@ -4247,8 +3990,7 @@ async fn topk_query(service: Box) { ORDER BY 2 ASC \ LIMIT 3", ) - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&[("a", 1), ("b", 2), ("c", 3)])); // Max, descending. @@ -4262,8 +4004,7 @@ async fn topk_query(service: Box) { ORDER BY 2 DESC \ LIMIT 3", ) - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&[("z", 100), ("y", 80), ("b", 50)])); // Max, ascending. @@ -4277,29 +4018,27 @@ async fn topk_query(service: Box) { ORDER BY 2 ASC \ LIMIT 3", ) - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&[("a", 1), ("e", 35), ("d", 40)])); + Ok(()) } -async fn topk_having(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn topk_having(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.Data1(url text, hits int)") - .await - .unwrap(); + .await?; service .exec_query("INSERT INTO s.Data1(url, hits) VALUES ('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('z', 100)") .await - .unwrap(); + ?; service .exec_query("CREATE TABLE s.Data2(url text, hits int)") - .await - .unwrap(); + .await?; service .exec_query("INSERT INTO s.Data2(url, hits) VALUES ('b', 50), ('c', 45), ('d', 40), ('e', 35), ('y', 80)") .await - .unwrap(); + ?; // A typical top-k query. let r = service @@ -4313,8 +4052,7 @@ async fn topk_having(service: Box) { ORDER BY 2 DESC \ LIMIT 3", ) - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&[("y", 80), ("b", 52), ("c", 48)])); let r = service @@ -4328,26 +4066,23 @@ async fn topk_having(service: Box) { ORDER BY 2 DESC \ LIMIT 3", ) - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&[("y", 80), ("c", 48), ("d", 44)])); service .exec_query("CREATE TABLE s.Data21(url text, hits int, hits_2 int)") - .await - .unwrap(); + .await?; service .exec_query("INSERT INTO s.Data21(url, hits, hits_2) VALUES ('b', 5, 2), ('d', 3, 4), ('c', 4, 1), ('e', 2, 10)") .await - .unwrap(); + ?; service .exec_query("CREATE TABLE s.Data22(url text, hits int, hits_2 int)") - .await - .unwrap(); + .await?; service .exec_query("INSERT INTO s.Data22(url, hits, hits_2) VALUES ('b', 50, 3), ('c', 45, 12), ('d', 40, 10), ('e', 35, 5)") .await - .unwrap(); + ?; let r = service .exec_query( @@ -4360,29 +4095,27 @@ async fn topk_having(service: Box) { ORDER BY 2 DESC \ LIMIT 2", ) - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&[("b", 55), ("d", 43)])); + Ok(()) } -async fn topk_decimals(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn topk_decimals(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.Data1(url text, hits decimal)") - .await - .unwrap(); + .await?; service .exec_query("INSERT INTO s.Data1(url, hits) VALUES ('a', NULL), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('z', 100)") .await - .unwrap(); + ?; service .exec_query("CREATE TABLE s.Data2(url text, hits decimal)") - .await - .unwrap(); + .await?; service .exec_query("INSERT INTO s.Data2(url, hits) VALUES ('b', 50), ('c', 45), ('d', 40), ('e', 35), ('y', 80), ('z', NULL)") .await - .unwrap(); + ?; // A typical top-k query. let r = service @@ -4395,24 +4128,22 @@ async fn topk_decimals(service: Box) { ORDER BY 2 DESC NULLS LAST \ LIMIT 3", ) - .await - .unwrap(); + .await?; assert_eq!( to_rows(&r), rows(&[("z", dec5(100)), ("y", dec5(80)), ("b", dec5(52))]) ); + Ok(()) } -async fn planning_topk_having(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn planning_topk_having(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.Data1(url text, hits int, uhits HLL_POSTGRES)") - .await - .unwrap(); + .await?; service .exec_query("CREATE TABLE s.Data2(url text, hits int, uhits HLL_POSTGRES)") - .await - .unwrap(); + .await?; let p = service .plan_query( "SELECT `url` `url`, SUM(`hits`) `hits` \ @@ -4424,8 +4155,7 @@ async fn planning_topk_having(service: Box) { ORDER BY 2 DESC \ LIMIT 3", ) - .await - .unwrap(); + .await?; let mut show_hints = PPOptions::default(); show_hints.show_filters = true; assert_eq!( @@ -4453,7 +4183,7 @@ async fn planning_topk_having(service: Box) { HAVING SUM(`hits`) > 10 AND CARDINALITY(MERGE(`uhits`)) > 5 \ ORDER BY 2 DESC \ LIMIT 3"; - let p = service.plan_query(query).await.unwrap(); + let p = service.plan_query(query).await?; let mut show_hints = PPOptions::default(); show_hints.show_filters = true; assert_eq!( @@ -4474,20 +4204,19 @@ async fn planning_topk_having(service: Box) { ); // Checking execution because the column name MERGE(Data.uhits) in the top projection in the // above assertion seems incorrect, but the column number is correct. - let result = service.exec_query(query).await.unwrap(); + let result = service.exec_query(query).await?; assert_eq!(result.len(), 0); + Ok(()) } -async fn planning_topk_hll(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn planning_topk_hll(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.Data1(url text, hits HLL_POSTGRES)") - .await - .unwrap(); + .await?; service .exec_query("CREATE TABLE s.Data2(url text, hits HLL_POSTGRES)") - .await - .unwrap(); + .await?; // A typical top-k query. let p = service .plan_query( @@ -4499,8 +4228,7 @@ async fn planning_topk_hll(service: Box) { ORDER BY 2 DESC \ LIMIT 3", ) - .await - .unwrap(); + .await?; let mut show_hints = PPOptions::default(); show_hints.show_filters = true; assert_eq!( @@ -4531,8 +4259,7 @@ async fn planning_topk_hll(service: Box) { ORDER BY 2 DESC \ LIMIT 3", ) - .await - .unwrap(); + .await?; let mut show_hints = PPOptions::default(); show_hints.show_filters = true; assert_eq!( @@ -4551,29 +4278,28 @@ async fn planning_topk_hll(service: Box) { \n Sort\ \n Empty" ); + Ok(()) } -async fn topk_hll(service: Box) { +async fn topk_hll(service: Box) -> Result<(), CubeError> { let hlls = ["X'118b7f'", "X'128b7fee22c470691a8134'", "X'138b7f04a10642078507c308e309230a420ac10c2510a2114511611363138116811848188218a119411a821ae11f0122e223a125a126632685276327a328e2296129e52b812fe23081320132c133e335a53641368236a23721374237e1382138e13a813c243e6140e341854304434148a24a034f8150c1520152e254e155a1564157e158e35ac25b265b615c615fc1620166a368226a416a626c016c816d677163728275817a637a817ac37b617c247c427d677f6180e18101826382e1846184e18541858287e1880189218a418b818bc38e018ea290a19244938295e4988198c299e29b239b419c419ce49da1a1e1a321a381a4c1aa61acc2ae01b0a1b101b142b161b443b801bd02bd61bf61c263c4a3c501c7a1caa1cb03cd03cf03cf42d123d4c3d662d744d901dd01df81e001e0a2e641e7e3edc1f0a2f1c1f203f484f5c4f763fc84fdc1fe02fea1'", "X'148b7f21083288a4320a12086719c65108c1088422884511063388232904418c8520484184862886528c65198832106328c83114e6214831108518d03208851948511884188441908119083388661842818c43190c320ce4210a50948221083084a421c8328c632104221c4120d01284e20902318ca5214641942319101294641906228483184e128c43188e308882204a538c8328903288642102220c64094631086330c832106320c46118443886329062118a230c63108a320c23204a11852419c6528c85210a318c6308c41088842086308ce7110a418864190650884210ca631064108642a1022186518c8509862109020a0a4318671144150842400e5090631a0811848320c821888120c81114a220880290622906310d0220c83090a118c433106128c221902210cc23106029044114841104409862190c43188111063104c310c6728c8618c62290441102310c23214440882438ca2110a32908548c432110329462188a43946328842114640944320884190c928c442084228863318a2190a318c6618ca3114651886618c44190c5108e2110612144319062284641908428882314862106419883310421988619ca420cc511442104633888218c4428465288651910730c81118821088218c6418c45108452106519ce410d841904218863308622086211483198c710c83104a328c620906218864118623086418c8711423094632186420c4620c41104620a441108e40882628c6311c212046428c8319021104672888428ca320c431984418c4209043084451886510c641108310c4c20c66188472146310ca71084820c621946218c8228822190e2410861904411c27288621144328c6440c6311063190813086228ca710c2218c4718865188c2114850888608864404a3194e22882310ce53088619ca31904519503188e1118c4214cb2948110c6119c2818c843108520c43188c5204821186528c871908311086214c630c4218c8418cc3298a31888210c63110a121042198622886531082098c419c4210c6210c8338c25294610944518c442104610884104424206310c8311462288873102308c2440c451082228824310440982220c4240c622084310c642850118c641148430d0128c8228c2120c221884428863208c21a0a4190a4404c21186548865204633906308ca32086211c8319ce22146520c6120803318a518c840084519461208c21908538cc428c2110844384e40906320c44014a3204e62042408c8328c632146318c812004310c41318e3208a5308a511827104a4188c51048421446090a7088631102231484104473084318c41210860906919083190652906129c4628c45310652848221443114420084500865184a618c81198c32906418c63190e320c231882728484184671888309465188a320c83208632144318c6331c642988108c61218812144328d022844021022184a31908328c6218c2328c4528cc541428190641046418c84108443146230c6419483214232184411863290a210824318c220868194631106618c43188821048230c4128c6310c0330462094241106330c42188c321043118863046438823110a041464108e3190e4209a11902439c43188631104321008090441106218c6419064294a229463594622244320cc71184510902924421908218c62308641044328ca328882111012884120ca52882428c62184442086718c4221c8211082208a321023115270086218c4218c6528ce400482310a520c43104a520c44210811884118c4310864198263942331822'"]; - service.exec_query("CREATE SCHEMA s").await.unwrap(); + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.Data1(url text, hits HLL_POSTGRES)") - .await - .unwrap(); + .await?; service .exec_query( &format!("INSERT INTO s.Data1(url, hits) VALUES ('a', {}), ('b', {}), ('c', {}), ('d', {}), ('k', {}) ", hlls[0], hlls[1], hlls[2], hlls[3], hlls[0] )) .await - .unwrap(); + ?; service .exec_query("CREATE TABLE s.Data2(url text, hits HLL_POSTGRES)") - .await - .unwrap(); + .await?; service .exec_query( &format!("INSERT INTO s.Data2(url, hits) VALUES ('b', {}), ('c', {}), ('e', {}), ('d', {}), ('h', {})", @@ -4581,7 +4307,7 @@ async fn topk_hll(service: Box) { ) ) .await - .unwrap(); + ?; // A typical top-k query. let r = service @@ -4594,8 +4320,7 @@ async fn topk_hll(service: Box) { ORDER BY 2 DESC \ LIMIT 3", ) - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&[("b", 9722), ("d", 9722), ("c", 171)])); let r = service @@ -4609,8 +4334,7 @@ async fn topk_hll(service: Box) { ORDER BY 2 DESC \ LIMIT 2", ) - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&[("c", 171), ("h", 164)])); let r = service .exec_query( @@ -4623,32 +4347,30 @@ async fn topk_hll(service: Box) { ORDER BY 2 DESC \ LIMIT 3", ) - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&[("h", 164)])); + Ok(()) } -async fn topk_hll_with_nulls(service: Box) { +async fn topk_hll_with_nulls(service: Box) -> Result<(), CubeError> { let hlls = ["X'118b7f'", "X'128b7fee22c470691a8134'", "X'138b7f04a10642078507c308e309230a420ac10c2510a2114511611363138116811848188218a119411a821ae11f0122e223a125a126632685276327a328e2296129e52b812fe23081320132c133e335a53641368236a23721374237e1382138e13a813c243e6140e341854304434148a24a034f8150c1520152e254e155a1564157e158e35ac25b265b615c615fc1620166a368226a416a626c016c816d677163728275817a637a817ac37b617c247c427d677f6180e18101826382e1846184e18541858287e1880189218a418b818bc38e018ea290a19244938295e4988198c299e29b239b419c419ce49da1a1e1a321a381a4c1aa61acc2ae01b0a1b101b142b161b443b801bd02bd61bf61c263c4a3c501c7a1caa1cb03cd03cf03cf42d123d4c3d662d744d901dd01df81e001e0a2e641e7e3edc1f0a2f1c1f203f484f5c4f763fc84fdc1fe02fea1'", "X'148b7f21083288a4320a12086719c65108c1088422884511063388232904418c8520484184862886528c65198832106328c83114e6214831108518d03208851948511884188441908119083388661842818c43190c320ce4210a50948221083084a421c8328c632104221c4120d01284e20902318ca5214641942319101294641906228483184e128c43188e308882204a538c8328903288642102220c64094631086330c832106320c46118443886329062118a230c63108a320c23204a11852419c6528c85210a318c6308c41088842086308ce7110a418864190650884210ca631064108642a1022186518c8509862109020a0a4318671144150842400e5090631a0811848320c821888120c81114a220880290622906310d0220c83090a118c433106128c221902210cc23106029044114841104409862190c43188111063104c310c6728c8618c62290441102310c23214440882438ca2110a32908548c432110329462188a43946328842114640944320884190c928c442084228863318a2190a318c6618ca3114651886618c44190c5108e2110612144319062284641908428882314862106419883310421988619ca420cc511442104633888218c4428465288651910730c81118821088218c6418c45108452106519ce410d841904218863308622086211483198c710c83104a328c620906218864118623086418c8711423094632186420c4620c41104620a441108e40882628c6311c212046428c8319021104672888428ca320c431984418c4209043084451886510c641108310c4c20c66188472146310ca71084820c621946218c8228822190e2410861904411c27288621144328c6440c6311063190813086228ca710c2218c4718865188c2114850888608864404a3194e22882310ce53088619ca31904519503188e1118c4214cb2948110c6119c2818c843108520c43188c5204821186528c871908311086214c630c4218c8418cc3298a31888210c63110a121042198622886531082098c419c4210c6210c8338c25294610944518c442104610884104424206310c8311462288873102308c2440c451082228824310440982220c4240c622084310c642850118c641148430d0128c8228c2120c221884428863208c21a0a4190a4404c21186548865204633906308ca32086211c8319ce22146520c6120803318a518c840084519461208c21908538cc428c2110844384e40906320c44014a3204e62042408c8328c632146318c812004310c41318e3208a5308a511827104a4188c51048421446090a7088631102231484104473084318c41210860906919083190652906129c4628c45310652848221443114420084500865184a618c81198c32906418c63190e320c231882728484184671888309465188a320c83208632144318c6331c642988108c61218812144328d022844021022184a31908328c6218c2328c4528cc541428190641046418c84108443146230c6419483214232184411863290a210824318c220868194631106618c43188821048230c4128c6310c0330462094241106330c42188c321043118863046438823110a041464108e3190e4209a11902439c43188631104321008090441106218c6419064294a229463594622244320cc71184510902924421908218c62308641044328ca328882111012884120ca52882428c62184442086718c4221c8211082208a321023115270086218c4218c6528ce400482310a520c43104a520c44210811884118c4310864198263942331822'"]; - service.exec_query("CREATE SCHEMA s").await.unwrap(); + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.Data1(url text, hits HLL_POSTGRES)") - .await - .unwrap(); + .await?; service .exec_query( &format!("INSERT INTO s.Data1(url, hits) VALUES ('a', {}), ('b', {}), ('c', {}), ('d', {}), ('k', {}) ", "Null", hlls[1], hlls[2], hlls[3], hlls[3] )) .await - .unwrap(); + ?; service .exec_query("CREATE TABLE s.Data2(url text, hits HLL_POSTGRES)") - .await - .unwrap(); + .await?; service .exec_query( &format!("INSERT INTO s.Data2(url, hits) VALUES ('b', {}), ('c', {}), ('e', {}), ('d', {}), ('h', {})", @@ -4656,7 +4378,7 @@ async fn topk_hll_with_nulls(service: Box) { ) ) .await - .unwrap(); + ?; // A typical top-k query. let r = service @@ -4669,37 +4391,28 @@ async fn topk_hll_with_nulls(service: Box) { ORDER BY 2 ASC \ LIMIT 3", ) - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&[("a", 0), ("e", 1), ("c", 164)])); + Ok(()) } -async fn offset(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); - service - .exec_query("CREATE TABLE s.Data1(t text)") - .await - .unwrap(); +async fn offset(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; + service.exec_query("CREATE TABLE s.Data1(t text)").await?; service .exec_query("INSERT INTO s.Data1(t) VALUES ('a'), ('b'), ('c'), ('z')") - .await - .unwrap(); - service - .exec_query("CREATE TABLE s.Data2(t text)") - .await - .unwrap(); + .await?; + service.exec_query("CREATE TABLE s.Data2(t text)").await?; service .exec_query("INSERT INTO s.Data2(t) VALUES ('f'), ('g'), ('h')") - .await - .unwrap(); + .await?; let r = service .exec_query( "SELECT t FROM (SELECT * FROM s.Data1 UNION ALL SELECT * FROM s.Data2)\ ORDER BY 1", ) - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&["a", "b", "c", "f", "g", "h", "z"])); let r = service .exec_query( @@ -4708,8 +4421,7 @@ async fn offset(service: Box) { LIMIT 3 \ OFFSET 2", ) - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&["c", "f", "g"])); let r = service @@ -4719,29 +4431,25 @@ async fn offset(service: Box) { LIMIT 3 \ OFFSET 1", ) - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&["h", "g", "f"])); + Ok(()) } -async fn having(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn having(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.Data1(id text, n int)") - .await - .unwrap(); + .await?; service .exec_query("INSERT INTO s.Data1(id, n) VALUES ('a', 1), ('b', 2), ('c', 3)") - .await - .unwrap(); + .await?; service .exec_query("CREATE TABLE s.Data2(id text, n int)") - .await - .unwrap(); + .await?; service .exec_query("INSERT INTO s.Data2(id, n) VALUES ('a', 4), ('b', 5), ('c', 6)") - .await - .unwrap(); + .await?; let r = service .exec_query( @@ -4750,8 +4458,7 @@ async fn having(service: Box) { GROUP BY 1 \ HAVING 2 <= sum(n)", ) - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&[("b", 1)])); let r = service @@ -4763,8 +4470,7 @@ async fn having(service: Box) { HAVING sum(n) <= 5 \ ORDER BY 1", ) - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&[("a", 2), ("b", 1)])); // We diverge from datafusion here, which resolve `n` in the HAVING to `sum(n)` and fail. @@ -4778,8 +4484,7 @@ async fn having(service: Box) { HAVING sum(n) > 5 \ ORDER BY 1", ) - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&[("b", 7), ("c", 9)])); // Since we do not resolve aliases, this will fail. let err = service @@ -4792,14 +4497,14 @@ async fn having(service: Box) { ) .await; assert!(err.is_err()); + Ok(()) } -async fn rolling_window_join(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn rolling_window_join(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.Data(day timestamp, name text, n int)") - .await - .unwrap(); + .await?; let raw_query = "SELECT `Series`.date_from as `series__date_from`, name as `name`, sum(`Table`.n) as n FROM (\ SELECT to_timestamp('2020-01-01T00:00:00.000') date_from, \ @@ -4826,7 +4531,7 @@ async fn rolling_window_join(service: Box) { raw_query ); - // let plan = service.plan_query(&query).await.unwrap().worker; + // let plan = service.plan_query(&query).await?.worker; // assert_eq!( // pp_phys_plan(plan.as_ref()), // "Sort\ @@ -4844,7 +4549,7 @@ async fn rolling_window_join(service: Box) { // let plan = service // .plan_query(&query_sort_subquery) // .await - // .unwrap() + // ? // .worker; // assert_eq!( // pp_phys_plan(plan.as_ref()), @@ -4869,7 +4574,7 @@ async fn rolling_window_join(service: Box) { ('2020-01-03T03:00:00.000', 'john', 11), \ ('2020-01-04T05:00:00.000', 'timmy', 5)") .await - .unwrap(); + ?; let mut jan = (1..=4) .map(|d| timestamp_from_string(&format!("2020-01-{:02}T00:00:00.000", d)).unwrap()) @@ -4878,7 +4583,7 @@ async fn rolling_window_join(service: Box) { for q in &[query.as_str(), query_sort_subquery.as_str()] { log::info!("Testing query {}", q); - let r = service.exec_query(q).await.unwrap(); + let r = service.exec_query(q).await?; assert_eq!( to_rows(&r), rows(&[ @@ -4894,14 +4599,14 @@ async fn rolling_window_join(service: Box) { ]) ); } + Ok(()) } -async fn rolling_window_query(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn rolling_window_query(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.Data(day int, name text, n int)") - .await - .unwrap(); + .await?; service .exec_query( "INSERT INTO s.Data(day, name, n) VALUES (1, 'john', 10), \ @@ -4911,8 +4616,7 @@ async fn rolling_window_query(service: Box) { (3, 'john', 11), \ (5, 'timmy', 5)", ) - .await - .unwrap(); + .await?; let r = service .exec_query( @@ -4949,7 +4653,7 @@ LIMIT 5000"#, ) .await - .unwrap(); + ?; assert_eq!( to_rows(&r), rows(&[(1, 17), (2, 17), (3, 23), (4, 23), (5, 5)]) @@ -5007,7 +4711,7 @@ LIMIT 5000"#, ) .await - .unwrap(); + ?; assert_eq!( to_rows(&r), rows(&[(1, 17), (2, 17), (3, 23), (4, 23), (5, 5)]) @@ -5048,7 +4752,7 @@ LIMIT 5000", ) .await - .unwrap(); + ?; assert_eq!( to_rows(&r), rows(&[(1, 17), (2, 23), (3, 23), (4, 5), (5, 5)]) @@ -5090,7 +4794,7 @@ LIMIT 5000", ) .await - .unwrap(); + ?; assert_eq!( to_rows(&r), rows(&[ @@ -5137,7 +4841,7 @@ LIMIT 5000", ) .await - .unwrap(); + ?; assert_eq!( to_rows(&r), rows(&[(1, 17), (2, 17), (3, 40), (4, 40), (5, 45)]), @@ -5176,7 +4880,7 @@ LIMIT 5000", ) .await - .unwrap(); + ?; assert_eq!( to_rows(&r), rows(&[(1, 45), (2, 28), (3, 28), (4, 5), (5, 5)]) @@ -5214,8 +4918,7 @@ LIMIT LIMIT 5000", ) - .await - .unwrap(); + .await?; assert_eq!( to_rows(&r), rows(&[(1, 45), (2, 45), (3, 45), (4, 45), (5, 45)]) @@ -5256,7 +4959,7 @@ LIMIT 5000", ) .await - .unwrap(); + ?; assert_eq!( to_rows(&r), rows(&[(1, 17), (2, 40), (3, 23), (4, 28), (5, 5)]) @@ -5297,7 +5000,7 @@ LIMIT 5000", ) .await - .unwrap(); + ?; assert_eq!( to_rows(&r), rows(&[ @@ -5343,7 +5046,7 @@ LIMIT 5000", ) .await - .unwrap(); + ?; assert_eq!( to_rows(&r), rows(&[ @@ -5392,7 +5095,7 @@ LIMIT 5000", ) .await - .unwrap(); + ?; assert_eq!(to_rows(&r), vec![] as Vec>); // Broader range step than input data. @@ -5431,7 +5134,7 @@ LIMIT 5000", ) .await - .unwrap(); + ?; assert_eq!(to_rows(&r), rows(&[(1, 40), (5, 5)])); // Dimension values not in the input data. @@ -5470,7 +5173,7 @@ LIMIT 5000", ) .await - .unwrap(); + ?; assert_eq!( to_rows(&r), rows(&[ @@ -5521,7 +5224,7 @@ LIMIT 5000", ) .await - .unwrap(); + ?; assert_eq!( to_rows(&r), rows(&[ @@ -5573,7 +5276,7 @@ LIMIT 5000", ) .await - .unwrap(); + ?; assert_eq!( to_rows(&r), rows(&[ @@ -5624,7 +5327,7 @@ LIMIT 5000", ) .await - .unwrap(); + ?; assert_eq!( to_rows(&r), rows(&[ @@ -5697,18 +5400,17 @@ LIMIT // .exec_query("SELECT day, ROLLING(SUM(n) RANGE 2 PRECEDING) FROM s.Data ROLLING_WINDOW DIMENSION day FROM 10 to 0 EVERY 10") // .await // .unwrap_err(); + Ok(()) } -async fn rolling_window_exprs(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn rolling_window_exprs(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.data(day int, n int)") - .await - .unwrap(); + .await?; service .exec_query("INSERT INTO s.data(day, n) VALUES(1, 10), (2, 20), (3, 30)") - .await - .unwrap(); + .await?; let r = service .exec_query( "SELECT @@ -5805,16 +5507,16 @@ LIMIT 5000", ) .await - .unwrap(); - assert_eq!(to_rows(&r), rows(&[(10, 10.), (15, 15.), (25, 25.)])) + ?; + assert_eq!(to_rows(&r), rows(&[(10, 10.), (15, 15.), (25, 25.)])); + Ok(()) } -async fn rolling_window_query_timestamps(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn rolling_window_query_timestamps(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.data(day timestamp, name string, n int)") - .await - .unwrap(); + .await?; service .exec_query( "INSERT INTO s.data(day, name, n)\ @@ -5826,8 +5528,7 @@ async fn rolling_window_query_timestamps(service: Box) { ('2021-01-03T00:00:00Z', 'john', 11), \ ('2021-01-05T00:00:00Z', 'timmy', 5)", ) - .await - .unwrap(); + .await?; let mut jan = (1..=5) .map(|d| timestamp_from_string(&format!("2021-01-{:02}T00:00:00.000Z", d)).unwrap()) @@ -5869,7 +5570,7 @@ LIMIT 5000", ) .await - .unwrap(); + ?; assert_eq!( to_rows(&r), rows(&[ @@ -5915,7 +5616,7 @@ LIMIT 5000", ) .await - .unwrap(); + ?; assert_eq!( to_rows(&r), rows(&[ @@ -5926,14 +5627,16 @@ LIMIT (jan[5], 5) ]) ); + Ok(()) } -async fn rolling_window_query_timestamps_exceeded(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn rolling_window_query_timestamps_exceeded( + service: Box, +) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.data(day int, name string, n int)") - .await - .unwrap(); + .await?; service .exec_query( "INSERT INTO s.data(day, name, n)\ @@ -5945,8 +5648,7 @@ async fn rolling_window_query_timestamps_exceeded(service: Box) { (6, 'john', 11), \ (7, 'timmy', 5)", ) - .await - .unwrap(); + .await?; let r = service .exec_query( @@ -5986,7 +5688,7 @@ LIMIT 5000", ) .await - .unwrap(); + ?; assert_eq!( to_rows(&r), rows(&[ @@ -6005,13 +5707,13 @@ LIMIT (5, Some("sara"), Some(10)) ]) ); + Ok(()) } -async fn rolling_window_extra_aggregate(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn rolling_window_extra_aggregate(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.Data(day int, name text, n int)") - .await - .unwrap(); + .await?; service .exec_query( "INSERT INTO s.Data(day, name, n) VALUES (1, 'john', 10), \ @@ -6021,8 +5723,7 @@ async fn rolling_window_extra_aggregate(service: Box) { (3, 'john', 11), \ (5, 'timmy', 5)", ) - .await - .unwrap(); + .await?; let r = service .exec_query( @@ -6078,7 +5779,7 @@ LIMIT 5000"#, ) .await - .unwrap(); + ?; assert_eq!( to_rows(&r), rows(&[ @@ -6145,7 +5846,7 @@ LIMIT 5000", ) .await - .unwrap(); + ?; assert_eq!( to_rows(&r), rows(&[ @@ -6169,7 +5870,7 @@ LIMIT // ORDER BY 1", // ) // .await - // .unwrap(); + // ?; // assert_eq!( // to_rows(&r), // rows(&[ @@ -6218,14 +5919,16 @@ LIMIT // ) // .await // .unwrap_err(); + Ok(()) } -async fn rolling_window_extra_aggregate_addon(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn rolling_window_extra_aggregate_addon( + service: Box, +) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.Data(day int, name text, n int)") - .await - .unwrap(); + .await?; service .exec_query( "INSERT INTO s.Data(day, name, n) VALUES (11, 'john', 10), \ @@ -6235,8 +5938,7 @@ async fn rolling_window_extra_aggregate_addon(service: Box) { (13, 'john', 11), \ (15, 'timmy', 5)", ) - .await - .unwrap(); + .await?; let r = service .exec_query( @@ -6292,7 +5994,7 @@ LIMIT 5000", ) .await - .unwrap(); + ?; assert_eq!( to_rows(&r), rows(&[ @@ -6305,14 +6007,16 @@ LIMIT (15, Some(5), Some(5)) ]) ); + Ok(()) } -async fn rolling_window_extra_aggregate_timestamps(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn rolling_window_extra_aggregate_timestamps( + service: Box, +) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.data(day timestamp, name string, n int)") - .await - .unwrap(); + .await?; service .exec_query( "INSERT INTO s.data(day, name, n)\ @@ -6324,8 +6028,7 @@ async fn rolling_window_extra_aggregate_timestamps(service: Box) ('2021-01-03T00:00:00Z', 'john', 11), \ ('2021-01-05T00:00:00Z', 'timmy', 5)", ) - .await - .unwrap(); + .await?; let mut jan = (1..=5) .map(|d| timestamp_from_string(&format!("2021-01-{:02}T00:00:00.000Z", d)).unwrap()) @@ -6386,7 +6089,7 @@ LIMIT 5000", ) .await - .unwrap(); + ?; assert_eq!( to_rows(&r), rows(&[ @@ -6397,14 +6100,14 @@ LIMIT (jan[5], 5, Some(5)) ]) ); + Ok(()) } -async fn rolling_window_one_week_interval(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn rolling_window_one_week_interval(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.data(day timestamp, name string, n int)") - .await - .unwrap(); + .await?; service .exec_query( "INSERT INTO s.data(day, name, n)\ @@ -6416,8 +6119,7 @@ async fn rolling_window_one_week_interval(service: Box) { ('2021-01-03T00:00:00Z', 'john', 11), \ ('2021-01-05T00:00:00Z', 'timmy', 5)", ) - .await - .unwrap(); + .await?; let mut jan = (1..=11) .map(|d| timestamp_from_string(&format!("2021-01-{:02}T00:00:00.000Z", d)).unwrap()) @@ -6479,20 +6181,20 @@ LIMIT 5000", ) .await - .unwrap(); + ?; println!("{:?}", to_rows(&r)); assert_eq!( to_rows(&r), rows(&[(jan[4], 40, Some(5)), (jan[11], 45, None),]) ); + Ok(()) } -async fn rolling_window_one_quarter_interval(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn rolling_window_one_quarter_interval(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.data(day timestamp, name string, n int)") - .await - .unwrap(); + .await?; service .exec_query( "INSERT INTO s.data(day, name, n)\ @@ -6505,8 +6207,7 @@ async fn rolling_window_one_quarter_interval(service: Box) { ('2021-01-05T00:00:00Z', 'timmy', 5), \ ('2021-04-01T00:00:00Z', 'ovr', 5)", ) - .await - .unwrap(); + .await?; let r = service .exec_query( @@ -6563,7 +6264,7 @@ LIMIT 5000", ) .await - .unwrap(); + ?; assert_eq!( to_rows(&r), rows(&[ @@ -6575,19 +6276,18 @@ LIMIT (TimestampValue::new(1625097600000000000), 50, None), ]) ); + Ok(()) } -async fn rolling_window_offsets(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn rolling_window_offsets(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.data(day int, n int)") - .await - .unwrap(); + .await?; service .exec_query("INSERT INTO s.data(day, n) VALUES (1, 1), (2, 2), (3, 3), (5, 5), (9, 9)") - .await - .unwrap(); + .await?; let r = service .exec_query( "SELECT @@ -6622,7 +6322,7 @@ LIMIT 5000", ) .await - .unwrap(); + ?; assert_eq!( to_rows(&r), rows(&[(0, 1), (2, 6), (4, 11), (6, 11), (8, 20), (10, 20)]) @@ -6662,7 +6362,7 @@ LIMIT 5000", ) .await - .unwrap(); + ?; assert_eq!( to_rows(&r), rows(&[ @@ -6674,16 +6374,16 @@ LIMIT (10, None) ]) ); + Ok(()) } -async fn rolling_window_filtered(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn rolling_window_filtered(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query( "CREATE TABLE s.data(category text, day timestamp, count int, claimed_count int)", ) - .await - .unwrap(); + .await?; service .exec_query( @@ -6695,8 +6395,7 @@ async fn rolling_window_filtered(service: Box) { ('starkex', '2023-12-05T00:00:00.000Z', 0, 0), \ ('starkex', '2023-12-07T00:00:00.000Z', 1, 1)", ) - .await - .unwrap(); + .await?; let r = service .exec_query( @@ -6769,7 +6468,7 @@ LIMIT "#, ) .await - .unwrap(); + ?; let days = (4..=10) .map(|d| timestamp_from_string(&format!("2023-12-{:02}T00:00:00.000Z", d)).unwrap()) .collect_vec(); @@ -6785,27 +6484,24 @@ LIMIT (days[6], Some(3), None), ]) ); + Ok(()) } -async fn decimal_index(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn decimal_index(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.Data(x decimal, y decimal)") - .await - .unwrap(); + .await?; service .exec_query("CREATE INDEX reverse on s.Data(y, x)") - .await - .unwrap(); + .await?; service .exec_query("INSERT INTO s.Data(x,y) VALUES (1, 2), (2, 3), (3, 4)") - .await - .unwrap(); + .await?; let r = service .exec_query("SELECT * FROM s.Data ORDER BY x") - .await - .unwrap(); + .await?; assert_eq!( to_rows(&r), @@ -6814,31 +6510,28 @@ async fn decimal_index(service: Box) { let r = service .exec_query("SELECT * FROM s.Data ORDER BY y DESC") - .await - .unwrap(); + .await?; assert_eq!( to_rows(&r), rows(&[(dec5(3), dec5(4)), (dec5(2), dec5(3)), (dec5(1), dec5(2))]) ); + Ok(()) } -async fn decimal_order(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn decimal_order(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.data(i decimal, j decimal)") - .await - .unwrap(); + .await?; service .exec_query( "INSERT INTO s.data(i, j) VALUES (1.0, -1.0), (2.0, 0.5), (0.5, 1.0), (100, -25.5)", ) - .await - .unwrap(); + .await?; let r = service .exec_query("SELECT i FROM s.data ORDER BY 1 DESC") - .await - .unwrap(); + .await?; assert_eq!( to_rows(&r), rows(&[dec5(100), dec5(2), dec5(1), dec5f1(0, 5)]) @@ -6847,8 +6540,7 @@ async fn decimal_order(service: Box) { // Two and more columns use a different code path, so test these too. let r = service .exec_query("SELECT i, j FROM s.data ORDER BY 2, 1") - .await - .unwrap(); + .await?; assert_eq!( to_rows(&r), rows(&[ @@ -6858,140 +6550,130 @@ async fn decimal_order(service: Box) { (dec5f1(0, 5), dec5(1)) ]) ); + Ok(()) } -async fn float_index(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn float_index(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.Data(x float, y float)") - .await - .unwrap(); + .await?; service .exec_query("CREATE INDEX reverse on s.Data(y, x)") - .await - .unwrap(); + .await?; service .exec_query("INSERT INTO s.Data(x,y) VALUES (1, 2), (2, 3), (3, 4)") - .await - .unwrap(); + .await?; let r = service .exec_query("SELECT * FROM s.Data ORDER BY x") - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&[(1., 2.), (2., 3.), (3., 4.)])); let r = service .exec_query("SELECT * FROM s.Data ORDER BY y DESC") - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&[(3., 4.), (2., 3.), (1., 2.)])); + Ok(()) } /// Ensure DataFusion code consistently uses IEEE754 total order for comparing floats. -async fn float_order(s: Box) { - s.exec_query("CREATE SCHEMA s").await.unwrap(); - s.exec_query("CREATE TABLE s.data(f float, i int)") - .await - .unwrap(); +async fn float_order(s: Box) -> Result<(), CubeError> { + s.exec_query("CREATE SCHEMA s").await?; + s.exec_query("CREATE TABLE s.data(f float, i int)").await?; s.exec_query("INSERT INTO s.data(f, i) VALUES (0., -1), (-0., 1), (-0., 2), (0., -2)") - .await - .unwrap(); + .await?; // Sorting one and multiple columns use different code paths in DataFusion. Test both. - let r = s - .exec_query("SELECT f FROM s.data ORDER BY f") - .await - .unwrap(); + let r = s.exec_query("SELECT f FROM s.data ORDER BY f").await?; assert_eq!(to_rows(&r), rows(&[-0., -0., 0., 0.])); let r = s .exec_query("SELECT f, i FROM s.data ORDER BY f, i") - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&[(-0., 1), (-0., 2), (0., -2), (0., -1)])); // DataFusion compares grouping keys with a separate code path. let _r = s .exec_query("SELECT f, min(i), max(i) FROM s.data GROUP BY f ORDER BY f") - .await - .unwrap(); + .await?; //FIXME it should be fixed later for InlineAggregate assert_eq!(to_rows(&r), rows(&[(-0., 1, 2), (0., -2, -1)])); + Ok(()) } -async fn date_add(service: Box) { +async fn date_add(service: Box) -> Result<(), CubeError> { let check_fun = |name, t, i, expected| { - let expected = timestamp_from_string(expected).unwrap(); let service = &service; async move { + let expected = timestamp_from_string(expected)?; let actual = service .exec_query(&format!( "SELECT {}(CAST('{}' as TIMESTAMP), INTERVAL '{}')", name, t, i )) - .await - .unwrap(); + .await?; assert_eq!(to_rows(&actual), rows(&[expected])); + Ok::<_, CubeError>(()) } }; let check_adds_to = |t, i, expected| check_fun("DATE_ADD", t, i, expected); let check_subs_to = |t, i, expected| check_fun("DATE_SUB", t, i, expected); - check_adds_to("2021-01-01T00:00:00Z", "1 second", "2021-01-01T00:00:01Z").await; - check_adds_to("2021-01-01T00:00:00Z", "1 minute", "2021-01-01T00:01:00Z").await; - check_adds_to("2021-01-01T00:00:00Z", "1 hour", "2021-01-01T01:00:00Z").await; - check_adds_to("2021-01-01T00:00:00Z", "1 day", "2021-01-02T00:00:00Z").await; + check_adds_to("2021-01-01T00:00:00Z", "1 second", "2021-01-01T00:00:01Z").await?; + check_adds_to("2021-01-01T00:00:00Z", "1 minute", "2021-01-01T00:01:00Z").await?; + check_adds_to("2021-01-01T00:00:00Z", "1 hour", "2021-01-01T01:00:00Z").await?; + check_adds_to("2021-01-01T00:00:00Z", "1 day", "2021-01-02T00:00:00Z").await?; check_adds_to( "2021-01-01T00:00:00Z", "1 day 1 hour 1 minute 1 second", "2021-01-02T01:01:01Z", ) - .await; + .await?; check_subs_to( "2021-01-02T01:01:01Z", "1 day 1 hour 1 minute 1 second", "2021-01-01T00:00:00Z", ) - .await; + .await?; - check_adds_to("2021-01-01T00:00:00Z", "1 month", "2021-02-01T00:00:00Z").await; + check_adds_to("2021-01-01T00:00:00Z", "1 month", "2021-02-01T00:00:00Z").await?; - check_adds_to("2021-01-01T00:00:00Z", "1 year", "2022-01-01T00:00:00Z").await; - check_subs_to("2022-01-01T00:00:00Z", "1 year", "2021-01-01T00:00:00Z").await; + check_adds_to("2021-01-01T00:00:00Z", "1 year", "2022-01-01T00:00:00Z").await?; + check_subs_to("2022-01-01T00:00:00Z", "1 year", "2021-01-01T00:00:00Z").await?; - check_adds_to("2021-01-01T00:00:00Z", "13 month", "2022-02-01T00:00:00Z").await; - check_subs_to("2022-02-01T00:00:00Z", "13 month", "2021-01-01T00:00:00Z").await; + check_adds_to("2021-01-01T00:00:00Z", "13 month", "2022-02-01T00:00:00Z").await?; + check_subs_to("2022-02-01T00:00:00Z", "13 month", "2021-01-01T00:00:00Z").await?; - check_adds_to("2021-01-01T23:59:00Z", "1 minute", "2021-01-02T00:00:00Z").await; - check_subs_to("2021-01-02T00:00:00Z", "1 minute", "2021-01-01T23:59:00Z").await; + check_adds_to("2021-01-01T23:59:00Z", "1 minute", "2021-01-02T00:00:00Z").await?; + check_subs_to("2021-01-02T00:00:00Z", "1 minute", "2021-01-01T23:59:00Z").await?; - check_adds_to("2021-12-01T00:00:00Z", "1 month", "2022-01-01T00:00:00Z").await; - check_subs_to("2022-01-01T00:00:00Z", "1 month", "2021-12-01T00:00:00Z").await; + check_adds_to("2021-12-01T00:00:00Z", "1 month", "2022-01-01T00:00:00Z").await?; + check_subs_to("2022-01-01T00:00:00Z", "1 month", "2021-12-01T00:00:00Z").await?; - check_adds_to("2021-12-31T00:00:00Z", "1 day", "2022-01-01T00:00:00Z").await; - check_subs_to("2022-01-01T00:00:00Z", "1 day", "2021-12-31T00:00:00Z").await; + check_adds_to("2021-12-31T00:00:00Z", "1 day", "2022-01-01T00:00:00Z").await?; + check_subs_to("2022-01-01T00:00:00Z", "1 day", "2021-12-31T00:00:00Z").await?; // Feb 29 on leap and non-leap years. - check_adds_to("2020-02-29T00:00:00Z", "1 day", "2020-03-01T00:00:00Z").await; - check_subs_to("2020-03-01T00:00:00Z", "1 day", "2020-02-29T00:00:00Z").await; + check_adds_to("2020-02-29T00:00:00Z", "1 day", "2020-03-01T00:00:00Z").await?; + check_subs_to("2020-03-01T00:00:00Z", "1 day", "2020-02-29T00:00:00Z").await?; - check_adds_to("2020-02-28T00:00:00Z", "1 day", "2020-02-29T00:00:00Z").await; - check_subs_to("2020-02-29T00:00:00Z", "1 day", "2020-02-28T00:00:00Z").await; + check_adds_to("2020-02-28T00:00:00Z", "1 day", "2020-02-29T00:00:00Z").await?; + check_subs_to("2020-02-29T00:00:00Z", "1 day", "2020-02-28T00:00:00Z").await?; - check_adds_to("2021-02-28T00:00:00Z", "1 day", "2021-03-01T00:00:00Z").await; - check_subs_to("2021-03-01T00:00:00Z", "1 day", "2021-02-28T00:00:00Z").await; + check_adds_to("2021-02-28T00:00:00Z", "1 day", "2021-03-01T00:00:00Z").await?; + check_subs_to("2021-03-01T00:00:00Z", "1 day", "2021-02-28T00:00:00Z").await?; - check_adds_to("2020-02-29T00:00:00Z", "1 year", "2021-02-28T00:00:00Z").await; - check_subs_to("2020-02-29T00:00:00Z", "1 year", "2019-02-28T00:00:00Z").await; + check_adds_to("2020-02-29T00:00:00Z", "1 year", "2021-02-28T00:00:00Z").await?; + check_subs_to("2020-02-29T00:00:00Z", "1 year", "2019-02-28T00:00:00Z").await?; - check_adds_to("2020-01-30T00:00:00Z", "1 month", "2020-02-29T00:00:00Z").await; - check_subs_to("2020-03-30T00:00:00Z", "1 month", "2020-02-29T00:00:00Z").await; + check_adds_to("2020-01-30T00:00:00Z", "1 month", "2020-02-29T00:00:00Z").await?; + check_subs_to("2020-03-30T00:00:00Z", "1 month", "2020-02-29T00:00:00Z").await?; - check_adds_to("2020-01-29T00:00:00Z", "1 month", "2020-02-29T00:00:00Z").await; - check_subs_to("2020-03-29T00:00:00Z", "1 month", "2020-02-29T00:00:00Z").await; + check_adds_to("2020-01-29T00:00:00Z", "1 month", "2020-02-29T00:00:00Z").await?; + check_subs_to("2020-03-29T00:00:00Z", "1 month", "2020-02-29T00:00:00Z").await?; - check_adds_to("2021-01-29T00:00:00Z", "1 month", "2021-02-28T00:00:00Z").await; - check_subs_to("2021-03-29T00:00:00Z", "1 month", "2021-02-28T00:00:00Z").await; + check_adds_to("2021-01-29T00:00:00Z", "1 month", "2021-02-28T00:00:00Z").await?; + check_subs_to("2021-03-29T00:00:00Z", "1 month", "2021-02-28T00:00:00Z").await?; // Nulls. let r = service @@ -6999,8 +6681,7 @@ async fn date_add(service: Box) { "SELECT date_add(CAST(NULL as timestamp), INTERVAL '1 month'), \ date_sub(CAST(NULL as timestamp), INTERVAL '3 month')", ) - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&[(NULL, NULL)])); // Invalid types passed to date_add. @@ -7025,38 +6706,35 @@ async fn date_add(service: Box) { service.exec_query("SELECT date_add(1)").await.unwrap_err(); // Must work on columnar data. - service.exec_query("CREATE SCHEMA s").await.unwrap(); + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.data(t timestamp)") - .await - .unwrap(); + .await?; service .exec_query( "INSERT INTO s.data(t) VALUES ('2020-01-01T00:00:00Z'), ('2020-02-01T00:00:00Z'), (NULL)", ) .await - .unwrap(); + ?; let r = service .exec_query("SELECT date_add(t, INTERVAL '1 year') FROM s.data ORDER BY 1") - .await - .unwrap(); + .await?; assert_eq!( to_rows(&r), rows(&[ - Some(timestamp_from_string("2021-01-01T00:00:00Z").unwrap()), - Some(timestamp_from_string("2021-02-01T00:00:00Z").unwrap()), + Some(timestamp_from_string("2021-01-01T00:00:00Z")?), + Some(timestamp_from_string("2021-02-01T00:00:00Z")?), None, ]), ); let r = service .exec_query("SELECT date_add(t, INTERVAL '1 hour') FROM s.data ORDER BY 1") - .await - .unwrap(); + .await?; assert_eq!( to_rows(&r), rows(&[ - Some(timestamp_from_string("2020-01-01T01:00:00Z").unwrap()), - Some(timestamp_from_string("2020-02-01T01:00:00Z").unwrap()), + Some(timestamp_from_string("2020-01-01T01:00:00Z")?), + Some(timestamp_from_string("2020-02-01T01:00:00Z")?), None, ]), ); @@ -7064,8 +6742,7 @@ async fn date_add(service: Box) { // Check we tolerate NOW(), perhaps with +00:00 time zone. let r = service .exec_query("SELECT NOW(), date_add(NOW(), INTERVAL '1 day')") - .await - .unwrap(); + .await?; let rows = to_rows(&r); assert_eq!(1, rows.len()); assert_eq!(2, rows[0].len()); @@ -7078,21 +6755,22 @@ async fn date_add(service: Box) { } _ => panic!("row has wrong types: {:?}", rows[0]), } + Ok(()) } -async fn date_bin(service: Box) { +async fn date_bin(service: Box) -> Result<(), CubeError> { let check_fn = |interval, source, origin, expected| { - let expected = timestamp_from_string(expected).unwrap(); let service = &service; async move { + let expected = timestamp_from_string(expected)?; let actual = service .exec_query(&format!( "SELECT DATE_BIN(INTERVAL '{}', CAST('{}' as TIMESTAMP), CAST('{}' as TIMESTAMP))", interval, source, origin )) - .await - .unwrap(); + .await?; assert_eq!(to_rows(&actual), rows(&[expected])); + Ok::<_, CubeError>(()) } }; @@ -7103,91 +6781,91 @@ async fn date_bin(service: Box) { "2024-01-01T01:00:00Z", "2024-01-01T01:00:00Z", ) - .await; + .await?; check_fn( "1 month", "2023-11-21T01:00:00Z", "2024-01-01T01:00:00Z", "2023-11-01T01:00:00Z", ) - .await; + .await?; check_fn( "1 month", "2024-02-21T01:00:00Z", "2024-01-01T01:00:00Z", "2024-02-01T01:00:00Z", ) - .await; + .await?; check_fn( "2 month", "2024-04-25T01:00:00Z", "2024-01-20T01:00:00Z", "2024-03-20T01:00:00Z", ) - .await; + .await?; check_fn( "2 month", "2024-04-15T01:00:00Z", "2024-01-20T01:00:00Z", "2024-03-20T01:00:00Z", ) - .await; + .await?; check_fn( "2 month", "2024-05-25T01:00:00Z", "2024-01-20T01:00:00Z", "2024-05-20T01:00:00Z", ) - .await; + .await?; check_fn( "2 month", "2024-05-15T01:00:00Z", "2024-01-20T01:00:00Z", "2024-03-20T01:00:00Z", ) - .await; + .await?; check_fn( "2 month", "2023-11-25T01:00:00Z", "2024-01-20T01:00:00Z", "2023-11-20T01:00:00Z", ) - .await; + .await?; check_fn( "2 month", "2023-11-15T01:00:00Z", "2024-01-20T01:00:00Z", "2023-09-20T01:00:00Z", ) - .await; + .await?; check_fn( "10 day", "2024-01-25T01:00:00Z", "2024-01-01T01:00:00Z", "2024-01-21T01:00:00Z", ) - .await; + .await?; check_fn( "10 day 2 hour 5 minute 10 second", "2024-01-15T01:00:00Z", "2024-01-01T01:00:00Z", "2024-01-11T03:05:10.000Z", ) - .await; + .await?; check_fn( "10 day 2 hour 5 minute 10 second", "2024-01-30T01:00:00Z", "2024-01-01T01:00:00Z", "2024-01-21T05:10:20.000Z", ) - .await; + .await?; check_fn( "10 day 2 hour 5 minute 10 second", "2023-12-30T01:00:00Z", "2024-01-01T01:00:00Z", "2023-12-21T22:54:50.000Z", ) - .await; + .await?; // Nulls let r = service @@ -7195,7 +6873,7 @@ async fn date_bin(service: Box) { "SELECT DATE_BIN(INTERVAL '1 month', CAST(NULL as timestamp), CAST('2023-12-30T01:00:00Z' AS timestamp))", ) .await - .unwrap(); + ?; assert_eq!(to_rows(&r), rows(&[(NULL)])); // Invalid number of args @@ -7228,51 +6906,47 @@ async fn date_bin(service: Box) { .unwrap_err(); // Columnar data - service.exec_query("CREATE SCHEMA s").await.unwrap(); + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.data(t timestamp)") - .await - .unwrap(); + .await?; service .exec_query( "INSERT INTO s.data(t) VALUES ('2024-01-21T01:00:00Z'), ('2023-11-21T01:00:00Z'), ('2024-02-21T01:00:00Z'), (NULL)", ) .await - .unwrap(); + ?; let r = service .exec_query("SELECT DATE_BIN(INTERVAL '1 month', t, CAST('2024-01-01T01:00:00Z' AS timestamp)) FROM s.data ORDER BY 1") .await - .unwrap(); + ?; assert_eq!( to_rows(&r), rows(&[ - Some(timestamp_from_string("2023-11-01T01:00:00Z").unwrap()), - Some(timestamp_from_string("2024-01-01T01:00:00Z").unwrap()), - Some(timestamp_from_string("2024-02-01T01:00:00Z").unwrap()), + Some(timestamp_from_string("2023-11-01T01:00:00Z")?), + Some(timestamp_from_string("2024-01-01T01:00:00Z")?), + Some(timestamp_from_string("2024-02-01T01:00:00Z")?), None, ]), ); + Ok(()) } -async fn unsorted_merge_assertion(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn unsorted_merge_assertion(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.Data1(x int, y int)") - .await - .unwrap(); + .await?; service .exec_query("INSERT INTO s.Data1(x,y) VALUES (1, 4), (2, 3), (3, 2)") - .await - .unwrap(); + .await?; service .exec_query("CREATE TABLE s.Data2(x int, y int)") - .await - .unwrap(); + .await?; service .exec_query("INSERT INTO s.Data2(x,y) VALUES (1, 4), (2, 3), (3, 2)") - .await - .unwrap(); + .await?; let r = service .exec_query( @@ -7282,17 +6956,16 @@ async fn unsorted_merge_assertion(service: Box) { GROUP BY y, x \ ORDER BY y, x", ) - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&[(3, 2, 2), (2, 3, 2), (1, 4, 2)])); + Ok(()) } -async fn unsorted_data_timestamps(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn unsorted_data_timestamps(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.data(t timestamp, n string)") - .await - .unwrap(); + .await?; service .exec_query( "INSERT INTO s.data(t, n) VALUES \ @@ -7300,15 +6973,14 @@ async fn unsorted_data_timestamps(service: Box) { ('2020-01-01T00:00:00.000000001Z', 'b'), \ ('2020-01-01T00:00:00.000000002Z', 'c')", ) - .await - .unwrap(); + .await?; // CubeStore currently truncs timestamps to millisecond precision. // This checks we sort trunced precisions on inserts. We rely on implementation details of // CubeStore here. - let r = service.exec_query("SELECT t, n FROM s.data").await.unwrap(); + let r = service.exec_query("SELECT t, n FROM s.data").await?; - let t = timestamp_from_string("2020-01-01T00:00:00Z").unwrap(); + let t = timestamp_from_string("2020-01-01T00:00:00Z")?; assert_eq!(to_rows(&r), rows(&[(t, "a"), (t, "b"), (t, "c")])); // This ends up using MergeSortExec, make sure we see no assertions. @@ -7318,14 +6990,14 @@ async fn unsorted_data_timestamps(service: Box) { GROUP BY 1, 2 \ ORDER BY 1, 2", ) - .await - .unwrap(); + .await?; assert_eq!(to_rows(&r), rows(&[(t, "a"), (t, "b"), (t, "c")])); + Ok(()) } -async fn now(service: Box) { +async fn now(service: Box) -> Result<(), CubeError> { // This is no longer a UDF, so we're just testing DataFusion. - let r = service.exec_query("SELECT now()").await.unwrap(); + let r = service.exec_query("SELECT now()").await?; assert_eq!(r.get_rows().len(), 1); assert_eq!(r.get_rows()[0].values().len(), 1); match &r.get_rows()[0].values()[0] { @@ -7333,20 +7005,13 @@ async fn now(service: Box) { v => panic!("not a timestamp: {:?}", v), } - service.exec_query("CREATE SCHEMA s").await.unwrap(); - service - .exec_query("CREATE TABLE s.Data(i int)") - .await - .unwrap(); + service.exec_query("CREATE SCHEMA s").await?; + service.exec_query("CREATE TABLE s.Data(i int)").await?; service .exec_query("INSERT INTO s.Data(i) VALUES (1), (2), (3)") - .await - .unwrap(); + .await?; - let r = service - .exec_query("SELECT i, now() FROM s.Data") - .await - .unwrap(); + let r = service.exec_query("SELECT i, now() FROM s.Data").await?; assert_eq!(r.len(), 3); let mut seen = None; for r in r.get_rows() { @@ -7361,40 +7026,37 @@ async fn now(service: Box) { let r = service .exec_query("SELECT i, now() FROM s.Data WHERE now() = now()") - .await - .unwrap(); + .await?; assert_eq!(r.len(), 3); - let r = service - .exec_query("SELECT now(), unix_timestamp()") - .await - .unwrap(); + let r = service.exec_query("SELECT now(), unix_timestamp()").await?; match r.get_rows()[0].values().as_slice() { &[TableValue::Timestamp(v), TableValue::Int(t)] => { assert_eq!(v.get_time_stamp() / 1_000_000_000, t) } _ => panic!("unexpected values: {:?}", r.get_rows()[0]), } + Ok(()) } -async fn dump(service: Box) { - let r = service.exec_query("DUMP SELECT 1").await.unwrap(); +async fn dump(service: Box) -> Result<(), CubeError> { + let r = service.exec_query("DUMP SELECT 1").await?; let dump_dir = match &r.get_rows()[0].values()[0] { TableValue::String(d) => d, _ => panic!("invalid result"), }; - assert!(tokio::fs::metadata(dump_dir).await.unwrap().is_dir()); + assert!(tokio::fs::metadata(dump_dir).await?.is_dir()); assert!( tokio::fs::metadata(Path::new(dump_dir).join("metastore-backup")) - .await - .unwrap() + .await? .is_dir() ); + Ok(()) } #[allow(dead_code)] -async fn ksql_simple(service: Box) { +async fn ksql_simple(service: Box) -> Result<(), CubeError> { let vars = env::var("TEST_KSQL_USER").and_then(|user| { env::var("TEST_KSQL_PASS") .and_then(|pass| env::var("TEST_KSQL_URL").map(|url| (user, pass, url))) @@ -7403,38 +7065,40 @@ async fn ksql_simple(service: Box) { service .exec_query(&format!("CREATE SOURCE OR UPDATE ksql AS 'ksql' VALUES (user = '{}', password = '{}', url = '{}')", user, pass, url)) .await - .unwrap(); + ?; - service.exec_query("CREATE SCHEMA test").await.unwrap(); - service.exec_query("CREATE TABLE test.events_by_type (`EVENT` text, `KSQL_COL_0` int) unique key (`EVENT`) location 'stream://ksql/EVENTS_BY_TYPE'").await.unwrap(); + service.exec_query("CREATE SCHEMA test").await?; + service.exec_query("CREATE TABLE test.events_by_type (`EVENT` text, `KSQL_COL_0` int) unique key (`EVENT`) location 'stream://ksql/EVENTS_BY_TYPE'").await?; for _ in 0..100 { let res = service .exec_query( "SELECT * FROM test.events_by_type WHERE `EVENT` = 'load_request_success'", ) - .await - .unwrap(); + .await?; if res.len() == 0 { tokio::time::sleep(Duration::from_millis(100)).await; continue; } if res.len() == 1 { - return; + return Ok(()); } } panic!("Can't load data from ksql"); } + Ok(()) } -async fn dimension_only_queries_for_stream_table(service: Box) { - service.exec_query("CREATE SCHEMA test").await.unwrap(); - service.exec_query("CREATE TABLE test.events_by_type (foo text, bar timestamp, bar_id text, measure1 int) unique key (foo, bar, bar_id)").await.unwrap(); +async fn dimension_only_queries_for_stream_table( + service: Box, +) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA test").await?; + service.exec_query("CREATE TABLE test.events_by_type (foo text, bar timestamp, bar_id text, measure1 int) unique key (foo, bar, bar_id)").await?; for i in 0..2 { for j in 0..2 { service .exec_query(&format!("INSERT INTO test.events_by_type (foo, bar, bar_id, measure1, __seq) VALUES ('a', '2021-01-01T00:00:00.000', '{}', {}, {})", i, j, i * 10 + j)) .await - .unwrap(); + ?; } } let r = service @@ -7442,39 +7106,42 @@ async fn dimension_only_queries_for_stream_table(service: Box) { "SELECT `bar_id` `bar_id` FROM test.events_by_type as `events` GROUP BY 1 ORDER BY 1 LIMIT 100", ) .await - .unwrap(); + ?; assert_eq!(to_rows(&r), rows(&[("0"), ("1")])); + Ok(()) } -async fn unique_key_and_multi_measures_for_stream_table(service: Box) { - service.exec_query("CREATE SCHEMA test").await.unwrap(); - service.exec_query("CREATE TABLE test.events_by_type (foo text, bar timestamp, bar_id text, measure1 int, measure2 text) unique key (foo, bar, bar_id)").await.unwrap(); +async fn unique_key_and_multi_measures_for_stream_table( + service: Box, +) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA test").await?; + service.exec_query("CREATE TABLE test.events_by_type (foo text, bar timestamp, bar_id text, measure1 int, measure2 text) unique key (foo, bar, bar_id)").await?; for i in 0..2 { for j in 0..2 { service .exec_query(&format!("INSERT INTO test.events_by_type (foo, bar, bar_id, measure1, measure2, __seq) VALUES ('a', '2021-01-01T00:00:00.000', '{}', {}, '{}', {})", i, j, "text_value", i * 10 + j)) .await - .unwrap(); + ?; } } let r = service .exec_query( "SELECT bar_id, measure1, measure2 FROM test.events_by_type as `events` LIMIT 100", ) - .await - .unwrap(); + .await?; assert_eq!( to_rows(&r), rows(&[("0", 1, "text_value"), ("1", 1, "text_value")]) ); + Ok(()) } -async fn unique_key_and_multi_partitions(service: Box) { - service.exec_query("CREATE SCHEMA test").await.unwrap(); - service.exec_query("CREATE TABLE test.unique_parts1 (a int, b int, c int, e int, val int) unique key (a, b, c, e) ").await.unwrap(); - service.exec_query("CREATE TABLE test.unique_parts2 (a int, b int, c int, e int, val int) unique key (a, b, c, e) ").await.unwrap(); +async fn unique_key_and_multi_partitions(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA test").await?; + service.exec_query("CREATE TABLE test.unique_parts1 (a int, b int, c int, e int, val int) unique key (a, b, c, e) ").await?; + service.exec_query("CREATE TABLE test.unique_parts2 (a int, b int, c int, e int, val int) unique key (a, b, c, e) ").await?; service .exec_query( " @@ -7485,8 +7152,7 @@ async fn unique_key_and_multi_partitions(service: Box) { (2, 2, 2, 2, 20, 2) ", ) - .await - .unwrap(); + .await?; service .exec_query( @@ -7498,8 +7164,7 @@ async fn unique_key_and_multi_partitions(service: Box) { (22, 22, 22, 22, 220, 21) ", ) - .await - .unwrap(); + .await?; service .exec_query( @@ -7511,8 +7176,7 @@ async fn unique_key_and_multi_partitions(service: Box) { (4, 4, 4, 4, 40, 4) ", ) - .await - .unwrap(); + .await?; let query = "SELECT a, b FROM ( SELECT * FROM test.unique_parts1 @@ -7520,7 +7184,7 @@ async fn unique_key_and_multi_partitions(service: Box) { SELECT * FROM test.unique_parts2 ) `tt` GROUP BY 1, 2 ORDER BY 1, 2 LIMIT 100"; - let r = service.exec_query(query).await.unwrap(); + let r = service.exec_query(query).await?; assert_eq!( to_rows(&r), @@ -7537,7 +7201,7 @@ async fn unique_key_and_multi_partitions(service: Box) { // Assert that we get a MergeSort node when there are multiple partitions. if test_multiple_partitions { - let plan = service.plan_query(query).await.unwrap(); + let plan = service.plan_query(query).await?; assert_eq!( pp_phys_plan_ext( @@ -7575,12 +7239,15 @@ async fn unique_key_and_multi_partitions(service: Box) { \n FilterByKeyRange, partitions: 1\ \n MemoryScan, partitions: 1"); } + Ok(()) } -async fn unique_key_and_multi_partitions_hash_aggregate(service: Box) { - service.exec_query("CREATE SCHEMA test").await.unwrap(); - service.exec_query("CREATE TABLE test.unique_parts1 (a int, b int, c int, e int, val int) unique key (a, b, c, e) ").await.unwrap(); - service.exec_query("CREATE TABLE test.unique_parts2 (a int, b int, c int, e int, val int) unique key (a, b, c, e) ").await.unwrap(); +async fn unique_key_and_multi_partitions_hash_aggregate( + service: Box, +) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA test").await?; + service.exec_query("CREATE TABLE test.unique_parts1 (a int, b int, c int, e int, val int) unique key (a, b, c, e) ").await?; + service.exec_query("CREATE TABLE test.unique_parts2 (a int, b int, c int, e int, val int) unique key (a, b, c, e) ").await?; service .exec_query( " @@ -7591,8 +7258,7 @@ async fn unique_key_and_multi_partitions_hash_aggregate(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); - service - .exec_query("CREATE TABLE s.t(i int, z int)") - .await - .unwrap(); +async fn divide_by_zero(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; + service.exec_query("CREATE TABLE s.t(i int, z int)").await?; service .exec_query("INSERT INTO s.t(i, z) VALUES (1, 0), (2, 0), (3, 0)") - .await - .unwrap(); + .await?; let r = service .exec_query("SELECT i / z FROM s.t") .await .err() - .unwrap(); + .expect("expected error"); assert_eq!( r.elide_backtrace(), CubeError::internal( "Execution error: Internal: Arrow error: Divide by zero error".to_string() ) ); + Ok(()) } -async fn panic_worker(service: Box) { +async fn panic_worker(service: Box) -> Result<(), CubeError> { let r = service.exec_query("SYS PANIC WORKER").await; assert_eq!(r, Err(CubeError::panic("worker panic".to_string()))); + Ok(()) } -async fn filter_multiple_in_for_decimal_setup(service: &dyn SqlClient) -> &'static str { - service.exec_query("CREATE SCHEMA s").await.unwrap(); - service - .exec_query("CREATE TABLE s.t(i decimal)") - .await - .unwrap(); +async fn filter_multiple_in_for_decimal_setup( + service: &dyn SqlClient, +) -> Result<&'static str, CubeError> { + service.exec_query("CREATE SCHEMA s").await?; + service.exec_query("CREATE TABLE s.t(i decimal)").await?; service .exec_query("INSERT INTO s.t(i) VALUES (1), (2), (3)") - .await - .unwrap(); + .await?; - ("SELECT count(*) FROM s.t WHERE i in ('2', '3')") as _ + Ok(("SELECT count(*) FROM s.t WHERE i in ('2', '3')") as _) } -async fn filter_multiple_in_for_decimal(service: Box) { - let query = filter_multiple_in_for_decimal_setup(service.as_ref()).await; +async fn filter_multiple_in_for_decimal(service: Box) -> Result<(), CubeError> { + let query = filter_multiple_in_for_decimal_setup(service.as_ref()).await?; - let r = service.exec_query(query).await.unwrap(); + let r = service.exec_query(query).await?; assert_eq!(to_rows(&r), rows(&[(2)])); + Ok(()) } -async fn planning_filter_multiple_in_for_decimal(service: Box) { - let query = filter_multiple_in_for_decimal_setup(service.as_ref()).await; +async fn planning_filter_multiple_in_for_decimal( + service: Box, +) -> Result<(), CubeError> { + let query = filter_multiple_in_for_decimal_setup(service.as_ref()).await?; // Verify we're casting '2' and '3' to decimal type and not casting i to Utf8, with Cube-specific DF comparison coercion changes. - let plans = service.plan_query(query).await.unwrap(); + let plans = service.plan_query(query).await?; let expected = "Projection, [count(Int64(1))@0:count(*)]\ \n LinearFinalAggregate\ @@ -7712,10 +7375,11 @@ async fn planning_filter_multiple_in_for_decimal(service: Box) { } ), ); + Ok(()) } -async fn planning_aggregate_index(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn planning_aggregate_index(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.Orders(a int, b int, c int, a_sum int, a_max int, a_min int, a_merge HYPERLOGLOG) AGGREGATIONS(sum(a_sum), max(a_max), min(a_min), merge(a_merge)) @@ -7723,12 +7387,11 @@ async fn planning_aggregate_index(service: Box) { AGGREGATE INDEX aggr_index (a, b) ") .await - .unwrap(); + ?; let p = service .plan_query("SELECT a, b, sum(a_sum) FROM s.Orders GROUP BY 1, 2") - .await - .unwrap(); + .await?; assert_eq!( pp_phys_plan(p.worker.as_ref()), "InlineFinalAggregate\ @@ -7742,7 +7405,7 @@ async fn planning_aggregate_index(service: Box) { let p = service .plan_query("SELECT a, b, sum(a_sum), max(a_max), min(a_min), merge(a_merge) FROM s.Orders GROUP BY 1, 2") .await - .unwrap(); + ?; assert_eq!( pp_phys_plan(p.worker.as_ref()), "InlineFinalAggregate\ @@ -7756,7 +7419,7 @@ async fn planning_aggregate_index(service: Box) { let p = service .plan_query("SELECT a, b, sum(a_sum), max(a_max), min(a_min), merge(a_merge) FROM s.Orders WHERE c = 1 GROUP BY 1, 2") .await - .unwrap(); + ?; assert_eq!( pp_phys_plan(p.worker.as_ref()), "InlineFinalAggregate\ @@ -7772,8 +7435,7 @@ async fn planning_aggregate_index(service: Box) { .plan_query( "SELECT a, sum(a_sum), max(a_max), min(a_min), merge(a_merge) FROM s.Orders GROUP BY 1", ) - .await - .unwrap(); + .await?; assert_eq!( pp_phys_plan(p.worker.as_ref()), "InlineFinalAggregate\ @@ -7786,8 +7448,7 @@ async fn planning_aggregate_index(service: Box) { let p = service .plan_query("SELECT a, avg(a_sum) FROM s.Orders GROUP BY 1") - .await - .unwrap(); + .await?; assert_eq!( pp_phys_plan(p.worker.as_ref()), "InlineFinalAggregate\ @@ -7800,8 +7461,7 @@ async fn planning_aggregate_index(service: Box) { let p = service .plan_query("SELECT a, sum(a_sum) FROM s.Orders WHERE b = 1 GROUP BY 1") - .await - .unwrap(); + .await?; assert_eq!( pp_phys_plan(p.worker.as_ref()), "InlineFinalAggregate\ @@ -7812,10 +7472,11 @@ async fn planning_aggregate_index(service: Box) { \n Sort\ \n Empty" ); + Ok(()) } -async fn aggregate_index(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn aggregate_index(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query( "CREATE TABLE s.Orders(a int, b int, c int, a_sum int, a_max int, a_min int) @@ -7824,8 +7485,7 @@ async fn aggregate_index(service: Box) { AGGREGATE INDEX aggr_index (a, b) ", ) - .await - .unwrap(); + .await?; service .exec_query( "INSERT INTO s.Orders (a, b, c, a_sum, a_max, a_min) VALUES (1, 10, 100, 10, 10, 10), \ @@ -7836,13 +7496,12 @@ async fn aggregate_index(service: Box) { (2, 20, 410, 20, 30, 30) \ ", ) - .await - .unwrap(); + .await?; let res = service .exec_query("SELECT a, b, sum(a_sum) as sum, max(a_max) as max, min(a_min) as min FROM s.Orders GROUP BY 1, 2 ORDER BY 1, 2") .await - .unwrap(); + ?; assert_eq!( to_rows(&res), @@ -7874,7 +7533,7 @@ async fn aggregate_index(service: Box) { let res = service .exec_query("SELECT a, sum(a_sum) as sum, max(a_max) as max, min(a_min) as min FROM s.Orders GROUP BY 1 ORDER BY 1") .await - .unwrap(); + ?; assert_eq!( to_rows(&res), @@ -7897,7 +7556,7 @@ async fn aggregate_index(service: Box) { let res = service .exec_query("SELECT a, sum(a_sum) as sum, max(a_max) as max, min(a_min) as min FROM s.Orders WHERE b = 20 GROUP BY 1 ORDER BY 1") .await - .unwrap(); + ?; assert_eq!( to_rows(&res), @@ -7908,10 +7567,11 @@ async fn aggregate_index(service: Box) { TableValue::Int(10) ],] ); + Ok(()) } -async fn aggregate_index_with_hll_bytes(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn aggregate_index_with_hll_bytes(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query( "CREATE TABLE s.Orders(a int, b int, hll bytes) @@ -7919,8 +7579,7 @@ async fn aggregate_index_with_hll_bytes(service: Box) { AGGREGATE INDEX agg_index (a, b) ", ) - .await - .unwrap(); + .await?; let sparse = "X'020C0200C02FF58941D5F0C6'"; let dense = "X'030C004020000001000000000000000000000000000000000000050020000001030100000410000000004102100000000000000051000020000020003220000003102000000000001200042000000001000200000002000000100000030040000000010040003010000000000100002000000000000000000031000020000000000000000000100000200302000000000000000000001002000000000002204000000001000001000200400000000000001000020031100000000080000000002003000000100000000100110000000000000000000010000000000000000000000020000001320205000100000612000000000004100020100000000000000000001000000002200000100000001000001020000000000020000000000000001000010300060000010000000000070100003000000000000020000000000001000010000104000000000000000000101000100000001401000000000000000000000000000100010000000000000000000000000400020000000002002300010000000000040000041000200005100000000000001000000000100000203010000000000000000000000000001006000100000000000000300100001000100254200000000000101100040000000020000010000050000000501000000000101020000000010000000003000000000200000102100000000204007000000200010000033000000000061000000000000000000000000000000000100001000001000000013000000003000000000002000000000000010001000000000000000000020010000020000000100001000000000000001000103000000000000000000020020000001000000000100001000000000000000020220200200000001001000010100000000200000000000001000002000000011000000000101200000000000000000000000000000000000000100130000000000000000000100000120000300040000000002000000000000000000000100000000070000100000000301000000401200002020000000000601030001510000000000000110100000000000000000050000000010000100000000000000000100022000100000101054010001000000000000001000001000000002000000000100000000000021000001000002000000000100000000000000000000951000000100000000000000000000000000102000200000000000000010000010000000000100002000000000000000000010000000000000010000000010000000102010000000010520100000021010100000030000000000000000100000001000000022000330051000000100000000000040003020000010000020000100000013000000102020000000050000000020010000000000000000101200C000100000001200400000000010000001000000000100010000000001000001000000100000000010000000004000000002000013102000100000000000000000000000600000010000000000000020000000000001000000000030000000000000020000000001000001000000000010000003002000003000200070001001003030010000000003000000000000020000006000000000000000011000000010000200000000000500000000000000020500000000003000000000000000004000030000100000000103000001000000000000200002004200000020000000030000000000000000000000002000100000000000000002000000000000000010020101000000005250000010000000000023010000001000000000000500002001000123100030011000020001310600000000000021000023000003000000000000000001000000000000220200000000004040000020201000000010201000000000020000400010000050000000000000000000000010000020000000000000000000000000000000000102000010000000000000000000000002010000200200000000000000000000000000100000000000000000200400000000010000000000000000000000000000000010000200300000000000100110000000000000000000000000010000030000001000000000010000010200013000000000000200000001000001200010000000010000000000001000000000000100000000410000040000001000100010000100000002001010000000000000000001000000000000010000000000000000000000002000000000001100001000000001010000000000000002200000000004000000000000100010000000000600000000100300000000000000000000010000003000000000000000000310000010100006000010001000000000000001010101000100000000000000000000000000000201000000000000000700010000030000000000000021000000000000000001020000000030000100001000000000000000000000004010100000000000000000000004000000040100000040100100001000000000300000100000000010010000300000200000000000001302000000000000000000100100000400030000001001000100100002300000004030000002010000220100000000000002000000010010000000003010500000000300000000005020102000200000000000000020100000000000000000000000011000000023000000000010000101000000000000010020040200040000020000004000020000000001000000000100000200000010000000000030100010001000000100000000000600400000000002000000000000132000000900010000000030021400000000004100006000304000000000000010000106000001300020000'"; @@ -7936,15 +7595,13 @@ async fn aggregate_index_with_hll_bytes(service: Box) { s = sparse, d = dense )) - .await - .unwrap(); + .await?; let res = service .exec_query( "SELECT a, b, cardinality(merge(hll)) FROM s.Orders GROUP BY 1, 2 ORDER BY 1, 2", ) - .await - .unwrap(); + .await?; assert_eq!( to_rows(&res), @@ -7962,10 +7619,11 @@ async fn aggregate_index_with_hll_bytes(service: Box) { [TableValue::Int(2), TableValue::Int(30), TableValue::Int(2),], ] ); + Ok(()) } -async fn aggregate_index_hll(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn aggregate_index_hll(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query( "CREATE TABLE s.Orders(a int, b int, a_hll hyperloglog) @@ -7973,8 +7631,7 @@ async fn aggregate_index_hll(service: Box) { AGGREGATE INDEX aggr_index (a, b) ", ) - .await - .unwrap(); + .await?; service .exec_query( "INSERT INTO s.Orders (a, b, a_hll) VALUES \ @@ -7984,13 +7641,12 @@ async fn aggregate_index_hll(service: Box) { (1, 20, X'020C0200C02FF58941D5F0C6') \ ", ) - .await - .unwrap(); + .await?; let res = service .exec_query("SELECT a, b, cardinality(merge(a_hll)) as hll FROM s.Orders GROUP BY 1, 2 ORDER BY 1, 2") .await - .unwrap(); + ?; assert_eq!( to_rows(&res), [ @@ -8002,20 +7658,20 @@ async fn aggregate_index_hll(service: Box) { let res = service .exec_query("SELECT a, cardinality(merge(a_hll)) as hll FROM s.Orders WHERE b = 20 GROUP BY 1 ORDER BY 1") .await - .unwrap(); + ?; assert_eq!(to_rows(&res), [[TableValue::Int(1), TableValue::Int(2)],]); let res = service .exec_query( "SELECT a, cardinality(merge(a_hll)) as hll FROM s.Orders GROUP BY 1 ORDER BY 1", ) - .await - .unwrap(); + .await?; assert_eq!(to_rows(&res), [[TableValue::Int(1), TableValue::Int(2)],]); + Ok(()) } -async fn aggregate_index_errors(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn aggregate_index_errors(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; service .exec_query("CREATE TABLE s.Orders(a int, b int, a_hll hyperloglog) AGGREGATE INDEX aggr_index (a, b, a_hll) @@ -8066,10 +7722,11 @@ async fn aggregate_index_errors(service: Box) { ) .await .expect_err("Aggregate function MERGE not allowed for column type integer"); + Ok(()) } -async fn inline_tables(service: Box) { - service.exec_query("CREATE SCHEMA Foo").await.unwrap(); +async fn inline_tables(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA Foo").await?; service .exec_query( "CREATE TABLE Foo.Persons ( @@ -8079,8 +7736,7 @@ async fn inline_tables(service: Box) { Timestamp timestamp )", ) - .await - .unwrap(); + .await?; service .exec_query( @@ -8096,13 +7752,9 @@ async fn inline_tables(service: Box) { (37, 'LastName 22', 'FirstName 2', '2020-01-03T00:00:00.000Z'), (38, 'LastName 21', 'FirstName 2', '2020-01-04T00:00:00.000Z')", ) - .await - .unwrap(); + .await?; - let result = service - .exec_query("SELECT * FROM Foo.Persons") - .await - .unwrap(); + let result = service.exec_query("SELECT * FROM Foo.Persons").await?; assert_eq!(result.get_rows().len(), 8); assert_eq!( result.get_rows()[0], @@ -8110,7 +7762,7 @@ async fn inline_tables(service: Box) { TableValue::Int(23), TableValue::String("FirstName 1".to_string()), TableValue::String("LastName 1".to_string()), - TableValue::Timestamp(timestamp_from_string("2020-01-01T00:00:00.000Z").unwrap()), + TableValue::Timestamp(timestamp_from_string("2020-01-01T00:00:00.000Z")?), ]) ); @@ -8125,19 +7777,19 @@ async fn inline_tables(service: Box) { TableValue::Null, TableValue::String("last 1".to_string()), TableValue::String("first 1".to_string()), - TableValue::Timestamp(timestamp_from_string("2020-01-01T00:00:00.000Z").unwrap()), + TableValue::Timestamp(timestamp_from_string("2020-01-01T00:00:00.000Z")?), ]), Row::new(vec![ TableValue::Int(2), TableValue::Null, TableValue::String("first 2".to_string()), - TableValue::Timestamp(timestamp_from_string("2020-01-02T00:00:00.000Z").unwrap()), + TableValue::Timestamp(timestamp_from_string("2020-01-02T00:00:00.000Z")?), ]), Row::new(vec![ TableValue::Int(3), TableValue::String("last 3".to_string()), TableValue::String("first 3".to_string()), - TableValue::Timestamp(timestamp_from_string("2020-01-03T00:00:00.000Z").unwrap()), + TableValue::Timestamp(timestamp_from_string("2020-01-03T00:00:00.000Z")?), ]), Row::new(vec![ TableValue::Int(4), @@ -8152,29 +7804,27 @@ async fn inline_tables(service: Box) { let context = SqlQueryContext::default().with_inline_tables(&inline_tables); let result = service .exec_query_with_context(context, "SELECT * FROM Persons") - .await - .unwrap(); + .await?; assert_eq!(result.get_rows(), &rows); let context = SqlQueryContext::default().with_inline_tables(&inline_tables); let result = service .exec_query_with_context(context, "SELECT LastName, Timestamp FROM Persons") - .await - .unwrap(); + .await?; assert_eq!( result.get_rows(), &vec![ Row::new(vec![ TableValue::String("last 1".to_string()), - TableValue::Timestamp(timestamp_from_string("2020-01-01T00:00:00.000Z").unwrap()), + TableValue::Timestamp(timestamp_from_string("2020-01-01T00:00:00.000Z")?), ]), Row::new(vec![ TableValue::Null, - TableValue::Timestamp(timestamp_from_string("2020-01-02T00:00:00.000Z").unwrap()), + TableValue::Timestamp(timestamp_from_string("2020-01-02T00:00:00.000Z")?), ]), Row::new(vec![ TableValue::String("last 3".to_string()), - TableValue::Timestamp(timestamp_from_string("2020-01-03T00:00:00.000Z").unwrap()), + TableValue::Timestamp(timestamp_from_string("2020-01-03T00:00:00.000Z")?), ]), Row::new(vec![ TableValue::String("last 4".to_string()), @@ -8196,18 +7846,17 @@ async fn inline_tables(service: Box) { ORDER BY LastName "#, ) - .await - .unwrap(); + .await?; assert_eq!( result.get_rows()[8..12].to_vec(), vec![ Row::new(vec![ TableValue::String("last 1".to_string()), - TableValue::Timestamp(timestamp_from_string("2020-01-01T00:00:00.000Z").unwrap()), + TableValue::Timestamp(timestamp_from_string("2020-01-01T00:00:00.000Z")?), ]), Row::new(vec![ TableValue::String("last 3".to_string()), - TableValue::Timestamp(timestamp_from_string("2020-01-03T00:00:00.000Z").unwrap()), + TableValue::Timestamp(timestamp_from_string("2020-01-03T00:00:00.000Z")?), ]), Row::new(vec![ TableValue::String("last 4".to_string()), @@ -8215,22 +7864,21 @@ async fn inline_tables(service: Box) { ]), Row::new(vec![ TableValue::Null, - TableValue::Timestamp(timestamp_from_string("2020-01-02T00:00:00.000Z").unwrap()), + TableValue::Timestamp(timestamp_from_string("2020-01-02T00:00:00.000Z")?), ]), ] ); + Ok(()) } -async fn inline_tables_2x(service: Box) { - service.exec_query("CREATE SCHEMA Foo").await.unwrap(); +async fn inline_tables_2x(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA Foo").await?; service .exec_query("CREATE TABLE Foo.Persons (ID int, First varchar(255), Last varchar(255))") - .await - .unwrap(); + .await?; service .exec_query("CREATE TABLE Foo.Persons2 (ID int, First varchar(255), Last varchar(255))") - .await - .unwrap(); + .await?; service .exec_query( @@ -8241,8 +7889,7 @@ async fn inline_tables_2x(service: Box) { (12, 'last 12', 'first 12'), (13, 'last 13', 'first 13')", ) - .await - .unwrap(); + .await?; service .exec_query( "INSERT INTO Foo.Persons2 @@ -8252,8 +7899,7 @@ async fn inline_tables_2x(service: Box) { (32, 'last 32', 'first 32'), (33, 'last 33', 'first 33')", ) - .await - .unwrap(); + .await?; let columns = vec![ Column::new("ID".to_string(), ColumnType::Int, 0), @@ -8316,8 +7962,7 @@ async fn inline_tables_2x(service: Box) { ORDER BY Last "#, ) - .await - .unwrap(); + .await?; assert_eq!( result.get_rows().to_vec(), vec![ @@ -8335,25 +7980,21 @@ async fn inline_tables_2x(service: Box) { Row::new(vec![TableValue::String("last 43".to_string())]), ] ); + Ok(()) } -async fn build_range_end(service: Box) { - service.exec_query("CREATE SCHEMA s").await.unwrap(); +async fn build_range_end(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA s").await?; - service - .exec_query("CREATE TABLE s.t0(x string)") - .await - .unwrap(); + service.exec_query("CREATE TABLE s.t0(x string)").await?; service .exec_query("CREATE TABLE s.t1(x string) WITH(build_range_end = '2020-01-01T00:00:00.000')") - .await - .unwrap(); + .await?; let r = service .exec_query("SELECT table_schema, table_name, build_range_end FROM system.tables") - .await - .unwrap(); + .await?; assert_eq!( r.get_rows(), @@ -8366,7 +8007,7 @@ async fn build_range_end(service: Box) { Row::new(vec![ TableValue::String("s".to_string()), TableValue::String("t1".to_string()), - TableValue::Timestamp(timestamp_from_string("2020-01-01T00:00:00.000").unwrap()), + TableValue::Timestamp(timestamp_from_string("2020-01-01T00:00:00.000")?), ]), ] ); @@ -8375,8 +8016,7 @@ async fn build_range_end(service: Box) { .exec_query( "SELECT table_schema, table_name, build_range_end FROM information_schema.tables", ) - .await - .unwrap(); + .await?; assert_eq!( r.get_rows(), @@ -8389,10 +8029,11 @@ async fn build_range_end(service: Box) { Row::new(vec![ TableValue::String("s".to_string()), TableValue::String("t1".to_string()), - TableValue::Timestamp(timestamp_from_string("2020-01-01T00:00:00.000").unwrap()), + TableValue::Timestamp(timestamp_from_string("2020-01-01T00:00:00.000")?), ]), ] ); + Ok(()) } async fn assert_limit_pushdown_using_search_string( @@ -8401,34 +8042,39 @@ async fn assert_limit_pushdown_using_search_string( expected_index: Option<&str>, is_limit_expected: bool, search_string: &str, -) -> Result, String> { +) -> Result, CubeError> { let res = service .exec_query(&format!("EXPLAIN ANALYZE {}", query)) - .await - .unwrap(); + .await?; match &res.get_rows()[1].values()[2] { TableValue::String(s) => { if let Some(ind) = expected_index { if !s.contains(ind) { - return Err(format!( + return Err(CubeError::internal(format!( "Expected index `{}` but it not found in the plan", ind - )); + ))); } } let expected_limit = search_string; if is_limit_expected { if !s.contains(expected_limit) { - return Err(format!("{} expected but not found", expected_limit)); + return Err(CubeError::internal(format!( + "{} expected but not found", + expected_limit + ))); } } else if s.contains(expected_limit) { - return Err(format!("{} unexpected but found", expected_limit)); + return Err(CubeError::internal(format!( + "{} unexpected but found", + expected_limit + ))); } } - _ => return Err("unexpected value".to_string()), + _ => return Err(CubeError::internal("unexpected value".to_string())), }; - let res = service.exec_query(query).await.unwrap(); + let res = service.exec_query(query).await?; Ok(res.get_rows().clone()) } @@ -8438,7 +8084,7 @@ async fn assert_limit_pushdown( expected_index: Option<&str>, is_limit_expected: bool, is_tail_limit: bool, -) -> Result, String> { +) -> Result, CubeError> { assert_limit_pushdown_using_search_string( service, query, @@ -8453,12 +8099,12 @@ async fn assert_limit_pushdown( .await } -async fn cache_incr(service: Box) { +async fn cache_incr(service: Box) -> Result<(), CubeError> { service.note_non_idempotent_migration_test(); let query = r#"CACHE INCR "prefix:key""#; service.migration_run_next_query(); - let r = service.exec_query(query).await.unwrap(); + let r = service.exec_query(query).await?; assert_eq!( r.get_rows(), @@ -8468,7 +8114,7 @@ async fn cache_incr(service: Box) { ); service.migration_run_next_query(); - let r = service.exec_query(query).await.unwrap(); + let r = service.exec_query(query).await?; assert_eq!( r.get_rows(), @@ -8476,16 +8122,16 @@ async fn cache_incr(service: Box) { (if !service.is_migration() { "2" } else { "4" }).to_string() ),]),] ); + Ok(()) } -async fn cache_set_get_rm(service: Box) { +async fn cache_set_get_rm(service: Box) -> Result<(), CubeError> { service.migration_run_next_query(); service .exec_query("CACHE SET 'key_to_rm' 'myvalue';") - .await - .unwrap(); + .await?; - let get_response = service.exec_query("CACHE GET 'key_to_rm'").await.unwrap(); + let get_response = service.exec_query("CACHE GET 'key_to_rm'").await?; assert_eq!( get_response.get_columns(), @@ -8500,23 +8146,20 @@ async fn cache_set_get_rm(service: Box) { service.migration_run_next_query(); service .exec_query("CACHE REMOVE 'key_to_rm' 'myvalue';") - .await - .unwrap(); + .await?; - let get_response = service.exec_query("CACHE GET 'key_to_rm'").await.unwrap(); + let get_response = service.exec_query("CACHE GET 'key_to_rm'").await?; assert_eq!( get_response.get_rows(), &vec![Row::new(vec![TableValue::Null,]),] ); + Ok(()) } -async fn cache_set_get_set_get(service: Box) { +async fn cache_set_get_set_get(service: Box) -> Result<(), CubeError> { if service.is_migration() { - let get_response = service - .exec_query("CACHE GET 'key_for_update'") - .await - .unwrap(); + let get_response = service.exec_query("CACHE GET 'key_for_update'").await?; assert_eq!( get_response.get_rows(), @@ -8529,13 +8172,9 @@ async fn cache_set_get_set_get(service: Box) { service.migration_run_next_query(); service .exec_query("CACHE SET 'key_for_update' '1';") - .await - .unwrap(); + .await?; - let get_response = service - .exec_query("CACHE GET 'key_for_update'") - .await - .unwrap(); + let get_response = service.exec_query("CACHE GET 'key_for_update'").await?; assert_eq!( get_response.get_rows(), @@ -8548,32 +8187,25 @@ async fn cache_set_get_set_get(service: Box) { service.migration_run_next_query(); service .exec_query("CACHE SET 'key_for_update' '2';") - .await - .unwrap(); + .await?; - let get_response = service - .exec_query("CACHE GET 'key_for_update'") - .await - .unwrap(); + let get_response = service.exec_query("CACHE GET 'key_for_update'").await?; assert_eq!( get_response.get_rows(), &vec![Row::new(vec![TableValue::String("2".to_string()),]),] ); } + Ok(()) } -async fn cache_compaction(service: Box) { +async fn cache_compaction(service: Box) -> Result<(), CubeError> { if !service.is_migration() { service .exec_query("CACHE SET NX TTL 4 'my_prefix:my_key' 'myvalue';") - .await - .unwrap(); + .await?; - let get_response = service - .exec_query("CACHE GET 'my_prefix:my_key'") - .await - .unwrap(); + let get_response = service.exec_query("CACHE GET 'my_prefix:my_key'").await?; assert_eq!( get_response.get_rows(), @@ -8583,15 +8215,9 @@ async fn cache_compaction(service: Box) { tokio::time::sleep(Duration::new(5, 0)).await; } service.tolerate_next_query_revisit(); - service - .exec_query("SYS CACHESTORE COMPACTION;") - .await - .unwrap(); + service.exec_query("SYS CACHESTORE COMPACTION;").await?; - let get_response = service - .exec_query("CACHE GET 'my_prefix:my_key'") - .await - .unwrap(); + let get_response = service.exec_query("CACHE GET 'my_prefix:my_key'").await?; assert_eq!( get_response.get_rows(), @@ -8603,20 +8229,20 @@ async fn cache_compaction(service: Box) { .exec_query( "select count(*) from system.cache where id = 'my_key' and prefix = 'my_prefix'", ) - .await - .unwrap(); + .await?; assert_eq!( cache_resp.get_rows(), &vec![Row::new(vec![TableValue::Int(0)]),] ); + Ok(()) } -async fn cache_set_nx(service: Box) { +async fn cache_set_nx(service: Box) -> Result<(), CubeError> { let set_nx_key_sql = "CACHE SET NX TTL 4 'mykey' 'myvalue';"; service.migration_run_next_query(); - let set_response = service.exec_query(set_nx_key_sql).await.unwrap(); + let set_response = service.exec_query(set_nx_key_sql).await?; assert_eq!( set_response.get_columns(), @@ -8630,7 +8256,7 @@ async fn cache_set_nx(service: Box) { // key was already defined service.migration_run_next_query(); - let set_response = service.exec_query(set_nx_key_sql).await.unwrap(); + let set_response = service.exec_query(set_nx_key_sql).await?; assert_eq!( set_response.get_rows(), @@ -8641,29 +8267,21 @@ async fn cache_set_nx(service: Box) { // key was expired service.migration_run_next_query(); - let set_response = service.exec_query(set_nx_key_sql).await.unwrap(); + let set_response = service.exec_query(set_nx_key_sql).await?; assert_eq!( set_response.get_rows(), &vec![Row::new(vec![TableValue::Boolean(true),]),] ); + Ok(()) } -async fn cache_prefix_keys(service: Box) { - service - .exec_query("CACHE SET 'locks:key1' '1';") - .await - .unwrap(); - service - .exec_query("CACHE SET 'locks:key2' '2';") - .await - .unwrap(); - service - .exec_query("CACHE SET 'locks:key3' '3';") - .await - .unwrap(); +async fn cache_prefix_keys(service: Box) -> Result<(), CubeError> { + service.exec_query("CACHE SET 'locks:key1' '1';").await?; + service.exec_query("CACHE SET 'locks:key2' '2';").await?; + service.exec_query("CACHE SET 'locks:key3' '3';").await?; - let keys_response = service.exec_query("CACHE KEYS 'locks'").await.unwrap(); + let keys_response = service.exec_query("CACHE KEYS 'locks'").await?; assert_eq!( keys_response.get_columns(), &vec![Column::new("key".to_string(), ColumnType::String, 0),] @@ -8676,18 +8294,17 @@ async fn cache_prefix_keys(service: Box) { Row::new(vec![TableValue::String("locks:key3".to_string())]), ] ); + Ok(()) } -async fn limit_pushdown_group(service: Box) { - service.exec_query("CREATE SCHEMA foo").await.unwrap(); +async fn limit_pushdown_group(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA foo").await?; service .exec_query("CREATE TABLE foo.pushdown1 (id int, n int)") - .await - .unwrap(); + .await?; service .exec_query("CREATE TABLE foo.pushdown2 (id int, n int)") - .await - .unwrap(); + .await?; service .exec_query( "INSERT INTO foo.pushdown1 @@ -8700,8 +8317,7 @@ async fn limit_pushdown_group(service: Box) { (12, 25) ", ) - .await - .unwrap(); + .await?; service .exec_query( "INSERT INTO foo.pushdown2 @@ -8714,8 +8330,7 @@ async fn limit_pushdown_group(service: Box) { (22, 25), (23, 30)", ) - .await - .unwrap(); + .await?; let res = assert_limit_pushdown( &service, @@ -8728,8 +8343,7 @@ async fn limit_pushdown_group(service: Box) { false, false, ) - .await - .unwrap(); + .await?; // TODO upgrade DF limit isn't expected and order can't be validated. // TODO But should we keep existing behavior of always sorted output? @@ -8742,19 +8356,20 @@ async fn limit_pushdown_group(service: Box) { // Row::new(vec![TableValue::Int(21), TableValue::Int(40)]), // ] // ); + Ok(()) } -async fn limit_pushdown_group_order(service: Box) { - service.exec_query("CREATE SCHEMA foo").await.unwrap(); +async fn limit_pushdown_group_order(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA foo").await?; service .exec_query("CREATE TABLE foo.pushdown_group1 (a int, b int, n int) index ind1 (a, b) index ind2 (b)") .await - .unwrap(); + ?; service .exec_query("CREATE TABLE foo.pushdown_group2 (a int, b int, n int) index ind1 (a, b) index ind2 (b)") .await - .unwrap(); + ?; service .exec_query( "INSERT INTO foo.pushdown_group1 @@ -8767,8 +8382,7 @@ async fn limit_pushdown_group_order(service: Box) { (12, 25, 1) ", ) - .await - .unwrap(); + .await?; service .exec_query( "INSERT INTO foo.pushdown_group2 @@ -8781,8 +8395,7 @@ async fn limit_pushdown_group_order(service: Box) { (22, 25, 1), (23, 30, 1)", ) - .await - .unwrap(); + .await?; let res = assert_limit_pushdown( &service, @@ -8795,8 +8408,7 @@ async fn limit_pushdown_group_order(service: Box) { true, false, ) - .await - .unwrap(); + .await?; assert_eq!( res, vec![ @@ -8831,8 +8443,7 @@ async fn limit_pushdown_group_order(service: Box) { true, false, ) - .await - .unwrap(); + .await?; assert_eq!( res, @@ -8868,8 +8479,7 @@ async fn limit_pushdown_group_order(service: Box) { false, false, ) - .await - .unwrap(); + .await?; assert_eq!( res, vec![ @@ -8903,8 +8513,7 @@ async fn limit_pushdown_group_order(service: Box) { false, false, ) - .await - .unwrap(); + .await?; assert_eq!( res, vec![ @@ -8938,8 +8547,7 @@ async fn limit_pushdown_group_order(service: Box) { true, true, ) - .await - .unwrap(); + .await?; assert_eq!( res, vec![ @@ -8973,8 +8581,7 @@ async fn limit_pushdown_group_order(service: Box) { true, true, ) - .await - .unwrap(); + .await?; assert_eq!( res, vec![ @@ -9009,8 +8616,7 @@ async fn limit_pushdown_group_order(service: Box) { true, true, ) - .await - .unwrap(); + .await?; assert_eq!( res, vec![ @@ -9045,8 +8651,7 @@ async fn limit_pushdown_group_order(service: Box) { true, false, ) - .await - .unwrap(); + .await?; assert_eq!( res, vec![ @@ -9069,8 +8674,7 @@ async fn limit_pushdown_group_order(service: Box) { true, false, ) - .await - .unwrap(); + .await?; assert_eq!( res, vec![ @@ -9103,8 +8707,7 @@ async fn limit_pushdown_group_order(service: Box) { true, false, ) - .await - .unwrap(); + .await?; assert_eq!( res, vec![ @@ -9125,19 +8728,20 @@ async fn limit_pushdown_group_order(service: Box) { ]), ] ); + Ok(()) } -async fn limit_pushdown_group_where_order(service: Box) { - service.exec_query("CREATE SCHEMA foo").await.unwrap(); +async fn limit_pushdown_group_where_order(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA foo").await?; service .exec_query("CREATE TABLE foo.pushdown_where_group1 (a int, b int, c int) index ind1 (a, b, c) index ind2 (c, b)") .await - .unwrap(); + ?; service .exec_query("CREATE TABLE foo.pushdown_where_group2 (a int, b int, c int) index ind1 (a, b, c) index ind2 (c, b)") .await - .unwrap(); + ?; service .exec_query( "INSERT INTO foo.pushdown_where_group1 @@ -9151,8 +8755,7 @@ async fn limit_pushdown_group_where_order(service: Box) { (12, 25, 6) ", ) - .await - .unwrap(); + .await?; service .exec_query( "INSERT INTO foo.pushdown_where_group2 @@ -9166,8 +8769,7 @@ async fn limit_pushdown_group_where_order(service: Box) { (22, 25, 12), (23, 30, 13)", ) - .await - .unwrap(); + .await?; let res = assert_limit_pushdown( &service, "SELECT a, b, SUM(c) FROM ( @@ -9181,8 +8783,7 @@ async fn limit_pushdown_group_where_order(service: Box) { true, false, ) - .await - .unwrap(); + .await?; assert_eq!( res, @@ -9218,8 +8819,7 @@ async fn limit_pushdown_group_where_order(service: Box) { true, true, ) - .await - .unwrap(); + .await?; assert_eq!( res, @@ -9255,8 +8855,7 @@ async fn limit_pushdown_group_where_order(service: Box) { true, false, ) - .await - .unwrap(); + .await?; assert_eq!( res, @@ -9280,8 +8879,7 @@ async fn limit_pushdown_group_where_order(service: Box) { false, false, ) - .await - .unwrap(); + .await?; assert_eq!( res, @@ -9305,8 +8903,7 @@ async fn limit_pushdown_group_where_order(service: Box) { true, true, ) - .await - .unwrap(); + .await?; assert_eq!( res, @@ -9331,8 +8928,7 @@ async fn limit_pushdown_group_where_order(service: Box) { true, false, ) - .await - .unwrap(); + .await?; assert_eq!( res, @@ -9355,8 +8951,7 @@ async fn limit_pushdown_group_where_order(service: Box) { true, true, ) - .await - .unwrap(); + .await?; assert_eq!( res, @@ -9379,8 +8974,7 @@ async fn limit_pushdown_group_where_order(service: Box) { true, false, ) - .await - .unwrap(); + .await?; assert_eq!( res, @@ -9404,8 +8998,7 @@ async fn limit_pushdown_group_where_order(service: Box) { false, false, ) - .await - .unwrap(); + .await?; assert_eq!( res, @@ -9429,23 +9022,23 @@ async fn limit_pushdown_group_where_order(service: Box) { true, false, ) - .await - .unwrap(); + .await?; assert_eq!(res, vec![Row::new(vec![TableValue::Int(20)]),]); + Ok(()) } -async fn limit_pushdown_without_group(service: Box) { - service.exec_query("CREATE SCHEMA foo").await.unwrap(); +async fn limit_pushdown_without_group(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA foo").await?; service .exec_query("CREATE TABLE foo.pushdown_where_group1 (a int, b int, c int) index ind1 (a, b, c) index ind2 (c, b)") .await - .unwrap(); + ?; service .exec_query("CREATE TABLE foo.pushdown_where_group2 (a int, b int, c int) index ind1 (a, b, c) index ind2 (c, b)") .await - .unwrap(); + ?; service .exec_query( "INSERT INTO foo.pushdown_where_group1 @@ -9459,8 +9052,7 @@ async fn limit_pushdown_without_group(service: Box) { (12, 25, 6) ", ) - .await - .unwrap(); + .await?; service .exec_query( "INSERT INTO foo.pushdown_where_group2 @@ -9474,8 +9066,7 @@ async fn limit_pushdown_without_group(service: Box) { (22, 25, 12), (23, 30, 13)", ) - .await - .unwrap(); + .await?; // ==================================== let res = assert_limit_pushdown_using_search_string( &service, @@ -9490,8 +9081,7 @@ async fn limit_pushdown_without_group(service: Box) { true, "Sort, fetch: 4", ) - .await - .unwrap(); + .await?; let mut expected = vec![ Row::new(vec![ @@ -9539,8 +9129,7 @@ async fn limit_pushdown_without_group(service: Box) { true, "Sort, fetch: 3", ) - .await - .unwrap(); + .await?; assert_eq!( res, @@ -9576,8 +9165,7 @@ async fn limit_pushdown_without_group(service: Box) { true, "Sort, fetch: 3", ) - .await - .unwrap(); + .await?; assert_eq!( res, @@ -9613,8 +9201,7 @@ async fn limit_pushdown_without_group(service: Box) { true, "Sort, fetch: 3", ) - .await - .unwrap(); + .await?; assert_eq!( res, @@ -9649,8 +9236,7 @@ async fn limit_pushdown_without_group(service: Box) { true, "Sort, fetch: 3", ) - .await - .unwrap(); + .await?; assert_eq!( res, @@ -9681,8 +9267,7 @@ async fn limit_pushdown_without_group(service: Box) { true, "Sort, fetch: 3", ) - .await - .unwrap(); + .await?; assert_eq!( res, @@ -9713,8 +9298,7 @@ async fn limit_pushdown_without_group(service: Box) { true, "Sort, fetch: 3", ) - .await - .unwrap(); + .await?; assert_eq!( res, @@ -9731,18 +9315,19 @@ async fn limit_pushdown_without_group(service: Box) { ]), ] ); + Ok(()) } -async fn limit_pushdown_without_group_resort(service: Box) { - service.exec_query("CREATE SCHEMA foo").await.unwrap(); +async fn limit_pushdown_without_group_resort(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA foo").await?; service .exec_query("CREATE TABLE foo.pushdown_where_group1 (a int, b int, c int) index ind1 (a, b, c) index ind2 (c, b)") .await - .unwrap(); + ?; service .exec_query("CREATE TABLE foo.pushdown_where_group2 (a int, b int, c int) index ind1 (a, b, c) index ind2 (c, b)") .await - .unwrap(); + ?; service .exec_query( "INSERT INTO foo.pushdown_where_group1 @@ -9756,8 +9341,7 @@ async fn limit_pushdown_without_group_resort(service: Box) { (12, 25, 6) ", ) - .await - .unwrap(); + .await?; service .exec_query( "INSERT INTO foo.pushdown_where_group2 @@ -9771,8 +9355,7 @@ async fn limit_pushdown_without_group_resort(service: Box) { (22, 25, 12), (23, 30, 13)", ) - .await - .unwrap(); + .await?; // ==================================== let res = assert_limit_pushdown_using_search_string( &service, @@ -9787,8 +9370,7 @@ async fn limit_pushdown_without_group_resort(service: Box) { true, "Sort, fetch: 4", ) - .await - .unwrap(); + .await?; let mut expected = vec![ Row::new(vec![ @@ -9834,8 +9416,7 @@ async fn limit_pushdown_without_group_resort(service: Box) { true, "Sort, fetch: 3", ) - .await - .unwrap(); + .await?; assert_eq!( res, @@ -9871,8 +9452,7 @@ async fn limit_pushdown_without_group_resort(service: Box) { false, false, ) - .await - .unwrap(); + .await?; assert_eq!( res, @@ -9889,18 +9469,19 @@ async fn limit_pushdown_without_group_resort(service: Box) { ]), ] ); + Ok(()) } -async fn limit_pushdown_unique_key(service: Box) { - service.exec_query("CREATE SCHEMA foo").await.unwrap(); +async fn limit_pushdown_unique_key(service: Box) -> Result<(), CubeError> { + service.exec_query("CREATE SCHEMA foo").await?; service .exec_query("CREATE TABLE foo.pushdown_where_group1 (a int, b int, c int) unique key (a, b) index ind1 (a, b)") .await - .unwrap(); + ?; service .exec_query("CREATE TABLE foo.pushdown_where_group2 (a int, b int, c int) unique key (a, b) index ind1 (a, b)") .await - .unwrap(); + ?; service .exec_query( "INSERT INTO foo.pushdown_where_group1 @@ -9914,8 +9495,7 @@ async fn limit_pushdown_unique_key(service: Box) { (12, 25, 6, 6) ", ) - .await - .unwrap(); + .await?; service .exec_query( "INSERT INTO foo.pushdown_where_group2 @@ -9929,8 +9509,7 @@ async fn limit_pushdown_unique_key(service: Box) { (22, 25, 12, 12), (23, 30, 13, 13)", ) - .await - .unwrap(); + .await?; // ==================================== let res = assert_limit_pushdown_using_search_string( &service, @@ -9945,8 +9524,7 @@ async fn limit_pushdown_unique_key(service: Box) { true, "Sort, fetch: 4", ) - .await - .unwrap(); + .await?; assert_eq!( res, @@ -9982,8 +9560,7 @@ async fn limit_pushdown_unique_key(service: Box) { true, "Sort, fetch: 3", ) - .await - .unwrap(); + .await?; assert_eq!( res, @@ -10019,8 +9596,7 @@ async fn limit_pushdown_unique_key(service: Box) { false, false, ) - .await - .unwrap(); + .await?; assert_eq!(res, vec![Row::new(vec![TableValue::Int(3)])]); //=========================== @@ -10037,8 +9613,7 @@ async fn limit_pushdown_unique_key(service: Box) { true, false, ) - .await - .unwrap(); + .await?; assert_eq!( res, @@ -10074,8 +9649,7 @@ async fn limit_pushdown_unique_key(service: Box) { false, false, ) - .await - .unwrap(); + .await?; assert_eq!( res, @@ -10110,8 +9684,7 @@ async fn limit_pushdown_unique_key(service: Box) { true, false, ) - .await - .unwrap(); + .await?; assert_eq!( res, @@ -10133,18 +9706,18 @@ async fn limit_pushdown_unique_key(service: Box) { ]), ] ); + Ok(()) } // Testing new rescheduling for old results which works on top of TTL // With V1 API it should return latest result after each ACK -async fn queue_latest_result_v1(service: Box) { +async fn queue_latest_result_v1(service: Box) -> Result<(), CubeError> { let service = Arc::new(service); for interval_id in 1..5 { let add_response = service .exec_query(r#"QUEUE ADD PRIORITY 1 "STANDALONE#queue:1" "payload";"#) - .await - .unwrap(); + .await?; assert_queue_add_columns(&add_response); assert_eq!( add_response.get_rows(), @@ -10157,8 +9730,7 @@ async fn queue_latest_result_v1(service: Box) { let retrieve_response = service .exec_query(r#"QUEUE RETRIEVE CONCURRENCY 1 "STANDALONE#queue:1""#) - .await - .unwrap(); + .await?; assert_queue_retrieve_columns(&retrieve_response); assert_eq!( retrieve_response.get_rows(), @@ -10177,8 +9749,7 @@ async fn queue_latest_result_v1(service: Box) { r#"QUEUE ACK "STANDALONE#queue:1" "result:{}""#, interval_id )) - .await - .unwrap(); + .await?; assert_eq!( ack_res.get_rows(), &vec![Row::new(vec![TableValue::Boolean(true)])] @@ -10186,8 +9757,7 @@ async fn queue_latest_result_v1(service: Box) { let blocking_res = service .exec_query(r#"QUEUE RESULT_BLOCKING 5000 "STANDALONE#queue:1""#) - .await - .unwrap(); + .await?; assert_eq!( blocking_res.get_rows(), &vec![Row::new(vec![ @@ -10196,22 +9766,21 @@ async fn queue_latest_result_v1(service: Box) { ]),] ); } + Ok(()) } -async fn queue_list_v1(service: Box) { +async fn queue_list_v1(service: Box) -> Result<(), CubeError> { let ctx_proc_a = SqlQueryContext::default().with_process_id(Some("process-a".to_string())); let ctx_proc_b = SqlQueryContext::default().with_process_id(Some("process-b".to_string())); let add_response = service .exec_query(r#"QUEUE ADD PRIORITY 1 "STANDALONE#queue:queue_key_1" "payload1";"#) - .await - .unwrap(); + .await?; assert_queue_add_columns(&add_response); let add_response = service .exec_query(r#"QUEUE ADD PRIORITY 1 "STANDALONE#queue:queue_key_2" "payload2";"#) - .await - .unwrap(); + .await?; assert_queue_add_columns(&add_response); // Exclusive items owned by different processes @@ -10220,8 +9789,7 @@ async fn queue_list_v1(service: Box) { ctx_proc_a.clone(), r#"QUEUE ADD EXCLUSIVE PRIORITY 1 "STANDALONE#queue:exclusive_key_a" "payload_a";"#, ) - .await - .unwrap(); + .await?; assert_queue_add_columns(&add_response); let add_response = service @@ -10229,15 +9797,13 @@ async fn queue_list_v1(service: Box) { ctx_proc_b.clone(), r#"QUEUE ADD EXCLUSIVE PRIORITY 1 "STANDALONE#queue:exclusive_key_b" "payload_b";"#, ) - .await - .unwrap(); + .await?; assert_queue_add_columns(&add_response); { let retrieve_response = service .exec_query(r#"QUEUE RETRIEVE CONCURRENCY 1 "STANDALONE#queue:queue_key_1""#) - .await - .unwrap(); + .await?; assert_queue_retrieve_columns(&retrieve_response); assert_eq!( retrieve_response.get_rows(), @@ -10255,8 +9821,7 @@ async fn queue_list_v1(service: Box) { // List without process_id: should see only non-exclusive items let list_response = service .exec_query(r#"QUEUE LIST "STANDALONE#queue";"#) - .await - .unwrap(); + .await?; assert_eq!( list_response.get_columns(), &vec![ @@ -10287,8 +9852,7 @@ async fn queue_list_v1(service: Box) { // List as process-a: should see non-exclusive items + exclusive_key_a only let list_response = service .exec_query_with_context(ctx_proc_a.clone(), r#"QUEUE LIST "STANDALONE#queue";"#) - .await - .unwrap(); + .await?; assert_eq!( list_response.get_rows(), &vec![ @@ -10316,8 +9880,7 @@ async fn queue_list_v1(service: Box) { // List as process-b: should see non-exclusive items + exclusive_key_b only let list_response = service .exec_query_with_context(ctx_proc_b.clone(), r#"QUEUE LIST "STANDALONE#queue";"#) - .await - .unwrap(); + .await?; assert_eq!( list_response.get_rows(), &vec![ @@ -10344,8 +9907,7 @@ async fn queue_list_v1(service: Box) { let list_response = service .exec_query(r#"QUEUE LIST WITH_PAYLOAD "STANDALONE#queue";"#) - .await - .unwrap(); + .await?; assert_eq!( list_response.get_columns(), &vec![ @@ -10375,13 +9937,13 @@ async fn queue_list_v1(service: Box) { ]) ] ); + Ok(()) } -async fn queue_full_workflow_v1(service: Box) { +async fn queue_full_workflow_v1(service: Box) -> Result<(), CubeError> { let add_response = service .exec_query(r#"QUEUE ADD PRIORITY 1 "STANDALONE#queue:queue_key_1" "payload1";"#) - .await - .unwrap(); + .await?; assert_queue_add_columns(&add_response); assert_eq!( add_response.get_rows(), @@ -10394,8 +9956,7 @@ async fn queue_full_workflow_v1(service: Box) { let add_response = service .exec_query(r#"QUEUE ADD PRIORITY 10 "STANDALONE#queue:queue_key_2" "payload2";"#) - .await - .unwrap(); + .await?; assert_queue_add_columns(&add_response); assert_eq!( add_response.get_rows(), @@ -10408,8 +9969,7 @@ async fn queue_full_workflow_v1(service: Box) { let add_response = service .exec_query(r#"QUEUE ADD PRIORITY 100 "STANDALONE#queue:queue_key_3" "payload3";"#) - .await - .unwrap(); + .await?; assert_queue_add_columns(&add_response); assert_eq!( add_response.get_rows(), @@ -10422,8 +9982,7 @@ async fn queue_full_workflow_v1(service: Box) { let add_response = service .exec_query(r#"QUEUE ADD PRIORITY 50 "STANDALONE#queue:queue_key_4" "payload4";"#) - .await - .unwrap(); + .await?; assert_queue_add_columns(&add_response); assert_eq!( add_response.get_rows(), @@ -10436,8 +9995,7 @@ async fn queue_full_workflow_v1(service: Box) { let add_response = service .exec_query(r#"QUEUE ADD PRIORITY -1 "STANDALONE#queue:queue_key_5" "payload5";"#) - .await - .unwrap(); + .await?; assert_queue_add_columns(&add_response); assert_eq!( add_response.get_rows(), @@ -10452,8 +10010,7 @@ async fn queue_full_workflow_v1(service: Box) { { let add_response = service .exec_query(r#"QUEUE ADD PRIORITY 1 "STANDALONE#queue:queue_key_1" "payload1";"#) - .await - .unwrap(); + .await?; assert_queue_add_columns(&add_response); assert_eq!( add_response.get_rows(), @@ -10468,8 +10025,7 @@ async fn queue_full_workflow_v1(service: Box) { { let pending_response = service .exec_query(r#"QUEUE PENDING "STANDALONE#queue""#) - .await - .unwrap(); + .await?; assert_eq!( pending_response.get_columns(), &vec![ @@ -10519,16 +10075,14 @@ async fn queue_full_workflow_v1(service: Box) { { let active_response = service .exec_query(r#"QUEUE ACTIVE "STANDALONE#queue""#) - .await - .unwrap(); + .await?; assert_eq!(active_response.get_rows().len(), 0); } { let retrieve_response = service .exec_query(r#"QUEUE RETRIEVE CONCURRENCY 1 "STANDALONE#queue:queue_key_3""#) - .await - .unwrap(); + .await?; assert_queue_retrieve_columns(&retrieve_response); assert_eq!( retrieve_response.get_rows(), @@ -10547,8 +10101,7 @@ async fn queue_full_workflow_v1(service: Box) { // concurrency limit let retrieve_response = service .exec_query(r#"QUEUE RETRIEVE CONCURRENCY 1 "STANDALONE#queue:queue_key_4""#) - .await - .unwrap(); + .await?; assert_queue_retrieve_columns(&retrieve_response); assert_eq!(retrieve_response.get_rows().len(), 0); } @@ -10556,8 +10109,7 @@ async fn queue_full_workflow_v1(service: Box) { { let active_response = service .exec_query(r#"QUEUE ACTIVE "STANDALONE#queue""#) - .await - .unwrap(); + .await?; assert_eq!( active_response.get_rows(), &vec![Row::new(vec![ @@ -10608,8 +10160,7 @@ async fn queue_full_workflow_v1(service: Box) { { let active_response = service .exec_query(r#"QUEUE ACTIVE "STANDALONE#queue""#) - .await - .unwrap(); + .await?; assert_eq!(active_response.get_rows().len(), 0); } @@ -10617,8 +10168,7 @@ async fn queue_full_workflow_v1(service: Box) { { let get_response = service .exec_query(r#"QUEUE GET "STANDALONE#queue:queue_key_2""#) - .await - .unwrap(); + .await?; assert_eq!( get_response.get_rows(), &vec![Row::new(vec![ @@ -10632,8 +10182,7 @@ async fn queue_full_workflow_v1(service: Box) { { let cancel_response = service .exec_query(r#"QUEUE CANCEL "STANDALONE#queue:queue_key_2""#) - .await - .unwrap(); + .await?; assert_eq!( cancel_response.get_rows(), &vec![Row::new(vec![ @@ -10645,17 +10194,16 @@ async fn queue_full_workflow_v1(service: Box) { // assertion that job was removed let get_response = service .exec_query(r#"QUEUE GET "STANDALONE#queue:queue_key_2""#) - .await - .unwrap(); + .await?; assert_eq!(get_response.get_rows().len(), 0); } + Ok(()) } -async fn queue_full_workflow_v2(service: Box) { +async fn queue_full_workflow_v2(service: Box) -> Result<(), CubeError> { let add_response = service .exec_query(r#"QUEUE ADD PRIORITY 1 "STANDALONE#queue:queue_key_1" "payload1";"#) - .await - .unwrap(); + .await?; assert_queue_add_columns(&add_response); assert_eq!( add_response.get_rows(), @@ -10668,8 +10216,7 @@ async fn queue_full_workflow_v2(service: Box) { let add_response = service .exec_query(r#"QUEUE ADD PRIORITY 10 "STANDALONE#queue:queue_key_2" "payload2";"#) - .await - .unwrap(); + .await?; assert_queue_add_columns(&add_response); assert_eq!( add_response.get_rows(), @@ -10682,8 +10229,7 @@ async fn queue_full_workflow_v2(service: Box) { let add_response = service .exec_query(r#"QUEUE ADD PRIORITY 100 "STANDALONE#queue:queue_key_3" "payload3";"#) - .await - .unwrap(); + .await?; assert_queue_add_columns(&add_response); assert_eq!( add_response.get_rows(), @@ -10696,8 +10242,7 @@ async fn queue_full_workflow_v2(service: Box) { let add_response = service .exec_query(r#"QUEUE ADD PRIORITY 50 "STANDALONE#queue:queue_key_4" "payload4";"#) - .await - .unwrap(); + .await?; assert_queue_add_columns(&add_response); assert_eq!( add_response.get_rows(), @@ -10710,8 +10255,7 @@ async fn queue_full_workflow_v2(service: Box) { let add_response = service .exec_query(r#"QUEUE ADD PRIORITY -1 "STANDALONE#queue:queue_key_5" "payload5";"#) - .await - .unwrap(); + .await?; assert_queue_add_columns(&add_response); assert_eq!( add_response.get_rows(), @@ -10726,8 +10270,7 @@ async fn queue_full_workflow_v2(service: Box) { { let add_response = service .exec_query(r#"QUEUE ADD PRIORITY 1 "STANDALONE#queue:queue_key_1" "payload1";"#) - .await - .unwrap(); + .await?; assert_queue_add_columns(&add_response); assert_eq!( add_response.get_rows(), @@ -10742,8 +10285,7 @@ async fn queue_full_workflow_v2(service: Box) { { let pending_response = service .exec_query(r#"QUEUE PENDING "STANDALONE#queue""#) - .await - .unwrap(); + .await?; assert_eq!( pending_response.get_columns(), &vec![ @@ -10793,16 +10335,14 @@ async fn queue_full_workflow_v2(service: Box) { { let active_response = service .exec_query(r#"QUEUE ACTIVE "STANDALONE#queue""#) - .await - .unwrap(); + .await?; assert_eq!(active_response.get_rows().len(), 0); } { let retrieve_response = service .exec_query(r#"QUEUE RETRIEVE CONCURRENCY 1 "STANDALONE#queue:queue_key_3""#) - .await - .unwrap(); + .await?; assert_queue_retrieve_columns(&retrieve_response); assert_eq!( retrieve_response.get_rows(), @@ -10821,8 +10361,7 @@ async fn queue_full_workflow_v2(service: Box) { // concurrency limit let retrieve_response = service .exec_query(r#"QUEUE RETRIEVE CONCURRENCY 1 "STANDALONE#queue:queue_key_4""#) - .await - .unwrap(); + .await?; assert_queue_retrieve_columns(&retrieve_response); assert_eq!(retrieve_response.get_rows().len(), 0); } @@ -10830,8 +10369,7 @@ async fn queue_full_workflow_v2(service: Box) { { let active_response = service .exec_query(r#"QUEUE ACTIVE "STANDALONE#queue""#) - .await - .unwrap(); + .await?; assert_eq!( active_response.get_rows(), &vec![Row::new(vec![ @@ -10882,14 +10420,13 @@ async fn queue_full_workflow_v2(service: Box) { { let active_response = service .exec_query(r#"QUEUE ACTIVE "STANDALONE#queue""#) - .await - .unwrap(); + .await?; assert_eq!(active_response.get_rows().len(), 0); } // get { - let get_response = service.exec_query(r#"QUEUE GET 2"#).await.unwrap(); + let get_response = service.exec_query(r#"QUEUE GET 2"#).await?; assert_eq!( get_response.get_rows(), &vec![Row::new(vec![ @@ -10901,7 +10438,7 @@ async fn queue_full_workflow_v2(service: Box) { // cancel job { - let cancel_response = service.exec_query(r#"QUEUE CANCEL 2"#).await.unwrap(); + let cancel_response = service.exec_query(r#"QUEUE CANCEL 2"#).await?; assert_eq!( cancel_response.get_rows(), &vec![Row::new(vec![ @@ -10911,9 +10448,10 @@ async fn queue_full_workflow_v2(service: Box) { ); // assertion that job was removed - let get_response = service.exec_query(r#"QUEUE GET 2"#).await.unwrap(); + let get_response = service.exec_query(r#"QUEUE GET 2"#).await?; assert_eq!(get_response.get_rows().len(), 0); } + Ok(()) } fn assert_queue_add_columns(response: &Arc) { @@ -10950,27 +10488,23 @@ fn assert_queue_result_blocking_columns(response: &Arc) { ); } -async fn queue_retrieve_extended(service: Box) { +async fn queue_retrieve_extended(service: Box) -> Result<(), CubeError> { service .exec_query(r#"QUEUE ADD PRIORITY 1 "STANDALONE#queue:1" "payload1";"#) - .await - .unwrap(); + .await?; service .exec_query(r#"QUEUE ADD PRIORITY 1 "STANDALONE#queue:2" "payload2";"#) - .await - .unwrap(); + .await?; service .exec_query(r#"QUEUE ADD PRIORITY 1 "STANDALONE#queue:3" "payload3";"#) - .await - .unwrap(); + .await?; { let retrieve_response = service .exec_query(r#"QUEUE RETRIEVE CONCURRENCY 1 "STANDALONE#queue:1""#) - .await - .unwrap(); + .await?; assert_queue_retrieve_columns(&retrieve_response); assert_eq!( retrieve_response.get_rows(), @@ -10988,8 +10522,7 @@ async fn queue_retrieve_extended(service: Box) { // concurrency limit let retrieve_response = service .exec_query(r#"QUEUE RETRIEVE EXTENDED CONCURRENCY 1 "STANDALONE#queue:2""#) - .await - .unwrap(); + .await?; assert_queue_retrieve_columns(&retrieve_response); assert_eq!( retrieve_response.get_rows(), @@ -11006,8 +10539,7 @@ async fn queue_retrieve_extended(service: Box) { { let retrieve_response = service .exec_query(r#"QUEUE RETRIEVE EXTENDED CONCURRENCY 2 "STANDALONE#queue:2""#) - .await - .unwrap(); + .await?; assert_queue_retrieve_columns(&retrieve_response); assert_eq!( retrieve_response.get_rows(), @@ -11020,18 +10552,17 @@ async fn queue_retrieve_extended(service: Box) { ]),] ); } + Ok(()) } -async fn queue_ack_then_result_v1(service: Box) { +async fn queue_ack_then_result_v1(service: Box) -> Result<(), CubeError> { service .exec_query(r#"QUEUE ADD PRIORITY 1 "STANDALONE#queue:5555" "payload1";"#) - .await - .unwrap(); + .await?; let ack_result = service .exec_query(r#"QUEUE ACK "STANDALONE#queue:5555" "result:5555""#) - .await - .unwrap(); + .await?; assert_eq!( ack_result.get_rows(), &vec![Row::new(vec![TableValue::Boolean(true)])] @@ -11041,8 +10572,7 @@ async fn queue_ack_then_result_v1(service: Box) { { let ack_result = service .exec_query(r#"QUEUE ACK "STANDALONE#queue:5555" "result:5555""#) - .await - .unwrap(); + .await?; assert_eq!( ack_result.get_rows(), &vec![Row::new(vec![TableValue::Boolean(false)])] @@ -11053,8 +10583,7 @@ async fn queue_ack_then_result_v1(service: Box) { { let ack_result = service .exec_query(r#"QUEUE ACK "STANDALONE#queue:123456" "result:5555""#) - .await - .unwrap(); + .await?; assert_eq!( ack_result.get_rows(), &vec![Row::new(vec![TableValue::Boolean(false)])] @@ -11063,8 +10592,7 @@ async fn queue_ack_then_result_v1(service: Box) { let result = service .exec_query(r#"QUEUE RESULT "STANDALONE#queue:5555""#) - .await - .unwrap(); + .await?; assert_eq!( result.get_columns(), @@ -11084,23 +10612,19 @@ async fn queue_ack_then_result_v1(service: Box) { // second call should not return anything, because first call should remove result let result = service .exec_query(r#"QUEUE RESULT "STANDALONE#queue:5555""#) - .await - .unwrap(); + .await?; assert_eq!(result.get_rows().len(), 0); + Ok(()) } -async fn queue_ack_then_result_v2(service: Box) { +async fn queue_ack_then_result_v2(service: Box) -> Result<(), CubeError> { let add_response = service .exec_query(r#"QUEUE ADD PRIORITY 1 "STANDALONE#queue:5555" "payload1";"#) - .await - .unwrap(); + .await?; assert_queue_add_columns(&add_response); - let ack_result = service - .exec_query(r#"QUEUE ACK 1 "result:5555""#) - .await - .unwrap(); + let ack_result = service.exec_query(r#"QUEUE ACK 1 "result:5555""#).await?; assert_eq!( ack_result.get_rows(), &vec![Row::new(vec![TableValue::Boolean(true)])] @@ -11108,10 +10632,7 @@ async fn queue_ack_then_result_v2(service: Box) { // double ack for result, should be restricted { - let ack_result = service - .exec_query(r#"QUEUE ACK 1 "result:5555""#) - .await - .unwrap(); + let ack_result = service.exec_query(r#"QUEUE ACK 1 "result:5555""#).await?; assert_eq!( ack_result.get_rows(), &vec![Row::new(vec![TableValue::Boolean(false)])] @@ -11120,10 +10641,7 @@ async fn queue_ack_then_result_v2(service: Box) { // ack on unknown queue item { - let ack_result = service - .exec_query(r#"QUEUE ACK 10 "result:5555""#) - .await - .unwrap(); + let ack_result = service.exec_query(r#"QUEUE ACK 10 "result:5555""#).await?; assert_eq!( ack_result.get_rows(), &vec![Row::new(vec![TableValue::Boolean(false)])] @@ -11132,8 +10650,7 @@ async fn queue_ack_then_result_v2(service: Box) { let result = service .exec_query(r#"QUEUE RESULT "STANDALONE#queue:5555""#) - .await - .unwrap(); + .await?; assert_eq!( result.get_columns(), @@ -11153,8 +10670,7 @@ async fn queue_ack_then_result_v2(service: Box) { // second call should not return anything, because first call should mark result as ready to delete let result = service .exec_query(r#"QUEUE RESULT "STANDALONE#queue:5555""#) - .await - .unwrap(); + .await?; assert_eq!(result.get_rows().len(), 0); tokio::time::sleep(Duration::new(1, 0)).await; @@ -11162,25 +10678,23 @@ async fn queue_ack_then_result_v2(service: Box) { // should return, because we use id let result = service .exec_query(r#"QUEUE RESULT_BLOCKING 1000 1"#) - .await - .unwrap(); + .await?; assert_queue_result_blocking_columns(&result); assert_eq!(result.get_rows().len(), 1); + Ok(()) } -async fn queue_ack_then_result_v2_with_external_id(service: Box) { +async fn queue_ack_then_result_v2_with_external_id( + service: Box, +) -> Result<(), CubeError> { let add_response = service .exec_query( r#"QUEUE ADD PRIORITY 1 EXTERNAL_ID 'ext-5555' "STANDALONE#queue:5555" "payload1";"#, ) - .await - .unwrap(); + .await?; assert_queue_add_columns(&add_response); - let ack_result = service - .exec_query(r#"QUEUE ACK 1 "result:5555""#) - .await - .unwrap(); + let ack_result = service.exec_query(r#"QUEUE ACK 1 "result:5555""#).await?; assert_eq!( ack_result.get_rows(), &vec![Row::new(vec![TableValue::Boolean(true)])] @@ -11188,10 +10702,7 @@ async fn queue_ack_then_result_v2_with_external_id(service: Box) // double ack for result, should be restricted { - let ack_result = service - .exec_query(r#"QUEUE ACK 1 "result:5555""#) - .await - .unwrap(); + let ack_result = service.exec_query(r#"QUEUE ACK 1 "result:5555""#).await?; assert_eq!( ack_result.get_rows(), &vec![Row::new(vec![TableValue::Boolean(false)])] @@ -11200,10 +10711,7 @@ async fn queue_ack_then_result_v2_with_external_id(service: Box) // ack on unknown queue item { - let ack_result = service - .exec_query(r#"QUEUE ACK 10 "result:5555""#) - .await - .unwrap(); + let ack_result = service.exec_query(r#"QUEUE ACK 10 "result:5555""#).await?; assert_eq!( ack_result.get_rows(), &vec![Row::new(vec![TableValue::Boolean(false)])] @@ -11213,8 +10721,7 @@ async fn queue_ack_then_result_v2_with_external_id(service: Box) // RESULT_BY_EXTERNAL_ID returns result and marks it for deletion let result = service .exec_query(r#"QUEUE RESULT_BY_EXTERNAL_ID "ext-5555""#) - .await - .unwrap(); + .await?; assert_eq!( result.get_columns(), &vec![ @@ -11231,8 +10738,7 @@ async fn queue_ack_then_result_v2_with_external_id(service: Box) ); let result = service .exec_query(r#"QUEUE RESULT_BY_EXTERNAL_ID "ext-5555""#) - .await - .unwrap(); + .await?; assert_eq!( result.get_rows(), &vec![Row::new(vec![ @@ -11244,8 +10750,7 @@ async fn queue_ack_then_result_v2_with_external_id(service: Box) // RESULT by path should also return empty (already marked as deleted) let result = service .exec_query(r#"QUEUE RESULT "STANDALONE#queue:5555""#) - .await - .unwrap(); + .await?; assert_eq!(result.get_rows().len(), 0); tokio::time::sleep(Duration::new(1, 0)).await; @@ -11253,34 +10758,28 @@ async fn queue_ack_then_result_v2_with_external_id(service: Box) // should return, because we use id let result = service .exec_query(r#"QUEUE RESULT_BLOCKING 1000 1"#) - .await - .unwrap(); + .await?; assert_queue_result_blocking_columns(&result); assert_eq!(result.get_rows().len(), 1); + Ok(()) } -async fn queue_orphaned_timeout(service: Box) { +async fn queue_orphaned_timeout(service: Box) -> Result<(), CubeError> { // CI is super slow, sometimes it can takes up to 1 second to bootstrap Cache Store // let's warmup it - service - .exec_query(r#"SYS CACHESTORE HEALTHCHECK;"#) - .await - .unwrap(); + service.exec_query(r#"SYS CACHESTORE HEALTHCHECK;"#).await?; service .exec_query(r#"QUEUE ADD PRIORITY 1 "STANDALONE#queue:queue_key_1" "payload1";"#) - .await - .unwrap(); + .await?; service .exec_query(r#"QUEUE ADD PRIORITY 1 "STANDALONE#queue:queue_key_2" "payload2";"#) - .await - .unwrap(); + .await?; let res = service .exec_query(r#"QUEUE TO_CANCEL 1000 1000 "STANDALONE#queue";"#) - .await - .unwrap(); + .await?; assert_eq!(res.len(), 0); // only active jobs can be orphaned @@ -11288,26 +10787,22 @@ async fn queue_orphaned_timeout(service: Box) { { service .exec_query(r#"QUEUE RETRIEVE CONCURRENCY 2 "STANDALONE#queue:queue_key_1""#) - .await - .unwrap(); + .await?; service .exec_query(r#"QUEUE RETRIEVE CONCURRENCY 2 "STANDALONE#queue:queue_key_2""#) - .await - .unwrap(); + .await?; } tokio::time::sleep(Duration::from_millis(1000)).await; service .exec_query(r#"QUEUE HEARTBEAT "STANDALONE#queue:queue_key_2";"#) - .await - .unwrap(); + .await?; let res = service .exec_query(r#"QUEUE TO_CANCEL 1000 1000 "STANDALONE#queue""#) - .await - .unwrap(); + .await?; assert_eq!( res.get_columns(), &vec![ @@ -11328,78 +10823,71 @@ async fn queue_orphaned_timeout(service: Box) { let res = service .exec_query(r#"QUEUE TO_CANCEL 1000 1000 "STANDALONE#queue""#) - .await - .unwrap(); + .await?; assert_eq!(res.len(), 2); + Ok(()) } -async fn queue_heartbeat_by_path(service: Box) { +async fn queue_heartbeat_by_path(service: Box) -> Result<(), CubeError> { service .exec_query(r#"QUEUE ADD PRIORITY 1 "STANDALONE#queue:1" "payload1";"#) - .await - .unwrap(); + .await?; let res = service .exec_query(r#"SELECT heartbeat FROM system.queue WHERE prefix = 'STANDALONE#queue'"#) - .await - .unwrap(); + .await?; assert_eq!(res.get_rows(), &vec![Row::new(vec![TableValue::Null,]),]); service .exec_query(r#"QUEUE HEARTBEAT "STANDALONE#queue:1";"#) - .await - .unwrap(); + .await?; let res = service .exec_query(r#"SELECT heartbeat FROM system.queue WHERE prefix = 'STANDALONE#queue'"#) - .await - .unwrap(); + .await?; - let row = res.get_rows().first().unwrap(); - match row.values().first().unwrap() { + let row = res.get_rows().first().expect("empty result"); + match row.values().first().expect("empty row") { TableValue::Timestamp(_) => {} other => panic!("heartbeat must be a timestamp type, actual: {:?}", other), } + Ok(()) } -async fn queue_heartbeat_by_id(service: Box) { +async fn queue_heartbeat_by_id(service: Box) -> Result<(), CubeError> { service .exec_query(r#"QUEUE ADD PRIORITY 1 "STANDALONE#queue:1" "payload1";"#) - .await - .unwrap(); + .await?; let res = service .exec_query(r#"SELECT heartbeat FROM system.queue WHERE prefix = 'STANDALONE#queue'"#) - .await - .unwrap(); + .await?; assert_eq!(res.get_rows(), &vec![Row::new(vec![TableValue::Null,]),]); - service.exec_query(r#"QUEUE HEARTBEAT 1;"#).await.unwrap(); + service.exec_query(r#"QUEUE HEARTBEAT 1;"#).await?; let res = service .exec_query(r#"SELECT heartbeat FROM system.queue WHERE prefix = 'STANDALONE#queue'"#) - .await - .unwrap(); + .await?; - let row = res.get_rows().first().unwrap(); - match row.values().first().unwrap() { + let row = res.get_rows().first().expect("empty result"); + match row.values().first().expect("empty row") { TableValue::Timestamp(_) => {} other => panic!("heartbeat must be a timestamp type, actual: {:?}", other), } + Ok(()) } -async fn queue_merge_extra_by_path(service: Box) { +async fn queue_merge_extra_by_path(service: Box) -> Result<(), CubeError> { service .exec_query(r#"QUEUE ADD PRIORITY 1 "STANDALONE#queue:1" "payload1";"#) - .await - .unwrap(); + .await?; // extra must be empty after creation { let res = service .exec_query(r#"QUEUE GET "STANDALONE#queue:1";"#) - .await - .unwrap(); + .await?; assert_eq!( res.get_columns(), &vec![ @@ -11418,15 +10906,13 @@ async fn queue_merge_extra_by_path(service: Box) { service .exec_query(r#"QUEUE MERGE_EXTRA "STANDALONE#queue:1" '{"first": true}';"#) - .await - .unwrap(); + .await?; // extra should contains first field { let res = service .exec_query(r#"QUEUE GET "STANDALONE#queue:1";"#) - .await - .unwrap(); + .await?; assert_eq!( res.get_columns(), &vec![ @@ -11442,17 +10928,17 @@ async fn queue_merge_extra_by_path(service: Box) { ]),] ); } + Ok(()) } -async fn queue_merge_extra_by_id(service: Box) { +async fn queue_merge_extra_by_id(service: Box) -> Result<(), CubeError> { service .exec_query(r#"QUEUE ADD PRIORITY 1 "STANDALONE#queue:1" "payload1";"#) - .await - .unwrap(); + .await?; // extra must be empty after creation { - let res = service.exec_query(r#"QUEUE GET 1;"#).await.unwrap(); + let res = service.exec_query(r#"QUEUE GET 1;"#).await?; assert_eq!( res.get_columns(), &vec![ @@ -11471,12 +10957,11 @@ async fn queue_merge_extra_by_id(service: Box) { service .exec_query(r#"QUEUE MERGE_EXTRA 1 '{"first": true}';"#) - .await - .unwrap(); + .await?; // extra should contains first field { - let res = service.exec_query(r#"QUEUE GET 1;"#).await.unwrap(); + let res = service.exec_query(r#"QUEUE GET 1;"#).await?; assert_eq!( res.get_columns(), &vec![ @@ -11492,13 +10977,13 @@ async fn queue_merge_extra_by_id(service: Box) { ]),] ); } + Ok(()) } -async fn queue_multiple_result_blocking(service: Box) { +async fn queue_multiple_result_blocking(service: Box) -> Result<(), CubeError> { service .exec_query(r#"QUEUE ADD PRIORITY 1 "STANDALONE#queue:12345" "payload1";"#) - .await - .unwrap(); + .await?; let service = Arc::new(service); @@ -11564,27 +11049,25 @@ async fn queue_multiple_result_blocking(service: Box) { ]),] ); } + Ok(()) } -async fn queue_custom_orphaned(service: Box) { +async fn queue_custom_orphaned(service: Box) -> Result<(), CubeError> { service .exec_query(r#"QUEUE ADD PRIORITY 1 "STANDALONE#queue:queue_key_1" "payload1";"#) - .await - .unwrap(); + .await?; service .exec_query( r#"QUEUE ADD PRIORITY 1 ORPHANED 60 "STANDALONE#queue:queue_key_2" "payload1";"#, ) - .await - .unwrap(); + .await?; tokio::time::sleep(Duration::new(1, 0)).await; let res = service .exec_query(r#"QUEUE TO_CANCEL 100 100 "STANDALONE#queue""#) - .await - .unwrap(); + .await?; assert_eq!( res.get_columns(), &vec![ @@ -11600,20 +11083,20 @@ async fn queue_custom_orphaned(service: Box) { TableValue::String("1".to_string()), ]),] ); + Ok(()) } -async fn queue_result_by_external_id(service: Box) { +async fn queue_result_by_external_id(service: Box) -> Result<(), CubeError> { service .exec_query( r#"QUEUE ADD PRIORITY 1 EXTERNAL_ID 'ext-123' "STANDALONE#queue:123456789" "payload123456789";"#, ) .await - .unwrap(); + ?; let ack_result = service .exec_query(r#"QUEUE ACK "STANDALONE#queue:123456789" "result:123456789""#) - .await - .unwrap(); + .await?; assert_eq!( ack_result.get_rows(), &vec![Row::new(vec![TableValue::Boolean(true)])] @@ -11621,14 +11104,12 @@ async fn queue_result_by_external_id(service: Box) { let result = service .exec_query(r#"QUEUE RESULT_BY_EXTERNAL_ID "unknown-ext-id""#) - .await - .unwrap(); + .await?; assert_eq!(result.get_rows().len(), 0); let result = service .exec_query(r#"QUEUE RESULT_BY_EXTERNAL_ID "ext-123""#) - .await - .unwrap(); + .await?; assert_eq!( result.get_columns(), &vec![ @@ -11648,8 +11129,7 @@ async fn queue_result_by_external_id(service: Box) { // Second call should return empty (result deleted after first retrieval) let result = service .exec_query(r#"QUEUE RESULT_BY_EXTERNAL_ID "ext-123""#) - .await - .unwrap(); + .await?; assert_eq!( result.get_rows(), &vec![Row::new(vec![ @@ -11657,38 +11137,34 @@ async fn queue_result_by_external_id(service: Box) { TableValue::String("success".to_string()) ]),] ); + Ok(()) } -async fn sys_cachestore_info(service: Box) { +async fn sys_cachestore_info(service: Box) -> Result<(), CubeError> { service.migration_run_next_query(); - service.exec_query("SYS CACHESTORE INFO").await.unwrap(); + service.exec_query("SYS CACHESTORE INFO").await?; + Ok(()) } -async fn sys_drop_cache(service: Box) { +async fn sys_drop_cache(service: Box) -> Result<(), CubeError> { service.migration_run_next_query(); - service - .exec_query(r#"SYS DROP QUERY CACHE;"#) - .await - .unwrap(); + service.exec_query(r#"SYS DROP QUERY CACHE;"#).await?; service.migration_run_next_query(); - service.exec_query(r#"SYS DROP CACHE;"#).await.unwrap(); + service.exec_query(r#"SYS DROP CACHE;"#).await?; + Ok(()) } -async fn sys_metastore_healthcheck(service: Box) { +async fn sys_metastore_healthcheck(service: Box) -> Result<(), CubeError> { service.migration_run_next_query(); - service - .exec_query(r#"SYS METASTORE HEALTHCHECK;"#) - .await - .unwrap(); + service.exec_query(r#"SYS METASTORE HEALTHCHECK;"#).await?; + Ok(()) } -async fn sys_cachestore_healthcheck(service: Box) { +async fn sys_cachestore_healthcheck(service: Box) -> Result<(), CubeError> { service.migration_run_next_query(); - service - .exec_query(r#"SYS CACHESTORE HEALTHCHECK;"#) - .await - .unwrap(); + service.exec_query(r#"SYS CACHESTORE HEALTHCHECK;"#).await?; + Ok(()) } pub fn to_rows(d: &DataFrame) -> Vec> { diff --git a/rust/cubestore/cubestore-sql-tests/tests/cluster.rs b/rust/cubestore/cubestore-sql-tests/tests/cluster.rs index 072899d81d4d9..f26b91201eb25 100644 --- a/rust/cubestore/cubestore-sql-tests/tests/cluster.rs +++ b/rust/cubestore/cubestore-sql-tests/tests/cluster.rs @@ -82,7 +82,8 @@ impl MultiProcTest for ClusterSqlTest { prefix: "cluster", service: services.sql_service, })) - .await; + .await + .unwrap(); }) .await; } diff --git a/rust/cubestore/cubestore-sql-tests/tests/in_process.rs b/rust/cubestore/cubestore-sql-tests/tests/in_process.rs index 15279db9e74f7..f50500886cbaf 100644 --- a/rust/cubestore/cubestore-sql-tests/tests/in_process.rs +++ b/rust/cubestore/cubestore-sql-tests/tests/in_process.rs @@ -20,7 +20,8 @@ fn main() { prefix, service: services.sql_service, })) - .await; + .await + .unwrap(); })); }); } diff --git a/rust/cubestore/cubestore-sql-tests/tests/migration.rs b/rust/cubestore/cubestore-sql-tests/tests/migration.rs index 42af90162aaf4..090de7630c777 100644 --- a/rust/cubestore/cubestore-sql-tests/tests/migration.rs +++ b/rust/cubestore/cubestore-sql-tests/tests/migration.rs @@ -60,7 +60,9 @@ fn main() { r.block_on(Config::run_migration_test( &test_name, |services| async move { - test_fn(Box::new(FilterWritesSqlClient::new(services.sql_service))).await; + test_fn(Box::new(FilterWritesSqlClient::new(services.sql_service))) + .await + .unwrap(); }, )); }); diff --git a/rust/cubestore/cubestore-sql-tests/tests/multi_process.rs b/rust/cubestore/cubestore-sql-tests/tests/multi_process.rs index 8c4367ca56423..688fdd8b7bc61 100644 --- a/rust/cubestore/cubestore-sql-tests/tests/multi_process.rs +++ b/rust/cubestore/cubestore-sql-tests/tests/multi_process.rs @@ -28,7 +28,8 @@ fn main() { prefix, service: services.sql_service, })) - .await; + .await + .unwrap(); }), ); }); diff --git a/rust/cubestore/cubestore/src/cachestore/queue_result.rs b/rust/cubestore/cubestore/src/cachestore/queue_result.rs index 634283ac539a9..1bb781d67857b 100644 --- a/rust/cubestore/cubestore/src/cachestore/queue_result.rs +++ b/rust/cubestore/cubestore/src/cachestore/queue_result.rs @@ -73,13 +73,18 @@ impl<'a> QueueResultRocksTable<'a> { } pub fn get_row_by_key(&self, key: QueueKey) -> Result>, CubeError> { - match key { + let row = match key { QueueKey::ByPath(path) => { let index_key = QueueResultIndexKey::ByPath(path); - self.get_single_opt_row_by_index_reverse(&index_key, &QueueResultRocksIndex::ByPath) + self.get_single_opt_row_by_index_reverse( + &index_key, + &QueueResultRocksIndex::ByPath, + )? } - QueueKey::ById(id) => self.get_row(id), - } + QueueKey::ById(id) => self.get_row(id)?, + }; + + Ok(row.filter(|r| r.get_row().get_expire() >= &Utc::now())) } pub fn get_row_by_external_id( diff --git a/rust/cubestore/cubestore/src/metastore/rocks_table.rs b/rust/cubestore/cubestore/src/metastore/rocks_table.rs index 0764ff6ffc031..280df9394705f 100644 --- a/rust/cubestore/cubestore/src/metastore/rocks_table.rs +++ b/rust/cubestore/cubestore/src/metastore/rocks_table.rs @@ -813,17 +813,16 @@ pub trait RocksTable: BaseRocksTable + Debug + Send + Sync { ))); } - let id = if let Some(id) = if reverse { + let to_fetch = if reverse { row_ids.last() } else { row_ids.first() - } { - id.clone() - } else { + }; + let Some(id) = to_fetch else { return Ok(None); }; - if let Some(row) = self.get_row(id)? { + if let Some(row) = self.get_row(*id)? { Ok(Some(row)) } else { let index = self.get_index_by_id(BaseRocksSecondaryIndex::get_id(secondary_index));