mirror of
https://github.com/t8y2/dbx.git
synced 2026-10-28 08:08:02 +00:00
fix(postgres): use pg_catalog instead of information_schema for table/schema listing
information_schema views apply permission filtering that causes empty results on openGauss/GaussDB for non-owner users. Switching to pg_catalog (pg_class + pg_namespace) matches the behavior of Navicat and DataGrip.
This commit is contained in:
@@ -171,20 +171,27 @@ impl AppState {
|
||||
let con = db::duckdb_driver::connect_path(&expand_tilde(&db_config.host))?;
|
||||
PoolKind::DuckDb(con)
|
||||
}
|
||||
DatabaseType::MongoDb => match db::mongo_driver::connect(&url).await {
|
||||
Ok(client) => {
|
||||
db::mongo_driver::test_connection(&client).await?;
|
||||
PoolKind::MongoDb(client)
|
||||
}
|
||||
Err(e) if e.contains("wire version") => {
|
||||
log::info!("Native MongoDB driver failed ({e}), falling back to agent driver");
|
||||
DatabaseType::MongoDb => {
|
||||
let native_err = match db::mongo_driver::connect(&url).await {
|
||||
Ok(client) => match db::mongo_driver::test_connection(&client).await {
|
||||
Ok(()) => {
|
||||
self.connections.write().await.insert(pool_key.clone(), PoolKind::MongoDb(client));
|
||||
return Ok(pool_key);
|
||||
}
|
||||
Err(e) => e,
|
||||
},
|
||||
Err(e) => e,
|
||||
};
|
||||
if native_err.contains("wire version") {
|
||||
log::info!("Native MongoDB driver failed ({native_err}), falling back to agent driver");
|
||||
let connect_params = serde_json::json!({ "connection": agent_connect_params(&db_config, &host, port, db_config.effective_database().unwrap_or("")) });
|
||||
let mut client = self.agent_manager.spawn(&DatabaseType::MongoDb, None).await?;
|
||||
client.call::<serde_json::Value>("connect", connect_params).await?;
|
||||
PoolKind::Agent(Arc::new(tokio::sync::Mutex::new(client)))
|
||||
} else {
|
||||
return Err(native_err);
|
||||
}
|
||||
Err(e) => return Err(e),
|
||||
},
|
||||
}
|
||||
DatabaseType::ClickHouse => {
|
||||
let username = if db_config.username.is_empty() { None } else { Some(db_config.username.clone()) };
|
||||
let password = if db_config.password.is_empty() { None } else { Some(db_config.password.clone()) };
|
||||
|
||||
@@ -201,11 +201,15 @@ pub async fn list_databases(pool: &PgPool) -> Result<Vec<DatabaseInfo>, String>
|
||||
|
||||
pub async fn list_tables(pool: &PgPool, schema: &str) -> Result<Vec<TableInfo>, String> {
|
||||
let rows: Vec<PgRow> = sqlx::query(
|
||||
"SELECT t.table_name, t.table_type, obj_description(c.oid) AS table_comment \
|
||||
FROM information_schema.tables t \
|
||||
LEFT JOIN pg_catalog.pg_class c ON c.relname = t.table_name \
|
||||
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace AND n.nspname = t.table_schema \
|
||||
WHERE t.table_schema = $1 ORDER BY t.table_name",
|
||||
"SELECT c.relname AS table_name, \
|
||||
CASE c.relkind WHEN 'r' THEN 'BASE TABLE' WHEN 'v' THEN 'VIEW' \
|
||||
WHEN 'm' THEN 'MATERIALIZED VIEW' WHEN 'f' THEN 'FOREIGN TABLE' \
|
||||
WHEN 'p' THEN 'BASE TABLE' END AS table_type, \
|
||||
obj_description(c.oid) AS table_comment \
|
||||
FROM pg_catalog.pg_class c \
|
||||
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace \
|
||||
WHERE n.nspname = $1 AND c.relkind IN ('r','v','m','f','p') \
|
||||
ORDER BY c.relname",
|
||||
)
|
||||
.bind(schema)
|
||||
.fetch_all(pool)
|
||||
@@ -224,11 +228,11 @@ pub async fn list_tables(pool: &PgPool, schema: &str) -> Result<Vec<TableInfo>,
|
||||
|
||||
pub async fn list_schemas(pool: &PgPool) -> Result<Vec<String>, String> {
|
||||
let rows: Vec<PgRow> = sqlx::query(
|
||||
"SELECT schema_name FROM information_schema.schemata \
|
||||
WHERE schema_name NOT IN ('information_schema', 'pg_catalog', 'pg_toast') \
|
||||
AND schema_name NOT LIKE 'pg_toast_temp_%' \
|
||||
AND schema_name NOT LIKE 'pg_temp_%' \
|
||||
ORDER BY schema_name",
|
||||
"SELECT n.nspname AS schema_name FROM pg_catalog.pg_namespace n \
|
||||
WHERE n.nspname NOT IN ('information_schema', 'pg_catalog', 'pg_toast') \
|
||||
AND n.nspname NOT LIKE 'pg_toast_temp_%' \
|
||||
AND n.nspname NOT LIKE 'pg_temp_%' \
|
||||
ORDER BY n.nspname",
|
||||
)
|
||||
.fetch_all(pool)
|
||||
.await
|
||||
|
||||
Reference in New Issue
Block a user