From 1d060ec093f18f897ebeeb053bff9c38114f3389 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 4 Oct 2004 11:45:07 +0200 Subject: [PATCH 1/7] To allow compilation on Tru64, the MySQL code should not mess with the system-reserved (and system-defined) '_REENTRANT' CPP identifier. Especially, it must not be "undefine"d, because the Tru64 compiler needs it if threads are enabled. include/my_pthread.h: On Tru64, '_REENTRANT' is set by the compiler when the "-pthread" option is given, and it must be set when the system's 'pthread.h' is included (or else a '#error' is activated). So it must not be undef'ed, and it should not be def'ed either, as it is a system-reserved CPP identifier with which we should not mess anyway - it is risky to use it! Build on all platforms was checked privately, change caused no errors! --- include/my_pthread.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/my_pthread.h b/include/my_pthread.h index 602a4439575..cd0cf49a891 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -234,7 +234,6 @@ extern int my_sigwait(const sigset_t *set,int *sig); #include #undef sigwait #endif -#undef _REENTRANT /* Fix if _REENTRANT is in pthread.h */ #include #ifndef _REENTRANT #define _REENTRANT From 76c9e10ebd554b4b11b193b7cefcfc2101ec1fb2 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 4 Oct 2004 17:13:31 +0400 Subject: [PATCH 2/7] Made TIMESTAMP NULL columns without explicit DEFAULT value to be always treated as DEFAULT NULL columns (independently from their position in table). (still to be discussed with Monty, Brian, Trudy et al. before push) mysql-test/r/type_timestamp.result: Update test after making TIMESTAMP NULL columns without explicit DEFAULT value to be always treated as DEFAULT NULL columns (independently from their position in table). mysql-test/t/type_timestamp.test: Update test after making TIMESTAMP NULL columns without explicit DEFAULT value to be always treated as DEFAULT NULL columns (independently from their position in table). sql/sql_parse.cc: add_field_to_list(): made TIMESTAMP NULL columns without explicit DEFAULT value to be always treated as DEFAULT NULL columns (independently from their position in table). This also simplifies code a bit. --- mysql-test/r/type_timestamp.result | 19 ++++++++++++++++-- mysql-test/t/type_timestamp.test | 15 +++++++++++++-- sql/sql_parse.cc | 31 ++++++++++++++++-------------- 3 files changed, 47 insertions(+), 18 deletions(-) diff --git a/mysql-test/r/type_timestamp.result b/mysql-test/r/type_timestamp.result index a823049634f..6a7cecdd460 100644 --- a/mysql-test/r/type_timestamp.result +++ b/mysql-test/r/type_timestamp.result @@ -369,7 +369,7 @@ create table t1 (a timestamp null, b timestamp null); show create table t1; Table Create Table t1 CREATE TABLE `t1` ( - `a` timestamp NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, + `a` timestamp NULL default NULL, `b` timestamp NULL default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 insert into t1 values (NULL, NULL); @@ -378,7 +378,22 @@ insert into t1 values (); select * from t1; a b NULL NULL -2001-09-09 04:46:57 NULL +NULL NULL +drop table t1; +create table t1 (a timestamp null default current_timestamp on update current_timestamp, b timestamp null); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` timestamp NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, + `b` timestamp NULL default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (NULL, NULL); +SET TIMESTAMP=1000000018; +insert into t1 values (); +select * from t1; +a b +NULL NULL +2001-09-09 04:46:58 NULL drop table t1; create table t1 (a timestamp null default null, b timestamp null default '2003-01-01 00:00:00'); show create table t1; diff --git a/mysql-test/t/type_timestamp.test b/mysql-test/t/type_timestamp.test index 7c1258785b0..3f0b41d7221 100644 --- a/mysql-test/t/type_timestamp.test +++ b/mysql-test/t/type_timestamp.test @@ -236,9 +236,10 @@ drop table t1; # # Test for TIMESTAMP columns which are able to store NULLs -# (Auto-set property should work for them and NULL values -# should be OK as default values) # + +# Unlike for default TIMESTAMP fields we don't interpret first field +# in this table as TIMESTAMP with DEFAULT NOW() ON UPDATE NOW() properties. create table t1 (a timestamp null, b timestamp null); show create table t1; insert into t1 values (NULL, NULL); @@ -247,6 +248,16 @@ insert into t1 values (); select * from t1; drop table t1; +# But explicit auto-set properties still should be OK. +create table t1 (a timestamp null default current_timestamp on update current_timestamp, b timestamp null); +show create table t1; +insert into t1 values (NULL, NULL); +SET TIMESTAMP=1000000018; +insert into t1 values (); +select * from t1; +drop table t1; + +# It is also OK to specify NULL as default explicitly for such fields. create table t1 (a timestamp null default null, b timestamp null default '2003-01-01 00:00:00'); show create table t1; insert into t1 values (NULL, NULL); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e8441c05609..34cad1b062d 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4142,12 +4142,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, } else if (default_value->type() == Item::NULL_ITEM) { - /* - TIMESTAMP type should be able to distingush non-specified default - value and default value NULL later. - */ - if (type != FIELD_TYPE_TIMESTAMP) - default_value= 0; + default_value= 0; if ((type_modifier & (NOT_NULL_FLAG | AUTO_INCREMENT_FLAG)) == NOT_NULL_FLAG) { @@ -4357,19 +4352,27 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, else new_field->unireg_check= (on_update_value?Field::TIMESTAMP_UN_FIELD: Field::NONE); - - if (default_value->type() == Item::NULL_ITEM) - new_field->def= 0; } else { - /* - We are setting TIMESTAMP_OLD_FIELD here only temporary, we will - replace this value by TIMESTAMP_DNUN_FIELD or NONE later when + /* + If we have default TIMESTAMP NOT NULL column without explicit DEFAULT + or ON UPDATE values then for the sake of compatiblity we should treat + this column as having DEFAULT NOW() ON UPDATE NOW() (when we don't + have another TIMESTAMP column with auto-set option before this one) + or DEFAULT 0 (in other cases). + So here we are setting TIMESTAMP_OLD_FIELD only temporary, and will + replace this value by TIMESTAMP_DNUN_FIELD or NONE later when information about all TIMESTAMP fields in table will be availiable. + + If we have TIMESTAMP NULL column without explicit DEFAULT value + we treat it as having DEFAULT NULL attribute. */ - new_field->unireg_check= on_update_value?Field::TIMESTAMP_UN_FIELD: - Field::TIMESTAMP_OLD_FIELD; + new_field->unireg_check= on_update_value ? + Field::TIMESTAMP_UN_FIELD : + (new_field->flags & NOT_NULL_FLAG ? + Field::TIMESTAMP_OLD_FIELD: + Field::NONE); } break; case FIELD_TYPE_DATE: // Old date type From ae14bc779e6d3443abd02d386623c47fc8651ebd Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 4 Oct 2004 18:58:06 +0400 Subject: [PATCH 3/7] Comments to the single-select optimization algorithm. --- sql/item_subselect.cc | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 3dbf4eae55b..bb2bb6319a9 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -638,6 +638,8 @@ String *Item_in_subselect::val_str(String *str) } +/* Rewrite a single-column IN/ALL/ANY subselect. */ + Item_subselect::trans_res Item_in_subselect::single_value_transformer(JOIN *join, Comp_creator *func) @@ -656,12 +658,27 @@ Item_in_subselect::single_value_transformer(JOIN *join, if (arena->is_stmt_prepare()) thd->set_n_backup_item_arena(arena, &backup); + /* + Check that the right part of the subselect contains no more than one + column. E.g. in SELECT 1 IN (SELECT * ..) the right part is (SELECT * ...) + */ if (select_lex->item_list.elements > 1) { my_error(ER_OPERAND_COLUMNS, MYF(0), 1); goto err; } + /* + If this is an ALL/ANY single-value subselect, try to rewrite it with + a MIN/MAX subselect. We can do that if a possible NULL result of the + subselect can be ignored. + E.g. SELECT * FROM t1 WHERE b > ANY (SELECT a FROM t2) can be rewritten + with SELECT * FROM t1 WHERE b > (SELECT MAX(a) FROM t2). + We can't check that this optimization is safe if it's not a top-level + item of the WHERE clause (e.g. because the WHERE clause can contain IS + NULL/IS NOT NULL functions). If so, we rewrite ALL/ANY with NOT EXISTS + later in this method. + */ if ((abort_on_null || (upper_not && upper_not->top_level())) && !select_lex->master_unit()->uncacheable && !func->eqne_op()) { @@ -764,7 +781,13 @@ Item_in_subselect::single_value_transformer(JOIN *join, Item *item; item= (Item*) select_lex->item_list.head(); - + /* + Add the left part of a subselect to a WHERE or HAVING clause of + the right part, e.g. SELECT 1 IN (SELECT a FROM t1) => + SELECT Item_in_optimizer(1, SELECT a FROM t1 WHERE a=1) + HAVING is used only if the right part contains a SUM function, a GROUP + BY or a HAVING clause. + */ if (join->having || select_lex->with_sum_func || select_lex->group_list.elements) { From ef40ba04e8f64c1bf6a3347ff70d7fea7ca6eba1 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 4 Oct 2004 19:48:41 +0300 Subject: [PATCH 4/7] lock0lock.c: Fix compiler warning innobase/lock/lock0lock.c: Fix compiler warning --- innobase/lock/lock0lock.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c index e91be39a0cd..e6d478070b0 100644 --- a/innobase/lock/lock0lock.c +++ b/innobase/lock/lock0lock.c @@ -365,6 +365,15 @@ lock_deadlock_recursive( ulint* cost); /* in/out: number of calculation steps thus far: if this exceeds LOCK_MAX_N_STEPS_... we return TRUE */ +/************************************************************************* +Gets the nth bit of a record lock. */ +UNIV_INLINE +ibool +lock_rec_get_nth_bit( +/*=================*/ + /* out: TRUE if bit set */ + lock_t* lock, /* in: record lock */ + ulint i); /* in: index of the bit */ #define lock_mutex_enter_kernel() mutex_enter(&kernel_mutex) #define lock_mutex_exit_kernel() mutex_exit(&kernel_mutex) From 9d2c186c5175419d579631d5bc5b1156f339126f Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 5 Oct 2004 06:49:11 +0000 Subject: [PATCH 5/7] bumped up version to 3.5.2 removed staus flag --- configure.in | 4 ++-- ndb/src/common/util/version.c | 21 ++++++++++++++------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/configure.in b/configure.in index 39151205533..97ecb90177d 100644 --- a/configure.in +++ b/configure.in @@ -15,8 +15,8 @@ SHARED_LIB_VERSION=14:0:0 # ndb version NDB_VERSION_MAJOR=3 NDB_VERSION_MINOR=5 -NDB_VERSION_BUILD=1 -NDB_VERSION_STATUS=beta +NDB_VERSION_BUILD=2 +NDB_VERSION_STATUS=0 # Set all version vars based on $VERSION. How do we do this more elegant ? # Remember that regexps needs to quote [ and ] since this is run through m4 diff --git a/ndb/src/common/util/version.c b/ndb/src/common/util/version.c index 937ca1d32dd..ae699beca14 100644 --- a/ndb/src/common/util/version.c +++ b/ndb/src/common/util/version.c @@ -37,13 +37,19 @@ Uint32 makeVersion(Uint32 major, Uint32 minor, Uint32 build) { char * getVersionString(Uint32 version, char * status) { char buff[100]; - snprintf(buff, sizeof(buff), - "Version %d.%d.%d (%s)", - getMajor(version), - getMinor(version), - getBuild(version), - status); - + if (status) + snprintf(buff, sizeof(buff), + "Version %d.%d.%d (%s)", + getMajor(version), + getMinor(version), + getBuild(version), + status); + else + snprintf(buff, sizeof(buff), + "Version %d.%d.%d", + getMajor(version), + getMinor(version), + getBuild(version)); return strdup(buff); } @@ -63,6 +69,7 @@ struct NdbUpGradeCompatible { #ifndef TEST_VERSION struct NdbUpGradeCompatible ndbCompatibleTable_full[] = { + { MAKE_VERSION(3,5,2), MAKE_VERSION(3,5,1), UG_Exact }, { 0, 0, UG_Null } }; From 2f3212910f3486799ae30d83aeba1cdbdc7c992a Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 5 Oct 2004 07:48:51 +0000 Subject: [PATCH 6/7] last try didnt work --- configure.in | 2 +- ndb/src/common/util/version.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index 97ecb90177d..2df5155ecbb 100644 --- a/configure.in +++ b/configure.in @@ -16,7 +16,7 @@ SHARED_LIB_VERSION=14:0:0 NDB_VERSION_MAJOR=3 NDB_VERSION_MINOR=5 NDB_VERSION_BUILD=2 -NDB_VERSION_STATUS=0 +NDB_VERSION_STATUS="" # Set all version vars based on $VERSION. How do we do this more elegant ? # Remember that regexps needs to quote [ and ] since this is run through m4 diff --git a/ndb/src/common/util/version.c b/ndb/src/common/util/version.c index ae699beca14..b8408c7f201 100644 --- a/ndb/src/common/util/version.c +++ b/ndb/src/common/util/version.c @@ -37,7 +37,7 @@ Uint32 makeVersion(Uint32 major, Uint32 minor, Uint32 build) { char * getVersionString(Uint32 version, char * status) { char buff[100]; - if (status) + if (status && status[0] != 0) snprintf(buff, sizeof(buff), "Version %d.%d.%d (%s)", getMajor(version), From ab5c7a9e0e57fdfd75be02959165eb4555841d6a Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 5 Oct 2004 10:04:09 +0000 Subject: [PATCH 7/7] moved code out of DBUG_ASSERT --- sql/ha_ndbcluster.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index d03a088775f..57232778d48 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -1206,7 +1206,8 @@ inline int ha_ndbcluster::next_result(byte *buf) { if (execute_commit(this,trans) != 0) DBUG_RETURN(ndb_err(trans)); - DBUG_ASSERT(trans->restart() == 0); + int res= trans->restart(); + DBUG_ASSERT(res == 0); } ops_pending= 0; } @@ -1644,7 +1645,8 @@ int ha_ndbcluster::write_row(byte *record) no_uncommitted_rows_execute_failure(); DBUG_RETURN(ndb_err(trans)); } - DBUG_ASSERT(trans->restart() == 0); + int res= trans->restart(); + DBUG_ASSERT(res == 0); } } if ((has_auto_increment) && (skip_auto_increment)) @@ -2281,7 +2283,8 @@ int ha_ndbcluster::rnd_init(bool scan) { if (!scan) DBUG_RETURN(1); - DBUG_ASSERT(cursor->restart() == 0); + int res= cursor->restart(); + DBUG_ASSERT(res == 0); } index_init(table->primary_key); DBUG_RETURN(0);