summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVitaly Stoyan <[email protected]>2024-03-01 19:59:19 +0300
committerGitHub <[email protected]>2024-03-01 19:59:19 +0300
commit0b229ad45468ae40824dda8123cd913b84e170ce (patch)
tree120463d35cf5f0b32bb214c047e9b5a1ba58a008
parentb679bae7c5dcc967c6a4f101cde03689a5e5feaf (diff)
implemented syscache RELNAMENSP (#2387)
-rw-r--r--ydb/library/yql/parser/pg_wrapper/parser.cpp3
-rw-r--r--ydb/library/yql/parser/pg_wrapper/postgresql/src/backend/utils/cache/syscache.c2
-rw-r--r--ydb/library/yql/parser/pg_wrapper/postgresql/src/backend/utils/misc/guc.c2
-rw-r--r--ydb/library/yql/parser/pg_wrapper/syscache.cpp138
-rw-r--r--ydb/library/yql/parser/pg_wrapper/ya.make4
5 files changed, 132 insertions, 17 deletions
diff --git a/ydb/library/yql/parser/pg_wrapper/parser.cpp b/ydb/library/yql/parser/pg_wrapper/parser.cpp
index 73c82fe2f9e..507ff637ad1 100644
--- a/ydb/library/yql/parser/pg_wrapper/parser.cpp
+++ b/ydb/library/yql/parser/pg_wrapper/parser.cpp
@@ -20,6 +20,7 @@ extern "C" {
#include "postgres.h"
#include "access/session.h"
#include "access/xact.h"
+#include "catalog/namespace.h"
#include "mb/pg_wchar.h"
#include "nodes/pg_list.h"
#include "nodes/parsenodes.h"
@@ -269,4 +270,6 @@ extern "C" void setup_pg_thread_cleanup() {
work_mem = MAX_KILOBYTES; // a way to postpone spilling for tuple stores
assign_max_stack_depth(1024, nullptr);
MyDatabaseId = 3; // from catalog.pg_database
+ namespace_search_path = pstrdup("public");
+ InitializeSessionUserId(nullptr, 1);
};
diff --git a/ydb/library/yql/parser/pg_wrapper/postgresql/src/backend/utils/cache/syscache.c b/ydb/library/yql/parser/pg_wrapper/postgresql/src/backend/utils/cache/syscache.c
index 0c0cd3d9998..06a8950ff56 100644
--- a/ydb/library/yql/parser/pg_wrapper/postgresql/src/backend/utils/cache/syscache.c
+++ b/ydb/library/yql/parser/pg_wrapper/postgresql/src/backend/utils/cache/syscache.c
@@ -1233,7 +1233,7 @@ SearchSysCacheExists(int cacheId,
* No lock is retained on the syscache entry.
*/
Oid
-GetSysCacheOid(int cacheId,
+GetSysCacheOid_original(int cacheId,
AttrNumber oidcol,
Datum key1,
Datum key2,
diff --git a/ydb/library/yql/parser/pg_wrapper/postgresql/src/backend/utils/misc/guc.c b/ydb/library/yql/parser/pg_wrapper/postgresql/src/backend/utils/misc/guc.c
index 59d17137165..3c6963c0946 100644
--- a/ydb/library/yql/parser/pg_wrapper/postgresql/src/backend/utils/misc/guc.c
+++ b/ydb/library/yql/parser/pg_wrapper/postgresql/src/backend/utils/misc/guc.c
@@ -3241,7 +3241,7 @@ set_config_option(const char *name, const char *value,
(errcode(ERRCODE_INVALID_TRANSACTION_STATE),
errmsg("cannot set parameters during a parallel operation")));
- record = find_option(name, true, false, elevel);
+ record = find_option(name, true, true, elevel);
if (record == NULL)
return 0;
diff --git a/ydb/library/yql/parser/pg_wrapper/syscache.cpp b/ydb/library/yql/parser/pg_wrapper/syscache.cpp
index 41599a1e5b9..da2ebfae8aa 100644
--- a/ydb/library/yql/parser/pg_wrapper/syscache.cpp
+++ b/ydb/library/yql/parser/pg_wrapper/syscache.cpp
@@ -6,7 +6,9 @@
extern "C" {
#include "utils/syscache.h"
#include "catalog/pg_database.h"
+#include "catalog/pg_class.h"
#include "catalog/pg_proc.h"
+#include "catalog/pg_namespace.h"
#include "catalog/pg_type.h"
#include "catalog/pg_type_d.h"
#include "catalog/pg_authid.h"
@@ -52,9 +54,30 @@ bool OidEquals1(const THeapTupleKey& key1, const THeapTupleKey& key2) {
return (Oid)std::get<0>(key1) == (Oid)std::get<0>(key2);
}
+size_t NsNameHasher(const THeapTupleKey& key) {
+ return CombineHashes(
+ std::hash<std::string_view>()((const char*)std::get<0>(key)),
+ std::hash<Oid>()((Oid)std::get<1>(key)));
+}
+
+bool NsNameEquals(const THeapTupleKey& key1, const THeapTupleKey& key2) {
+ return strcmp((const char*)std::get<0>(key1), (const char*)std::get<0>(key2)) == 0 &&
+ (Oid)std::get<1>(key1) == (Oid)std::get<1>(key2);
+}
+
+struct TSysCacheItem {
+ TSysCacheItem(THeapTupleHasher hasher, THeapTupleEquals equals, TupleDesc desc)
+ : Map(0, hasher, equals)
+ , Desc(desc)
+ {}
+
+ TSysCacheHashMap Map;
+ TupleDesc Desc;
+};
+
struct TSysCache {
TArenaMemoryContext Arena;
- std::unique_ptr<TSysCacheHashMap> Maps[SysCacheSize];
+ std::unique_ptr<TSysCacheItem> Items[SysCacheSize];
static const TSysCache& Instance() {
return *Singleton<TSysCache>();
@@ -66,6 +89,7 @@ struct TSysCache {
InitializeTypes();
InitializeDatabase();
InitializeAuthId();
+ InitializeNameNamespaces();
Arena.Release();
}
@@ -85,7 +109,6 @@ struct TSysCache {
}
void InitializeProcs() {
- auto& map = Maps[PROCOID] = std::make_unique<TSysCacheHashMap>(0, OidHasher1, OidEquals1);
TupleDesc tupleDesc = CreateTemplateTupleDesc(Natts_pg_proc);
FillAttr(tupleDesc, Anum_pg_proc_oid, OIDOID);
FillAttr(tupleDesc, Anum_pg_proc_proname, NAMEOID);
@@ -117,6 +140,8 @@ struct TSysCache {
FillAttr(tupleDesc, Anum_pg_proc_prosqlbody, PG_NODE_TREEOID);
FillAttr(tupleDesc, Anum_pg_proc_proconfig, TEXTARRAYOID);
FillAttr(tupleDesc, Anum_pg_proc_proacl, ACLITEMARRAYOID);
+ auto& cacheItem = Items[PROCOID] = std::make_unique<TSysCacheItem>(OidHasher1, OidEquals1, tupleDesc);
+ auto& map = cacheItem->Map;
NPg::EnumProc([&](ui32 oid, const NPg::TProcDesc& desc){
auto key = THeapTupleKey(oid, 0, 0, 0);
@@ -128,19 +153,18 @@ struct TSysCache {
std::fill_n(nulls, Anum_pg_proc_prorettype, false); // fixed part of Form_pg_proc
FillDatum(Natts_pg_proc, values, nulls, Anum_pg_proc_oid, oid);
FillDatum(Natts_pg_proc, values, nulls, Anum_pg_proc_prorettype, desc.ResultType);
- auto name = MakeFixedString(desc.Name, NPg::LookupType(NAMEOID).TypeLen);
+ auto name = MakeFixedString(desc.Name, NAMEDATALEN);
FillDatum(Natts_pg_proc, values, nulls, Anum_pg_proc_proname, (Datum)name);
HeapTuple h = heap_form_tuple(tupleDesc, values, nulls);
auto row = (Form_pg_proc)GETSTRUCT(h);
Y_ENSURE(row->oid == oid);
Y_ENSURE(row->prorettype == desc.ResultType);
Y_ENSURE(NameStr(row->proname) == desc.Name);
- map->emplace(key, h);
+ map.emplace(key, h);
});
}
void InitializeTypes() {
- auto& map = Maps[TYPEOID] = std::make_unique<TSysCacheHashMap>(0, OidHasher1, OidEquals1);
TupleDesc tupleDesc = CreateTemplateTupleDesc(Natts_pg_type);
FillAttr(tupleDesc, Anum_pg_type_oid, OIDOID);
FillAttr(tupleDesc, Anum_pg_type_typname, NAMEOID);
@@ -174,6 +198,8 @@ struct TSysCache {
FillAttr(tupleDesc, Anum_pg_type_typdefaultbin, PG_NODE_TREEOID);
FillAttr(tupleDesc, Anum_pg_type_typdefault, TEXTOID);
FillAttr(tupleDesc, Anum_pg_type_typacl, ACLITEMARRAYOID);
+ auto& cacheItems = Items[TYPEOID] = std::make_unique<TSysCacheItem>(OidHasher1, OidEquals1, tupleDesc);
+ auto& map = cacheItems->Map;
NPg::EnumTypes([&](ui32 oid, const NPg::TTypeDesc& desc){
auto key = THeapTupleKey(oid, 0, 0, 0);
@@ -226,13 +252,12 @@ struct TSysCache {
Y_ENSURE(row->typmodout == desc.TypeModOutFuncId);
Y_ENSURE(row->typalign == desc.TypeAlign);
Y_ENSURE(row->typstorage == TYPSTORAGE_PLAIN);
- map->emplace(key, h);
+ map.emplace(key, h);
});
}
void InitializeDatabase() {
- auto& map = Maps[DATABASEOID] = std::make_unique<TSysCacheHashMap>(0, OidHasher1, OidEquals1);
TupleDesc tupleDesc = CreateTemplateTupleDesc(Natts_pg_database);
FillAttr(tupleDesc, Anum_pg_database_oid, OIDOID);
FillAttr(tupleDesc, Anum_pg_database_datname, NAMEOID);
@@ -248,6 +273,8 @@ struct TSysCache {
FillAttr(tupleDesc, Anum_pg_database_datminmxid, XIDOID);
FillAttr(tupleDesc, Anum_pg_database_dattablespace, OIDOID);
FillAttr(tupleDesc, Anum_pg_database_datacl, ACLITEMARRAYOID);
+ auto& cacheItems = Items[DATABASEOID] = std::make_unique<TSysCacheItem>(OidHasher1, OidEquals1, tupleDesc);
+ auto& map = cacheItems->Map;
for (ui32 oid = 1; oid <= 3; ++oid) {
auto key = THeapTupleKey(oid, 0, 0, 0);
@@ -269,12 +296,11 @@ struct TSysCache {
auto row = (Form_pg_database) GETSTRUCT(h);
Y_ENSURE(row->oid == oid);
Y_ENSURE(strcmp(NameStr(row->datname), name) == 0);
- map->emplace(key, h);
+ map.emplace(key, h);
}
}
void InitializeAuthId() {
- auto& map = Maps[AUTHOID] = std::make_unique<TSysCacheHashMap>(0, OidHasher1, OidEquals1);
TupleDesc tupleDesc = CreateTemplateTupleDesc(Natts_pg_authid);
FillAttr(tupleDesc, Anum_pg_authid_oid, OIDOID);
FillAttr(tupleDesc, Anum_pg_authid_rolname, NAMEOID);
@@ -288,6 +314,9 @@ struct TSysCache {
FillAttr(tupleDesc, Anum_pg_authid_rolconnlimit, INT4OID);
FillAttr(tupleDesc, Anum_pg_authid_rolpassword, TEXTOID);
FillAttr(tupleDesc, Anum_pg_authid_rolvaliduntil, TIMESTAMPTZOID);
+ auto& cacheItems = Items[AUTHOID] = std::make_unique<TSysCacheItem>(OidHasher1, OidEquals1, tupleDesc);
+ auto& map = cacheItems->Map;
+
auto key = THeapTupleKey(1, 0, 0, 0);
const char* rolname = "postgres";
@@ -318,7 +347,69 @@ struct TSysCache {
Y_ENSURE(row->rolreplication);
Y_ENSURE(row->rolbypassrls);
Y_ENSURE(row->rolconnlimit == -1);
- map->emplace(key, h);
+ map.emplace(key, h);
+ }
+
+ void InitializeNameNamespaces() {
+ TupleDesc tupleDesc = CreateTemplateTupleDesc(Natts_pg_class);
+ FillAttr(tupleDesc, Anum_pg_class_oid, OIDOID);
+ FillAttr(tupleDesc, Anum_pg_class_relname, NAMEOID);
+ FillAttr(tupleDesc, Anum_pg_class_relnamespace, OIDOID);
+ FillAttr(tupleDesc, Anum_pg_class_reltype, OIDOID);
+ FillAttr(tupleDesc, Anum_pg_class_reloftype, OIDOID);
+ FillAttr(tupleDesc, Anum_pg_class_relowner, OIDOID);
+ FillAttr(tupleDesc, Anum_pg_class_relam, OIDOID);
+ FillAttr(tupleDesc, Anum_pg_class_relfilenode, OIDOID);
+ FillAttr(tupleDesc, Anum_pg_class_reltablespace, OIDOID);
+ FillAttr(tupleDesc, Anum_pg_class_relpages, INT4OID);
+ FillAttr(tupleDesc, Anum_pg_class_reltuples, FLOAT4OID);
+ FillAttr(tupleDesc, Anum_pg_class_relallvisible, INT4OID);
+ FillAttr(tupleDesc, Anum_pg_class_reltoastrelid, OIDOID);
+ FillAttr(tupleDesc, Anum_pg_class_relhasindex, BOOLOID);
+ FillAttr(tupleDesc, Anum_pg_class_relisshared, BOOLOID);
+ FillAttr(tupleDesc, Anum_pg_class_relpersistence, CHAROID);
+ FillAttr(tupleDesc, Anum_pg_class_relkind, CHAROID);
+ FillAttr(tupleDesc, Anum_pg_class_relnatts, INT2OID);
+ FillAttr(tupleDesc, Anum_pg_class_relchecks, INT2OID);
+ FillAttr(tupleDesc, Anum_pg_class_relhasrules, BOOLOID);
+ FillAttr(tupleDesc, Anum_pg_class_relhastriggers, BOOLOID);
+ FillAttr(tupleDesc, Anum_pg_class_relhassubclass, BOOLOID);
+ FillAttr(tupleDesc, Anum_pg_class_relrowsecurity, BOOLOID);
+ FillAttr(tupleDesc, Anum_pg_class_relforcerowsecurity, BOOLOID);
+ FillAttr(tupleDesc, Anum_pg_class_relispopulated, BOOLOID);
+ FillAttr(tupleDesc, Anum_pg_class_relreplident, CHAROID);
+ FillAttr(tupleDesc, Anum_pg_class_relispartition, BOOLOID);
+ FillAttr(tupleDesc, Anum_pg_class_relrewrite, OIDOID);
+ FillAttr(tupleDesc, Anum_pg_class_relfrozenxid, XIDOID);
+ FillAttr(tupleDesc, Anum_pg_class_relminmxid, XIDOID);
+ FillAttr(tupleDesc, Anum_pg_class_relacl, ACLITEMARRAYOID);
+ FillAttr(tupleDesc, Anum_pg_class_reloptions, TEXTARRAYOID);
+ FillAttr(tupleDesc, Anum_pg_class_relpartbound, PG_NODE_TREEOID);
+ auto& cacheItems = Items[RELNAMENSP] = std::make_unique<TSysCacheItem>(NsNameHasher, NsNameEquals, tupleDesc);
+ auto& map = cacheItems->Map;
+
+ Datum values[Natts_pg_class];
+ bool nulls[Natts_pg_class];
+ Zero(values);
+ std::fill_n(nulls, Natts_pg_class, true);
+ std::fill_n(nulls, Anum_pg_class_relminmxid, false); // fixed part of Form_pg_class
+ for (const auto& t : NPg::GetStaticTables()) {
+ auto name = (Datum)MakeFixedString(t.Name, NAMEDATALEN);
+ auto ns = (Datum)(t.Schema == "pg_catalog" ? PG_CATALOG_NAMESPACE : 1);
+ FillDatum(Natts_pg_class, values, nulls, Anum_pg_class_oid, (Datum)t.Oid);
+ FillDatum(Natts_pg_class, values, nulls, Anum_pg_class_relname, name);
+ FillDatum(Natts_pg_class, values, nulls, Anum_pg_class_relnamespace, ns);
+ FillDatum(Natts_pg_class, values, nulls, Anum_pg_class_relowner, (Datum)1);
+ HeapTuple h = heap_form_tuple(tupleDesc, values, nulls);
+ auto row = (Form_pg_class) GETSTRUCT(h);
+ Y_ENSURE(row->oid == t.Oid);
+ Y_ENSURE(strcmp(NameStr(row->relname), t.Name.c_str()) == 0);
+ Y_ENSURE(row->relowner == 1);
+ Y_ENSURE(row->relnamespace == ns);
+
+ auto key = THeapTupleKey(name, ns, 0, 0);
+ map.emplace(key, h);
+ }
}
};
@@ -327,14 +418,15 @@ struct TSysCache {
HeapTuple SearchSysCache(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4) {
- Y_ENSURE(cacheId >= 0 && cacheId < SysCacheSize);
- const auto& map = NYql::TSysCache::Instance().Maps[cacheId];
- if (!map) {
+ Y_ENSURE(cacheId >= 0 && cacheId < SysCacheSize);
+ const auto& cacheItem = NYql::TSysCache::Instance().Items[cacheId];
+ if (!cacheItem) {
return nullptr;
}
- auto it = map->find(std::make_tuple(key1, key2, key3, key4));
- if (it == map->end()) {
+ const auto& map = cacheItem->Map;
+ auto it = map.find(std::make_tuple(key1, key2, key3, key4));
+ if (it == map.end()) {
return nullptr;
}
@@ -361,4 +453,20 @@ void ReleaseSysCache(HeapTuple tuple) {
Y_UNUSED(tuple);
}
+Oid GetSysCacheOid(int cacheId, AttrNumber oidcol, Datum key1, Datum key2, Datum key3, Datum key4) {
+ Y_ENSURE(cacheId >= 0 && cacheId < SysCacheSize);
+ const auto& cacheItem = NYql::TSysCache::Instance().Items[cacheId];
+ HeapTuple tuple;
+ bool isNull;
+ Oid result;
+
+ tuple = SearchSysCache(cacheId, key1, key2, key3, key4);
+ if (!HeapTupleIsValid(tuple))
+ return InvalidOid;
+ result = heap_getattr(tuple, oidcol, cacheItem->Desc, &isNull);
+ Y_ENSURE(!isNull); /* columns used as oids should never be NULL */
+ ReleaseSysCache(tuple);
+ return result;
+}
+
diff --git a/ydb/library/yql/parser/pg_wrapper/ya.make b/ydb/library/yql/parser/pg_wrapper/ya.make
index 6e99f8b04dc..978e1137c8b 100644
--- a/ydb/library/yql/parser/pg_wrapper/ya.make
+++ b/ydb/library/yql/parser/pg_wrapper/ya.make
@@ -62,6 +62,10 @@ ELSE()
CFLAGS(-DUSE_SLOW_PG_KERNELS)
ENDIF()
+IF (BUILD_TYPE == "DEBUG")
+CFLAGS(-DDISABLE_COMPLEX_MACRO)
+ENDIF()
+
PEERDIR(
library/cpp/resource
library/cpp/yson