@@ -2502,6 +2502,34 @@ void TABLE_SHARE::free_frm_image(const uchar *frm)
2502
2502
}
2503
2503
2504
2504
2505
+ static bool fix_vcol_expr (THD *thd, Virtual_column_info *vcol)
2506
+ {
2507
+ DBUG_ENTER (" fix_vcol_expr" );
2508
+
2509
+ const enum enum_mark_columns save_mark_used_columns= thd->mark_used_columns ;
2510
+ thd->mark_used_columns = MARK_COLUMNS_NONE;
2511
+
2512
+ const char *save_where= thd->where ;
2513
+ thd->where = " virtual column function" ;
2514
+
2515
+ thd->in_stored_expression = 1 ;
2516
+
2517
+ int error= vcol->expr_item ->fix_fields (thd, &vcol->expr_item );
2518
+
2519
+ thd->in_stored_expression = 0 ;
2520
+ thd->mark_used_columns = save_mark_used_columns;
2521
+ thd->where = save_where;
2522
+
2523
+ if (unlikely (error))
2524
+ {
2525
+ my_error (ER_ERROR_EVALUATING_EXPRESSION, MYF (0 ), vcol->expr_str );
2526
+ DBUG_RETURN (1 );
2527
+ }
2528
+
2529
+ DBUG_RETURN (0 );
2530
+ }
2531
+
2532
+
2505
2533
/*
2506
2534
@brief
2507
2535
Perform semantic analysis of the defining expression for a virtual column
@@ -2529,53 +2557,38 @@ void TABLE_SHARE::free_frm_image(const uchar *frm)
2529
2557
FALSE Otherwise
2530
2558
*/
2531
2559
2532
- static bool fix_vcol_expr (THD *thd, TABLE *table, Field *field,
2533
- Virtual_column_info *vcol)
2560
+ static bool fix_and_check_vcol_expr (THD *thd, TABLE *table, Field *field,
2561
+ Virtual_column_info *vcol)
2534
2562
{
2535
2563
Item* func_expr= vcol->expr_item ;
2536
- bool result= TRUE ;
2537
- TABLE_LIST tables;
2538
- int error= 0 ;
2539
- const char *save_where;
2540
- enum_mark_columns save_mark_used_columns= thd->mark_used_columns ;
2541
- DBUG_ENTER (" fix_vcol_expr" );
2564
+ DBUG_ENTER (" fix_and_check_vcol_expr" );
2542
2565
DBUG_PRINT (" info" , (" vcol: %p" , vcol));
2543
2566
DBUG_ASSERT (func_expr);
2544
2567
2545
- thd->mark_used_columns = MARK_COLUMNS_NONE;
2568
+ if (func_expr->fixed )
2569
+ DBUG_RETURN (0 ); // nothing to do
2546
2570
2547
- save_where= thd-> where ;
2548
- thd-> where = " virtual column function " ;
2571
+ if ( fix_vcol_expr ( thd, vcol))
2572
+ DBUG_RETURN ( 1 ) ;
2549
2573
2550
- /* Fix fields referenced to by the virtual column function */
2551
- thd->in_stored_expression = 1 ;
2552
- if (!func_expr->fixed )
2553
- error= func_expr->fix_fields (thd, &vcol->expr_item );
2554
- thd->in_stored_expression = 0 ;
2574
+ if (vcol->flags )
2575
+ DBUG_RETURN (0 ); // already checked, no need to do it again
2555
2576
2556
- if (unlikely (error))
2557
- {
2558
- DBUG_PRINT (" info" ,
2559
- (" Field in virtual column expression does not belong to the table" ));
2560
- my_error (ER_ERROR_EVALUATING_EXPRESSION, MYF (0 ), vcol->expr_str );
2561
- goto end;
2562
- }
2563
2577
/* fix_fields could've changed the expression */
2564
2578
func_expr= vcol->expr_item ;
2565
2579
2566
2580
/* Number of columns will be checked later */
2567
- thd->where = save_where;
2568
2581
if (unlikely (func_expr->result_type () == ROW_RESULT))
2569
2582
{
2570
2583
my_error (ER_ROW_EXPR_FOR_VCOL, MYF (0 ));
2571
- goto end ;
2584
+ DBUG_RETURN ( 1 ) ;
2572
2585
}
2573
2586
2574
2587
/* Check that we are not refering to any not yet initialized fields */
2575
2588
if (field)
2576
2589
{
2577
2590
if (func_expr->walk (&Item::check_field_expression_processor, 0 , field))
2578
- goto end ;
2591
+ DBUG_RETURN ( 1 ) ;
2579
2592
}
2580
2593
2581
2594
/*
@@ -2585,12 +2598,12 @@ static bool fix_vcol_expr(THD *thd, TABLE *table, Field *field,
2585
2598
Item::vcol_func_processor_result res;
2586
2599
res.errors = 0 ;
2587
2600
2588
- error= func_expr->walk (&Item::check_vcol_func_processor, 0 , &res);
2601
+ int error= func_expr->walk (&Item::check_vcol_func_processor, 0 , &res);
2589
2602
if (error || (res.errors & VCOL_IMPOSSIBLE))
2590
2603
{ // this can only happen if the frm was corrupted
2591
2604
my_error (ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED, MYF (0 ), res.name ,
2592
2605
" ???" , field ? field->field_name : " ?????" );
2593
- goto end ;
2606
+ DBUG_RETURN ( 1 ) ;
2594
2607
}
2595
2608
vcol->flags = res.errors ;
2596
2609
@@ -2600,16 +2613,10 @@ static bool fix_vcol_expr(THD *thd, TABLE *table, Field *field,
2600
2613
if (vcol->stored_in_db && vcol->flags & VCOL_NON_DETERMINISTIC)
2601
2614
table->s ->non_determinstic_insert = 1 ;
2602
2615
2603
- result= FALSE ;
2604
-
2605
- end:
2606
-
2607
- thd->mark_used_columns = save_mark_used_columns;
2608
- table->map = 0 ; // Restore old value
2609
-
2610
- DBUG_RETURN (result);
2616
+ DBUG_RETURN (0 );
2611
2617
}
2612
2618
2619
+
2613
2620
/*
2614
2621
@brief
2615
2622
Unpack the definition of a virtual column from its linear representation
@@ -2629,7 +2636,7 @@ static bool fix_vcol_expr(THD *thd, TABLE *table, Field *field,
2629
2636
pointer to this item is placed into in a Virtual_column_info object
2630
2637
that is created. After this the function performs
2631
2638
semantic analysis of the item by calling the the function
2632
- fix_vcol_expr (). Since the defining expression is part of the table
2639
+ fix_and_check_vcol_expr (). Since the defining expression is part of the table
2633
2640
definition the item for it is created in table->memroot within the
2634
2641
special arena TABLE::expr_arena or in the thd memroot for INSERT DELAYED
2635
2642
@@ -2736,15 +2743,10 @@ Virtual_column_info *unpack_vcol_info_from_frm(THD *thd,
2736
2743
if (error)
2737
2744
goto err;
2738
2745
2739
- /*
2740
- mark if expression will be stored in the table. This is also used by
2741
- fix_vcol_expr() to mark if we are using non deterministic functions.
2742
- */
2743
2746
vcol_storage.vcol_info ->stored_in_db = vcol->stored_in_db ;
2744
2747
vcol_storage.vcol_info ->name = vcol->name ;
2745
2748
vcol_storage.vcol_info ->utf8 = vcol->utf8 ;
2746
- /* Validate the Item tree. */
2747
- if (!fix_vcol_expr (thd, table, field, vcol_storage.vcol_info ))
2749
+ if (!fix_and_check_vcol_expr (thd, table, field, vcol_storage.vcol_info ))
2748
2750
{
2749
2751
vcol_info= vcol_storage.vcol_info ; // Expression ok
2750
2752
goto end;
0 commit comments