feat: adopt dedicated PostgreSQL schema for Recoco internal tracking tables#94
Conversation
…m PR #1459) Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com>
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ❌ Deployment failed View logs |
recoco-docs | acf16dd | Mar 13 2026, 09:41 PM |
There was a problem hiding this comment.
Pull request overview
Adds an optional dedicated PostgreSQL schema for Recoco/CocoIndex internal tables to keep bookkeeping tables out of user-facing schemas.
Changes:
- Introduces
Settings.db_schema_nameand persists it globally for DB helpers. - Schema-qualifies internal metadata/tracking table SQL and creates the schema when configured (metadata path).
- Documents the new configuration option and adds deserialization tests.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| site/src/content/docs/reference/configuration.md | Documents db_schema_name and shows configuration example. |
| crates/recoco-core/src/setup/db_metadata.rs | Qualifies setup metadata table name and creates the schema before table creation. |
| crates/recoco-core/src/settings.rs | Adds db_schema_name to settings plus JSON deserialization tests. |
| crates/recoco-core/src/lib_context.rs | Stores configured internal schema in a global lock for synchronous access. |
| crates/recoco-core/src/execution/db_tracking_setup.rs | Adds helper to qualify internal table names with schema and updates rename/drop usage. |
| crates/recoco-core/src/execution/db_tracking.rs | Updates tracking table queries to use schema-qualified table names. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| let schema_name = get_internal_db_schema().unwrap_or_else(|| "public".to_string()); | ||
| let exists: Option<bool> = sqlx::query_scalar( | ||
| "SELECT EXISTS (SELECT 1 FROM pg_tables WHERE schemaname = 'public' AND tablename = $1)", | ||
| "SELECT EXISTS (SELECT 1 FROM pg_tables WHERE schemaname = $1 AND tablename = $2)", | ||
| ) | ||
| .bind(SETUP_METADATA_TABLE_NAME) | ||
| .bind(&schema_name) | ||
| .bind(SETUP_METADATA_TABLE_NAME_UNQUALIFIED) |
| @@ -38,14 +57,14 @@ async fn upgrade_tracking_table( | |||
| existing_version_id: i32, | |||
| ) -> Result<()> { | |||
| if existing_version_id < 1 && desired_state.version_id >= 1 { | |||
| let query = format!( | ||
| "CREATE TABLE IF NOT EXISTS {qualified_table_name} ( |
| }), | ||
|
|
||
| // Optional: store internal tracking tables in a dedicated schema | ||
| // instead of the default public schema |
|
|
||
| | Field | Type | Default | Description | | ||
| |-------|------|---------|-------------| | ||
| | `db_schema_name` | `Option<String>` | `None` | PostgreSQL schema for internal Recoco tracking/metadata tables. When set, a schema is auto-created and all internal tables are placed there, keeping them separate from application tables. When unset, the default schema (usually `public`) is used. | |
| pub fn get_internal_db_schema() -> Option<String> { | ||
| INTERNAL_DB_SCHEMA.read().unwrap().clone() | ||
| } |
|
@copilot apply changes based on the comments in this thread |
Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com>
Applied all four review fixes in acf16dd:
Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
Syncs the upstream CocoIndex architecture change (#1459): all Recoco-internal tables (
cocoindex_setup_metadata,<flow>__cocoindex_tracking,<flow>__cocoindex_srcstate) can now be isolated in a dedicated PostgreSQL schema, keeping them out of user-facing schemas.Changes
Settingsstruct (settings.rs)db_schema_name: Option<String>— when set, all internal tables are placed in that schema; defaults toNone(existing behavior, uses connection default schema)Global schema store (
lib_context.rs)INTERNAL_DB_SCHEMA(LazyLock<RwLock<Option<String>>>) — stores the configured schema at init time for synchronous access throughout DB helpersget_internal_db_schema() -> Option<String>public accessorcreate_lib_contextpersists the schema;clear_lib_contextclears it (test isolation)Schema qualification helpers
qualify_table_name_with_schema(table: &str) -> Stringindb_tracking_setup.rs— returnsschema.tableor plaintabledepending on configget_setup_metadata_table_name() -> Stringinsetup/db_metadata.rs— same for the metadata tableSQL operations (
db_tracking.rs,db_tracking_setup.rs,setup/db_metadata.rs)MetadataTableSetup::apply_changeissuesCREATE SCHEMA IF NOT EXISTSbefore table creation when a schema is configuredread_setup_metadata— parameterizedschemaname/tablenamequery instead of hardcodedschemaname = 'public'Usage
When
db_schema_nameisNone(default), behavior is unchanged — tables land in the connection's default schema.Documentation (
site/src/content/docs/reference/configuration.md)db_schema_nameto the settings reference with example and behavioral notesWarning
Firewall rules blocked me from connecting to one or more addresses (expand for details)
I tried to connect to the following addresses, but was blocked by firewall rules:
test/home/REDACTED/work/recoco/recoco/target/debug/deps/recoco_core-e9addf7bc802a9c3 /home/REDACTED/work/recoco/recoco/target/debug/deps/recoco_core-e9addf7bc802a9c3 /home/REDACTED/.rustup/toolchains/stable-x86_64-REDACTED-linux-gnu/lib/rustlib/x86_-z /home/REDACTED/.rustup/toolchains/stable-x86_64-REDACTED-linux-gnu/lib/rustlib/x86_relro /home/REDACTED/.rustup/toolchains/stable-x86_64-REDACTED-linux-gnu/lib/rustlib/x86_-o /home/REDACTED/.rustup/toolchains/stable-x86_64-REDACTED-linux-gnu/lib/rustlib/x86_/home/REDACTED/work/recoco/recoco/target/debug/deps/libasync_openai_macros-b4a0e9c4e5088142.so /home/REDACTED/.rustup/toolchains/stable-x86_64-REDACTED-linux-gnu/lib/rustlib/x86_/usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu/crti.o /home/REDACTED/.rustup/toolchains/stable-x86_64-REDACTED-linux-gnu/lib/rustlib/x86_/usr/lib/gcc/x86_64-linux-gnu/13/crtbeginS.o /src/lib.rs /home/REDACTED/.rustup/toolchains/stable-x86_64-REDACTED-linux-gnu/lib/rustlib/x86_-L/home/REDACTED/.rustup/toolchains/stable-x86_64-REDACTED-linux-gnu/lib/rustlib/x86_64-REDACTED-linux-gnu/lib /home/REDACTED/.rustup/toolchains/stable-x86_64-REDACTED-linux-gnu/lib/rustlib/x86_64-u�� /home/REDACTED/.rustup/toolchains/stable-x86_64-REDACTED-linux-gnu/lib/rustlib/x86_64-REDACTED-linux-gnu/lib/librustc_std_workspace_alloc-1aa74596e1d30fe3.rlib /home/REDACTED/.rustup/toolchains/stable-x86_64-REDACTED-linux-gnu/lib/rustlib/x86_64-REDACTED-linux-gnu/lib/libminiz_oxide-92023c1cb0992e10.rlib -194�� ld/blake3-1ddee7/home/REDACTED/work/recoco/recoco/target/debug/deps/indoc-c245401abdd5e8b3.indoc.3/home/REDACTED/.rustup/toolchains/stable-x86_64-REDACTED-linux-gnu/lib/rustlib/x86_64-REDACTED-linux-gnu/bin/rust-lld -1949cf8c6b5b557/home/REDACTED/work/recoco/recoco/target/debug/deps/indoc-c245401abdd5e8b3.indoc.3-flavor f/schemars_deriv/home/REDACTED/work/recoco/recoco/target/debug/deps/indoc-c245401abdd5e8b3.indoc.3gnu -g /index.crates.io-m64 d36f965af7/out/b/home/REDACTED/work/recoco/recoco/target/debug/build/thiserror-807aad773eed03cf/ru-plugin-opt=/usr/libexec/gcc/x86_64-linux-gnu/13/lto-wrapper /index.crates.io/home/REDACTED/work/recoco/recoco/target/debug/build/thiserror-807aad773eed03cf/bu-plugin-opt=-fresolution=/tmp/ccpL1iwf.res(dns block)/home/REDACTED/work/recoco/recoco/target/debug/deps/recoco_core-e9addf7bc802a9c3 /home/REDACTED/work/recoco/recoco/target/debug/deps/recoco_core-e9addf7bc802a9c3 debuginfo=2 -C debug-assertions=on 0d67�� 0d6780f47d96841.derive_where.ee2dcf92753f67b2-cgu.05.rcgu.o 0d6780f47d96841.derive_where.ee2dcf92753f67b2-cgu.06.rcgu.o bin/rustc 0d6780f47d96841./home/REDACTED/.rustup/toolchains/stable-x86_64-REDACTED-linux-gnu/bin/rustc dbdd36-cgu.0.rcg--crate-name u.o bin/rustc 0d67�� 0d6780f47d96841.--error-format=json 0d6780f47d96841.--json=diagnostic-rendered-ansi,artifacts,future-incompat bin/rustc /lto-wrapper ul_p384.o ul_p384_alt.o bin/rustc(dns block)/home/REDACTED/work/recoco/recoco/target/debug/deps/recoco_core-e9addf7bc802a9c3 /home/REDACTED/work/recoco/recoco/target/debug/deps/recoco_core-e9addf7bc802a9c3 _macro-2f105f69e--crate-name _macro-2f105f69earraydeque bin/rustc _mac�� a.rs stable-x86_64-un--json=diagnostic-rendered-ansi,artifacts,future-incompat f/rustls-0.23.36--crate-type f98bb5df7b618.rliptables e-8f6043c0591a70-w 462bfddf44ae.rli-t 463b17398.rlib 3026�� e050294cd.rlib 7d0200b95c8.rlib-C ld/mime_guess-4bcodegen-units=256 s/async_stream_igit s/async_stream_ishow s/libunicase-10b30ba25993b1599363559dccc5b12ede21141733f:crates/recoco-core/src/execution/db_tracking.rs known-linux-gnu/debug-assertions=on(dns block)If you need me to access, download, or install something from one of these locations, you can either:
Original prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.