|
1 | 1 | use crate::utils::{create_new_session_builder, setup_tracing, unique_keyspace_name, PerformDDL};
|
| 2 | +use assert_matches::assert_matches; |
| 3 | +use scylla::errors::BadQuery; |
| 4 | +use scylla::errors::ExecutionError; |
| 5 | +use scylla::serialize::value::SerializeValue; |
2 | 6 | use scylla::{
|
3 | 7 | batch::{Batch, BatchType},
|
4 | 8 | query::Query,
|
5 | 9 | response::PagingState,
|
| 10 | + serialize, |
6 | 11 | statement::SerialConsistency,
|
7 | 12 | };
|
8 | 13 | use scylla_cql::Consistency;
|
| 14 | +use std::collections::BTreeMap; |
| 15 | +use std::collections::HashMap; |
9 | 16 | use std::collections::HashSet;
|
10 | 17 | use std::sync::{Arc, Mutex};
|
11 | 18 |
|
@@ -306,3 +313,149 @@ async fn test_timestamp_generator() {
|
306 | 313 | .map(|row_result| row_result.unwrap())
|
307 | 314 | .all(|(_a, _b, writetime)| timestamps_locked.contains(&writetime)));
|
308 | 315 | }
|
| 316 | + |
| 317 | +#[tokio::test] |
| 318 | +async fn test_named_bind_markers() { |
| 319 | + let session = create_new_session_builder().build().await.unwrap(); |
| 320 | + let ks = unique_keyspace_name(); |
| 321 | + |
| 322 | + session |
| 323 | + .ddl(format!("CREATE KEYSPACE {} WITH REPLICATION = {{'class' : 'NetworkTopologyStrategy', 'replication_factor' : 1}}", ks)) |
| 324 | + .await |
| 325 | + .unwrap(); |
| 326 | + |
| 327 | + session.use_keyspace(ks, false).await.unwrap(); |
| 328 | + |
| 329 | + session |
| 330 | + .ddl("CREATE TABLE t (pk int, ck int, v int, PRIMARY KEY (pk, ck, v))") |
| 331 | + .await |
| 332 | + .unwrap(); |
| 333 | + |
| 334 | + let prepared = session |
| 335 | + .prepare("INSERT INTO t (pk, ck, v) VALUES (:pk, :ck, :v)") |
| 336 | + .await |
| 337 | + .unwrap(); |
| 338 | + let hashmap: HashMap<&str, i32> = HashMap::from([("pk", 7), ("v", 42), ("ck", 13)]); |
| 339 | + session.execute_unpaged(&prepared, &hashmap).await.unwrap(); |
| 340 | + |
| 341 | + let btreemap: BTreeMap<&str, i32> = BTreeMap::from([("ck", 113), ("v", 142), ("pk", 17)]); |
| 342 | + session.execute_unpaged(&prepared, &btreemap).await.unwrap(); |
| 343 | + |
| 344 | + let rows: Vec<(i32, i32, i32)> = session |
| 345 | + .query_unpaged("SELECT pk, ck, v FROM t", &[]) |
| 346 | + .await |
| 347 | + .unwrap() |
| 348 | + .into_rows_result() |
| 349 | + .unwrap() |
| 350 | + .rows::<(i32, i32, i32)>() |
| 351 | + .unwrap() |
| 352 | + .collect::<Result<_, _>>() |
| 353 | + .unwrap(); |
| 354 | + |
| 355 | + assert_eq!(rows, vec![(7, 13, 42), (17, 113, 142)]); |
| 356 | + |
| 357 | + let wrongmaps = [ |
| 358 | + HashMap::from([("v", 7), ("fefe", 42), ("ck", 13)]), |
| 359 | + HashMap::from([("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", 7)]), |
| 360 | + HashMap::new(), |
| 361 | + HashMap::from([("ck", 9)]), |
| 362 | + ]; |
| 363 | + for wrongmap in wrongmaps { |
| 364 | + let result = session.execute_unpaged(&prepared, &wrongmap).await; |
| 365 | + let Err(ExecutionError::BadQuery(BadQuery::SerializationError(e))) = result else { |
| 366 | + panic!("Expected ValueMissingForColumn error"); |
| 367 | + }; |
| 368 | + assert_matches!(&e |
| 369 | + .downcast_ref::<serialize::row::BuiltinTypeCheckError>() |
| 370 | + .unwrap() |
| 371 | + .kind, |
| 372 | + serialize::row::BuiltinTypeCheckErrorKind::ValueMissingForColumn { name } |
| 373 | + if name == "pk"); |
| 374 | + } |
| 375 | +} |
| 376 | + |
| 377 | +#[tokio::test] |
| 378 | +async fn test_unusual_valuelists() { |
| 379 | + setup_tracing(); |
| 380 | + |
| 381 | + let session = create_new_session_builder().build().await.unwrap(); |
| 382 | + let ks = unique_keyspace_name(); |
| 383 | + |
| 384 | + session.ddl(format!("CREATE KEYSPACE IF NOT EXISTS {} WITH REPLICATION = {{'class' : 'NetworkTopologyStrategy', 'replication_factor' : 1}}", ks)).await.unwrap(); |
| 385 | + session.use_keyspace(ks, false).await.unwrap(); |
| 386 | + |
| 387 | + session |
| 388 | + .ddl("CREATE TABLE IF NOT EXISTS tab (a int, b int, c varchar, primary key (a, b, c))") |
| 389 | + .await |
| 390 | + .unwrap(); |
| 391 | + |
| 392 | + let insert_a_b_c = session |
| 393 | + .prepare("INSERT INTO tab (a, b, c) VALUES (?, ?, ?)") |
| 394 | + .await |
| 395 | + .unwrap(); |
| 396 | + |
| 397 | + let values_dyn: Vec<&dyn SerializeValue> = vec![ |
| 398 | + &1 as &dyn SerializeValue, |
| 399 | + &2 as &dyn SerializeValue, |
| 400 | + &"&dyn" as &dyn SerializeValue, |
| 401 | + ]; |
| 402 | + session |
| 403 | + .execute_unpaged(&insert_a_b_c, values_dyn) |
| 404 | + .await |
| 405 | + .unwrap(); |
| 406 | + |
| 407 | + let values_box_dyn: Vec<Box<dyn SerializeValue>> = vec![ |
| 408 | + Box::new(1) as Box<dyn SerializeValue>, |
| 409 | + Box::new(3) as Box<dyn SerializeValue>, |
| 410 | + Box::new("Box dyn") as Box<dyn SerializeValue>, |
| 411 | + ]; |
| 412 | + session |
| 413 | + .execute_unpaged(&insert_a_b_c, values_box_dyn) |
| 414 | + .await |
| 415 | + .unwrap(); |
| 416 | + |
| 417 | + session |
| 418 | + .execute_unpaged( |
| 419 | + &insert_a_b_c, |
| 420 | + ( |
| 421 | + Box::new(1) as Box<dyn SerializeValue>, |
| 422 | + &2 as &dyn SerializeValue, |
| 423 | + &"Box,&dyn" as &dyn SerializeValue, |
| 424 | + ), |
| 425 | + ) |
| 426 | + .await |
| 427 | + .unwrap(); |
| 428 | + |
| 429 | + session |
| 430 | + .execute_unpaged( |
| 431 | + &insert_a_b_c, |
| 432 | + ( |
| 433 | + &2 as &dyn SerializeValue, |
| 434 | + Box::new(1) as Box<dyn SerializeValue>, |
| 435 | + &"&dyn,Box" as &dyn SerializeValue, |
| 436 | + ), |
| 437 | + ) |
| 438 | + .await |
| 439 | + .unwrap(); |
| 440 | + |
| 441 | + let mut all_rows: Vec<(i32, i32, String)> = session |
| 442 | + .query_unpaged("SELECT a, b, c FROM tab", ()) |
| 443 | + .await |
| 444 | + .unwrap() |
| 445 | + .into_rows_result() |
| 446 | + .unwrap() |
| 447 | + .rows::<(i32, i32, String)>() |
| 448 | + .unwrap() |
| 449 | + .map(|r| r.unwrap()) |
| 450 | + .collect(); |
| 451 | + all_rows.sort_unstable(); |
| 452 | + assert_eq!( |
| 453 | + all_rows, |
| 454 | + vec![ |
| 455 | + (1i32, 2i32, "&dyn".to_owned()), |
| 456 | + (1, 2i32, "Box,&dyn".to_owned()), |
| 457 | + (1, 3, "Box dyn".to_owned()), |
| 458 | + (2i32, 1, "&dyn,Box".to_owned()) |
| 459 | + ] |
| 460 | + ); |
| 461 | +} |
0 commit comments