Skip to content

Commit f1521ae

Browse files
Ensure keys are qualified
Signed-off-by: Abhi Agarwal <[email protected]>
1 parent 7f85c76 commit f1521ae

File tree

2 files changed

+122
-3
lines changed

2 files changed

+122
-3
lines changed

etl-destinations/src/deltalake/expr.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,4 +529,71 @@ mod tests {
529529
let res = qualify_primary_keys(primary_keys, "source", "target");
530530
assert!(res.is_none());
531531
}
532+
533+
#[test]
534+
fn test_qualify_primary_keys_case_sensitivity() {
535+
let primary_keys = vec![
536+
Expr::Column(Column::new_unqualified("id")),
537+
Expr::Column(Column::new_unqualified("NAME")),
538+
];
539+
let result = qualify_primary_keys(primary_keys, "source", "target").unwrap();
540+
541+
assert_debug_snapshot!(result, @r#"
542+
BinaryExpr(
543+
BinaryExpr {
544+
left: BinaryExpr(
545+
BinaryExpr {
546+
left: Column(
547+
Column {
548+
relation: Some(
549+
Bare {
550+
table: "source",
551+
},
552+
),
553+
name: "id",
554+
},
555+
),
556+
op: Eq,
557+
right: Column(
558+
Column {
559+
relation: Some(
560+
Bare {
561+
table: "target",
562+
},
563+
),
564+
name: "id",
565+
},
566+
),
567+
},
568+
),
569+
op: And,
570+
right: BinaryExpr(
571+
BinaryExpr {
572+
left: Column(
573+
Column {
574+
relation: Some(
575+
Bare {
576+
table: "source",
577+
},
578+
),
579+
name: "NAME",
580+
},
581+
),
582+
op: Eq,
583+
right: Column(
584+
Column {
585+
relation: Some(
586+
Bare {
587+
table: "target",
588+
},
589+
),
590+
name: "NAME",
591+
},
592+
),
593+
},
594+
),
595+
},
596+
)
597+
"#);
598+
}
532599
}

etl-destinations/src/deltalake/operations/merge.rs

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use deltalake::DeltaTableError;
22
use deltalake::datafusion::common::Column;
3-
use deltalake::datafusion::prelude::{SessionContext, col};
3+
use deltalake::datafusion::prelude::SessionContext;
44
use deltalake::operations::merge::MergeBuilder;
55
use deltalake::{DeltaResult, DeltaTable, datafusion::prelude::Expr};
66
use etl::types::{TableRow as PgTableRow, TableSchema as PgTableSchema};
@@ -10,6 +10,10 @@ use crate::deltalake::config::DeltaTableConfig;
1010
use crate::deltalake::expr::qualify_primary_keys;
1111
use crate::deltalake::schema::postgres_to_arrow_schema;
1212

13+
pub(crate) fn source_qualified_column_expr(column_name: &str, source_alias: &str) -> Expr {
14+
Expr::Column(Column::new(Some(source_alias), column_name))
15+
}
16+
1317
pub async fn merge_to_table(
1418
table: &mut DeltaTable,
1519
config: &DeltaTableConfig,
@@ -55,12 +59,18 @@ pub async fn merge_to_table(
5559
.with_target_alias("target")
5660
.when_not_matched_insert(|insert| {
5761
all_columns.iter().fold(insert, |insert, &column| {
58-
insert.set(column.to_string(), col(format!("source.{column}")))
62+
insert.set(
63+
column.to_string(),
64+
source_qualified_column_expr(column, "source"),
65+
)
5966
})
6067
})?
6168
.when_matched_update(|update| {
6269
all_columns.iter().fold(update, |update, &column| {
63-
update.update(column.to_string(), col(format!("source.{column}")))
70+
update.update(
71+
column.to_string(),
72+
source_qualified_column_expr(column, "source"),
73+
)
6474
})
6575
})?;
6676

@@ -73,3 +83,45 @@ pub async fn merge_to_table(
7383
*table = merged_table;
7484
Ok(())
7585
}
86+
87+
#[cfg(test)]
88+
mod tests {
89+
use super::*;
90+
use insta::assert_debug_snapshot;
91+
92+
#[test]
93+
fn source_qualified_column_expr_preserves_case_and_alias() {
94+
let expr = source_qualified_column_expr("CASESensitivecolumn", "source");
95+
96+
assert_debug_snapshot!(expr, @r#"
97+
Column(
98+
Column {
99+
relation: Some(
100+
Bare {
101+
table: "source",
102+
},
103+
),
104+
name: "CASESensitivecolumn",
105+
},
106+
)
107+
"#);
108+
}
109+
110+
#[test]
111+
fn source_qualified_column_expr_handles_lowercase() {
112+
let expr = source_qualified_column_expr("lowercasecolumn", "source");
113+
114+
assert_debug_snapshot!(expr, @r#"
115+
Column(
116+
Column {
117+
relation: Some(
118+
Bare {
119+
table: "source",
120+
},
121+
),
122+
name: "lowercasecolumn",
123+
},
124+
)
125+
"#);
126+
}
127+
}

0 commit comments

Comments
 (0)