ferrum-orm 0.1.15__tar.gz → 0.1.16__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/Cargo.lock +4 -4
  2. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/Cargo.toml +1 -1
  3. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/PKG-INFO +1 -1
  4. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/crates/ferrum-sql/src/emit.rs +85 -3
  5. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/pyproject.toml +1 -1
  6. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/__init__.py +1 -1
  7. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/LICENSE +0 -0
  8. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/README.md +0 -0
  9. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/crates/ferrum-core/Cargo.toml +0 -0
  10. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/crates/ferrum-core/benches/hydrate.rs +0 -0
  11. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/crates/ferrum-core/src/compile/mod.rs +0 -0
  12. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/crates/ferrum-core/src/error.rs +0 -0
  13. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/crates/ferrum-core/src/hydrate/mod.rs +0 -0
  14. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/crates/ferrum-core/src/ir/metadata.rs +0 -0
  15. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/crates/ferrum-core/src/ir/mod.rs +0 -0
  16. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/crates/ferrum-core/src/lib.rs +0 -0
  17. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/crates/ferrum-core/src/migrate/mod.rs +0 -0
  18. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/crates/ferrum-pyo3/Cargo.toml +0 -0
  19. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/crates/ferrum-pyo3/src/lib.rs +0 -0
  20. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/crates/ferrum-sql/Cargo.toml +0 -0
  21. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/crates/ferrum-sql/benches/compile.rs +0 -0
  22. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/crates/ferrum-sql/src/dialect.rs +0 -0
  23. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/crates/ferrum-sql/src/fts/mod.rs +0 -0
  24. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/crates/ferrum-sql/src/fts/mssql.rs +0 -0
  25. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/crates/ferrum-sql/src/fts/mysql.rs +0 -0
  26. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/crates/ferrum-sql/src/fts/postgres.rs +0 -0
  27. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/crates/ferrum-sql/src/fts/sqlite.rs +0 -0
  28. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/crates/ferrum-sql/src/lib.rs +0 -0
  29. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/_native.pyi +0 -0
  30. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/cli/__init__.py +0 -0
  31. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/cli/app.py +0 -0
  32. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/cli/bootstrap.py +0 -0
  33. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/cli/init.py +0 -0
  34. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/cli/inspectdb_cmd.py +0 -0
  35. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/cli/makemigrations_cmd.py +0 -0
  36. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/cli/migrate_cmd.py +0 -0
  37. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/cli/migrations_cmd.py +0 -0
  38. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/cli/resetdb_cmd.py +0 -0
  39. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/cli/revert_cmd.py +0 -0
  40. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/cli/showmigrations_cmd.py +0 -0
  41. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/cli/sqlmigrate_cmd.py +0 -0
  42. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/config.py +0 -0
  43. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/connection.py +0 -0
  44. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/contrib/__init__.py +0 -0
  45. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/contrib/fastapi.py +0 -0
  46. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/drivers/__init__.py +0 -0
  47. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/drivers/mssql.py +0 -0
  48. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/drivers/mysql.py +0 -0
  49. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/drivers/postgres.py +0 -0
  50. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/drivers/protocol.py +0 -0
  51. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/drivers/sqlite.py +0 -0
  52. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/drivers/streaming.py +0 -0
  53. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/echo.py +0 -0
  54. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/errors.py +0 -0
  55. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/expressions.py +0 -0
  56. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/ext/__init__.py +0 -0
  57. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/ext/fts.py +0 -0
  58. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/ext/pgvector.py +0 -0
  59. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/hooks.py +0 -0
  60. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/migrations/__init__.py +0 -0
  61. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/migrations/base.py +0 -0
  62. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/migrations/drift.py +0 -0
  63. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/migrations/fts/__init__.py +0 -0
  64. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/migrations/fts/mssql.py +0 -0
  65. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/migrations/fts/mysql.py +0 -0
  66. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/migrations/fts/postgres.py +0 -0
  67. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/migrations/fts/sqlite.py +0 -0
  68. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/migrations/gates.py +0 -0
  69. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/migrations/introspect.py +0 -0
  70. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/migrations/ledger.py +0 -0
  71. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/migrations/loader.py +0 -0
  72. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/migrations/operations.py +0 -0
  73. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/migrations/orchestrator.py +0 -0
  74. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/migrations/tokens.py +0 -0
  75. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/models.py +0 -0
  76. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/observability.py +0 -0
  77. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/py.typed +0 -0
  78. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/queryset.py +0 -0
  79. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/registry.py +0 -0
  80. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/relations.py +0 -0
  81. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/runtime.py +0 -0
  82. {ferrum_orm-0.1.15 → ferrum_orm-0.1.16}/python/ferrum/session.py +0 -0
@@ -223,7 +223,7 @@ checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6"
223
223
 
224
224
  [[package]]
225
225
  name = "ferrum-core"
226
- version = "0.1.15"
226
+ version = "0.1.16"
227
227
  dependencies = [
228
228
  "criterion",
229
229
  "proptest",
@@ -234,7 +234,7 @@ dependencies = [
234
234
 
235
235
  [[package]]
236
236
  name = "ferrum-migrate"
237
- version = "0.1.15"
237
+ version = "0.1.16"
238
238
  dependencies = [
239
239
  "ferrum-core",
240
240
  "serde",
@@ -243,7 +243,7 @@ dependencies = [
243
243
 
244
244
  [[package]]
245
245
  name = "ferrum-pyo3"
246
- version = "0.1.15"
246
+ version = "0.1.16"
247
247
  dependencies = [
248
248
  "ferrum-core",
249
249
  "ferrum-sql",
@@ -255,7 +255,7 @@ dependencies = [
255
255
 
256
256
  [[package]]
257
257
  name = "ferrum-sql"
258
- version = "0.1.15"
258
+ version = "0.1.16"
259
259
  dependencies = [
260
260
  "criterion",
261
261
  "ferrum-core",
@@ -3,7 +3,7 @@ members = ["crates/ferrum-core", "crates/ferrum-sql", "crates/ferrum-pyo3"]
3
3
  resolver = "2"
4
4
 
5
5
  [workspace.package]
6
- version = "0.1.15"
6
+ version = "0.1.16"
7
7
  edition = "2021"
8
8
  authors = ["Ferrum Contributors"]
9
9
  license = "Apache-2.0"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ferrum-orm
3
- Version: 0.1.15
3
+ Version: 0.1.16
4
4
  Classifier: Development Status :: 3 - Alpha
5
5
  Classifier: Framework :: AsyncIO
6
6
  Classifier: Intended Audience :: Developers
@@ -1219,6 +1219,11 @@ fn filter_clause(
1219
1219
  /// `UPDATE … FROM (VALUES …)` requires explicit casts so `PostgreSQL` can infer
1220
1220
  /// the correct column types when the VALUES clause contains multiple rows.
1221
1221
  /// The cast is appended to the placeholder, e.g. `$1::bigint`, `$2::text`.
1222
+ ///
1223
+ /// The cast must be assignment-compatible with the DDL column type, and for PK
1224
+ /// columns it must match exactly: the join predicate `t.pk = v.pk` resolves an
1225
+ /// operator rather than an assignment cast, so a `uuid` column compared against
1226
+ /// a `text` VALUES column fails with `UndefinedFunction` (42883).
1222
1227
  fn postgres_value_cast(
1223
1228
  field_type: ferrum_core::ir::metadata::FieldType,
1224
1229
  placeholder: &str,
@@ -1226,8 +1231,11 @@ fn postgres_value_cast(
1226
1231
  use ferrum_core::ir::metadata::FieldType;
1227
1232
  let cast = match field_type {
1228
1233
  FieldType::Int | FieldType::BigInt => "bigint",
1229
- FieldType::Float | FieldType::Decimal => "double precision",
1230
- FieldType::Text | FieldType::Uuid | FieldType::TsVector | FieldType::Enum => "text",
1234
+ FieldType::Float => "double precision",
1235
+ FieldType::Decimal => "numeric",
1236
+ FieldType::Text | FieldType::Enum => "text",
1237
+ FieldType::Uuid => "uuid",
1238
+ FieldType::TsVector => "tsvector",
1231
1239
  FieldType::Bool => "boolean",
1232
1240
  FieldType::Datetime => "timestamptz",
1233
1241
  FieldType::Date => "date",
@@ -1235,7 +1243,8 @@ fn postgres_value_cast(
1235
1243
  FieldType::Json => "jsonb",
1236
1244
  FieldType::Bytes => "bytea",
1237
1245
  FieldType::Vector => "vector",
1238
- FieldType::ArrayText | FieldType::ArrayUuid => "text[]",
1246
+ FieldType::ArrayText => "text[]",
1247
+ FieldType::ArrayUuid => "uuid[]",
1239
1248
  FieldType::ArrayInt => "bigint[]",
1240
1249
  FieldType::ArrayFloat => "double precision[]",
1241
1250
  };
@@ -2112,6 +2121,79 @@ mod tests {
2112
2121
  assert!(matches!(err, CompileError::MalformedIr { .. }));
2113
2122
  }
2114
2123
 
2124
+ /// Every VALUES placeholder must carry the cast of its DDL column type.
2125
+ /// A `uuid` PK cast to `text` made `t.id = v.id` resolve `uuid = text`,
2126
+ /// which `PostgreSQL` rejects with `UndefinedFunction` (42883); `uuid[]` and
2127
+ /// `tsvector` columns failed the SET assignment for the same reason.
2128
+ #[test]
2129
+ fn bulk_update_casts_match_column_types() {
2130
+ let field = |name: &str, field_type: FieldType| FieldMeta {
2131
+ name: name.into(),
2132
+ column_name: name.into(),
2133
+ field_type,
2134
+ allowed_operators: vec!["eq".into()],
2135
+ nullable: true,
2136
+ vector_dimensions: None,
2137
+ fts_config: None,
2138
+ fts_source_columns: None,
2139
+ };
2140
+ let meta = ModelMetadata {
2141
+ model_name: "Ticket".into(),
2142
+ table_name: "tickets".into(),
2143
+ fields: vec![
2144
+ field("id", FieldType::Uuid),
2145
+ field("tags", FieldType::ArrayUuid),
2146
+ field("search", FieldType::TsVector),
2147
+ field("amount", FieldType::Decimal),
2148
+ ],
2149
+ pk_index: 0,
2150
+ pk_fields: vec![0],
2151
+ full_text_indexes: vec![],
2152
+ };
2153
+ let field_ref = |name: &str, index: usize| FieldRef {
2154
+ name: name.into(),
2155
+ index,
2156
+ };
2157
+ let ir = QuerySetIR {
2158
+ version: IR_VERSION,
2159
+ model_name: "Ticket".into(),
2160
+ operation: Operation::BulkUpdate {
2161
+ pk_fields: vec![field_ref("id", 0)],
2162
+ fields: vec![
2163
+ field_ref("tags", 1),
2164
+ field_ref("search", 2),
2165
+ field_ref("amount", 3),
2166
+ ],
2167
+ rows: vec![ferrum_core::ir::BulkUpdateRow {
2168
+ pk_values: vec![BindValue::Text(
2169
+ "00000000-0000-0000-0000-000000000001".into(),
2170
+ )],
2171
+ values: vec![
2172
+ BindValue::TextArray(vec![]),
2173
+ BindValue::Text("lexeme".into()),
2174
+ BindValue::Text("1.005".into()),
2175
+ ],
2176
+ }],
2177
+ },
2178
+ filters: vec![],
2179
+ order_by: vec![],
2180
+ limit: None,
2181
+ offset: None,
2182
+ vector_order_by: None,
2183
+ text_rank_by: None,
2184
+ predicate: None,
2185
+ distinct: false,
2186
+ exists: false,
2187
+ joins: vec![],
2188
+ aggregation: None,
2189
+ };
2190
+ let q = emit_bulk_update(Dialect::Postgres, &meta, &ir).unwrap();
2191
+ assert!(q.sql_text.contains("$1::uuid,"), "{}", q.sql_text);
2192
+ assert!(q.sql_text.contains("$2::uuid[]"), "{}", q.sql_text);
2193
+ assert!(q.sql_text.contains("$3::tsvector"), "{}", q.sql_text);
2194
+ assert!(q.sql_text.contains("$4::numeric"), "{}", q.sql_text);
2195
+ }
2196
+
2115
2197
  // ── MessagePack wire-format round-trip ───────────────────────────────────
2116
2198
 
2117
2199
  /// IR + metadata `MessagePack`-encoded (NAMED) decode back into the same serde
@@ -4,7 +4,7 @@ build-backend = "maturin"
4
4
 
5
5
  [project]
6
6
  name = "ferrum-orm"
7
- version = "0.1.15"
7
+ version = "0.1.16"
8
8
  description = "Next-generation async ORM for Python with a Rust-powered core"
9
9
  license = { text = "Apache-2.0" }
10
10
  readme = "README.md"
@@ -6,7 +6,7 @@ Import paths are stable API; internal module paths are not.
6
6
 
7
7
  from __future__ import annotations
8
8
 
9
- __version__ = "0.1.15"
9
+ __version__ = "0.1.16"
10
10
  __all__ = [
11
11
  "Aggregate",
12
12
  "CreateExtension",
File without changes
File without changes