initial commit

This commit is contained in:
Pavel 2024-05-28 11:05:04 +03:00
commit 461b25829f
7 changed files with 104 additions and 0 deletions

3
.cargo/config.toml Normal file
View File

@ -0,0 +1,3 @@
[target.'cfg(target_os="macos")']
# Postgres symbols won't be available until runtime
rustflags = ["-Clink-arg=-Wl,-undefined,dynamic_lookup"]

6
.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
.DS_Store
.idea/
/target
*.iml
**/*.rs.bk
Cargo.lock

32
Cargo.toml Normal file
View File

@ -0,0 +1,32 @@
[package]
name = "pqddlread"
version = "0.0.0"
edition = "2021"
[lib]
crate-type = ["cdylib"]
[features]
default = ["pg13"]
pg11 = ["pgrx/pg11", "pgrx-tests/pg11" ]
pg12 = ["pgrx/pg12", "pgrx-tests/pg12" ]
pg13 = ["pgrx/pg13", "pgrx-tests/pg13" ]
pg14 = ["pgrx/pg14", "pgrx-tests/pg14" ]
pg15 = ["pgrx/pg15", "pgrx-tests/pg15" ]
pg16 = ["pgrx/pg16", "pgrx-tests/pg16" ]
pg_test = []
[dependencies]
pgrx = "=0.11.4"
[dev-dependencies]
pgrx-tests = "=0.11.4"
[profile.dev]
panic = "unwind"
[profile.release]
panic = "unwind"
opt-level = 3
lto = "fat"
codegen-units = 1

23
README.md Normal file
View File

@ -0,0 +1,23 @@
Базовый пример установки хука на `ExecutorEnd_hook`. Для наглядности в примере сразу вызывается сбой после завершения выполнения любого запроса.
Как выглядит работа:
```sql
psql (13.15)
Type "help" for help.
pqddlread=# create extension pqddlread;
CREATE EXTENSION
pqddlread=# -- Хук пока не установлен, все запросы выполняются.
pqddlread=# select 1;
?column?
----------
1
(1 row)
pqddlread=# -- Устанавливаем хук. Он сразу же заработает т.к. на момент завершения вызова функции хук уже стоит.
pqddlread=# select pqddlread();
ERROR: This panic indicates that hook was called successfully. Last query info: QueryDesc { operation: 1, plannedstmt: 0x5f9ec2a32650, sourceText: 0x5f9ec2958740, snapshot: 0x5f9ec29df648, crosscheck_snapshot: 0x0, dest: 0x5f9ec2a327c0, params: 0x0, queryEnv: 0x0, instrument_options: 0, tupDesc: 0x5f9ec2a2c3b0, estate: 0x5f9ec2a2bf70, planstate: 0x5f9ec2a2c1a8, already_executed: true, totaltime: 0x0 }
pqddlread=# -- Теперь ВСЕ запросы сломаны :)
pqddlread=# select 1;
ERROR: This panic indicates that hook was called successfully. Last query info: QueryDesc { operation: 1, plannedstmt: 0x5f9ec2a32458, sourceText: 0x5f9ec2958740, snapshot: 0x5f9ec2a1c868, crosscheck_snapshot: 0x0, dest: 0x5f9ec2a325c8, params: 0x0, queryEnv: 0x0, instrument_options: 0, tupDesc: 0x5f9ec29dfa50, estate: 0x5f9ec29df610, planstate: 0x5f9ec29df848, already_executed: true, totaltime: 0x0 }
pqddlread=# -- Хук выводит всю информацию о запросе. Мы можем делать с ней что угодно.
```

5
pqddlread.control Normal file
View File

@ -0,0 +1,5 @@
comment = 'pqddlread: Created by pgrx'
default_version = '@CARGO_VERSION@'
module_pathname = '$libdir/pqddlread'
relocatable = false
superuser = true

23
src/hook.rs Normal file
View File

@ -0,0 +1,23 @@
use pgrx::prelude::*;
use pgrx::hooks::PgHooks;
use pgrx::hooks::HookResult;
pub struct Catcher {}
impl Catcher {
pub fn new() -> &'static mut (dyn PgHooks + 'static) {
let val: &'static mut Catcher = Box::leak(Box::new(Catcher {}));
val
}
}
impl PgHooks for Catcher {
fn executor_finish(
&mut self,
query_desc: PgBox<pg_sys::QueryDesc>,
prev_hook: fn(query_desc: PgBox<pg_sys::QueryDesc>) -> HookResult<()>,
) -> HookResult<()> {
panic!("{}", format!("This panic indicates that hook was called successfully. Last query info: {:?}", query_desc));
prev_hook(query_desc)
}
}

12
src/lib.rs Normal file
View File

@ -0,0 +1,12 @@
use pgrx::prelude::*;
mod hook;
::pgrx::pg_module_magic!();
#[pg_extern]
fn pqddlread() {
unsafe {
pgrx::hooks::register_hook(hook::Catcher::new());
}
}