Skip to content

Commit

Permalink
remove RangeTblEntry, we can get by just passing Oid around instead. …
Browse files Browse the repository at this point in the history
…The only thing we're missing is the alias that was attached to the RangeTblEntry but since we are parsing the same query as Postgres, the alias should be resolved by the system anyways
  • Loading branch information
Tishj committed Jun 10, 2024
1 parent 510c699 commit c7d9c93
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 48 deletions.
4 changes: 2 additions & 2 deletions include/quack/quack_heap_seq_scan.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class PostgresHeapSeqParallelScanState {
class PostgresHeapSeqScan {
private:
public:
PostgresHeapSeqScan(RangeTblEntry *table);
PostgresHeapSeqScan(Oid relid);
~PostgresHeapSeqScan();
PostgresHeapSeqScan(const PostgresHeapSeqScan &other) = delete;
PostgresHeapSeqScan &operator=(const PostgresHeapSeqScan &other) = delete;
Expand All @@ -90,7 +90,7 @@ class PostgresHeapSeqScan {
Page PreparePageRead(PostgresHeapSeqScanThreadInfo &threadScanInfo);

private:
RangeTblEntry * m_table = nullptr;
Oid m_relid = InvalidOid;
Relation m_rel = nullptr;
Snapshot m_snapshot = nullptr;
PostgresHeapSeqParallelScanState m_parallel_scan_state;
Expand Down
64 changes: 24 additions & 40 deletions src/quack_heap_scan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ PostgresHeapScanLocalState::~PostgresHeapScanLocalState() {
PostgresHeapScanFunction::PostgresHeapScanFunction()
: TableFunction("postgres_heap_scan", {}, PostgresHeapScanFunc, PostgresHeapBind, PostgresHeapInitGlobal,
PostgresHeapInitLocal) {
named_parameters["table"] = duckdb::LogicalType::POINTER;
named_parameters["relid"] = duckdb::LogicalType::UINTEGER;
named_parameters["snapshot"] = duckdb::LogicalType::POINTER;
projection_pushdown = true;
filter_pushdown = true;
Expand All @@ -81,14 +81,14 @@ duckdb::unique_ptr<duckdb::FunctionData>
PostgresHeapScanFunction::PostgresHeapBind(duckdb::ClientContext &context, duckdb::TableFunctionBindInput &input,
duckdb::vector<duckdb::LogicalType> &return_types,
duckdb::vector<duckdb::string> &names) {
auto table = (reinterpret_cast<RangeTblEntry *>(input.named_parameters["table"].GetPointer()));
auto relid = input.named_parameters["relid"].GetValue<uint32_t>();
auto snapshot = (reinterpret_cast<Snapshot>(input.named_parameters["snapshot"].GetPointer()));

auto rel = PostgresHeapSeqScan(table);
auto rel = PostgresHeapSeqScan(relid);
auto tupleDesc = RelationGetDescr(rel.GetRelation());

if (!tupleDesc) {
elog(ERROR, "Failed to get tuple descriptor for relation with OID %u", table->relid);
elog(ERROR, "Failed to get tuple descriptor for relation with OID %u", relid);
return nullptr;
}

Expand Down Expand Up @@ -148,51 +148,36 @@ PostgresHeapScanFunction::PostgresHeapScanFunc(duckdb::ClientContext &context, d
// PostgresHeapReplacementScan
//

static RangeTblEntry *
FindMatchingHeapRelation(List *tables, const duckdb::string &to_find) {
ListCell *lc;

foreach (lc, tables) {
RangeTblEntry *table = (RangeTblEntry *)lfirst(lc);
if (table->relid) {
auto rel = RelationIdGetRelation(table->relid);
if (!RelationIsValid(rel)) {
elog(ERROR, "Relation with OID %u is not valid", table->relid);
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);
}
static Oid
FindMatchingRelation(const duckdb::string &to_find) {
RangeVar *tableRangeVar = makeRangeVarFromNameList(stringToQualifiedNameList(to_find.c_str(), NULL));
Oid relOid = RangeVarGetRelid(tableRangeVar, AccessShareLock, true);
if (relOid != InvalidOid) {
return relOid;
}

return nullptr;
return InvalidOid;
}

static duckdb::vector<duckdb::unique_ptr<duckdb::ParsedExpression>>
CreateFunctionArguments(RangeTblEntry *table, Snapshot snapshot) {
CreateFunctionArguments(Oid relid, Snapshot snapshot) {
duckdb::vector<duckdb::unique_ptr<duckdb::ParsedExpression>> children;
children.push_back(duckdb::make_uniq<duckdb::ComparisonExpression>(
duckdb::ExpressionType::COMPARE_EQUAL, duckdb::make_uniq<duckdb::ColumnRefExpression>("table"),
duckdb::make_uniq<duckdb::ConstantExpression>(duckdb::Value::POINTER(duckdb::CastPointerToValue(table)))));
duckdb::ExpressionType::COMPARE_EQUAL, duckdb::make_uniq<duckdb::ColumnRefExpression>("relid"),
duckdb::make_uniq<duckdb::ConstantExpression>(duckdb::Value::UINTEGER(relid))));

children.push_back(duckdb::make_uniq<duckdb::ComparisonExpression>(
duckdb::ExpressionType::COMPARE_EQUAL, duckdb::make_uniq<duckdb::ColumnRefExpression>("snapshot"),
duckdb::make_uniq<duckdb::ConstantExpression>(duckdb::Value::POINTER(duckdb::CastPointerToValue(snapshot)))));
return children;
}

duckdb::unique_ptr<duckdb::TableRef> ReplaceView(RangeTblEntry *view) {
auto oid = ObjectIdGetDatum(view->relid);
duckdb::unique_ptr<duckdb::TableRef> ReplaceView(Oid view) {
auto oid = ObjectIdGetDatum(view);
Datum viewdef = DirectFunctionCall1(pg_get_viewdef, oid);
auto view_definition = text_to_cstring(DatumGetTextP(viewdef));

if (!view_definition) {
elog(ERROR, "Could not retrieve view definition for Relation with relid: %u", view->relid);
elog(ERROR, "Could not retrieve view definition for Relation with relid: %u", view);
}

duckdb::Parser parser;
Expand All @@ -219,28 +204,28 @@ PostgresHeapReplacementScan(duckdb::ClientContext &context, duckdb::ReplacementS
auto &scan_data = reinterpret_cast<PostgresHeapReplacementScanData &>(*data);

/* Check name against query table list and verify that it is heap table */
auto table = FindMatchingHeapRelation(scan_data.m_tables, table_name);
auto relid = FindMatchingRelation(table_name);

if (!table) {
if (relid == InvalidOid) {
return nullptr;
}

// Check if the Relation is a VIEW
auto tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(table->relid));
auto tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
if (!HeapTupleIsValid(tuple)) {
elog(ERROR, "Cache lookup failed for relation %u", table->relid);
elog(ERROR, "Cache lookup failed for relation %u", relid);
}

auto relForm = (Form_pg_class) GETSTRUCT(tuple);

// Check if the relation is a view
if (relForm->relkind == RELKIND_VIEW) {
ReleaseSysCache(tuple);
return ReplaceView(table);
return ReplaceView(relid);
}
ReleaseSysCache(tuple);

auto rel = RelationIdGetRelation(table->relid);
auto rel = RelationIdGetRelation(relid);
/* 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 */
Expand All @@ -250,10 +235,9 @@ PostgresHeapReplacementScan(duckdb::ClientContext &context, duckdb::ReplacementS
RelationClose(rel);

// Create POINTER values from the 'table' and 'snapshot' variables
auto children = CreateFunctionArguments(table, GetActiveSnapshot());
auto children = CreateFunctionArguments(relid, 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
12 changes: 6 additions & 6 deletions src/quack_heap_seq_scan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ extern "C" {
#include <thread>

namespace quack {
PostgresHeapSeqScan::PostgresHeapSeqScan(RangeTblEntry *table)
: m_table(table), m_rel(nullptr), m_snapshot(nullptr) {
PostgresHeapSeqScan::PostgresHeapSeqScan(Oid relid)
: m_relid(relid), m_rel(nullptr), m_snapshot(nullptr) {
}

PostgresHeapSeqScan::~PostgresHeapSeqScan() {
Expand All @@ -26,15 +26,15 @@ PostgresHeapSeqScan::~PostgresHeapSeqScan() {
}

PostgresHeapSeqScan::PostgresHeapSeqScan(PostgresHeapSeqScan &&other)
: m_table(other.m_table), m_rel(nullptr) {
: m_relid(other.m_relid), m_rel(nullptr) {
other.CloseRelation();
other.m_table = nullptr;
other.m_relid = InvalidOid;
}

Relation
PostgresHeapSeqScan::GetRelation() {
if (m_table && m_rel == nullptr) {
m_rel = RelationIdGetRelation(m_table->relid);
if (m_relid != InvalidOid && m_rel == nullptr) {
m_rel = RelationIdGetRelation(m_relid);
}
return m_rel;
}
Expand Down

0 comments on commit c7d9c93

Please sign in to comment.