polyglot_sql/optimizer/
mod.rs1pub mod annotate_types;
8pub mod canonicalize;
10pub mod eliminate_ctes;
12pub mod eliminate_joins;
14pub mod isolate_table_selects;
16pub mod normalize;
18pub mod normalize_identifiers;
20pub mod optimize_joins;
22pub mod optimizer;
24pub mod pushdown_predicates;
26pub mod pushdown_projections;
28pub mod qualify_columns;
30pub mod qualify_tables;
32pub mod simplify;
34pub mod subquery;
36
37pub use annotate_types::{annotate_types, TypeAnnotator, TypeCoercionClass};
39pub use canonicalize::canonicalize;
41pub use eliminate_ctes::{eliminate_ctes, is_cte_referenced};
43pub use eliminate_joins::eliminate_joins;
45pub use isolate_table_selects::isolate_table_selects;
47pub use normalize::{
49 normalization_distance, normalize, normalized, NormalizeError, DEFAULT_MAX_DISTANCE,
50};
51pub use normalize_identifiers::{
53 get_normalization_strategy, is_case_sensitive, normalize_identifier, normalize_identifiers,
54 NormalizationStrategy,
55};
56pub use optimize_joins::{is_reorderable, normalize_joins, optimize_joins, reorder_joins};
58pub use optimizer::{
60 optimize, optimize_with_rules, quick_optimize, OptimizationRule, OptimizerConfig, DEFAULT_RULES,
61};
62pub use pushdown_predicates::{pushdown_predicates, replace_aliases};
64pub use pushdown_projections::{default_selection, pushdown_projections};
66pub use qualify_columns::{
68 qualify_columns, qualify_outputs, quote_identifiers, validate_qualify_columns,
69 QualifyColumnsError, QualifyColumnsOptions,
70};
71pub use qualify_tables::{qualify_tables, QualifyTablesOptions};
73pub use simplify::{always_false, always_true, is_false, is_null, is_zero, simplify, Simplifier};
75pub use subquery::{is_correlated, is_mergeable, merge_subqueries, unnest_subqueries};
77
78fn structural_identity_key(expr: &crate::expressions::Expression) -> String {
81 fn remove_spans(value: &mut serde_json::Value) {
82 match value {
83 serde_json::Value::Object(fields) => {
84 fields.remove("span");
85 for value in fields.values_mut() {
86 remove_spans(value);
87 }
88 }
89 serde_json::Value::Array(values) => {
90 for value in values {
91 remove_spans(value);
92 }
93 }
94 _ => {}
95 }
96 }
97 let mut value = serde_json::to_value(expr).expect("expression serializes");
98 remove_spans(&mut value);
99 value.to_string()
100}
101
102pub(crate) fn qualify_schema_aware_expression(
108 expression: crate::expressions::Expression,
109 schema: &dyn crate::schema::Schema,
110 dialect: Option<crate::dialects::DialectType>,
111) -> Result<crate::expressions::Expression, QualifyColumnsError> {
112 let effective_dialect = dialect.or_else(|| schema.dialect());
113 let mut table_options = QualifyTablesOptions::new()
114 .with_alias_unaliased_tables(false)
115 .with_alias_unaliased_subqueries(true)
116 .with_normalize_set_operation_subqueries(false);
117 let mut column_options = QualifyColumnsOptions::new().with_allow_partial(true);
118
119 if let Some(dialect) = effective_dialect {
120 table_options = table_options.with_dialect(dialect);
121 column_options = column_options.with_dialect(dialect);
122 }
123
124 let expression = qualify_tables(expression, &table_options);
125 qualify_columns(expression, schema, &column_options)
126}