7
7
#include < util/string/cast.h>
8
8
#include < util/string/split.h>
9
9
#include < util/system/env.h>
10
+ #include < util/system/mutex.h>
11
+ #include < util/system/tempfile.h>
10
12
#include < library/cpp/resource/resource.h>
11
13
12
14
namespace NYql ::NPg {
@@ -1585,70 +1587,13 @@ const TColumnInfoRaw AllStaticColumnsRaw[] = {
1585
1587
#include " columns.generated.h"
1586
1588
};
1587
1589
1590
+ const char * AllowedProcsRaw[] = {
1591
+ #include " safe_procs.h"
1592
+ #include " used_procs.h"
1593
+ };
1594
+
1588
1595
struct TCatalog {
1589
- TCatalog ()
1590
- : ProhibitedProcs({
1591
- // revoked from public
1592
- " pg_start_backup" ,
1593
- " pg_stop_backup" ,
1594
- " pg_create_restore_point" ,
1595
- " pg_switch_wal" ,
1596
- " pg_wal_replay_pause" ,
1597
- " pg_wal_replay_resume" ,
1598
- " pg_rotate_logfile" ,
1599
- " pg_reload_conf" ,
1600
- " pg_current_logfile" ,
1601
- " pg_promote" ,
1602
- " pg_stat_reset" ,
1603
- " pg_stat_reset_shared" ,
1604
- " pg_stat_reset_slru" ,
1605
- " pg_stat_reset_single_table_counters" ,
1606
- " pg_stat_reset_single_function_counters" ,
1607
- " pg_stat_reset_replication_slot" ,
1608
- " lo_import" ,
1609
- " lo_export" ,
1610
- " pg_ls_logdir" ,
1611
- " pg_ls_waldir" ,
1612
- " pg_ls_archive_statusdir" ,
1613
- " pg_ls_tmpdir" ,
1614
- " pg_read_file" ,
1615
- " pg_read_binary_file" ,
1616
- " pg_replication_origin_advance" ,
1617
- " pg_replication_origin_create" ,
1618
- " pg_replication_origin_drop" ,
1619
- " pg_replication_origin_oid" ,
1620
- " pg_replication_origin_progress" ,
1621
- " pg_replication_origin_session_is_setup" ,
1622
- " pg_replication_origin_session_progress" ,
1623
- " pg_replication_origin_session_reset" ,
1624
- " pg_replication_origin_session_setup" ,
1625
- " pg_replication_origin_xact_reset" ,
1626
- " pg_replication_origin_xact_setup" ,
1627
- " pg_show_replication_origin_status" ,
1628
- " pg_stat_file" ,
1629
- " pg_ls_dir" ,
1630
- // transactions
1631
- " pg_last_committed_xact" ,
1632
- " pg_current_wal_lsn" ,
1633
- // large_objects
1634
- " lo_creat" ,
1635
- " lo_create" ,
1636
- " lo_import" ,
1637
- " lo_import_with_oid" ,
1638
- " lo_export" ,
1639
- " lo_open" ,
1640
- " lo_write" ,
1641
- " lo_read" ,
1642
- " lo_lseek" ,
1643
- " lo_lseek64" ,
1644
- " lo_tell" ,
1645
- " lo_tell64" ,
1646
- " lo_truncate" ,
1647
- " lo_truncate64" ,
1648
- " lo_close" ,
1649
- " lo_unlink"
1650
- })
1651
- {
1596
+ TCatalog () {
1652
1597
for (size_t i = 0 ; i < Y_ARRAY_SIZE (AllStaticTablesRaw); ++i) {
1653
1598
const auto & raw = AllStaticTablesRaw[i];
1654
1599
AllStaticTables.push_back (
@@ -1918,6 +1863,73 @@ struct TCatalog {
1918
1863
1919
1864
Conversions = ParseConversions (conversionData, ProcByName);
1920
1865
Languages = ParseLanguages (languagesData);
1866
+
1867
+ if (auto exportDir = GetEnv (" YQL_EXPORT_PG_FUNCTIONS_DIR" )) {
1868
+ ExportFile.ConstructInPlace (MakeTempName (exportDir.c_str (), " procs" ), CreateAlways | RdWr);
1869
+ for (const auto & a : Aggregations) {
1870
+ const auto & desc = a.second ;
1871
+ ExportFunction (desc.TransFuncId );
1872
+ ExportFunction (desc.FinalFuncId );
1873
+ ExportFunction (desc.CombineFuncId );
1874
+ ExportFunction (desc.SerializeFuncId );
1875
+ ExportFunction (desc.DeserializeFuncId );
1876
+ }
1877
+
1878
+ for (const auto & t : Types) {
1879
+ const auto & desc = t.second ;
1880
+ ExportFunction (desc.InFuncId );
1881
+ ExportFunction (desc.OutFuncId );
1882
+ ExportFunction (desc.SendFuncId );
1883
+ ExportFunction (desc.ReceiveFuncId );
1884
+ ExportFunction (desc.TypeModInFuncId );
1885
+ ExportFunction (desc.TypeModOutFuncId );
1886
+ ExportFunction (desc.TypeSubscriptFuncId );
1887
+ ExportFunction (desc.LessProcId );
1888
+ ExportFunction (desc.EqualProcId );
1889
+ ExportFunction (desc.CompareProcId );
1890
+ ExportFunction (desc.HashProcId );
1891
+ }
1892
+
1893
+ for (const auto & o : Operators) {
1894
+ const auto & desc = o.second ;
1895
+ ExportFunction (desc.ProcId );
1896
+ }
1897
+
1898
+ for (const auto & c : Casts) {
1899
+ const auto & desc = c.second ;
1900
+ ExportFunction (desc.FunctionId );
1901
+ }
1902
+ } else {
1903
+ for (size_t i = 0 ; i < Y_ARRAY_SIZE (AllowedProcsRaw); ++i) {
1904
+ const auto & raw = AllowedProcsRaw[i];
1905
+ AllowedProcs.insert (raw);
1906
+ }
1907
+
1908
+ for (const auto & t : Types) {
1909
+ AllowedProcs.insert (t.second .Name );
1910
+ }
1911
+ }
1912
+ }
1913
+
1914
+ void ExportFunction (ui32 procOid) const {
1915
+ if (!procOid || !ExportFile) {
1916
+ return ;
1917
+ }
1918
+
1919
+ auto procPtr = Procs.FindPtr (procOid);
1920
+ Y_ENSURE (procPtr);
1921
+ ExportFunction (procPtr->Name );
1922
+ }
1923
+
1924
+ void ExportFunction (const TString& name) const {
1925
+ if (!ExportFile) {
1926
+ return ;
1927
+ }
1928
+
1929
+ TString line = TStringBuilder () << " \" " << name << " \" ,\n " ;
1930
+ with_lock (ExportGuard) {
1931
+ ExportFile->Write (line.Data (), line.Size ());
1932
+ }
1921
1933
}
1922
1934
1923
1935
static const TCatalog& Instance () {
@@ -1941,12 +1953,16 @@ struct TCatalog {
1941
1953
THashMap<std::pair<ui32, ui32>, ui32> CastsByDir;
1942
1954
THashMap<TString, TVector<ui32>> OperatorsByName;
1943
1955
THashMap<TString, TVector<ui32>> AggregationsByName;
1944
- THashSet<TString> ProhibitedProcs;
1945
1956
1946
1957
TVector<TTableInfo> AllStaticTables;
1947
1958
TVector<TColumnInfo> AllStaticColumns;
1948
1959
THashMap<TTableInfoKey, TTableInfo> StaticTables;
1949
1960
THashMap<TTableInfoKey, TVector<TColumnInfo>> StaticColumns;
1961
+
1962
+ mutable TMaybe<TFile> ExportFile;
1963
+ TMutex ExportGuard;
1964
+
1965
+ THashSet<TString> AllowedProcs;
1950
1966
};
1951
1967
1952
1968
bool ValidateProcArgs (const TProcDesc& d, const TVector<ui32>& argTypeIds) {
@@ -1961,21 +1977,22 @@ const TProcDesc& LookupProc(ui32 procId, const TVector<ui32>& argTypeIds) {
1961
1977
throw yexception () << " No such proc: " << procId;
1962
1978
}
1963
1979
1980
+ if (!catalog.ExportFile && !catalog.AllowedProcs .contains (procPtr->Name )) {
1981
+ throw yexception () << " No access to proc: " << procPtr->Name ;
1982
+ }
1983
+
1964
1984
if (!ValidateProcArgs (*procPtr, argTypeIds)) {
1965
1985
throw yexception () << " Unable to find an overload for proc with oid " << procId << " with given argument types: " <<
1966
1986
ArgTypesList (argTypeIds);
1967
1987
}
1968
1988
1989
+ catalog.ExportFunction (procId);
1969
1990
return *procPtr;
1970
1991
}
1971
1992
1972
1993
const TProcDesc& LookupProc (const TString& name, const TVector<ui32>& argTypeIds) {
1973
1994
const auto & catalog = TCatalog::Instance ();
1974
1995
auto lower = to_lower (name);
1975
- if (catalog.ProhibitedProcs .contains (lower)) {
1976
- throw yexception () << " No access to proc: " << name;
1977
- }
1978
-
1979
1996
auto procIdPtr = catalog.ProcByName .FindPtr (lower);
1980
1997
if (!procIdPtr) {
1981
1998
throw yexception () << " No such proc: " << name;
@@ -1984,10 +2001,15 @@ const TProcDesc& LookupProc(const TString& name, const TVector<ui32>& argTypeIds
1984
2001
for (const auto & id : *procIdPtr) {
1985
2002
const auto & d = catalog.Procs .FindPtr (id);
1986
2003
Y_ENSURE (d);
2004
+ if (!catalog.ExportFile && !catalog.AllowedProcs .contains (d->Name )) {
2005
+ throw yexception () << " No access to proc: " << d->Name ;
2006
+ }
2007
+
1987
2008
if (!ValidateProcArgs (*d, argTypeIds)) {
1988
2009
continue ;
1989
2010
}
1990
2011
2012
+ catalog.ExportFunction (d->Name );
1991
2013
return *d;
1992
2014
}
1993
2015
@@ -2002,6 +2024,11 @@ const TProcDesc& LookupProc(ui32 procId) {
2002
2024
throw yexception () << " No such proc: " << procId;
2003
2025
}
2004
2026
2027
+ if (!catalog.ExportFile && !catalog.AllowedProcs .contains (procPtr->Name )) {
2028
+ throw yexception () << " No access to proc: " << procPtr->Name ;
2029
+ }
2030
+
2031
+ catalog.ExportFunction (procId);
2005
2032
return *procPtr;
2006
2033
}
2007
2034
@@ -2611,10 +2638,6 @@ bool IsCoercible(ui32 fromTypeId, ui32 toTypeId, ECoercionCode coercionType) {
2611
2638
std::variant<const TProcDesc*, const TTypeDesc*> LookupProcWithCasts (const TString& name, const TVector<ui32>& argTypeIds) {
2612
2639
const auto & catalog = TCatalog::Instance ();
2613
2640
auto lower = to_lower (name);
2614
- if (catalog.ProhibitedProcs .contains (lower)) {
2615
- throw yexception () << " No access to proc: " << name;
2616
- }
2617
-
2618
2641
auto procIdPtr = catalog.ProcByName .FindPtr (lower);
2619
2642
if (!procIdPtr) {
2620
2643
throw yexception () << " No such proc: " << name;
@@ -2627,6 +2650,10 @@ std::variant<const TProcDesc*, const TTypeDesc*> LookupProcWithCasts(const TStri
2627
2650
const auto & d = catalog.Procs .FindPtr (id);
2628
2651
Y_ENSURE (d);
2629
2652
2653
+ if (!catalog.ExportFile && !catalog.AllowedProcs .contains (d->Name )) {
2654
+ throw yexception () << " No access to proc: " << d->Name ;
2655
+ }
2656
+
2630
2657
if (NPrivate::IsExactMatch (d->ArgTypes , d->VariadicType , argTypeIds)) {
2631
2658
// At most one exact match is possible, so look no further
2632
2659
// https://www.postgresql.org/docs/14/typeconv-func.html, step 2
0 commit comments