use super::super::PhysicalPlan;
use crate::{plan_vector_search, OptimizerContext};
use hawdb_plan_cypher::{LogicalPlan, VectorCandidateSource, VectorSearchLogicalPlan};
pub(super) fn lower(
logical: &LogicalPlan,
optimizer_context: &OptimizerContext,
) -> Option<PhysicalPlan> {
match logical {
LogicalPlan::ProjectGraph {
name,
node_labels,
rel_types,
relationship_predicates,
} => Some(PhysicalPlan::ProjectGraph {
name: name.clone(),
node_labels: node_labels.clone(),
rel_types: rel_types.clone(),
relationship_predicates: relationship_predicates.clone(),
}),
LogicalPlan::GraphAlgorithmOutput(output) => {
Some(PhysicalPlan::GraphAlgorithmOutput(output.clone()))
}
LogicalPlan::GraphAlgorithm {
algorithm,
graph_name,
options,
score_column,
return_node_identity,
node_visibility_predicate,
} => Some(PhysicalPlan::GraphAlgorithm {
algorithm: *algorithm,
graph_name: graph_name.clone(),
options: *options,
score_column: score_column.clone(),
return_node_identity: *return_node_identity,
node_visibility_predicate: node_visibility_predicate.clone(),
}),
LogicalPlan::GraphSeed {
query_parameter,
label,
variable,
score_column,
top_k,
node_visibility_predicate,
} => Some(PhysicalPlan::GraphSeedScan {
query_parameter: query_parameter.clone(),
label: label.clone(),
variable: variable.clone(),
score_column: score_column.clone(),
top_k: *top_k,
node_visibility_predicate: node_visibility_predicate.clone(),
}),
LogicalPlan::TextSeed {
query_parameter,
top_k,
complete,
output_external_id,
} => {
let hints = optimizer_context.resource_hints();
Some(PhysicalPlan::TextSeedScan {
query_parameter: query_parameter.clone(),
top_k: *top_k,
complete: *complete,
output_external_id: *output_external_id,
metadata_filters: Default::default(),
resource_profile: hawdb_plan_cypher::VectorExecutionResourceProfile {
priority: hints.priority,
max_parallelism: hints.max_parallelism.max(1),
max_working_memory_bytes: hints.max_memory_bytes,
},
})
}
LogicalPlan::VectorSeed {
embedding_parameter,
embedding_dimension,
top_k,
output_external_id,
} => {
let logical = VectorSearchLogicalPlan {
embedding_dimension: *embedding_dimension,
filter_fields: Vec::new(),
residual_filter_fields: Vec::new(),
initial_candidate_limit: *top_k,
candidate_source: VectorCandidateSource::Scalar,
candidate_limit: *top_k,
top_k: *top_k,
};
let planned = plan_vector_search(&logical, optimizer_context).ok()?;
Some(PhysicalPlan::VectorSeedScan {
embedding_parameter: embedding_parameter.clone(),
output_external_id: *output_external_id,
metadata_filters: Default::default(),
resource_profile: planned.properties.execution_resource_profile(),
vector_plan: planned.plan,
})
}
LogicalPlan::ThreadRepairStats {
label,
identity_label,
identity_ref_property,
thread_id_property,
message_rel_type,
message_label,
memory_rel_type,
memory_label,
} => Some(PhysicalPlan::ThreadRepairStatsExec {
label: label.clone(),
identity_label: identity_label.clone(),
identity_ref_property: identity_ref_property.clone(),
thread_id_property: thread_id_property.clone(),
message_rel_type: message_rel_type.clone(),
message_label: message_label.clone(),
memory_rel_type: memory_rel_type.clone(),
memory_label: memory_label.clone(),
}),
_ => None,
}
}