use super::{choose_custom_plan, specialize_parameters, PreparedPlanUsage};
use uqa_core::Value;
use uqa_sql::{ColumnType, SQLParam, ScalarExpr};
#[test]
fn integer_parameter_order_keys_are_values_not_output_positions() {
let output = vec![("v".into(), ScalarExpr::Column("v".into()))];
for value in [0, 1, 2, -1, i64::MAX] {
let mut plan = crate::UnifiedPlan::lower(
uqa_sql::compile("SELECT v FROM t ORDER BY $1, v")
.unwrap()
.remove(0),
);
specialize_parameters(&mut plan, &[SQLParam::Scalar(Value::Int(value))]);
let crate::UnifiedPlan::Query(query) = plan else {
panic!("query expected")
};
let crate::RelationalPlan::QueryBlock(block) = query.root else {
panic!("query block expected")
};
let key = uqa_execution::query::ordering::resolve_order_expression(
&block.order_by[0].expr,
&output,
)
.unwrap();
assert_eq!(
uqa_execution::scalar::eval_constant_scalar(&key).unwrap(),
Value::Int(value)
);
}
}
#[test]
fn custom_plan_selection_respects_parameterless_queries_sampling_and_cost_ties() {
let usage = PreparedPlanUsage {
has_parameters: true,
custom_plans: 4,
total_custom_cost: 40.0,
};
assert!(choose_custom_plan(usage, "auto", Some(0.0)));
assert!(!choose_custom_plan(
usage,
"force_generic_plan",
Some(100.0)
));
assert!(choose_custom_plan(usage, "force_custom_plan", None));
let sampled = PreparedPlanUsage {
custom_plans: 5,
total_custom_cost: 50.0,
..usage
};
assert!(!choose_custom_plan(sampled, "auto", None));
assert!(!choose_custom_plan(sampled, "auto", Some(9.0)));
assert!(choose_custom_plan(sampled, "auto", Some(10.0)));
for mode in ["auto", "force_generic_plan", "force_custom_plan"] {
assert!(!choose_custom_plan(
PreparedPlanUsage {
has_parameters: false,
..usage
},
mode,
Some(100.0)
));
}
}
#[test]
fn specialization_preserves_bound_domain_and_parameter_provenance() {
let domain = ColumnType::Domain {
schema: "public".into(),
name: "positive".into(),
oid: 90_001,
array_oid: None,
base: Box::new(ColumnType::Integer),
};
let mut plan =
crate::UnifiedPlan::lower(uqa_sql::compile("SELECT $1, $2, $3, $4").unwrap().remove(0));
specialize_parameters(
&mut plan,
&[
SQLParam::typed_scalar(Value::Int(7), domain.clone()),
SQLParam::Scalar(Value::Null),
SQLParam::Vector(vec![1.0, 2.0]),
],
);
let mut expressions = Vec::new();
plan.rewrite_scalar_expressions(&mut |expression| expressions.push(expression.clone()));
assert!(expressions.iter().any(|expression| matches!(expression, ScalarExpr::TypedLiteral { value: Value::Int(7), bound_type: Some(ty), parameter_index: Some(1), .. } if ty == &domain)));
assert!(expressions
.iter()
.any(|expression| matches!(expression, ScalarExpr::Literal(Value::Null))));
assert!(expressions
.iter()
.any(|expression| matches!(expression, ScalarExpr::Param(3))));
assert!(expressions
.iter()
.any(|expression| matches!(expression, ScalarExpr::Param(4))));
assert!(!expressions
.iter()
.any(|expression| matches!(expression, ScalarExpr::Param(1 | 2))));
}