catalog.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  1. #pragma once
  2. #include <yql/essentials/public/issue/yql_issue.h>
  3. #include <util/generic/maybe.h>
  4. #include <util/generic/string.h>
  5. #include <util/generic/vector.h>
  6. #include <util/generic/set.h>
  7. #include <util/stream/output.h>
  8. #include <variant>
  9. #include <functional>
  10. struct Node;
  11. namespace NYql {
  12. class TExprNode;
  13. struct TExprContext;
  14. }
  15. namespace NYql::NPg {
  16. constexpr ui32 UnknownOid = 705;
  17. constexpr ui32 AnyOid = 2276;
  18. constexpr ui32 AnyArrayOid = 2277;
  19. constexpr ui32 AnyNonArrayOid = 2776;
  20. constexpr ui32 AnyElementOid = 2283;
  21. constexpr ui32 RecordOid = 2249;
  22. constexpr ui32 VarcharOid = 1043;
  23. constexpr ui32 TextOid = 25;
  24. // copied from pg_class.h
  25. enum class ERelPersistence : char
  26. {
  27. Permanent = 'p',
  28. Unlogged = 'u',
  29. Temp = 't',
  30. };
  31. enum class EOperKind {
  32. Binary,
  33. LeftUnary,
  34. RightUnary
  35. };
  36. struct TOperDesc {
  37. ui32 OperId = 0;
  38. TString Name;
  39. TString Descr;
  40. EOperKind Kind = EOperKind::Binary;
  41. ui32 LeftType = 0;
  42. ui32 RightType = 0;
  43. ui32 ResultType = 0;
  44. ui32 ProcId = 0;
  45. ui32 ComId = 0;
  46. ui32 NegateId = 0;
  47. ui32 ExtensionIndex = 0;
  48. };
  49. enum class EProcKind : char {
  50. Function = 'f',
  51. Aggregate = 'a',
  52. Window = 'w'
  53. };
  54. constexpr ui32 LangInternal = 12;
  55. constexpr ui32 LangC = 13;
  56. constexpr ui32 LangSQL = 14;
  57. struct TProcDesc {
  58. ui32 ProcId = 0;
  59. TString Name;
  60. TString Src;
  61. TString Descr;
  62. TVector<ui32> ArgTypes;
  63. TVector<TString> InputArgNames;
  64. ui32 ResultType = 0;
  65. bool IsStrict = true;
  66. EProcKind Kind = EProcKind::Function;
  67. bool ReturnSet = false;
  68. TVector<TString> OutputArgNames;
  69. TVector<ui32> OutputArgTypes;
  70. ui32 Lang = LangInternal;
  71. ui32 VariadicType = 0;
  72. ui32 VariadicArgType = 0;
  73. TString VariadicArgName;
  74. TVector<TMaybe<TString>> DefaultArgs;
  75. TExprNode* ExprNode = nullptr;
  76. ui32 ExtensionIndex = 0;
  77. };
  78. // Copied from pg_collation_d.h
  79. constexpr ui32 InvalidCollationOid = 0;
  80. constexpr ui32 DefaultCollationOid = 100;
  81. constexpr ui32 C_CollationOid = 950;
  82. constexpr ui32 PosixCollationOid = 951;
  83. // Copied from pg_type_d.h, TYPTYPE_* constants
  84. enum class ETypType : char {
  85. Base = 'b',
  86. Composite = 'c',
  87. Domain = 'd',
  88. Enum = 'e',
  89. Multirange = 'm',
  90. Pseudo = 'p',
  91. Range = 'r',
  92. };
  93. constexpr char InvalidCategory = '\0';
  94. struct TTypeDesc {
  95. ui32 TypeId = 0;
  96. ui32 ArrayTypeId = 0;
  97. TString Descr;
  98. TString Name;
  99. ui32 ElementTypeId = 0;
  100. bool PassByValue = false;
  101. char Category = InvalidCategory;
  102. bool IsPreferred = false;
  103. char TypeAlign = '\0';
  104. char TypeDelim = ',';
  105. /*
  106. * Collation: InvalidCollationOid if type cannot use collations, nonzero (typically
  107. * DefaultCollationOid) for collatable base types, possibly some other
  108. * OID for domains over collatable types
  109. */
  110. ui32 TypeCollation = InvalidCollationOid;
  111. ui32 InFuncId = 0;
  112. ui32 OutFuncId = 0;
  113. ui32 SendFuncId = 0;
  114. ui32 ReceiveFuncId = 0;
  115. ui32 TypeModInFuncId = 0;
  116. ui32 TypeModOutFuncId = 0;
  117. ui32 TypeSubscriptFuncId = 0;
  118. i32 TypeLen = 0;
  119. // from opclass
  120. ui32 LessProcId = 0;
  121. ui32 EqualProcId = 0;
  122. ui32 CompareProcId = 0;
  123. ui32 HashProcId = 0;
  124. // If TypType is 'c', typrelid is the OID of the class' entry in pg_class.
  125. ETypType TypType = ETypType::Base;
  126. ui32 ExtensionIndex = 0;
  127. };
  128. enum class ECastMethod {
  129. Function,
  130. InOut,
  131. Binary
  132. };
  133. enum class ECoercionCode : char {
  134. Unknown = '?', // not specified
  135. Implicit = 'i', // coercion in context of expression
  136. Assignment = 'a', // coercion in context of assignment
  137. Explicit = 'e', // explicit cast operation
  138. };
  139. struct TCastDesc {
  140. ui32 SourceId = 0;
  141. ui32 TargetId = 0;
  142. ECastMethod Method = ECastMethod::Function;
  143. ui32 FunctionId = 0;
  144. ECoercionCode CoercionCode = ECoercionCode::Unknown;
  145. ui32 ExtensionIndex = 0;
  146. };
  147. enum class EAggKind : char {
  148. Normal = 'n',
  149. OrderedSet = 'o',
  150. Hypothetical = 'h'
  151. };
  152. struct TAggregateDesc {
  153. ui32 AggId = 0;
  154. TString Name;
  155. TVector<ui32> ArgTypes;
  156. EAggKind Kind = EAggKind::Normal;
  157. ui32 TransTypeId = 0;
  158. ui32 TransFuncId = 0;
  159. ui32 FinalFuncId = 0;
  160. ui32 CombineFuncId = 0;
  161. ui32 SerializeFuncId = 0;
  162. ui32 DeserializeFuncId = 0;
  163. TString InitValue;
  164. bool FinalExtra = false;
  165. ui32 NumDirectArgs = 0;
  166. ui32 ExtensionIndex = 0;
  167. };
  168. enum class EAmType {
  169. Table = 't',
  170. Index = 'i'
  171. };
  172. struct TAmDesc {
  173. ui32 Oid = 0;
  174. TString Descr;
  175. TString AmName;
  176. EAmType AmType = EAmType::Index;
  177. };
  178. struct TNamespaceDesc {
  179. ui32 Oid = 0;
  180. TString Name;
  181. TString Descr;
  182. };
  183. enum class EOpClassMethod {
  184. Btree,
  185. Hash
  186. };
  187. struct TOpFamilyDesc {
  188. TString Name;
  189. ui32 FamilyId = 0;
  190. ui32 ExtensionIndex = 0;
  191. };
  192. struct TOpClassDesc {
  193. EOpClassMethod Method = EOpClassMethod::Btree;
  194. ui32 TypeId = 0;
  195. TString Name;
  196. TString Family;
  197. ui32 FamilyId = 0;
  198. ui32 ExtensionIndex = 0;
  199. };
  200. struct TAmOpDesc {
  201. TString Family;
  202. ui32 FamilyId = 0;
  203. ui32 Strategy = 0;
  204. ui32 LeftType = 0;
  205. ui32 RightType = 0;
  206. ui32 OperId = 0;
  207. ui32 ExtensionIndex = 0;
  208. };
  209. enum class EBtreeAmStrategy {
  210. Less = 1,
  211. LessOrEqual = 2,
  212. Equal = 3,
  213. GreaterOrEqual = 4,
  214. Greater = 5
  215. };
  216. struct TAmProcDesc {
  217. TString Family;
  218. ui32 FamilyId = 0;
  219. ui32 ProcNum = 0;
  220. ui32 LeftType = 0;
  221. ui32 RightType = 0;
  222. ui32 ProcId = 0;
  223. ui32 ExtensionIndex = 0;
  224. };
  225. enum class EBtreeAmProcNum {
  226. Compare = 1
  227. };
  228. enum class EHashAmProcNum {
  229. Hash = 1
  230. };
  231. struct TConversionDesc {
  232. ui32 ConversionId = 0;
  233. TString From;
  234. TString To;
  235. TString Descr;
  236. ui32 ProcId = 0;
  237. };
  238. struct TLanguageDesc {
  239. ui32 LangId = 0;
  240. TString Name;
  241. TString Descr;
  242. };
  243. const TProcDesc& LookupProc(const TString& name, const TVector<ui32>& argTypeIds);
  244. const TProcDesc& LookupProc(ui32 procId, const TVector<ui32>& argTypeIds);
  245. const TProcDesc& LookupProc(ui32 procId);
  246. std::variant<const TProcDesc*, const TTypeDesc*> LookupProcWithCasts(const TString& name, const TVector<ui32>& argTypeIds);
  247. bool HasReturnSetProc(const TString& name);
  248. void EnumProc(std::function<void(ui32, const TProcDesc&)> f);
  249. bool HasProc(const TString& name, EProcKind kind);
  250. bool HasType(const TString& name);
  251. bool HasType(ui32 typeId);
  252. const TTypeDesc& LookupType(const TString& name);
  253. const TTypeDesc& LookupType(ui32 typeId);
  254. TMaybe<TIssue> LookupCommonType(const TVector<ui32>& typeIds, const std::function<TPosition(size_t i)>& GetPosition, const TTypeDesc*& typeDesc);
  255. TMaybe<TIssue> LookupCommonType(const TVector<ui32>& typeIds, const std::function<TPosition(size_t i)>& GetPosition, const TTypeDesc*& typeDesc, bool& castsNeeded);
  256. void EnumTypes(std::function<void(ui32, const TTypeDesc&)> f);
  257. const TAmDesc& LookupAm(ui32 oid);
  258. void EnumAm(std::function<void(ui32, const TAmDesc&)> f);
  259. void EnumConversions(std::function<void(const TConversionDesc&)> f);
  260. const TNamespaceDesc& LookupNamespace(ui32 oid);
  261. void EnumNamespace(std::function<void(ui32, const TNamespaceDesc&)> f);
  262. void EnumOperators(std::function<void(const TOperDesc&)> f);
  263. bool HasCast(ui32 sourceId, ui32 targetId);
  264. const TCastDesc& LookupCast(ui32 sourceId, ui32 targetId);
  265. const TOperDesc& LookupOper(const TString& name, const TVector<ui32>& argTypeIds);
  266. const TOperDesc& LookupOper(ui32 operId, const TVector<ui32>& argTypeIds);
  267. const TOperDesc& LookupOper(ui32 operId);
  268. bool HasAggregation(const TString& name, EAggKind kind);
  269. const TAggregateDesc& LookupAggregation(const TString& name, const TVector<ui32>& argTypeIds);
  270. const TAggregateDesc& LookupAggregation(const TString& name, ui32 stateType, ui32 resultType);
  271. void EnumAggregation(std::function<void(ui32, const TAggregateDesc&)> f);
  272. bool HasOpClass(EOpClassMethod method, ui32 typeId);
  273. const TOpClassDesc* LookupDefaultOpClass(EOpClassMethod method, ui32 typeId);
  274. bool HasAmOp(ui32 familyId, ui32 strategy, ui32 leftType, ui32 rightType);
  275. const TAmOpDesc& LookupAmOp(ui32 familyId, ui32 strategy, ui32 leftType, ui32 rightType);
  276. bool HasAmProc(ui32 familyId, ui32 num, ui32 leftType, ui32 rightType);
  277. const TAmProcDesc& LookupAmProc(ui32 familyId, ui32 num, ui32 leftType, ui32 rightType);
  278. bool HasConversion(const TString& from, const TString& to);
  279. const TConversionDesc& LookupConversion(const TString& from, const TString& to);
  280. const TLanguageDesc& LookupLanguage(ui32 langId);
  281. void EnumLanguages(std::function<void(ui32, const TLanguageDesc&)> f);
  282. bool IsCompatibleTo(ui32 actualType, ui32 expectedType);
  283. bool IsCoercible(ui32 fromTypeId, ui32 toTypeId, ECoercionCode coercionType);
  284. inline bool IsArrayType(const TTypeDesc& typeDesc) noexcept {
  285. return typeDesc.ArrayTypeId == typeDesc.TypeId;
  286. }
  287. enum class ERelKind : char {
  288. Relation = 'r',
  289. View = 'v'
  290. };
  291. struct TTableInfoKey {
  292. TString Schema;
  293. TString Name;
  294. bool operator==(const TTableInfoKey& other) const {
  295. return Schema == other.Schema && Name == other.Name;
  296. }
  297. bool operator<(const TTableInfoKey& other) const {
  298. return std::tie(Schema, Name) < std::tie(other.Schema, other.Name);
  299. }
  300. size_t Hash() const {
  301. auto stringHasher = THash<TString>();
  302. return CombineHashes(stringHasher(Schema), stringHasher(Name));
  303. }
  304. };
  305. constexpr ui32 TypeRelationOid = 1247;
  306. constexpr ui32 DatabaseRelationOid = 1262;
  307. constexpr ui32 TableSpaceRelationOid = 1213;
  308. constexpr ui32 SharedDescriptionRelationOid = 2396;
  309. constexpr ui32 TriggerRelationOid = 2620;
  310. constexpr ui32 InheritsRelationOid = 2611;
  311. constexpr ui32 DescriptionRelationOid = 2609;
  312. constexpr ui32 AccessMethodRelationOid = 2601;
  313. constexpr ui32 NamespaceRelationOid = 2615;
  314. constexpr ui32 AuthMemRelationOid = 1261;
  315. constexpr ui32 RelationRelationOid = 1259;
  316. struct TTableInfo : public TTableInfoKey {
  317. ERelKind Kind;
  318. ui32 Oid;
  319. ui32 ExtensionIndex = 0;
  320. };
  321. struct TColumnInfo {
  322. TString Schema;
  323. TString TableName;
  324. TString Name;
  325. TString UdtType;
  326. ui32 ExtensionIndex = 0;
  327. };
  328. const TVector<TTableInfo>& GetStaticTables();
  329. const TTableInfo& LookupStaticTable(const TTableInfoKey& tableKey);
  330. const THashMap<TTableInfoKey, TVector<TColumnInfo>>& GetStaticColumns();
  331. const TVector<TMaybe<TString>>* ReadTable(
  332. const TTableInfoKey& tableKey,
  333. const TVector<TString>& columnNames,
  334. size_t* columnsRemap, // should have the same length as columnNames
  335. size_t& rowStep);
  336. bool AreAllFunctionsAllowed();
  337. void AllowFunction(const TString& name);
  338. struct TExtensionDesc {
  339. TString Name; // postgis
  340. TString InstallName; // $libdir/postgis-3
  341. TVector<TString> SqlPaths; // paths to SQL files with DDL (CREATE TYPE/CREATE FUNCTION/etc), DML (INSERT/VALUES)
  342. TString LibraryPath; // file path
  343. bool TypesOnly = false; // Can't be loaded if true
  344. TString LibraryMD5; // optional
  345. TString Version; // version of extension
  346. };
  347. class IExtensionSqlBuilder {
  348. public:
  349. virtual ~IExtensionSqlBuilder() = default;
  350. virtual void CreateProc(const TProcDesc& desc) = 0;
  351. virtual void PrepareType(ui32 extensionIndex,const TString& name) = 0;
  352. virtual void UpdateType(const TTypeDesc& desc) = 0;
  353. virtual void CreateTable(const TTableInfo& table, const TVector<TColumnInfo>& columns) = 0;
  354. virtual void InsertValues(const TTableInfoKey& table, const TVector<TString>& columns,
  355. const TVector<TMaybe<TString>>& data) = 0; // row based layout
  356. virtual void CreateCast(const TCastDesc& desc) = 0;
  357. virtual void PrepareOper(ui32 extensionIndex, const TString& name, const TVector<ui32>& args) = 0;
  358. virtual void UpdateOper(const TOperDesc& desc) = 0;
  359. virtual void CreateAggregate(const TAggregateDesc& desc) = 0;
  360. virtual void CreateOpClass(const TOpClassDesc& opclass, const TVector<TAmOpDesc>& ops, const TVector<TAmProcDesc>& procs) = 0;
  361. };
  362. class IExtensionSqlParser {
  363. public:
  364. virtual ~IExtensionSqlParser() = default;
  365. virtual void Parse(ui32 extensionIndex, const TVector<TString>& sqls, IExtensionSqlBuilder& builder) = 0;
  366. };
  367. class IExtensionLoader {
  368. public:
  369. virtual ~IExtensionLoader() = default;
  370. virtual void Load(ui32 extensionIndex, const TString& name, const TString& path) = 0;
  371. };
  372. class ISystemFunctionsParser {
  373. public:
  374. virtual ~ISystemFunctionsParser() = default;
  375. virtual void Parse(const TString& sql, TVector<TProcDesc>& procs) const = 0;
  376. };
  377. class ISqlLanguageParser {
  378. public:
  379. virtual ~ISqlLanguageParser() = default;
  380. virtual void Parse(const TString& sql, TProcDesc& proc) = 0;
  381. virtual void ParseNode(const Node* stmt, TProcDesc& proc) = 0;
  382. virtual void Freeze() = 0;
  383. virtual TExprContext& GetContext() = 0;
  384. };
  385. void SetSqlLanguageParser(std::unique_ptr<ISqlLanguageParser> parser);
  386. ISqlLanguageParser* GetSqlLanguageParser();
  387. void LoadSystemFunctions(ISystemFunctionsParser& parser);
  388. // either RegisterExtensions or ImportExtensions should be called at most once, see ClearExtensions as well
  389. void RegisterExtensions(const TVector<TExtensionDesc>& extensions, bool typesOnly,
  390. IExtensionSqlParser& parser, IExtensionLoader* loader);
  391. // converts all library paths to basenames
  392. TString ExportExtensions(const TMaybe<TSet<ui32>>& filter = Nothing());
  393. void ImportExtensions(const TString& exported, bool typesOnly, IExtensionLoader* loader);
  394. void ClearExtensions();
  395. void EnumExtensions(std::function<void(ui32 extensionIndex, const TExtensionDesc&)> f);
  396. const TExtensionDesc& LookupExtension(ui32 extensionIndex);
  397. ui32 LookupExtensionByName(const TString& name);
  398. ui32 LookupExtensionByInstallName(const TString& installName);
  399. }
  400. template <>
  401. inline void Out<NYql::NPg::ETypType>(IOutputStream& o, NYql::NPg::ETypType typType) {
  402. o.Write(static_cast<std::underlying_type<NYql::NPg::ETypType>::type>(typType));
  403. }
  404. template <>
  405. inline void Out<NYql::NPg::ECoercionCode>(IOutputStream& o, NYql::NPg::ECoercionCode coercionCode) {
  406. o.Write(static_cast<std::underlying_type<NYql::NPg::ECoercionCode>::type>(coercionCode));
  407. }
  408. template <>
  409. struct THash<NYql::NPg::TTableInfoKey> {
  410. size_t operator ()(const NYql::NPg::TTableInfoKey& val) const {
  411. return val.Hash();
  412. }
  413. };