use spark_connect::column::{col, lit};
use spark_connect::dataframe::DataFrame;
use spark_connect::functions as f;
use spark_connect::plan::JoinType;
use spark_connect::session::SparkSession;
use spark_connect::types::DataType;
fn should_run() -> bool {
std::env::var("SPARK_REMOTE").is_ok()
}
fn session() -> SparkSession {
let url = std::env::var("SPARK_REMOTE").unwrap_or_else(|_| "sc://localhost:15002".to_string());
SparkSession::builder()
.remote(&url)
.get_or_create()
.expect("session")
}
fn base(s: &SparkSession) -> DataFrame {
s.sql("SELECT * FROM VALUES (1,'a',1.0),(2,'b',2.0),(2,'b',2.0),(3,'c',3.0) AS t(id, name, v)")
.expect("base df")
}
fn expr(c: spark_connect::column::Column) -> spark_connect::expression::Expression {
c.expression().clone()
}
#[test]
fn transforms_execute() {
if !should_run() {
return;
}
let s = session();
let df = base(&s);
assert_eq!(df.select(vec![col("id")]).count().unwrap(), 4);
let _ = df.select_expr(vec!["id + 1 AS x"]).collect().unwrap();
let _ = df.filter(col("id").gt(lit(1))).collect().unwrap();
let _ = df.where_(col("id").gt(lit(1))).collect().unwrap();
let _ = df.with_column("y", lit(1)).collect().unwrap();
let _ = df
.with_columns(vec![("p".to_string(), lit(1)), ("q".to_string(), lit(2))])
.collect()
.unwrap();
let _ = df.with_column_renamed("name", "nm").collect().unwrap();
let _ = df
.with_columns_renamed(vec![("v".to_string(), "val".to_string())])
.collect()
.unwrap();
let _ = df.drop(vec!["name"]).collect().unwrap();
let _ = df.limit(2).collect().unwrap();
let _ = df.offset(1).collect().unwrap();
let _ = df.tail(2).collect().unwrap();
let _ = df.distinct().collect().unwrap();
let _ = df.drop_duplicates(None).collect().unwrap();
let _ = df.drop_duplicates(Some(vec!["id"])).collect().unwrap();
let _ = df.sort(vec![expr(col("id"))]).collect().unwrap();
let _ = df.order_by(vec![expr(col("id"))]).collect().unwrap();
let _ = df
.sort_within_partitions(vec![expr(col("id"))])
.collect()
.unwrap();
let _ = df.repartition(3).collect().unwrap();
let _ = df.coalesce(1).collect().unwrap();
let _ = df
.repartition_by_range(2, vec![expr(col("id"))])
.collect()
.unwrap();
let _ = df.repartition_by_id(2, col("id")).collect().unwrap();
let _ = df
.hint("broadcast", Vec::<String>::new())
.collect()
.unwrap();
let _ = df.broadcast().collect().unwrap();
let _ = df.to_df(vec!["a", "b", "c"]).collect().unwrap();
let _ = df.alias("t2").collect().unwrap();
let _ = df.sample(0.9, Some(7)).collect().unwrap();
}
#[test]
fn joins_and_setops_execute() {
if !should_run() {
return;
}
let s = session();
let df = base(&s);
let other = s
.sql("SELECT * FROM VALUES (2,'b',2.0),(9,'z',9.0) AS t(id, name, v)")
.unwrap();
let right = s
.sql("SELECT * FROM VALUES (1,10),(2,20) AS t(rid, w)")
.unwrap();
for jt in [
JoinType::Inner,
JoinType::LeftOuter,
JoinType::RightOuter,
JoinType::FullOuter,
JoinType::LeftSemi,
JoinType::LeftAnti,
] {
let _ = df
.join(&right, Some(col("id").eq(col("rid"))), jt)
.collect();
}
let _ = df
.join_using(&other, vec!["id".to_string()], JoinType::Inner)
.collect()
.unwrap();
let _ = df.cross_join(&right).collect().unwrap();
let _ = df.union(&other).collect().unwrap();
let _ = df.union_all(&other).collect().unwrap();
let _ = df.union_by_name(&other).collect().unwrap();
let _ = df.union_by_name_opt(&other, true).collect().unwrap();
let _ = df.intersect(&other).collect().unwrap();
let _ = df.intersect_all(&other).collect().unwrap();
let _ = df.subtract(&other).collect().unwrap();
let _ = df.except_all(&other).collect().unwrap();
}
#[test]
fn aggregates_execute() {
if !should_run() {
return;
}
let s = session();
let df = base(&s);
let _ = df
.group_by(vec![col("id")])
.agg(vec![expr(f::sum(col("v")))])
.collect()
.unwrap();
let _ = df.group_by(vec![col("id")]).count().collect().unwrap();
let _ = df
.group_by(vec![col("id")])
.sum(vec!["v"])
.collect()
.unwrap();
let _ = df
.group_by(vec![col("id")])
.avg(vec!["v"])
.collect()
.unwrap();
let _ = df
.group_by(vec![col("id")])
.min(vec!["v"])
.collect()
.unwrap();
let _ = df
.group_by(vec![col("id")])
.max(vec!["v"])
.collect()
.unwrap();
let _ = df
.group_by(vec![col("id")])
.mean(vec!["v"])
.collect()
.unwrap();
let _ = df.rollup(vec![col("id")]).count().collect().unwrap();
let _ = df.cube(vec![col("id")]).count().collect().unwrap();
let _ = df
.group_by(vec![col("id")])
.pivot(col("name"), None)
.agg(vec![expr(f::sum(col("v")))])
.collect();
let _ = df.agg(vec![expr(f::sum(col("v")))]).collect().unwrap();
let _ = df.observe("obs", vec![expr(f::sum(col("v")))]).collect();
}
#[test]
fn na_reshape_execute() {
if !should_run() {
return;
}
let s = session();
let df = base(&s);
let _ = df.fillna(0, Some(vec!["id"])).collect().unwrap();
let _ = df.fillna_double(0.0, Some(vec!["v"])).collect().unwrap();
let _ = df.fillna_string("x", Some(vec!["name"])).collect().unwrap();
let _ = df.dropna(Some("any"), None, None).collect().unwrap();
let _ = df
.replace(vec![("a".to_string(), "A".to_string())], Some(vec!["name"]))
.collect()
.unwrap();
let _ = df.describe(vec!["id", "v"]).collect().unwrap();
let _ = df.summary(vec!["count", "mean"]).collect().unwrap();
let _ = df
.melt(vec!["id"], Some(vec!["v"]), "var", "val")
.collect()
.unwrap();
let _ = df
.unpivot(vec![col("id")], Some(vec![col("v")]), "var", "val")
.collect()
.unwrap();
let _ = df.select(vec![col("id"), col("v")]).transpose();
let _ = df
.to(DataType::from_ddl("id INT, name STRING, v DOUBLE").unwrap())
.collect();
}
#[test]
fn sources_and_accessors_execute() {
if !should_run() {
return;
}
let s = session();
let df = base(&s);
assert!(s.range(5).unwrap().count().unwrap() >= 0);
assert!(s.range_full(0, 6, 2, None).unwrap().count().unwrap() >= 0);
let _ = df.schema().unwrap();
let _ = df.columns().unwrap();
let _ = df.dtypes().unwrap();
let _ = df.is_empty().unwrap();
let _ = df.first().unwrap();
let _ = df.head().unwrap();
let _ = df.take(2).unwrap();
let _ = df.to_json().unwrap();
let _ = df.select(vec![col("id")]).limit(1).scalar();
let _ = df.semantic_hash();
let _ = df.same_semantics(&df);
let _ = df.to_local_iterator(false);
let _ = df.collect_record_batches();
}