Skip to content

Commit

Permalink
feat: Implement parameter status message for pgsrv (#102)
Browse files Browse the repository at this point in the history
* feat: Implement parameter status message for pgsrv

Sends parameter status messages when starting up a new connection.

Currently only sends `server_version`. This was enough to get pgJDBC to startup
properly. This was an attempt to try to get
benchbase (https://github.com/GlareDB/benchbase/tree/glaredb) running against a
glaredb server.

I have not gotten benchbase to successfully run a benchmark, see
#101.

* Include both byte and char reps in error string
  • Loading branch information
scsmithr authored Sep 16, 2022
1 parent 07a8868 commit 3e1ac1c
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 3 deletions.
7 changes: 6 additions & 1 deletion crates/pgsrv/src/codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ impl Encoder<BackendMessage> for PgCodec {
BackendMessage::AuthenticationOk => b'R',
BackendMessage::AuthenticationCleartextPassword => b'R',
BackendMessage::EmptyQueryResponse => b'I',
BackendMessage::ParameterStatus { .. } => b'S',
BackendMessage::ReadyForQuery(_) => b'Z',
BackendMessage::CommandComplete { .. } => b'C',
BackendMessage::RowDescription(_) => b'T',
Expand All @@ -197,6 +198,10 @@ impl Encoder<BackendMessage> for PgCodec {
BackendMessage::AuthenticationOk => dst.put_i32(0),
BackendMessage::AuthenticationCleartextPassword => dst.put_i32(3),
BackendMessage::EmptyQueryResponse => (),
BackendMessage::ParameterStatus { key, val } => {
dst.put_cstring(&key);
dst.put_cstring(&val);
}
BackendMessage::ReadyForQuery(status) => match status {
TransactionStatus::Idle => dst.put_u8(b'I'),
TransactionStatus::InBlock => dst.put_u8(b'T'),
Expand Down Expand Up @@ -279,7 +284,7 @@ impl Decoder for PgCodec {
let msg_len = i32::from_be_bytes(src[1..5].try_into().unwrap()) as usize;

// Not enough bytes to read the full message yet.
if src.len() < msg_len - 1 {
if src.len() < msg_len {
src.reserve(msg_len - src.len());
return Ok(None);
}
Expand Down
5 changes: 4 additions & 1 deletion crates/pgsrv/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ pub enum PgSrvError {
#[error("missing null byte")]
MissingNullByte,

#[error("invalid message type: {0}")]
/// We've received an unexpected message identifier from the frontend.
/// Includes the char representation to allow for easy cross referencing
/// with the Postgres message format documentation.
#[error("invalid message type: byte={0}, char={}", *.0 as char)]
InvalidMsgType(u8),

#[error(transparent)]
Expand Down
21 changes: 20 additions & 1 deletion crates/pgsrv/src/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@ use std::collections::HashMap;
use tokio::io::{AsyncRead, AsyncWrite, AsyncWriteExt};
use tracing::trace;

/// Default parameters to send to the frontend on startup. Existing postgres
/// drivers may expect these in the server response on startup.
///
/// See https://www.postgresql.org/docs/current/runtime-config-preset.html for
/// other parameters we may want to provide.
///
/// Some parameters will eventually be provided at runtime.
const DEFAULT_READ_ONLY_PARAMS: &[(&str, &str)] = &[("server_version", "0.0.0")];

/// A wrapper around a sqlengine that implements the Postgres frontend/backend
/// protocol.
pub struct Handler {
Expand Down Expand Up @@ -56,7 +65,7 @@ impl Handler {
}
}
StartupMessage::CancelRequest { .. } => {
trace!("recieved cancel request");
trace!("received cancel request");
// TODO: Properly handle requests to cancel sessions.

// Note that we should not respond to this request.
Expand Down Expand Up @@ -103,6 +112,16 @@ impl Handler {
}
};

// Send server parameters.
for (key, val) in DEFAULT_READ_ONLY_PARAMS {
framed
.send(BackendMessage::ParameterStatus {
key: key.to_string(),
val: val.to_string(),
})
.await?;
}

let cs = ClientSession::new(sess, framed);
cs.run().await
}
Expand Down
1 change: 1 addition & 0 deletions crates/pgsrv/src/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ pub enum BackendMessage {
NoticeResponse(NoticeResponse),
AuthenticationOk,
AuthenticationCleartextPassword,
ParameterStatus { key: String, val: String },
EmptyQueryResponse,
ReadyForQuery(TransactionStatus),
CommandComplete { tag: String },
Expand Down

0 comments on commit 3e1ac1c

Please sign in to comment.