Skip to content

Commit

Permalink
Merge pull request #33 from hydradatabase/search_path
Browse files Browse the repository at this point in the history
Match heap tables with fully qualified name
  • Loading branch information
mkaruza authored May 27, 2024
2 parents 456f8a7 + d3fb9e8 commit 47a6105
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 14 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ SRCS = src/utility/copy.cpp \

OBJS = $(subst .cpp,.o, $(SRCS))

REGRESS = basic
REGRESS = $(subst .sql,,$(subst sql/,,$(wildcard sql/*.sql)))

PG_CONFIG ?= pg_config

Expand Down
1 change: 1 addition & 0 deletions expected/basic.out
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,4 @@ DEBUG: -- (DuckDB/PostgresHeapScanGlobalState) Running 4 threads --
SET quack.max_threads_per_query TO default;
SET client_min_messages TO default;
DROP TABLE t;
DROP EXTENSION quack;
71 changes: 71 additions & 0 deletions expected/search_path.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
CREATE EXTENSION quack;
CREATE TABLE t(a INT);
INSERT INTO t SELECT g from generate_series(1,10) g;
SELECT count(*) FROM t;
count_star()
--------------
10
(1 row)

SELECT count(*) FROM public.t;
count_star()
--------------
10
(1 row)

-- Create schema `other`
CREATE SCHEMA other;
CREATE TABLE other.t(a INT);
INSERT INTO other.t SELECT g from generate_series(1,100) g;
SELECT count(*) FROM other.t;
count_star()
--------------
100
(1 row)

-- Test fully qualified table name combinations
SELECT count(*) FROM public.t, other.t;
count_star()
--------------
1000
(1 row)

SELECT count(*) FROM t, other.t;
count_star()
--------------
1000
(1 row)

SELECT count(*) FROM t,t;
ERROR: table name "t" specified more than once
-- search_path ORDER matters.
SET search_path TO other, public;
SELECT count(*) FROM t;
count_star()
--------------
100
(1 row)

SELECT count(*) FROM t, public.t;
count_star()
--------------
1000
(1 row)

-- No search_path
SET search_path TO '';
SELECT count(*) FROM t, other.t;
ERROR: relation "t" does not exist
LINE 1: SELECT count(*) FROM t, other.t;
^
SELECT count(*) FROM public.t, other.t;
count_star()
--------------
1000
(1 row)

-- Cleanup
DROP TABLE other.t;
DROP SCHEMA other;
RESET search_path;
DROP EXTENSION quack;
4 changes: 3 additions & 1 deletion sql/basic.sql
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,6 @@ SELECT a, COUNT(*) FROM t WHERE a > 5 GROUP BY a ORDER BY a;
SET quack.max_threads_per_query TO default;
SET client_min_messages TO default;

DROP TABLE t;
DROP TABLE t;

DROP EXTENSION quack;
34 changes: 34 additions & 0 deletions sql/search_path.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
CREATE EXTENSION quack;

CREATE TABLE t(a INT);
INSERT INTO t SELECT g from generate_series(1,10) g;
SELECT count(*) FROM t;
SELECT count(*) FROM public.t;

-- Create schema `other`
CREATE SCHEMA other;
CREATE TABLE other.t(a INT);
INSERT INTO other.t SELECT g from generate_series(1,100) g;
SELECT count(*) FROM other.t;

-- Test fully qualified table name combinations
SELECT count(*) FROM public.t, other.t;
SELECT count(*) FROM t, other.t;
SELECT count(*) FROM t,t;

-- search_path ORDER matters.
SET search_path TO other, public;
SELECT count(*) FROM t;
SELECT count(*) FROM t, public.t;

-- No search_path
SET search_path TO '';
SELECT count(*) FROM t, other.t;
SELECT count(*) FROM public.t, other.t;

-- Cleanup
DROP TABLE other.t;
DROP SCHEMA other;
RESET search_path;

DROP EXTENSION quack;
33 changes: 21 additions & 12 deletions src/quack_heap_scan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,15 @@
#include "duckdb/parser/expression/constant_expression.hpp"
#include "duckdb/parser/expression/comparison_expression.hpp"
#include "duckdb/parser/expression/columnref_expression.hpp"
#include "duckdb/parser/qualified_name.hpp"
#include "duckdb/common/enums/expression_type.hpp"

extern "C" {
#include "postgres.h"
#include "catalog/namespace.h"
#include "utils/regproc.h"
}

#include "quack/quack_heap_scan.hpp"
#include "quack/quack_types.hpp"

Expand Down Expand Up @@ -139,6 +146,7 @@ PostgresHeapScanFunction::PostgresHeapScanFunc(duckdb::ClientContext &context, d
static RangeTblEntry *
FindMatchingHeapRelation(List *tables, const duckdb::string &to_find) {
ListCell *lc;

foreach (lc, tables) {
RangeTblEntry *table = (RangeTblEntry *)lfirst(lc);
if (table->relid) {
Expand All @@ -147,22 +155,22 @@ FindMatchingHeapRelation(List *tables, const duckdb::string &to_find) {
elog(ERROR, "Relation with OID %u is not valid", table->relid);
return nullptr;
}
char *rel_name = RelationGetRelationName(rel);
auto table_name = std::string(rel_name);
if (duckdb::StringUtil::CIEquals(table_name, to_find)) {
/* Allow only heap tables */
if (!rel->rd_amhandler || (GetTableAmRoutine(rel->rd_amhandler) != GetHeapamTableAmRoutine())) {
/* This doesn't have an access method handler, we cant read from this */
RelationClose(rel);
return nullptr;
} else {
RelationClose(rel);
return table;
}
/* Allow only heap tables */
if (!rel->rd_amhandler || (GetTableAmRoutine(rel->rd_amhandler) != GetHeapamTableAmRoutine())) {
/* This doesn't have an access method handler, we cant read from this */
RelationClose(rel);
return nullptr;
}
RangeVar *tableRangeVar = makeRangeVarFromNameList(stringToQualifiedNameList(to_find.c_str(), NULL));
Oid relOid = RangeVarGetRelid(tableRangeVar, AccessShareLock, true);
if (table->relid == relOid) {
RelationClose(rel);
return table;
}
RelationClose(rel);
}
}

return nullptr;
}

Expand Down Expand Up @@ -196,6 +204,7 @@ PostgresHeapReplacementScan(duckdb::ClientContext &context, const duckdb::string
auto children = CreateFunctionArguments(table, GetActiveSnapshot());
auto table_function = duckdb::make_uniq<duckdb::TableFunctionRef>();
table_function->function = duckdb::make_uniq<duckdb::FunctionExpression>("postgres_heap_scan", std::move(children));
table_function->alias = table->alias ? table->alias->aliasname : table_name;

return std::move(table_function);
}
Expand Down

0 comments on commit 47a6105

Please sign in to comment.