diff --git b/sql/ha_partition.cc a/sql/ha_partition.cc
index 9700810f3b8..123e89f8846 100644
--- b/sql/ha_partition.cc
+++ a/sql/ha_partition.cc
@@ -7241,6 +7241,8 @@ bool ha_partition::check_parallel_search()
         if (order_field && order_field->table == table_list->table)
         {
           Field *part_field= m_part_info->full_part_field_array[0];
+          if (set_top_table_fields)
+            order_field= top_table_field[order_field->field_index];
           DBUG_PRINT("info",("partition order_field: %p", order_field));
           DBUG_PRINT("info",("partition part_field: %p", part_field));
           if (part_field == order_field)
@@ -7284,6 +7286,8 @@ bool ha_partition::check_parallel_search()
         if (group_field && group_field->table == table_list->table)
         {
           Field *part_field= m_part_info->full_part_field_array[0];
+          if (set_top_table_fields)
+            group_field= top_table_field[group_field->field_index];
           DBUG_PRINT("info",("partition group_field: %p", group_field));
           DBUG_PRINT("info",("partition part_field: %p", part_field));
           if (part_field == group_field)
@@ -11219,6 +11223,22 @@ const COND *ha_partition::cond_push(const COND *cond)
   COND *res_cond= NULL;
   DBUG_ENTER("ha_partition::cond_push");
 
+  if (set_top_table_fields)
+  {
+    /*
+      We want to do this in a separate loop to not come into a situation
+      where we have only done cond_push() to some of the tables
+    */
+    do
+    {
+      if (((*file)->set_top_table_and_fields(top_table,
+                                             top_table_field,
+                                             top_table_fields)))
+        DBUG_RETURN(cond);                      // Abort cond push, no error
+    } while (*(++file));
+    file= m_file;
+  }
+
   do
   {
     if ((*file)->pushed_cond != cond)
@@ -11850,6 +11870,23 @@ int ha_partition::info_push(uint info_type, void *info)
 }
 
 
+void ha_partition::clear_top_table_fields()
+{
+  handler **file;
+  DBUG_ENTER("ha_partition::clear_top_table_fields");
+
+  if (set_top_table_fields)
+  {
+    set_top_table_fields= FALSE;
+    top_table= NULL;
+    top_table_field= NULL;
+    top_table_fields= 0;
+    for (file= m_file; *file; file++)
+      (*file)->clear_top_table_fields();
+  }
+  DBUG_VOID_RETURN;
+}
+
 bool
 ha_partition::can_convert_string(const Field_string* field,
 		                 const Column_definition& new_type) const
diff --git b/sql/ha_partition.h a/sql/ha_partition.h
index 120d5cb2b30..f7da67562ae 100644
--- b/sql/ha_partition.h
+++ a/sql/ha_partition.h
@@ -1552,6 +1552,7 @@ class ha_partition :public handler
   */
     const COND *cond_push(const COND *cond) override;
     void cond_pop() override;
+    void clear_top_table_fields() override;
     int info_push(uint info_type, void *info) override;
 
     private:
diff --git b/sql/handler.cc a/sql/handler.cc
index 1af0157783e..eac029fd5ac 100644
--- b/sql/handler.cc
+++ a/sql/handler.cc
@@ -6581,6 +6581,7 @@ int handler::ha_reset()
   cancel_pushed_idx_cond();
   /* Reset information about pushed index conditions */
   cancel_pushed_rowid_filter();
+  clear_top_table_fields();
   if (lookup_handler != this)
   {
     lookup_handler->ha_external_unlock(table->in_use);
diff --git b/sql/handler.h a/sql/handler.h
index f592c635c5d..1fd9a1c6fe0 100644
--- b/sql/handler.h
+++ a/sql/handler.h
@@ -3238,6 +3238,12 @@ class handler :public Sql_alloc
   /** End a batch started with @c start_psi_batch_mode. */
   void end_psi_batch_mode();
 
+  bool set_top_table_fields;
+
+  struct TABLE *top_table;
+  Field **top_table_field;
+  uint top_table_fields;
+
   /* If we have row logging enabled for this table */
   bool row_logging, row_logging_init;
   /* If the row logging should be done in transaction cache */
@@ -3286,6 +3292,8 @@ class handler :public Sql_alloc
     m_psi_batch_mode(PSI_BATCH_MODE_NONE),
     m_psi_numrows(0),
     m_psi_locker(NULL),
+    set_top_table_fields(FALSE), top_table(0),
+    top_table_field(0), top_table_fields(0),
     row_logging(0), row_logging_init(0),
     m_lock_type(F_UNLCK), ha_share(NULL), m_prev_insert_id(0)
   {
@@ -4327,6 +4335,36 @@ class handler :public Sql_alloc
  */
  virtual int info_push(uint info_type, void *info) { return 0; };
 
+ /**
+    This function is used to get correlating of a parent (table/column)
+    and children (table/column). When conditions are pushed down to child
+    table (like child of myisam_merge), child table needs to know about
+    which table/column is my parent for understanding conditions.
+ */
+ virtual int set_top_table_and_fields(TABLE *top_table,
+                                      Field **top_table_field,
+                                      uint top_table_fields)
+ {
+   if (!set_top_table_fields)
+   {
+     set_top_table_fields= TRUE;
+     this->top_table= top_table;
+     this->top_table_field= top_table_field;
+     this->top_table_fields= top_table_fields;
+   }
+   return 0;
+ }
+ virtual void clear_top_table_fields()
+ {
+   if (set_top_table_fields)
+   {
+     set_top_table_fields= FALSE;
+     top_table= NULL;
+     top_table_field= NULL;
+     top_table_fields= 0;
+   }
+ }
+
  /**
    Push down an index condition to the handler.
 
diff --git b/sql/sql_base.cc a/sql/sql_base.cc
index 39fdefbc189..8dd85d3de24 100644
--- b/sql/sql_base.cc
+++ a/sql/sql_base.cc
@@ -1977,11 +1977,13 @@ bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx)
                                    MYF(MY_WME))))
       goto err_lock;
 
+    table_list->intention_table= table;
     error= open_table_from_share(thd, share, &table_list->alias,
                                  HA_OPEN_KEYFILE | HA_TRY_READ_ONLY,
                                  EXTRA_RECORD,
                                  thd->open_options, table, FALSE,
-                                 IF_PARTITIONING(table_list->partition_names,0));
+                                 IF_PARTITIONING(table_list->partition_names,0),
+                                 table_list);
 
     if (unlikely(error))
     {
diff --git b/sql/table.cc a/sql/table.cc
index 9c9d462fe3a..71040129365 100644
--- b/sql/table.cc
+++ a/sql/table.cc
@@ -3868,7 +3868,8 @@ bool copy_keys_from_share(TABLE *outparam, MEM_ROOT *root)
 enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share,
                        const LEX_CSTRING *alias, uint db_stat, uint prgflag,
                        uint ha_open_flags, TABLE *outparam,
-                       bool is_create_table, List<String> *partitions_to_open)
+                       bool is_create_table, List<String> *partitions_to_open,
+                       TABLE_LIST *table_list)
 {
   enum open_frm_error error;
   uint records, i, bitmap_size, bitmap_count;
@@ -3890,6 +3891,7 @@ enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share,
   outparam->s= share;
   outparam->db_stat= db_stat;
   outparam->write_row_record= NULL;
+  outparam->intention_pos_in_table_list= table_list;
 
   if (share->incompatible_version &&
       !(ha_open_flags & (HA_OPEN_FOR_ALTER | HA_OPEN_FOR_REPAIR)))
diff --git b/sql/table.h a/sql/table.h
index f2fad6c19b2..18a5c776434 100644
--- b/sql/table.h
+++ a/sql/table.h
@@ -1289,6 +1289,9 @@ struct TABLE
   /* Table's triggers, 0 if there are no of them */
   Table_triggers_list *triggers;
   TABLE_LIST *pos_in_table_list;/* Element referring to this table */
+  /* This is same as pos_in_table_list, but it is set as soon as possible when
+     TABLE is allocated */
+  TABLE_LIST *intention_pos_in_table_list;
   /* Position in thd->locked_table_list under LOCK TABLES */
   TABLE_LIST *pos_in_locked_tables;
   /* Tables used in DEFAULT and CHECK CONSTRAINT (normally sequence tables) */
@@ -2262,6 +2265,9 @@ struct TABLE_LIST
   /* Index names in a "... JOIN ... USE/IGNORE INDEX ..." clause. */
   List<Index_hint> *index_hints;
   TABLE        *table;                          /* opened table */
+  /* This is same as table, but it is set as soon as possible when
+     TABLE is allocated */
+  TABLE        *intention_table;
   ulonglong         table_id; /* table id (from binlog) for opened table */
   /*
     select_result for derived table to pass it from table creation to table
@@ -3107,7 +3113,8 @@ enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share,
                        const LEX_CSTRING *alias, uint db_stat, uint prgflag,
                        uint ha_open_flags, TABLE *outparam,
                        bool is_create_table,
-                       List<String> *partitions_to_open= NULL);
+                       List<String> *partitions_to_open= NULL,
+                       TABLE_LIST *table_list= NULL);
 bool copy_keys_from_share(TABLE *outparam, MEM_ROOT *root);
 bool fix_session_vcol_expr(THD *thd, Virtual_column_info *vcol);
 bool fix_session_vcol_expr_for_read(THD *thd, Field *field,
diff --git b/storage/spider/ha_spider.cc a/storage/spider/ha_spider.cc
index ce9447a61a9..bbb7434825b 100644
--- b/storage/spider/ha_spider.cc
+++ a/storage/spider/ha_spider.cc
@@ -424,7 +424,15 @@ int ha_spider::open(
     wide_handler->rnd_write_bitmap = rnd_write_bitmap;
     wide_handler->owner = owner;
     if (table_share->tmp_table == NO_TMP_TABLE)
-      wide_handler->top_share = table->s;
+    {
+      TABLE_LIST *top = spider_get_parent_table_list(this);
+      if (top->intention_table)
+      {
+        wide_handler->top_share = top->intention_table->s;
+      } else {
+        wide_handler->top_share = top->table->s;
+      }
+    }
     owner->wide_handler_owner = TRUE;
     memset(wide_handler->ft_discard_bitmap, 0xFF,
       no_bytes_in_map(table->read_set));
@@ -12051,6 +12059,80 @@ bool ha_spider::is_fatal_error(
   DBUG_RETURN(TRUE);
 }
 
+int ha_spider::set_top_table_and_fields(
+  TABLE *top_table,
+  Field **top_table_field,
+  uint top_table_fields
+) {
+  DBUG_ENTER("ha_spider::set_top_table_and_fields");
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+  if (
+    wide_handler->stage == SPD_HND_STAGE_SET_TOP_TABLE_AND_FIELDS &&
+    wide_handler->stage_executor != this)
+  {
+    DBUG_RETURN(0);
+  }
+  wide_handler->stage = SPD_HND_STAGE_SET_TOP_TABLE_AND_FIELDS;
+  wide_handler->stage_executor = this;
+#endif
+  if (!wide_handler->set_top_table_fields)
+  {
+    wide_handler->set_top_table_fields = TRUE;
+    wide_handler->top_table = top_table;
+    wide_handler->top_table_field = top_table_field;
+    wide_handler->top_table_fields = top_table_fields;
+  }
+  DBUG_RETURN(0);
+}
+void ha_spider::clear_top_table_fields()
+{
+  DBUG_ENTER("ha_spider::clear_top_table_fields");
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+  if (
+    wide_handler->stage == SPD_HND_STAGE_CLEAR_TOP_TABLE_FIELDS &&
+    wide_handler->stage_executor != this)
+  {
+    DBUG_VOID_RETURN;
+  }
+  wide_handler->stage = SPD_HND_STAGE_CLEAR_TOP_TABLE_FIELDS;
+  wide_handler->stage_executor = this;
+#endif
+  if (wide_handler->set_top_table_fields)
+  {
+    wide_handler->set_top_table_fields = FALSE;
+    wide_handler->top_table = NULL;
+    wide_handler->top_table_field = NULL;
+    wide_handler->top_table_fields = 0;
+  }
+  DBUG_VOID_RETURN;
+}
+
+Field *ha_spider::get_top_table_field(
+  uint16 field_index
+) {
+  Field *field;
+  DBUG_ENTER("ha_spider::get_top_table_field");
+#ifdef HA_CAN_BULK_ACCESS
+  if (is_bulk_access_clone)
+  {
+    DBUG_RETURN(pt_clone_source_handler->get_top_table_field(field_index));
+  }
+#endif
+  DBUG_PRINT("info",("spider field_index=%u", field_index));
+#ifdef HANDLER_HAS_TOP_TABLE_FIELDS
+  if (wide_handler->set_top_table_fields)
+  {
+    field = wide_handler->top_table->field[field_index];
+  } else {
+#endif
+    field = table->field[field_index];
+#ifdef HANDLER_HAS_TOP_TABLE_FIELDS
+  }
+#endif
+  DBUG_PRINT("info",("spider out field=%p", field));
+  DBUG_RETURN(field);
+}
+
 Field *ha_spider::field_exchange(
   Field *field
 ) {
@@ -12063,9 +12145,22 @@ Field *ha_spider::field_exchange(
 #endif
   DBUG_PRINT("info",("spider in field=%p", field));
   DBUG_PRINT("info",("spider in field->table=%p", field->table));
-  DBUG_PRINT("info",("spider table=%p", table));
-  if (field->table != table)
-    DBUG_RETURN(NULL);
+#ifdef HANDLER_HAS_TOP_TABLE_FIELDS
+  if (wide_handler->set_top_table_fields)
+  {
+    DBUG_PRINT("info",("spider top_table=%p", wide_handler->top_table));
+    if (field->table != wide_handler->top_table)
+      DBUG_RETURN(NULL);
+    if (!(field = wide_handler->top_table_field[field->field_index]))
+      DBUG_RETURN(NULL);
+  } else {
+#endif
+    DBUG_PRINT("info",("spider table=%p", table));
+    if (field->table != table)
+      DBUG_RETURN(NULL);
+#ifdef HANDLER_HAS_TOP_TABLE_FIELDS
+  }
+#endif
   DBUG_PRINT("info",("spider out field=%p", field));
   DBUG_RETURN(field);
 }
@@ -12418,6 +12513,16 @@ TABLE *ha_spider::get_table()
   DBUG_RETURN(table);
 }
 
+TABLE *ha_spider::get_top_table()
+{
+  DBUG_ENTER("ha_spider::get_top_table");
+#ifdef HANDLER_HAS_TOP_TABLE_FIELDS
+  if (set_top_table_fields)
+    DBUG_RETURN(top_table);
+#endif
+  DBUG_RETURN(table);
+}
+
 void ha_spider::set_ft_discard_bitmap()
 {
   DBUG_ENTER("ha_spider::set_ft_discard_bitmap");
diff --git b/storage/spider/ha_spider.h a/storage/spider/ha_spider.h
index db184baf682..13bbacf0b0e 100644
--- b/storage/spider/ha_spider.h
+++ a/storage/spider/ha_spider.h
@@ -855,6 +855,15 @@ class ha_spider: public handler
     int error_num,
     uint flags
   );
+  int set_top_table_and_fields(
+    TABLE *top_table,
+    Field **top_table_field,
+    uint top_table_fields
+  );
+  void clear_top_table_fields();
+  Field *get_top_table_field(
+    uint16 field_index
+  );
   Field *field_exchange(
     Field *field
   );
@@ -870,6 +879,7 @@ class ha_spider: public handler
   void return_record_by_parent();
 #endif
   TABLE *get_table();
+  TABLE *get_top_table();
   void set_ft_discard_bitmap();
   void set_searched_bitmap();
   void set_clone_searched_bitmap();
diff --git b/storage/spider/spd_include.h a/storage/spider/spd_include.h
index 31c75b68d6e..0fe1a45dd27 100644
--- b/storage/spider/spd_include.h
+++ a/storage/spider/spd_include.h
@@ -726,6 +726,8 @@ typedef struct st_spider_wide_handler
   List<Item>         *direct_update_fields;
   List<Item>         *direct_update_values;
 #endif
+  TABLE              *top_table;
+  Field              **top_table_field;
   TABLE_SHARE        *top_share;
   enum thr_lock_type lock_type;
   uchar              lock_table_type;
@@ -771,6 +773,7 @@ typedef struct st_spider_wide_handler
   bool               write_can_replace;
   bool               insert_with_update;
   bool               cond_check;
+  bool               set_top_table_fields;
 #if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
 #ifdef HANDLER_HAS_DIRECT_UPDATE_ROWS
   bool               hs_increment;
diff --git b/storage/spider/spd_table.cc a/storage/spider/spd_table.cc
index 1607dd07902..94b1ca543ad 100644
--- b/storage/spider/spd_table.cc
+++ a/storage/spider/spd_table.cc
@@ -8743,9 +8743,28 @@ void spider_free_tmp_dbton_handler(
 TABLE_LIST *spider_get_parent_table_list(
   ha_spider *spider
 ) {
-  TABLE *table = spider->get_table();
+  TABLE *table = spider->get_top_table();
+  TABLE_LIST *current, *parent;
   DBUG_ENTER("spider_get_parent_table_list");
-  DBUG_RETURN(table->pos_in_table_list);
+  DBUG_PRINT("info",("spider table=%p", table));
+  if (table->pos_in_table_list)
+  {
+    current = table->pos_in_table_list;
+  } else {
+    current = table->intention_pos_in_table_list;
+  }
+#ifdef HANDLER_HAS_TOP_TABLE_FIELDS
+  if (!spider->set_top_table_fields)
+  {
+#endif
+    while ((parent = current->parent_l))
+    {
+      current = parent;
+    }
+#ifdef HANDLER_HAS_TOP_TABLE_FIELDS
+  }
+#endif
+  DBUG_RETURN(current);
 }
 
 List<Index_hint> *spider_get_index_hints(
@@ -9068,7 +9087,7 @@ bool spider_check_direct_order_limit(
   longlong select_limit;
   longlong offset_limit;
   DBUG_ENTER("spider_check_direct_order_limit");
-  if (spider_check_index_merge(spider->get_table(),
+  if (spider_check_index_merge(spider->get_top_table(),
     spider_get_select_lex(spider)))
   {
     DBUG_PRINT("info",("spider set use_index_merge"));
@@ -9324,9 +9343,22 @@ Field *spider_field_exchange(
 #endif
   DBUG_PRINT("info",("spider in field=%p", field));
   DBUG_PRINT("info",("spider in field->table=%p", field->table));
+#ifdef HANDLER_HAS_TOP_TABLE_FIELDS
+  if (handler->set_top_table_fields)
+  {
+    DBUG_PRINT("info",("spider top_table=%p", handler->top_table));
+    if (field->table != handler->top_table)
+      DBUG_RETURN(NULL);
+    if (!(field = handler->top_table_field[field->field_index]))
+      DBUG_RETURN(NULL);
+  } else {
+#endif
     DBUG_PRINT("info",("spider table=%p", handler->get_table()));
     if (field->table != handler->get_table())
       DBUG_RETURN(NULL);
+#ifdef HANDLER_HAS_TOP_TABLE_FIELDS
+  }
+#endif
   DBUG_PRINT("info",("spider out field=%p", field));
   DBUG_RETURN(field);
 }
