syscache.cpp 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852
  1. #include "pg_compat.h"
  2. #define SortBy PG_SortBy
  3. #define TypeName PG_TypeName
  4. extern "C" {
  5. #include "utils/syscache.h"
  6. #include "utils/catcache.h"
  7. #include "catalog/pg_database.h"
  8. #include "catalog/pg_class.h"
  9. #include "catalog/pg_proc.h"
  10. #include "catalog/pg_namespace.h"
  11. #include "catalog/pg_type.h"
  12. #include "catalog/pg_type_d.h"
  13. #include "catalog/pg_authid.h"
  14. #include "access/htup_details.h"
  15. #include "utils/fmgroids.h"
  16. #include "utils/array.h"
  17. #include "utils/builtins.h"
  18. }
  19. #undef TypeName
  20. #undef SortBy
  21. #undef LOG
  22. #undef INFO
  23. #undef NOTICE
  24. #undef WARNING
  25. //#undef ERROR
  26. #undef FATAL
  27. #undef PANIC
  28. #undef open
  29. #undef fopen
  30. #undef bind
  31. #undef locale_t
  32. #include <yql/essentials/minikql/mkql_alloc.h>
  33. #include <yql/essentials/parser/pg_catalog/catalog.h>
  34. #include <yql/essentials/parser/pg_wrapper/interface/context.h>
  35. #include <yql/essentials/parser/pg_wrapper/memory_context.h>
  36. #include <yql/essentials/parser/pg_wrapper/pg_catalog_consts.h>
  37. #include "arena_ctx.h"
  38. #include "utils.h"
  39. #include <unordered_map>
  40. #include <functional>
  41. #include <tuple>
  42. namespace NYql {
  43. namespace {
  44. using THeapTupleKey = std::tuple<Datum, Datum, Datum, Datum>;
  45. using THeapTupleHasher = std::function<size_t(const THeapTupleKey&)>;
  46. using THeapTupleEquals = std::function<bool(const THeapTupleKey&, const THeapTupleKey&)>;
  47. using TSysCacheHashMap = std::unordered_map<THeapTupleKey, HeapTuple, THeapTupleHasher, THeapTupleEquals>;
  48. struct TRangeItem {
  49. TVector<HeapTuple> Items;
  50. CatCList* CList = nullptr;
  51. };
  52. using TSysCacheRangeMap = std::unordered_map<THeapTupleKey, TRangeItem, THeapTupleHasher, THeapTupleEquals>;
  53. size_t OidHasher1(const THeapTupleKey& key) {
  54. return std::hash<Oid>()((Oid)std::get<0>(key));
  55. }
  56. bool OidEquals1(const THeapTupleKey& key1, const THeapTupleKey& key2) {
  57. return (Oid)std::get<0>(key1) == (Oid)std::get<0>(key2);
  58. }
  59. size_t NsNameHasher(const THeapTupleKey& key) {
  60. return CombineHashes(
  61. std::hash<std::string_view>()((const char*)std::get<0>(key)),
  62. std::hash<Oid>()((Oid)std::get<1>(key)));
  63. }
  64. bool NsNameEquals(const THeapTupleKey& key1, const THeapTupleKey& key2) {
  65. return strcmp((const char*)std::get<0>(key1), (const char*)std::get<0>(key2)) == 0 &&
  66. (Oid)std::get<1>(key1) == (Oid)std::get<1>(key2);
  67. }
  68. size_t OidVectorHash(Datum d) {
  69. oidvector *v = (oidvector *)d;
  70. Y_DEBUG_ABORT_UNLESS(v->ndim == 1);
  71. size_t hash = v->dim1;
  72. for (int i = 0; i < v->dim1; ++i) {
  73. hash = CombineHashes(hash, std::hash<Oid>()(v->values[i]));
  74. }
  75. return hash;
  76. }
  77. bool OidVectorEquals(Datum d1, Datum d2) {
  78. oidvector *v1 = (oidvector *)d1;
  79. oidvector *v2 = (oidvector *)d2;
  80. Y_DEBUG_ABORT_UNLESS(v1->ndim == 1 && v2->ndim == 1);
  81. if (v1->dim1 != v2->dim1) {
  82. return false;
  83. }
  84. for (int i = 0; i < v1->dim1; ++i) {
  85. if (v1->values[i] != v2->values[i]) {
  86. return false;
  87. }
  88. }
  89. return true;
  90. }
  91. size_t ByNameProcHasher1(const THeapTupleKey& key) {
  92. return std::hash<std::string_view>()((const char*)std::get<0>(key));
  93. }
  94. size_t ByNameProcHasher3(const THeapTupleKey& key) {
  95. return CombineHashes(CombineHashes(std::hash<std::string_view>()((const char*)std::get<0>(key)),
  96. OidVectorHash(std::get<1>(key))),
  97. std::hash<Oid>()((Oid)std::get<2>(key)));
  98. }
  99. bool ByNameProcEquals1(const THeapTupleKey& key1, const THeapTupleKey& key2) {
  100. return strcmp((const char*)std::get<0>(key1), (const char*)std::get<0>(key2)) == 0;
  101. }
  102. bool ByNameProcEquals3(const THeapTupleKey& key1, const THeapTupleKey& key2) {
  103. return strcmp((const char*)std::get<0>(key1), (const char*)std::get<0>(key2)) == 0 &&
  104. OidVectorEquals(std::get<1>(key1), std::get<1>(key2)) &&
  105. (Oid)std::get<2>(key1) == (Oid)std::get<2>(key2);
  106. }
  107. struct TSysCacheItem {
  108. TSysCacheItem(THeapTupleHasher hasher, THeapTupleEquals equals, TupleDesc desc, ui32 numKeys = 1,
  109. THeapTupleHasher hasherRange1 = {}, THeapTupleEquals equalsRange1 = {})
  110. : NumKeys(numKeys)
  111. , LookupMap(0, hasher, equals)
  112. , RangeMap1(numKeys > 1 ? TMaybe<TSysCacheRangeMap>(TSysCacheRangeMap(0, hasherRange1, equalsRange1)) : Nothing())
  113. , Desc(desc)
  114. {}
  115. CatCList* BuildCList(const TVector<HeapTuple>& items) {
  116. auto cl = (CatCList *)palloc(offsetof(CatCList, members) + items.size() * sizeof(CatCTup *));
  117. cl->cl_magic = CL_MAGIC;
  118. cl->my_cache = nullptr;
  119. cl->refcount = 0;
  120. cl->dead = false;
  121. cl->ordered = false;
  122. cl->nkeys = NumKeys;
  123. cl->hash_value = 0;
  124. cl->n_members = items.size();
  125. for (size_t i = 0; i < items.size(); ++i) {
  126. auto dtp = items[i];
  127. auto ct = (CatCTup *) palloc(sizeof(CatCTup) + MAXIMUM_ALIGNOF + dtp->t_len);
  128. ct->ct_magic = CT_MAGIC;
  129. ct->my_cache = nullptr;
  130. ct->c_list = NULL;
  131. ct->refcount = 0;
  132. ct->dead = false;
  133. ct->negative = false;
  134. ct->hash_value = 0;
  135. Zero(ct->keys);
  136. ct->tuple.t_len = dtp->t_len;
  137. ct->tuple.t_self = dtp->t_self;
  138. ct->tuple.t_tableOid = dtp->t_tableOid;
  139. ct->tuple.t_data = (HeapTupleHeader)MAXALIGN(((char *) ct) + sizeof(CatCTup));
  140. /* copy tuple contents */
  141. std::memcpy((char *) ct->tuple.t_data, (const char *) dtp->t_data, dtp->t_len);
  142. cl->members[i] = ct;
  143. }
  144. return cl;
  145. }
  146. void FinalizeRangeMaps() {
  147. if (RangeMap1) {
  148. for (auto& x : *RangeMap1) {
  149. x.second.CList = BuildCList(x.second.Items);
  150. }
  151. }
  152. EmptyCList = BuildCList({});
  153. }
  154. const ui32 NumKeys;
  155. TSysCacheHashMap LookupMap;
  156. TMaybe<TSysCacheRangeMap> RangeMap1;
  157. TupleDesc Desc;
  158. CatCList* EmptyCList = nullptr;
  159. std::function<std::optional<HeapTuple>(const THeapTupleKey&)> PgThreadContextLookup = nullptr;
  160. };
  161. struct TSysCache {
  162. TArenaMemoryContext Arena;
  163. std::unique_ptr<TSysCacheItem> Items[SysCacheSize];
  164. static const TSysCache& Instance() {
  165. return *Singleton<TSysCache>();
  166. }
  167. static TSysCache& MutableInstance() {
  168. return *Singleton<TSysCache>();
  169. }
  170. TSysCache()
  171. {
  172. Arena.Release();
  173. Rebuild();
  174. }
  175. ~TSysCache() {
  176. Arena.Acquire();
  177. }
  178. void Rebuild() {
  179. with_lock(Arena) {
  180. for (auto& x : Items) {
  181. x.reset();
  182. }
  183. InitializeProcs();
  184. InitializeTypes();
  185. InitializeDatabase();
  186. InitializeAuthId();
  187. InitializeNameAndOidNamespaces();
  188. InitializeRelNameNamespaces();
  189. for (auto& item : Items) {
  190. if (item) {
  191. item->FinalizeRangeMaps();
  192. }
  193. }
  194. }
  195. }
  196. static void FillDatum(ui32 count, Datum* values, bool* nulls, ui32 attrNum, Datum value) {
  197. Y_ENSURE(attrNum > 0 && attrNum <= count);
  198. values[attrNum - 1] = value;
  199. nulls[attrNum - 1] = false;
  200. }
  201. static void FillAttr(TupleDesc tupleDesc, ui32 attrNum, Oid type) {
  202. Y_ENSURE(attrNum > 0 && attrNum <= tupleDesc->natts);
  203. TupleDescInitEntry(tupleDesc, attrNum, nullptr, type, -1, 0);
  204. }
  205. void InitializeProcs() {
  206. TupleDesc tupleDesc = CreateTemplateTupleDesc(Natts_pg_proc);
  207. FillAttr(tupleDesc, Anum_pg_proc_oid, OIDOID);
  208. FillAttr(tupleDesc, Anum_pg_proc_proname, NAMEOID);
  209. FillAttr(tupleDesc, Anum_pg_proc_pronamespace, OIDOID);
  210. FillAttr(tupleDesc, Anum_pg_proc_proowner, OIDOID);
  211. FillAttr(tupleDesc, Anum_pg_proc_prolang, OIDOID);
  212. FillAttr(tupleDesc, Anum_pg_proc_procost, FLOAT4OID);
  213. FillAttr(tupleDesc, Anum_pg_proc_prorows, FLOAT4OID);
  214. FillAttr(tupleDesc, Anum_pg_proc_provariadic, OIDOID);
  215. FillAttr(tupleDesc, Anum_pg_proc_prosupport, REGPROCOID);
  216. FillAttr(tupleDesc, Anum_pg_proc_prokind, CHAROID);
  217. FillAttr(tupleDesc, Anum_pg_proc_prosecdef, BOOLOID);
  218. FillAttr(tupleDesc, Anum_pg_proc_proleakproof, BOOLOID);
  219. FillAttr(tupleDesc, Anum_pg_proc_proisstrict, BOOLOID);
  220. FillAttr(tupleDesc, Anum_pg_proc_proretset, BOOLOID);
  221. FillAttr(tupleDesc, Anum_pg_proc_provolatile, CHAROID);
  222. FillAttr(tupleDesc, Anum_pg_proc_proparallel, CHAROID);
  223. FillAttr(tupleDesc, Anum_pg_proc_pronargs, INT2OID);
  224. FillAttr(tupleDesc, Anum_pg_proc_pronargdefaults, INT2OID);
  225. FillAttr(tupleDesc, Anum_pg_proc_prorettype, OIDOID);
  226. FillAttr(tupleDesc, Anum_pg_proc_proargtypes, OIDVECTOROID);
  227. FillAttr(tupleDesc, Anum_pg_proc_proallargtypes, OIDARRAYOID);
  228. FillAttr(tupleDesc, Anum_pg_proc_proargmodes, TEXTARRAYOID);
  229. FillAttr(tupleDesc, Anum_pg_proc_proargnames, TEXTARRAYOID);
  230. FillAttr(tupleDesc, Anum_pg_proc_proargdefaults, PG_NODE_TREEOID);
  231. FillAttr(tupleDesc, Anum_pg_proc_protrftypes, OIDARRAYOID);
  232. FillAttr(tupleDesc, Anum_pg_proc_prosrc, TEXTOID);
  233. FillAttr(tupleDesc, Anum_pg_proc_probin, TEXTOID);
  234. FillAttr(tupleDesc, Anum_pg_proc_prosqlbody, PG_NODE_TREEOID);
  235. FillAttr(tupleDesc, Anum_pg_proc_proconfig, TEXTARRAYOID);
  236. FillAttr(tupleDesc, Anum_pg_proc_proacl, ACLITEMARRAYOID);
  237. auto& cacheItem = Items[PROCOID] = std::make_unique<TSysCacheItem>(OidHasher1, OidEquals1, tupleDesc);
  238. auto& lookupMap = cacheItem->LookupMap;
  239. auto& byNameCacheItem = Items[PROCNAMEARGSNSP] = std::make_unique<TSysCacheItem>(ByNameProcHasher3, ByNameProcEquals3, tupleDesc, 3, ByNameProcHasher1, ByNameProcEquals1);
  240. auto& byNameLookupMap = byNameCacheItem->LookupMap;
  241. auto& byNameRangeMap1 = *byNameCacheItem->RangeMap1;
  242. const auto& oidDesc = NPg::LookupType(OIDOID);
  243. const auto& charDesc = NPg::LookupType(CHAROID);
  244. const auto& textDesc = NPg::LookupType(TEXTOID);
  245. NPg::EnumProc([&](ui32 oid, const NPg::TProcDesc& desc){
  246. auto key = THeapTupleKey(oid, 0, 0, 0);
  247. Datum values[Natts_pg_proc];
  248. bool nulls[Natts_pg_proc];
  249. Zero(values);
  250. std::fill_n(nulls, Natts_pg_proc, true);
  251. std::fill_n(nulls, Anum_pg_proc_prorettype, false); // fixed part of Form_pg_proc
  252. FillDatum(Natts_pg_proc, values, nulls, Anum_pg_proc_oid, oid);
  253. FillDatum(Natts_pg_proc, values, nulls, Anum_pg_proc_prorettype, desc.ResultType);
  254. auto name = MakeFixedString(desc.Name, NAMEDATALEN);
  255. FillDatum(Natts_pg_proc, values, nulls, Anum_pg_proc_proname, (Datum)name);
  256. FillDatum(Natts_pg_proc, values, nulls, Anum_pg_proc_pronargs, (Datum)desc.ArgTypes.size());
  257. if (!desc.VariadicType) {
  258. auto arr = buildoidvector(desc.ArgTypes.data(), (int)desc.ArgTypes.size());
  259. FillDatum(Natts_pg_proc, values, nulls, Anum_pg_proc_proargtypes, (Datum)arr);
  260. } else {
  261. std::unique_ptr<Oid[]> allOids(new Oid[1 + desc.ArgTypes.size()]);
  262. std::copy(desc.ArgTypes.begin(), desc.ArgTypes.end(), allOids.get());
  263. allOids[desc.ArgTypes.size()] = desc.VariadicArgType;
  264. auto arr = buildoidvector(allOids.get(), (int)(1 + desc.ArgTypes.size()));
  265. FillDatum(Natts_pg_proc, values, nulls, Anum_pg_proc_proargtypes, (Datum)arr);
  266. }
  267. auto variadicDelta = desc.VariadicType ? 1 : 0;
  268. const ui32 fullArgsCount = desc.ArgTypes.size() + desc.OutputArgTypes.size() + variadicDelta;
  269. if (!desc.OutputArgTypes.empty() || variadicDelta)
  270. {
  271. std::unique_ptr<Oid[]> allOids(new Oid[fullArgsCount]);
  272. std::copy(desc.ArgTypes.begin(), desc.ArgTypes.end(), allOids.get());
  273. if (variadicDelta) {
  274. allOids.get()[desc.ArgTypes.size()] = desc.VariadicArgType;
  275. }
  276. std::copy(desc.OutputArgTypes.begin(), desc.OutputArgTypes.end(), allOids.get() + desc.ArgTypes.size() + variadicDelta);
  277. auto arr = buildoidvector(allOids.get(), (int)fullArgsCount);
  278. FillDatum(Natts_pg_proc, values, nulls, Anum_pg_proc_proallargtypes, (Datum)arr);
  279. }
  280. if (!desc.OutputArgTypes.empty() || variadicDelta)
  281. {
  282. int dims[MAXDIM];
  283. int lbs[MAXDIM];
  284. dims[0] = fullArgsCount;
  285. lbs[0] = 1;
  286. std::unique_ptr<Datum[]> dvalues(new Datum[fullArgsCount]);
  287. std::unique_ptr<bool[]> dnulls(new bool[fullArgsCount]);
  288. std::fill_n(dvalues.get(), desc.ArgTypes.size(), CharGetDatum('i'));
  289. if (variadicDelta) {
  290. dvalues.get()[desc.ArgTypes.size()] = CharGetDatum('v');
  291. }
  292. std::fill_n(dvalues.get() + desc.ArgTypes.size() + variadicDelta, desc.OutputArgTypes.size(), CharGetDatum('o'));
  293. std::fill_n(dnulls.get(), fullArgsCount, false);
  294. auto arr = construct_md_array(dvalues.get(), dnulls.get(), 1, dims, lbs, CHAROID, charDesc.TypeLen, charDesc.PassByValue, charDesc.TypeAlign);
  295. FillDatum(Natts_pg_proc, values, nulls, Anum_pg_proc_proargmodes, (Datum)arr);
  296. }
  297. if (!desc.OutputArgNames.empty() || !desc.InputArgNames.empty() || !desc.VariadicArgName.empty()) {
  298. Y_ENSURE(desc.InputArgNames.size() + variadicDelta + desc.OutputArgNames.size() == fullArgsCount);
  299. int dims[MAXDIM];
  300. int lbs[MAXDIM];
  301. dims[0] = fullArgsCount;
  302. lbs[0] = 1;
  303. std::unique_ptr<Datum[]> dvalues(new Datum[fullArgsCount]);
  304. std::unique_ptr<bool[]> dnulls(new bool[fullArgsCount]);
  305. for (ui32 i = 0; i < desc.InputArgNames.size(); ++i) {
  306. dvalues[i] = PointerGetDatum(MakeVar(desc.InputArgNames[i]));
  307. }
  308. if (variadicDelta) {
  309. dvalues[desc.InputArgNames.size()] = PointerGetDatum(MakeVar(desc.VariadicArgName));
  310. }
  311. for (ui32 i = 0; i < desc.OutputArgNames.size(); ++i) {
  312. dvalues[i + desc.InputArgNames.size() + variadicDelta] = PointerGetDatum(MakeVar(desc.OutputArgNames[i]));
  313. }
  314. std::fill_n(dnulls.get(), fullArgsCount, false);
  315. auto arr = construct_md_array(dvalues.get(), dnulls.get(), 1, dims, lbs, TEXTOID, textDesc.TypeLen, textDesc.PassByValue, textDesc.TypeAlign);
  316. FillDatum(Natts_pg_proc, values, nulls, Anum_pg_proc_proargnames, (Datum)arr);
  317. for (ui32 i = 0; i < fullArgsCount; ++i) {
  318. pfree(DatumGetPointer(dvalues[i]));
  319. }
  320. }
  321. HeapTuple h = heap_form_tuple(tupleDesc, values, nulls);
  322. auto row = (Form_pg_proc)GETSTRUCT(h);
  323. Y_ENSURE(row->oid == oid);
  324. Y_ENSURE(row->prorettype == desc.ResultType);
  325. Y_ENSURE(NameStr(row->proname) == desc.Name);
  326. Y_ENSURE(row->pronargs == desc.ArgTypes.size());
  327. lookupMap.emplace(key, h);
  328. THeapTupleKey byNameLookupKey((Datum)name, (Datum)&row->proargtypes, PG_CATALOG_NAMESPACE, 0);
  329. THeapTupleKey byNameRangeKey1((Datum)name, 0, 0, 0);
  330. byNameLookupMap.emplace(byNameLookupKey, h);
  331. byNameRangeMap1[byNameRangeKey1].Items.push_back(h);
  332. });
  333. }
  334. void InitializeTypes() {
  335. TupleDesc tupleDesc = CreateTemplateTupleDesc(Natts_pg_type);
  336. FillAttr(tupleDesc, Anum_pg_type_oid, OIDOID);
  337. FillAttr(tupleDesc, Anum_pg_type_typname, NAMEOID);
  338. FillAttr(tupleDesc, Anum_pg_type_typnamespace, OIDOID);
  339. FillAttr(tupleDesc, Anum_pg_type_typowner, OIDOID);
  340. FillAttr(tupleDesc, Anum_pg_type_typlen, INT2OID);
  341. FillAttr(tupleDesc, Anum_pg_type_typbyval, BOOLOID);
  342. FillAttr(tupleDesc, Anum_pg_type_typtype, CHAROID);
  343. FillAttr(tupleDesc, Anum_pg_type_typcategory, CHAROID);
  344. FillAttr(tupleDesc, Anum_pg_type_typispreferred, BOOLOID);
  345. FillAttr(tupleDesc, Anum_pg_type_typisdefined, BOOLOID);
  346. FillAttr(tupleDesc, Anum_pg_type_typdelim, CHAROID);
  347. FillAttr(tupleDesc, Anum_pg_type_typrelid, OIDOID);
  348. FillAttr(tupleDesc, Anum_pg_type_typsubscript, REGPROCOID);
  349. FillAttr(tupleDesc, Anum_pg_type_typelem, OIDOID);
  350. FillAttr(tupleDesc, Anum_pg_type_typarray, OIDOID);
  351. FillAttr(tupleDesc, Anum_pg_type_typinput, REGPROCOID);
  352. FillAttr(tupleDesc, Anum_pg_type_typoutput, REGPROCOID);
  353. FillAttr(tupleDesc, Anum_pg_type_typreceive, REGPROCOID);
  354. FillAttr(tupleDesc, Anum_pg_type_typsend, REGPROCOID);
  355. FillAttr(tupleDesc, Anum_pg_type_typmodin, REGPROCOID);
  356. FillAttr(tupleDesc, Anum_pg_type_typmodout, REGPROCOID);
  357. FillAttr(tupleDesc, Anum_pg_type_typanalyze, REGPROCOID);
  358. FillAttr(tupleDesc, Anum_pg_type_typalign, CHAROID);
  359. FillAttr(tupleDesc, Anum_pg_type_typstorage, CHAROID);
  360. FillAttr(tupleDesc, Anum_pg_type_typnotnull, BOOLOID);
  361. FillAttr(tupleDesc, Anum_pg_type_typbasetype, OIDOID);
  362. FillAttr(tupleDesc, Anum_pg_type_typtypmod, INT4OID);
  363. FillAttr(tupleDesc, Anum_pg_type_typndims, INT4OID);
  364. FillAttr(tupleDesc, Anum_pg_type_typcollation, OIDOID);
  365. FillAttr(tupleDesc, Anum_pg_type_typdefaultbin, PG_NODE_TREEOID);
  366. FillAttr(tupleDesc, Anum_pg_type_typdefault, TEXTOID);
  367. FillAttr(tupleDesc, Anum_pg_type_typacl, ACLITEMARRAYOID);
  368. auto& cacheItem1 = Items[TYPEOID] = std::make_unique<TSysCacheItem>(OidHasher1, OidEquals1, tupleDesc);
  369. auto& lookupMap1 = cacheItem1->LookupMap;
  370. auto& cacheItem2 = Items[TYPENAMENSP] = std::make_unique<TSysCacheItem>(NsNameHasher, NsNameEquals, tupleDesc);
  371. auto& lookupMap2 = cacheItem2->LookupMap;
  372. NPg::EnumTypes([&](ui32 oid, const NPg::TTypeDesc& desc){
  373. Datum values[Natts_pg_type];
  374. bool nulls[Natts_pg_type];
  375. Zero(values);
  376. std::fill_n(nulls, Natts_pg_type, true);
  377. std::fill_n(nulls, Anum_pg_type_typcollation, false); // fixed part of Form_pg_type
  378. FillDatum(Natts_pg_type, values, nulls, Anum_pg_type_oid, oid);
  379. auto name = MakeFixedString(desc.Name, NAMEDATALEN);
  380. FillDatum(Natts_pg_type, values, nulls, Anum_pg_type_typname, (Datum)name);
  381. FillDatum(Natts_pg_type, values, nulls, Anum_pg_type_typbyval, desc.PassByValue);
  382. FillDatum(Natts_pg_type, values, nulls, Anum_pg_type_typlen, desc.TypeLen);
  383. FillDatum(Natts_pg_type, values, nulls, Anum_pg_type_typtype, (char)desc.TypType);
  384. FillDatum(Natts_pg_type, values, nulls, Anum_pg_type_typcategory, desc.Category);
  385. FillDatum(Natts_pg_type, values, nulls, Anum_pg_type_typispreferred, desc.IsPreferred);
  386. FillDatum(Natts_pg_type, values, nulls, Anum_pg_type_typisdefined, true);
  387. FillDatum(Natts_pg_type, values, nulls, Anum_pg_type_typdelim, desc.TypeDelim);
  388. FillDatum(Natts_pg_type, values, nulls, Anum_pg_type_typarray, desc.ArrayTypeId);
  389. FillDatum(Natts_pg_type, values, nulls, Anum_pg_type_typsubscript,
  390. (desc.ArrayTypeId == desc.TypeId) ? F_ARRAY_SUBSCRIPT_HANDLER : desc.TypeSubscriptFuncId);
  391. FillDatum(Natts_pg_type, values, nulls, Anum_pg_type_typelem, desc.ElementTypeId);
  392. FillDatum(Natts_pg_type, values, nulls, Anum_pg_type_typinput, desc.InFuncId);
  393. FillDatum(Natts_pg_type, values, nulls, Anum_pg_type_typoutput, desc.OutFuncId);
  394. FillDatum(Natts_pg_type, values, nulls, Anum_pg_type_typreceive, desc.ReceiveFuncId);
  395. FillDatum(Natts_pg_type, values, nulls, Anum_pg_type_typsend, desc.SendFuncId);
  396. FillDatum(Natts_pg_type, values, nulls, Anum_pg_type_typmodin, desc.TypeModInFuncId);
  397. FillDatum(Natts_pg_type, values, nulls, Anum_pg_type_typmodout, desc.TypeModOutFuncId);
  398. FillDatum(Natts_pg_type, values, nulls, Anum_pg_type_typalign, desc.TypeAlign);
  399. auto storage = desc.TypeId == desc.ArrayTypeId ? TYPSTORAGE_EXTENDED : TYPSTORAGE_PLAIN;
  400. FillDatum(Natts_pg_type, values, nulls, Anum_pg_type_typstorage, storage);
  401. HeapTuple h = heap_form_tuple(tupleDesc, values, nulls);
  402. auto row = (Form_pg_type)GETSTRUCT(h);
  403. Y_ENSURE(row->oid == oid);
  404. Y_ENSURE(NameStr(row->typname) == desc.Name);
  405. Y_ENSURE(row->typlen == desc.TypeLen);
  406. Y_ENSURE(row->typbyval == desc.PassByValue);
  407. Y_ENSURE(row->typtype == (char)desc.TypType);
  408. Y_ENSURE(row->typcategory == desc.Category);
  409. Y_ENSURE(row->typispreferred == desc.IsPreferred);
  410. Y_ENSURE(row->typisdefined == true);
  411. Y_ENSURE(row->typdelim == desc.TypeDelim);
  412. Y_ENSURE(row->typelem == desc.ElementTypeId);
  413. Y_ENSURE(row->typarray == desc.ArrayTypeId);
  414. Y_ENSURE(row->typinput == desc.InFuncId);
  415. Y_ENSURE(row->typoutput == desc.OutFuncId);
  416. Y_ENSURE(row->typreceive == desc.ReceiveFuncId);
  417. Y_ENSURE(row->typsend == desc.SendFuncId);
  418. Y_ENSURE(row->typmodin == desc.TypeModInFuncId);
  419. Y_ENSURE(row->typmodout == desc.TypeModOutFuncId);
  420. Y_ENSURE(row->typalign == desc.TypeAlign);
  421. Y_ENSURE(row->typstorage == storage);
  422. auto key1 = THeapTupleKey(oid, 0, 0, 0);
  423. lookupMap1.emplace(key1, h);
  424. auto key2 = THeapTupleKey((Datum)desc.Name.c_str(), PG_CATALOG_NAMESPACE, 0, 0);
  425. lookupMap2.emplace(key2, h);
  426. });
  427. }
  428. static HeapTuple MakePgDatabaseHeapTuple(ui32 oid, const char* name) {
  429. TupleDesc tupleDesc = CreateTemplateTupleDesc(Natts_pg_database);
  430. FillAttr(tupleDesc, Anum_pg_database_oid, OIDOID);
  431. FillAttr(tupleDesc, Anum_pg_database_datname, NAMEOID);
  432. FillAttr(tupleDesc, Anum_pg_database_datdba, OIDOID);
  433. FillAttr(tupleDesc, Anum_pg_database_encoding, INT4OID);
  434. FillAttr(tupleDesc, Anum_pg_database_datlocprovider, CHAROID);
  435. FillAttr(tupleDesc, Anum_pg_database_datistemplate, BOOLOID);
  436. FillAttr(tupleDesc, Anum_pg_database_datallowconn, BOOLOID);
  437. FillAttr(tupleDesc, Anum_pg_database_datconnlimit, INT4OID);
  438. FillAttr(tupleDesc, Anum_pg_database_datfrozenxid, XIDOID);
  439. FillAttr(tupleDesc, Anum_pg_database_datminmxid, XIDOID);
  440. FillAttr(tupleDesc, Anum_pg_database_dattablespace, OIDOID);
  441. FillAttr(tupleDesc, Anum_pg_database_datcollate, TEXTOID);
  442. FillAttr(tupleDesc, Anum_pg_database_datctype, TEXTOID);
  443. FillAttr(tupleDesc, Anum_pg_database_daticulocale, TEXTOID);
  444. FillAttr(tupleDesc, Anum_pg_database_datcollversion, TEXTOID);
  445. FillAttr(tupleDesc, Anum_pg_database_datacl, ACLITEMARRAYOID);
  446. Datum values[Natts_pg_database];
  447. bool nulls[Natts_pg_database];
  448. Zero(values);
  449. std::fill_n(nulls, Natts_pg_database, true);
  450. FillDatum(Natts_pg_database, values, nulls, Anum_pg_database_oid, (Datum)oid);
  451. FillDatum(Natts_pg_database, values, nulls, Anum_pg_database_datname, (Datum)MakeFixedString(name, NAMEDATALEN));
  452. return heap_form_tuple(tupleDesc, values, nulls);
  453. }
  454. void InitializeDatabase() {
  455. TupleDesc tupleDesc = CreateTemplateTupleDesc(Natts_pg_database);
  456. FillAttr(tupleDesc, Anum_pg_database_oid, OIDOID);
  457. FillAttr(tupleDesc, Anum_pg_database_datname, NAMEOID);
  458. FillAttr(tupleDesc, Anum_pg_database_datdba, OIDOID);
  459. FillAttr(tupleDesc, Anum_pg_database_encoding, INT4OID);
  460. FillAttr(tupleDesc, Anum_pg_database_datlocprovider, CHAROID);
  461. FillAttr(tupleDesc, Anum_pg_database_datistemplate, BOOLOID);
  462. FillAttr(tupleDesc, Anum_pg_database_datallowconn, BOOLOID);
  463. FillAttr(tupleDesc, Anum_pg_database_datconnlimit, INT4OID);
  464. FillAttr(tupleDesc, Anum_pg_database_datfrozenxid, XIDOID);
  465. FillAttr(tupleDesc, Anum_pg_database_datminmxid, XIDOID);
  466. FillAttr(tupleDesc, Anum_pg_database_dattablespace, OIDOID);
  467. FillAttr(tupleDesc, Anum_pg_database_datcollate, TEXTOID);
  468. FillAttr(tupleDesc, Anum_pg_database_datctype, TEXTOID);
  469. FillAttr(tupleDesc, Anum_pg_database_daticulocale, TEXTOID);
  470. FillAttr(tupleDesc, Anum_pg_database_datcollversion, TEXTOID);
  471. FillAttr(tupleDesc, Anum_pg_database_datacl, ACLITEMARRAYOID);
  472. auto& cacheItem = Items[DATABASEOID] = std::make_unique<TSysCacheItem>(OidHasher1, OidEquals1, tupleDesc);
  473. auto& lookupMap = cacheItem->LookupMap;
  474. for (ui32 oid = 1; oid <= 3; ++oid) {
  475. auto key = THeapTupleKey(oid, 0, 0, 0);
  476. Datum values[Natts_pg_database];
  477. bool nulls[Natts_pg_database];
  478. Zero(values);
  479. std::fill_n(nulls, Natts_pg_database, true);
  480. FillDatum(Natts_pg_database, values, nulls, Anum_pg_database_oid, (Datum)oid);
  481. const char* name = nullptr;
  482. switch (oid) {
  483. case 1: name = "template1"; break;
  484. case 2: name = "template0"; break;
  485. case PG_POSTGRES_DATABASE_ID: name = "postgres"; break;
  486. }
  487. Y_ENSURE(name);
  488. FillDatum(Natts_pg_database, values, nulls, Anum_pg_database_datname, (Datum)MakeFixedString(name, NAMEDATALEN));
  489. HeapTuple h = heap_form_tuple(tupleDesc, values, nulls);
  490. auto row = (Form_pg_database) GETSTRUCT(h);
  491. Y_ENSURE(row->oid == oid);
  492. Y_ENSURE(strcmp(NameStr(row->datname), name) == 0);
  493. lookupMap.emplace(key, h);
  494. }
  495. //add specific lookup for 4 to cacheItem. save heaptuple to MainContext_.
  496. auto threadContextLookup = [&] (const THeapTupleKey& key) -> std::optional<HeapTuple> {
  497. if (std::get<0>(key) == PG_CURRENT_DATABASE_ID && NKikimr::NMiniKQL::TlsAllocState) {
  498. auto ctx = (TMainContext*)NKikimr::NMiniKQL::TlsAllocState->MainContext;
  499. if (ctx && ctx->CurrentDatabaseName) {
  500. return ctx->CurrentDatabaseName;
  501. }
  502. }
  503. return std::nullopt;
  504. };
  505. cacheItem->PgThreadContextLookup = std::move(threadContextLookup);
  506. }
  507. static HeapTuple MakePgRolesHeapTuple(ui32 oid, const char* rolname) {
  508. TupleDesc tupleDesc = CreateTemplateTupleDesc(Natts_pg_authid);
  509. FillAttr(tupleDesc, Anum_pg_authid_oid, OIDOID);
  510. FillAttr(tupleDesc, Anum_pg_authid_rolname, NAMEOID);
  511. FillAttr(tupleDesc, Anum_pg_authid_rolsuper, BOOLOID);
  512. FillAttr(tupleDesc, Anum_pg_authid_rolinherit, BOOLOID);
  513. FillAttr(tupleDesc, Anum_pg_authid_rolcreaterole, BOOLOID);
  514. FillAttr(tupleDesc, Anum_pg_authid_rolcreatedb, BOOLOID);
  515. FillAttr(tupleDesc, Anum_pg_authid_rolcanlogin, BOOLOID);
  516. FillAttr(tupleDesc, Anum_pg_authid_rolreplication, BOOLOID);
  517. FillAttr(tupleDesc, Anum_pg_authid_rolbypassrls, BOOLOID);
  518. FillAttr(tupleDesc, Anum_pg_authid_rolconnlimit, INT4OID);
  519. FillAttr(tupleDesc, Anum_pg_authid_rolpassword, TEXTOID);
  520. FillAttr(tupleDesc, Anum_pg_authid_rolvaliduntil, TIMESTAMPTZOID);
  521. Datum values[Natts_pg_authid];
  522. bool nulls[Natts_pg_authid];
  523. Zero(values);
  524. std::fill_n(nulls, Natts_pg_authid, true);
  525. FillDatum(Natts_pg_authid, values, nulls, Anum_pg_authid_oid, (Datum)oid);
  526. FillDatum(Natts_pg_authid, values, nulls, Anum_pg_authid_rolname, (Datum)MakeFixedString(rolname, NAMEDATALEN));
  527. FillDatum(Natts_pg_authid, values, nulls, Anum_pg_authid_rolsuper, BoolGetDatum(true));
  528. FillDatum(Natts_pg_authid, values, nulls, Anum_pg_authid_rolinherit, BoolGetDatum(true));
  529. FillDatum(Natts_pg_authid, values, nulls, Anum_pg_authid_rolcreaterole, BoolGetDatum(true));
  530. FillDatum(Natts_pg_authid, values, nulls, Anum_pg_authid_rolcreatedb, BoolGetDatum(true));
  531. FillDatum(Natts_pg_authid, values, nulls, Anum_pg_authid_rolcanlogin, BoolGetDatum(true));
  532. FillDatum(Natts_pg_authid, values, nulls, Anum_pg_authid_rolreplication, BoolGetDatum(true));
  533. FillDatum(Natts_pg_authid, values, nulls, Anum_pg_authid_rolbypassrls, BoolGetDatum(true));
  534. FillDatum(Natts_pg_authid, values, nulls, Anum_pg_authid_rolconnlimit, Int32GetDatum(-1));
  535. HeapTuple h = heap_form_tuple(tupleDesc, values, nulls);
  536. auto row = (Form_pg_authid) GETSTRUCT(h);
  537. Y_ENSURE(row->oid == oid);
  538. Y_ENSURE(strcmp(NameStr(row->rolname), rolname) == 0);
  539. Y_ENSURE(row->rolsuper);
  540. Y_ENSURE(row->rolinherit);
  541. Y_ENSURE(row->rolcreaterole);
  542. Y_ENSURE(row->rolcreatedb);
  543. Y_ENSURE(row->rolcanlogin);
  544. Y_ENSURE(row->rolreplication);
  545. Y_ENSURE(row->rolbypassrls);
  546. Y_ENSURE(row->rolconnlimit == -1);
  547. return h;
  548. }
  549. void InitializeAuthId() {
  550. TupleDesc tupleDesc = CreateTemplateTupleDesc(Natts_pg_authid);
  551. FillAttr(tupleDesc, Anum_pg_authid_oid, OIDOID);
  552. FillAttr(tupleDesc, Anum_pg_authid_rolname, NAMEOID);
  553. FillAttr(tupleDesc, Anum_pg_authid_rolsuper, BOOLOID);
  554. FillAttr(tupleDesc, Anum_pg_authid_rolinherit, BOOLOID);
  555. FillAttr(tupleDesc, Anum_pg_authid_rolcreaterole, BOOLOID);
  556. FillAttr(tupleDesc, Anum_pg_authid_rolcreatedb, BOOLOID);
  557. FillAttr(tupleDesc, Anum_pg_authid_rolcanlogin, BOOLOID);
  558. FillAttr(tupleDesc, Anum_pg_authid_rolreplication, BOOLOID);
  559. FillAttr(tupleDesc, Anum_pg_authid_rolbypassrls, BOOLOID);
  560. FillAttr(tupleDesc, Anum_pg_authid_rolconnlimit, INT4OID);
  561. FillAttr(tupleDesc, Anum_pg_authid_rolpassword, TEXTOID);
  562. FillAttr(tupleDesc, Anum_pg_authid_rolvaliduntil, TIMESTAMPTZOID);
  563. auto& cacheItem = Items[AUTHOID] = std::make_unique<TSysCacheItem>(OidHasher1, OidEquals1, tupleDesc);
  564. auto& lookupMap = cacheItem->LookupMap;
  565. auto key = THeapTupleKey(1, 0, 0, 0);
  566. lookupMap.emplace(key, MakePgRolesHeapTuple(1, "postgres"));
  567. auto threadContextLookup = [&] (const THeapTupleKey& key) -> std::optional<HeapTuple> {
  568. if (std::get<0>(key) == PG_CURRENT_USER_ID && NKikimr::NMiniKQL::TlsAllocState) {
  569. auto ctx = (TMainContext*)NKikimr::NMiniKQL::TlsAllocState->MainContext;
  570. if (ctx && ctx->CurrentUserName) {
  571. return ctx->CurrentUserName;
  572. }
  573. }
  574. return std::nullopt;
  575. };
  576. cacheItem->PgThreadContextLookup = std::move(threadContextLookup);
  577. }
  578. void InitializeRelNameNamespaces() {
  579. TupleDesc tupleDesc = CreateTemplateTupleDesc(Natts_pg_class);
  580. FillAttr(tupleDesc, Anum_pg_class_oid, OIDOID);
  581. FillAttr(tupleDesc, Anum_pg_class_relname, NAMEOID);
  582. FillAttr(tupleDesc, Anum_pg_class_relnamespace, OIDOID);
  583. FillAttr(tupleDesc, Anum_pg_class_reltype, OIDOID);
  584. FillAttr(tupleDesc, Anum_pg_class_reloftype, OIDOID);
  585. FillAttr(tupleDesc, Anum_pg_class_relowner, OIDOID);
  586. FillAttr(tupleDesc, Anum_pg_class_relam, OIDOID);
  587. FillAttr(tupleDesc, Anum_pg_class_relfilenode, OIDOID);
  588. FillAttr(tupleDesc, Anum_pg_class_reltablespace, OIDOID);
  589. FillAttr(tupleDesc, Anum_pg_class_relpages, INT4OID);
  590. FillAttr(tupleDesc, Anum_pg_class_reltuples, FLOAT4OID);
  591. FillAttr(tupleDesc, Anum_pg_class_relallvisible, INT4OID);
  592. FillAttr(tupleDesc, Anum_pg_class_reltoastrelid, OIDOID);
  593. FillAttr(tupleDesc, Anum_pg_class_relhasindex, BOOLOID);
  594. FillAttr(tupleDesc, Anum_pg_class_relisshared, BOOLOID);
  595. FillAttr(tupleDesc, Anum_pg_class_relpersistence, CHAROID);
  596. FillAttr(tupleDesc, Anum_pg_class_relkind, CHAROID);
  597. FillAttr(tupleDesc, Anum_pg_class_relnatts, INT2OID);
  598. FillAttr(tupleDesc, Anum_pg_class_relchecks, INT2OID);
  599. FillAttr(tupleDesc, Anum_pg_class_relhasrules, BOOLOID);
  600. FillAttr(tupleDesc, Anum_pg_class_relhastriggers, BOOLOID);
  601. FillAttr(tupleDesc, Anum_pg_class_relhassubclass, BOOLOID);
  602. FillAttr(tupleDesc, Anum_pg_class_relrowsecurity, BOOLOID);
  603. FillAttr(tupleDesc, Anum_pg_class_relforcerowsecurity, BOOLOID);
  604. FillAttr(tupleDesc, Anum_pg_class_relispopulated, BOOLOID);
  605. FillAttr(tupleDesc, Anum_pg_class_relreplident, CHAROID);
  606. FillAttr(tupleDesc, Anum_pg_class_relispartition, BOOLOID);
  607. FillAttr(tupleDesc, Anum_pg_class_relrewrite, OIDOID);
  608. FillAttr(tupleDesc, Anum_pg_class_relfrozenxid, XIDOID);
  609. FillAttr(tupleDesc, Anum_pg_class_relminmxid, XIDOID);
  610. FillAttr(tupleDesc, Anum_pg_class_relacl, ACLITEMARRAYOID);
  611. FillAttr(tupleDesc, Anum_pg_class_reloptions, TEXTARRAYOID);
  612. FillAttr(tupleDesc, Anum_pg_class_relpartbound, PG_NODE_TREEOID);
  613. auto& cacheItem = Items[RELNAMENSP] = std::make_unique<TSysCacheItem>(NsNameHasher, NsNameEquals, tupleDesc);
  614. auto& lookupMap = cacheItem->LookupMap;
  615. Datum values[Natts_pg_class];
  616. bool nulls[Natts_pg_class];
  617. Zero(values);
  618. std::fill_n(nulls, Natts_pg_class, true);
  619. std::fill_n(nulls, Anum_pg_class_relminmxid, false); // fixed part of Form_pg_class
  620. for (const auto& t : NPg::GetStaticTables()) {
  621. auto name = (Datum)MakeFixedString(t.Name, NAMEDATALEN);
  622. auto ns = (Datum)(t.Schema == "pg_catalog" ? PG_CATALOG_NAMESPACE : 1);
  623. FillDatum(Natts_pg_class, values, nulls, Anum_pg_class_oid, (Datum)t.Oid);
  624. FillDatum(Natts_pg_class, values, nulls, Anum_pg_class_relname, name);
  625. FillDatum(Natts_pg_class, values, nulls, Anum_pg_class_relnamespace, ns);
  626. FillDatum(Natts_pg_class, values, nulls, Anum_pg_class_relowner, (Datum)1);
  627. HeapTuple h = heap_form_tuple(tupleDesc, values, nulls);
  628. auto row = (Form_pg_class) GETSTRUCT(h);
  629. Y_ENSURE(row->oid == t.Oid);
  630. Y_ENSURE(strcmp(NameStr(row->relname), t.Name.c_str()) == 0);
  631. Y_ENSURE(row->relowner == 1);
  632. Y_ENSURE(row->relnamespace == ns);
  633. auto key = THeapTupleKey(name, ns, 0, 0);
  634. lookupMap.emplace(key, h);
  635. }
  636. }
  637. void InitializeNameAndOidNamespaces() {
  638. TupleDesc tupleDesc = CreateTemplateTupleDesc(Natts_pg_namespace);
  639. FillAttr(tupleDesc, Anum_pg_namespace_oid, OIDOID);
  640. FillAttr(tupleDesc, Anum_pg_namespace_nspname, NAMEOID);
  641. FillAttr(tupleDesc, Anum_pg_namespace_nspowner, OIDOID);
  642. FillAttr(tupleDesc, Anum_pg_namespace_nspacl, ACLITEMARRAYOID);
  643. auto& cacheItem1 = Items[NAMESPACENAME] = std::make_unique<TSysCacheItem>(NsNameHasher, NsNameEquals, tupleDesc);
  644. auto& lookupMap1 = cacheItem1->LookupMap;
  645. auto& cacheItem2 = Items[NAMESPACEOID] = std::make_unique<TSysCacheItem>(OidHasher1, OidEquals1, tupleDesc);
  646. auto& lookupMap2 = cacheItem2->LookupMap;
  647. NPg::EnumNamespace([&](ui32 oid, const NPg::TNamespaceDesc& desc) {
  648. Datum values[Natts_pg_namespace];
  649. bool nulls[Natts_pg_namespace];
  650. Zero(values);
  651. std::fill_n(nulls, Natts_pg_namespace, true);
  652. FillDatum(Natts_pg_namespace, values, nulls, Anum_pg_namespace_oid, oid);
  653. auto name = MakeFixedString(desc.Name, NAMEDATALEN);
  654. FillDatum(Natts_pg_namespace, values, nulls, Anum_pg_namespace_nspname, (Datum)name);
  655. FillDatum(Natts_pg_namespace, values, nulls, Anum_pg_namespace_nspowner, (Datum)1);
  656. HeapTuple h = heap_form_tuple(tupleDesc, values, nulls);
  657. auto row = (Form_pg_namespace)GETSTRUCT(h);
  658. Y_ENSURE(row->oid == oid);
  659. Y_ENSURE(NameStr(row->nspname) == desc.Name);
  660. Y_ENSURE(row->nspowner == 1);
  661. auto key1 = THeapTupleKey((Datum)name, 0, 0, 0);
  662. lookupMap1.emplace(key1, h);
  663. auto key2 = THeapTupleKey((Datum)oid, 0, 0, 0);
  664. lookupMap2.emplace(key2, h);
  665. });
  666. }
  667. };
  668. }
  669. void RebuildSysCache() {
  670. TSysCache::MutableInstance().Rebuild();
  671. }
  672. }
  673. namespace NKikimr {
  674. namespace NMiniKQL {
  675. void PgCreateSysCacheEntries(void* ctx) {
  676. auto main = (TMainContext*)ctx;
  677. if (main->GUCSettings) {
  678. if (main->GUCSettings->Get("ydb_database") && main->GUCSettings->Get("ydb_database")->size() < NAMEDATALEN) {
  679. main->CurrentDatabaseName = NYql::TSysCache::MakePgDatabaseHeapTuple(NYql::PG_CURRENT_DATABASE_ID, main->GUCSettings->Get("ydb_database")->c_str());
  680. }
  681. if (main->GUCSettings->Get("ydb_user") && main->GUCSettings->Get("ydb_user")->size() < NAMEDATALEN) {
  682. main->CurrentUserName = NYql::TSysCache::MakePgRolesHeapTuple(NYql::PG_CURRENT_USER_ID, main->GUCSettings->Get("ydb_user")->c_str());
  683. }
  684. }
  685. }
  686. } //namespace NKikimr
  687. } //namespace NMiniKQL
  688. HeapTuple SearchSysCache(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4) {
  689. Y_ENSURE(cacheId >= 0 && cacheId < SysCacheSize);
  690. const auto& cacheItem = NYql::TSysCache::Instance().Items[cacheId];
  691. if (!cacheItem) {
  692. return nullptr;
  693. }
  694. const auto& lookupMap = cacheItem->LookupMap;
  695. auto it = lookupMap.find(std::make_tuple(key1, key2, key3, key4));
  696. if (it == lookupMap.end()) {
  697. if (cacheItem->PgThreadContextLookup) {
  698. if (auto value = cacheItem->PgThreadContextLookup(std::make_tuple(key1, key2, key3, key4))) {
  699. return *value;
  700. }
  701. }
  702. return nullptr;
  703. }
  704. return it->second;
  705. }
  706. HeapTuple SearchSysCache1(int cacheId, Datum key1) {
  707. return SearchSysCache(cacheId, key1, 0, 0, 0);
  708. }
  709. HeapTuple SearchSysCache2(int cacheId, Datum key1, Datum key2) {
  710. return SearchSysCache(cacheId, key1, key2, 0, 0);
  711. }
  712. HeapTuple SearchSysCache3(int cacheId, Datum key1, Datum key2, Datum key3) {
  713. return SearchSysCache(cacheId, key1, key2, key3, 0);
  714. }
  715. HeapTuple SearchSysCache4(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4) {
  716. return SearchSysCache(cacheId, key1, key2, key3, key4);
  717. }
  718. void ReleaseSysCache(HeapTuple tuple) {
  719. Y_UNUSED(tuple);
  720. }
  721. Oid GetSysCacheOid(int cacheId, AttrNumber oidcol, Datum key1, Datum key2, Datum key3, Datum key4) {
  722. Y_ENSURE(cacheId >= 0 && cacheId < SysCacheSize);
  723. const auto& cacheItem = NYql::TSysCache::Instance().Items[cacheId];
  724. HeapTuple tuple;
  725. bool isNull;
  726. Oid result;
  727. tuple = SearchSysCache(cacheId, key1, key2, key3, key4);
  728. if (!HeapTupleIsValid(tuple)) {
  729. return InvalidOid;
  730. }
  731. result = heap_getattr(tuple, oidcol, cacheItem->Desc, &isNull);
  732. Y_ENSURE(!isNull); /* columns used as oids should never be NULL */
  733. ReleaseSysCache(tuple);
  734. return result;
  735. }
  736. Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull) {
  737. Y_ENSURE(cacheId >= 0 && cacheId < SysCacheSize);
  738. const auto& cacheItem = NYql::TSysCache::Instance().Items[cacheId];
  739. Y_ENSURE(cacheItem);
  740. return heap_getattr(tup, attributeNumber, cacheItem->Desc, isNull);
  741. }
  742. struct catclist* SearchSysCacheList(int cacheId, int nkeys, Datum key1, Datum key2, Datum key3) {
  743. Y_ENSURE(cacheId >= 0 && cacheId < SysCacheSize);
  744. const auto& cacheItem = NYql::TSysCache::Instance().Items[cacheId];
  745. Y_ENSURE(cacheItem);
  746. if (nkeys == 1 && cacheItem->NumKeys > 1) {
  747. const auto& rangeMap1 = *cacheItem->RangeMap1;
  748. auto it = rangeMap1.find(std::make_tuple(key1, 0, 0, 0));
  749. if (it == rangeMap1.end()) {
  750. return cacheItem->EmptyCList;
  751. }
  752. return it->second.CList;
  753. }
  754. return cacheItem->EmptyCList;
  755. }