3
3
#include < Common/KnownObjectNames.h>
4
4
#include < Common/re2.h>
5
5
#include < Common/maskURIPassword.h>
6
+ #include < Common/NamedCollections/NamedCollections.h>
7
+ #include < Common/NamedCollections/NamedCollectionsFactory.h>
6
8
#include < Core/QualifiedTableName.h>
7
9
#include < base/defines.h>
8
10
#include < boost/algorithm/string/predicate.hpp>
11
+ #include < Poco/String.h>
9
12
10
13
11
14
namespace DB
@@ -29,6 +32,21 @@ class AbstractFunction
29
32
virtual ~Arguments () = default ;
30
33
virtual size_t size () const = 0;
31
34
virtual std::unique_ptr<Argument> at (size_t n) const = 0;
35
+ void skipArgument (size_t n) { skipped_indexes.insert (n); }
36
+ void unskipArguments () { skipped_indexes.clear (); }
37
+ size_t getRealIndex (size_t n) const
38
+ {
39
+ for (auto idx : skipped_indexes)
40
+ {
41
+ if (n < idx)
42
+ break ;
43
+ ++n;
44
+ }
45
+ return n;
46
+ }
47
+ size_t skippedSize () const { return skipped_indexes.size (); }
48
+ private:
49
+ std::set<size_t > skipped_indexes;
32
50
};
33
51
34
52
virtual ~AbstractFunction () = default ;
@@ -75,14 +93,15 @@ class FunctionSecretArgumentsFinder
75
93
{
76
94
if (index >= function->arguments ->size ())
77
95
return ;
96
+ auto real_index = function->arguments ->getRealIndex (index );
78
97
if (!result.count )
79
98
{
80
- result.start = index ;
99
+ result.start = real_index ;
81
100
result.are_named = argument_is_named;
82
101
}
83
- chassert (index >= result.start ); // / We always check arguments consecutively
102
+ chassert (real_index >= result.start ); // / We always check arguments consecutively
84
103
chassert (result.replacement .empty ()); // / We shouldn't use replacement with masking other arguments
85
- result.count = index + 1 - result.start ;
104
+ result.count = real_index + 1 - result.start ;
86
105
if (!argument_is_named)
87
106
result.are_named = false ;
88
107
}
@@ -100,14 +119,18 @@ class FunctionSecretArgumentsFinder
100
119
{
101
120
findMongoDBSecretArguments ();
102
121
}
122
+ else if (function->name () == " iceberg" )
123
+ {
124
+ findIcebergFunctionSecretArguments ();
125
+ }
103
126
else if ((function->name () == " s3" ) || (function->name () == " cosn" ) || (function->name () == " oss" ) ||
104
- (function->name () == " deltaLake" ) || (function->name () == " hudi" ) || (function-> name () == " iceberg " ) ||
127
+ (function->name () == " deltaLake" ) || (function->name () == " hudi" ) ||
105
128
(function->name () == " gcs" ) || (function->name () == " icebergS3" ))
106
129
{
107
130
// / s3('url', 'aws_access_key_id', 'aws_secret_access_key', ...)
108
131
findS3FunctionSecretArguments (/* is_cluster_function= */ false );
109
132
}
110
- else if (function->name () == " s3Cluster" )
133
+ else if (( function->name () == " s3Cluster" ) || (function-> name () == " icebergS3Cluster " ) )
111
134
{
112
135
// / s3Cluster('cluster_name', 'url', 'aws_access_key_id', 'aws_secret_access_key', ...)
113
136
findS3FunctionSecretArguments (/* is_cluster_function= */ true );
@@ -117,7 +140,7 @@ class FunctionSecretArgumentsFinder
117
140
// / azureBlobStorage(connection_string|storage_account_url, container_name, blobpath, account_name, account_key, format, compression, structure)
118
141
findAzureBlobStorageFunctionSecretArguments (/* is_cluster_function= */ false );
119
142
}
120
- else if (function->name () == " azureBlobStorageCluster" )
143
+ else if (( function->name () == " azureBlobStorageCluster" ) || (function-> name () == " icebergAzureCluster " ) )
121
144
{
122
145
// / azureBlobStorageCluster(cluster, connection_string|storage_account_url, container_name, blobpath, [account_name, account_key, format, compression, structure])
123
146
findAzureBlobStorageFunctionSecretArguments (/* is_cluster_function= */ true );
@@ -218,11 +241,18 @@ class FunctionSecretArgumentsFinder
218
241
findSecretNamedArgument (" secret_access_key" , 1 );
219
242
return ;
220
243
}
244
+ if (is_cluster_function && isNamedCollectionName (1 ))
245
+ {
246
+ // / s3Cluster(cluster, named_collection, ..., secret_access_key = 'secret_access_key', ...)
247
+ findSecretNamedArgument (" secret_access_key" , 2 );
248
+ return ;
249
+ }
221
250
222
251
// / We should check other arguments first because we don't need to do any replacement in case of
223
252
// / s3('url', NOSIGN, 'format' [, 'compression'] [, extra_credentials(..)] [, headers(..)])
224
253
// / s3('url', 'format', 'structure' [, 'compression'] [, extra_credentials(..)] [, headers(..)])
225
254
size_t count = excludeS3OrURLNestedMaps ();
255
+
226
256
if ((url_arg_idx + 3 <= count) && (count <= url_arg_idx + 4 ))
227
257
{
228
258
String second_arg;
@@ -287,6 +317,48 @@ class FunctionSecretArgumentsFinder
287
317
markSecretArgument (url_arg_idx + 4 );
288
318
}
289
319
320
+ std::string findIcebergStorageType ()
321
+ {
322
+ std::string storage_type = " s3" ;
323
+
324
+ size_t count = function->arguments ->size ();
325
+ if (!count)
326
+ return storage_type;
327
+
328
+ auto storage_type_idx = findNamedArgument (&storage_type, " storage_type" );
329
+ if (storage_type_idx != -1 )
330
+ {
331
+ storage_type = Poco::toLower (storage_type);
332
+ function->arguments ->skipArgument (storage_type_idx);
333
+ }
334
+ else if (isNamedCollectionName (0 ))
335
+ {
336
+ std::string collection_name;
337
+ if (function->arguments ->at (0 )->tryGetString (&collection_name, true ))
338
+ {
339
+ NamedCollectionPtr collection = NamedCollectionFactory::instance ().tryGet (collection_name);
340
+ if (collection && collection->has (" storage_type" ))
341
+ {
342
+ storage_type = Poco::toLower (collection->get <std::string>(" storage_type" ));
343
+ }
344
+ }
345
+ }
346
+
347
+ return storage_type;
348
+ }
349
+
350
+ void findIcebergFunctionSecretArguments ()
351
+ {
352
+ auto storage_type = findIcebergStorageType ();
353
+
354
+ if (storage_type == " s3" )
355
+ findS3FunctionSecretArguments (false );
356
+ else if (storage_type == " azure" )
357
+ findAzureBlobStorageFunctionSecretArguments (false );
358
+
359
+ function->arguments ->unskipArguments ();
360
+ }
361
+
290
362
bool maskAzureConnectionString (ssize_t url_arg_idx, bool argument_is_named = false , size_t start = 0 )
291
363
{
292
364
String url_arg;
@@ -310,7 +382,7 @@ class FunctionSecretArgumentsFinder
310
382
if (RE2::Replace (&url_arg, account_key_pattern, " AccountKey=[HIDDEN]\\ 1" ))
311
383
{
312
384
chassert (result.count == 0 ); // / We shouldn't use replacement with masking other arguments
313
- result.start = url_arg_idx;
385
+ result.start = function-> arguments -> getRealIndex ( url_arg_idx) ;
314
386
result.are_named = argument_is_named;
315
387
result.count = 1 ;
316
388
result.replacement = url_arg;
@@ -458,6 +530,7 @@ class FunctionSecretArgumentsFinder
458
530
void findTableEngineSecretArguments ()
459
531
{
460
532
const String & engine_name = function->name ();
533
+
461
534
if (engine_name == " ExternalDistributed" )
462
535
{
463
536
// / ExternalDistributed('engine', 'host:port', 'database', 'table', 'user', 'password')
@@ -475,10 +548,13 @@ class FunctionSecretArgumentsFinder
475
548
{
476
549
findMongoDBSecretArguments ();
477
550
}
551
+ else if (engine_name == " Iceberg" )
552
+ {
553
+ findIcebergTableEngineSecretArguments ();
554
+ }
478
555
else if ((engine_name == " S3" ) || (engine_name == " COSN" ) || (engine_name == " OSS" )
479
556
|| (engine_name == " DeltaLake" ) || (engine_name == " Hudi" )
480
- || (engine_name == " Iceberg" ) || (engine_name == " IcebergS3" )
481
- || (engine_name == " S3Queue" ))
557
+ || (engine_name == " IcebergS3" ) || (engine_name == " S3Queue" ))
482
558
{
483
559
// / S3('url', ['aws_access_key_id', 'aws_secret_access_key',] ...)
484
560
findS3TableEngineSecretArguments ();
@@ -487,7 +563,7 @@ class FunctionSecretArgumentsFinder
487
563
{
488
564
findURLSecretArguments ();
489
565
}
490
- else if (engine_name == " AzureBlobStorage" )
566
+ else if (( engine_name == " AzureBlobStorage" ) || (engine_name == " IcebergAzure " ) )
491
567
{
492
568
findAzureBlobStorageTableEngineSecretArguments ();
493
569
}
@@ -579,6 +655,18 @@ class FunctionSecretArgumentsFinder
579
655
markSecretArgument (url_arg_idx + 4 );
580
656
}
581
657
658
+ void findIcebergTableEngineSecretArguments ()
659
+ {
660
+ auto storage_type = findIcebergStorageType ();
661
+
662
+ if (storage_type == " s3" )
663
+ findS3TableEngineSecretArguments ();
664
+ else if (storage_type == " azure" )
665
+ findAzureBlobStorageTableEngineSecretArguments ();
666
+
667
+ function->arguments ->unskipArguments ();
668
+ }
669
+
582
670
void findDatabaseEngineSecretArguments ()
583
671
{
584
672
const String & engine_name = function->name ();
0 commit comments