| 1107 | } |
| 1108 | |
| 1109 | pub async fn handle_bind<T>( |
| 1110 | framed: &mut Framed<T, crate::protocol::PostgresCodec>, |
| 1111 | session: &Arc<SessionState>, |
| 1112 | portal: String, |
| 1113 | statement: String, |
| 1114 | formats: Vec<i16>, |
| 1115 | values: Vec<Option<Vec<u8>>>, |
| 1116 | result_formats: Vec<i16>, |
| 1117 | ) -> Result<(), PgSqliteError> |
| 1118 | where |
| 1119 | T: tokio::io::AsyncRead + tokio::io::AsyncWrite + Unpin, |
| 1120 | { |
| 1121 | // Fast path for simple queries - skip debug logging and python parameter checking |
| 1122 | let is_simple_query = { |
| 1123 | let statements = session.prepared_statements.read().await; |
| 1124 | if let Some(stmt) = statements.get(&statement) { |
| 1125 | stmt.query.starts_with("SELECT") && !stmt.query.contains("%(") |
| 1126 | } else { |
| 1127 | false |
| 1128 | } |
| 1129 | }; |
| 1130 | |
| 1131 | if !is_simple_query { |
| 1132 | // Binding portal to statement |
| 1133 | |
| 1134 | // Check if this statement used Python-style parameters and reorder values if needed |
| 1135 | { |
| 1136 | let python_mappings = session.python_param_mapping.read().await; |
| 1137 | if let Some(param_names) = python_mappings.get(&statement) { |
| 1138 | info!("Statement '{}' used Python parameters: {:?}", statement, param_names); |
| 1139 | |
| 1140 | // The values come in as a map (conceptually), but we received them as a Vec |
| 1141 | // We need to reorder them to match the $1, $2, $3... order we created |
| 1142 | // Since we already converted %(name__0)s -> $1, %(name__1)s -> $2, etc. in parse, |
| 1143 | // the values should already be in the correct order |
| 1144 | info!("Python parameter mapping found, values should already be in correct order"); |
| 1145 | } |
| 1146 | } |
| 1147 | } |
| 1148 | |
| 1149 | // Get the prepared statement (handle unnamed statements specially) |
| 1150 | let statements = session.prepared_statements.read().await; |
| 1151 | |
| 1152 | // For unnamed statements, try both empty string and the actual value |
| 1153 | let stmt = if statement.is_empty() { |
| 1154 | // Try empty string key first for unnamed statements |
| 1155 | statements.get("") |
| 1156 | .or_else(|| statements.get(&statement)) |
| 1157 | } else { |
| 1158 | statements.get(&statement) |
| 1159 | } |
| 1160 | .ok_or_else(|| { |
| 1161 | info!("Statement lookup failed for '{}', available statements: {:?}", |
| 1162 | statement, statements.keys().collect::<Vec<_>>()); |
| 1163 | PgSqliteError::Protocol(format!("Unknown statement: {statement}")) |
| 1164 | })?; |
| 1165 | |
| 1166 | // Processing parameter types and formats |