fix(postgres): don't fetch ColumnOrigin for transparently-prepared statements

This commit is contained in:
Austin Bonander 2025-02-01 23:42:51 -08:00
parent 28b64509bd
commit 7d646a9251
2 changed files with 12 additions and 9 deletions

View File

@ -102,7 +102,8 @@ impl PgConnection {
pub(super) async fn handle_row_description(
&mut self,
desc: Option<RowDescription>,
should_fetch: bool,
fetch_type_info: bool,
fetch_column_description: bool,
) -> Result<(Vec<PgColumn>, HashMap<UStr, usize>), Error> {
let mut columns = Vec::new();
let mut column_names = HashMap::new();
@ -121,13 +122,13 @@ impl PgConnection {
let name = UStr::from(field.name);
let type_info = self
.maybe_fetch_type_info_by_oid(field.data_type_id, should_fetch)
.maybe_fetch_type_info_by_oid(field.data_type_id, fetch_type_info)
.await?;
let origin = if let (Some(relation_oid), Some(attribute_no)) =
(field.relation_id, field.relation_attribute_no)
{
self.maybe_fetch_column_origin(relation_oid, attribute_no, should_fetch)
self.maybe_fetch_column_origin(relation_oid, attribute_no, fetch_column_description)
.await?
} else {
ColumnOrigin::Expression

View File

@ -25,6 +25,7 @@ async fn prepare(
sql: &str,
parameters: &[PgTypeInfo],
metadata: Option<Arc<PgStatementMetadata>>,
fetch_column_origin: bool,
) -> Result<(StatementId, Arc<PgStatementMetadata>), Error> {
let id = conn.inner.next_statement_id;
conn.inner.next_statement_id = id.next();
@ -79,7 +80,7 @@ async fn prepare(
let parameters = conn.handle_parameter_description(parameters).await?;
let (columns, column_names) = conn.handle_row_description(rows, true).await?;
let (columns, column_names) = conn.handle_row_description(rows, true, fetch_column_origin).await?;
// ensure that if we did fetch custom data, we wait until we are fully ready before
// continuing
@ -168,12 +169,13 @@ impl PgConnection {
// optional metadata that was provided by the user, this means they are reusing
// a statement object
metadata: Option<Arc<PgStatementMetadata>>,
fetch_column_origin: bool,
) -> Result<(StatementId, Arc<PgStatementMetadata>), Error> {
if let Some(statement) = self.inner.cache_statement.get_mut(sql) {
return Ok((*statement).clone());
}
let statement = prepare(self, sql, parameters, metadata).await?;
let statement = prepare(self, sql, parameters, metadata, fetch_column_origin).await?;
if store_to_cache && self.inner.cache_statement.is_enabled() {
if let Some((id, _)) = self.inner.cache_statement.insert(sql, statement.clone()) {
@ -222,7 +224,7 @@ impl PgConnection {
// prepare the statement if this our first time executing it
// always return the statement ID here
let (statement, metadata_) = self
.get_or_prepare(query, &arguments.types, persistent, metadata_opt)
.get_or_prepare(query, &arguments.types, persistent, metadata_opt, false)
.await?;
metadata = metadata_;
@ -327,7 +329,7 @@ impl PgConnection {
BackendMessageFormat::RowDescription => {
// indicates that a *new* set of rows are about to be returned
let (columns, column_names) = self
.handle_row_description(Some(message.decode()?), false)
.handle_row_description(Some(message.decode()?), false, false)
.await?;
metadata = Arc::new(PgStatementMetadata {
@ -449,7 +451,7 @@ impl<'c> Executor<'c> for &'c mut PgConnection {
Box::pin(async move {
self.wait_until_ready().await?;
let (_, metadata) = self.get_or_prepare(sql, parameters, true, None).await?;
let (_, metadata) = self.get_or_prepare(sql, parameters, true, None, true).await?;
Ok(PgStatement {
sql: Cow::Borrowed(sql),
@ -468,7 +470,7 @@ impl<'c> Executor<'c> for &'c mut PgConnection {
Box::pin(async move {
self.wait_until_ready().await?;
let (stmt_id, metadata) = self.get_or_prepare(sql, &[], true, None).await?;
let (stmt_id, metadata) = self.get_or_prepare(sql, &[], true, None, true).await?;
let nullable = self.get_nullable_for_columns(stmt_id, &metadata).await?;