Skip to content

Commit

Permalink
fix: Load httpfs & Store DuckDB extensions in PGDATA (#200)
Browse files Browse the repository at this point in the history
* try to load httpfs

* Make read-only

* Fix

* try this

* Set extension path to PGDATA dir

* rm chmod and codecov

* also rm above

* cargo fmt

---------

Co-authored-by: Ming Ying <[email protected]>
  • Loading branch information
philippemnoel and rebasedming authored Jan 31, 2025
1 parent 7a67e82 commit 82229a1
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 10 deletions.
10 changes: 0 additions & 10 deletions .github/workflows/test-pg_analytics.yml
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,6 @@ jobs:
LLVM_PROFILE_FILE: target/coverage/pg_analytics-%p-%m.profraw
RUST_BACKTRACE: full
run: |
echo ""
echo "Enabling code coverage..."
echo -e "\n# Enable code coverage on Linux only, for CI builds\n[target.'cfg(target_os=\"linux\")']\nrustflags = [\"-Cinstrument-coverage\"]" >> .cargo/config.toml
mkdir -p target/coverage target/coverage-report
echo ""
echo "Running Rust tests..."
export DATABASE_URL=postgresql://localhost:288${{ matrix.pg_version }}/postgres
Expand Down Expand Up @@ -267,11 +262,6 @@ jobs:
LLVM_PROFILE_FILE: target/coverage/pg_analytics-%p-%m.profraw
RUST_BACKTRACE: full
run: |
echo ""
echo "Enabling code coverage..."
echo -e "\n# Enable code coverage on Linux only, for CI builds\n[target.'cfg(target_os=\"linux\")']\nrustflags = [\"-Cinstrument-coverage\"]" >> .cargo/config.toml
mkdir -p target/coverage target/coverage-report
echo ""
echo "Running Rust tests..."
export DATABASE_URL=postgresql://localhost:288${{ matrix.pg_version }}/postgres
Expand Down
18 changes: 18 additions & 0 deletions src/duckdb/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,16 @@ pub fn set_search_path(search_path: Vec<String>) -> Result<()> {
Ok(())
}

pub fn set_duckdb_extension_directory(extension_directory_path: &str) -> Result<()> {
// Set duckdb extension directory
execute(
format!("SET extension_directory = '{extension_directory_path}'").as_str(),
[],
)?;

Ok(())
}

pub fn execute_explain(query: &str) -> Result<String> {
let conn = unsafe { &*get_global_connection().get() };
let mut stmt = conn.prepare(query)?;
Expand All @@ -272,3 +282,11 @@ pub fn execute_explain(query: &str) -> Result<String> {

Ok(rows.join(""))
}

pub fn install_httpfs() -> Result<()> {
if !check_extension_loaded("httpfs")? {
execute("INSTALL httpfs", [])?;
execute("LOAD httpfs", [])?;
}
Ok(())
}
15 changes: 15 additions & 0 deletions src/fdw/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,16 @@ use anyhow::{anyhow, bail, Result};
use duckdb::arrow::array::RecordBatch;
use pgrx::*;
use std::collections::HashMap;
use std::ffi::CStr;
use strum::IntoEnumIterator;
use supabase_wrappers::prelude::*;
use thiserror::Error;

use super::handler::FdwHandler;
use crate::duckdb::connection;
use crate::fdw::base::connection::set_duckdb_extension_directory;
use crate::schema::cell::*;

#[cfg(debug_assertions)]
use crate::DEBUG_GUCS;

Expand Down Expand Up @@ -223,6 +226,18 @@ pub fn register_duckdb_view(
connection::create_secret(DEFAULT_SECRET, user_mapping_options)?;
}

// In CloudNativePG, the filesystem is read-only. To work around this, we force
// DuckDB to install its extensions in the PGDATA directory, which is writable.
let data_dir = unsafe {
CStr::from_ptr(pgrx::pg_sys::DataDir)
.to_str()
.map_err(|e| anyhow::anyhow!("Failed to convert DataDir to &str: {}", e))?
};
let _ = set_duckdb_extension_directory(data_dir);

// duckdb-rs stopped bundling in httpfs, so we need to load it ourselves
connection::install_httpfs()?;

if !connection::view_exists(table_name, schema_name)? {
// Initialize DuckDB view
connection::execute(
Expand Down

0 comments on commit 82229a1

Please sign in to comment.