MCPcopy Create free account
hub / github.com/erans/pgsqlite / analyze_insert_params

Method analyze_insert_params

src/query/extended.rs:5716–5776  ·  view source on GitHub ↗

Analyze INSERT query to determine parameter types from schema

(query: &str, db: &Arc<DbHandler>)

Source from the content-addressed store, hash-verified

5714
5715 /// Analyze INSERT query to determine parameter types from schema
5716 async fn analyze_insert_params(query: &str, db: &Arc<DbHandler>) -> Result<(Vec<i32>, Vec<i32>), PgSqliteError> {
5717 // Use QueryContextAnalyzer to extract table and column info
5718 let (table_name, columns) = crate::types::QueryContextAnalyzer::get_insert_column_info(query)
5719 .ok_or_else(|| PgSqliteError::Protocol("Failed to parse INSERT query".to_string()))?;
5720
5721 info!("Analyzing INSERT for table '{}' with columns: {:?}", table_name, columns);
5722
5723 // Get cached table schema
5724 let table_schema = db.get_table_schema(&table_name).await
5725 .map_err(|e| PgSqliteError::Protocol(format!("Failed to get table schema: {e}")))?;
5726
5727 // If no explicit columns, use all columns from the table
5728 let columns = if columns.is_empty() {
5729 table_schema.columns.iter()
5730 .map(|col| col.name.clone())
5731 .collect()
5732 } else {
5733 columns
5734 };
5735
5736 // Look up types for each column using cached schema
5737 let mut param_types = Vec::new();
5738 let mut original_types = Vec::new();
5739 for column in &columns {
5740 if let Some(col_info) = table_schema.column_map.get(&column.to_lowercase()) {
5741 original_types.push(col_info.pg_oid);
5742
5743 // For certain PostgreSQL types that tokio-postgres doesn't support in binary format,
5744 // use TEXT as the parameter type to allow string representation
5745 let param_oid = match col_info.pg_oid {
5746 t if t == PgType::Macaddr8.to_oid() => PgType::Text.to_oid(), // MACADDR8 -> TEXT
5747 t if t == PgType::Macaddr.to_oid() => PgType::Text.to_oid(), // MACADDR -> TEXT
5748 t if t == PgType::Inet.to_oid() => PgType::Text.to_oid(), // INET -> TEXT
5749 t if t == PgType::Cidr.to_oid() => PgType::Text.to_oid(), // CIDR -> TEXT
5750 t if t == PgType::Money.to_oid() => PgType::Text.to_oid(), // MONEY -> TEXT
5751 t if t == PgType::Int4range.to_oid() => PgType::Text.to_oid(), // INT4RANGE -> TEXT
5752 t if t == PgType::Int8range.to_oid() => PgType::Text.to_oid(), // INT8RANGE -> TEXT
5753 t if t == PgType::Numrange.to_oid() => PgType::Text.to_oid(), // NUMRANGE -> TEXT
5754 t if t == PgType::Bit.to_oid() => PgType::Text.to_oid(), // BIT -> TEXT
5755 t if t == PgType::Varbit.to_oid() => PgType::Text.to_oid(), // VARBIT -> TEXT
5756 _ => col_info.pg_oid, // Use original OID for supported types
5757 };
5758
5759 param_types.push(param_oid);
5760 if param_oid != col_info.pg_oid {
5761 info!("Mapped parameter type for {}.{}: {} (OID {}) -> TEXT (OID 25) for binary protocol compatibility",
5762 table_name, column, col_info.pg_type, col_info.pg_oid);
5763 } else {
5764 info!("Found cached type for {}.{}: {} (OID {})",
5765 table_name, column, col_info.pg_type, col_info.pg_oid);
5766 }
5767 } else {
5768 // Default to text if column not found
5769 param_types.push(PgType::Text.to_oid());
5770 original_types.push(PgType::Text.to_oid());
5771 info!("Column {}.{} not found in schema, defaulting to text", table_name, column);
5772 }
5773 }

Callers

nothing calls this directly

Calls 5

to_oidMethod · 0.80
get_table_schemaMethod · 0.45
is_emptyMethod · 0.45
cloneMethod · 0.45
getMethod · 0.45

Tested by

no test coverage detected