Skip to content

Commit d9244c7

Browse files
committed
Basic attach working - tons of todos
1 parent 2508641 commit d9244c7

24 files changed

+1168
-56
lines changed

concurrency_test.cpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ std::mt19937 rng(rd()); // random-number engine used (Mersenne-Twister in this c
99

1010
using namespace duckdb;
1111

12-
struct PGQueryResult {
13-
~PGQueryResult() {
12+
struct PostgresResult {
13+
~PostgresResult() {
1414
if (res) {
1515
PQclear(res);
1616
}
@@ -31,7 +31,7 @@ struct PGQueryResult {
3131
};
3232

3333
static void PGExec(PGconn *conn, string q) {
34-
auto res = make_uniq<PGQueryResult>();
34+
auto res = make_uniq<PostgresResult>();
3535
res->res = PQexec(conn, q.c_str());
3636

3737
if (!res->res) {
@@ -42,8 +42,8 @@ static void PGExec(PGconn *conn, string q) {
4242
}
4343
}
4444

45-
static unique_ptr<PGQueryResult> PGQuery(PGconn *conn, string q) {
46-
auto res = make_uniq<PGQueryResult>();
45+
static unique_ptr<PostgresResult> PGQuery(PGconn *conn, string q) {
46+
auto res = make_uniq<PostgresResult>();
4747
res->res = PQexec(conn, q.c_str());
4848

4949
if (!res->res) {

src/CMakeLists.txt

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
include_directories(include)
22

3+
add_subdirectory(storage)
4+
35
add_library(
46
postgres_ext_library OBJECT
7+
postgres_connection.cpp
58
postgres_extension.cpp
6-
postgres_scanner.cpp)
9+
postgres_scanner.cpp
10+
postgres_stmt.cpp
11+
postgres_storage.cpp
12+
postgres_utils.cpp)
713
set(ALL_OBJECT_FILES
814
${ALL_OBJECT_FILES} $<TARGET_OBJECTS:postgres_ext_library>
915
PARENT_SCOPE)

src/include/postgres_connection.hpp

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
//===----------------------------------------------------------------------===//
2+
// DuckDB
3+
//
4+
// postgres_connection.hpp
5+
//
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#pragma once
10+
11+
#include "postgres_utils.hpp"
12+
#include "postgres_result.hpp"
13+
14+
namespace duckdb {
15+
class PostgresStatement;
16+
class PostgresResult;
17+
struct IndexInfo;
18+
19+
class PostgresConnection {
20+
public:
21+
PostgresConnection();
22+
PostgresConnection(PGconn *connection);
23+
~PostgresConnection();
24+
// disable copy constructors
25+
PostgresConnection(const PostgresConnection &other) = delete;
26+
PostgresConnection &operator=(const PostgresConnection &) = delete;
27+
//! enable move constructors
28+
PostgresConnection(PostgresConnection &&other) noexcept;
29+
PostgresConnection &operator=(PostgresConnection &&) noexcept;
30+
31+
32+
public:
33+
static PostgresConnection Open(const string &connection_string);
34+
bool TryPrepare(const string &query, PostgresStatement &result, string &error);
35+
PostgresStatement Prepare(const string &query);
36+
void Execute(const string &query);
37+
unique_ptr<PostgresResult> Query(const string &query);
38+
vector<string> GetTables();
39+
40+
vector<string> GetEntries(string entry_type);
41+
CatalogType GetEntryType(const string &name);
42+
void GetTableInfo(const string &table_name, ColumnList &columns, vector<unique_ptr<Constraint>> &constraints);
43+
void GetViewInfo(const string &view_name, string &sql);
44+
void GetIndexInfo(const string &index_name, string &sql, string &table_name);
45+
//! Gets the max row id of a table, returns false if the table does not have a rowid column
46+
bool GetMaxRowId(const string &table_name, idx_t &row_id);
47+
bool ColumnExists(const string &table_name, const string &column_name);
48+
vector<IndexInfo> GetIndexInfo(const string &table_name);
49+
50+
bool IsOpen();
51+
void Close();
52+
53+
private:
54+
PGconn *connection;
55+
56+
};
57+
58+
} // namespace duckdb

src/include/postgres_result.hpp

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
//===----------------------------------------------------------------------===//
2+
// DuckDB
3+
//
4+
// postgres_result.hpp
5+
//
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#pragma once
10+
11+
#include "postgres_utils.hpp"
12+
13+
namespace duckdb {
14+
15+
class PostgresResult {
16+
public:
17+
PostgresResult(PGresult *res_p) : res(res_p) {
18+
}
19+
~PostgresResult() {
20+
if (res) {
21+
PQclear(res);
22+
}
23+
}
24+
PGresult *res = nullptr;
25+
26+
public:
27+
string GetString(idx_t row, idx_t col) {
28+
D_ASSERT(res);
29+
return string(PQgetvalue(res, row, col));
30+
}
31+
32+
int32_t GetInt32(idx_t row, idx_t col) {
33+
return atoi(PQgetvalue(res, row, col));
34+
}
35+
int64_t GetInt64(idx_t row, idx_t col) {
36+
return atoll(PQgetvalue(res, row, col));
37+
}
38+
bool GetBool(idx_t row, idx_t col) {
39+
return strcmp(PQgetvalue(res, row, col), "t");
40+
}
41+
idx_t Count() {
42+
D_ASSERT(res);
43+
return PQntuples(res);
44+
}
45+
};
46+
47+
}

src/include/postgres_stmt.hpp

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//===----------------------------------------------------------------------===//
2+
// DuckDB
3+
//
4+
// postgres_utils.hpp
5+
//
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#pragma once
10+
11+
#include "postgres_utils.hpp"
12+
13+
#include <cstddef>
14+
15+
namespace duckdb {
16+
17+
class PostgresStatement {
18+
public:
19+
PostgresStatement();
20+
PostgresStatement(PGconn *connection, string name);
21+
~PostgresStatement();
22+
// disable copy constructors
23+
PostgresStatement(const PostgresStatement &other) = delete;
24+
PostgresStatement &operator=(const PostgresStatement &) = delete;
25+
//! enable move constructors
26+
PostgresStatement(PostgresStatement &&other) noexcept;
27+
PostgresStatement &operator=(PostgresStatement &&) noexcept;
28+
29+
PGconn *connection;
30+
string name;
31+
};
32+
33+
} // namespace duckdb

src/include/postgres_utils.hpp

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//===----------------------------------------------------------------------===//
2+
// DuckDB
3+
//
4+
// postgres_utils.hpp
5+
//
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#pragma once
10+
11+
#include "duckdb.hpp"
12+
#include <libpq-fe.h>
13+
14+
namespace duckdb {
15+
16+
class PostgresUtils {
17+
public:
18+
static PGconn *PGConnect(const string &dsn);
19+
20+
static LogicalType ToPostgresType(const LogicalType &input);
21+
22+
};
23+
24+
} // namespace duckdb
+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
//===----------------------------------------------------------------------===//
2+
// DuckDB
3+
//
4+
// storage/postgres_catalog.hpp
5+
//
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#pragma once
10+
11+
#include "duckdb/catalog/catalog.hpp"
12+
#include "duckdb/common/enums/access_mode.hpp"
13+
#include "postgres_connection.hpp"
14+
15+
namespace duckdb {
16+
class PostgresSchemaEntry;
17+
18+
class PostgresCatalog : public Catalog {
19+
public:
20+
explicit PostgresCatalog(AttachedDatabase &db_p, const string &path, AccessMode access_mode);
21+
~PostgresCatalog();
22+
23+
string path;
24+
AccessMode access_mode;
25+
26+
public:
27+
void Initialize(bool load_builtin) override;
28+
string GetCatalogType() override {
29+
return "postgres";
30+
}
31+
32+
optional_ptr<CatalogEntry> CreateSchema(CatalogTransaction transaction, CreateSchemaInfo &info) override;
33+
34+
void ScanSchemas(ClientContext &context, std::function<void(SchemaCatalogEntry &)> callback) override;
35+
36+
optional_ptr<SchemaCatalogEntry> GetSchema(CatalogTransaction transaction, const string &schema_name,
37+
OnEntryNotFound if_not_found,
38+
QueryErrorContext error_context = QueryErrorContext()) override;
39+
40+
PostgresSchemaEntry &GetMainSchema() {
41+
return *main_schema;
42+
}
43+
44+
unique_ptr<PhysicalOperator> PlanInsert(ClientContext &context, LogicalInsert &op,
45+
unique_ptr<PhysicalOperator> plan) override;
46+
unique_ptr<PhysicalOperator> PlanCreateTableAs(ClientContext &context, LogicalCreateTable &op,
47+
unique_ptr<PhysicalOperator> plan) override;
48+
unique_ptr<PhysicalOperator> PlanDelete(ClientContext &context, LogicalDelete &op,
49+
unique_ptr<PhysicalOperator> plan) override;
50+
unique_ptr<PhysicalOperator> PlanUpdate(ClientContext &context, LogicalUpdate &op,
51+
unique_ptr<PhysicalOperator> plan) override;
52+
unique_ptr<LogicalOperator> BindCreateIndex(Binder &binder, CreateStatement &stmt, TableCatalogEntry &table,
53+
unique_ptr<LogicalOperator> plan) override;
54+
55+
DatabaseSize GetDatabaseSize(ClientContext &context) override;
56+
57+
//! Whether or not this is an in-memory Postgres database
58+
bool InMemory() override;
59+
string GetDBPath() override;
60+
61+
private:
62+
void DropSchema(ClientContext &context, DropInfo &info) override;
63+
64+
private:
65+
unique_ptr<PostgresSchemaEntry> main_schema;
66+
};
67+
68+
} // namespace duckdb
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//===----------------------------------------------------------------------===//
2+
// DuckDB
3+
//
4+
// storage/postgres_schema_entry.hpp
5+
//
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#pragma once
10+
11+
#include "duckdb/catalog/catalog_entry/schema_catalog_entry.hpp"
12+
13+
namespace duckdb {
14+
class PostgresTransaction;
15+
16+
class PostgresSchemaEntry : public SchemaCatalogEntry {
17+
public:
18+
PostgresSchemaEntry(Catalog &catalog);
19+
20+
public:
21+
optional_ptr<CatalogEntry> CreateTable(CatalogTransaction transaction, BoundCreateTableInfo &info) override;
22+
optional_ptr<CatalogEntry> CreateFunction(CatalogTransaction transaction, CreateFunctionInfo &info) override;
23+
optional_ptr<CatalogEntry> CreateIndex(ClientContext &context, CreateIndexInfo &info,
24+
TableCatalogEntry &table) override;
25+
optional_ptr<CatalogEntry> CreateView(CatalogTransaction transaction, CreateViewInfo &info) override;
26+
optional_ptr<CatalogEntry> CreateSequence(CatalogTransaction transaction, CreateSequenceInfo &info) override;
27+
optional_ptr<CatalogEntry> CreateTableFunction(CatalogTransaction transaction,
28+
CreateTableFunctionInfo &info) override;
29+
optional_ptr<CatalogEntry> CreateCopyFunction(CatalogTransaction transaction,
30+
CreateCopyFunctionInfo &info) override;
31+
optional_ptr<CatalogEntry> CreatePragmaFunction(CatalogTransaction transaction,
32+
CreatePragmaFunctionInfo &info) override;
33+
optional_ptr<CatalogEntry> CreateCollation(CatalogTransaction transaction, CreateCollationInfo &info) override;
34+
optional_ptr<CatalogEntry> CreateType(CatalogTransaction transaction, CreateTypeInfo &info) override;
35+
void Alter(ClientContext &context, AlterInfo &info) override;
36+
void Scan(ClientContext &context, CatalogType type, const std::function<void(CatalogEntry &)> &callback) override;
37+
void Scan(CatalogType type, const std::function<void(CatalogEntry &)> &callback) override;
38+
void DropEntry(ClientContext &context, DropInfo &info) override;
39+
optional_ptr<CatalogEntry> GetEntry(CatalogTransaction transaction, CatalogType type, const string &name) override;
40+
41+
private:
42+
void AlterTable(PostgresTransaction &transaction, RenameTableInfo &info);
43+
void AlterTable(PostgresTransaction &transaction, RenameColumnInfo &info);
44+
void AlterTable(PostgresTransaction &transaction, AddColumnInfo &info);
45+
void AlterTable(PostgresTransaction &transaction, RemoveColumnInfo &info);
46+
47+
void TryDropEntry(ClientContext &context, CatalogType catalog_type, const string &name);
48+
};
49+
50+
} // namespace duckdb
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//===----------------------------------------------------------------------===//
2+
// DuckDB
3+
//
4+
// storage/postgres_table_entry.hpp
5+
//
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#pragma once
10+
11+
#include "duckdb/catalog/catalog_entry/table_catalog_entry.hpp"
12+
13+
namespace duckdb {
14+
15+
class PostgresTableEntry : public TableCatalogEntry {
16+
public:
17+
PostgresTableEntry(Catalog &catalog, SchemaCatalogEntry &schema, CreateTableInfo &info);
18+
19+
public:
20+
unique_ptr<BaseStatistics> GetStatistics(ClientContext &context, column_t column_id) override;
21+
22+
TableFunction GetScanFunction(ClientContext &context, unique_ptr<FunctionData> &bind_data) override;
23+
24+
TableStorageInfo GetStorageInfo(ClientContext &context) override;
25+
26+
void BindUpdateConstraints(LogicalGet &get, LogicalProjection &proj, LogicalUpdate &update,
27+
ClientContext &context) override;
28+
29+
};
30+
31+
} // namespace duckdb

0 commit comments

Comments
 (0)