From f9a22b7af047d3bcc45e159aa054d4bd198b183b Mon Sep 17 00:00:00 2001 From: Sean Evans Date: Wed, 20 May 2026 10:34:26 -0400 Subject: [PATCH] Qualify pg_git object references in SQL definitions --- sql/functions/001-init.sql | 4 +- sql/functions/003-commit.sql | 6 +-- sql/functions/004-log.sql | 8 ++-- sql/functions/005-status.sql | 6 +-- sql/functions/006-branch.sql | 16 +++---- sql/functions/007-merge.sql | 20 ++++----- sql/functions/008-diff.sql | 12 +++--- sql/functions/009-reset.sql | 6 +-- sql/functions/010-tag.sql | 4 +- sql/functions/011-remote.sql | 8 ++-- sql/functions/013-merge-conflicts.sql | 10 ++--- sql/functions/014-https.sql | 2 +- sql/functions/015-admin.sql | 48 ++++++++++----------- sql/schema/001-core.sql | 40 ++++++++--------- sql/schema/pgit-schema.sql | 2 +- test/sql/search_path_qualification_test.sql | 37 ++++++++++++++++ 16 files changed, 133 insertions(+), 96 deletions(-) create mode 100644 test/sql/search_path_qualification_test.sql diff --git a/sql/functions/001-init.sql b/sql/functions/001-init.sql index d24b9d7..d454b54 100644 --- a/sql/functions/001-init.sql +++ b/sql/functions/001-init.sql @@ -1,4 +1,4 @@ -CREATE TABLE repositories ( +CREATE TABLE pg_git.repositories ( id SERIAL PRIMARY KEY, name TEXT NOT NULL, path TEXT NOT NULL UNIQUE, @@ -15,7 +15,7 @@ DECLARE v_initial_commit TEXT; BEGIN -- Create repository record - INSERT INTO repositories (name, path) + INSERT INTO pg_git.repositories (name, path) VALUES (p_name, p_path) RETURNING id INTO v_repo_id; diff --git a/sql/functions/003-commit.sql b/sql/functions/003-commit.sql index 7057ba1..d5d764a 100644 --- a/sql/functions/003-commit.sql +++ b/sql/functions/003-commit.sql @@ -38,7 +38,7 @@ DECLARE BEGIN -- Get current HEAD SELECT commit_hash INTO v_parent_hash - FROM refs + FROM pg_git.refs WHERE repo_id = p_repo_id AND name = 'HEAD'; -- Create tree from index @@ -54,8 +54,8 @@ BEGIN ); -- Update HEAD and branch reference - UPDATE refs SET commit_hash = v_commit_hash WHERE repo_id = p_repo_id AND name = 'HEAD'; - UPDATE refs + UPDATE pg_git.refs SET commit_hash = v_commit_hash WHERE repo_id = p_repo_id AND name = 'HEAD'; + UPDATE pg_git.refs SET commit_hash = v_commit_hash WHERE repo_id = p_repo_id AND commit_hash = v_parent_hash diff --git a/sql/functions/004-log.sql b/sql/functions/004-log.sql index 0c43798..19c8513 100644 --- a/sql/functions/004-log.sql +++ b/sql/functions/004-log.sql @@ -17,19 +17,19 @@ DECLARE BEGIN -- Get HEAD commit SELECT commit_hash INTO v_head_commit - FROM refs + FROM pg_git.refs WHERE repo_id = p_repo_id AND name = 'HEAD'; RETURN QUERY WITH RECURSIVE commit_log AS ( SELECT c.* - FROM commits c + FROM pg_git.commits c WHERE c.repo_id = p_repo_id AND c.hash = v_head_commit UNION ALL SELECT c.* - FROM commits c + FROM pg_git.commits c INNER JOIN commit_log cl ON c.repo_id = p_repo_id AND c.hash = cl.parent_hash ) SELECT * @@ -55,7 +55,7 @@ BEGIN c.timestamp, array_agg(r.name) as ref_names FROM pg_git.get_log(p_repo_id, p_limit) c - LEFT JOIN refs r ON r.repo_id = p_repo_id AND c.hash = r.commit_hash + LEFT JOIN pg_git.refs r ON r.repo_id = p_repo_id AND c.hash = r.commit_hash GROUP BY c.hash, c.message, c.author, c.timestamp ) SELECT diff --git a/sql/functions/005-status.sql b/sql/functions/005-status.sql index 357105f..d03e5c0 100644 --- a/sql/functions/005-status.sql +++ b/sql/functions/005-status.sql @@ -14,8 +14,8 @@ DECLARE BEGIN -- Get HEAD commit and tree SELECT c.hash, c.tree_hash INTO v_head_commit, v_head_tree - FROM refs r - JOIN commits c ON r.repo_id = p_repo_id AND c.repo_id = r.repo_id AND r.commit_hash = c.hash + FROM pg_git.refs r + JOIN pg_git.commits c ON r.repo_id = p_repo_id AND c.repo_id = r.repo_id AND r.commit_hash = c.hash WHERE r.repo_id = p_repo_id AND r.name = 'HEAD'; RETURN QUERY @@ -35,7 +35,7 @@ BEGIN END, TRUE FROM index_entries i - LEFT JOIN trees t ON t.repo_id = p_repo_id AND t.hash = v_head_tree + LEFT JOIN pg_git.trees t ON t.repo_id = p_repo_id AND t.hash = v_head_tree WHERE i.repo_id = p_repo_id; END; $$ LANGUAGE plpgsql; diff --git a/sql/functions/006-branch.sql b/sql/functions/006-branch.sql index e78817d..a24fddb 100644 --- a/sql/functions/006-branch.sql +++ b/sql/functions/006-branch.sql @@ -12,13 +12,13 @@ BEGIN -- Get commit hash from start point or HEAD IF p_start_point IS NULL THEN SELECT commit_hash INTO v_commit_hash - FROM refs WHERE repo_id = p_repo_id AND name = 'HEAD'; + FROM pg_git.refs WHERE repo_id = p_repo_id AND name = 'HEAD'; ELSE v_commit_hash := p_start_point; END IF; -- Create branch reference - INSERT INTO refs (repo_id, name, commit_hash) + INSERT INTO pg_git.refs (repo_id, name, commit_hash) VALUES (p_repo_id, p_branch_name, v_commit_hash); END; $$ LANGUAGE plpgsql; @@ -34,8 +34,8 @@ SELECT r.name, r.commit_hash, r.commit_hash = head.commit_hash AS is_current -FROM refs r -CROSS JOIN (SELECT commit_hash FROM refs WHERE repo_id = p_repo_id AND name = 'HEAD') head +FROM pg_git.refs r +CROSS JOIN (SELECT commit_hash FROM pg_git.refs WHERE repo_id = p_repo_id AND name = 'HEAD') head WHERE r.repo_id = p_repo_id AND r.name != 'HEAD' ORDER BY r.name; $$ LANGUAGE sql; @@ -50,21 +50,21 @@ DECLARE BEGIN -- Get branch commit SELECT commit_hash INTO v_commit_hash - FROM refs WHERE repo_id = p_repo_id AND name = p_branch_name; + FROM pg_git.refs WHERE repo_id = p_repo_id AND name = p_branch_name; IF NOT FOUND AND p_create THEN -- Create new branch from HEAD SELECT commit_hash INTO v_commit_hash - FROM refs WHERE repo_id = p_repo_id AND name = 'HEAD'; + FROM pg_git.refs WHERE repo_id = p_repo_id AND name = 'HEAD'; - INSERT INTO refs (repo_id, name, commit_hash) + INSERT INTO pg_git.refs (repo_id, name, commit_hash) VALUES (p_repo_id, p_branch_name, v_commit_hash); ELSIF NOT FOUND THEN RAISE EXCEPTION 'Branch % does not exist', p_branch_name; END IF; -- Update HEAD - UPDATE refs SET commit_hash = v_commit_hash + UPDATE pg_git.refs SET commit_hash = v_commit_hash WHERE repo_id = p_repo_id AND name = 'HEAD'; RETURN v_commit_hash; diff --git a/sql/functions/007-merge.sql b/sql/functions/007-merge.sql index 535397f..d28882f 100644 --- a/sql/functions/007-merge.sql +++ b/sql/functions/007-merge.sql @@ -8,11 +8,11 @@ CREATE OR REPLACE FUNCTION pg_git.find_merge_base( WITH RECURSIVE commit_ancestors AS ( -- Get all ancestors of commit1 SELECT hash, parent_hash, 1 AS source - FROM commits + FROM pg_git.commits WHERE hash = p_commit1 UNION ALL SELECT c.hash, c.parent_hash, 1 - FROM commits c + FROM pg_git.commits c JOIN commit_ancestors ca ON ca.parent_hash = c.hash WHERE ca.source = 1 @@ -20,11 +20,11 @@ WITH RECURSIVE commit_ancestors AS ( -- Get all ancestors of commit2 SELECT hash, parent_hash, 2 AS source - FROM commits + FROM pg_git.commits WHERE hash = p_commit2 UNION ALL SELECT c.hash, c.parent_hash, 2 - FROM commits c + FROM pg_git.commits c JOIN commit_ancestors ca ON ca.parent_hash = c.hash WHERE ca.source = 2 ) @@ -35,7 +35,7 @@ FROM ( GROUP BY hash ) a WHERE array_length(sources, 1) > 1 -ORDER BY (SELECT timestamp FROM commits WHERE hash = a.hash) DESC +ORDER BY (SELECT timestamp FROM pg_git.commits WHERE hash = a.hash) DESC LIMIT 1; $$ LANGUAGE sql; @@ -45,11 +45,11 @@ CREATE OR REPLACE FUNCTION pg_git.can_fast_forward( ) RETURNS BOOLEAN AS $$ WITH RECURSIVE ancestor_chain AS ( SELECT hash, parent_hash - FROM commits + FROM pg_git.commits WHERE hash = p_target UNION ALL SELECT c.hash, c.parent_hash - FROM commits c + FROM pg_git.commits c JOIN ancestor_chain ac ON ac.parent_hash = c.hash ) SELECT EXISTS ( @@ -69,15 +69,15 @@ DECLARE BEGIN -- Get commit hashes SELECT commit_hash INTO v_source_commit - FROM refs WHERE repo_id = p_repo_id AND name = p_source_branch; + FROM pg_git.refs WHERE repo_id = p_repo_id AND name = p_source_branch; SELECT commit_hash INTO v_target_commit - FROM refs WHERE repo_id = p_repo_id AND name = p_target_branch; + FROM pg_git.refs WHERE repo_id = p_repo_id AND name = p_target_branch; -- Check if fast-forward is possible IF pg_git.can_fast_forward(v_source_commit, v_target_commit) THEN -- Fast-forward merge - UPDATE refs + UPDATE pg_git.refs SET commit_hash = v_source_commit WHERE repo_id = p_repo_id AND name = p_target_branch; diff --git a/sql/functions/008-diff.sql b/sql/functions/008-diff.sql index d1a3cd4..56870d0 100644 --- a/sql/functions/008-diff.sql +++ b/sql/functions/008-diff.sql @@ -12,12 +12,12 @@ DECLARE v_old_content TEXT; v_new_content TEXT; BEGIN - -- Get content from blobs + -- Get content from pg_git.blobs SELECT encode(content, 'escape') INTO v_old_content - FROM blobs WHERE hash = p_old_hash; + FROM pg_git.blobs WHERE hash = p_old_hash; SELECT encode(content, 'escape') INTO v_new_content - FROM blobs WHERE hash = p_new_hash; + FROM pg_git.blobs WHERE hash = p_new_hash; RETURN QUERY SELECT * @@ -78,15 +78,15 @@ DECLARE BEGIN -- Get tree hashes SELECT repo_id, tree_hash INTO v_repo_id, v_old_tree - FROM commits WHERE hash = p_old_commit; + FROM pg_git.commits WHERE hash = p_old_commit; IF v_repo_id IS NULL THEN SELECT repo_id INTO v_repo_id - FROM commits WHERE hash = p_new_commit; + FROM pg_git.commits WHERE hash = p_new_commit; END IF; SELECT tree_hash INTO v_new_tree - FROM commits WHERE hash = p_new_commit AND repo_id = v_repo_id; + FROM pg_git.commits WHERE hash = p_new_commit AND repo_id = v_repo_id; RETURN QUERY SELECT diff --git a/sql/functions/009-reset.sql b/sql/functions/009-reset.sql index 850da34..278e89f 100644 --- a/sql/functions/009-reset.sql +++ b/sql/functions/009-reset.sql @@ -7,7 +7,7 @@ CREATE OR REPLACE FUNCTION pg_git.reset_soft( ) RETURNS VOID AS $$ BEGIN -- Move HEAD to specified commit - UPDATE refs + UPDATE pg_git.refs SET commit_hash = p_commit WHERE repo_id = p_repo_id AND name = 'HEAD'; END; @@ -35,11 +35,11 @@ DECLARE BEGIN -- Get tree from commit SELECT tree_hash INTO v_tree_hash - FROM commits WHERE repo_id = p_repo_id AND hash = p_commit; + FROM pg_git.commits WHERE repo_id = p_repo_id AND hash = p_commit; -- Get blob hash from tree SELECT (e->>'hash')::TEXT INTO v_blob_hash - FROM trees t, + FROM pg_git.trees t, jsonb_array_elements(t.entries) e WHERE t.repo_id = p_repo_id AND t.hash = v_tree_hash AND e->>'name' = p_path; diff --git a/sql/functions/010-tag.sql b/sql/functions/010-tag.sql index b22600d..06b5b24 100644 --- a/sql/functions/010-tag.sql +++ b/sql/functions/010-tag.sql @@ -2,7 +2,7 @@ -- pg_git tag operations CREATE TABLE pg_git.tags ( - repo_id INTEGER REFERENCES repositories(id), + repo_id INTEGER REFERENCES pg_git.repositories(id), name TEXT NOT NULL, target_hash TEXT NOT NULL, tagger TEXT NOT NULL, @@ -24,7 +24,7 @@ BEGIN -- Resolve target to commit hash IF p_target = 'HEAD' THEN SELECT commit_hash INTO v_target_hash - FROM refs WHERE repo_id = p_repo_id AND name = 'HEAD'; + FROM pg_git.refs WHERE repo_id = p_repo_id AND name = 'HEAD'; ELSE v_target_hash := p_target; END IF; diff --git a/sql/functions/011-remote.sql b/sql/functions/011-remote.sql index e7cc33d..47c5c8d 100644 --- a/sql/functions/011-remote.sql +++ b/sql/functions/011-remote.sql @@ -2,7 +2,7 @@ -- pg_git remote operations CREATE TABLE pg_git.remotes ( - repo_id INTEGER REFERENCES repositories(id), + repo_id INTEGER REFERENCES pg_git.repositories(id), name TEXT NOT NULL, url TEXT NOT NULL, created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, @@ -48,8 +48,8 @@ BEGIN -- In a real implementation, this would: -- 1. Connect to remote database using v_remote_url - -- 2. Fetch new objects (blobs, trees, commits) - -- 3. Update remote refs + -- 2. Fetch new objects (pg_git.blobs, pg_git.trees, pg_git.commits) + -- 3. Update remote pg_git.refs -- For now, just return empty result RETURN QUERY SELECT NULL::TEXT, NULL::TEXT, NULL::TEXT WHERE FALSE; END; @@ -71,7 +71,7 @@ BEGIN -- Get local ref SELECT commit_hash INTO v_commit_hash - FROM refs WHERE repo_id = p_repo_id AND name = p_ref_name; + FROM pg_git.refs WHERE repo_id = p_repo_id AND name = p_ref_name; -- In a real implementation, this would: -- 1. Connect to remote database diff --git a/sql/functions/013-merge-conflicts.sql b/sql/functions/013-merge-conflicts.sql index c6fbae2..8642080 100644 --- a/sql/functions/013-merge-conflicts.sql +++ b/sql/functions/013-merge-conflicts.sql @@ -2,12 +2,12 @@ -- pg_git merge conflict resolution CREATE TABLE pg_git.merge_conflicts ( - repo_id INTEGER REFERENCES repositories(id), + repo_id INTEGER REFERENCES pg_git.repositories(id), path TEXT NOT NULL, - our_blob_hash TEXT REFERENCES blobs(hash), - their_blob_hash TEXT REFERENCES blobs(hash), - base_blob_hash TEXT REFERENCES blobs(hash), - resolution_blob_hash TEXT REFERENCES blobs(hash), + our_blob_hash TEXT REFERENCES pg_git.blobs(hash), + their_blob_hash TEXT REFERENCES pg_git.blobs(hash), + base_blob_hash TEXT REFERENCES pg_git.blobs(hash), + resolution_blob_hash TEXT REFERENCES pg_git.blobs(hash), status TEXT CHECK (status IN ('unresolved', 'resolved', 'ignored')), created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (repo_id, path) diff --git a/sql/functions/014-https.sql b/sql/functions/014-https.sql index a43cf2c..fc1a423 100644 --- a/sql/functions/014-https.sql +++ b/sql/functions/014-https.sql @@ -2,7 +2,7 @@ -- pg_git HTTPS transport CREATE TABLE pg_git.credentials ( - repo_id INTEGER REFERENCES repositories(id), + repo_id INTEGER REFERENCES pg_git.repositories(id), host TEXT NOT NULL, username TEXT NOT NULL, password BYTEA NOT NULL, diff --git a/sql/functions/015-admin.sql b/sql/functions/015-admin.sql index 8cc5d24..1792df9 100644 --- a/sql/functions/015-admin.sql +++ b/sql/functions/015-admin.sql @@ -16,25 +16,25 @@ BEGIN CREATE TEMP TABLE tmp_reachable_objects(hash TEXT PRIMARY KEY) ON COMMIT DROP; WITH RECURSIVE reachable(object_type, hash) AS ( - -- Start from refs - SELECT 'commit', commit_hash FROM refs WHERE repo_id = p_repo_id + -- Start from pg_git.refs + SELECT 'commit', commit_hash FROM pg_git.refs WHERE repo_id = p_repo_id UNION - -- Walk parent commits + -- Walk parent pg_git.commits SELECT 'commit', c.parent_hash - FROM commits c + FROM pg_git.commits c JOIN reachable r ON r.object_type = 'commit' AND c.repo_id = p_repo_id AND c.hash = r.hash WHERE c.parent_hash IS NOT NULL UNION - -- Commits reference trees + -- Commits reference pg_git.trees SELECT 'tree', c.tree_hash - FROM commits c + FROM pg_git.commits c JOIN reachable r ON r.object_type = 'commit' AND c.repo_id = p_repo_id AND c.hash = r.hash UNION - -- Trees reference blobs and subtrees + -- Trees reference pg_git.blobs and subtrees SELECT (e->>'type')::TEXT, e->>'hash' - FROM trees t + FROM pg_git.trees t JOIN reachable r ON r.object_type = 'tree' AND t.repo_id = p_repo_id AND t.hash = r.hash CROSS JOIN LATERAL jsonb_array_elements(t.entries) AS e @@ -45,33 +45,33 @@ BEGIN -- Remove unreachable objects RETURN QUERY WITH deleted_blobs AS ( - DELETE FROM blobs b + DELETE FROM pg_git.blobs b WHERE b.repo_id = p_repo_id AND NOT EXISTS ( SELECT 1 FROM tmp_reachable_objects r WHERE r.hash = b.hash ) RETURNING octet_length(content) AS size ), deleted_trees AS ( - DELETE FROM trees t + DELETE FROM pg_git.trees t WHERE t.repo_id = p_repo_id AND NOT EXISTS ( SELECT 1 FROM tmp_reachable_objects r WHERE r.hash = t.hash ) RETURNING octet_length(entries::TEXT) AS size ), deleted_commits AS ( - DELETE FROM commits c + DELETE FROM pg_git.commits c WHERE c.repo_id = p_repo_id AND NOT EXISTS ( SELECT 1 FROM tmp_reachable_objects r WHERE r.hash = c.hash ) RETURNING octet_length(message) AS size ) - SELECT 'blobs'::TEXT, + SELECT 'pg_git.blobs'::TEXT, count(*)::INTEGER, COALESCE(sum(size),0)::BIGINT FROM deleted_blobs UNION ALL - SELECT 'trees'::TEXT, + SELECT 'pg_git.trees'::TEXT, count(*)::INTEGER, COALESCE(sum(size),0)::BIGINT FROM deleted_trees UNION ALL - SELECT 'commits'::TEXT, + SELECT 'pg_git.commits'::TEXT, count(*)::INTEGER, COALESCE(sum(size),0)::BIGINT FROM deleted_commits; @@ -88,33 +88,33 @@ CREATE OR REPLACE FUNCTION pg_git.verify_integrity( details TEXT ) AS $$ BEGIN - -- Check dangling commits + -- Check dangling pg_git.commits RETURN QUERY SELECT 'dangling_commits'::TEXT, CASE WHEN count(*) = 0 THEN 'ok' ELSE 'warning' END, - count(*) || ' dangling commits found' - FROM commits c + count(*) || ' dangling pg_git.commits found' + FROM pg_git.commits c WHERE c.repo_id = p_repo_id - AND NOT EXISTS (SELECT 1 FROM refs r WHERE r.repo_id = p_repo_id AND r.commit_hash = c.hash); + AND NOT EXISTS (SELECT 1 FROM pg_git.refs r WHERE r.repo_id = p_repo_id AND r.commit_hash = c.hash); -- Check broken parent links RETURN QUERY SELECT 'broken_parents'::TEXT, CASE WHEN count(*) = 0 THEN 'ok' ELSE 'error' END, - count(*) || ' commits with invalid parent references' - FROM commits c + count(*) || ' pg_git.commits with invalid parent references' + FROM pg_git.commits c WHERE c.repo_id = p_repo_id AND c.parent_hash IS NOT NULL - AND NOT EXISTS (SELECT 1 FROM commits p WHERE p.repo_id = p_repo_id AND p.hash = c.parent_hash); + AND NOT EXISTS (SELECT 1 FROM pg_git.commits p WHERE p.repo_id = p_repo_id AND p.hash = c.parent_hash); -- Check broken tree references RETURN QUERY SELECT 'broken_trees'::TEXT, CASE WHEN count(*) = 0 THEN 'ok' ELSE 'error' END, - count(*) || ' commits with invalid tree references' - FROM commits c + count(*) || ' pg_git.commits with invalid tree references' + FROM pg_git.commits c WHERE c.repo_id = p_repo_id - AND NOT EXISTS (SELECT 1 FROM trees t WHERE t.repo_id = p_repo_id AND t.hash = c.tree_hash); + AND NOT EXISTS (SELECT 1 FROM pg_git.trees t WHERE t.repo_id = p_repo_id AND t.hash = c.tree_hash); END; $$ LANGUAGE plpgsql; diff --git a/sql/schema/001-core.sql b/sql/schema/001-core.sql index 2714ac9..99793a1 100644 --- a/sql/schema/001-core.sql +++ b/sql/schema/001-core.sql @@ -1,20 +1,20 @@ -- Core tables -CREATE TABLE blobs ( - repo_id INTEGER REFERENCES repositories(id), +CREATE TABLE pg_git.blobs ( + repo_id INTEGER REFERENCES pg_git.repositories(id), hash TEXT, content BYTEA NOT NULL, PRIMARY KEY (repo_id, hash) ); -CREATE TABLE trees ( - repo_id INTEGER REFERENCES repositories(id), +CREATE TABLE pg_git.trees ( + repo_id INTEGER REFERENCES pg_git.repositories(id), hash TEXT, entries JSONB NOT NULL, -- [{mode, type, hash, name}] PRIMARY KEY (repo_id, hash) ); -CREATE TABLE commits ( - repo_id INTEGER REFERENCES repositories(id), +CREATE TABLE pg_git.commits ( + repo_id INTEGER REFERENCES pg_git.repositories(id), hash TEXT, tree_hash TEXT NOT NULL, parent_hash TEXT, @@ -22,16 +22,16 @@ CREATE TABLE commits ( message TEXT NOT NULL, timestamp TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (repo_id, hash), - FOREIGN KEY (repo_id, tree_hash) REFERENCES trees(repo_id, hash), - FOREIGN KEY (repo_id, parent_hash) REFERENCES commits(repo_id, hash) + FOREIGN KEY (repo_id, tree_hash) REFERENCES pg_git.trees(repo_id, hash), + FOREIGN KEY (repo_id, parent_hash) REFERENCES pg_git.commits(repo_id, hash) ); -CREATE TABLE refs ( - repo_id INTEGER REFERENCES repositories(id), +CREATE TABLE pg_git.refs ( + repo_id INTEGER REFERENCES pg_git.repositories(id), name TEXT, commit_hash TEXT NOT NULL, PRIMARY KEY (repo_id, name), - FOREIGN KEY (repo_id, commit_hash) REFERENCES commits(repo_id, hash) + FOREIGN KEY (repo_id, commit_hash) REFERENCES pg_git.commits(repo_id, hash) ); -- Function to create a blob @@ -43,7 +43,7 @@ DECLARE v_hash TEXT; BEGIN v_hash := encode(sha256(p_content), 'hex'); - INSERT INTO blobs (repo_id, hash, content) + INSERT INTO pg_git.blobs (repo_id, hash, content) VALUES (p_repo_id, v_hash, p_content) ON CONFLICT DO NOTHING; RETURN v_hash; @@ -59,7 +59,7 @@ DECLARE v_hash TEXT; BEGIN v_hash := encode(sha256(p_entries::text::bytea), 'hex'); - INSERT INTO trees (repo_id, hash, entries) + INSERT INTO pg_git.trees (repo_id, hash, entries) VALUES (p_repo_id, v_hash, p_entries) ON CONFLICT DO NOTHING; RETURN v_hash; @@ -91,7 +91,7 @@ BEGIN RAISE EXCEPTION 'Commit hash calculation returned NULL'; END IF; - INSERT INTO commits (repo_id, hash, tree_hash, parent_hash, author, message) + INSERT INTO pg_git.commits (repo_id, hash, tree_hash, parent_hash, author, message) VALUES (p_repo_id, v_hash, p_tree_hash, p_parent_hash, p_author, p_message); RETURN v_hash; @@ -105,7 +105,7 @@ CREATE OR REPLACE FUNCTION update_ref( p_commit_hash TEXT ) RETURNS VOID AS $$ BEGIN - INSERT INTO refs (repo_id, name, commit_hash) + INSERT INTO pg_git.refs (repo_id, name, commit_hash) VALUES (p_repo_id, p_name, p_commit_hash) ON CONFLICT (repo_id, name) DO UPDATE SET commit_hash = p_commit_hash; @@ -125,16 +125,16 @@ CREATE OR REPLACE FUNCTION get_commit_history( timestamp TIMESTAMP WITH TIME ZONE ) AS $$ WITH RECURSIVE commit_history AS ( - SELECT * FROM commits WHERE repo_id = p_repo_id AND hash = p_start_commit + SELECT * FROM pg_git.commits WHERE repo_id = p_repo_id AND hash = p_start_commit UNION ALL SELECT c.* - FROM commits c + FROM pg_git.commits c INNER JOIN commit_history ch ON c.repo_id = p_repo_id AND c.hash = ch.parent_hash ) SELECT * FROM commit_history; $$ LANGUAGE sql; --- Function to diff two trees +-- Function to diff two pg_git.trees CREATE OR REPLACE FUNCTION diff_trees( p_repo_id INTEGER, p_old_tree_hash TEXT, @@ -150,8 +150,8 @@ DECLARE v_new_entries JSONB; BEGIN -- Get tree entries - SELECT entries INTO v_old_entries FROM trees WHERE repo_id = p_repo_id AND hash = p_old_tree_hash; - SELECT entries INTO v_new_entries FROM trees WHERE repo_id = p_repo_id AND hash = p_new_tree_hash; + SELECT entries INTO v_old_entries FROM pg_git.trees WHERE repo_id = p_repo_id AND hash = p_old_tree_hash; + SELECT entries INTO v_new_entries FROM pg_git.trees WHERE repo_id = p_repo_id AND hash = p_new_tree_hash; -- Added files RETURN QUERY diff --git a/sql/schema/pgit-schema.sql b/sql/schema/pgit-schema.sql index 5be472e..98c0569 100644 --- a/sql/schema/pgit-schema.sql +++ b/sql/schema/pgit-schema.sql @@ -1,7 +1,7 @@ -- Central schema definitions for PGit CREATE TABLE index_entries ( - repo_id INTEGER REFERENCES repositories(id), + repo_id INTEGER REFERENCES pg_git.repositories(id), path TEXT NOT NULL, blob_hash TEXT NOT NULL, mode TEXT NOT NULL DEFAULT '100644', diff --git a/test/sql/search_path_qualification_test.sql b/test/sql/search_path_qualification_test.sql new file mode 100644 index 0000000..6c631ae --- /dev/null +++ b/test/sql/search_path_qualification_test.sql @@ -0,0 +1,37 @@ +-- Path: /test/sql/search_path_qualification_test.sql +-- Validate pg_git functions work with a non-default search_path. + +BEGIN; + +SELECT plan(4); + +SET LOCAL search_path TO public; + +SELECT pg_git.init_repository('spath_repo', '/tmp/spath_repo') AS repo_id \gset +SELECT pg_git.stage_file(:repo_id, 'file.txt', 'hello world'::bytea); + +SELECT lives_ok( + $$SELECT pg_git.commit_index(:repo_id, 'search_path_tester', 'commit under custom search_path')$$, + 'Commit succeeds with non-default search_path' +); + +SELECT results_eq( + $$SELECT COUNT(*)::bigint FROM pg_git.commits WHERE repo_id = :repo_id$$, + $$VALUES (2::bigint)$$, + 'Commit rows are written in pg_git.commits' +); + +SELECT results_eq( + $$SELECT commit_hash FROM pg_git.refs WHERE repo_id = :repo_id AND name = 'master'$$, + $$SELECT commit_hash FROM pg_git.refs WHERE repo_id = :repo_id AND name = 'HEAD'$$, + 'HEAD and master remain aligned after commit' +); + +SELECT results_eq( + $$SELECT message FROM pg_git.commits WHERE repo_id = :repo_id ORDER BY timestamp DESC LIMIT 1$$, + $$VALUES ('commit under custom search_path'::text)$$, + 'Latest commit message is stored correctly' +); + +SELECT * FROM finish(); +ROLLBACK;