Analyze SELECT query to determine parameter types from WHERE clause
(query: &str, db: &Arc<DbHandler>, session: &Arc<SessionState>)
| 5818 | |
| 5819 | /// Analyze SELECT query to determine parameter types from WHERE clause |
| 5820 | async fn analyze_select_params(query: &str, db: &Arc<DbHandler>, session: &Arc<SessionState>) -> Result<Vec<i32>, PgSqliteError> { |
| 5821 | // First, check for explicit parameter casts like $1::int4 |
| 5822 | let mut param_types = Vec::new(); |
| 5823 | |
| 5824 | // Count parameters and try to determine their types |
| 5825 | for i in 1..=99 { |
| 5826 | let param = format!("${i}"); |
| 5827 | if !query.contains(¶m) { |
| 5828 | break; |
| 5829 | } |
| 5830 | |
| 5831 | // Check for explicit cast first (e.g., $1::int4) |
| 5832 | let cast_pattern = format!(r"\${i}::\s*(\w+)"); |
| 5833 | let cast_regex = regex::Regex::new(&cast_pattern).unwrap(); |
| 5834 | let mut found_type = false; |
| 5835 | |
| 5836 | if let Some(captures) = cast_regex.captures(query) |
| 5837 | && let Some(type_match) = captures.get(1) { |
| 5838 | let cast_type = type_match.as_str(); |
| 5839 | let oid = Self::pg_type_name_to_oid(cast_type); |
| 5840 | param_types.push(oid); |
| 5841 | info!("Found explicit cast for parameter {}: {} (OID {})", i, cast_type, oid); |
| 5842 | found_type = true; |
| 5843 | } |
| 5844 | |
| 5845 | if found_type { |
| 5846 | continue; |
| 5847 | } |
| 5848 | |
| 5849 | // If no explicit cast, try to infer from column comparisons |
| 5850 | // Extract table name from SELECT query (only if needed) |
| 5851 | let table_name = if let Some(name) = extract_table_name_from_select(query) { |
| 5852 | name |
| 5853 | } else { |
| 5854 | // No table found, default to text |
| 5855 | param_types.push(25); |
| 5856 | info!("Could not extract table name for parameter {}, defaulting to text", i); |
| 5857 | continue; |
| 5858 | }; |
| 5859 | |
| 5860 | info!("Analyzing SELECT params for table: {}", table_name); |
| 5861 | let query_lower = query.to_lowercase(); |
| 5862 | |
| 5863 | // Try to find which column this parameter is compared against |
| 5864 | // Look for patterns like "column = $n" or "column < $n" etc. |
| 5865 | |
| 5866 | // Look for the parameter in the query and find the column it's compared to |
| 5867 | // Use simpler string matching instead of complex regex |
| 5868 | let param_escaped = regex::escape(¶m); |
| 5869 | let patterns = vec![ |
| 5870 | format!(r"(\w+)\s*=\s*{}", param_escaped), |
| 5871 | format!(r"(\w+)\s*<\s*{}", param_escaped), |
| 5872 | format!(r"(\w+)\s*>\s*{}", param_escaped), |
| 5873 | format!(r"(\w+)\s*<=\s*{}", param_escaped), |
| 5874 | format!(r"(\w+)\s*>=\s*{}", param_escaped), |
| 5875 | format!(r"(\w+)\s*!=\s*{}", param_escaped), |
| 5876 | format!(r"(\w+)\s*<>\s*{}", param_escaped), |
| 5877 | ]; |
nothing calls this directly
no test coverage detected