Skip to content

Commit 94714ba

Browse files
authored
Merge de88d1e into 61cd3dd
2 parents 61cd3dd + de88d1e commit 94714ba

File tree

3 files changed

+174
-21
lines changed

3 files changed

+174
-21
lines changed

ydb/library/yql/parser/pg_wrapper/postgresql/src/backend/utils/cache/catcache.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1783,6 +1783,7 @@ SearchCatCacheList(CatCache *cache,
17831783
void
17841784
ReleaseCatCacheList(CatCList *list)
17851785
{
1786+
return;
17861787
/* Safety checks to ensure we were handed a cache entry */
17871788
Assert(list->cl_magic == CL_MAGIC);
17881789
Assert(list->refcount > 0);

ydb/library/yql/parser/pg_wrapper/postgresql/src/backend/utils/cache/syscache.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1437,7 +1437,7 @@ GetSysCacheHashValue(int cacheId,
14371437
* List-search interface
14381438
*/
14391439
struct catclist *
1440-
SearchSysCacheList(int cacheId, int nkeys,
1440+
SearchSysCacheList_original(int cacheId, int nkeys,
14411441
Datum key1, Datum key2, Datum key3)
14421442
{
14431443
if (cacheId < 0 || cacheId >= SysCacheSize ||

ydb/library/yql/parser/pg_wrapper/syscache.cpp

Lines changed: 172 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
extern "C" {
77
#include "utils/syscache.h"
8+
#include "utils/catcache.h"
89
#include "catalog/pg_database.h"
910
#include "catalog/pg_class.h"
1011
#include "catalog/pg_proc.h"
@@ -47,6 +48,13 @@ using THeapTupleHasher = std::function<size_t(const THeapTupleKey&)>;
4748
using THeapTupleEquals = std::function<bool(const THeapTupleKey&, const THeapTupleKey&)>;
4849
using TSysCacheHashMap = std::unordered_map<THeapTupleKey, HeapTuple, THeapTupleHasher, THeapTupleEquals>;
4950

51+
struct TRangeItem {
52+
TVector<HeapTuple> Items;
53+
CatCList* CList = nullptr;
54+
};
55+
56+
using TSysCacheRangeMap = std::unordered_map<THeapTupleKey, TRangeItem, THeapTupleHasher, THeapTupleEquals>;
57+
5058
size_t OidHasher1(const THeapTupleKey& key) {
5159
return std::hash<Oid>()((Oid)std::get<0>(key));
5260
}
@@ -66,14 +74,124 @@ bool NsNameEquals(const THeapTupleKey& key1, const THeapTupleKey& key2) {
6674
(Oid)std::get<1>(key1) == (Oid)std::get<1>(key2);
6775
}
6876

77+
size_t OidVectorHash(Datum d) {
78+
oidvector *v = (oidvector *)d;
79+
if (!v->ndim) {
80+
return 0;
81+
}
82+
83+
Y_DEBUG_ABORT_UNLESS(v->ndim == 1);
84+
size_t hash = v->dim1;
85+
for (int i = 0; i < v->dim1; ++i) {
86+
hash = CombineHashes(hash, std::hash<Oid>()(v->values[i]));
87+
}
88+
89+
return hash;
90+
}
91+
92+
bool OidVectorEquals(Datum d1, Datum d2) {
93+
oidvector *v1 = (oidvector *)d1;
94+
oidvector *v2 = (oidvector *)d2;
95+
if (v1->ndim != v2->ndim) {
96+
return false;
97+
}
98+
99+
if (v1->ndim == 0) {
100+
return true;
101+
}
102+
103+
Y_DEBUG_ABORT_UNLESS(v1->ndim == 1);
104+
if (v1->dim1 != v2->dim1) {
105+
return false;
106+
}
107+
108+
for (int i = 0; i < v1->dim1; ++i) {
109+
if (v1->values[i] != v2->values[i]) {
110+
return false;
111+
}
112+
}
113+
114+
return true;
115+
}
116+
117+
size_t ByNameProcHasher1(const THeapTupleKey& key) {
118+
return std::hash<std::string_view>()((const char*)std::get<0>(key));
119+
}
120+
121+
size_t ByNameProcHasher3(const THeapTupleKey& key) {
122+
return CombineHashes(CombineHashes(std::hash<std::string_view>()((const char*)std::get<0>(key)),
123+
OidVectorHash(std::get<1>(key))),
124+
std::hash<Oid>()((Oid)std::get<2>(key)));
125+
}
126+
127+
bool ByNameProcEquals1(const THeapTupleKey& key1, const THeapTupleKey& key2) {
128+
return strcmp((const char*)std::get<0>(key1), (const char*)std::get<0>(key2)) == 0;
129+
}
130+
131+
bool ByNameProcEquals3(const THeapTupleKey& key1, const THeapTupleKey& key2) {
132+
return strcmp((const char*)std::get<0>(key1), (const char*)std::get<0>(key2)) == 0 &&
133+
OidVectorEquals(std::get<1>(key1), std::get<1>(key2)) &&
134+
(Oid)std::get<2>(key1) == (Oid)std::get<2>(key2);
135+
}
136+
69137
struct TSysCacheItem {
70-
TSysCacheItem(THeapTupleHasher hasher, THeapTupleEquals equals, TupleDesc desc)
71-
: Map(0, hasher, equals)
138+
TSysCacheItem(THeapTupleHasher hasher, THeapTupleEquals equals, TupleDesc desc, ui32 numKeys = 1,
139+
THeapTupleHasher hasherRange1 = {}, THeapTupleEquals equalsRange1 = {})
140+
: NumKeys(numKeys)
141+
, LookupMap(0, hasher, equals)
142+
, RangeMap1(numKeys > 1 ? TMaybe<TSysCacheRangeMap>(TSysCacheRangeMap(0, hasherRange1, equalsRange1)) : Nothing())
72143
, Desc(desc)
73144
{}
74145

75-
TSysCacheHashMap Map;
146+
CatCList* BuildCList(const TVector<HeapTuple>& items) {
147+
auto cl = (CatCList *)palloc(offsetof(CatCList, members) + items.size() * sizeof(CatCTup *));
148+
cl->cl_magic = CL_MAGIC;
149+
cl->my_cache = nullptr;
150+
cl->refcount = 0;
151+
cl->dead = false;
152+
cl->ordered = false;
153+
cl->nkeys = NumKeys;
154+
cl->hash_value = 0;
155+
cl->n_members = items.size();
156+
for (size_t i = 0; i < items.size(); ++i) {
157+
auto dtp = items[i];
158+
auto ct = (CatCTup *) palloc(sizeof(CatCTup) + MAXIMUM_ALIGNOF + dtp->t_len);
159+
ct->ct_magic = CT_MAGIC;
160+
ct->my_cache = nullptr;
161+
ct->c_list = NULL;
162+
ct->refcount = 0;
163+
ct->dead = false;
164+
ct->negative = false;
165+
ct->hash_value = 0;
166+
Zero(ct->keys);
167+
168+
ct->tuple.t_len = dtp->t_len;
169+
ct->tuple.t_self = dtp->t_self;
170+
ct->tuple.t_tableOid = dtp->t_tableOid;
171+
ct->tuple.t_data = (HeapTupleHeader)MAXALIGN(((char *) ct) + sizeof(CatCTup));
172+
/* copy tuple contents */
173+
std::memcpy((char *) ct->tuple.t_data, (const char *) dtp->t_data, dtp->t_len);
174+
cl->members[i] = ct;
175+
}
176+
177+
return cl;
178+
}
179+
180+
void FinalizeRangeMaps() {
181+
if (RangeMap1) {
182+
for (auto& x : *RangeMap1) {
183+
x.second.CList = BuildCList(x.second.Items);
184+
}
185+
}
186+
187+
EmptyCList = BuildCList({});
188+
}
189+
190+
const ui32 NumKeys;
191+
TSysCacheHashMap LookupMap;
192+
TMaybe<TSysCacheRangeMap> RangeMap1;
76193
TupleDesc Desc;
194+
CatCList* EmptyCList = nullptr;
77195
};
78196

79197
struct TSysCache {
@@ -91,6 +209,12 @@ struct TSysCache {
91209
InitializeDatabase();
92210
InitializeAuthId();
93211
InitializeNameNamespaces();
212+
for (auto& item : Items) {
213+
if (item) {
214+
item->FinalizeRangeMaps();
215+
}
216+
}
217+
94218
Arena.Release();
95219
}
96220

@@ -142,7 +266,11 @@ struct TSysCache {
142266
FillAttr(tupleDesc, Anum_pg_proc_proconfig, TEXTARRAYOID);
143267
FillAttr(tupleDesc, Anum_pg_proc_proacl, ACLITEMARRAYOID);
144268
auto& cacheItem = Items[PROCOID] = std::make_unique<TSysCacheItem>(OidHasher1, OidEquals1, tupleDesc);
145-
auto& map = cacheItem->Map;
269+
auto& lookupMap = cacheItem->LookupMap;
270+
271+
auto& byNameCacheItem = Items[PROCNAMEARGSNSP] = std::make_unique<TSysCacheItem>(ByNameProcHasher3, ByNameProcEquals3, tupleDesc, 3, ByNameProcHasher1, ByNameProcEquals1);
272+
auto& byNameLookupMap = byNameCacheItem->LookupMap;
273+
auto& byNameRangeMap1 = *byNameCacheItem->RangeMap1;
146274

147275
const auto& oidDesc = NPg::LookupType(OIDOID);
148276
const auto& charDesc = NPg::LookupType(CHAROID);
@@ -236,7 +364,13 @@ struct TSysCache {
236364
Y_ENSURE(row->prorettype == desc.ResultType);
237365
Y_ENSURE(NameStr(row->proname) == desc.Name);
238366
Y_ENSURE(row->pronargs == desc.ArgTypes.size());
239-
map.emplace(key, h);
367+
lookupMap.emplace(key, h);
368+
369+
THeapTupleKey byNameLookupKey((Datum)name, (Datum)&row->proargtypes, PG_CATALOG_NAMESPACE, 0);
370+
THeapTupleKey byNameRangeKey1((Datum)name, 0, 0, 0);
371+
372+
byNameLookupMap.emplace(byNameLookupKey, h);
373+
byNameRangeMap1[byNameRangeKey1].Items.push_back(h);
240374
});
241375
}
242376

@@ -274,8 +408,8 @@ struct TSysCache {
274408
FillAttr(tupleDesc, Anum_pg_type_typdefaultbin, PG_NODE_TREEOID);
275409
FillAttr(tupleDesc, Anum_pg_type_typdefault, TEXTOID);
276410
FillAttr(tupleDesc, Anum_pg_type_typacl, ACLITEMARRAYOID);
277-
auto& cacheItems = Items[TYPEOID] = std::make_unique<TSysCacheItem>(OidHasher1, OidEquals1, tupleDesc);
278-
auto& map = cacheItems->Map;
411+
auto& cacheItem = Items[TYPEOID] = std::make_unique<TSysCacheItem>(OidHasher1, OidEquals1, tupleDesc);
412+
auto& lookupMap = cacheItem->LookupMap;
279413

280414
NPg::EnumTypes([&](ui32 oid, const NPg::TTypeDesc& desc){
281415
auto key = THeapTupleKey(oid, 0, 0, 0);
@@ -329,7 +463,7 @@ struct TSysCache {
329463
Y_ENSURE(row->typmodout == desc.TypeModOutFuncId);
330464
Y_ENSURE(row->typalign == desc.TypeAlign);
331465
Y_ENSURE(row->typstorage == storage);
332-
map.emplace(key, h);
466+
lookupMap.emplace(key, h);
333467
});
334468

335469
}
@@ -350,8 +484,8 @@ struct TSysCache {
350484
FillAttr(tupleDesc, Anum_pg_database_datminmxid, XIDOID);
351485
FillAttr(tupleDesc, Anum_pg_database_dattablespace, OIDOID);
352486
FillAttr(tupleDesc, Anum_pg_database_datacl, ACLITEMARRAYOID);
353-
auto& cacheItems = Items[DATABASEOID] = std::make_unique<TSysCacheItem>(OidHasher1, OidEquals1, tupleDesc);
354-
auto& map = cacheItems->Map;
487+
auto& cacheItem = Items[DATABASEOID] = std::make_unique<TSysCacheItem>(OidHasher1, OidEquals1, tupleDesc);
488+
auto& lookupMap = cacheItem->LookupMap;
355489

356490
for (ui32 oid = 1; oid <= 3; ++oid) {
357491
auto key = THeapTupleKey(oid, 0, 0, 0);
@@ -373,7 +507,7 @@ struct TSysCache {
373507
auto row = (Form_pg_database) GETSTRUCT(h);
374508
Y_ENSURE(row->oid == oid);
375509
Y_ENSURE(strcmp(NameStr(row->datname), name) == 0);
376-
map.emplace(key, h);
510+
lookupMap.emplace(key, h);
377511
}
378512
}
379513

@@ -391,8 +525,8 @@ struct TSysCache {
391525
FillAttr(tupleDesc, Anum_pg_authid_rolconnlimit, INT4OID);
392526
FillAttr(tupleDesc, Anum_pg_authid_rolpassword, TEXTOID);
393527
FillAttr(tupleDesc, Anum_pg_authid_rolvaliduntil, TIMESTAMPTZOID);
394-
auto& cacheItems = Items[AUTHOID] = std::make_unique<TSysCacheItem>(OidHasher1, OidEquals1, tupleDesc);
395-
auto& map = cacheItems->Map;
528+
auto& cacheItem = Items[AUTHOID] = std::make_unique<TSysCacheItem>(OidHasher1, OidEquals1, tupleDesc);
529+
auto& lookupMap = cacheItem->LookupMap;
396530

397531
auto key = THeapTupleKey(1, 0, 0, 0);
398532

@@ -424,7 +558,7 @@ struct TSysCache {
424558
Y_ENSURE(row->rolreplication);
425559
Y_ENSURE(row->rolbypassrls);
426560
Y_ENSURE(row->rolconnlimit == -1);
427-
map.emplace(key, h);
561+
lookupMap.emplace(key, h);
428562
}
429563

430564
void InitializeNameNamespaces() {
@@ -462,8 +596,8 @@ struct TSysCache {
462596
FillAttr(tupleDesc, Anum_pg_class_relacl, ACLITEMARRAYOID);
463597
FillAttr(tupleDesc, Anum_pg_class_reloptions, TEXTARRAYOID);
464598
FillAttr(tupleDesc, Anum_pg_class_relpartbound, PG_NODE_TREEOID);
465-
auto& cacheItems = Items[RELNAMENSP] = std::make_unique<TSysCacheItem>(NsNameHasher, NsNameEquals, tupleDesc);
466-
auto& map = cacheItems->Map;
599+
auto& cacheItem = Items[RELNAMENSP] = std::make_unique<TSysCacheItem>(NsNameHasher, NsNameEquals, tupleDesc);
600+
auto& lookupMap = cacheItem->LookupMap;
467601

468602
Datum values[Natts_pg_class];
469603
bool nulls[Natts_pg_class];
@@ -485,7 +619,7 @@ struct TSysCache {
485619
Y_ENSURE(row->relnamespace == ns);
486620

487621
auto key = THeapTupleKey(name, ns, 0, 0);
488-
map.emplace(key, h);
622+
lookupMap.emplace(key, h);
489623
}
490624
}
491625
};
@@ -501,9 +635,9 @@ HeapTuple SearchSysCache(int cacheId, Datum key1, Datum key2, Datum key3, Datum
501635
return nullptr;
502636
}
503637

504-
const auto& map = cacheItem->Map;
505-
auto it = map.find(std::make_tuple(key1, key2, key3, key4));
506-
if (it == map.end()) {
638+
const auto& lookupMap = cacheItem->LookupMap;
639+
auto it = lookupMap.find(std::make_tuple(key1, key2, key3, key4));
640+
if (it == lookupMap.end()) {
507641
return nullptr;
508642
}
509643

@@ -554,3 +688,21 @@ Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bo
554688
Y_ENSURE(cacheItem);
555689
return heap_getattr(tup, attributeNumber, cacheItem->Desc, isNull);
556690
}
691+
692+
struct catclist* SearchSysCacheList(int cacheId, int nkeys, Datum key1, Datum key2, Datum key3) {
693+
Y_ENSURE(cacheId >= 0 && cacheId < SysCacheSize);
694+
const auto& cacheItem = NYql::TSysCache::Instance().Items[cacheId];
695+
Y_ENSURE(cacheItem);
696+
if (nkeys == 1 && cacheItem->NumKeys > 1) {
697+
const auto& rangeMap1 = *cacheItem->RangeMap1;
698+
auto it = rangeMap1.find(std::make_tuple(key1, 0, 0, 0));
699+
if (it == rangeMap1.end()) {
700+
return cacheItem->EmptyCList;
701+
}
702+
703+
return it->second.CList;
704+
}
705+
706+
return cacheItem->EmptyCList;
707+
}
708+

0 commit comments

Comments
 (0)