@@ -713,23 +713,127 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived)
713713 cursor= cursor->next_local )
714714 cursor->outer_join |= JOIN_TYPE_OUTER;
715715 }
716- if ((thd->stmt_arena ->is_stmt_prepare () ||
717- !thd->stmt_arena ->is_stmt_execute ()) &&
718- !derived->is_view () && sl->table_list .elements > 0 )
716+
717+ // System Versioning begin
718+ #pragma GCC diagnostic push
719+ #pragma GCC diagnostic ignored "-Wformat"
720+ #pragma GCC diagnostic ignored "-Wformat-extra-args"
721+ if ((thd->stmt_arena ->is_stmt_prepare () || !thd->stmt_arena ->is_stmt_execute ())
722+ && sl->table_list .elements > 0 )
719723 {
720- TABLE_LIST *tl= sl->table_list .first ;
721- if (tl->table && tl->table ->versioned ())
724+ // Similar logic as in mysql_create_view()
725+ TABLE_LIST *impli_table= NULL , *expli_table= NULL ;
726+ const char *impli_start, *impli_end;
727+ Item_field *expli_start= NULL , *expli_end= NULL ;
728+
729+ for (TABLE_LIST *table= sl->table_list .first ; table; table= table->next_local )
730+ {
731+ if (!table->table || !table->table ->versioned ())
732+ continue ;
733+
734+ const char *table_start= table->table ->vers_start_field ()->field_name ;
735+ const char *table_end= table->table ->vers_end_field ()->field_name ;
736+ if (!impli_table)
737+ {
738+ impli_table= table;
739+ impli_start= table_start;
740+ impli_end= table_end;
741+ }
742+
743+ /* Implicitly add versioning fields if needed */
744+ Item *item;
745+ List_iterator_fast<Item> it (sl->item_list );
746+
747+ DBUG_ASSERT (table->alias );
748+ while ((item= it++))
749+ {
750+ if (item->real_item ()->type () != Item::FIELD_ITEM)
751+ continue ;
752+ Item_field *fld= (Item_field*) (item->real_item ());
753+ if (fld->table_name && 0 != my_strcasecmp (table_alias_charset, table->alias , fld->table_name ))
754+ continue ;
755+ DBUG_ASSERT (fld->field_name );
756+ if (0 == my_strcasecmp (system_charset_info, table_start, fld->field_name ))
757+ {
758+ if (expli_start)
759+ {
760+ my_printf_error (
761+ ER_VERS_DERIVED_PROHIBITED,
762+ " Derived table is prohibited: multiple start system fields `%s.%s`, `%s.%s` in query!" , MYF (0 ),
763+ expli_table->alias ,
764+ expli_start->field_name ,
765+ table->alias ,
766+ fld->field_name );
767+ res= true ;
768+ goto exit;
769+ }
770+ if (expli_table)
771+ {
772+ if (expli_table != table)
773+ {
774+ expli_table_err:
775+ my_printf_error (
776+ ER_VERS_DERIVED_PROHIBITED,
777+ " Derived table is prohibited: system fields from multiple tables %`s, %`s in query!" , MYF (0 ),
778+ expli_table->alias ,
779+ table->alias );
780+ res= true ;
781+ goto exit;
782+ }
783+ }
784+ else
785+ expli_table= table;
786+ expli_start= fld;
787+ impli_end= table_end;
788+ }
789+ else if (0 == my_strcasecmp (system_charset_info, table_end, fld->field_name ))
790+ {
791+ if (expli_end)
792+ {
793+ my_printf_error (
794+ ER_VERS_DERIVED_PROHIBITED,
795+ " Derived table is prohibited: multiple end system fields `%s.%s`, `%s.%s` in query!" , MYF (0 ),
796+ expli_table->alias ,
797+ expli_end->field_name ,
798+ table->alias ,
799+ fld->field_name );
800+ res= true ;
801+ goto exit;
802+ }
803+ if (expli_table)
804+ {
805+ if (expli_table != table)
806+ goto expli_table_err;
807+ }
808+ else
809+ expli_table= table;
810+ expli_end= fld;
811+ impli_start= table_start;
812+ }
813+ } // while ((item= it++))
814+ } // for (TABLE_LIST *table)
815+
816+ if (expli_table)
817+ impli_table= expli_table;
818+
819+ if (impli_table)
722820 {
723- TABLE_SHARE *s= tl->table ->s ;
724- const char *db= tl->db ;
725- const char *alias= tl->alias ;
726821 Query_arena_stmt on_stmt_arena (thd);
727- sl->item_list .push_back (new (thd->mem_root ) Item_field (
728- thd, &sl->context , db, alias, s->vers_start_field ()->field_name ));
729- sl->item_list .push_back (new (thd->mem_root ) Item_field (
730- thd, &sl->context , db, alias, s->vers_end_field ()->field_name ));
822+ if (!expli_start && (res= sl->vers_push_field (thd, impli_table, impli_start)))
823+ goto exit;
824+ if (!expli_end && (res= sl->vers_push_field (thd, impli_table, impli_end)))
825+ goto exit;
826+
827+ if (impli_table->vers_conditions )
828+ sl->vers_derived_conds = impli_table->vers_conditions ;
829+ else if (sl->vers_conditions )
830+ sl->vers_derived_conds = sl->vers_conditions ;
831+ else
832+ sl->vers_conditions .import_outer = true ;
731833 }
732- }
834+ } // if (sl->table_list.elements > 0)
835+ #pragma GCC diagnostic pop
836+ // System Versioning end
733837 }
734838
735839 unit->derived = derived;
0 commit comments