use uqa_execution::RowSchema;
use uqa_planner::{QueryPlan, SourcePlan, TableFunctionPlan};
use uqa_sql::ast::{JoinKind, JoinUsing};
use uqa_sql::{SQLError, SQLParam};
use super::{analysis, projection::rename_schema, CteScope, ScalarExpr, SchemaScope};
use crate::engine_user_functions::RoutineResolution;
pub(super) fn alias_table_schema(
schema: &RowSchema,
qualifier: &str,
column_aliases: &[String],
) -> Result<RowSchema, SQLError> {
if column_aliases.len() > schema.len() {
return Err(SQLError::Routine {
sqlstate: "42P10".into(),
message: format!(
"table \"{qualifier}\" has {} columns available but {} columns specified",
schema.len(),
column_aliases.len()
),
});
}
Ok(rename_schema(schema, column_aliases, Some(qualifier)))
}
pub(super) struct JoinSchemaBinding<'a> {
pub(super) routines: &'a dyn RoutineResolution,
pub(super) kind: JoinKind,
pub(super) on: Option<&'a ScalarExpr>,
pub(super) using: Option<&'a JoinUsing>,
pub(super) natural: bool,
pub(super) alias: Option<&'a str>,
pub(super) column_aliases: &'a [String],
pub(super) left: &'a RowSchema,
pub(super) right: &'a RowSchema,
pub(super) subqueries: &'a [QueryPlan],
pub(super) params: &'a [SQLParam],
pub(super) outer: Option<&'a RowSchema>,
}
pub(super) fn table_function_member_source(function: &TableFunctionPlan) -> SourcePlan {
SourcePlan::Function {
name: function.name.clone(),
binding: function.binding.clone(),
output_name: function.output_name.clone(),
relations: function.relations.clone(),
args: function.args.clone(),
alias: None,
column_aliases: function.column_aliases.clone(),
ordinality: false,
column_types: function.column_types.clone(),
}
}
pub(in crate::sql) fn bind_source_plan_schema(
routines: &dyn RoutineResolution,
source: &SourcePlan,
params: &[SQLParam],
ctes: &CteScope,
outer: Option<&RowSchema>,
) -> Result<RowSchema, SQLError> {
SchemaScope::from_execution_scope(ctes)?.bind_source(
routines,
source,
&ctes.scalar_subqueries,
params,
outer,
)
}
pub(in crate::sql) fn with_query_table_pseudo_columns(schema: &RowSchema) -> RowSchema {
analysis::with_unqualified_table_pseudo_columns(schema)
}
pub(in crate::sql) fn analyze_source_plan_schema(
routines: &dyn RoutineResolution,
source: &SourcePlan,
params: &[SQLParam],
ctes: &CteScope,
outer: Option<&RowSchema>,
) -> Result<RowSchema, SQLError> {
SchemaScope::for_analysis(ctes)?.bind_source(
routines,
source,
&ctes.scalar_subqueries,
params,
outer,
)
}
pub(in crate::sql) fn bind_source_plan_schema_for_execution(
routines: &dyn RoutineResolution,
source: &mut SourcePlan,
params: &[SQLParam],
ctes: &CteScope,
outer: Option<&RowSchema>,
) -> Result<RowSchema, SQLError> {
SchemaScope::from_execution_scope(ctes)?.bind_source_for_execution(
routines,
source,
&ctes.scalar_subqueries,
params,
outer,
)
}