From: Ole John Aske Date: March 17 2011 12:25pm Subject: bzr push into mysql-5.1-telco-7.0-spj-scan-vs-scan branch (ole.john.aske:3447 to 3448) List-Archive: http://lists.mysql.com/commits/133205 Message-Id: <20110317122557.0F3F8223@fimafeng09.norway.sun.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 3448 Ole John Aske 2011-03-17 SPJ refactoring of handler interface extensions used for retrospecting pushed joins. Intention is to clean up code, improve readability, *and* prepare for later enhanced EXPLAIN of pushed joins which should also include info about the parent/child relations. Renamed member variables an methods in order to clearify theirs usage: - handler::is_parent_of_pushed_join() -> handler::number_of_pushed_joins() - handler::member_of_pushed_join() -> handler::root_of_pushed_join() - ha_ndbcluster::m_pushed_join -> ha_ndbcluster::m_pushed_join_member Introduced: int ha_ndbcluster::m_pushed_join_operation: Enumerates the pushed query operation which relates to this handler instance static const uint ha_ndbcluster::PUSHED_ROOT= 0: Enumerates the pushed operation being the root in the pushed query. Mainly for improved readability of the code. handler::parent_of_pushed_join(): Returns the pushed parent of this handler instance. NULL if operation is unpushed, or if this is the root of the pushed query. modified: sql/ha_ndbcluster.cc sql/ha_ndbcluster.h sql/handler.h sql/sql_select.cc storage/ndb/include/ndbapi/NdbQueryBuilder.hpp storage/ndb/src/ndbapi/NdbQueryBuilder.cpp 3447 Ole John Aske 2011-03-17 [merge] Merge from telco mainline -> SPJ-scan-scan removed: mysql-test/suite/rpl_ndb/t/rpl_ndb_conflict_d_d.inc mysql-test/suite/rpl_ndb/t/rpl_ndb_conflict_d_u.inc mysql-test/suite/rpl_ndb/t/rpl_ndb_conflict_i_i.inc mysql-test/suite/rpl_ndb/t/rpl_ndb_conflict_init.inc mysql-test/suite/rpl_ndb/t/rpl_ndb_conflict_u_d.inc mysql-test/suite/rpl_ndb/t/rpl_ndb_conflict_u_u.inc storage/ndb/test/sql/ storage/ndb/test/sql/BANK.sql storage/ndb/test/sql/T1.sql storage/ndb/test/sql/test_create_drop.pl storage/ndb/test/sql/test_range_bounds.pl storage/ndb/tools/clean-links.sh storage/ndb/tools/make-errors.pl storage/ndb/tools/make-links.sh added: mysql-test/suite/binlog/r/binlog_incident_ignore.result mysql-test/suite/binlog/t/binlog_incident_ignore-master.opt mysql-test/suite/binlog/t/binlog_incident_ignore.test mysql-test/suite/rpl/r/rpl_skip_incident.result mysql-test/suite/rpl/t/rpl_skip_incident-master.opt mysql-test/suite/rpl/t/rpl_skip_incident-slave.opt mysql-test/suite/rpl/t/rpl_skip_incident.test mysql-test/suite/rpl_ndb/r/rpl_ndb_ignore_db.result mysql-test/suite/rpl_ndb/r/rpl_ndb_skip_gap_event.result mysql-test/suite/rpl_ndb/t/rpl_ndb_ignore_db-master.opt mysql-test/suite/rpl_ndb/t/rpl_ndb_ignore_db.test mysql-test/suite/rpl_ndb/t/rpl_ndb_skip_gap_event-slave.opt mysql-test/suite/rpl_ndb/t/rpl_ndb_skip_gap_event.test renamed: mysql-test/include/ndb_conflict_info.inc => mysql-test/suite/rpl_ndb/t/ndb_conflict_info.inc mysql-test/include/ndb_conflict_info_init.inc => mysql-test/suite/rpl_ndb/t/ndb_conflict_info_init.inc modified: mysql-test/suite/ndb/r/ndb_basic.result mysql-test/suite/ndb_binlog/r/ndb_binlog_ignore_db.result mysql-test/suite/ndb_binlog/t/ndb_binlog_ignore_db-master.opt mysql-test/suite/ndb_binlog/t/ndb_binlog_ignore_db.test mysql-test/suite/rpl_ndb/ndb_master-slave.inc mysql-test/suite/rpl_ndb/r/rpl_ndb_gap_event.result mysql-test/suite/rpl_ndb/t/rpl_ndb_conflict_1.inc mysql-test/suite/rpl_ndb/t/rpl_ndb_gap_event.test sql/ha_ndbcluster.cc sql/ha_ndbcluster.h sql/log.cc sql/log_event.cc sql/log_event.h sql/rpl_injector.h storage/ndb/docs/doxygen/Doxyfile.mgmapi storage/ndb/docs/doxygen/Doxyfile.ndbapi storage/ndb/include/ndb_config.h.in storage/ndb/ndb_configure.cmake storage/ndb/src/common/portlib/NdbCondition.c storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp storage/ndb/src/kernel/blocks/pgman.cpp storage/ndb/src/kernel/blocks/tsman.cpp === modified file 'sql/ha_ndbcluster.cc' --- a/sql/ha_ndbcluster.cc 2011-03-17 08:17:18 +0000 +++ b/sql/ha_ndbcluster.cc 2011-03-17 12:25:32 +0000 @@ -780,12 +780,13 @@ ha_ndbcluster::make_pushed_join(ndb_push DBUG_PRINT("info", ("Created pushed join with %d child operations", push_cnt-1)); - m_pushed_join= new ndb_pushed_join(context.plan(), + m_pushed_join_member= new ndb_pushed_join( + context.plan(), context.join_scope(), fld_refs, referred_fields, query_def); - if (unlikely (m_pushed_join == NULL)) + if (unlikely (m_pushed_join_member == NULL)) { builder->destroy(); DBUG_RETURN(HA_ERR_OUT_OF_MEM); @@ -793,10 +794,11 @@ ha_ndbcluster::make_pushed_join(ndb_push for (uint i = 0; i < push_cnt; i++) { - const TABLE* const tab= m_pushed_join->get_table(i); + const TABLE* const tab= m_pushed_join_member->get_table(i); DBUG_ASSERT(tab->file->ht == ht); - ha_ndbcluster* handler= static_cast(tab->file); - handler->m_pushed_join_member= this; + ha_ndbcluster* child= static_cast(tab->file); + child->m_pushed_join_member= m_pushed_join_member; + child->m_pushed_join_operation= i; } builder->destroy(); @@ -899,13 +901,13 @@ bool ha_ndbcluster::check_if_pushable(const NdbQueryOperationTypeWrapper& type, uint idx, bool needSorted) const { - if (m_pushed_join == NULL) + if (m_pushed_join_operation != PUSHED_ROOT) { return FALSE; } const NdbQueryOperationDef* const root_operation= - m_pushed_join->get_query_def().getQueryOperation(0U); + m_pushed_join_member->get_query_def().getQueryOperation(PUSHED_ROOT); const NdbQueryOperationTypeWrapper& query_def_type= root_operation->getType(); @@ -980,9 +982,9 @@ ha_ndbcluster::check_if_pushable(const N // There may be referrences to Field values from tables outside the scope of // our pushed join which are supplied as paramValues(). // If any of these are NULL values, join can't be pushed - for (uint i= 0; i < m_pushed_join->get_field_referrences_count(); i++) + for (uint i= 0; i < m_pushed_join_member->get_field_referrences_count(); i++) { - Field* field= m_pushed_join->get_field_ref(i); + Field* field= m_pushed_join_member->get_field_ref(i); if (field->is_real_null()) { DBUG_PRINT("info", @@ -1013,34 +1015,36 @@ int ha_ndbcluster::create_pushed_join(NdbQueryParamValue* paramValues, uint paramOffs) { DBUG_ENTER("create_pushed_join"); + DBUG_ASSERT(m_pushed_join_operation == PUSHED_ROOT); DBUG_PRINT("info", ("executing chain of %d pushed joins." " First table is %s, accessed as %s.", - m_pushed_join->get_operation_count(), - m_pushed_join->get_table(0)->alias, + m_pushed_join_member->get_operation_count(), + m_pushed_join_member->get_table(0)->alias, NdbQueryOperationDef::getTypeName( - m_pushed_join->get_query_def().getQueryOperation(0U)->getType())) + m_pushed_join_member->get_query_def().getQueryOperation(PUSHED_ROOT)->getType())) ); // There may be referrences to Field values from tables outside the scope of // our pushed join: These are expected to be supplied as paramValues() - for (uint i= 0; i < m_pushed_join->get_field_referrences_count(); i++) + for (uint i= 0; i < m_pushed_join_member->get_field_referrences_count(); i++) { - Field* field= m_pushed_join->get_field_ref(i); + Field* field= m_pushed_join_member->get_field_ref(i); DBUG_ASSERT(!field->is_real_null()); // Checked by ::check_if_pushable() paramValues[paramOffs+i]= NdbQueryParamValue(field->ptr, false); } - NdbQuery* const query= m_thd_ndb->trans->createQuery(&m_pushed_join->get_query_def(), paramValues); + NdbQuery* const query= m_thd_ndb->trans->createQuery(&m_pushed_join_member->get_query_def(), paramValues); if (unlikely(query==NULL)) ERR_RETURN(m_thd_ndb->trans->getNdbError()); // Bind to instantiated NdbQueryOperations. - for (uint i= 0; i < m_pushed_join->get_operation_count(); i++) + for (uint i= 0; i < m_pushed_join_member->get_operation_count(); i++) { - const TABLE* const tab= m_pushed_join->get_table(i); + const TABLE* const tab= m_pushed_join_member->get_table(i); ha_ndbcluster* handler= static_cast(tab->file); + DBUG_ASSERT(handler->m_pushed_join_operation==i); NdbQueryOperation* const op= query->getQueryOperation(i); handler->m_pushed_operation= op; @@ -1066,23 +1070,50 @@ ha_ndbcluster::create_pushed_join(NdbQue /** - * Check if this table access operation is part if a pushed join operation + * Check if this table access operation is part of a pushed join operation * which is actively executing. */ bool ha_ndbcluster::check_is_pushed() const { - return (m_pushed_join_member && m_pushed_join_member->m_active_query); -} + if (m_pushed_join_member == NULL) + return false; + handler *root= m_pushed_join_member->get_table(PUSHED_ROOT)->file; + return (static_cast(root)->m_active_query); +} uint -ha_ndbcluster::is_parent_of_pushed_join() const +ha_ndbcluster::number_of_pushed_joins() const { - if (!m_pushed_join) + if (m_pushed_join_member == NULL) return 0; else - return m_pushed_join->get_operation_count(); + return m_pushed_join_member->get_operation_count(); +} + +const TABLE* +ha_ndbcluster::root_of_pushed_join() const +{ + if (m_pushed_join_member == NULL) + return NULL; + else + return m_pushed_join_member->get_table(PUSHED_ROOT); +} + +const TABLE* +ha_ndbcluster::parent_of_pushed_join() const +{ + if (m_pushed_join_operation > PUSHED_ROOT) + { + DBUG_ASSERT(m_pushed_join_member!=NULL); + uint parent_ix= m_pushed_join_member + ->get_query_def().getQueryOperation(m_pushed_join_operation) + ->getParentOperation(0) + ->getQueryOperationIx(); + return m_pushed_join_member->get_table(parent_ix); + } + return NULL; } bool @@ -1121,8 +1152,8 @@ ha_ndbcluster::test_push_flag(enum ha_pu * column values (paramValues), the pushed join has dependencies * in addition to the root operation itself. */ - if (m_pushed_join && - m_pushed_join->get_field_referrences_count() > 0) // Childs has field refs + if (m_pushed_join_operation==PUSHED_ROOT && + m_pushed_join_member->get_field_referrences_count() > 0) // Childs has field refs { DBUG_RETURN(true); } @@ -1130,13 +1161,13 @@ ha_ndbcluster::test_push_flag(enum ha_pu case HA_PUSH_NO_ORDERED_INDEX: { - if (!m_pushed_join) + if (m_pushed_join_operation != PUSHED_ROOT) { DBUG_RETURN(true); } - const NdbQueryDef& query_def = m_pushed_join->get_query_def(); + const NdbQueryDef& query_def = m_pushed_join_member->get_query_def(); const NdbQueryOperationTypeWrapper& root_type= - query_def.getQueryOperation(0U)->getType(); + query_def.getQueryOperation(PUSHED_ROOT)->getType(); /** * Primary key/ unique key lookup is always 'ordered' wrt. itself. @@ -3701,7 +3732,7 @@ int ha_ndbcluster::pk_read(const uchar * } else { - if (m_pushed_join != NULL) + if (m_pushed_join_operation == PUSHED_ROOT) { m_thd_ndb->m_pushed_queries_dropped++; } @@ -4113,7 +4144,7 @@ int ha_ndbcluster::unique_index_read(con } else { - if (m_pushed_join != NULL) + if (m_pushed_join_operation == PUSHED_ROOT) { m_thd_ndb->m_pushed_queries_dropped++; } @@ -4341,9 +4372,8 @@ int ha_ndbcluster::index_next_pushed(uch DBUG_RETURN(index_next(buf)); } - DBUG_ASSERT(m_pushed_join_member && m_active_query==NULL); // Child of a pushed join - DBUG_ASSERT(m_pushed_join_member->m_pushed_join); - DBUG_ASSERT(m_pushed_join_member->m_active_query); + DBUG_ASSERT(m_pushed_join_operation>PUSHED_ROOT); // Child of a pushed join + DBUG_ASSERT(m_active_query==NULL); int res = fetch_next_pushed(); if (res == NdbQuery::NextResult_gotRow) @@ -4676,7 +4706,7 @@ int ha_ndbcluster::ordered_index_scan(co DBUG_RETURN(error); NdbQuery* const query= m_active_query; - if (sorted && query->getQueryOperation(0U) + if (sorted && query->getQueryOperation(PUSHED_ROOT) ->setOrdering(descending ? NdbQueryOptions::ScanOrdering_descending : NdbQueryOptions::ScanOrdering_ascending)) { @@ -4698,7 +4728,7 @@ int ha_ndbcluster::ordered_index_scan(co } else // if (check_if_pushable(NdbQueryOperationDef::OrderedIndexScan)) { - if (m_pushed_join != NULL) + if (m_pushed_join_operation == PUSHED_ROOT) { m_thd_ndb->m_pushed_queries_dropped++; } @@ -4805,7 +4835,7 @@ int ha_ndbcluster::full_table_scan(const if (m_use_partition_pruning && m_user_defined_partitioning) { - DBUG_ASSERT(!m_pushed_join); + DBUG_ASSERT(m_pushed_join_operation != PUSHED_ROOT); part_spec.start_part= 0; part_spec.end_part= m_part_info->get_tot_partitions() - 1; prune_partition_set(table, &part_spec); @@ -4873,7 +4903,7 @@ int ha_ndbcluster::full_table_scan(const } else // if (check_if_pushable(NdbQueryOperationDef::TableScan)) { - if (m_pushed_join != NULL) + if (m_pushed_join_operation == PUSHED_ROOT) { m_thd_ndb->m_pushed_queries_dropped++; } @@ -6826,7 +6856,7 @@ int ha_ndbcluster::read_range_first_to_b if (m_use_partition_pruning) { - DBUG_ASSERT(!m_pushed_join); + DBUG_ASSERT(!m_pushed_join_operation != PUSHED_ROOT); get_partition_set(table, buf, active_index, start_key, &part_spec); DBUG_PRINT("info", ("part_spec.start_part: %u part_spec.end_part: %u", part_spec.start_part, part_spec.end_part)); @@ -7454,12 +7484,12 @@ int ha_ndbcluster::reset() m_cond->cond_clear(); } DBUG_ASSERT(m_active_query == NULL); - if (m_pushed_join) + if (m_pushed_join_operation==PUSHED_ROOT) // Root of pushed query { - delete m_pushed_join; - m_pushed_join= NULL; + delete m_pushed_join_member; } m_pushed_join_member= NULL; + m_pushed_join_operation= -1; m_disable_pushed_join= FALSE; /* @@ -10712,8 +10742,6 @@ ha_ndbcluster::ha_ndbcluster(handlerton handler(hton, table_arg), m_thd_ndb(NULL), m_active_cursor(NULL), - m_active_query(NULL), - m_pushed_operation(NULL), m_table(NULL), m_ndb_record(0), m_ndb_hidden_key_record(0), @@ -10745,9 +10773,11 @@ ha_ndbcluster::ha_ndbcluster(handlerton m_blobs_buffer_size(0), m_dupkey((uint) -1), m_autoincrement_prefetch(DEFAULT_AUTO_PREFETCH), - m_pushed_join(NULL), m_pushed_join_member(NULL), + m_pushed_join_operation(-1), m_disable_pushed_join(FALSE), + m_active_query(NULL), + m_pushed_operation(NULL), m_cond(NULL), m_multi_cursor(NULL) { @@ -10802,11 +10832,11 @@ ha_ndbcluster::~ha_ndbcluster() } DBUG_PRINT("info", ("Deleting pushed joins")); DBUG_ASSERT(m_active_query == NULL); - if (m_pushed_join) + if (m_pushed_join_operation==PUSHED_ROOT) { - delete m_pushed_join; - m_pushed_join= NULL; + delete m_pushed_join_member; } + m_pushed_join_member= NULL; DBUG_VOID_RETURN; } @@ -13791,8 +13821,9 @@ ha_ndbcluster::read_multi_range_first(KE (cur_index_type == UNIQUE_INDEX && has_null_in_unique_index(active_index) && null_value_index_search(ranges, ranges+range_count, buffer)) - || (m_pushed_join && !m_disable_pushed_join && - !m_pushed_join->get_query_def().isScanQuery()) + || (m_pushed_join_operation==PUSHED_ROOT && + !m_disable_pushed_join && + !m_pushed_join_member->get_query_def().isScanQuery()) || m_delete_cannot_batch || m_update_cannot_batch) { DBUG_PRINT("info", ("read_multi_range not possible, falling back to default handler implementation")); @@ -13891,7 +13922,8 @@ ha_ndbcluster::read_multi_range_first(KE } r->range_flag&= ~(uint)SKIP_RANGE; - if ((m_pushed_join && m_pushed_join->get_query_def().isScanQuery()) || // Pushed joins currently restricted to ordered range scan in mrr + if ((m_pushed_join_operation==PUSHED_ROOT && + m_pushed_join_member->get_query_def().isScanQuery()) || // Pushed joins restricted to ordered range scan in mrr read_multi_needs_scan(cur_index_type, key_info, r)) { if (!trans) @@ -13942,14 +13974,14 @@ ha_ndbcluster::read_multi_range_first(KE NdbQuery* const query= m_active_query; if (sorted && - query->getQueryOperation(0U)->setOrdering(NdbQueryOptions::ScanOrdering_ascending)) + query->getQueryOperation(PUSHED_ROOT)->setOrdering(NdbQueryOptions::ScanOrdering_ascending)) ERR_RETURN(query->getNdbError()); } } // check_if_pushable() else if (!m_multi_cursor) { - if (m_pushed_join != NULL) + if (m_pushed_join_operation == PUSHED_ROOT) { m_thd_ndb->m_pushed_queries_dropped++; } @@ -14050,9 +14082,9 @@ ha_ndbcluster::read_multi_range_first(KE r->range_flag&= ~(uint)UNIQUE_RANGE; num_scan_ranges++; } - else // if ((m_pushed_join && m_pushed_join->get_query_def().isScanQuery()) ||... + else // if ((...PUSHED_ROOT && m_pushed_join->get_query_def().isScanQuery()) ||... { - if (m_pushed_join != NULL) + if (m_pushed_join_operation == PUSHED_ROOT) { m_thd_ndb->m_pushed_queries_dropped++; } @@ -14102,9 +14134,9 @@ ha_ndbcluster::read_multi_range_first(KE // 'Pushable codepath' is incomplete and expected not // to be produced as make_join_pushed() handle // AT_MULTI_UNIQUE_KEY as non-pushable - if (m_pushed_join && + if (m_pushed_join_operation==PUSHED_ROOT && !m_disable_pushed_join && - !m_pushed_join->get_query_def().isScanQuery()) + !m_pushed_join_member->get_query_def().isScanQuery()) { DBUG_ASSERT(false); // Incomplete code, should not be executed DBUG_ASSERT(lm == NdbOperation::LM_CommittedRead); @@ -14116,7 +14148,7 @@ ha_ndbcluster::read_multi_range_first(KE } else { - if (m_pushed_join) + if (m_pushed_join_operation == PUSHED_ROOT) { DBUG_PRINT("info", ("Cannot push join due to incomplete implementation.")); m_thd_ndb->m_pushed_queries_dropped++; @@ -14137,7 +14169,7 @@ ha_ndbcluster::read_multi_range_first(KE buffer->end_of_used_area= row_buf; if (m_active_query != NULL && - m_pushed_join->get_query_def().isScanQuery()) + m_pushed_join_member->get_query_def().isScanQuery()) { m_thd_ndb->m_scan_count++; if (sorted) === modified file 'sql/ha_ndbcluster.h' --- a/sql/ha_ndbcluster.h 2011-03-17 08:17:18 +0000 +++ b/sql/ha_ndbcluster.h 2011-03-17 12:25:32 +0000 @@ -597,10 +597,9 @@ static void set_tabname(const char *path bool test_push_flag(enum ha_push_flag flag) const; - uint is_parent_of_pushed_join() const; - const handler* member_of_pushed_join() const - { return m_pushed_join_member; - } + uint number_of_pushed_joins() const; + const TABLE* root_of_pushed_join() const; + const TABLE* parent_of_pushed_join() const; int index_read_pushed(uchar *buf, const uchar *key, key_part_map keypart_map); @@ -853,8 +852,6 @@ private: Thd_ndb *m_thd_ndb; NdbScanOperation *m_active_cursor; - NdbQuery* m_active_query; - NdbQueryOperation* m_pushed_operation; const NdbDictionary::Table *m_table; /* @@ -940,9 +937,14 @@ private: ha_rows m_autoincrement_prefetch; // Joins pushed to NDB. - const class ndb_pushed_join *m_pushed_join; // Pushed join def. if I am parent - const ha_ndbcluster *m_pushed_join_member; // Parent handler instance - bool m_disable_pushed_join; // Execution allowed? + const class ndb_pushed_join + *m_pushed_join_member; // Pushed join def. I am member of + int m_pushed_join_operation; // Op. id. in above pushed join + static const uint PUSHED_ROOT= 0; // Op. id. if I'm root + + bool m_disable_pushed_join; // Pushed execution allowed? + NdbQuery* m_active_query; // Pushed query instance executing + NdbQueryOperation* m_pushed_operation; // Pushed operation instance ha_ndbcluster_cond *m_cond; bool m_disable_multi_read; === modified file 'sql/handler.h' --- a/sql/handler.h 2011-01-04 14:50:54 +0000 +++ b/sql/handler.h 2011-03-17 12:25:32 +0000 @@ -1890,17 +1890,24 @@ public: virtual void cond_pop() { return; }; /** - Reports #tables included in pushed join starting from - this handler instance. + Reports #tables included in pushed join which this + handler instance is part of. ==0 -> Not pushed */ - virtual uint is_parent_of_pushed_join() const + virtual uint number_of_pushed_joins() const { return 0; } /** - Is this handler instance part of a pushed join sequence - having the returned handler instance as parent? + If this handler instance is part of a pushed join sequence + returned TABLE instance being root of the pushed query? */ - virtual const handler* member_of_pushed_join() const + virtual const TABLE* root_of_pushed_join() const + { return NULL; } + + /** + If this handler instance is a child in a pushed join sequence + returned TABLE instance being my parent? + */ + virtual const TABLE* parent_of_pushed_join() const { return NULL; } virtual bool test_push_flag(enum ha_push_flag flag) const === modified file 'sql/sql_select.cc' --- a/sql/sql_select.cc 2011-02-23 13:09:10 +0000 +++ b/sql/sql_select.cc 2011-03-17 12:25:32 +0000 @@ -1670,12 +1670,14 @@ make_pushed_join(THD *thd, JOIN *join) { JOIN_TAB *tab=join->join_tab+i; - if (tab->table->file->member_of_pushed_join()) + uint pushed_joins= tab->table->file->number_of_pushed_joins(); + if (pushed_joins > 0) { - uint pushed_joins= tab->table->file->is_parent_of_pushed_join(); - active_pushed_joins += pushed_joins; - - if (pushed_joins == 0) + if (tab->table->file->root_of_pushed_join() == tab->table) + { + active_pushed_joins += pushed_joins; + } + else { // Is child of a pushed join operation: // Replace 'read_key' access with its linked counterpart @@ -1694,7 +1696,7 @@ make_pushed_join(THD *thd, JOIN *join) * or write to a temp. table later being filesorted. */ if (join->const_tables < join->tables && - join->join_tab[join->const_tables].table->file->is_parent_of_pushed_join()) + join->join_tab[join->const_tables].table->file->number_of_pushed_joins() > 0) { const handler *ha=join->join_tab[join->const_tables].table->file; @@ -17198,8 +17200,8 @@ static void select_describe(JOIN *join, } else { - const handler* pushed_join= table->file->member_of_pushed_join(); - if (pushed_join) + const TABLE* pushed_root= table->file->root_of_pushed_join(); + if (pushed_root) { char buf[64]; int len; @@ -17207,16 +17209,17 @@ static void select_describe(JOIN *join, for (JOIN_TAB* prev= join->join_tab; prev <= tab; prev++) { - if (prev->table->file->is_parent_of_pushed_join() > 0) + const TABLE* prev_root= prev->table->file->root_of_pushed_join(); + if (prev_root == prev->table) { pushed_id++; - if (prev->table->file->member_of_pushed_join() == pushed_join) + if (prev_root == pushed_root) break; } } - uint pushed_count= tab->table->file->is_parent_of_pushed_join(); - if (pushed_count > 0) + if (pushed_root == table) { + uint pushed_count= tab->table->file->number_of_pushed_joins(); len= my_snprintf(buf, sizeof(buf)-1, "; Parent of %d pushed join@%d", pushed_count, pushed_id); === modified file 'storage/ndb/include/ndbapi/NdbQueryBuilder.hpp' --- a/storage/ndb/include/ndbapi/NdbQueryBuilder.hpp 2011-02-11 13:12:09 +0000 +++ b/storage/ndb/include/ndbapi/NdbQueryBuilder.hpp 2011-03-17 12:25:32 +0000 @@ -223,6 +223,11 @@ public: static const char* getTypeName(Type type); + /** + * Get the ordinal position of this operation within the QueryDef. + */ + Uint32 getQueryOperationIx() const; + Uint32 getNoOfParentOperations() const; const NdbQueryOperationDef* getParentOperation(Uint32 i) const; === modified file 'storage/ndb/src/ndbapi/NdbQueryBuilder.cpp' --- a/storage/ndb/src/ndbapi/NdbQueryBuilder.cpp 2011-02-11 13:12:09 +0000 +++ b/storage/ndb/src/ndbapi/NdbQueryBuilder.cpp 2011-03-17 12:25:32 +0000 @@ -616,6 +616,11 @@ NdbQueryIndexScanOperationDefImpl& getIm } +Uint32 +NdbQueryOperationDef::getQueryOperationIx() const +{ + return ::getImpl(*this).getQueryOperationIx(); +} Uint32 NdbQueryOperationDef::getNoOfParentOperations() const No bundle (reason: useless for push emails).