diff --git a/src/store/adapters/postgres.rs b/src/store/adapters/postgres.rs index 4320ece3..4d25db22 100644 --- a/src/store/adapters/postgres.rs +++ b/src/store/adapters/postgres.rs @@ -90,6 +90,12 @@ pub async fn migrate(config: &StoreConfig) -> Result<()> { Ok(()) } +// Explicit columns instead of `*` so cached prepared statements survive migrations that add columns. +const RETURNING_COLUMNS: &str = " RETURNING inflight_taskactivations.id, activation, topic, partition, + kafka_offset AS offset, added_at, received_at, processing_attempts, expires_at, delay_until, + processing_deadline_duration, processing_deadline, claim_expires_at, heartbeat, heartbeat_deadline, + status, at_most_once, application, namespace, taskname, on_attempts_exceeded, bucket"; + /// Database representation of an [`Activation`], used for both reads and /// writes. /// @@ -621,7 +627,7 @@ impl ActivationStore for PostgresStore { query_builder.push(" FROM selected_activations "); query_builder.push(" WHERE inflight_taskactivations.id = selected_activations.id"); - query_builder.push(" RETURNING *, kafka_offset AS offset"); + query_builder.push(RETURNING_COLUMNS); let mut conn = self.acquire_write_conn_metric("claim_activations").await?; let rows: Vec = query_builder @@ -928,13 +934,14 @@ impl ActivationStore for PostgresStore { retry_query(&self.config.retry, "set_status", || async { let mut tx = self.begin_write_tx_metric("set_status").await?; - let result: Option = sqlx::query_as( - "UPDATE inflight_taskactivations SET status = $1 WHERE id = $2 RETURNING *, kafka_offset AS offset", - ) - .bind(status.to_string()) - .bind(id) - .fetch_optional(&mut *tx) - .await?; + let sql = format!( + "UPDATE inflight_taskactivations SET status = $1 WHERE id = $2{RETURNING_COLUMNS}" + ); + let result: Option = sqlx::query_as(&sql) + .bind(status.to_string()) + .bind(id) + .fetch_optional(&mut *tx) + .await?; let Some(mut row) = result else { return Ok(None); @@ -964,13 +971,11 @@ impl ActivationStore for PostgresStore { if needs_update { let updated_activation = activation.encode_to_vec(); - sqlx::query( - "UPDATE inflight_taskactivations SET activation = $1 WHERE id = $2", - ) - .bind(&updated_activation) - .bind(id) - .execute(&mut *tx) - .await?; + sqlx::query("UPDATE inflight_taskactivations SET activation = $1 WHERE id = $2") + .bind(&updated_activation) + .bind(id) + .execute(&mut *tx) + .await?; row.activation = Cow::Owned(updated_activation); }