From: Ole John Aske Date: May 2 2012 12:33pm Subject: bzr push into mysql-trunk branch (ole.john.aske:3881 to 3882) WL#5940 List-Archive: http://lists.mysql.com/commits/143705 Message-Id: <20120502123330.6E771242@fimafeng09.norway.sun.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 3882 Ole John Aske 2012-05-02 WL#5940 changes according to 'round #2' comments from Evgeny P. This is intended to be the last set of changes related to these comments. The handler extension ::test_push_flag() has now been removed. The two remaining HA_PUSH_-flags related to this extension has been made obsolete by: - HA_PUSH_BLOCK_CONST_TABLE is replaced with the 'test_flag' HA_BLOCK_CONST_TABLE. Furthermore it was identified that usage of this flag was obsolete at one of the places it was used. (As 'system' table optimization is not possible for handlers with non-EXACT statistics) - HA_PUSH_MULTIPLE_DEPENDENCY has been entirely removed as this covered a corner case with questionable advantage of being pushed. Previous changes to join_no_more_records() has been reverted. modified: sql/ha_ndbcluster.cc sql/ha_ndbcluster.h sql/handler.h sql/sql_executor.cc sql/sql_optimizer.cc sql/sql_select.cc 3881 Ole John Aske 2012-04-27 Added fix to pushed join JSON explain to WL#5940 branch modified: sql/opt_explain_json.cc === modified file 'sql/ha_ndbcluster.cc' --- a/sql/ha_ndbcluster.cc 2012-04-25 11:41:51 +0000 +++ b/sql/ha_ndbcluster.cc 2012-05-02 12:33:07 +0000 @@ -12344,6 +12344,21 @@ ulonglong ha_ndbcluster::table_flags(voi */ if (thd->variables.binlog_format == BINLOG_FORMAT_STMT) f= (f | HA_BINLOG_STMT_CAPABLE) & ~HA_HAS_OWN_BINLOGGING; + + /** + * To maximize join pushability we want const-table optimization + * blocked if table is possibly pushable, that is: + * - Variable 'ndb_join_pushdown= on' + * - Lock mode is LM_CommittedRead + * - There are no BLOBs in this table + */ + if (THDVAR(thd, join_pushdown) && + get_ndb_lock_mode(m_lock.type) == NdbOperation::LM_CommittedRead && + !(table_share && table_share->blob_fields > 0)) + { + f= f | HA_BLOCK_CONST_TABLE; + } + return f; } @@ -14503,57 +14518,6 @@ ha_ndbcluster::parent_of_pushed_join() c return NULL; } -bool -ha_ndbcluster::test_push_flag(enum ha_push_flag flag) const -{ - DBUG_ENTER("test_push_flag"); - switch (flag) { - case HA_PUSH_BLOCK_CONST_TABLE: - { - /** - * We don't support join push down if... - * - not LM_CommittedRead - * - uses blobs - */ - THD *thd= current_thd; - if (unlikely(!THDVAR(thd, join_pushdown))) - DBUG_RETURN(false); - - if (table->read_set != NULL && uses_blob_value(table->read_set)) - { - DBUG_RETURN(false); - } - - NdbOperation::LockMode lm= get_ndb_lock_mode(m_lock.type); - - if (lm != NdbOperation::LM_CommittedRead) - { - DBUG_RETURN(false); - } - - DBUG_RETURN(true); - } - case HA_PUSH_MULTIPLE_DEPENDENCY: - /** - * If any child operation within this pushed join refer - * column values (paramValues), the pushed join has dependencies - * in addition to the root operation itself. - */ - if (m_pushed_join_operation==PUSHED_ROOT && - m_pushed_join_member->get_field_referrences_count() > 0) // Childs has field refs - { - DBUG_RETURN(true); - } - DBUG_RETURN(false); - - default: - DBUG_ASSERT(0); - DBUG_RETURN(false); - } - DBUG_RETURN(false); -} - - /** @param[in] comment table comment defined by user === modified file 'sql/ha_ndbcluster.h' --- a/sql/ha_ndbcluster.h 2012-03-30 06:52:25 +0000 +++ b/sql/ha_ndbcluster.h 2012-05-02 12:33:07 +0000 @@ -415,8 +415,6 @@ static void set_tabname(const char *path bool maybe_pushable_join(const char*& reason) const; int assign_pushed_join(const ndb_pushed_join* pushed_join); - bool test_push_flag(enum ha_push_flag flag) const; - uint number_of_pushed_joins() const; const TABLE* root_of_pushed_join() const; const TABLE* parent_of_pushed_join() const; === modified file 'sql/handler.h' --- a/sql/handler.h 2012-03-30 06:52:25 +0000 +++ b/sql/handler.h 2012-05-02 12:33:07 +0000 @@ -189,6 +189,12 @@ enum enum_alter_inplace_result { */ #define HA_READ_BEFORE_WRITE_REMOVAL (LL(1) << 38) +/* + The handler don't want accesses to this table to + be const-table optimized +*/ +#define HA_BLOCK_CONST_TABLE (LL(1) << 39) + /* bits in index_flags(index_number) for what you can do with index */ #define HA_READ_NEXT 1 /* TODO really use this flag */ #define HA_READ_PREV 2 /* supports ::index_prev */ @@ -410,21 +416,6 @@ namespace AQP { class Join_plan; }; -/* Flag used for for test_push_flag() */ -enum ha_push_flag { - - /* Handler want to block const table optimization */ - HA_PUSH_BLOCK_CONST_TABLE - - /* Handler reports a pushed join as having multiple dependencies - if its results does not only depend on the root operation: - ie. results from some child operations does not only depend - on results from the root operation and/or other child operations - within this pushed join - */ - ,HA_PUSH_MULTIPLE_DEPENDENCY -}; - /** struct xid_t is binary compatible with the XID structure as in the X/Open CAE Specification, Distributed Transaction Processing: @@ -2464,11 +2455,6 @@ public: virtual const TABLE* parent_of_pushed_join() const { return NULL; } - virtual bool test_push_flag(enum ha_push_flag flag) const - { - return FALSE; - } - virtual int index_read_pushed(uchar * buf, const uchar * key, key_part_map keypart_map) { return HA_ERR_WRONG_COMMAND; } === modified file 'sql/sql_executor.cc' --- a/sql/sql_executor.cc 2012-03-30 06:52:25 +0000 +++ b/sql/sql_executor.cc 2012-05-02 12:33:07 +0000 @@ -3115,19 +3115,8 @@ join_read_last_key(JOIN_TAB *tab) /* ARGSUSED */ static int -join_no_more_records(READ_RECORD *info) +join_no_more_records(READ_RECORD *info __attribute__((unused))) { - /** - * When a pushed join completes, and its results did not only depend on - * the key of this root operations: ('tab->ref.key_buff') - * Results from this pushed join can not be reused - * for later queries having the same root key. - * (ref: join_read_key(), join_read_const() & join_read_system() - */ - if (info->table->file->test_push_flag(HA_PUSH_MULTIPLE_DEPENDENCY)) - { - info->table->status= STATUS_GARBAGE; - } return -1; } === modified file 'sql/sql_optimizer.cc' --- a/sql/sql_optimizer.cc 2012-04-25 11:52:33 +0000 +++ b/sql/sql_optimizer.cc 2012-05-02 12:33:07 +0000 @@ -3050,14 +3050,6 @@ make_join_statistics(JOIN *join, TABLE_L */ extract_method= extract_no_table; } - else if (table->file->test_push_flag(HA_PUSH_BLOCK_CONST_TABLE)) - { - /* - Handler implements pushed joins, and prefer const tables to - be pushed together with rest of the pushed query. - */ - extract_method= extract_no_table; - } else if (*s->on_expr_ref) { /* s is the only inner table of an outer join, extract empty tables */ @@ -3241,7 +3233,7 @@ const_table_extraction_done: !tl->in_outer_join_nest() && // 2 !(tl->embedding && tl->embedding->sj_on_expr) && // 3 !(*s->on_expr_ref && (*s->on_expr_ref)->is_expensive()) &&// 4 - !table->file->test_push_flag(HA_PUSH_BLOCK_CONST_TABLE)) // 5 + !(table->file->ha_table_flags() & HA_BLOCK_CONST_TABLE)) // 5 { if (table->key_info[key].flags & HA_NOSAME) { === modified file 'sql/sql_select.cc' --- a/sql/sql_select.cc 2012-04-18 10:46:39 +0000 +++ b/sql/sql_select.cc 2012-05-02 12:33:07 +0000 @@ -1510,7 +1510,7 @@ bool create_ref_for_key(JOIN *join, JOIN j->ref.null_ref_key= null_ref_key; } else if (keyuse_uses_no_tables && - !table->file->test_push_flag(HA_PUSH_BLOCK_CONST_TABLE)) + !(table->file->ha_table_flags() & HA_BLOCK_CONST_TABLE)) { /* This happen if we are using a constant expression in the ON part No bundle (reason: useless for push emails).