pgdog.git / summary / log / commit / refs

commit    3f4da08ca5b889fc0808d17455e3846daadd131e
Author:   Lev Kokotov <levkk@users.noreply.github.com>
Commit:   GitHub <noreply@github.com>
Date:     Wed Sep 03 05:32:44 2025 +0000

    Per-statement routing test (#394)
    
    * Per-statement routing test
    
    * clippy


integration/rust/tests/integration/mod.rs | 1 + .../rust/tests/integration/per_stmt_routing.rs | 58 +++ pgdog-plugin/src/bindings.rs | 468 ++++++++------------- .../src/backend/pool/connection/mirror/handler.rs | 2 +- pgdog/src/frontend/router/parser/aggregate.rs | 91 ++-- pgdog/src/util.rs | 4 +- 6 files changed, 290 insertions(+), 334 deletions(-) diff --git a/integration/rust/tests/integration/mod.rs b/integration/rust/tests/integration/mod.rs index 6077e8cc..c15e0cc3 100644 --- a/integration/rust/tests/integration/mod.rs +++ b/integration/rust/tests/integration/mod.rs @@ -5,6 +5,7 @@ pub mod distinct; pub mod fake_transactions; pub mod maintenance_mode; pub mod notify; +pub mod per_stmt_routing; pub mod prepared; pub mod reload; pub mod set_sharding_key; diff --git a/integration/rust/tests/integration/per_stmt_routing.rs b/integration/rust/tests/integration/per_stmt_routing.rs new file mode 100644 index 00000000..fb089db4 --- /dev/null +++ b/integration/rust/tests/integration/per_stmt_routing.rs @@ -0,0 +1,58 @@ +use rust::setup::connections_sqlx; +use sqlx::{Acquire, Executor, Row}; + +#[tokio::test] +async fn per_stmt_routing() -> Result<(), Box<dyn std::error::Error>> { + let conns = connections_sqlx().await; + let sharded = conns.get(1).cloned().unwrap(); + + sharded + .execute( + "CREATE TABLE IF NOT EXISTS per_stmt_routing (customer_id BIGINT PRIMARY KEY, value VARCHAR)", + ) + .await?; + + sharded.execute("TRUNCATE TABLE per_stmt_routing").await?; + + for i in 0..50 { + sqlx::query("INSERT INTO per_stmt_routing (customer_id, value) VALUES ($1, $2)") + .bind(i as i64) + .bind(format!("test_{}", i)) + .execute(&sharded) + .await?; + } + + let mut conn = sharded.acquire().await?; + let mut tx = conn.begin().await?; + + for i in 0..50 { + // This will always return a row. + sqlx::query("SELECT * FROM per_stmt_routing WHERE customer_id = $1") + .bind(i as i64) + .fetch_one(&mut *tx) + .await?; + } + + let rows = sqlx::query("SELECT * FROM per_stmt_routing") + .fetch_all(&mut *tx) + .await?; + assert_eq!(rows.len(), 50); + + let count = sqlx::query("SELECT COUNT(*)::bigint FROM per_stmt_routing") + .fetch_one(&mut *tx) + .await?; + assert_eq!(count.get::<i64, _>(0), 50); + + for i in 50..100 { + // No duplicate key violations. + sqlx::query("INSERT INTO per_stmt_routing (customer_id, value) VALUES ($1, $2)") + .bind(i as i64) + .bind(format!("test_{}", i)) + .execute(&mut *tx) + .await?; + } + + tx.rollback().await?; + + Ok(()) +} diff --git a/pgdog-plugin/src/bindings.rs b/pgdog-plugin/src/bindings.rs index 6f47703d..55cbc159 100644 --- a/pgdog-plugin/src/bindings.rs +++ b/pgdog-plugin/src/bindings.rs @@ -1,338 +1,211 @@ /* automatically generated by rust-bindgen 0.71.1 */ +pub const _STDINT_H: u32 = 1; +pub const _FEATURES_H: u32 = 1; +pub const _DEFAULT_SOURCE: u32 = 1; +pub const __GLIBC_USE_ISOC2X: u32 = 0; +pub const __USE_ISOC11: u32 = 1; +pub const __USE_ISOC99: u32 = 1; +pub const __USE_ISOC95: u32 = 1; +pub const __USE_POSIX_IMPLICITLY: u32 = 1; +pub const _POSIX_SOURCE: u32 = 1; +pub const _POSIX_C_SOURCE: u32 = 200809; +pub const __USE_POSIX: u32 = 1; +pub const __USE_POSIX2: u32 = 1; +pub const __USE_POSIX199309: u32 = 1; +pub const __USE_POSIX199506: u32 = 1; +pub const __USE_XOPEN2K: u32 = 1; +pub const __USE_XOPEN2K8: u32 = 1; +pub const _ATFILE_SOURCE: u32 = 1; pub const __WORDSIZE: u32 = 64; -pub const __has_safe_buffers: u32 = 1; -pub const __DARWIN_ONLY_64_BIT_INO_T: u32 = 1; -pub const __DARWIN_ONLY_UNIX_CONFORMANCE: u32 = 1; -pub const __DARWIN_ONLY_VERS_1050: u32 = 1; -pub const __DARWIN_UNIX03: u32 = 1; -pub const __DARWIN_64_BIT_INO_T: u32 = 1; -pub const __DARWIN_VERS_1050: u32 = 1; -pub const __DARWIN_NON_CANCELABLE: u32 = 0; -pub const __DARWIN_SUF_EXTSN: &[u8; 14] = b"$DARWIN_EXTSN\0"; -pub const __DARWIN_C_ANSI: u32 = 4096; -pub const __DARWIN_C_FULL: u32 = 900000; -pub const __DARWIN_C_LEVEL: u32 = 900000; -pub const __STDC_WANT_LIB_EXT1__: u32 = 1; -pub const __DARWIN_NO_LONG_LONG: u32 = 0; -pub const _DARWIN_FEATURE_64_BIT_INODE: u32 = 1; -pub const _DARWIN_FEATURE_ONLY_64_BIT_INODE: u32 = 1; -pub const _DARWIN_FEATURE_ONLY_VERS_1050: u32 = 1; -pub const _DARWIN_FEATURE_ONLY_UNIX_CONFORMANCE: u32 = 1; -pub const _DARWIN_FEATURE_UNIX_CONFORMANCE: u32 = 3; -pub const __has_ptrcheck: u32 = 0; -pub const USE_CLANG_TYPES: u32 = 0; -pub const __PTHREAD_SIZE__: u32 = 8176; -pub const __PTHREAD_ATTR_SIZE__: u32 = 56; -pub const __PTHREAD_MUTEXATTR_SIZE__: u32 = 8; -pub const __PTHREAD_MUTEX_SIZE__: u32 = 56; -pub const __PTHREAD_CONDATTR_SIZE__: u32 = 8; -pub const __PTHREAD_COND_SIZE__: u32 = 40; -pub const __PTHREAD_ONCE_SIZE__: u32 = 8; -pub const __PTHREAD_RWLOCK_SIZE__: u32 = 192; -pub const __PTHREAD_RWLOCKATTR_SIZE__: u32 = 16; -pub const INT8_MAX: u32 = 127; -pub const INT16_MAX: u32 = 32767; -pub const INT32_MAX: u32 = 2147483647; -pub const INT64_MAX: u64 = 9223372036854775807; +pub const __WORDSIZE_TIME64_COMPAT32: u32 = 1; +pub const __SYSCALL_WORDSIZE: u32 = 64; +pub const __TIMESIZE: u32 = 64; +pub const __USE_MISC: u32 = 1; +pub const __USE_ATFILE: u32 = 1; +pub const __USE_FORTIFY_LEVEL: u32 = 0; +pub const __GLIBC_USE_DEPRECATED_GETS: u32 = 0; +pub const __GLIBC_USE_DEPRECATED_SCANF: u32 = 0; +pub const __GLIBC_USE_C2X_STRTOL: u32 = 0; +pub const _STDC_PREDEF_H: u32 = 1; +pub const __STDC_IEC_559__: u32 = 1; +pub const __STDC_IEC_60559_BFP__: u32 = 201404; +pub const __STDC_IEC_559_COMPLEX__: u32 = 1; +pub const __STDC_IEC_60559_COMPLEX__: u32 = 201404; +pub const __STDC_ISO_10646__: u32 = 201706; +pub const __GNU_LIBRARY__: u32 = 6; +pub const __GLIBC__: u32 = 2; +pub const __GLIBC_MINOR__: u32 = 39; +pub const _SYS_CDEFS_H: u32 = 1; +pub const __glibc_c99_flexarr_available: u32 = 1; +pub const __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI: u32 = 0; +pub const __HAVE_GENERIC_SELECTION: u32 = 1; +pub const __GLIBC_USE_LIB_EXT2: u32 = 0; +pub const __GLIBC_USE_IEC_60559_BFP_EXT: u32 = 0; +pub const __GLIBC_USE_IEC_60559_BFP_EXT_C2X: u32 = 0; +pub const __GLIBC_USE_IEC_60559_EXT: u32 = 0; +pub const __GLIBC_USE_IEC_60559_FUNCS_EXT: u32 = 0; +pub const __GLIBC_USE_IEC_60559_FUNCS_EXT_C2X: u32 = 0; +pub const __GLIBC_USE_IEC_60559_TYPES_EXT: u32 = 0; +pub const _BITS_TYPES_H: u32 = 1; +pub const _BITS_TYPESIZES_H: u32 = 1; +pub const __OFF_T_MATCHES_OFF64_T: u32 = 1; +pub const __INO_T_MATCHES_INO64_T: u32 = 1; +pub const __RLIM_T_MATCHES_RLIM64_T: u32 = 1; +pub const __STATFS_MATCHES_STATFS64: u32 = 1; +pub const __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64: u32 = 1; +pub const __FD_SETSIZE: u32 = 1024; +pub const _BITS_TIME64_H: u32 = 1; +pub const _BITS_WCHAR_H: u32 = 1; +pub const _BITS_STDINT_INTN_H: u32 = 1; +pub const _BITS_STDINT_UINTN_H: u32 = 1; +pub const _BITS_STDINT_LEAST_H: u32 = 1; pub const INT8_MIN: i32 = -128; pub const INT16_MIN: i32 = -32768; pub const INT32_MIN: i32 = -2147483648; -pub const INT64_MIN: i64 = -9223372036854775808; +pub const INT8_MAX: u32 = 127; +pub const INT16_MAX: u32 = 32767; +pub const INT32_MAX: u32 = 2147483647; pub const UINT8_MAX: u32 = 255; pub const UINT16_MAX: u32 = 65535; pub const UINT32_MAX: u32 = 4294967295; -pub const UINT64_MAX: i32 = -1; pub const INT_LEAST8_MIN: i32 = -128; pub const INT_LEAST16_MIN: i32 = -32768; pub const INT_LEAST32_MIN: i32 = -2147483648; -pub const INT_LEAST64_MIN: i64 = -9223372036854775808; pub const INT_LEAST8_MAX: u32 = 127; pub const INT_LEAST16_MAX: u32 = 32767; pub const INT_LEAST32_MAX: u32 = 2147483647; -pub const INT_LEAST64_MAX: u64 = 9223372036854775807; pub const UINT_LEAST8_MAX: u32 = 255; pub const UINT_LEAST16_MAX: u32 = 65535; pub const UINT_LEAST32_MAX: u32 = 4294967295; -pub const UINT_LEAST64_MAX: i32 = -1; pub const INT_FAST8_MIN: i32 = -128; -pub const INT_FAST16_MIN: i32 = -32768; -pub const INT_FAST32_MIN: i32 = -2147483648; -pub const INT_FAST64_MIN: i64 = -9223372036854775808; +pub const INT_FAST16_MIN: i64 = -9223372036854775808; +pub const INT_FAST32_MIN: i64 = -9223372036854775808; pub const INT_FAST8_MAX: u32 = 127; -pub const INT_FAST16_MAX: u32 = 32767; -pub const INT_FAST32_MAX: u32 = 2147483647; -pub const INT_FAST64_MAX: u64 = 9223372036854775807; +pub const INT_FAST16_MAX: u64 = 9223372036854775807; +pub const INT_FAST32_MAX: u64 = 9223372036854775807; pub const UINT_FAST8_MAX: u32 = 255; -pub const UINT_FAST16_MAX: u32 = 65535; -pub const UINT_FAST32_MAX: u32 = 4294967295; -pub const UINT_FAST64_MAX: i32 = -1; -pub const INTPTR_MAX: u64 = 9223372036854775807; +pub const UINT_FAST16_MAX: i32 = -1; +pub const UINT_FAST32_MAX: i32 = -1; pub const INTPTR_MIN: i64 = -9223372036854775808; +pub const INTPTR_MAX: u64 = 9223372036854775807; pub const UINTPTR_MAX: i32 = -1; -pub const SIZE_MAX: i32 = -1; -pub const RSIZE_MAX: i32 = -1; -pub const WINT_MIN: i32 = -2147483648; -pub const WINT_MAX: u32 = 2147483647; +pub const PTRDIFF_MIN: i64 = -9223372036854775808; +pub const PTRDIFF_MAX: u64 = 9223372036854775807; pub const SIG_ATOMIC_MIN: i32 = -2147483648; pub const SIG_ATOMIC_MAX: u32 = 2147483647; +pub const SIZE_MAX: i32 = -1; +pub const WINT_MIN: u32 = 0; +pub const WINT_MAX: u32 = 4294967295; pub type wchar_t = ::std::os::raw::c_int; -pub type max_align_t = f64; -pub type int_least8_t = i8; -pub type int_least16_t = i16; -pub type int_least32_t = i32; -pub type int_least64_t = i64; -pub type uint_least8_t = u8; -pub type uint_least16_t = u16; -pub type uint_least32_t = u32; -pub type uint_least64_t = u64; -pub type int_fast8_t = i8; -pub type int_fast16_t = i16; -pub type int_fast32_t = i32; -pub type int_fast64_t = i64; -pub type uint_fast8_t = u8; -pub type uint_fast16_t = u16; -pub type uint_fast32_t = u32; -pub type uint_fast64_t = u64; -pub type __int8_t = ::std::os::raw::c_schar; -pub type __uint8_t = ::std::os::raw::c_uchar; -pub type __int16_t = ::std::os::raw::c_short; -pub type __uint16_t = ::std::os::raw::c_ushort; -pub type __int32_t = ::std::os::raw::c_int; -pub type __uint32_t = ::std::os::raw::c_uint; -pub type __int64_t = ::std::os::raw::c_longlong; -pub type __uint64_t = ::std::os::raw::c_ulonglong; -pub type __darwin_intptr_t = ::std::os::raw::c_long; -pub type __darwin_natural_t = ::std::os::raw::c_uint; -pub type __darwin_ct_rune_t = ::std::os::raw::c_int; -#[repr(C)] -#[derive(Copy, Clone)] -pub union __mbstate_t { - pub __mbstate8: [::std::os::raw::c_char; 128usize], - pub _mbstateL: ::std::os::raw::c_longlong, -} -#[allow(clippy::unnecessary_operation, clippy::identity_op)] -const _: () = { - ["Size of __mbstate_t"][::std::mem::size_of::<__mbstate_t>() - 128usize]; - ["Alignment of __mbstate_t"][::std::mem::align_of::<__mbstate_t>() - 8usize]; - ["Offset of field: __mbstate_t::__mbstate8"] - [::std::mem::offset_of!(__mbstate_t, __mbstate8) - 0usize]; - ["Offset of field: __mbstate_t::_mbstateL"] - [::std::mem::offset_of!(__mbstate_t, _mbstateL) - 0usize]; -}; -pub type __darwin_mbstate_t = __mbstate_t; -pub type __darwin_ptrdiff_t = ::std::os::raw::c_long; -pub type __darwin_size_t = ::std::os::raw::c_ulong; -pub type __darwin_va_list = __builtin_va_list; -pub type __darwin_wchar_t = ::std::os::raw::c_int; -pub type __darwin_rune_t = __darwin_wchar_t; -pub type __darwin_wint_t = ::std::os::raw::c_int; -pub type __darwin_clock_t = ::std::os::raw::c_ulong; -pub type __darwin_socklen_t = __uint32_t; -pub type __darwin_ssize_t = ::std::os::raw::c_long; -pub type __darwin_time_t = ::std::os::raw::c_long; -pub type __darwin_blkcnt_t = __int64_t; -pub type __darwin_blksize_t = __int32_t; -pub type __darwin_dev_t = __int32_t; -pub type __darwin_fsblkcnt_t = ::std::os::raw::c_uint; -pub type __darwin_fsfilcnt_t = ::std::os::raw::c_uint; -pub type __darwin_gid_t = __uint32_t; -pub type __darwin_id_t = __uint32_t; -pub type __darwin_ino64_t = __uint64_t; -pub type __darwin_ino_t = __darwin_ino64_t; -pub type __darwin_mach_port_name_t = __darwin_natural_t; -pub type __darwin_mach_port_t = __darwin_mach_port_name_t; -pub type __darwin_mode_t = __uint16_t; -pub type __darwin_off_t = __int64_t; -pub type __darwin_pid_t = __int32_t; -pub type __darwin_sigset_t = __uint32_t; -pub type __darwin_suseconds_t = __int32_t; -pub type __darwin_uid_t = __uint32_t; -pub type __darwin_useconds_t = __uint32_t; -pub type __darwin_uuid_t = [::std::os::raw::c_uchar; 16usize]; -pub type __darwin_uuid_string_t = [::std::os::raw::c_char; 37usize]; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct __darwin_pthread_handler_rec { - pub __routine: ::std::option::Option<unsafe extern "C" fn(arg1: *mut ::std::os::raw::c_void)>, - pub __arg: *mut ::std::os::raw::c_void, - pub __next: *mut __darwin_pthread_handler_rec, -} -#[allow(clippy::unnecessary_operation, clippy::identity_op)] -const _: () = { - ["Size of __darwin_pthread_handler_rec"] - [::std::mem::size_of::<__darwin_pthread_handler_rec>() - 24usize]; - ["Alignment of __darwin_pthread_handler_rec"] - [::std::mem::align_of::<__darwin_pthread_handler_rec>() - 8usize]; - ["Offset of field: __darwin_pthread_handler_rec::__routine"] - [::std::mem::offset_of!(__darwin_pthread_handler_rec, __routine) - 0usize]; - ["Offset of field: __darwin_pthread_handler_rec::__arg"] - [::std::mem::offset_of!(__darwin_pthread_handler_rec, __arg) - 8usize]; - ["Offset of field: __darwin_pthread_handler_rec::__next"] - [::std::mem::offset_of!(__darwin_pthread_handler_rec, __next) - 16usize]; -}; #[repr(C)] +#[repr(align(16))] #[derive(Debug, Copy, Clone)] -pub struct _opaque_pthread_attr_t { - pub __sig: ::std::os::raw::c_long, - pub __opaque: [::std::os::raw::c_char; 56usize], +pub struct max_align_t { + pub __clang_max_align_nonce1: ::std::os::raw::c_longlong, + pub __bindgen_padding_0: u64, + pub __clang_max_align_nonce2: u128, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] const _: () = { - ["Size of _opaque_pthread_attr_t"][::std::mem::size_of::<_opaque_pthread_attr_t>() - 64usize]; - ["Alignment of _opaque_pthread_attr_t"] - [::std::mem::align_of::<_opaque_pthread_attr_t>() - 8usize]; - ["Offset of field: _opaque_pthread_attr_t::__sig"] - [::std::mem::offset_of!(_opaque_pthread_attr_t, __sig) - 0usize]; - ["Offset of field: _opaque_pthread_attr_t::__opaque"] - [::std::mem::offset_of!(_opaque_pthread_attr_t, __opaque) - 8usize]; -}; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct _opaque_pthread_cond_t { - pub __sig: ::std::os::raw::c_long, - pub __opaque: [::std::os::raw::c_char; 40usize], -} -#[allow(clippy::unnecessary_operation, clippy::identity_op)] -const _: () = { - ["Size of _opaque_pthread_cond_t"][::std::mem::size_of::<_opaque_pthread_cond_t>() - 48usize]; - ["Alignment of _opaque_pthread_cond_t"] - [::std::mem::align_of::<_opaque_pthread_cond_t>() - 8usize]; - ["Offset of field: _opaque_pthread_cond_t::__sig"] - [::std::mem::offset_of!(_opaque_pthread_cond_t, __sig) - 0usize]; - ["Offset of field: _opaque_pthread_cond_t::__opaque"] - [::std::mem::offset_of!(_opaque_pthread_cond_t, __opaque) - 8usize]; -}; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct _opaque_pthread_condattr_t { - pub __sig: ::std::os::raw::c_long, - pub __opaque: [::std::os::raw::c_char; 8usize], -} -#[allow(clippy::unnecessary_operation, clippy::identity_op)] -const _: () = { - ["Size of _opaque_pthread_condattr_t"] - [::std::mem::size_of::<_opaque_pthread_condattr_t>() - 16usize]; - ["Alignment of _opaque_pthread_condattr_t"] - [::std::mem::align_of::<_opaque_pthread_condattr_t>() - 8usize]; - ["Offset of field: _opaque_pthread_condattr_t::__sig"] - [::std::mem::offset_of!(_opaque_pthread_condattr_t, __sig) - 0usize]; - ["Offset of field: _opaque_pthread_condattr_t::__opaque"] - [::std::mem::offset_of!(_opaque_pthread_condattr_t, __opaque) - 8usize]; -}; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct _opaque_pthread_mutex_t { - pub __sig: ::std::os::raw::c_long, - pub __opaque: [::std::os::raw::c_char; 56usize], -} -#[allow(clippy::unnecessary_operation, clippy::identity_op)] -const _: () = { - ["Size of _opaque_pthread_mutex_t"][::std::mem::size_of::<_opaque_pthread_mutex_t>() - 64usize]; - ["Alignment of _opaque_pthread_mutex_t"] - [::std::mem::align_of::<_opaque_pthread_mutex_t>() - 8usize]; - ["Offset of field: _opaque_pthread_mutex_t::__sig"] - [::std::mem::offset_of!(_opaque_pthread_mutex_t, __sig) - 0usize]; - ["Offset of field: _opaque_pthread_mutex_t::__opaque"] - [::std::mem::offset_of!(_opaque_pthread_mutex_t, __opaque) - 8usize]; -}; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct _opaque_pthread_mutexattr_t { - pub __sig: ::std::os::raw::c_long, - pub __opaque: [::std::os::raw::c_char; 8usize], -} -#[allow(clippy::unnecessary_operation, clippy::identity_op)] -const _: () = { - ["Size of _opaque_pthread_mutexattr_t"] - [::std::mem::size_of::<_opaque_pthread_mutexattr_t>() - 16usize]; - ["Alignment of _opaque_pthread_mutexattr_t"] - [::std::mem::align_of::<_opaque_pthread_mutexattr_t>() - 8usize]; - ["Offset of field: _opaque_pthread_mutexattr_t::__sig"] - [::std::mem::offset_of!(_opaque_pthread_mutexattr_t, __sig) - 0usize]; - ["Offset of field: _opaque_pthread_mutexattr_t::__opaque"] - [::std::mem::offset_of!(_opaque_pthread_mutexattr_t, __opaque) - 8usize]; -}; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct _opaque_pthread_once_t { - pub __sig: ::std::os::raw::c_long, - pub __opaque: [::std::os::raw::c_char; 8usize], -} -#[allow(clippy::unnecessary_operation, clippy::identity_op)] -const _: () = { - ["Size of _opaque_pthread_once_t"][::std::mem::size_of::<_opaque_pthread_once_t>() - 16usize]; - ["Alignment of _opaque_pthread_once_t"] - [::std::mem::align_of::<_opaque_pthread_once_t>() - 8usize]; - ["Offset of field: _opaque_pthread_once_t::__sig"] - [::std::mem::offset_of!(_opaque_pthread_once_t, __sig) - 0usize]; - ["Offset of field: _opaque_pthread_once_t::__opaque"] - [::std::mem::offset_of!(_opaque_pthread_once_t, __opaque) - 8usize]; -}; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct _opaque_pthread_rwlock_t { - pub __sig: ::std::os::raw::c_long, - pub __opaque: [::std::os::raw::c_char; 192usize], -} -#[allow(clippy::unnecessary_operation, clippy::identity_op)] -const _: () = { - ["Size of _opaque_pthread_rwlock_t"] - [::std::mem::size_of::<_opaque_pthread_rwlock_t>() - 200usize]; - ["Alignment of _opaque_pthread_rwlock_t"] - [::std::mem::align_of::<_opaque_pthread_rwlock_t>() - 8usize]; - ["Offset of field: _opaque_pthread_rwlock_t::__sig"] - [::std::mem::offset_of!(_opaque_pthread_rwlock_t, __sig) - 0usize]; - ["Offset of field: _opaque_pthread_rwlock_t::__opaque"] - [::std::mem::offset_of!(_opaque_pthread_rwlock_t, __opaque) - 8usize]; -}; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct _opaque_pthread_rwlockattr_t { - pub __sig: ::std::os::raw::c_long, - pub __opaque: [::std::os::raw::c_char; 16usize], -} -#[allow(clippy::unnecessary_operation, clippy::identity_op)] -const _: () = { - ["Size of _opaque_pthread_rwlockattr_t"] - [::std::mem::size_of::<_opaque_pthread_rwlockattr_t>() - 24usize]; - ["Alignment of _opaque_pthread_rwlockattr_t"] - [::std::mem::align_of::<_opaque_pthread_rwlockattr_t>() - 8usize]; - ["Offset of field: _opaque_pthread_rwlockattr_t::__sig"] - [::std::mem::offset_of!(_opaque_pthread_rwlockattr_t, __sig) - 0usize]; - ["Offset of field: _opaque_pthread_rwlockattr_t::__opaque"] - [::std::mem::offset_of!(_opaque_pthread_rwlockattr_t, __opaque) - 8usize]; + ["Size of max_align_t"][::std::mem::size_of::<max_align_t>() - 32usize]; + ["Alignment of max_align_t"][::std::mem::align_of::<max_align_t>() - 16usize]; + ["Offset of field: max_align_t::__clang_max_align_nonce1"] + [::std::mem::offset_of!(max_align_t, __clang_max_align_nonce1) - 0usize]; + ["Offset of field: max_align_t::__clang_max_align_nonce2"] + [::std::mem::offset_of!(max_align_t, __clang_max_align_nonce2) - 16usize]; }; +pub type __u_char = ::std::os::raw::c_uchar; +pub type __u_short = ::std::os::raw::c_ushort; +pub type __u_int = ::std::os::raw::c_uint; +pub type __u_long = ::std::os::raw::c_ulong; +pub type __int8_t = ::std::os::raw::c_schar; +pub type __uint8_t = ::std::os::raw::c_uchar; +pub type __int16_t = ::std::os::raw::c_short; +pub type __uint16_t = ::std::os::raw::c_ushort; +pub type __int32_t = ::std::os::raw::c_int; +pub type __uint32_t = ::std::os::raw::c_uint; +pub type __int64_t = ::std::os::raw::c_long; +pub type __uint64_t = ::std::os::raw::c_ulong; +pub type __int_least8_t = __int8_t; +pub type __uint_least8_t = __uint8_t; +pub type __int_least16_t = __int16_t; +pub type __uint_least16_t = __uint16_t; +pub type __int_least32_t = __int32_t; +pub type __uint_least32_t = __uint32_t; +pub type __int_least64_t = __int64_t; +pub type __uint_least64_t = __uint64_t; +pub type __quad_t = ::std::os::raw::c_long; +pub type __u_quad_t = ::std::os::raw::c_ulong; +pub type __intmax_t = ::std::os::raw::c_long; +pub type __uintmax_t = ::std::os::raw::c_ulong; +pub type __dev_t = ::std::os::raw::c_ulong; +pub type __uid_t = ::std::os::raw::c_uint; +pub type __gid_t = ::std::os::raw::c_uint; +pub type __ino_t = ::std::os::raw::c_ulong; +pub type __ino64_t = ::std::os::raw::c_ulong; +pub type __mode_t = ::std::os::raw::c_uint; +pub type __nlink_t = ::std::os::raw::c_ulong; +pub type __off_t = ::std::os::raw::c_long; +pub type __off64_t = ::std::os::raw::c_long; +pub type __pid_t = ::std::os::raw::c_int; #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct _opaque_pthread_t { - pub __sig: ::std::os::raw::c_long, - pub __cleanup_stack: *mut __darwin_pthread_handler_rec, - pub __opaque: [::std::os::raw::c_char; 8176usize], +pub struct __fsid_t { + pub __val: [::std::os::raw::c_int; 2usize], } #[allow(clippy::unnecessary_operation, clippy::identity_op)] const _: () = { - ["Size of _opaque_pthread_t"][::std::mem::size_of::<_opaque_pthread_t>() - 8192usize]; - ["Alignment of _opaque_pthread_t"][::std::mem::align_of::<_opaque_pthread_t>() - 8usize]; - ["Offset of field: _opaque_pthread_t::__sig"] - [::std::mem::offset_of!(_opaque_pthread_t, __sig) - 0usize]; - ["Offset of field: _opaque_pthread_t::__cleanup_stack"] - [::std::mem::offset_of!(_opaque_pthread_t, __cleanup_stack) - 8usize]; - ["Offset of field: _opaque_pthread_t::__opaque"] - [::std::mem::offset_of!(_opaque_pthread_t, __opaque) - 16usize]; + ["Size of __fsid_t"][::std::mem::size_of::<__fsid_t>() - 8usize]; + ["Alignment of __fsid_t"][::std::mem::align_of::<__fsid_t>() - 4usize]; + ["Offset of field: __fsid_t::__val"][::std::mem::offset_of!(__fsid_t, __val) - 0usize]; }; -pub type __darwin_pthread_attr_t = _opaque_pthread_attr_t; -pub type __darwin_pthread_cond_t = _opaque_pthread_cond_t; -pub type __darwin_pthread_condattr_t = _opaque_pthread_condattr_t; -pub type __darwin_pthread_key_t = ::std::os::raw::c_ulong; -pub type __darwin_pthread_mutex_t = _opaque_pthread_mutex_t; -pub type __darwin_pthread_mutexattr_t = _opaque_pthread_mutexattr_t; -pub type __darwin_pthread_once_t = _opaque_pthread_once_t; -pub type __darwin_pthread_rwlock_t = _opaque_pthread_rwlock_t; -pub type __darwin_pthread_rwlockattr_t = _opaque_pthread_rwlockattr_t; -pub type __darwin_pthread_t = *mut _opaque_pthread_t; -pub type intmax_t = ::std::os::raw::c_long; -pub type uintmax_t = ::std::os::raw::c_ulong; +pub type __clock_t = ::std::os::raw::c_long; +pub type __rlim_t = ::std::os::raw::c_ulong; +pub type __rlim64_t = ::std::os::raw::c_ulong; +pub type __id_t = ::std::os::raw::c_uint; +pub type __time_t = ::std::os::raw::c_long; +pub type __useconds_t = ::std::os::raw::c_uint; +pub type __suseconds_t = ::std::os::raw::c_long; +pub type __suseconds64_t = ::std::os::raw::c_long; +pub type __daddr_t = ::std::os::raw::c_int; +pub type __key_t = ::std::os::raw::c_int; +pub type __clockid_t = ::std::os::raw::c_int; +pub type __timer_t = *mut ::std::os::raw::c_void; +pub type __blksize_t = ::std::os::raw::c_long; +pub type __blkcnt_t = ::std::os::raw::c_long; +pub type __blkcnt64_t = ::std::os::raw::c_long; +pub type __fsblkcnt_t = ::std::os::raw::c_ulong; +pub type __fsblkcnt64_t = ::std::os::raw::c_ulong; +pub type __fsfilcnt_t = ::std::os::raw::c_ulong; +pub type __fsfilcnt64_t = ::std::os::raw::c_ulong; +pub type __fsword_t = ::std::os::raw::c_long; +pub type __ssize_t = ::std::os::raw::c_long; +pub type __syscall_slong_t = ::std::os::raw::c_long; +pub type __syscall_ulong_t = ::std::os::raw::c_ulong; +pub type __loff_t = __off64_t; +pub type __caddr_t = *mut ::std::os::raw::c_char; +pub type __intptr_t = ::std::os::raw::c_long; +pub type __socklen_t = ::std::os::raw::c_uint; +pub type __sig_atomic_t = ::std::os::raw::c_int; +pub type int_least8_t = __int_least8_t; +pub type int_least16_t = __int_least16_t; +pub type int_least32_t = __int_least32_t; +pub type int_least64_t = __int_least64_t; +pub type uint_least8_t = __uint_least8_t; +pub type uint_least16_t = __uint_least16_t; +pub type uint_least32_t = __uint_least32_t; +pub type uint_least64_t = __uint_least64_t; +pub type int_fast8_t = ::std::os::raw::c_schar; +pub type int_fast16_t = ::std::os::raw::c_long; +pub type int_fast32_t = ::std::os::raw::c_long; +pub type int_fast64_t = ::std::os::raw::c_long; +pub type uint_fast8_t = ::std::os::raw::c_uchar; +pub type uint_fast16_t = ::std::os::raw::c_ulong; +pub type uint_fast32_t = ::std::os::raw::c_ulong; +pub type uint_fast64_t = ::std::os::raw::c_ulong; +pub type intmax_t = __intmax_t; +pub type uintmax_t = __uintmax_t; #[doc = " Wrapper around Rust's [`&str`], without allocating memory, unlike [`std::ffi::CString`].\n The caller must use it as a Rust string. This is not a C-string."] #[repr(C)] #[derive(Debug, Copy, Clone)] @@ -449,4 +322,3 @@ const _: () = { ["Offset of field: PdRoute::shard"][::std::mem::offset_of!(PdRoute, shard) - 0usize]; ["Offset of field: PdRoute::read_write"][::std::mem::offset_of!(PdRoute, read_write) - 8usize]; }; -pub type __builtin_va_list = *mut ::std::os::raw::c_char; diff --git a/pgdog/src/backend/pool/connection/mirror/handler.rs b/pgdog/src/backend/pool/connection/mirror/handler.rs index 0be585e4..7ae44b20 100644 --- a/pgdog/src/backend/pool/connection/mirror/handler.rs +++ b/pgdog/src/backend/pool/connection/mirror/handler.rs @@ -107,7 +107,7 @@ impl MirrorHandler { buffer: std::mem::take(&mut self.buffer), }) { Ok(()) => true, - Err(e) => { + Err(_) => { warn!("mirror buffer overflow, dropping transaction"); false } diff --git a/pgdog/src/frontend/router/parser/aggregate.rs b/pgdog/src/frontend/router/parser/aggregate.rs index da0f672a..fb3c0c90 100644 --- a/pgdog/src/frontend/router/parser/aggregate.rs +++ b/pgdog/src/frontend/router/parser/aggregate.rs @@ -1,7 +1,9 @@ use pg_query::protobuf::Integer; -use pg_query::protobuf::{self, a_const::Val, SelectStmt}; +use pg_query::protobuf::{a_const::Val, SelectStmt}; use pg_query::NodeEnum; +use crate::frontend::router::parser::Function; + use super::Error; #[derive(Debug, Clone, PartialEq)] @@ -58,39 +60,35 @@ impl Aggregate { for (idx, node) in stmt.target_list.iter().enumerate() { if let Some(NodeEnum::ResTarget(ref res)) = &node.node { if let Some(node) = &res.val { - if let Some(NodeEnum::FuncCall(func)) = &node.node { - if let Some(name) = func.funcname.first() { - if let Some(NodeEnum::String(protobuf::String { sval })) = &name.node { - match sval.as_str() { - "count" => { - targets.push(AggregateTarget { - column: idx, - function: AggregateFunction::Count, - }); - } - - "max" => { - targets.push(AggregateTarget { - column: idx, - function: AggregateFunction::Max, - }); - } - - "min" => { - targets.push(AggregateTarget { - column: idx, - function: AggregateFunction::Min, - }); - } - - "sum" => targets.push(AggregateTarget { - column: idx, - function: AggregateFunction::Max, - }), - - _ => {} - } + if let Ok(func) = Function::try_from(node.as_ref()) { + match func.name { + "count" => { + targets.push(AggregateTarget { + column: idx, + function: AggregateFunction::Count, + }); + } + + "max" => { + targets.push(AggregateTarget { + column: idx, + function: AggregateFunction::Max, + }); } + + "min" => { + targets.push(AggregateTarget { + column: idx, + function: AggregateFunction::Min, + }); + } + + "sum" => targets.push(AggregateTarget { + column: idx, + function: AggregateFunction::Max, + }), + + _ => {} } } } @@ -136,3 +134,30 @@ impl Aggregate { self.targets.len() } } + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_parse_aggregate() { + let query = pg_query::parse("SELECT COUNT(*)::bigint FROM users") + .unwrap() + .protobuf + .stmts + .first() + .cloned() + .unwrap(); + match query.stmt.unwrap().node.unwrap() { + NodeEnum::SelectStmt(stmt) => { + let aggr = Aggregate::parse(&stmt).unwrap(); + assert_eq!( + aggr.targets().first().unwrap().function, + AggregateFunction::Count + ); + } + + _ => panic!("not a select"), + } + } +} diff --git a/pgdog/src/util.rs b/pgdog/src/util.rs index 3dbd592b..f6bf6ad3 100644 --- a/pgdog/src/util.rs +++ b/pgdog/src/util.rs @@ -3,7 +3,7 @@ use chrono::{DateTime, Local, Utc}; use pgdog_plugin::comp; use rand::{distributions::Alphanumeric, Rng}; -use std::time::Duration; // 0.8 +use std::{ops::Deref, time::Duration}; // 0.8 pub fn format_time(time: DateTime<Local>) -> String { time.format("%Y-%m-%d %H:%M:%S%.3f %Z").to_string() @@ -82,7 +82,7 @@ pub fn pgdog_version() -> String { "v{} [main@{}, {}]", env!("CARGO_PKG_VERSION"), env!("GIT_HASH"), - comp::rustc_version().to_string() + comp::rustc_version().deref() ) } [parent: 615ff989567c]