v0.3.3-pre.009-fix.005

This commit is contained in:
2026-08-30 15:46:03 +02:00
parent 5f1938c7c3
commit ba2e52f841
5 changed files with 183 additions and 15 deletions

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-store-postgres-lib/src/schema.rs
// version: 5
// version: 7
/// Immutable V000 physical schema resource inventory.
pub(crate) const V000_RESOURCES: &[SchemaResource] = &[SchemaResource {
@@ -1138,7 +1138,7 @@ fn matches_expected_constraint_definition(table: &str, kind: &str, definition: &
}
fn normalize_catalog_sql(value: &str) -> std::string::String {
let value = normalize_quoted_numeric_cast_literals(value);
let value = normalize_quoted_integral_cast_literals(value);
return value
.chars()
.filter(|character| return !character.is_whitespace() && *character != '"' && *character != '(' && *character != ')')
@@ -1147,11 +1147,15 @@ fn normalize_catalog_sql(value: &str) -> std::string::String {
.replace("::numeric", "")
.replace("::bigint", "")
.replace("::smallint", "")
.replace("::integer", "")
.replace("::int8", "")
.replace("::int4", "")
.replace("::int2", "")
.to_ascii_lowercase();
}
fn normalize_quoted_numeric_cast_literals(value: &str) -> std::string::String {
const NUMERIC_CAST: &str = "::numeric";
fn normalize_quoted_integral_cast_literals(value: &str) -> std::string::String {
const INTEGRAL_CASTS: &[&str] = &["::bigint", "::int2", "::int4", "::int8", "::integer", "::numeric", "::smallint"];
let mut normalized = std::string::String::with_capacity(value.len());
let mut remaining = value;
loop {
@@ -1172,15 +1176,24 @@ fn normalize_quoted_numeric_cast_literals(value: &str) -> std::string::String {
},
};
let has_digit = literal.chars().any(|character| return character.is_ascii_digit());
let numeric_literal = !literal.is_empty()
let integral_literal = !literal.is_empty()
&& has_digit
&& literal
.chars()
.enumerate()
.all(|(offset, character)| return character.is_ascii_digit() || (offset == 0 && (character == '+' || character == '-')));
if numeric_literal && let std::option::Option::Some(after_numeric_cast) = after_literal.strip_prefix(NUMERIC_CAST) {
let mut after_integral_cast = std::option::Option::None;
if integral_literal {
for cast in INTEGRAL_CASTS {
if let std::option::Option::Some(value) = after_literal.strip_prefix(*cast) {
after_integral_cast = std::option::Option::Some(value);
break;
}
}
}
if let std::option::Option::Some(value) = after_integral_cast {
normalized.push_str(literal);
remaining = after_numeric_cast;
remaining = value;
continue;
}
normalized.push('\'');