12
12
// See the License for the specific language governing permissions and
13
13
// limitations under the License.
14
14
15
- use std:: fmt:: Write ;
16
- use std:: sync:: Arc ;
17
-
18
15
use databend_common_ast:: ast:: Identifier ;
19
16
use databend_common_ast:: ast:: SampleConfig ;
20
17
use databend_common_ast:: ast:: Statement ;
@@ -24,27 +21,19 @@ use databend_common_ast::ast::WithOptions;
24
21
use databend_common_ast:: parser:: parse_sql;
25
22
use databend_common_ast:: parser:: tokenize_sql;
26
23
use databend_common_ast:: Span ;
27
- use databend_common_catalog:: table:: Table ;
28
24
use databend_common_catalog:: table:: TimeNavigation ;
29
25
use databend_common_catalog:: table_with_options:: check_with_opt_valid;
30
26
use databend_common_catalog:: table_with_options:: get_with_opt_consume;
31
27
use databend_common_catalog:: table_with_options:: get_with_opt_max_batch_size;
32
28
use databend_common_exception:: ErrorCode ;
33
29
use databend_common_exception:: Result ;
34
- use databend_common_expression:: types:: DataType ;
35
- use databend_common_expression:: Scalar ;
36
- use databend_common_expression:: TableDataType ;
37
30
use databend_common_storages_view:: view_table:: QUERY ;
38
31
use databend_storages_common_table_meta:: table:: get_change_type;
39
32
40
33
use crate :: binder:: util:: TableIdentifier ;
41
34
use crate :: binder:: Binder ;
42
35
use crate :: optimizer:: ir:: SExpr ;
43
36
use crate :: BindContext ;
44
- use crate :: ColumnBindingBuilder ;
45
- use crate :: ColumnEntry ;
46
- use crate :: IndexType ;
47
- use crate :: Visibility ;
48
37
49
38
impl Binder {
50
39
/// Bind a base table.
@@ -173,7 +162,9 @@ impl Binder {
173
162
bind_context. planning_agg_index ,
174
163
false ,
175
164
None ,
176
- ) ;
165
+ & mut bind_context. virtual_column_context ,
166
+ & mut bind_context. columns ,
167
+ ) ?;
177
168
let ( s_expr, mut bind_context) = self . bind_base_table (
178
169
bind_context,
179
170
database. as_str ( ) ,
@@ -258,7 +249,9 @@ impl Binder {
258
249
false ,
259
250
false ,
260
251
None ,
261
- ) ;
252
+ & mut bind_context. virtual_column_context ,
253
+ & mut bind_context. columns ,
254
+ ) ?;
262
255
let ( s_expr, mut new_bind_context) =
263
256
self . bind_query ( & mut new_bind_context, query) ?;
264
257
if let Some ( alias) = alias {
@@ -290,8 +283,9 @@ impl Binder {
290
283
bind_context. planning_agg_index ,
291
284
false ,
292
285
cte_suffix_name,
293
- ) ;
294
- self . bind_table_virtual_column ( bind_context, table_meta. clone ( ) , table_index) ?;
286
+ & mut bind_context. virtual_column_context ,
287
+ & mut bind_context. columns ,
288
+ ) ?;
295
289
296
290
let ( s_expr, mut bind_context) = self . bind_base_table (
297
291
bind_context,
@@ -331,183 +325,4 @@ impl Binder {
331
325
_ => Ok ( ( ) ) ,
332
326
}
333
327
}
334
-
335
- fn bind_table_virtual_column (
336
- & mut self ,
337
- bind_context : & mut BindContext ,
338
- table : Arc < dyn Table > ,
339
- table_index : IndexType ,
340
- ) -> Result < ( ) > {
341
- if !bind_context. virtual_column_context . allow_pushdown {
342
- return Ok ( ( ) ) ;
343
- }
344
-
345
- // Ignore tables that do not support virtual columns
346
- if !table. support_virtual_columns ( ) {
347
- return Ok ( ( ) ) ;
348
- }
349
-
350
- let table_meta = & table. get_table_info ( ) . meta ;
351
- let Some ( ref virtual_schema) = table_meta. virtual_schema else {
352
- return Ok ( ( ) ) ;
353
- } ;
354
-
355
- if !bind_context
356
- . virtual_column_context
357
- . table_indices
358
- . contains ( & table_index)
359
- {
360
- bind_context
361
- . virtual_column_context
362
- . table_indices
363
- . insert ( table_index) ;
364
- for virtual_field in virtual_schema. fields . iter ( ) {
365
- let Some ( base_column) = ( {
366
- let guard = self . metadata . read ( ) ;
367
- guard
368
- . columns_by_table_index ( table_index)
369
- . iter ( )
370
- . find_map ( |column| {
371
- if let ColumnEntry :: BaseTableColumn ( base_column) = column {
372
- if base_column. column_id == Some ( virtual_field. source_column_id ) {
373
- return Some ( base_column. clone ( ) ) ;
374
- }
375
- }
376
- None
377
- } )
378
- } ) else {
379
- continue ;
380
- } ;
381
-
382
- let name = format ! ( "{}{}" , base_column. column_name, virtual_field. name) ;
383
- let mut index = 0 ;
384
- // Check for duplicate virtual columns
385
- for table_column in self
386
- . metadata
387
- . read ( )
388
- . virtual_columns_by_table_index ( table_index)
389
- {
390
- if table_column. name ( ) == name {
391
- index = table_column. index ( ) ;
392
- break ;
393
- }
394
- }
395
- let column_id = virtual_field. column_id ;
396
-
397
- // It's not possible to determine the actual type based on the type of generated virtual columns,
398
- // as fields in non-leaf nodes are not generated with virtual columns,
399
- // and these ungenerated nodes may have inconsistent types.
400
- let table_data_type = TableDataType :: Nullable ( Box :: new ( TableDataType :: Variant ) ) ;
401
- let data_type = Box :: new ( DataType :: from ( & table_data_type) ) ;
402
-
403
- if index == 0 {
404
- let is_created = true ;
405
-
406
- let path = Self :: convert_array_index ( & virtual_field. name ) ?;
407
- index = self . metadata . write ( ) . add_virtual_column (
408
- & base_column,
409
- column_id,
410
- name. clone ( ) ,
411
- table_data_type,
412
- Scalar :: String ( path) ,
413
- None ,
414
- is_created,
415
- ) ;
416
- }
417
- let virtual_column_binding =
418
- ColumnBindingBuilder :: new ( name, index, data_type, Visibility :: InVisible )
419
- . table_index ( Some ( table_index) )
420
- . build ( ) ;
421
- bind_context. columns . push ( virtual_column_binding) ;
422
- }
423
- }
424
-
425
- Ok ( ( ) )
426
- }
427
-
428
- fn convert_array_index ( input : & str ) -> Result < String > {
429
- let mut chars = input. chars ( ) . peekable ( ) ;
430
- let mut path = "{" . to_string ( ) ;
431
-
432
- while chars. peek ( ) . is_some ( ) {
433
- if chars. next ( ) != Some ( '[' ) {
434
- return Err ( ErrorCode :: InvalidArgument ( "Expected '['" . to_string ( ) ) ) ;
435
- }
436
- if let Some ( '\'' ) = chars. peek ( ) {
437
- let _ = chars. next ( ) ;
438
- path. push ( '"' ) ;
439
-
440
- let mut is_empty = true ;
441
- for c in chars. by_ref ( ) {
442
- is_empty = false ;
443
- if c == '\'' {
444
- break ;
445
- }
446
- path. write_char ( c) ?;
447
- }
448
- if is_empty {
449
- let _ = path. pop ( ) ;
450
- } else {
451
- path. push ( '"' )
452
- }
453
- if chars. next ( ) != Some ( ']' ) {
454
- return Err ( ErrorCode :: InvalidArgument ( "Expected ']' after string" ) ) ;
455
- }
456
- } else {
457
- while let Some ( & c) = chars. peek ( ) {
458
- if c == ']' {
459
- break ;
460
- }
461
- path. write_char ( c) ?;
462
- chars. next ( ) ;
463
- }
464
- if chars. next ( ) != Some ( ']' ) {
465
- return Err ( ErrorCode :: InvalidArgument (
466
- "Expected ']' after index" . to_string ( ) ,
467
- ) ) ;
468
- }
469
- } ;
470
-
471
- path. write_char ( ',' ) ?;
472
- }
473
- if path. len ( ) > 1 {
474
- let _ = path. pop ( ) ;
475
- }
476
- path. write_char ( '}' ) ?;
477
-
478
- if chars. next ( ) . is_some ( ) {
479
- return Err ( ErrorCode :: InvalidArgument ( "Unexpected trailing characters" ) ) ;
480
- }
481
- Ok ( path)
482
- }
483
- }
484
-
485
- #[ cfg( test) ]
486
- mod test {
487
- use databend_common_exception:: Result ;
488
-
489
- use crate :: Binder ;
490
-
491
- #[ test]
492
- fn test_convert_array_index ( ) -> Result < ( ) > {
493
- let success = vec ! [
494
- ( "['a']" , "{\" a\" }" ) ,
495
- ( "['a'][0]" , "{\" a\" ,0}" ) ,
496
- ( "['a']['b']" , "{\" a\" ,\" b\" }" ) ,
497
- ( "['a']['some_word']" , "{\" a\" ,\" some_word\" }" ) ,
498
- ( "['a'][42]['long_string']" , "{\" a\" ,42,\" long_string\" }" ) ,
499
- ( "['a'][0]['b']['c']" , "{\" a\" ,0,\" b\" ,\" c\" }" ) ,
500
- ( "['key']['value'][123]" , "{\" key\" ,\" value\" ,123}" ) ,
501
- ( "[0]" , "{0}" ) ,
502
- ] ;
503
- let failure = vec ! [ "invalid" , "['a'" , "['a']extra" ] ;
504
- for ( case, result) in success {
505
- assert_eq ! ( result, Binder :: convert_array_index( case) ?) ;
506
- }
507
- for case in failure {
508
- assert ! ( Binder :: convert_array_index( case) . is_err( ) ) ;
509
- }
510
-
511
- Ok ( ( ) )
512
- }
513
328
}
0 commit comments