aliases are normalized and used in normalized state, but nonnormalized aliases contain everything

This commit is contained in:
Filipriec
2026-08-25 10:22:27 +02:00
parent 2e1b213137
commit e6840f6d9b
19 changed files with 198 additions and 34 deletions

View File

@@ -4,6 +4,7 @@ use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::path::Path;
use std::sync::{Arc, Mutex};
use common::alias::canonical_alias;
use common::proto::komp_ac::search::searcher_server::Searcher;
pub use common::proto::komp_ac::search::searcher_server::SearcherServer;
use common::proto::komp_ac::search::{
@@ -951,7 +952,7 @@ async fn resolve_constraint_targets(
let rows = if let Some(table_name) = table_filter {
sqlx::query(
r#"
SELECT td.table_name, tdc.physical_name, tdc.field_type
SELECT td.table_name, tdc.display_name, tdc.physical_name, tdc.field_type
FROM schemas s
JOIN table_definitions td ON td.schema_id = s.id
JOIN table_definition_columns tdc ON tdc.table_definition_id = td.id
@@ -965,35 +966,42 @@ async fn resolve_constraint_targets(
ORDER BY visible.is_global ASC
LIMIT 1
)
AND tdc.display_name = $3
"#,
)
.bind(profile_name)
.bind(table_name)
.bind(column)
.fetch_all(pool)
.await
} else {
sqlx::query(
r#"
SELECT td.table_name, tdc.physical_name, tdc.field_type
SELECT td.table_name, tdc.display_name, tdc.physical_name, tdc.field_type
FROM schemas s
JOIN table_definitions td ON td.schema_id = s.id
JOIN table_definition_columns tdc ON tdc.table_definition_id = td.id
WHERE (s.name = $1 OR td.is_global = TRUE)
AND td.deleted = FALSE
AND tdc.display_name = $2
"#,
)
.bind(profile_name)
.bind(column)
.fetch_all(pool)
.await
}
.map_err(|e| Status::internal(format!("Column mapping lookup failed: {}", e)))?;
let rows = if rows.is_empty() {
let Some(field_type) = public_search_system_type(column) else {
let requested_key = canonical_alias(column);
let mut matching_rows = Vec::new();
for row in rows {
let display_name: String = row
.try_get("display_name")
.map_err(|e| Status::internal(format!("Column mapping alias read failed: {e}")))?;
if canonical_alias(&display_name) == requested_key {
matching_rows.push(row);
}
}
let rows = if matching_rows.is_empty() {
let Some(field_type) = public_search_system_type(&requested_key) else {
return Err(Status::invalid_argument(format!(
"Column alias '{}' was not found{}",
column,
@@ -1028,12 +1036,12 @@ async fn resolve_constraint_targets(
.into_iter()
.map(|table_name| SearchConstraintTarget {
table_name: table_filter.is_none().then_some(table_name),
column: column.to_string(),
column: requested_key.clone(),
query: query.clone(),
})
.collect());
} else {
rows
matching_rows
};
let mut seen = HashSet::new();
@@ -1239,13 +1247,14 @@ async fn resolve_order_column(
table_name: &str,
requested_column: &str,
) -> Result<ResolvedOrderColumn, Status> {
if requested_column.eq_ignore_ascii_case("position") {
let requested_key = canonical_alias(requested_column);
if requested_key == "position" {
return Ok(ResolvedOrderColumn::Position);
}
// Sorting by "the display column" means the first one: it is the part
// callers read left to right. A table with none sorts by id instead.
let requested_column = if requested_column.eq_ignore_ascii_case("row_display_columns") {
let requested_column = if requested_key == "row_display_columns" {
table_row_display_columns(pool, profile_name, table_name)
.await?
.into_iter()
@@ -1254,17 +1263,18 @@ async fn resolve_order_column(
} else {
requested_column.to_string()
};
let requested_key = canonical_alias(&requested_column);
let physical_to_display =
table_physical_to_display_map(pool, profile_name, table_name).await?;
let physical_column = physical_to_display
.iter()
.find(|(_, display)| display.eq_ignore_ascii_case(&requested_column))
.find(|(_, display)| canonical_alias(display) == requested_key)
.map(|(physical, _)| physical.clone())
.or_else(|| {
(is_system_column(&requested_column)
&& !is_internal_column(&requested_column)
&& !physical_to_display.contains_key(&requested_column))
.then(|| requested_column.clone())
(is_system_column(&requested_key)
&& !is_internal_column(&requested_key)
&& !physical_to_display.contains_key(&requested_key))
.then(|| requested_key.clone())
})
.ok_or_else(|| {
Status::invalid_argument(format!(