aboutsummaryrefslogtreecommitdiffstats
path: root/yql/essentials/parser/pg_catalog/catalog.h
blob: e753f2ebc822ce005c361a1e8180bf621f89a4e8 (plain) (blame)
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
#pragma once
#include <yql/essentials/public/issue/yql_issue.h>
#include <util/generic/maybe.h>
#include <util/generic/string.h>
#include <util/generic/vector.h>
#include <util/generic/set.h>
#include <util/stream/output.h>
#include <variant>
#include <functional>

struct Node;

namespace NYql {
class TExprNode;
struct TExprContext;
}

namespace NYql::NPg {

constexpr ui32 UnknownOid = 705;
constexpr ui32 AnyOid = 2276;
constexpr ui32 AnyArrayOid = 2277;
constexpr ui32 AnyNonArrayOid = 2776;
constexpr ui32 AnyElementOid = 2283;
constexpr ui32 RecordOid = 2249;
constexpr ui32 VarcharOid = 1043;
constexpr ui32 TextOid = 25;

// copied from pg_class.h
enum class ERelPersistence : char
{
    Permanent = 'p',
    Unlogged = 'u',
    Temp = 't',
};

enum class EOperKind {
    Binary,
    LeftUnary,
    RightUnary
};

struct TOperDesc {
    ui32 OperId = 0;
    TString Name;
    TString Descr;
    EOperKind Kind = EOperKind::Binary;
    ui32 LeftType = 0;
    ui32 RightType = 0;
    ui32 ResultType = 0;
    ui32 ProcId = 0;
    ui32 ComId = 0;
    ui32 NegateId = 0;
    ui32 ExtensionIndex = 0;
};

enum class EProcKind : char {
    Function = 'f',
    Aggregate = 'a',
    Window = 'w'
};

constexpr ui32 LangInternal = 12;
constexpr ui32 LangC = 13;
constexpr ui32 LangSQL = 14;

struct TProcDesc {
    ui32 ProcId = 0;
    TString Name;
    TString Src;
    TString Descr;
    TVector<ui32> ArgTypes;
    TVector<TString> InputArgNames;
    ui32 ResultType = 0;
    bool IsStrict = true;
    EProcKind Kind = EProcKind::Function;
    bool ReturnSet = false;
    TVector<TString> OutputArgNames;
    TVector<ui32> OutputArgTypes;
    ui32 Lang = LangInternal;
    ui32 VariadicType = 0;
    ui32 VariadicArgType = 0;
    TString VariadicArgName;
    TVector<TMaybe<TString>> DefaultArgs;
    TExprNode* ExprNode = nullptr;
    ui32 ExtensionIndex = 0;
};

// Copied from pg_collation_d.h
constexpr ui32 InvalidCollationOid = 0;
constexpr ui32 DefaultCollationOid = 100;
constexpr ui32 C_CollationOid = 950;
constexpr ui32 PosixCollationOid = 951;

// Copied from pg_type_d.h, TYPTYPE_* constants
enum class ETypType : char {
    Base = 'b',
    Composite = 'c',
    Domain = 'd',
    Enum = 'e',
    Multirange = 'm',
    Pseudo = 'p',
    Range = 'r',
};

constexpr char InvalidCategory = '\0';

struct TTypeDesc {
    ui32 TypeId = 0;
    ui32 ArrayTypeId = 0;
    TString Descr;
    TString Name;
    ui32 ElementTypeId = 0;
    bool PassByValue = false;
    char Category = InvalidCategory;
    bool IsPreferred = false;
    char TypeAlign = '\0';
    char TypeDelim = ',';

    /*
     * Collation: InvalidCollationOid if type cannot use collations, nonzero (typically
     * DefaultCollationOid) for collatable base types, possibly some other
     * OID for domains over collatable types
     */
    ui32 TypeCollation = InvalidCollationOid;

    ui32 InFuncId = 0;
    ui32 OutFuncId = 0;
    ui32 SendFuncId = 0;
    ui32 ReceiveFuncId = 0;
    ui32 TypeModInFuncId = 0;
    ui32 TypeModOutFuncId = 0;
    ui32 TypeSubscriptFuncId = 0;
    i32 TypeLen = 0;
    // from opclass
    ui32 LessProcId = 0;
    ui32 EqualProcId = 0;
    ui32 CompareProcId = 0;
    ui32 HashProcId = 0;

    // If TypType is 'c', typrelid is the OID of the class' entry in pg_class.
    ETypType TypType = ETypType::Base;

    ui32 ExtensionIndex = 0;
};

enum class ECastMethod {
    Function,
    InOut,
    Binary
};

enum class ECoercionCode : char {
    Unknown = '?',      // not specified
    Implicit = 'i',     // coercion in context of expression
    Assignment = 'a',   // coercion in context of assignment
    Explicit = 'e',     // explicit cast operation
};

struct TCastDesc {
    ui32 SourceId = 0;
    ui32 TargetId = 0;
    ECastMethod Method = ECastMethod::Function;
    ui32 FunctionId = 0;
    ECoercionCode CoercionCode = ECoercionCode::Unknown;
    ui32 ExtensionIndex = 0;
};

enum class EAggKind : char {
    Normal = 'n',
    OrderedSet = 'o',
    Hypothetical = 'h'
};

struct TAggregateDesc {
    ui32 AggId = 0;
    TString Name;
    TVector<ui32> ArgTypes;
    EAggKind Kind = EAggKind::Normal;
    ui32 TransTypeId = 0;
    ui32 TransFuncId = 0;
    ui32 FinalFuncId = 0;
    ui32 CombineFuncId = 0;
    ui32 SerializeFuncId = 0;
    ui32 DeserializeFuncId = 0;
    TString InitValue;
    bool FinalExtra = false;
    ui32 NumDirectArgs = 0;
    ui32 ExtensionIndex = 0;
};

enum class EAmType {
    Table = 't',
    Index = 'i'
};

struct TAmDesc {
    ui32 Oid = 0;
    TString Descr;
    TString AmName;
    EAmType AmType = EAmType::Index;
};

struct TNamespaceDesc {
    ui32 Oid = 0;
    TString Name;
    TString Descr;
};

enum class EOpClassMethod {
    Btree,
    Hash
};

struct TOpFamilyDesc {
    TString Name;
    ui32 FamilyId = 0;
    ui32 ExtensionIndex = 0;
};

struct TOpClassDesc {
    EOpClassMethod Method = EOpClassMethod::Btree;
    ui32 TypeId = 0;
    TString Name;
    TString Family;
    ui32 FamilyId = 0;
    ui32 ExtensionIndex = 0;
};

struct TAmOpDesc {
    TString Family;
    ui32 FamilyId = 0;
    ui32 Strategy = 0;
    ui32 LeftType = 0;
    ui32 RightType = 0;
    ui32 OperId = 0;
    ui32 ExtensionIndex = 0;
};

enum class EBtreeAmStrategy {
    Less = 1,
    LessOrEqual = 2,
    Equal = 3,
    GreaterOrEqual = 4,
    Greater = 5
};

struct TAmProcDesc {
    TString Family;
    ui32 FamilyId = 0;
    ui32 ProcNum = 0;
    ui32 LeftType = 0;
    ui32 RightType = 0;
    ui32 ProcId = 0;
    ui32 ExtensionIndex = 0;
};

enum class EBtreeAmProcNum {
    Compare = 1
};

enum class EHashAmProcNum {
    Hash = 1
};

struct TConversionDesc {
    ui32 ConversionId = 0;
    TString From;
    TString To;
    TString Descr;
    ui32 ProcId = 0;
};

struct TLanguageDesc {
    ui32 LangId = 0;
    TString Name;
    TString Descr;
};

const TProcDesc& LookupProc(const TString& name, const TVector<ui32>& argTypeIds);
const TProcDesc& LookupProc(ui32 procId, const TVector<ui32>& argTypeIds);
const TProcDesc& LookupProc(ui32 procId);
std::variant<const TProcDesc*, const TTypeDesc*> LookupProcWithCasts(const TString& name, const TVector<ui32>& argTypeIds);
bool HasReturnSetProc(const TString& name);
void EnumProc(std::function<void(ui32, const TProcDesc&)> f);
bool HasProc(const TString& name, EProcKind kind);

bool HasType(const TString& name);
bool HasType(ui32 typeId);
const TTypeDesc& LookupType(const TString& name);
const TTypeDesc& LookupType(ui32 typeId);
TMaybe<TIssue> LookupCommonType(const TVector<ui32>& typeIds, const std::function<TPosition(size_t i)>& GetPosition, const TTypeDesc*& typeDesc);
TMaybe<TIssue> LookupCommonType(const TVector<ui32>& typeIds, const std::function<TPosition(size_t i)>& GetPosition, const TTypeDesc*& typeDesc, bool& castsNeeded);
void EnumTypes(std::function<void(ui32, const TTypeDesc&)> f);

const TAmDesc& LookupAm(ui32 oid);
void EnumAm(std::function<void(ui32, const TAmDesc&)> f);

void EnumConversions(std::function<void(const TConversionDesc&)> f);

const TNamespaceDesc& LookupNamespace(ui32 oid);
void EnumNamespace(std::function<void(ui32, const TNamespaceDesc&)> f);

void EnumOperators(std::function<void(const TOperDesc&)> f);

bool HasCast(ui32 sourceId, ui32 targetId);
const TCastDesc& LookupCast(ui32 sourceId, ui32 targetId);

const TOperDesc& LookupOper(const TString& name, const TVector<ui32>& argTypeIds);
const TOperDesc& LookupOper(ui32 operId, const TVector<ui32>& argTypeIds);
const TOperDesc& LookupOper(ui32 operId);

bool HasAggregation(const TString& name, EAggKind kind);
const TAggregateDesc& LookupAggregation(const TString& name, const TVector<ui32>& argTypeIds);
const TAggregateDesc& LookupAggregation(const TString& name, ui32 stateType, ui32 resultType);
void EnumAggregation(std::function<void(ui32, const TAggregateDesc&)> f);

bool HasOpClass(EOpClassMethod method, ui32 typeId);
const TOpClassDesc* LookupDefaultOpClass(EOpClassMethod method, ui32 typeId);

bool HasAmOp(ui32 familyId, ui32 strategy, ui32 leftType, ui32 rightType);
const TAmOpDesc& LookupAmOp(ui32 familyId, ui32 strategy, ui32 leftType, ui32 rightType);

bool HasAmProc(ui32 familyId, ui32 num, ui32 leftType, ui32 rightType);
const TAmProcDesc& LookupAmProc(ui32 familyId, ui32 num, ui32 leftType, ui32 rightType);

bool HasConversion(const TString& from, const TString& to);
const TConversionDesc& LookupConversion(const TString& from, const TString& to);

const TLanguageDesc& LookupLanguage(ui32 langId);
void EnumLanguages(std::function<void(ui32, const TLanguageDesc&)> f);

bool IsCompatibleTo(ui32 actualType, ui32 expectedType);
bool IsCoercible(ui32 fromTypeId, ui32 toTypeId, ECoercionCode coercionType);

inline bool IsArrayType(const TTypeDesc& typeDesc) noexcept {
    return typeDesc.ArrayTypeId == typeDesc.TypeId;
}

enum class ERelKind : char {
    Relation = 'r',
    View = 'v'
};
struct TTableInfoKey {
    TString Schema;
    TString Name;

    bool operator==(const TTableInfoKey& other) const {
        return Schema == other.Schema && Name == other.Name;
    }

    bool operator<(const TTableInfoKey& other) const {
        return std::tie(Schema, Name) < std::tie(other.Schema, other.Name);
    }

    size_t Hash() const {
        auto stringHasher = THash<TString>();
        return CombineHashes(stringHasher(Schema), stringHasher(Name));
    }
};

constexpr ui32 TypeRelationOid = 1247;
constexpr ui32 DatabaseRelationOid = 1262;
constexpr ui32 TableSpaceRelationOid = 1213;
constexpr ui32 SharedDescriptionRelationOid = 2396;
constexpr ui32 TriggerRelationOid = 2620;
constexpr ui32 InheritsRelationOid = 2611;
constexpr ui32 DescriptionRelationOid = 2609;
constexpr ui32 AccessMethodRelationOid = 2601;
constexpr ui32 NamespaceRelationOid = 2615;
constexpr ui32 AuthMemRelationOid = 1261;
constexpr ui32 RelationRelationOid = 1259;

struct TTableInfo : public TTableInfoKey {
    ERelKind Kind;
    ui32 Oid;
    ui32 ExtensionIndex = 0;
};

struct TColumnInfo {
    TString Schema;
    TString TableName;
    TString Name;
    TString UdtType;
    ui32 ExtensionIndex = 0;
};

const TVector<TTableInfo>& GetStaticTables();
const TTableInfo& LookupStaticTable(const TTableInfoKey& tableKey);
const THashMap<TTableInfoKey, TVector<TColumnInfo>>& GetStaticColumns();
const TVector<TMaybe<TString>>* ReadTable(
    const TTableInfoKey& tableKey,
    const TVector<TString>& columnNames,
    size_t* columnsRemap, // should have the same length as columnNames
    size_t& rowStep);

bool AreAllFunctionsAllowed();
void AllowFunction(const TString& name);

struct TExtensionDesc {
    TString Name;               // postgis
    TString InstallName;        // $libdir/postgis-3
    TVector<TString> SqlPaths;  // paths to SQL files with DDL (CREATE TYPE/CREATE FUNCTION/etc), DML (INSERT/VALUES)
    TString LibraryPath;        // file path
    bool TypesOnly = false;     // Can't be loaded if true
    TString LibraryMD5;         // optional
    TString Version;            // version of extension
};

class IExtensionSqlBuilder {
public:
    virtual ~IExtensionSqlBuilder() = default;

    virtual void CreateProc(const TProcDesc& desc) = 0;

    virtual void PrepareType(ui32 extensionIndex,const TString& name) = 0;

    virtual void UpdateType(const TTypeDesc& desc) = 0;

    virtual void CreateTable(const TTableInfo& table, const TVector<TColumnInfo>& columns) = 0;

    virtual void InsertValues(const TTableInfoKey& table, const TVector<TString>& columns,
        const TVector<TMaybe<TString>>& data) = 0; // row based layout

    virtual void CreateCast(const TCastDesc& desc) = 0;

    virtual void PrepareOper(ui32 extensionIndex, const TString& name, const TVector<ui32>& args) = 0;

    virtual void UpdateOper(const TOperDesc& desc) = 0;

    virtual void CreateAggregate(const TAggregateDesc& desc) = 0;

    virtual void CreateOpClass(const TOpClassDesc& opclass, const TVector<TAmOpDesc>& ops, const TVector<TAmProcDesc>& procs) = 0;
};

class IExtensionSqlParser {
public:
    virtual ~IExtensionSqlParser() = default;
    virtual void Parse(ui32 extensionIndex, const TVector<TString>& sqls, IExtensionSqlBuilder& builder) = 0;
};

class IExtensionLoader {
public:
    virtual ~IExtensionLoader() = default;
    virtual void Load(ui32 extensionIndex, const TString& name, const TString& path) = 0;
};

class ISystemFunctionsParser {
public:
    virtual ~ISystemFunctionsParser() = default;
    virtual void Parse(const TString& sql, TVector<TProcDesc>& procs) const = 0;
};

class ISqlLanguageParser {
public:
    virtual ~ISqlLanguageParser() = default;
    virtual void Parse(const TString& sql, TProcDesc& proc) = 0;
    virtual void ParseNode(const Node* stmt, TProcDesc& proc) = 0;
    virtual void Freeze() = 0;
    virtual TExprContext& GetContext() = 0;
};

void SetSqlLanguageParser(std::unique_ptr<ISqlLanguageParser> parser);
ISqlLanguageParser* GetSqlLanguageParser();

void LoadSystemFunctions(ISystemFunctionsParser& parser);

// either RegisterExtensions or ImportExtensions should be called at most once, see ClearExtensions as well
void RegisterExtensions(const TVector<TExtensionDesc>& extensions, bool typesOnly,
    IExtensionSqlParser& parser, IExtensionLoader* loader);
// converts all library paths to basenames
TString ExportExtensions(const TMaybe<TSet<ui32>>& filter = Nothing());
void ImportExtensions(const TString& exported, bool typesOnly, IExtensionLoader* loader);
void ClearExtensions();

void EnumExtensions(std::function<void(ui32 extensionIndex, const TExtensionDesc&)> f);
const TExtensionDesc& LookupExtension(ui32 extensionIndex);
ui32 LookupExtensionByName(const TString& name);
ui32 LookupExtensionByInstallName(const TString& installName);

}

template <>
inline void Out<NYql::NPg::ETypType>(IOutputStream& o, NYql::NPg::ETypType typType) {
    o.Write(static_cast<std::underlying_type<NYql::NPg::ETypType>::type>(typType));
}

template <>
inline void Out<NYql::NPg::ECoercionCode>(IOutputStream& o, NYql::NPg::ECoercionCode coercionCode) {
    o.Write(static_cast<std::underlying_type<NYql::NPg::ECoercionCode>::type>(coercionCode));
}

template <>
struct THash<NYql::NPg::TTableInfoKey> {
    size_t operator ()(const NYql::NPg::TTableInfoKey& val) const {
        return val.Hash();
    }
};