Skip to content
This repository was archived by the owner on Jan 14, 2025. It is now read-only.

Commit ace81c7

Browse files
kelvichJulius de Bruijn
authored and
Julius de Bruijn
committed
Return more RowDescription fields
As we are trying to match client-side behaviour with node-postgres we need to return this fields as well because node-postgres returns them.
1 parent 76fb906 commit ace81c7

File tree

4 files changed

+84
-5
lines changed

4 files changed

+84
-5
lines changed

tokio-postgres/src/client.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -445,8 +445,10 @@ impl Client {
445445
if let Some(row_description) = row_description {
446446
let mut it = row_description.fields();
447447
while let Some(field) = it.next().map_err(Error::parse)? {
448+
// NB: for some types that function may send a query to the server. At least in
449+
// raw text mode we don't need that info and can skip this.
448450
let type_ = get_type(&self.inner, field.type_oid()).await?;
449-
let column = Column::new(field.name().to_string(), type_);
451+
let column = Column::new(field.name().to_string(), type_, field);
450452
columns.push(column);
451453
}
452454
}

tokio-postgres/src/prepare.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ pub async fn prepare(
9595
let mut it = row_description.fields();
9696
while let Some(field) = it.next().map_err(Error::parse)? {
9797
let type_ = get_type(client, field.type_oid()).await?;
98-
let column = Column::new(field.name().to_string(), type_);
98+
let column = Column::new(field.name().to_string(), type_, field);
9999
columns.push(column);
100100
}
101101
}

tokio-postgres/src/statement.rs

+55-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ use crate::client::InnerClient;
22
use crate::codec::FrontendMessage;
33
use crate::connection::RequestMessages;
44
use crate::types::Type;
5-
use postgres_protocol::message::frontend;
5+
use postgres_protocol::{
6+
message::{backend::Field, frontend},
7+
Oid,
8+
};
69
use postgres_types::Format;
710
use std::{
811
fmt,
@@ -91,11 +94,30 @@ impl Statement {
9194
pub struct Column {
9295
name: String,
9396
type_: Type,
97+
98+
// raw fields from RowDescription
99+
table_oid: Oid,
100+
column_id: i16,
101+
format: i16,
102+
103+
// that better be stored in self.type_, but that is more radical refactoring
104+
type_oid: Oid,
105+
type_size: i16,
106+
type_modifier: i32,
94107
}
95108

96109
impl Column {
97-
pub(crate) fn new(name: String, type_: Type) -> Column {
98-
Column { name, type_ }
110+
pub(crate) fn new(name: String, type_: Type, raw_field: Field<'_>) -> Column {
111+
Column {
112+
name,
113+
type_,
114+
table_oid: raw_field.table_oid(),
115+
column_id: raw_field.column_id(),
116+
format: raw_field.format(),
117+
type_oid: raw_field.type_oid(),
118+
type_size: raw_field.type_size(),
119+
type_modifier: raw_field.type_modifier(),
120+
}
99121
}
100122

101123
/// Returns the name of the column.
@@ -107,6 +129,36 @@ impl Column {
107129
pub fn type_(&self) -> &Type {
108130
&self.type_
109131
}
132+
133+
/// Returns the table OID of the column.
134+
pub fn table_oid(&self) -> Oid {
135+
self.table_oid
136+
}
137+
138+
/// Returns the column ID of the column.
139+
pub fn column_id(&self) -> i16 {
140+
self.column_id
141+
}
142+
143+
/// Returns the format of the column.
144+
pub fn format(&self) -> i16 {
145+
self.format
146+
}
147+
148+
/// Returns the type OID of the column.
149+
pub fn type_oid(&self) -> Oid {
150+
self.type_oid
151+
}
152+
153+
/// Returns the type size of the column.
154+
pub fn type_size(&self) -> i16 {
155+
self.type_size
156+
}
157+
158+
/// Returns the type modifier of the column.
159+
pub fn type_modifier(&self) -> i32 {
160+
self.type_modifier
161+
}
110162
}
111163

112164
impl fmt::Debug for Column {

tokio-postgres/tests/test/main.rs

+25
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,31 @@ async fn command_tag() {
353353
assert_eq!(row_stream.command_tag(), Some("SELECT 3".to_string()));
354354
}
355355

356+
#[tokio::test]
357+
async fn column_extras() {
358+
let client = connect("user=postgres").await;
359+
360+
let rows: Vec<tokio_postgres::Row> = client
361+
.query_raw_txt("select relacl, relname from pg_class limit 1", [])
362+
.await
363+
.unwrap()
364+
.try_collect()
365+
.await
366+
.unwrap();
367+
368+
let column = rows[0].columns().get(1).unwrap();
369+
assert_eq!(column.name(), "relname");
370+
assert_eq!(column.type_(), &Type::NAME);
371+
372+
assert!(column.table_oid() > 0);
373+
assert_eq!(column.column_id(), 2);
374+
assert_eq!(column.format(), 0);
375+
376+
assert_eq!(column.type_oid(), 19);
377+
assert_eq!(column.type_size(), 64);
378+
assert_eq!(column.type_modifier(), -1);
379+
}
380+
356381
#[tokio::test]
357382
async fn custom_composite() {
358383
let client = connect("user=postgres").await;

0 commit comments

Comments
 (0)