Describe the parameter and result metadata for a SQL query.
(
&mut self,
sql: &str,
options: Option<&QueryOptions>,
)
| 773 | |
| 774 | /// Describe the parameter and result metadata for a SQL query. |
| 775 | pub fn describe_query( |
| 776 | &mut self, |
| 777 | sql: &str, |
| 778 | options: Option<&QueryOptions>, |
| 779 | ) -> Result<DescribeQueryResult> { |
| 780 | self.check_ready()?; |
| 781 | |
| 782 | let default_options = QueryOptions::default(); |
| 783 | let query_opts = options.unwrap_or(&default_options); |
| 784 | |
| 785 | let options_snapshot = options.cloned(); |
| 786 | let mut exec_opts = ExecProtocolOptions::no_sync(); |
| 787 | exec_opts.on_notice = query_opts.on_notice.clone(); |
| 788 | exec_opts.data_transfer_container = query_opts.data_transfer_container; |
| 789 | |
| 790 | let mut describe_messages: Vec<BackendMessage> = Vec::new(); |
| 791 | |
| 792 | let result: Result<()> = (|| { |
| 793 | let param_types = if query_opts.param_types.is_empty() { |
| 794 | &[] as &[i32] |
| 795 | } else { |
| 796 | &query_opts.param_types |
| 797 | }; |
| 798 | |
| 799 | let mut describe_batch = Vec::new(); |
| 800 | describe_batch.extend(Serialize::parse(None, sql, param_types)); |
| 801 | describe_batch.extend(Serialize::describe(&PortalTarget::new('S', None))); |
| 802 | describe_batch.extend(Serialize::sync()); |
| 803 | let ExecProtocolResult { messages, .. } = |
| 804 | self.exec_protocol(&describe_batch, exec_opts.clone())?; |
| 805 | if !messages |
| 806 | .iter() |
| 807 | .any(|message| matches!(message, BackendMessage::ParseComplete { .. })) |
| 808 | { |
| 809 | bail!("extended query parse did not complete"); |
| 810 | } |
| 811 | describe_messages.extend(messages); |
| 812 | |
| 813 | Ok(()) |
| 814 | })(); |
| 815 | |
| 816 | if let Err(err) = result { |
| 817 | match err.downcast::<DatabaseError>() { |
| 818 | Ok(db_err) => { |
| 819 | let enriched = PgliteError::new(db_err, sql, Vec::new(), options_snapshot); |
| 820 | return Err(enriched.into()); |
| 821 | } |
| 822 | Err(err) => { |
| 823 | return Err(err.context(format!("failed to describe query: {sql}"))); |
| 824 | } |
| 825 | } |
| 826 | } |
| 827 | |
| 828 | let param_type_ids = parse_describe_statement_results(&describe_messages); |
| 829 | self.ensure_array_types_for_oids(param_type_ids.iter().copied(), Some(query_opts))?; |
| 830 | let result_type_ids = describe_messages |
| 831 | .iter() |
| 832 | .filter_map(|msg| match msg { |
no test coverage detected