mz_pgwire/
message.rs

1// Copyright Materialize, Inc. and contributors. All rights reserved.
2//
3// Use of this software is governed by the Business Source License
4// included in the LICENSE file.
5//
6// As of the Change Date specified in that file, in accordance with
7// the Business Source License, use of this software will be governed
8// by the Apache License, Version 2.0.
9
10use enum_kinds::EnumKind;
11use itertools::Itertools;
12use mz_adapter::session::TransactionCode;
13use mz_pgwire_common::ErrorResponse;
14use mz_repr::{ColumnName, RelationDesc};
15
16/// Internal representation of a backend [message]
17///
18/// [message]: https://www.postgresql.org/docs/11/protocol-message-formats.html
19#[derive(Debug, EnumKind)]
20#[enum_kind(BackendMessageKind)]
21pub enum BackendMessage {
22    AuthenticationOk,
23    AuthenticationCleartextPassword,
24    CommandComplete {
25        tag: String,
26    },
27    EmptyQueryResponse,
28    ReadyForQuery(TransactionCode),
29    RowDescription(Vec<FieldDescription>),
30    DataRow(Vec<Option<mz_pgrepr::Value>>),
31    ParameterStatus(&'static str, String),
32    BackendKeyData {
33        conn_id: u32,
34        secret_key: u32,
35    },
36    ParameterDescription(Vec<mz_pgrepr::Type>),
37    PortalSuspended,
38    NoData,
39    ParseComplete,
40    BindComplete,
41    CloseComplete,
42    ErrorResponse(ErrorResponse),
43    CopyInResponse {
44        overall_format: mz_pgwire_common::Format,
45        column_formats: Vec<mz_pgwire_common::Format>,
46    },
47    CopyOutResponse {
48        overall_format: mz_pgwire_common::Format,
49        column_formats: Vec<mz_pgwire_common::Format>,
50    },
51    CopyData(Vec<u8>),
52    CopyDone,
53}
54
55impl From<ErrorResponse> for BackendMessage {
56    fn from(err: ErrorResponse) -> BackendMessage {
57        BackendMessage::ErrorResponse(err)
58    }
59}
60
61#[derive(Debug)]
62pub struct FieldDescription {
63    pub name: ColumnName,
64    pub table_id: u32,
65    pub column_id: u16,
66    pub type_oid: u32,
67    pub type_len: i16,
68    pub type_mod: i32,
69    pub format: mz_pgwire_common::Format,
70}
71
72pub fn encode_row_description(
73    desc: &RelationDesc,
74    formats: &[mz_pgwire_common::Format],
75) -> Vec<FieldDescription> {
76    desc.iter()
77        .zip_eq(formats)
78        .map(|((name, typ), format)| {
79            let pg_type = mz_pgrepr::Type::from(&typ.scalar_type);
80            FieldDescription {
81                name: name.clone(),
82                table_id: 0,
83                column_id: 0,
84                type_oid: pg_type.oid(),
85                type_len: pg_type.typlen(),
86                type_mod: pg_type.typmod(),
87                format: *format,
88            }
89        })
90        .collect()
91}