Below is the list of changes that have just been committed into a local
5.1 repository of mikron. When mikron does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet
1.1852 05/07/18 13:31:02 mronstrom@stripped +99 -0
Patch for push of wl1354 Partitioning
sql/sql_partition.cc
1.1 05/07/18 13:30:38 mronstrom@stripped +3117 -0
Patch for push of wl1354 Partitioning
sql/ha_partition.h
1.1 05/07/18 13:30:38 mronstrom@stripped +916 -0
Patch for push of wl1354 Partitioning
sql/sql_partition.cc
1.0 05/07/18 13:30:38 mronstrom@stripped +0 -0
BitKeeper file /Users/mikron/wl1354_push/sql/sql_partition.cc
sql/ha_partition.h
1.0 05/07/18 13:30:38 mronstrom@stripped +0 -0
BitKeeper file /Users/mikron/wl1354_push/sql/ha_partition.h
sql/ha_partition.cc
1.1 05/07/18 13:30:37 mronstrom@stripped +3162 -0
Patch for push of wl1354 Partitioning
sql/ha_partition.cc
1.0 05/07/18 13:30:37 mronstrom@stripped +0 -0
BitKeeper file /Users/mikron/wl1354_push/sql/ha_partition.cc
mysql-test/t/partition_range.test
1.1 05/07/18 13:30:36 mronstrom@stripped +560 -0
Patch for push of wl1354 Partitioning
mysql-test/t/partition_range.test
1.0 05/07/18 13:30:36 mronstrom@stripped +0 -0
BitKeeper file /Users/mikron/wl1354_push/mysql-test/t/partition_range.test
mysql-test/t/partition_order.test
1.1 05/07/18 13:30:35 mronstrom@stripped +828 -0
Patch for push of wl1354 Partitioning
mysql-test/t/partition_list.test
1.1 05/07/18 13:30:35 mronstrom@stripped +316 -0
Patch for push of wl1354 Partitioning
mysql-test/t/partition_order.test
1.0 05/07/18 13:30:35 mronstrom@stripped +0 -0
BitKeeper file /Users/mikron/wl1354_push/mysql-test/t/partition_order.test
mysql-test/t/partition_list.test
1.0 05/07/18 13:30:35 mronstrom@stripped +0 -0
BitKeeper file /Users/mikron/wl1354_push/mysql-test/t/partition_list.test
mysql-test/t/partition_hash.test
1.1 05/07/18 13:30:34 mronstrom@stripped +77 -0
Patch for push of wl1354 Partitioning
mysql-test/t/partition.test
1.1 05/07/18 13:30:34 mronstrom@stripped +494 -0
Patch for push of wl1354 Partitioning
mysql-test/t/partition_hash.test
1.0 05/07/18 13:30:34 mronstrom@stripped +0 -0
BitKeeper file /Users/mikron/wl1354_push/mysql-test/t/partition_hash.test
mysql-test/t/partition.test
1.0 05/07/18 13:30:34 mronstrom@stripped +0 -0
BitKeeper file /Users/mikron/wl1354_push/mysql-test/t/partition.test
mysql-test/t/ndb_partition_range.test
1.1 05/07/18 13:30:33 mronstrom@stripped +86 -0
Patch for push of wl1354 Partitioning
mysql-test/t/ndb_partition_range.test
1.0 05/07/18 13:30:33 mronstrom@stripped +0 -0
BitKeeper file /Users/mikron/wl1354_push/mysql-test/t/ndb_partition_range.test
mysql-test/t/ndb_partition_key.test
1.1 05/07/18 13:30:32 mronstrom@stripped +58 -0
Patch for push of wl1354 Partitioning
mysql-test/r/partition_range.result
1.1 05/07/18 13:30:32 mronstrom@stripped +455 -0
Patch for push of wl1354 Partitioning
mysql-test/t/ndb_partition_key.test
1.0 05/07/18 13:30:32 mronstrom@stripped +0 -0
BitKeeper file /Users/mikron/wl1354_push/mysql-test/t/ndb_partition_key.test
mysql-test/r/partition_range.result
1.0 05/07/18 13:30:32 mronstrom@stripped +0 -0
BitKeeper file /Users/mikron/wl1354_push/mysql-test/r/partition_range.result
mysql-test/r/partition_order.result
1.1 05/07/18 13:30:31 mronstrom@stripped +733 -0
Patch for push of wl1354 Partitioning
mysql-test/r/partition_order.result
1.0 05/07/18 13:30:31 mronstrom@stripped +0 -0
BitKeeper file /Users/mikron/wl1354_push/mysql-test/r/partition_order.result
mysql-test/r/partition_list.result
1.1 05/07/18 13:30:30 mronstrom@stripped +342 -0
Patch for push of wl1354 Partitioning
mysql-test/r/partition_hash.result
1.1 05/07/18 13:30:30 mronstrom@stripped +66 -0
Patch for push of wl1354 Partitioning
mysql-test/r/partition_list.result
1.0 05/07/18 13:30:30 mronstrom@stripped +0 -0
BitKeeper file /Users/mikron/wl1354_push/mysql-test/r/partition_list.result
mysql-test/r/partition_hash.result
1.0 05/07/18 13:30:30 mronstrom@stripped +0 -0
BitKeeper file /Users/mikron/wl1354_push/mysql-test/r/partition_hash.result
mysql-test/r/partition.result
1.1 05/07/18 13:30:29 mronstrom@stripped +355 -0
Patch for push of wl1354 Partitioning
mysql-test/r/partition.result
1.0 05/07/18 13:30:29 mronstrom@stripped +0 -0
BitKeeper file /Users/mikron/wl1354_push/mysql-test/r/partition.result
mysql-test/r/ndb_partition_range.result
1.1 05/07/18 13:30:28 mronstrom@stripped +105 -0
Patch for push of wl1354 Partitioning
mysql-test/r/ndb_partition_range.result
1.0 05/07/18 13:30:28 mronstrom@stripped +0 -0
BitKeeper file /Users/mikron/wl1354_push/mysql-test/r/ndb_partition_range.result
mysql-test/r/ndb_partition_key.result
1.1 05/07/18 13:30:27 mronstrom@stripped +71 -0
Patch for push of wl1354 Partitioning
mysql-test/r/ndb_partition_key.result
1.0 05/07/18 13:30:27 mronstrom@stripped +0 -0
BitKeeper file /Users/mikron/wl1354_push/mysql-test/r/ndb_partition_key.result
mysql-test/r/have_partition.require
1.1 05/07/18 13:30:26 mronstrom@stripped +2 -0
Patch for push of wl1354 Partitioning
mysql-test/r/have_partition.require
1.0 05/07/18 13:30:26 mronstrom@stripped +0 -0
BitKeeper file /Users/mikron/wl1354_push/mysql-test/r/have_partition.require
mysql-test/include/have_partition.inc
1.1 05/07/18 13:30:25 mronstrom@stripped +4 -0
Patch for push of wl1354 Partitioning
config/ac-macros/ha_partition.m4
1.1 05/07/18 13:30:25 mronstrom@stripped +30 -0
Patch for push of wl1354 Partitioning
mysql-test/include/have_partition.inc
1.0 05/07/18 13:30:25 mronstrom@stripped +0 -0
BitKeeper file /Users/mikron/wl1354_push/mysql-test/include/have_partition.inc
config/ac-macros/ha_partition.m4
1.0 05/07/18 13:30:25 mronstrom@stripped +0 -0
BitKeeper file /Users/mikron/wl1354_push/config/ac-macros/ha_partition.m4
storage/ndb/tools/restore/Restore.cpp
1.27 05/07/18 13:30:24 mronstrom@stripped +2 -1
Patch for push of wl1354 Partitioning
storage/ndb/test/run-test/README
1.3 05/07/18 13:30:24 mronstrom@stripped +2 -2
Patch for push of wl1354 Partitioning
storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp
1.35 05/07/18 13:30:24 mronstrom@stripped +3 -1
Patch for push of wl1354 Partitioning
storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp
1.86 05/07/18 13:30:24 mronstrom@stripped +63 -29
Patch for push of wl1354 Partitioning
storage/ndb/src/ndbapi/NdbDictionary.cpp
1.38 05/07/18 13:30:24 mronstrom@stripped +20 -2
Patch for push of wl1354 Partitioning
storage/ndb/src/ndbapi/NdbBlob.cpp
1.26 05/07/18 13:30:24 mronstrom@stripped +33 -3
Patch for push of wl1354 Partitioning
storage/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp
1.9 05/07/18 13:30:23 mronstrom@stripped +1 -0
Patch for push of wl1354 Partitioning
storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp
1.19 05/07/18 13:30:23 mronstrom@stripped +5 -5
Patch for push of wl1354 Partitioning
storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp
1.25 05/07/18 13:30:23 mronstrom@stripped +1 -1
Patch for push of wl1354 Partitioning
storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
1.83 05/07/18 13:30:23 mronstrom@stripped +51 -7
Patch for push of wl1354 Partitioning
storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp
1.30 05/07/18 13:30:23 mronstrom@stripped +7 -0
Patch for push of wl1354 Partitioning
storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
1.71 05/07/18 13:30:22 mronstrom@stripped +2 -2
Patch for push of wl1354 Partitioning
storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp
1.16 05/07/18 13:30:22 mronstrom@stripped +1 -1
Patch for push of wl1354 Partitioning
storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
1.35 05/07/18 13:30:21 mronstrom@stripped +1 -1
Patch for push of wl1354 Partitioning
storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
1.30 05/07/18 13:30:21 mronstrom@stripped +183 -150
Patch for push of wl1354 Partitioning
storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp
1.10 05/07/18 13:30:21 mronstrom@stripped +5 -2
Patch for push of wl1354 Partitioning
storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp
1.13 05/07/18 13:30:21 mronstrom@stripped +4 -0
Patch for push of wl1354 Partitioning
storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
1.46 05/07/18 13:30:21 mronstrom@stripped +57 -17
Patch for push of wl1354 Partitioning
storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp
1.54 05/07/18 13:30:20 mronstrom@stripped +1 -1
Patch for push of wl1354 Partitioning
storage/ndb/src/kernel/blocks/dbacc/DbaccInit.cpp
1.15 05/07/18 13:30:20 mronstrom@stripped +1 -1
Patch for push of wl1354 Partitioning
storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp
1.21 05/07/18 13:30:19 mronstrom@stripped +1 -1
Patch for push of wl1354 Partitioning
storage/ndb/src/common/debugger/signaldata/CreateFragmentation.cpp
1.4 05/07/18 13:30:19 mronstrom@stripped +0 -1
Patch for push of wl1354 Partitioning
storage/ndb/include/ndbapi/NdbDictionary.hpp
1.51 05/07/18 13:30:19 mronstrom@stripped +15 -1
Patch for push of wl1354 Partitioning
storage/ndb/include/kernel/signaldata/FireTrigOrd.hpp
1.3 05/07/18 13:30:19 mronstrom@stripped +4 -3
Patch for push of wl1354 Partitioning
storage/ndb/include/kernel/signaldata/DictTabInfo.hpp
1.19 05/07/18 13:30:19 mronstrom@stripped +6 -1
Patch for push of wl1354 Partitioning
storage/ndb/include/kernel/signaldata/CreateFragmentation.hpp
1.4 05/07/18 13:30:19 mronstrom@stripped +6 -6
Patch for push of wl1354 Partitioning
storage/ndb/include/kernel/ndb_limits.h
1.18 05/07/18 13:30:19 mronstrom@stripped +1 -0
Patch for push of wl1354 Partitioning
storage/ndb/include/kernel/GlobalSignalNumbers.h
1.9 05/07/18 13:30:18 mronstrom@stripped +1 -1
Patch for push of wl1354 Partitioning
storage/ndb/include/kernel/AttributeHeader.hpp
1.9 05/07/18 13:30:18 mronstrom@stripped +2 -2
Patch for push of wl1354 Partitioning
sql/unireg.h
1.40 05/07/18 13:30:17 mronstrom@stripped +1 -0
Patch for push of wl1354 Partitioning
sql/unireg.cc
1.62 05/07/18 13:30:17 mronstrom@stripped +38 -20
Patch for push of wl1354 Partitioning
sql/tztime.cc
1.25 05/07/18 13:30:17 mronstrom@stripped +5 -5
Patch for push of wl1354 Partitioning
sql/table.h
1.103 05/07/18 13:30:17 mronstrom@stripped +7 -0
Patch for push of wl1354 Partitioning
sql/table.cc
1.173 05/07/18 13:30:17 mronstrom@stripped +38 -6
Patch for push of wl1354 Partitioning
sql/sql_yacc.yy
1.397 05/07/18 13:30:17 mronstrom@stripped +448 -10
Patch for push of wl1354 Partitioning
sql/sql_update.cc
1.165 05/07/18 13:30:16 mronstrom@stripped +8 -3
Patch for push of wl1354 Partitioning
sql/sql_table.cc
1.255 05/07/18 13:30:16 mronstrom@stripped +127 -7
Patch for push of wl1354 Partitioning
sql/sql_show.cc
1.254 05/07/18 13:30:16 mronstrom@stripped +28 -6
Patch for push of wl1354 Partitioning
sql/sql_select.h
1.93 05/07/18 13:30:16 mronstrom@stripped +1 -0
Patch for push of wl1354 Partitioning
sql/sql_select.cc
1.349 05/07/18 13:30:15 mronstrom@stripped +48 -19
Patch for push of wl1354 Partitioning
sql/sql_lex.h
1.188 05/07/18 13:30:15 mronstrom@stripped +3 -0
Patch for push of wl1354 Partitioning
sql/sql_lex.cc
1.154 05/07/18 13:30:15 mronstrom@stripped +1 -0
Patch for push of wl1354 Partitioning
sql/sql_help.cc
1.48 05/07/18 13:30:15 mronstrom@stripped +2 -2
Patch for push of wl1354 Partitioning
sql/sql_handler.cc
1.73 05/07/18 13:30:15 mronstrom@stripped +3 -3
Patch for push of wl1354 Partitioning
sql/sql_base.cc
1.260 05/07/18 13:30:14 mronstrom@stripped +40 -1
Patch for push of wl1354 Partitioning
sql/sql_acl.cc
1.149 05/07/18 13:30:14 mronstrom@stripped +5 -5
Patch for push of wl1354 Partitioning
sql/sp.cc
1.83 05/07/18 13:30:14 mronstrom@stripped +2 -2
Patch for push of wl1354 Partitioning
sql/share/errmsg.txt
1.40 05/07/18 13:30:14 mronstrom@stripped +78 -0
Patch for push of wl1354 Partitioning
sql/set_var.cc
1.124 05/07/18 13:30:13 mronstrom@stripped +1 -0
Patch for push of wl1354 Partitioning
sql/records.cc
1.41 05/07/18 13:30:13 mronstrom@stripped +68 -0
Patch for push of wl1354 Partitioning
sql/opt_sum.cc
1.45 05/07/18 13:30:13 mronstrom@stripped +2 -2
Patch for push of wl1354 Partitioning
sql/opt_range.cc
1.175 05/07/18 13:30:13 mronstrom@stripped +26 -17
Patch for push of wl1354 Partitioning
sql/mysqld.cc
1.468 05/07/18 13:30:12 mronstrom@stripped +18 -0
Patch for push of wl1354 Partitioning
sql/mysql_priv.h
1.317 05/07/18 13:30:12 mronstrom@stripped +18 -1
Patch for push of wl1354 Partitioning
sql/lex.h
1.138 05/07/18 13:30:12 mronstrom@stripped +13 -0
Patch for push of wl1354 Partitioning
sql/key.cc
1.35 05/07/18 13:30:12 mronstrom@stripped +83 -0
Patch for push of wl1354 Partitioning
sql/item_subselect.cc
1.114 05/07/18 13:30:11 mronstrom@stripped +2 -2
Patch for push of wl1354 Partitioning
sql/handler.h
1.148 05/07/18 13:30:11 mronstrom@stripped +245 -4
Patch for push of wl1354 Partitioning
sql/handler.cc
1.179 05/07/18 13:30:11 mronstrom@stripped +75 -20
Patch for push of wl1354 Partitioning
sql/ha_ndbcluster.h
1.89 05/07/18 13:30:11 mronstrom@stripped +24 -7
Patch for push of wl1354 Partitioning
sql/ha_ndbcluster.cc
1.196 05/07/18 13:30:11 mronstrom@stripped +383 -152
Patch for push of wl1354 Partitioning
sql/ha_innodb.h
1.98 05/07/18 13:30:10 mronstrom@stripped +1 -1
Patch for push of wl1354 Partitioning
sql/ha_innodb.cc
1.220 05/07/18 13:30:10 mronstrom@stripped +3 -2
Patch for push of wl1354 Partitioning
sql/ha_federated.h
1.14 05/07/18 13:30:10 mronstrom@stripped +1 -1
Patch for push of wl1354 Partitioning
sql/ha_federated.cc
1.31 05/07/18 13:30:10 mronstrom@stripped +1 -1
Patch for push of wl1354 Partitioning
sql/ha_berkeley.h
1.71 05/07/18 13:30:10 mronstrom@stripped +2 -2
Patch for push of wl1354 Partitioning
sql/ha_berkeley.cc
1.152 05/07/18 13:30:10 mronstrom@stripped +4 -4
Patch for push of wl1354 Partitioning
sql/field.h
1.165 05/07/18 13:30:09 mronstrom@stripped +16 -3
Patch for push of wl1354 Partitioning
sql/field.cc
1.277 05/07/18 13:30:09 mronstrom@stripped +39 -4
Patch for push of wl1354 Partitioning
sql/Makefile.am
1.112 05/07/18 13:30:09 mronstrom@stripped +2 -1
Patch for push of wl1354 Partitioning
mysys/queues.c
1.16 05/07/18 13:30:08 mronstrom@stripped +388 -12
Patch for push of wl1354 Partitioning
mysys/my_bitmap.c
1.34 05/07/18 13:30:08 mronstrom@stripped +14 -22
Patch for push of wl1354 Partitioning
mysys/Makefile.am
1.66 05/07/18 13:30:08 mronstrom@stripped +3 -0
Patch for push of wl1354 Partitioning
include/queues.h
1.12 05/07/18 13:30:08 mronstrom@stripped +3 -0
Patch for push of wl1354 Partitioning
include/mysql_com.h
1.101 05/07/18 13:30:07 mronstrom@stripped +2 -0
Patch for push of wl1354 Partitioning
include/my_global.h
1.97 05/07/18 13:30:07 mronstrom@stripped +88 -0
Patch for push of wl1354 Partitioning
include/my_base.h
1.71 05/07/18 13:30:07 mronstrom@stripped +1 -0
Patch for push of wl1354 Partitioning
configure.in
1.281 05/07/18 13:30:07 mronstrom@stripped +1 -0
Patch for push of wl1354 Partitioning
config/ac-macros/ha_ndbcluster.m4
1.7 05/07/18 13:30:07 mronstrom@stripped +2 -1
Patch for push of wl1354 Partitioning
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: mronstrom
# Host: c-7008e253.1238-1-64736c10.cust.bredbandsbolaget.se
# Root: /Users/mikron/wl1354_push
--- 1.280/configure.in 2005-07-15 15:08:26 +02:00
+++ 1.281/configure.in 2005-07-18 13:30:07 +02:00
@@ -2437,6 +2437,7 @@
MYSQL_CHECK_BLACKHOLEDB
MYSQL_CHECK_NDBCLUSTER
MYSQL_CHECK_FEDERATED
+MYSQL_CHECK_PARTITIONDB
# If we have threads generate some library functions and test programs
sql_server_dirs=
--- 1.70/include/my_base.h 2005-06-24 19:34:50 +02:00
+++ 1.71/include/my_base.h 2005-07-18 13:30:07 +02:00
@@ -388,6 +388,7 @@
#define EQ_RANGE 32
#define NULL_RANGE 64
#define GEOM_FLAG 128
+#define SKIP_RANGE 256
typedef struct st_key_range
{
--- 1.100/include/mysql_com.h 2005-07-05 18:46:01 +02:00
+++ 1.101/include/mysql_com.h 2005-07-18 13:30:07 +02:00
@@ -88,6 +88,8 @@
#define GROUP_FLAG 32768 /* Intern: Group field */
#define UNIQUE_FLAG 65536 /* Intern: Used by sql_yacc */
#define BINCMP_FLAG 131072 /* Intern: Used by sql_yacc */
+#define GET_FIXED_FIELDS_FLAG (1 << 18) /* Used to get fields in item tree */
+#define FIELD_IN_PART_FUNC_FLAG (1 << 19)/* Field part of partition func */
#define REFRESH_GRANT 1 /* Refresh grant tables */
#define REFRESH_LOG 2 /* Start on new log file */
--- 1.11/include/queues.h 2004-11-21 09:50:20 +01:00
+++ 1.12/include/queues.h 2005-07-18 13:30:08 +02:00
@@ -41,6 +41,9 @@
#define queue_element(queue,index) ((queue)->root[index+1])
#define queue_end(queue) ((queue)->root[(queue)->elements])
#define queue_replaced(queue) _downheap(queue,1)
+#define queue_set_cmp_arg(queue, set_arg) (queue)->first_cmp_arg= set_arg
+#define queue_set_max_at_top(queue, set_arg) \
+ (queue)->max_at_top= set_arg ? (-1 ^ 1) : 0
typedef int (*queue_compare)(void *,byte *, byte *);
int init_queue(QUEUE *queue,uint max_elements,uint offset_to_key,
--- 1.65/mysys/Makefile.am 2005-07-12 19:23:20 +02:00
+++ 1.66/mysys/Makefile.am 2005-07-18 13:30:08 +02:00
@@ -84,6 +84,9 @@
test_bitmap$(EXEEXT): my_bitmap.c $(LIBRARIES)
$(LINK) $(FLAGS) -DMAIN ./my_bitmap.c $(LDADD) $(LIBS)
+test_priority_queue$(EXEEXT): queues.c $(LIBRARIES)
+ $(LINK) $(FLAGS) -DMAIN ./queues.c $(LDADD) $(LIBS)
+
test_thr_alarm$(EXEEXT): thr_alarm.c $(LIBRARIES)
$(CP) $(srcdir)/thr_alarm.c ./test_thr_alarm.c
$(LINK) $(FLAGS) -DMAIN ./test_thr_alarm.c $(LDADD) $(LIBS)
--- 1.15/mysys/queues.c 2003-10-16 02:08:36 +02:00
+++ 1.16/mysys/queues.c 2005-07-18 13:30:08 +02:00
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (C) 2000, 2005 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -17,6 +17,10 @@
/*
Code for generell handling of priority Queues.
Implemention of queues from "Algoritms in C" by Robert Sedgewick.
+ An optimisation of _downheap suggested in Exercise 7.51 in "Data
+ Structures & Algorithms in C++" by Mark Allen Weiss, Second Edition
+ was implemented by Mikael Ronström 2005. Also the O(N) algorithm
+ of queue_fix was implemented.
*/
#include "mysys_priv.h"
@@ -214,11 +218,67 @@
}
#endif
- /* Fix heap when index have changed */
+#ifndef OLD_VERSION
void _downheap(register QUEUE *queue, uint idx)
{
byte *element;
+ uint elements,half_queue,offset_to_key, next_index;
+ bool first= TRUE;
+ uint start_idx= idx;
+
+ offset_to_key=queue->offset_to_key;
+ element=queue->root[idx];
+ half_queue=(elements=queue->elements) >> 1;
+
+ while (idx <= half_queue)
+ {
+ int cmp;
+ next_index=idx+idx;
+ if (next_index < elements &&
+ (queue->compare(queue->first_cmp_arg,
+ queue->root[next_index]+offset_to_key,
+ queue->root[next_index+1]+offset_to_key) ^
+ queue->max_at_top) > 0)
+ next_index++;
+ if (first &&
+ (((cmp=queue->compare(queue->first_cmp_arg,
+ queue->root[next_index]+offset_to_key,
+ element+offset_to_key)) == 0) ||
+ ((cmp ^ queue->max_at_top) > 0)))
+ {
+ queue->root[idx]= element;
+ return;
+ }
+ queue->root[idx]=queue->root[next_index];
+ idx=next_index;
+ first= FALSE;
+ }
+
+ next_index= idx >> 1;
+ while (next_index > start_idx)
+ {
+ if ((queue->compare(queue->first_cmp_arg,
+ queue->root[next_index]+offset_to_key,
+ element+offset_to_key) ^
+ queue->max_at_top) < 0)
+ break;
+ queue->root[idx]=queue->root[next_index];
+ idx=next_index;
+ next_index= idx >> 1;
+ }
+ queue->root[idx]=element;
+}
+
+#else
+ /*
+ The old _downheap version is kept for comparisons with the benchmark
+ suit or new benchmarks anyone wants to run for comparisons.
+ */
+ /* Fix heap when index have changed */
+void _downheap(register QUEUE *queue, uint idx)
+{
+ byte *element;
uint elements,half_queue,next_index,offset_to_key;
int cmp;
@@ -247,20 +307,336 @@
}
-static int queue_fix_cmp(QUEUE *queue, void **a, void **b)
-{
- return queue->compare(queue->first_cmp_arg,
- (byte*) (*a)+queue->offset_to_key,
- (byte*) (*b)+queue->offset_to_key);
-}
+#endif
/*
- Fix heap when every element was changed,
- actually, it can be done better, in linear time, not in n*log(n)
+ Fix heap when every element was changed.
*/
void queue_fix(QUEUE *queue)
{
- qsort2(queue->root+1,queue->elements, sizeof(void *),
- (qsort2_cmp)queue_fix_cmp, queue);
+ uint i;
+ for (i= queue->elements >> 1; i > 0; i--)
+ _downheap(queue, i);
+}
+
+#ifdef MAIN
+ /*
+ A test program for the priority queue implementation.
+ It can also be used to benchmark changes of the implementation
+ Build by doing the following in the directory mysys
+ make test_priority_queue
+ ./test_priority_queue
+
+ Written by Mikael Ronström, 2005
+ */
+
+static uint num_array[1025];
+static uint tot_no_parts= 0;
+static uint tot_no_loops= 0;
+static uint expected_part= 0;
+static uint expected_num= 0;
+static bool max_ind= 0;
+static bool fix_used= 0;
+static ulonglong start_time= 0;
+
+static bool is_divisible_by(uint num, uint divisor)
+{
+ uint quotient= num / divisor;
+ if (quotient * divisor == num)
+ return TRUE;
+ return FALSE;
+}
+
+void calculate_next()
+{
+ uint part= expected_part, num= expected_num;
+ uint no_parts= tot_no_parts;
+ if (max_ind)
+ {
+ do
+ {
+ while (++part <= no_parts)
+ {
+ if (is_divisible_by(num, part) &&
+ (num <= ((1 << 21) + part)))
+ {
+ expected_part= part;
+ expected_num= num;
+ return;
+ }
+ }
+ part= 0;
+ } while (--num);
+ }
+ else
+ {
+ do
+ {
+ while (--part > 0)
+ {
+ if (is_divisible_by(num, part))
+ {
+ expected_part= part;
+ expected_num= num;
+ return;
+ }
+ }
+ part= no_parts + 1;
+ } while (++num);
+ }
}
+
+void calculate_end_next(uint part)
+{
+ uint no_parts= tot_no_parts, num;
+ num_array[part]= 0;
+ if (max_ind)
+ {
+ expected_num= 0;
+ for (part= no_parts; part > 0 ; part--)
+ {
+ if (num_array[part])
+ {
+ num= num_array[part] & 0x3FFFFF;
+ if (num >= expected_num)
+ {
+ expected_num= num;
+ expected_part= part;
+ }
+ }
+ }
+ if (expected_num == 0)
+ expected_part= 0;
+ }
+ else
+ {
+ expected_num= 0xFFFFFFFF;
+ for (part= 1; part <= no_parts; part++)
+ {
+ if (num_array[part])
+ {
+ num= num_array[part] & 0x3FFFFF;
+ if (num <= expected_num)
+ {
+ expected_num= num;
+ expected_part= part;
+ }
+ }
+ }
+ if (expected_num == 0xFFFFFFFF)
+ expected_part= 0;
+ }
+ return;
+}
+static int test_compare(void *null_arg, byte *a, byte *b)
+{
+ uint a_num= (*(uint*)a) & 0x3FFFFF;
+ uint b_num= (*(uint*)b) & 0x3FFFFF;
+ uint a_part, b_part;
+ if (a_num > b_num)
+ return +1;
+ if (a_num < b_num)
+ return -1;
+ a_part= (*(uint*)a) >> 22;
+ b_part= (*(uint*)b) >> 22;
+ if (a_part < b_part)
+ return +1;
+ if (a_part > b_part)
+ return -1;
+ return 0;
+}
+
+bool check_num(uint num_part)
+{
+ uint part= num_part >> 22;
+ uint num= num_part & 0x3FFFFF;
+ if (part == expected_part)
+ if (num == expected_num)
+ return FALSE;
+ printf("Expect part %u Expect num 0x%x got part %u num 0x%x max_ind %u fix_used %u \n",
+ expected_part, expected_num, part, num, max_ind, fix_used);
+ return TRUE;
+}
+
+
+void perform_insert(QUEUE *queue)
+{
+ uint i= 1, no_parts= tot_no_parts;
+ uint backward_start= 0;
+
+ expected_part= 1;
+ expected_num= 1;
+
+ if (max_ind)
+ backward_start= 1 << 21;
+
+ do
+ {
+ uint num= (i + backward_start);
+ if (max_ind)
+ {
+ while (!is_divisible_by(num, i))
+ num--;
+ if (max_ind && (num > expected_num ||
+ (num == expected_num && i < expected_part)))
+ {
+ expected_num= num;
+ expected_part= i;
+ }
+ }
+ num_array[i]= num + (i << 22);
+ if (fix_used)
+ queue_element(queue, i-1)= (byte*)&num_array[i];
+ else
+ queue_insert(queue, (byte*)&num_array[i]);
+ } while (++i <= no_parts);
+ if (fix_used)
+ {
+ queue->elements= no_parts;
+ queue_fix(queue);
+ }
+}
+
+bool perform_ins_del(QUEUE *queue, bool max_ind)
+{
+ uint i= 0, no_loops= tot_no_loops, j= tot_no_parts;
+ do
+ {
+ uint num_part= *(uint*)queue_top(queue);
+ uint part= num_part >> 22;
+ if (check_num(num_part))
+ return TRUE;
+ if (j++ >= no_loops)
+ {
+ calculate_end_next(part);
+ queue_remove(queue, (uint) 0);
+ }
+ else
+ {
+ calculate_next();
+ if (max_ind)
+ num_array[part]-= part;
+ else
+ num_array[part]+= part;
+ queue_top(queue)= (byte*)&num_array[part];
+ queue_replaced(queue);
+ }
+ } while (++i < no_loops);
+ return FALSE;
+}
+
+bool do_test(uint no_parts, uint l_max_ind, bool l_fix_used)
+{
+ QUEUE queue;
+ bool result;
+ max_ind= l_max_ind;
+ fix_used= l_fix_used;
+ init_queue(&queue, no_parts, 0, max_ind, test_compare, NULL);
+ tot_no_parts= no_parts;
+ tot_no_loops= 1024;
+ perform_insert(&queue);
+ if ((result= perform_ins_del(&queue, max_ind)))
+ delete_queue(&queue);
+ if (result)
+ {
+ printf("Error\n");
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void start_measurement()
+{
+ start_time= my_getsystime();
+}
+
+static void stop_measurement()
+{
+ ulonglong stop_time= my_getsystime();
+ uint time_in_micros;
+ stop_time-= start_time;
+ stop_time/= 10; /* Convert to microseconds */
+ time_in_micros= (uint)stop_time;
+ printf("Time expired is %u microseconds \n", time_in_micros);
+}
+
+static void benchmark_test()
+{
+ QUEUE queue_real;
+ QUEUE *queue= &queue_real;
+ uint i, add;
+ fix_used= TRUE;
+ max_ind= FALSE;
+ tot_no_parts= 1024;
+ init_queue(queue, tot_no_parts, 0, max_ind, test_compare, NULL);
+ /*
+ First benchmark whether queue_fix is faster than using queue_insert
+ for sizes of 16 partitions.
+ */
+ for (tot_no_parts= 2, add=2; tot_no_parts < 128;
+ tot_no_parts+= add, add++)
+ {
+ printf("Start benchmark queue_fix, tot_no_parts= %u \n", tot_no_parts);
+ start_measurement();
+ for (i= 0; i < 128; i++)
+ {
+ perform_insert(queue);
+ queue_remove_all(queue);
+ }
+ stop_measurement();
+
+ fix_used= FALSE;
+ printf("Start benchmark queue_insert\n");
+ start_measurement();
+ for (i= 0; i < 128; i++)
+ {
+ perform_insert(queue);
+ queue_remove_all(queue);
+ }
+ stop_measurement();
+ }
+ /*
+ Now benchmark insertion and deletion of 16400 elements.
+ Used in consecutive runs this shows whether the optimised _downheap
+ is faster than the standard implementation.
+ */
+ printf("Start benchmarking _downheap \n");
+ start_measurement();
+ perform_insert(queue);
+ for (i= 0; i < 65536; i++)
+ {
+ uint num, part;
+ num= *(uint*)queue_top(queue);
+ num+= 16;
+ part= num >> 22;
+ num_array[part]= num;
+ queue_top(queue)= (byte*)&num_array[part];
+ queue_replaced(queue);
+ }
+ for (i= 0; i < 16; i++)
+ queue_remove(queue, (uint) 0);
+ queue_remove_all(queue);
+ stop_measurement();
+}
+
+int main()
+{
+ int i, add= 1;
+ for (i= 1; i < 1024; i+=add, add++)
+ {
+ printf("Start test for priority queue of size %u\n", i);
+ if (do_test(i, 0, 1))
+ return -1;
+ if (do_test(i, 1, 1))
+ return -1;
+ if (do_test(i, 0, 0))
+ return -1;
+ if (do_test(i, 1, 0))
+ return -1;
+ }
+ benchmark_test();
+ printf("OK\n");
+ return 0;
+}
+#endif
--- 1.111/sql/Makefile.am 2005-07-12 19:23:21 +02:00
+++ 1.112/sql/Makefile.am 2005-07-18 13:30:09 +02:00
@@ -63,7 +63,7 @@
parse_file.h sql_view.h sql_trigger.h \
examples/ha_example.h examples/ha_archive.h \
examples/ha_tina.h ha_blackhole.h \
- ha_federated.h
+ ha_federated.h ha_partition.h
mysqld_SOURCES = sql_lex.cc sql_handler.cc \
item.cc item_sum.cc item_buff.cc item_func.cc \
item_cmpfunc.cc item_strfunc.cc item_timefunc.cc \
@@ -100,6 +100,7 @@
sp_cache.cc parse_file.cc sql_trigger.cc \
examples/ha_example.cc examples/ha_archive.cc \
examples/ha_tina.cc ha_blackhole.cc \
+ ha_partition.cc sql_partition.cc \
ha_federated.cc
gen_lex_hash_SOURCES = gen_lex_hash.cc
--- 1.276/sql/field.cc 2005-07-15 19:48:15 +02:00
+++ 1.277/sql/field.cc 2005-07-18 13:30:09 +02:00
@@ -6311,7 +6311,8 @@
}
-int Field_varstring::cmp(const char *a_ptr, const char *b_ptr)
+int Field_varstring::cmp_max(const char *a_ptr, const char *b_ptr,
+ uint max_len)
{
uint a_length, b_length;
int diff;
@@ -6326,6 +6327,8 @@
a_length= uint2korr(a_ptr);
b_length= uint2korr(b_ptr);
}
+ set_if_smaller(a_length, max_len);
+ set_if_smaller(b_length, max_len);
diff= field_charset->coll->strnncollsp(field_charset,
(const uchar*) a_ptr+
length_bytes,
@@ -6956,13 +6959,16 @@
}
-int Field_blob::cmp(const char *a_ptr, const char *b_ptr)
+int Field_blob::cmp_max(const char *a_ptr, const char *b_ptr,
+ uint max_length)
{
char *blob1,*blob2;
memcpy_fixed(&blob1,a_ptr+packlength,sizeof(char*));
memcpy_fixed(&blob2,b_ptr+packlength,sizeof(char*));
- return Field_blob::cmp(blob1,get_length(a_ptr),
- blob2,get_length(b_ptr));
+ uint a_len= get_length(a_ptr), b_len= get_length(b_ptr);
+ set_if_smaller(a_len, max_length);
+ set_if_smaller(b_len, max_length);
+ return Field_blob::cmp(blob1,a_len,blob2,b_len);
}
@@ -7976,6 +7982,35 @@
{
int2my_decimal(E_DEC_FATAL_ERROR, val_int(), 1, deciaml_value);
return deciaml_value;
+}
+
+
+/*
+ Compare two bit fields using pointers within the record.
+ SYNOPSIS
+ cmp_max()
+ a Pointer to field->ptr in first record
+ b Pointer to field->ptr in second record
+ max_len Maximum length used in index
+ DESCRIPTION
+ This method is used from key_rec_cmp used by merge sorts used
+ by partitioned index read and later other similar places.
+ The a and b pointer must be pointers to the field in a record
+ (not the table->record[0] necessarily)
+*/
+int Field_bit::cmp_max(const char *a, const char *b, uint max_len)
+{
+ my_ptrdiff_t a_diff= a - ptr;
+ my_ptrdiff_t b_diff= b - ptr;
+ if (bit_len)
+ {
+ int flag;
+ uchar bits_a= get_rec_bits(bit_ptr+a_diff, bit_ofs, bit_len);
+ uchar bits_b= get_rec_bits(bit_ptr+b_diff, bit_ofs, bit_len);
+ if ((flag= (int) (bits_a - bits_b)))
+ return flag;
+ }
+ return memcmp(a, b, field_length);
}
--- 1.164/sql/field.h 2005-07-12 19:23:21 +02:00
+++ 1.165/sql/field.h 2005-07-18 13:30:09 +02:00
@@ -87,7 +87,7 @@
utype unireg_check;
uint32 field_length; // Length of field
uint field_index; // field number in fields array
- uint16 flags;
+ uint32 flags;
/* fieldnr is the id of the field (first field = 1) as is also
used in key_part.
*/
@@ -154,6 +154,8 @@
virtual enum_field_types type() const =0;
virtual enum_field_types real_type() const { return type(); }
inline int cmp(const char *str) { return cmp(ptr,str); }
+ virtual int cmp_max(const char *a, const char *b, uint max_len)
+ { return cmp(a, b); }
virtual int cmp(const char *,const char *)=0;
virtual int cmp_binary(const char *a,const char *b, uint32 max_length=~0L)
{ return memcmp(a,b,pack_length()); }
@@ -1059,7 +1061,11 @@
longlong val_int(void);
String *val_str(String*,String *);
my_decimal *val_decimal(my_decimal *);
- int cmp(const char *,const char*);
+ int cmp_max(const char *, const char *, uint max_length);
+ int cmp(const char *a,const char*b)
+ {
+ return cmp_max(a, b, ~0);
+ }
void sort_string(char *buff,uint length);
void get_key_image(char *buff,uint length, imagetype type);
void set_key_image(char *buff,uint length);
@@ -1115,7 +1121,9 @@
longlong val_int(void);
String *val_str(String*,String *);
my_decimal *val_decimal(my_decimal *);
- int cmp(const char *,const char*);
+ int cmp_max(const char *, const char *, uint max_length);
+ int cmp(const char *a,const char*b)
+ { return cmp_max(a, b, ~0); }
int cmp(const char *a, uint32 a_length, const char *b, uint32 b_length);
int cmp_binary(const char *a,const char *b, uint32 max_length=~0L);
int key_cmp(const byte *,const byte*);
@@ -1139,6 +1147,10 @@
{
memcpy_fixed(str,ptr+packlength,sizeof(char*));
}
+ inline void get_ptr(char **str, uint row_offset)
+ {
+ memcpy_fixed(str,ptr+packlength+row_offset,sizeof(char*));
+ }
inline void set_ptr(char *length,char *data)
{
memcpy(ptr,length,packlength);
@@ -1307,6 +1319,7 @@
my_decimal *val_decimal(my_decimal *);
int cmp(const char *a, const char *b)
{ return cmp_binary(a, b); }
+ int cmp_max(const char *a, const char *b, uint max_length);
int key_cmp(const byte *a, const byte *b)
{ return cmp_binary((char *) a, (char *) b); }
int key_cmp(const byte *str, uint length);
--- 1.151/sql/ha_berkeley.cc 2005-06-09 15:48:47 +02:00
+++ 1.152/sql/ha_berkeley.cc 2005-07-18 13:30:10 +02:00
@@ -1360,7 +1360,7 @@
}
-int ha_berkeley::index_init(uint keynr)
+int ha_berkeley::index_init(uint keynr, bool sorted)
{
int error;
DBUG_ENTER("ha_berkeley::index_init");
@@ -1638,7 +1638,7 @@
{
DBUG_ENTER("rnd_init");
current_row.flags=DB_DBT_REALLOC;
- DBUG_RETURN(index_init(primary_key));
+ DBUG_RETURN(index_init(primary_key, 0));
}
int ha_berkeley::rnd_end()
@@ -2146,7 +2146,7 @@
(void) ha_berkeley::extra(HA_EXTRA_KEYREAD);
/* Set 'active_index' */
- ha_berkeley::index_init(table->s->next_number_index);
+ ha_berkeley::index_init(table->s->next_number_index, 0);
if (!table->s->next_number_key_offset)
{ // Autoincrement at key-start
@@ -2485,7 +2485,7 @@
if (!(share->status & STATUS_PRIMARY_KEY_INIT))
{
(void) extra(HA_EXTRA_KEYREAD);
- index_init(primary_key);
+ index_init(primary_key, 0);
if (!index_last(table->record[1]))
share->auto_ident=uint5korr(current_ident);
index_end();
--- 1.70/sql/ha_berkeley.h 2005-05-09 11:26:46 +02:00
+++ 1.71/sql/ha_berkeley.h 2005-07-18 13:30:10 +02:00
@@ -98,7 +98,7 @@
const char **bas_ext() const;
ulong table_flags(void) const { return int_table_flags; }
uint max_supported_keys() const { return MAX_KEY-1; }
- uint extra_rec_buf_length() { return BDB_HIDDEN_PRIMARY_KEY_LENGTH; }
+ uint extra_rec_buf_length() const { return BDB_HIDDEN_PRIMARY_KEY_LENGTH; }
ha_rows estimate_rows_upper_bound();
const key_map *keys_to_use_for_scanning() { return &key_map_full; }
bool has_transactions() { return 1;}
@@ -109,7 +109,7 @@
int write_row(byte * buf);
int update_row(const byte * old_data, byte * new_data);
int delete_row(const byte * buf);
- int index_init(uint index);
+ int index_init(uint index, bool sorted);
int index_end();
int index_read(byte * buf, const byte * key,
uint key_len, enum ha_rkey_function find_flag);
--- 1.178/sql/handler.cc 2005-07-12 19:23:22 +02:00
+++ 1.179/sql/handler.cc 2005-07-18 13:30:11 +02:00
@@ -34,6 +34,9 @@
#ifdef HAVE_EXAMPLE_DB
#include "examples/ha_example.h"
#endif
+#ifdef HAVE_PARTITION_DB
+#include "ha_partition.h"
+#endif
#ifdef HAVE_ARCHIVE_DB
#include "examples/ha_archive.h"
#endif
@@ -170,7 +173,13 @@
{
if (ha_storage_engine_is_enabled(database_type))
return database_type;
-
+#ifdef HAVE_PARTITION_DB
+ /*
+ Partition handler is not in the list of handlers shown since it is an internal
handler
+ */
+ if (database_type == DB_TYPE_PARTITION_DB)
+ return database_type;
+#endif
if (no_substitute)
{
if (report_error)
@@ -236,6 +245,13 @@
file= new ha_example(table);
break;
#endif
+#ifdef HAVE_PARTITION_DB
+ case DB_TYPE_PARTITION_DB:
+ {
+ file= new ha_partition(table);
+ break;
+ }
+#endif
#ifdef HAVE_ARCHIVE_DB
case DB_TYPE_ARCHIVE_DB:
file= new ha_archive(table);
@@ -290,6 +306,29 @@
return file;
}
+
+#ifdef HAVE_PARTITION_DB
+handler *get_ha_partition(partition_info *part_info)
+{
+ ha_partition *partition;
+ DBUG_ENTER("get_ha_partition");
+ if ((partition= new ha_partition(part_info)))
+ {
+ if (partition->ha_initialise())
+ {
+ delete partition;
+ partition= 0;
+ }
+ }
+ else
+ {
+ my_error(ER_OUTOFMEMORY, MYF(0), sizeof(ha_partition));
+ }
+ DBUG_RETURN(((handler*) partition));
+}
+#endif
+
+
/*
Register handler error messages for use with my_error().
@@ -1406,27 +1445,41 @@
my_bool r;
#endif
DBUG_ENTER("ha_allocate_read_write_set");
- DBUG_PRINT("info", ("no_fields = %d", no_fields));
- read_set= (MY_BITMAP*)sql_alloc(sizeof(MY_BITMAP));
- write_set= (MY_BITMAP*)sql_alloc(sizeof(MY_BITMAP));
- read_buf= (uint32*)sql_alloc(bitmap_size);
- write_buf= (uint32*)sql_alloc(bitmap_size);
- if (!read_set || !write_set || !read_buf || !write_buf)
+ DBUG_PRINT("enter", ("no_fields = %d", no_fields));
+
+ if (table)
{
- ha_deallocate_read_write_set();
- DBUG_RETURN(TRUE);
- }
+ if (table->read_set == NULL)
+ {
+ read_set= (MY_BITMAP*)sql_alloc(sizeof(MY_BITMAP));
+ write_set= (MY_BITMAP*)sql_alloc(sizeof(MY_BITMAP));
+ read_buf= (uint32*)sql_alloc(bitmap_size);
+ write_buf= (uint32*)sql_alloc(bitmap_size);
+ if (!read_set || !write_set || !read_buf || !write_buf)
+ {
+ ha_deallocate_read_write_set();
+ DBUG_RETURN(TRUE);
+ }
#ifndef DEBUG_OFF
- r =
+ r =
#endif
- bitmap_init(read_set, read_buf, no_fields+1, FALSE);
- DBUG_ASSERT(!r /*bitmap_init(read_set...)*/);
+ bitmap_init(read_set, read_buf, no_fields+1, FALSE);
+ DBUG_ASSERT(!r /*bitmap_init(read_set...)*/);
#ifndef DEBUG_OFF
- r =
+ r =
#endif
- bitmap_init(write_set, write_buf, no_fields+1, FALSE);
- DBUG_ASSERT(!r /*bitmap_init(write_set...)*/);
- ha_clear_all_set();
+ bitmap_init(write_set, write_buf, no_fields+1, FALSE);
+ DBUG_ASSERT(!r /*bitmap_init(write_set...)*/);
+ table->read_set= read_set;
+ table->write_set= write_set;
+ ha_clear_all_set();
+ }
+ else
+ {
+ read_set= table->read_set;
+ write_set= table->write_set;
+ }
+ }
DBUG_RETURN(FALSE);
}
@@ -1476,6 +1529,8 @@
}
DBUG_VOID_RETURN;
}
+
+
/*
Read first row (only) from a table
This is never called for InnoDB or BDB tables, as these table types
@@ -1504,7 +1559,7 @@
else
{
/* Find the first row through the primary key */
- (void) ha_index_init(primary_key);
+ (void) ha_index_init(primary_key, 0);
error=index_first(buf);
(void) ha_index_end();
}
@@ -1688,7 +1743,7 @@
int error;
(void) extra(HA_EXTRA_KEYREAD);
- index_init(table->s->next_number_index);
+ index_init(table->s->next_number_index, 1);
if (!table->s->next_number_key_offset)
{ // Autoincrement at key-start
error=index_last(table->record[1]);
@@ -2512,7 +2567,7 @@
int handler::index_read_idx(byte * buf, uint index, const byte * key,
uint key_len, enum ha_rkey_function find_flag)
{
- int error= ha_index_init(index);
+ int error= ha_index_init(index, 0);
if (!error)
error= index_read(buf, key, key_len, find_flag);
if (!error)
--- 1.147/sql/handler.h 2005-07-12 19:23:22 +02:00
+++ 1.148/sql/handler.h 2005-07-18 13:30:11 +02:00
@@ -89,6 +89,11 @@
#define HA_NEED_READ_RANGE_BUFFER (1 << 29) /* for read_multi_range */
#define HA_ANY_INDEX_MAY_BE_UNIQUE (1 << 30)
+/* Flags for partition handlers */
+#define HA_CAN_PARTITION (1 << 0) /* Partition support */
+#define HA_CAN_UPDATE_PARTITION_KEY (1 << 1)
+#define HA_CAN_PARTITION_UNIQUE (1 << 2)
+
/* bits in index_flags(index_number) for what you can do with index */
#define HA_READ_NEXT 1 /* TODO really use this flag */
@@ -172,6 +177,7 @@
DB_TYPE_EXAMPLE_DB, DB_TYPE_ARCHIVE_DB, DB_TYPE_CSV_DB,
DB_TYPE_FEDERATED_DB,
DB_TYPE_BLACKHOLE_DB,
+ DB_TYPE_PARTITION_DB,
DB_TYPE_DEFAULT // Must be last
};
@@ -364,6 +370,208 @@
enum enum_tx_isolation { ISO_READ_UNCOMMITTED, ISO_READ_COMMITTED,
ISO_REPEATABLE_READ, ISO_SERIALIZABLE};
+
+typedef struct {
+ uint32 start_part;
+ uint32 end_part;
+ bool use_bit_array;
+} part_id_range;
+/**
+ * An enum and a struct to handle partitioning and subpartitioning.
+ */
+enum partition_type {
+ NOT_A_PARTITION= 0,
+ RANGE_PARTITION,
+ HASH_PARTITION,
+ LIST_PARTITION
+};
+
+#define UNDEF_NODEGROUP 65535
+class Item;
+
+class partition_element :public Sql_alloc {
+public:
+ List<partition_element> subpartitions;
+ List<Item> list_expr_list;
+ ulonglong part_max_rows;
+ ulonglong part_min_rows;
+ char *partition_name;
+ char *tablespace_name;
+ Item* range_expr;
+ char* part_comment;
+ char* data_file_name;
+ char* index_file_name;
+ enum db_type engine_type;
+ uint16 nodegroup_id;
+
+ partition_element()
+ : part_max_rows(0), part_min_rows(0), partition_name(NULL),
+ tablespace_name(NULL), range_expr(NULL), part_comment(NULL),
+ data_file_name(NULL), index_file_name(NULL),
+ engine_type(DB_TYPE_UNKNOWN), nodegroup_id(UNDEF_NODEGROUP)
+ {
+ subpartitions.empty();
+ list_expr_list.empty();
+ }
+ ~partition_element() {}
+};
+
+typedef struct {
+ longlong list_value;
+ uint partition_id;
+} LIST_PART_ENTRY;
+enum Item_result;
+
+class partition_info;
+
+typedef bool (*get_part_id_func)(partition_info *part_info,
+ uint32 *part_id);
+typedef uint32 (*get_subpart_id_func)(partition_info *part_info);
+
+class partition_info :public Sql_alloc {
+public:
+ /*
+ * Here comes a set of definitions needed for partitioned table handlers.
+ */
+ List<partition_element> partitions;
+
+ List<char> part_field_list;
+ List<char> subpart_field_list;
+
+ get_part_id_func get_partition_id;
+ get_part_id_func get_part_partition_id;
+ get_subpart_id_func get_subpartition_id;
+
+ Field **part_field_array;
+ Field **subpart_field_array;
+ Field **full_part_field_array;
+
+ Item *part_expr;
+ Item *subpart_expr;
+
+ Item *item_free_list;
+
+ union {
+ longlong *range_int_array;
+ LIST_PART_ENTRY *list_array;
+ };
+ char* part_info_string;
+
+ char *part_func_string;
+ char *subpart_func_string;
+
+ partition_element *curr_part_elem;
+ partition_element *current_partition;
+ /*
+ These key_map's are used for Partitioning to enable quick decisions
+ on whether we can derive more information about which partition to
+ scan just by looking at what index is used.
+ */
+ key_map all_fields_in_PF, all_fields_in_PPF, all_fields_in_SPF;
+ key_map some_fields_in_PF;
+
+ enum db_type default_engine_type;
+ Item_result part_result_type;
+ partition_type part_type;
+ partition_type subpart_type;
+
+ uint part_info_len;
+ uint part_func_len;
+ uint subpart_func_len;
+
+ uint no_full_parts;
+ uint no_parts;
+ uint no_subparts;
+ uint count_curr_parts;
+ uint count_curr_subparts;
+
+ uint part_error_code;
+
+ uint no_list_values;
+
+ uint no_part_fields;
+ uint no_subpart_fields;
+ uint no_full_part_fields;
+
+ uint16 linear_hash_mask;
+
+ bool use_default_partitions;
+ bool use_default_subpartitions;
+ bool defined_max_value;
+ bool list_of_part_fields;
+ bool list_of_subpart_fields;
+ bool linear_hash_ind;
+
+ partition_info()
+ : get_partition_id(NULL), get_part_partition_id(NULL),
+ get_subpartition_id(NULL),
+ part_field_array(NULL), subpart_field_array(NULL),
+ full_part_field_array(NULL),
+ part_expr(NULL), subpart_expr(NULL), item_free_list(NULL),
+ list_array(NULL),
+ part_info_string(NULL),
+ part_func_string(NULL), subpart_func_string(NULL),
+ curr_part_elem(NULL), current_partition(NULL),
+ default_engine_type(DB_TYPE_UNKNOWN),
+ part_result_type(INT_RESULT),
+ part_type(NOT_A_PARTITION), subpart_type(NOT_A_PARTITION),
+ part_info_len(0), part_func_len(0), subpart_func_len(0),
+ no_full_parts(0), no_parts(0), no_subparts(0),
+ count_curr_parts(0), count_curr_subparts(0), part_error_code(0),
+ no_list_values(0), no_part_fields(0), no_subpart_fields(0),
+ no_full_part_fields(0), linear_hash_mask(0),
+ use_default_partitions(TRUE),
+ use_default_subpartitions(TRUE), defined_max_value(FALSE),
+ list_of_part_fields(FALSE), list_of_subpart_fields(FALSE),
+ linear_hash_ind(FALSE)
+ {
+ all_fields_in_PF.clear_all();
+ all_fields_in_PPF.clear_all();
+ all_fields_in_SPF.clear_all();
+ some_fields_in_PF.clear_all();
+ partitions.empty();
+ part_field_list.empty();
+ subpart_field_list.empty();
+ }
+ ~partition_info() {}
+};
+
+
+#ifdef HAVE_PARTITION_DB
+/*
+ Answers the question if subpartitioning is used for a certain table
+ SYNOPSIS
+ is_sub_partitioned()
+ part_info A reference to the partition_info struct
+ RETURN VALUE
+ Returns true if subpartitioning used and false otherwise
+ DESCRIPTION
+ A routine to check for subpartitioning for improved readability of code
+*/
+inline
+bool is_sub_partitioned(partition_info *part_info)
+{ return (part_info->subpart_type == NOT_A_PARTITION ? FALSE : TRUE); }
+
+
+/*
+ Returns the total number of partitions on the leaf level.
+ SYNOPSIS
+ get_tot_partitions()
+ part_info A reference to the partition_info struct
+ RETURN VALUE
+ Returns the number of partitions
+ DESCRIPTION
+ A routine to check for number of partitions for improved readability
+ of code
+*/
+inline
+uint get_tot_partitions(partition_info *part_info)
+{
+ return part_info->no_parts *
+ (is_sub_partitioned(part_info) ? part_info->no_subparts : 1);
+}
+#endif
+
typedef struct st_ha_create_information
{
CHARSET_INFO *table_charset, *default_table_charset;
@@ -412,6 +620,31 @@
} HA_CHECK_OPT;
+#ifdef HAVE_PARTITION_DB
+handler *get_ha_partition(partition_info *part_info);
+int get_parts_for_update(const byte *old_data, byte *new_data,
+ const byte *rec0, partition_info *part_info,
+ uint32 *old_part_id, uint32 *new_part_id);
+int get_part_for_delete(const byte *buf, const byte *rec0,
+ partition_info *part_info, uint32 *part_id);
+bool check_partition_info(partition_info *part_info,enum db_type eng_type,
+ handler *file, ulonglong max_rows);
+bool fix_partition_func(THD *thd, const char *name, TABLE *table);
+char *generate_partition_syntax(partition_info *part_info,
+ uint *buf_length, bool use_sql_alloc);
+bool partition_key_modified(TABLE *table, List<Item> &fields);
+void get_partition_set(const TABLE *table, byte *buf, const uint index,
+ const key_range *key_spec,
+ part_id_range *part_spec);
+void get_full_part_id_from_key(const TABLE *table, byte *buf,
+ KEY *key_info,
+ const key_range *key_spec,
+ part_id_range *part_spec);
+bool mysql_unpack_partition(File file, THD *thd, uint part_info_len,
+ TABLE *table);
+#endif
+
+
/*
This is a buffer area that the handler can use to store rows.
'end_of_used_area' should be kept updated after calls to
@@ -429,10 +662,13 @@
class handler :public Sql_alloc
{
+#ifdef HAVE_PARTITION_DB
+ friend class ha_partition;
+#endif
protected:
struct st_table *table; /* The table definition */
- virtual int index_init(uint idx) { active_index=idx; return 0; }
+ virtual int index_init(uint idx, bool sorted) { active_index=idx; return 0; }
virtual int index_end() { active_index=MAX_KEY; return 0; }
/*
rnd_init() can be called two times without rnd_end() in between
@@ -518,7 +754,7 @@
{ return rows2double(ranges+rows); }
virtual const key_map *keys_to_use_for_scanning() { return &key_map_empty; }
virtual bool has_transactions(){ return 0;}
- virtual uint extra_rec_buf_length() { return 0; }
+ virtual uint extra_rec_buf_length() const { return 0; }
/*
Return upper bound of current number of records in the table
@@ -537,12 +773,12 @@
virtual const char *index_type(uint key_number) { DBUG_ASSERT(0); return "";}
- int ha_index_init(uint idx)
+ int ha_index_init(uint idx, bool sorted)
{
DBUG_ENTER("ha_index_init");
DBUG_ASSERT(inited==NONE);
inited=INDEX;
- DBUG_RETURN(index_init(idx));
+ DBUG_RETURN(index_init(idx, sorted));
}
int ha_index_end()
{
@@ -902,6 +1138,10 @@
virtual const char *table_type() const =0;
virtual const char **bas_ext() const =0;
virtual ulong table_flags(void) const =0;
+#ifdef HAVE_PARTITION_DB
+ virtual ulong partition_flags(void) const { return 0;}
+ virtual int get_default_no_partitions(ulonglong max_rows) { return 1;}
+#endif
virtual ulong index_flags(uint idx, uint part, bool all_parts) const =0;
virtual ulong index_ddl_flags(KEY *wanted_index) const
{ return (HA_DDL_SUPPORT); }
@@ -941,6 +1181,7 @@
virtual int delete_table(const char *name);
virtual int create(const char *name, TABLE *form, HA_CREATE_INFO *info)=0;
+ virtual int create_handler_files(const char *name) { return FALSE;}
/* lock_count() can be more than one if the table is a MERGE */
virtual uint lock_count(void) const { return 1; }
--- 1.34/sql/key.cc 2005-05-06 12:46:02 +02:00
+++ 1.35/sql/key.cc 2005-07-18 13:30:12 +02:00
@@ -429,3 +429,86 @@
}
return 0; // Keys are equal
}
+
+
+/*
+ Compare two records in index order
+ SYNOPSIS
+ key_rec_cmp()
+ key Index information
+ rec0 Pointer to table->record[0]
+ first_rec Pointer to record compare with
+ second_rec Pointer to record compare against first_rec
+ DESCRIPTION
+ This method is set-up such that it can be called directly from the
+ priority queue and it is attempted to be optimised as much as possible
+ since this will be called O(N * log N) times while performing a merge
+ sort in various places in the code.
+
+ We retrieve the pointer to table->record[0] using the fact that key_parts
+ have an offset making it possible to calculate the start of the record.
+ We need to get the diff to the compared record since none of the records
+ being compared are stored in table->record[0].
+
+ We first check for NULL values, if there are no NULL values we use
+ a compare method that gets two field pointers and a max length
+ and return the result of the comparison.
+*/
+
+int key_rec_cmp(void *key, byte *first_rec, byte *second_rec)
+{
+ KEY *key_info= (KEY*)key;
+ uint key_parts= key_info->key_parts, i= 0;
+ KEY_PART_INFO *key_part= key_info->key_part;
+ char *rec0= key_part->field->ptr - key_part->offset;
+ my_ptrdiff_t first_diff= first_rec - rec0, sec_diff= second_rec - rec0;
+ int result= 0;
+ DBUG_ENTER("key_rec_cmp");
+
+ do
+ {
+ Field *field= key_part->field;
+ uint length;
+
+ if (key_part->null_bit)
+ {
+ /* The key_part can contain NULL values */
+ bool first_is_null= field->is_null(first_diff);
+ bool sec_is_null= field->is_null(sec_diff);
+ /*
+ NULL is smaller then everything so if first is NULL and the other
+ not then we know that we should return -1 and for the opposite
+ we should return +1. If both are NULL then we call it equality
+ although it is a strange form of equality, we have equally little
+ information of the real value.
+ */
+ if (!first_is_null)
+ {
+ if (!sec_is_null)
+ ; /* Fall through, no NULL fields */
+ else
+ {
+ DBUG_RETURN(+1);
+ }
+ }
+ else if (!sec_is_null)
+ {
+ DBUG_RETURN(-1);
+ }
+ else
+ goto next_loop; /* Both were NULL */
+ }
+ /*
+ No null values in the fields
+ We use the virtual method cmp_max with a max length parameter.
+ For most field types this translates into a cmp without
+ max length. The exceptions are the BLOB and VARCHAR field types
+ that take the max length into account.
+ */
+ result= field->cmp_max(field->ptr+first_diff, field->ptr+sec_diff,
+ key_part->length);
+next_loop:
+ key_part++;
+ } while (!result && ++i < key_parts);
+ DBUG_RETURN(result);
+}
--- 1.137/sql/lex.h 2005-07-01 14:51:49 +02:00
+++ 1.138/sql/lex.h 2005-07-18 13:30:12 +02:00
@@ -274,11 +274,14 @@
{ "LEAVE", SYM(LEAVE_SYM)},
{ "LEAVES", SYM(LEAVES)},
{ "LEFT", SYM(LEFT)},
+ { "LESS", SYM(LESS_SYM)},
{ "LEVEL", SYM(LEVEL_SYM)},
{ "LIKE", SYM(LIKE)},
{ "LIMIT", SYM(LIMIT)},
+ { "LINEAR", SYM(LINEAR_SYM)},
{ "LINES", SYM(LINES)},
{ "LINESTRING", SYM(LINESTRING)},
+ { "LIST", SYM(LIST_SYM)},
{ "LOAD", SYM(LOAD)},
{ "LOCAL", SYM(LOCAL_SYM)},
{ "LOCALTIME", SYM(NOW_SYM)},
@@ -312,6 +315,7 @@
{ "MAX_ROWS", SYM(MAX_ROWS)},
{ "MAX_UPDATES_PER_HOUR", SYM(MAX_UPDATES_PER_HOUR)},
{ "MAX_USER_CONNECTIONS", SYM(MAX_USER_CONNECTIONS_SYM)},
+ { "MAXVALUE", SYM(MAX_VALUE_SYM)},
{ "MEDIUM", SYM(MEDIUM_SYM)},
{ "MEDIUMBLOB", SYM(MEDIUMBLOB)},
{ "MEDIUMINT", SYM(MEDIUMINT)},
@@ -343,6 +347,7 @@
{ "NEW", SYM(NEW_SYM)},
{ "NEXT", SYM(NEXT_SYM)},
{ "NO", SYM(NO_SYM)},
+ { "NODEGROUP", SYM(NODEGROUP_SYM)},
{ "NONE", SYM(NONE_SYM)},
{ "NOT", SYM(NOT_SYM)},
{ "NO_WRITE_TO_BINLOG", SYM(NO_WRITE_TO_BINLOG)},
@@ -365,6 +370,10 @@
{ "OUTFILE", SYM(OUTFILE)},
{ "PACK_KEYS", SYM(PACK_KEYS_SYM)},
{ "PARTIAL", SYM(PARTIAL)},
+#ifdef HAVE_PARTITION_DB
+ { "PARTITION", SYM(PARTITION_SYM)},
+#endif
+ { "PARTITIONS", SYM(PARTITIONS_SYM)},
{ "PASSWORD", SYM(PASSWORD)},
{ "PHASE", SYM(PHASE_SYM)},
{ "POINT", SYM(POINT_SYM)},
@@ -385,6 +394,7 @@
{ "RAID_CHUNKS", SYM(RAID_CHUNKS)},
{ "RAID_CHUNKSIZE", SYM(RAID_CHUNKSIZE)},
{ "RAID_TYPE", SYM(RAID_TYPE)},
+ { "RANGE", SYM(RANGE_SYM)},
{ "READ", SYM(READ_SYM)},
{ "READS", SYM(READS_SYM)},
{ "REAL", SYM(REAL)},
@@ -476,6 +486,8 @@
{ "STRING", SYM(STRING_SYM)},
{ "STRIPED", SYM(RAID_STRIPED_SYM)},
{ "SUBJECT", SYM(SUBJECT_SYM)},
+ { "SUBPARTITION", SYM(SUBPARTITION_SYM)},
+ { "SUBPARTITIONS", SYM(SUBPARTITIONS_SYM)},
{ "SUPER", SYM(SUPER_SYM)},
{ "SUSPEND", SYM(SUSPEND_SYM)},
{ "TABLE", SYM(TABLE_SYM)},
@@ -485,6 +497,7 @@
{ "TEMPTABLE", SYM(TEMPTABLE_SYM)},
{ "TERMINATED", SYM(TERMINATED)},
{ "TEXT", SYM(TEXT_SYM)},
+ { "THAN", SYM(THAN_SYM)},
{ "THEN", SYM(THEN_SYM)},
{ "TIME", SYM(TIME_SYM)},
{ "TIMESTAMP", SYM(TIMESTAMP)},
--- 1.316/sql/mysql_priv.h 2005-07-15 15:08:28 +02:00
+++ 1.317/sql/mysql_priv.h 2005-07-18 13:30:12 +02:00
@@ -614,6 +614,18 @@
bool no_errors);
bool check_global_access(THD *thd, ulong want_access);
+/*
+ General routine to change field->ptr of a NULL-terminated array of Field
+ objects. Useful when needed to call val_int, val_str or similar and the
+ field data is not in table->record[0] but in some other structure.
+ set_key_field_ptr changes all fields of an index using a key_info object.
+ All methods presume that there is at least one field to change.
+*/
+
+void set_field_ptr(Field **ptr, const byte *new_buf, const byte *old_buf);
+void set_key_field_ptr(KEY *key_info, const byte *new_buf,
+ const byte *old_buf);
+
bool mysql_backup_table(THD* thd, TABLE_LIST* table_list);
bool mysql_restore_table(THD* thd, TABLE_LIST* table_list);
@@ -772,6 +784,9 @@
find_field_in_real_table(THD *thd, TABLE *table, const char *name,
uint length, bool check_grants, bool allow_rowid,
uint *cached_field_index_ptr);
+Field *
+find_field_in_table_sef(TABLE *table, const char *name);
+
#ifdef HAVE_OPENSSL
#include <openssl/des.h>
struct st_des_keyblock
@@ -1020,6 +1035,7 @@
void key_unpack(String *to,TABLE *form,uint index);
bool check_if_key_used(TABLE *table, uint idx, List<Item> &fields);
int key_cmp(KEY_PART_INFO *key_part, const byte *key, uint key_length);
+int key_rec_cmp(void *key_info, byte *a, byte *b);
bool init_errmessage(void);
void sql_perror(const char *message);
@@ -1188,6 +1204,7 @@
extern SHOW_COMP_OPTION have_geometry, have_rtree_keys;
extern SHOW_COMP_OPTION have_crypt;
extern SHOW_COMP_OPTION have_compress;
+extern SHOW_COMP_OPTION have_partition_db;
#ifndef __WIN__
extern pthread_t signal_thread;
@@ -1238,7 +1255,7 @@
uint key_count,KEY *key_info,handler *db_type);
int rea_create_table(THD *thd, my_string file_name,HA_CREATE_INFO *create_info,
List<create_field> &create_field,
- uint key_count,KEY *key_info);
+ uint key_count,KEY *key_info, handler *file);
int format_number(uint inputflag,uint max_length,my_string pos,uint length,
my_string *errpos);
int openfrm(THD *thd, const char *name,const char *alias,uint filestat,
--- 1.467/sql/mysqld.cc 2005-07-12 19:51:31 +02:00
+++ 1.468/sql/mysqld.cc 2005-07-18 13:30:12 +02:00
@@ -325,6 +325,7 @@
ulong opt_ndb_cache_check_time;
const char *opt_ndb_mgmd;
ulong opt_ndb_nodeid;
+bool opt_ndb_linear_hash;
#endif
my_bool opt_readonly, use_temp_pool, relay_log_purge;
my_bool opt_sync_frm, opt_allow_suspicious_udfs;
@@ -430,6 +431,7 @@
SHOW_COMP_OPTION have_berkeley_db, have_innodb, have_isam, have_ndbcluster,
have_example_db, have_archive_db, have_csv_db;
SHOW_COMP_OPTION have_federated_db;
+SHOW_COMP_OPTION have_partition_db;
SHOW_COMP_OPTION have_raid, have_openssl, have_symlink, have_query_cache;
SHOW_COMP_OPTION have_geometry, have_rtree_keys;
SHOW_COMP_OPTION have_crypt, have_compress;
@@ -4235,6 +4237,7 @@
OPT_NDB_FORCE_SEND, OPT_NDB_AUTOINCREMENT_PREFETCH_SZ,
OPT_NDB_SHM, OPT_NDB_OPTIMIZED_NODE_SELECTION, OPT_NDB_CACHE_CHECK_TIME,
OPT_NDB_MGMD, OPT_NDB_NODEID,
+ OPT_NDB_LINEAR_HASH,
OPT_SKIP_SAFEMALLOC,
OPT_TEMP_POOL, OPT_TX_ISOLATION, OPT_COMPLETION_TYPE,
OPT_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS,
@@ -4800,6 +4803,16 @@
(gptr*) &global_system_variables.ndb_autoincrement_prefetch_sz,
(gptr*) &global_system_variables.ndb_autoincrement_prefetch_sz,
0, GET_ULONG, REQUIRED_ARG, 32, 1, 256, 0, 0, 0},
+ {"ndb-use-linear-hash", OPT_NDB_LINEAR_HASH,
+ "Flag to indicate whether to use linear hash for default in new tables",
+ (gptr*) &opt_ndb_linear_hash,
+ (gptr*) &opt_ndb_linear_hash,
+ 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
+ {"ndb_use_linear_hash", OPT_NDB_LINEAR_HASH,
+ "Flag to indicate whether to use linear hash for default in new tables",
+ (gptr*) &opt_ndb_linear_hash,
+ (gptr*) &opt_ndb_linear_hash,
+ 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
{"ndb-force-send", OPT_NDB_FORCE_SEND,
"Force send of buffers to ndb immediately without waiting for "
"other threads.",
@@ -6054,6 +6067,11 @@
have_example_db= SHOW_OPTION_YES;
#else
have_example_db= SHOW_OPTION_NO;
+#endif
+#ifdef HAVE_PARTITION_DB
+ have_partition_db= SHOW_OPTION_YES;
+#else
+ have_partition_db= SHOW_OPTION_NO;
#endif
#ifdef HAVE_ARCHIVE_DB
have_archive_db= SHOW_OPTION_YES;
--- 1.174/sql/opt_range.cc 2005-07-12 19:23:23 +02:00
+++ 1.175/sql/opt_range.cc 2005-07-18 13:30:13 +02:00
@@ -751,7 +751,7 @@
DBUG_ENTER("QUICK_RANGE_SELECT::init");
if (file->inited == handler::NONE)
- DBUG_RETURN(error= file->ha_index_init(index));
+ DBUG_RETURN(error= file->ha_index_init(index, 1));
error= 0;
DBUG_RETURN(0);
}
@@ -6049,7 +6049,7 @@
range= NULL;
cur_range= (QUICK_RANGE**) ranges.buffer;
- if (file->inited == handler::NONE && (error= file->ha_index_init(index)))
+ if (file->inited == handler::NONE && (error=
file->ha_index_init(index,1)))
DBUG_RETURN(error);
/* Do not allocate the buffers twice. */
@@ -6308,7 +6308,7 @@
(byte*) range->min_key,
range->min_length,
(ha_rkey_function)(range->flag ^ GEOM_FLAG));
- if (result != HA_ERR_KEY_NOT_FOUND)
+ if (result != HA_ERR_KEY_NOT_FOUND && result != HA_ERR_END_OF_FILE)
DBUG_RETURN(result);
range=0; // Not found, to next range
}
@@ -6451,7 +6451,7 @@
}
if (result)
{
- if (result != HA_ERR_KEY_NOT_FOUND)
+ if (result != HA_ERR_KEY_NOT_FOUND && result != HA_ERR_END_OF_FILE)
DBUG_RETURN(result);
range=0; // Not found, to next range
continue;
@@ -8083,7 +8083,7 @@
DBUG_ENTER("QUICK_GROUP_MIN_MAX_SELECT::reset");
file->extra(HA_EXTRA_KEYREAD); /* We need only the key attributes */
- result= file->ha_index_init(index);
+ result= file->ha_index_init(index, 1);
result= file->index_last(record);
if (result == HA_ERR_END_OF_FILE)
DBUG_RETURN(0);
@@ -8159,7 +8159,7 @@
DBUG_ASSERT(is_last_prefix <= 0);
if (result == HA_ERR_KEY_NOT_FOUND)
continue;
- else if (result)
+ if (result)
break;
if (have_min)
@@ -8189,10 +8189,11 @@
HA_READ_KEY_EXACT);
result= have_min ? min_res : have_max ? max_res : result;
- }
- while (result == HA_ERR_KEY_NOT_FOUND && is_last_prefix != 0);
+ } while ((result == HA_ERR_KEY_NOT_FOUND || result == HA_ERR_END_OF_FILE) &&
+ is_last_prefix != 0);
if (result == 0)
+ {
/*
Partially mimic the behavior of end_select_send. Copy the
field data from Item_field::field into Item_field::result_field
@@ -8200,6 +8201,7 @@
other fields in non-ANSI SQL mode).
*/
copy_fields(&join->tmp_table_param);
+ }
else if (result == HA_ERR_KEY_NOT_FOUND)
result= HA_ERR_END_OF_FILE;
@@ -8226,6 +8228,7 @@
RETURN
0 on success
HA_ERR_KEY_NOT_FOUND if no MIN key was found that fulfills all conditions.
+ HA_ERR_END_OF_FILE - "" -
other if some error occurred
*/
@@ -8279,7 +8282,7 @@
if (key_cmp(index_info->key_part, group_prefix, real_prefix_len))
key_restore(record, tmp_record, index_info, 0);
}
- else if (result == HA_ERR_KEY_NOT_FOUND)
+ else if (result == HA_ERR_KEY_NOT_FOUND || result == HA_ERR_END_OF_FILE)
result= 0; /* There is a result in any case. */
}
}
@@ -8304,6 +8307,7 @@
RETURN
0 on success
HA_ERR_KEY_NOT_FOUND if no MAX key was found that fulfills all conditions.
+ HA_ERR_END_OF_FILE - "" -
other if some error occurred
*/
@@ -8404,6 +8408,7 @@
0 on success
HA_ERR_KEY_NOT_FOUND if there is no key with the given prefix in any of
the ranges
+ HA_ERR_END_OF_FILE - "" -
other if some error
*/
@@ -8448,11 +8453,12 @@
result= file->index_read(record, group_prefix, search_prefix_len,
find_flag);
- if ((result == HA_ERR_KEY_NOT_FOUND) &&
- (cur_range->flag & (EQ_RANGE | NULL_RANGE)))
- continue; /* Check the next range. */
- else if (result)
+ if (result)
{
+ if ((result == HA_ERR_KEY_NOT_FOUND || result == HA_ERR_END_OF_FILE) &&
+ (cur_range->flag & (EQ_RANGE | NULL_RANGE)))
+ continue; /* Check the next range. */
+
/*
In all other cases (HA_ERR_*, HA_READ_KEY_EXACT with NO_MIN_RANGE,
HA_READ_AFTER_KEY, HA_READ_KEY_OR_NEXT) if the lookup failed for this
@@ -8479,7 +8485,7 @@
/* Check if record belongs to the current group. */
if (key_cmp(index_info->key_part, group_prefix, real_prefix_len))
{
- result = HA_ERR_KEY_NOT_FOUND;
+ result= HA_ERR_KEY_NOT_FOUND;
continue;
}
@@ -8497,7 +8503,7 @@
if (!((cur_range->flag & NEAR_MAX) && (cmp_res == -1) ||
(cmp_res <= 0)))
{
- result = HA_ERR_KEY_NOT_FOUND;
+ result= HA_ERR_KEY_NOT_FOUND;
continue;
}
}
@@ -8536,6 +8542,7 @@
0 on success
HA_ERR_KEY_NOT_FOUND if there is no key with the given prefix in any of
the ranges
+ HA_ERR_END_OF_FILE - "" -
other if some error
*/
@@ -8581,10 +8588,12 @@
result= file->index_read(record, group_prefix, search_prefix_len,
find_flag);
- if ((result == HA_ERR_KEY_NOT_FOUND) && (cur_range->flag & EQ_RANGE))
- continue; /* Check the next range. */
if (result)
{
+ if ((result == HA_ERR_KEY_NOT_FOUND || result == HA_ERR_END_OF_FILE) &&
+ (cur_range->flag & EQ_RANGE))
+ continue; /* Check the next range. */
+
/*
In no key was found with this upper bound, there certainly are no keys
in the ranges to the left.
--- 1.44/sql/opt_sum.cc 2005-06-06 13:03:28 +02:00
+++ 1.45/sql/opt_sum.cc 2005-07-18 13:30:13 +02:00
@@ -181,7 +181,7 @@
const_result= 0;
break;
}
- error= table->file->ha_index_init((uint) ref.key);
+ error= table->file->ha_index_init((uint) ref.key, 1);
if (!ref.key_length)
error= table->file->index_first(table->record[0]);
@@ -253,7 +253,7 @@
const_result= 0;
break;
}
- error= table->file->ha_index_init((uint) ref.key);
+ error= table->file->ha_index_init((uint) ref.key, 1);
if (!ref.key_length)
error= table->file->index_last(table->record[0]);
--- 1.40/sql/records.cc 2005-04-07 18:24:08 +02:00
+++ 1.41/sql/records.cc 2005-07-18 13:30:13 +02:00
@@ -31,6 +31,74 @@
/* init struct for read with info->read_record */
+/*
+ init_read_record is used to scan by using a number of different methods.
+ Which method to use is set-up in this call so that later calls to
+ the info->read_record will call the appropriate method using a function
+ pointer.
+
+ There are five methods that relate completely to the sort function
+ filesort. The result of a filesort is retrieved using read_record
+ calls. The other two methods are used for normal table access.
+
+ The filesort will produce references to the records sorted, these
+ references can be stored in memory or in a temporary file.
+
+ The temporary file is normally used when the references doesn't fit into
+ a properly sized memory buffer. For most small queries the references
+ are stored in the memory buffer.
+
+ The temporary file is also used when performing an update where a key is
+ modified.
+
+ Methods used when ref's are in memory (using rr_from_pointers):
+ rr_unpack_from_buffer:
+ ----------------------
+ This method is used when table->sort.addon_field is allocated.
+ This is allocated for most SELECT queries not involving any BLOB's.
+ In this case the records are fetched from a memory buffer.
+ rr_from_pointers:
+ -----------------
+ Used when the above is not true, UPDATE, DELETE and so forth and
+ SELECT's involving BLOB's. It is also used when the addon_field
+ buffer is not allocated due to that its size was bigger than the
+ session variable max_length_for_sort_data.
+ In this case the record data is fetched from the handler using the
+ saved reference using the rnd_pos handler call.
+
+ Methods used when ref's are in a temporary file (using rr_from_tempfile)
+ rr_unpack_from_tempfile:
+ ------------------------
+ Same as rr_unpack_from_buffer except that references are fetched from
+ temporary file. Should obviously not really happen other than in
+ strange configurations.
+
+ rr_from_tempfile:
+ -----------------
+ Same as rr_from_pointers except that references are fetched from
+ temporary file instead of from
+ rr_from_cache:
+ --------------
+ This is a special variant of rr_from_tempfile that can be used for
+ handlers that is not using the HA_FAST_KEY_READ table flag. Instead
+ of reading the references one by one from the temporary file it reads
+ a set of them, sorts them and reads all of them into a buffer which
+ is then used for a number of subsequent calls to rr_from_cache.
+ It is only used for SELECT queries and a number of other conditions
+ on table size.
+
+ All other accesses use either index access methods (rr_quick) or a full
+ table scan (rr_sequential).
+ rr_quick:
+ ---------
+ rr_quick uses one of the QUICK_SELECT classes in opt_range.cc to
+ perform an index scan. There are loads of functionality hidden
+ in these quick classes. It handles all index scans of various kinds.
+ rr_sequential:
+ --------------
+ This is the most basic access method of a table using rnd_init,
+ rnd_next and rnd_end. No indexes are used.
+*/
void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
SQL_SELECT *select,
int use_record_cache, bool print_error)
--- 1.148/sql/sql_acl.cc 2005-07-12 19:23:25 +02:00
+++ 1.149/sql/sql_acl.cc 2005-07-18 13:30:14 +02:00
@@ -2048,7 +2048,7 @@
key_copy(key, col_privs->record[0], col_privs->key_info, key_prefix_len);
col_privs->field[4]->store("",0, &my_charset_latin1);
- col_privs->file->ha_index_init(0);
+ col_privs->file->ha_index_init(0, 1);
if (col_privs->file->index_read(col_privs->record[0],
(byte*) key,
key_prefix_len, HA_READ_KEY_EXACT))
@@ -2193,7 +2193,7 @@
List_iterator <LEX_COLUMN> iter(columns);
class LEX_COLUMN *column;
- table->file->ha_index_init(0);
+ table->file->ha_index_init(0, 1);
while ((column= iter++))
{
ulong privileges= column->rights;
@@ -3168,8 +3168,8 @@
t_table = tables[0].table; c_table = tables[1].table;
p_table= tables[2].table;
- t_table->file->ha_index_init(0);
- p_table->file->ha_index_init(0);
+ t_table->file->ha_index_init(0, 1);
+ p_table->file->ha_index_init(0, 1);
if (!t_table->file->index_first(t_table->record[0]))
{
/* Will be restored by org_thd->store_globals() */
@@ -4473,7 +4473,7 @@
user_key, key_prefix_length,
HA_READ_KEY_EXACT)))
{
- if (error != HA_ERR_KEY_NOT_FOUND)
+ if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
{
table->file->print_error(error, MYF(0));
result= -1;
--- 1.259/sql/sql_base.cc 2005-07-15 19:48:15 +02:00
+++ 1.260/sql/sql_base.cc 2005-07-18 13:30:14 +02:00
@@ -2561,6 +2561,42 @@
/*
+ Find field in table, no side effects, only purpose is to check for field
+ in table object and get reference to the field if found.
+
+ SYNOPSIS
+ find_field_in_table_sef()
+
+ table table where to find
+ name Name of field searched for
+
+ RETURN
+ 0 field is not found
+ # pointer to field
+*/
+
+Field *find_field_in_table_sef(TABLE *table, const char *name)
+{
+ Field **field_ptr;
+ if (table->s->name_hash.records)
+ field_ptr= (Field**)hash_search(&table->s->name_hash,(byte*) name,
+ strlen(name));
+ else
+ {
+ if (!(field_ptr= table->field))
+ return (Field *)0;
+ for (; *field_ptr; ++field_ptr)
+ if (!my_strcasecmp(system_charset_info, (*field_ptr)->field_name, name))
+ break;
+ }
+ if (field_ptr)
+ return *field_ptr;
+ else
+ return (Field *)0;
+}
+
+
+/*
Find field in table
SYNOPSIS
@@ -2623,13 +2659,16 @@
(bool)(thd->set_query_id-1));
if (field->query_id != thd->query_id)
{
+ if (table->get_fields_in_item_tree)
+ field->flags|= GET_FIXED_FIELDS_FLAG;
field->query_id=thd->query_id;
table->used_fields++;
table->used_keys.intersect(field->part_of_key);
}
else
thd->dupp_field=field;
- }
+ } else if (table->get_fields_in_item_tree)
+ field->flags|= GET_FIXED_FIELDS_FLAG;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (check_grants && check_grant_column(thd, &table->grant,
table->s->db,
--- 1.153/sql/sql_lex.cc 2005-07-15 15:08:29 +02:00
+++ 1.154/sql/sql_lex.cc 2005-07-18 13:30:15 +02:00
@@ -155,6 +155,7 @@
lex->yylineno = 1;
lex->in_comment=0;
lex->length=0;
+ lex->part_info= 0;
lex->select_lex.in_sum_expr=0;
lex->select_lex.expr_list.empty();
lex->select_lex.ftfunc_list_alloc.empty();
--- 1.187/sql/sql_lex.h 2005-07-15 15:08:29 +02:00
+++ 1.188/sql/sql_lex.h 2005-07-18 13:30:15 +02:00
@@ -25,6 +25,7 @@
class sp_name;
class sp_instr;
class sp_pcontext;
+class partition_info;
/*
The following hack is needed because mysql_yacc.cc does not define
@@ -721,6 +722,8 @@
TABLE_LIST **query_tables_last;
/* store original leaf_tables for INSERT SELECT and PS/SP */
TABLE_LIST *leaf_tables_insert;
+ /* Partition info structure filled in by PARTITION BY parse part */
+ partition_info *part_info;
List<key_part_spec> col_list;
List<key_part_spec> ref_list;
--- 1.348/sql/sql_select.cc 2005-07-15 15:08:30 +02:00
+++ 1.349/sql/sql_select.cc 2005-07-18 13:30:15 +02:00
@@ -1277,6 +1277,9 @@
/* Copy data to the temporary table */
thd->proc_info= "Copying to tmp table";
DBUG_PRINT("info", ("%s", thd->proc_info));
+ if (!curr_join->sort_and_group &&
+ curr_join->const_tables != curr_join->tables)
+ curr_join->join_tab[curr_join->const_tables].sorted= 0;
if ((tmp_error= do_select(curr_join, (List<Item> *) 0, curr_tmp_table, 0)))
{
error= tmp_error;
@@ -1423,6 +1426,9 @@
1, TRUE))
DBUG_VOID_RETURN;
curr_join->group_list= 0;
+ if (!curr_join->sort_and_group &&
+ curr_join->const_tables != curr_join->tables)
+ curr_join->join_tab[curr_join->const_tables].sorted= 0;
if (setup_sum_funcs(curr_join->thd, curr_join->sum_funcs) ||
(tmp_error= do_select(curr_join, (List<Item> *) 0, curr_tmp_table,
0)))
@@ -1608,6 +1614,16 @@
(select_options & OPTION_FOUND_ROWS ?
HA_POS_ERROR : unit->select_limit_cnt)))
DBUG_VOID_RETURN;
+ if (curr_join->const_tables != curr_join->tables &&
+ !curr_join->join_tab[curr_join->const_tables].table->sort.io_cache)
+ {
+ /*
+ If no IO cache exists for the first table then we are using an
+ INDEX SCAN and no filesort. Thus we should not remove the sorted
+ attribute on the INDEX SCAN.
+ */
+ skip_sort_order= 1;
+ }
}
}
/* XXX: When can we have here thd->net.report_error not zero? */
@@ -5659,6 +5675,7 @@
uint i;
bool statistics= test(!(join->select_options & SELECT_DESCRIBE));
+ bool sorted= 1;
DBUG_ENTER("make_join_readinfo");
for (i=join->const_tables ; i < join->tables ; i++)
@@ -5668,6 +5685,8 @@
tab->read_record.table= table;
tab->read_record.file=table->file;
tab->next_select=sub_select; /* normal select */
+ tab->sorted= sorted;
+ sorted= 0; // only first must be sorted
switch (tab->type) {
case JT_SYSTEM: // Only happens with left join
table->status=STATUS_NO_RECORD;
@@ -8915,7 +8934,12 @@
new_table.file->extra(HA_EXTRA_WRITE_CACHE);
#endif
- /* copy all old rows */
+ /*
+ copy all old rows from heap table to MyISAM table
+ This is the only code that uses record[1] to read/write but this
+ is safe as this is a temporary MyISAM table without timestamp/autoincrement
+ or partitioning.
+ */
while (!table->file->rnd_next(new_table.record[1]))
{
if ((write_err=new_table.file->write_row(new_table.record[1])))
@@ -9046,7 +9070,7 @@
empty_record(table);
if (table->group && join->tmp_table_param.sum_func_count &&
table->s->keys && !table->file->inited)
- table->file->ha_index_init(0);
+ table->file->ha_index_init(0, 0);
}
/* Set up select_end */
join->join_tab[join->tables-1].next_select= setup_end_select_func(join);
@@ -9660,7 +9684,13 @@
table->file->extra(HA_EXTRA_KEYREAD);
tab->index= tab->ref.key;
}
- if ((error=join_read_const(tab)))
+ error=join_read_const(tab);
+ if (table->key_read)
+ {
+ table->key_read=0;
+ table->file->extra(HA_EXTRA_NO_KEYREAD);
+ }
+ if (error)
{
tab->info="unique row not found";
/* Mark for EXPLAIN that the row was not found */
@@ -9668,11 +9698,6 @@
if (!table->maybe_null || error > 0)
DBUG_RETURN(error);
}
- if (table->key_read)
- {
- table->key_read=0;
- table->file->extra(HA_EXTRA_NO_KEYREAD);
- }
}
if (*tab->on_expr_ref && !table->null_row)
{
@@ -9744,7 +9769,7 @@
table->status= STATUS_NOT_FOUND;
mark_as_null_row(tab->table);
empty_record(table);
- if (error != HA_ERR_KEY_NOT_FOUND)
+ if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
return report_error(table, error);
return -1;
}
@@ -9767,7 +9792,9 @@
TABLE *table= tab->table;
if (!table->file->inited)
- table->file->ha_index_init(tab->ref.key);
+ {
+ table->file->ha_index_init(tab->ref.key, tab->sorted);
+ }
if (cmp_buffer_with_ref(tab) ||
(table->status & (STATUS_GARBAGE | STATUS_NO_PARENT | STATUS_NULL_ROW)))
{
@@ -9779,7 +9806,7 @@
error=table->file->index_read(table->record[0],
tab->ref.key_buff,
tab->ref.key_length,HA_READ_KEY_EXACT);
- if (error && error != HA_ERR_KEY_NOT_FOUND)
+ if (error && error != HA_ERR_KEY_NOT_FOUND && error !=
HA_ERR_END_OF_FILE)
return report_error(table, error);
}
table->null_row=0;
@@ -9794,14 +9821,16 @@
TABLE *table= tab->table;
if (!table->file->inited)
- table->file->ha_index_init(tab->ref.key);
+ {
+ table->file->ha_index_init(tab->ref.key, tab->sorted);
+ }
if (cp_buffer_from_ref(tab->join->thd, &tab->ref))
return -1;
if ((error=table->file->index_read(table->record[0],
tab->ref.key_buff,
tab->ref.key_length,HA_READ_KEY_EXACT)))
{
- if (error != HA_ERR_KEY_NOT_FOUND)
+ if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
return report_error(table, error);
return -1; /* purecov: inspected */
}
@@ -9821,14 +9850,14 @@
TABLE *table= tab->table;
if (!table->file->inited)
- table->file->ha_index_init(tab->ref.key);
+ table->file->ha_index_init(tab->ref.key, tab->sorted);
if (cp_buffer_from_ref(tab->join->thd, &tab->ref))
return -1;
if ((error=table->file->index_read_last(table->record[0],
tab->ref.key_buff,
tab->ref.key_length)))
{
- if (error != HA_ERR_KEY_NOT_FOUND)
+ if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
return report_error(table, error);
return -1; /* purecov: inspected */
}
@@ -9931,7 +9960,7 @@
tab->read_record.index=tab->index;
tab->read_record.record=table->record[0];
if (!table->file->inited)
- table->file->ha_index_init(tab->index);
+ table->file->ha_index_init(tab->index, tab->sorted);
if ((error=tab->table->file->index_first(tab->table->record[0])))
{
if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
@@ -9970,7 +9999,7 @@
tab->read_record.index=tab->index;
tab->read_record.record=table->record[0];
if (!table->file->inited)
- table->file->ha_index_init(tab->index);
+ table->file->ha_index_init(tab->index, 1);
if ((error= tab->table->file->index_last(tab->table->record[0])))
return report_error(table, error);
return 0;
@@ -9994,7 +10023,7 @@
TABLE *table= tab->table;
if (!table->file->inited)
- table->file->ha_index_init(tab->ref.key);
+ table->file->ha_index_init(tab->ref.key, 1);
#if NOT_USED_YET
if (cp_buffer_from_ref(tab->join->thd, &tab->ref)) // as ft-key doesn't
use store_key's
return -1; // see also FT_SELECT::init()
@@ -10380,7 +10409,7 @@
error, 0))
DBUG_RETURN(NESTED_LOOP_ERROR); // Not a table_is_full error
/* Change method to update rows */
- table->file->ha_index_init(0);
+ table->file->ha_index_init(0, 0);
join->join_tab[join->tables-1].next_select=end_unique_update;
}
join->send_records++;
--- 1.92/sql/sql_select.h 2005-07-14 13:27:15 +02:00
+++ 1.93/sql/sql_select.h 2005-07-18 13:30:16 +02:00
@@ -133,6 +133,7 @@
uint used_fields,used_fieldlength,used_blobs;
enum join_type type;
bool cached_eq_ref_table,eq_ref_table,not_used_in_distinct;
+ bool sorted;
TABLE_REF ref;
JOIN_CACHE cache;
JOIN *join;
--- 1.253/sql/sql_show.cc 2005-07-07 15:48:40 +02:00
+++ 1.254/sql/sql_show.cc 2005-07-18 13:30:16 +02:00
@@ -963,11 +963,16 @@
packet->append("\n)", 2);
if (!(thd->variables.sql_mode & MODE_NO_TABLE_OPTIONS) &&
!foreign_db_mode)
{
- if (thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40))
- packet->append(" TYPE=", 6);
- else
- packet->append(" ENGINE=", 8);
- packet->append(file->table_type());
+#ifdef HAVE_PARTITION_DB
+ if (!table->s->part_info)
+#endif
+ {
+ if (thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40))
+ packet->append(" TYPE=", 6);
+ else
+ packet->append(" ENGINE=", 8);
+ packet->append(file->table_type());
+ }
if (share->table_charset &&
!(thd->variables.sql_mode & MODE_MYSQL323) &&
@@ -1034,6 +1039,23 @@
append_directory(thd, packet, "DATA", create_info.data_file_name);
append_directory(thd, packet, "INDEX", create_info.index_file_name);
}
+#ifdef HAVE_PARTITION_DB
+ {
+ /*
+ Partition syntax for CREATE TABLE is at the end of the syntax.
+ */
+ uint part_syntax_len;
+ char *part_syntax;
+ if (table->s->part_info &&
+ ((part_syntax= generate_partition_syntax(table->s->part_info,
+ &part_syntax_len,
+ FALSE))))
+ {
+ packet->append(part_syntax, part_syntax_len);
+ my_free(part_syntax, MYF(0));
+ }
+ }
+#endif
DBUG_RETURN(0);
}
@@ -2728,7 +2750,7 @@
{
DBUG_RETURN(1);
}
- proc_table->file->ha_index_init(0);
+ proc_table->file->ha_index_init(0, 1);
if ((res= proc_table->file->index_first(proc_table->record[0])))
{
res= (res == HA_ERR_END_OF_FILE) ? 0 : 1;
--- 1.254/sql/sql_table.cc 2005-07-15 15:08:31 +02:00
+++ 1.255/sql/sql_table.cc 2005-07-18 13:30:16 +02:00
@@ -28,6 +28,7 @@
#include <io.h>
#endif
+
const char *primary_key_name="PRIMARY";
static bool check_if_keyname_exists(const char *name,KEY *start, KEY *end);
@@ -1513,7 +1514,66 @@
if (create_info->row_type == ROW_TYPE_DYNAMIC)
db_options|=HA_OPTION_PACK_RECORD;
alias= table_case_name(create_info, table_name);
- file=get_new_handler((TABLE*) 0, create_info->db_type);
+ if (!(file=get_new_handler((TABLE*) 0, create_info->db_type)))
+ {
+ my_error(ER_OUTOFMEMORY, MYF(0), 128);//128 bytes invented
+ DBUG_RETURN(TRUE);
+ }
+#ifdef HAVE_PARTITION_DB
+ partition_info *part_info= thd->lex->part_info;
+ if (part_info)
+ {
+ /*
+ The table has been specified as a partitioned table.
+ If this is part of an ALTER TABLE the handler will be the partition
+ handler but we need to specify the default handler to use for
+ partitions also in the call to check_partition_info. We transport
+ this information in the default_db_type variable, it is either
+ DB_TYPE_DEFAULT or the engine set in the ALTER TABLE command.
+ */
+ enum db_type part_engine_type= create_info->db_type;
+ char *part_syntax_buf;
+ uint syntax_len;
+ if (part_engine_type == DB_TYPE_PARTITION_DB)
+ {
+ /*
+ This only happens at ALTER TABLE.
+ default_engine_type was assigned from the engine set in the ALTER
+ TABLE command.
+ */
+ part_engine_type= ha_checktype(thd,
+ part_info->default_engine_type, 0, 0);
+ }
+ if (check_partition_info(part_info, part_engine_type,
+ file, create_info->max_rows))
+ DBUG_RETURN(TRUE);
+ /*
+ We reverse the partitioning parser and generate a standard format
+ for syntax stored in frm file.
+ */
+ if (!(part_syntax_buf= generate_partition_syntax(part_info,
+ &syntax_len,
+ TRUE)))
+ DBUG_RETURN(TRUE);
+ part_info->part_info_string= part_syntax_buf;
+ part_info->part_info_len= syntax_len;
+ if ((!(file->partition_flags() & HA_CAN_PARTITION)) ||
+ create_info->db_type == DB_TYPE_PARTITION_DB)
+ {
+ /*