forked from duckdb/duckdb-postgres
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpostgres_index_set.cpp
88 lines (80 loc) · 3.07 KB
/
postgres_index_set.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include "storage/postgres_index_set.hpp"
#include "storage/postgres_schema_entry.hpp"
#include "storage/postgres_transaction.hpp"
#include "duckdb/parser/parsed_data/create_schema_info.hpp"
#include "storage/postgres_index_entry.hpp"
#include "duckdb/parser/parsed_expression_iterator.hpp"
namespace duckdb {
PostgresIndexSet::PostgresIndexSet(PostgresSchemaEntry &schema, unique_ptr<PostgresResultSlice> index_result_p)
: PostgresInSchemaSet(schema, !index_result_p), index_result(std::move(index_result_p)) {
}
string PostgresIndexSet::GetInitializeQuery(const string &schema) {
string base_query = R"(
SELECT pg_namespace.oid, tablename, indexname
FROM pg_indexes
JOIN pg_namespace ON (schemaname=nspname)
${CONDITION}
ORDER BY pg_namespace.oid;
)";
string condition;
if (!schema.empty()) {
condition += "WHERE pg_namespace.nspname=" + KeywordHelper::WriteQuoted(schema);
}
return StringUtil::Replace(base_query, "${CONDITION}", condition);
}
void PostgresIndexSet::LoadEntries(ClientContext &context) {
if (!index_result) {
throw InternalException("PostgresIndexSet::LoadEntries called without an index result defined");
}
auto &result = index_result->GetResult();
for (idx_t row = index_result->start; row < index_result->end; row++) {
auto table_name = result.GetString(row, 1);
auto index_name = result.GetString(row, 2);
CreateIndexInfo info;
info.schema = schema.name;
info.table = table_name;
info.index_name = index_name;
auto index_entry = make_uniq<PostgresIndexEntry>(catalog, schema, info, table_name);
CreateEntry(std::move(index_entry));
}
index_result.reset();
}
void PGUnqualifyColumnReferences(ParsedExpression &expr) {
if (expr.type == ExpressionType::COLUMN_REF) {
auto &colref = expr.Cast<ColumnRefExpression>();
auto name = std::move(colref.column_names.back());
colref.column_names = {std::move(name)};
return;
}
ParsedExpressionIterator::EnumerateChildren(expr, PGUnqualifyColumnReferences);
}
string PGGetCreateIndexSQL(CreateIndexInfo &info, TableCatalogEntry &tbl) {
string sql;
sql = "CREATE";
if (info.constraint_type == IndexConstraintType::UNIQUE) {
sql += " UNIQUE";
}
sql += " INDEX ";
sql += PostgresUtils::QuotePostgresIdentifier(info.index_name);
sql += " ON ";
sql += PostgresUtils::QuotePostgresIdentifier(tbl.schema.name) + ".";
sql += PostgresUtils::QuotePostgresIdentifier(tbl.name);
sql += "(";
for (idx_t i = 0; i < info.parsed_expressions.size(); i++) {
if (i > 0) {
sql += ", ";
}
PGUnqualifyColumnReferences(*info.parsed_expressions[i]);
sql += info.parsed_expressions[i]->ToString();
}
sql += ")";
return sql;
}
optional_ptr<CatalogEntry> PostgresIndexSet::CreateIndex(ClientContext &context, CreateIndexInfo &info,
TableCatalogEntry &table) {
auto &postgres_transaction = PostgresTransaction::Get(context, table.catalog);
postgres_transaction.Query(PGGetCreateIndexSQL(info, table));
auto index_entry = make_uniq<PostgresIndexEntry>(schema.ParentCatalog(), schema, info, table.name);
return CreateEntry(std::move(index_entry));
}
} // namespace duckdb