extern crate firn;
use anyhow::Result;
use firn::{QueryData, SnowflakeApi};
#[tokio::main]
async fn main() -> Result<()> {
let _ = dotenvy::dotenv();
pretty_env_logger::init();
let api = SnowflakeApi::from_env()?;
let baseline = first_string(&api, "SHOW PARAMETERS LIKE 'TIMEZONE' IN SESSION").await?;
println!("baseline TIMEZONE = {baseline}");
let r = api
.query("SELECT CURRENT_TIMESTAMP() AS ts")
.with_session_param("TIMEZONE", "UTC")
.execute()
.await?;
println!(
"with TIMEZONE=UTC override -> ts row count = {}",
r.metadata.total_rows.unwrap_or(0)
);
let after = first_string(&api, "SHOW PARAMETERS LIKE 'TIMEZONE' IN SESSION").await?;
println!("post-query TIMEZONE = {after}");
if after == baseline {
println!("\nOK: session parameter did not leak.");
} else {
println!(
"\nLEAK: session parameter changed from {baseline} to {after}; \
expected request-scoped behavior"
);
}
let _ = api
.query("SELECT CURRENT_TIMESTAMP() AS ts")
.with_session_params([
("TIMEZONE", "Europe/Berlin"),
("QUERY_TAG", "snowflake-rs:session_params example"),
])
.execute()
.await?;
println!("ran query with TIMEZONE=Europe/Berlin + QUERY_TAG override");
Ok(())
}
async fn first_string(api: &SnowflakeApi, sql: &str) -> Result<String> {
let r = api.query(sql).execute().await?;
match r.data {
QueryData::Json(j) => {
let v = j
.value
.as_array()
.and_then(|rows| rows.first())
.and_then(|row| row.as_array())
.and_then(|cols| cols.get(1))
.and_then(|c| c.as_str())
.unwrap_or("(missing)");
Ok(v.to_owned())
}
QueryData::Arrow(_) | QueryData::Empty => Ok("(non-json)".to_owned()),
}
}