Skip to content

Commit a97208c

Browse files
postgres: use Oid type everywhere instead of u32 (#1602)
* postgres: use Oid type instead of u32 * Make serde happy * Expose the inner u32 * docs * Try to fix tests * Fix unit tests * Fix order * Not sure what happened here
1 parent a68957b commit a97208c

22 files changed

+270
-201
lines changed

sqlx-core/src/postgres/arguments.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ impl PgArguments {
9696

9797
for (offset, name) in type_holes {
9898
let oid = conn.fetch_type_id_by_name(&*name).await?;
99-
buffer[*offset..(*offset + 4)].copy_from_slice(&oid.to_be_bytes());
99+
buffer[*offset..(*offset + 4)].copy_from_slice(&oid.0.to_be_bytes());
100100
}
101101

102102
Ok(())

sqlx-core/src/postgres/connection/describe.rs

+20-16
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::ext::ustr::UStr;
33
use crate::postgres::message::{ParameterDescription, RowDescription};
44
use crate::postgres::statement::PgStatementMetadata;
55
use crate::postgres::type_info::{PgCustomType, PgType, PgTypeKind};
6+
use crate::postgres::types::Oid;
67
use crate::postgres::{PgArguments, PgColumn, PgConnection, PgTypeInfo};
78
use crate::query_as::query_as;
89
use crate::query_scalar::{query_scalar, query_scalar_with};
@@ -147,7 +148,7 @@ impl PgConnection {
147148

148149
async fn maybe_fetch_type_info_by_oid(
149150
&mut self,
150-
oid: u32,
151+
oid: Oid,
151152
should_fetch: bool,
152153
) -> Result<PgTypeInfo, Error> {
153154
// first we check if this is a built-in type
@@ -183,9 +184,9 @@ impl PgConnection {
183184
}
184185
}
185186

186-
fn fetch_type_by_oid(&mut self, oid: u32) -> BoxFuture<'_, Result<PgTypeInfo, Error>> {
187+
fn fetch_type_by_oid(&mut self, oid: Oid) -> BoxFuture<'_, Result<PgTypeInfo, Error>> {
187188
Box::pin(async move {
188-
let (name, typ_type, category, relation_id, element, base_type): (String, i8, i8, u32, u32, u32) = query_as(
189+
let (name, typ_type, category, relation_id, element, base_type): (String, i8, i8, Oid, Oid, Oid) = query_as(
189190
"SELECT typname, typtype, typcategory, typrelid, typelem, typbasetype FROM pg_catalog.pg_type WHERE oid = $1",
190191
)
191192
.bind(oid)
@@ -237,7 +238,7 @@ impl PgConnection {
237238
})
238239
}
239240

240-
async fn fetch_enum_by_oid(&mut self, oid: u32, name: String) -> Result<PgTypeInfo, Error> {
241+
async fn fetch_enum_by_oid(&mut self, oid: Oid, name: String) -> Result<PgTypeInfo, Error> {
241242
let variants: Vec<String> = query_scalar(
242243
r#"
243244
SELECT enumlabel
@@ -259,12 +260,12 @@ ORDER BY enumsortorder
259260

260261
fn fetch_composite_by_oid(
261262
&mut self,
262-
oid: u32,
263-
relation_id: u32,
263+
oid: Oid,
264+
relation_id: Oid,
264265
name: String,
265266
) -> BoxFuture<'_, Result<PgTypeInfo, Error>> {
266267
Box::pin(async move {
267-
let raw_fields: Vec<(String, u32)> = query_as(
268+
let raw_fields: Vec<(String, Oid)> = query_as(
268269
r#"
269270
SELECT attname, atttypid
270271
FROM pg_catalog.pg_attribute
@@ -296,8 +297,8 @@ ORDER BY attnum
296297

297298
fn fetch_domain_by_oid(
298299
&mut self,
299-
oid: u32,
300-
base_type: u32,
300+
oid: Oid,
301+
base_type: Oid,
301302
name: String,
302303
) -> BoxFuture<'_, Result<PgTypeInfo, Error>> {
303304
Box::pin(async move {
@@ -313,11 +314,11 @@ ORDER BY attnum
313314

314315
fn fetch_range_by_oid(
315316
&mut self,
316-
oid: u32,
317+
oid: Oid,
317318
name: String,
318319
) -> BoxFuture<'_, Result<PgTypeInfo, Error>> {
319320
Box::pin(async move {
320-
let element_oid: u32 = query_scalar(
321+
let element_oid: Oid = query_scalar(
321322
r#"
322323
SELECT rngsubtype
323324
FROM pg_catalog.pg_range
@@ -338,13 +339,13 @@ WHERE rngtypid = $1
338339
})
339340
}
340341

341-
pub(crate) async fn fetch_type_id_by_name(&mut self, name: &str) -> Result<u32, Error> {
342+
pub(crate) async fn fetch_type_id_by_name(&mut self, name: &str) -> Result<Oid, Error> {
342343
if let Some(oid) = self.cache_type_oid.get(name) {
343344
return Ok(*oid);
344345
}
345346

346347
// language=SQL
347-
let (oid,): (u32,) = query_as(
348+
let (oid,): (Oid,) = query_as(
348349
"
349350
SELECT oid FROM pg_catalog.pg_type WHERE typname ILIKE $1
350351
",
@@ -362,7 +363,7 @@ SELECT oid FROM pg_catalog.pg_type WHERE typname ILIKE $1
362363

363364
pub(crate) async fn get_nullable_for_columns(
364365
&mut self,
365-
stmt_id: u32,
366+
stmt_id: Oid,
366367
meta: &PgStatementMetadata,
367368
) -> Result<Vec<Option<bool>>, Error> {
368369
if meta.columns.is_empty() {
@@ -424,10 +425,13 @@ SELECT oid FROM pg_catalog.pg_type WHERE typname ILIKE $1
424425
/// and returns `None` for all others.
425426
async fn nullables_from_explain(
426427
&mut self,
427-
stmt_id: u32,
428+
stmt_id: Oid,
428429
params_len: usize,
429430
) -> Result<Vec<Option<bool>>, Error> {
430-
let mut explain = format!("EXPLAIN (VERBOSE, FORMAT JSON) EXECUTE sqlx_s_{}", stmt_id);
431+
let mut explain = format!(
432+
"EXPLAIN (VERBOSE, FORMAT JSON) EXECUTE sqlx_s_{}",
433+
stmt_id.0
434+
);
431435
let mut comma = false;
432436

433437
if params_len > 0 {

sqlx-core/src/postgres/connection/establish.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use crate::postgres::connection::{sasl, stream::PgStream, tls};
77
use crate::postgres::message::{
88
Authentication, BackendKeyData, MessageFormat, Password, ReadyForQuery, Startup,
99
};
10+
use crate::postgres::types::Oid;
1011
use crate::postgres::{PgConnectOptions, PgConnection};
1112

1213
// https://www.postgresql.org/docs/current/protocol-flow.html#id-1.10.5.7.3
@@ -143,7 +144,7 @@ impl PgConnection {
143144
transaction_status,
144145
transaction_depth: 0,
145146
pending_ready_for_query_count: 0,
146-
next_statement_id: 1,
147+
next_statement_id: Oid(1),
147148
cache_statement: StatementCache::new(options.statement_cache_capacity),
148149
cache_type_oid: HashMap::new(),
149150
cache_type_info: HashMap::new(),

sqlx-core/src/postgres/connection/executor.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use crate::postgres::message::{
88
};
99
use crate::postgres::statement::PgStatementMetadata;
1010
use crate::postgres::type_info::PgType;
11+
use crate::postgres::types::Oid;
1112
use crate::postgres::{
1213
statement::PgStatement, PgArguments, PgConnection, PgQueryResult, PgRow, PgTypeInfo,
1314
PgValueFormat, Postgres,
@@ -24,9 +25,9 @@ async fn prepare(
2425
sql: &str,
2526
parameters: &[PgTypeInfo],
2627
metadata: Option<Arc<PgStatementMetadata>>,
27-
) -> Result<(u32, Arc<PgStatementMetadata>), Error> {
28+
) -> Result<(Oid, Arc<PgStatementMetadata>), Error> {
2829
let id = conn.next_statement_id;
29-
conn.next_statement_id = conn.next_statement_id.wrapping_add(1);
30+
conn.next_statement_id.incr_one();
3031

3132
// build a list of type OIDs to send to the database in the PARSE command
3233
// we have not yet started the query sequence, so we are *safe* to cleanly make
@@ -169,7 +170,7 @@ impl PgConnection {
169170
// optional metadata that was provided by the user, this means they are reusing
170171
// a statement object
171172
metadata: Option<Arc<PgStatementMetadata>>,
172-
) -> Result<(u32, Arc<PgStatementMetadata>), Error> {
173+
) -> Result<(Oid, Arc<PgStatementMetadata>), Error> {
173174
if let Some(statement) = self.cache_statement.get_mut(sql) {
174175
return Ok((*statement).clone());
175176
}

sqlx-core/src/postgres/connection/mod.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use crate::postgres::message::{
1515
Close, Message, MessageFormat, Query, ReadyForQuery, Terminate, TransactionStatus,
1616
};
1717
use crate::postgres::statement::PgStatementMetadata;
18+
use crate::postgres::types::Oid;
1819
use crate::postgres::{PgConnectOptions, PgTypeInfo, Postgres};
1920
use crate::transaction::Transaction;
2021

@@ -46,14 +47,14 @@ pub struct PgConnection {
4647

4748
// sequence of statement IDs for use in preparing statements
4849
// in PostgreSQL, the statement is prepared to a user-supplied identifier
49-
next_statement_id: u32,
50+
next_statement_id: Oid,
5051

5152
// cache statement by query string to the id and columns
52-
cache_statement: StatementCache<(u32, Arc<PgStatementMetadata>)>,
53+
cache_statement: StatementCache<(Oid, Arc<PgStatementMetadata>)>,
5354

5455
// cache user-defined types by id <-> info
55-
cache_type_info: HashMap<u32, PgTypeInfo>,
56-
cache_type_oid: HashMap<UStr, u32>,
56+
cache_type_info: HashMap<Oid, PgTypeInfo>,
57+
cache_type_oid: HashMap<UStr, Oid>,
5758

5859
// number of ReadyForQuery messages that we are currently expecting
5960
pub(crate) pending_ready_for_query_count: usize,

sqlx-core/src/postgres/io/buf_mut.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1+
use crate::postgres::types::Oid;
2+
13
pub trait PgBufMutExt {
24
fn put_length_prefixed<F>(&mut self, f: F)
35
where
46
F: FnOnce(&mut Vec<u8>);
57

6-
fn put_statement_name(&mut self, id: u32);
8+
fn put_statement_name(&mut self, id: Oid);
79

8-
fn put_portal_name(&mut self, id: Option<u32>);
10+
fn put_portal_name(&mut self, id: Option<Oid>);
911
}
1012

1113
impl PgBufMutExt for Vec<u8> {
@@ -29,22 +31,22 @@ impl PgBufMutExt for Vec<u8> {
2931

3032
// writes a statement name by ID
3133
#[inline]
32-
fn put_statement_name(&mut self, id: u32) {
34+
fn put_statement_name(&mut self, id: Oid) {
3335
// N.B. if you change this don't forget to update it in ../describe.rs
3436
self.extend(b"sqlx_s_");
3537

36-
self.extend(itoa::Buffer::new().format(id).as_bytes());
38+
self.extend(itoa::Buffer::new().format(id.0).as_bytes());
3739

3840
self.push(0);
3941
}
4042

4143
// writes a portal name by ID
4244
#[inline]
43-
fn put_portal_name(&mut self, id: Option<u32>) {
45+
fn put_portal_name(&mut self, id: Option<Oid>) {
4446
if let Some(id) = id {
4547
self.extend(b"sqlx_p_");
4648

47-
self.extend(itoa::Buffer::new().format(id).as_bytes());
49+
self.extend(itoa::Buffer::new().format(id.0).as_bytes());
4850
}
4951

5052
self.push(0);

sqlx-core/src/postgres/message/bind.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
use crate::io::Encode;
22
use crate::postgres::io::PgBufMutExt;
3+
use crate::postgres::types::Oid;
34
use crate::postgres::PgValueFormat;
45

56
#[derive(Debug)]
67
pub struct Bind<'a> {
78
/// The ID of the destination portal (`None` selects the unnamed portal).
8-
pub portal: Option<u32>,
9+
pub portal: Option<Oid>,
910

1011
/// The id of the source prepared statement.
11-
pub statement: u32,
12+
pub statement: Oid,
1213

1314
/// The parameter format codes. Each must presently be zero (text) or one (binary).
1415
///

sqlx-core/src/postgres/message/close.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
use crate::io::Encode;
22
use crate::postgres::io::PgBufMutExt;
3+
use crate::postgres::types::Oid;
34

45
const CLOSE_PORTAL: u8 = b'P';
56
const CLOSE_STATEMENT: u8 = b'S';
67

78
#[derive(Debug)]
89
#[allow(dead_code)]
910
pub enum Close {
10-
Statement(u32),
11-
Portal(u32),
11+
Statement(Oid),
12+
Portal(Oid),
1213
}
1314

1415
impl Encode<'_> for Close {

sqlx-core/src/postgres/message/describe.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::io::Encode;
22
use crate::postgres::io::PgBufMutExt;
3+
use crate::postgres::types::Oid;
34

45
const DESCRIBE_PORTAL: u8 = b'P';
56
const DESCRIBE_STATEMENT: u8 = b'S';
@@ -10,10 +11,10 @@ const DESCRIBE_STATEMENT: u8 = b'S';
1011
#[allow(dead_code)]
1112
pub enum Describe {
1213
UnnamedStatement,
13-
Statement(u32),
14+
Statement(Oid),
1415

1516
UnnamedPortal,
16-
Portal(u32),
17+
Portal(Oid),
1718
}
1819

1920
impl Encode<'_> for Describe {
@@ -54,7 +55,7 @@ fn test_encode_describe_portal() {
5455
const EXPECTED: &[u8] = b"D\0\0\0\x0EPsqlx_p_5\0";
5556

5657
let mut buf = Vec::new();
57-
let m = Describe::Portal(5);
58+
let m = Describe::Portal(Oid(5));
5859

5960
m.encode(&mut buf);
6061

@@ -78,7 +79,7 @@ fn test_encode_describe_statement() {
7879
const EXPECTED: &[u8] = b"D\0\0\0\x0ESsqlx_s_5\0";
7980

8081
let mut buf = Vec::new();
81-
let m = Describe::Statement(5);
82+
let m = Describe::Statement(Oid(5));
8283

8384
m.encode(&mut buf);
8485

sqlx-core/src/postgres/message/execute.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use crate::io::Encode;
22
use crate::postgres::io::PgBufMutExt;
3+
use crate::postgres::types::Oid;
34

45
pub struct Execute {
56
/// The id of the portal to execute (`None` selects the unnamed portal).
6-
pub portal: Option<u32>,
7+
pub portal: Option<Oid>,
78

89
/// Maximum number of rows to return, if portal contains a query
910
/// that returns rows (ignored otherwise). Zero denotes “no limit”.
@@ -28,7 +29,7 @@ fn test_encode_execute() {
2829

2930
let mut buf = Vec::new();
3031
let m = Execute {
31-
portal: Some(5),
32+
portal: Some(Oid(5)),
3233
limit: 2,
3334
};
3435

sqlx-core/src/postgres/message/parameter_description.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ use smallvec::SmallVec;
33

44
use crate::error::Error;
55
use crate::io::Decode;
6+
use crate::postgres::types::Oid;
67

78
#[derive(Debug)]
89
pub struct ParameterDescription {
9-
pub types: SmallVec<[u32; 6]>,
10+
pub types: SmallVec<[Oid; 6]>,
1011
}
1112

1213
impl Decode<'_> for ParameterDescription {
@@ -15,7 +16,7 @@ impl Decode<'_> for ParameterDescription {
1516
let mut types = SmallVec::with_capacity(cnt as usize);
1617

1718
for _ in 0..cnt {
18-
types.push(buf.get_u32());
19+
types.push(Oid(buf.get_u32()));
1920
}
2021

2122
Ok(Self { types })
@@ -29,8 +30,8 @@ fn test_decode_parameter_description() {
2930
let m = ParameterDescription::decode(DATA.into()).unwrap();
3031

3132
assert_eq!(m.types.len(), 2);
32-
assert_eq!(m.types[0], 0x0000_0000);
33-
assert_eq!(m.types[1], 0x0000_0500);
33+
assert_eq!(m.types[0], Oid(0x0000_0000));
34+
assert_eq!(m.types[1], Oid(0x0000_0500));
3435
}
3536

3637
#[test]

0 commit comments

Comments
 (0)