Merge lp:~paul-mccullagh/maria/maria-pbxt-rc3 into lp:~maria-captains/maria/5.1-converting

Proposed by Paul McCullagh
Status: Merged
Approved by: Kristian Nielsen
Approved revision: not available
Merged at revision: not available
Proposed branch: lp:~paul-mccullagh/maria/maria-pbxt-rc3
Merge into: lp:~maria-captains/maria/5.1-converting
Diff against target: 5759 lines (+2595/-366)
47 files modified
sql/handler.cc (+9/-1)
storage/pbxt/ChangeLog (+52/-0)
storage/pbxt/src/Makefile.am (+2/-2)
storage/pbxt/src/backup_xt.cc (+802/-0)
storage/pbxt/src/backup_xt.h (+34/-0)
storage/pbxt/src/cache_xt.cc (+7/-3)
storage/pbxt/src/cache_xt.h (+1/-1)
storage/pbxt/src/database_xt.cc (+14/-0)
storage/pbxt/src/database_xt.h (+8/-0)
storage/pbxt/src/datadic_xt.cc (+1/-6)
storage/pbxt/src/datalog_xt.cc (+4/-4)
storage/pbxt/src/discover_xt.cc (+301/-15)
storage/pbxt/src/filesys_xt.cc (+3/-5)
storage/pbxt/src/filesys_xt.h (+1/-1)
storage/pbxt/src/ha_pbxt.cc (+526/-119)
storage/pbxt/src/ha_pbxt.h (+26/-9)
storage/pbxt/src/ha_xtsys.h (+2/-1)
storage/pbxt/src/heap_xt.cc (+1/-1)
storage/pbxt/src/index_xt.cc (+18/-7)
storage/pbxt/src/lock_xt.cc (+1/-1)
storage/pbxt/src/locklist_xt.h (+7/-2)
storage/pbxt/src/memory_xt.cc (+2/-3)
storage/pbxt/src/myxt_xt.cc (+164/-29)
storage/pbxt/src/myxt_xt.h (+4/-0)
storage/pbxt/src/pbms.h (+12/-12)
storage/pbxt/src/pbms_enabled.cc (+11/-12)
storage/pbxt/src/pbms_enabled.h (+0/-7)
storage/pbxt/src/pthread_xt.cc (+2/-2)
storage/pbxt/src/restart_xt.cc (+119/-49)
storage/pbxt/src/restart_xt.h (+13/-1)
storage/pbxt/src/strutil_xt.cc (+10/-4)
storage/pbxt/src/systab_xt.cc (+2/-2)
storage/pbxt/src/tabcache_xt.cc (+3/-1)
storage/pbxt/src/tabcache_xt.h (+1/-1)
storage/pbxt/src/table_xt.cc (+85/-20)
storage/pbxt/src/table_xt.h (+3/-2)
storage/pbxt/src/thread_xt.cc (+16/-1)
storage/pbxt/src/thread_xt.h (+4/-1)
storage/pbxt/src/util_xt.cc (+17/-0)
storage/pbxt/src/util_xt.h (+1/-0)
storage/pbxt/src/xaction_xt.cc (+169/-6)
storage/pbxt/src/xaction_xt.h (+29/-1)
storage/pbxt/src/xactlog_xt.cc (+48/-23)
storage/pbxt/src/xactlog_xt.h (+12/-2)
storage/pbxt/src/xt_config.h (+15/-2)
storage/pbxt/src/xt_defs.h (+30/-7)
storage/pbxt/src/xt_errno.h (+3/-0)
To merge this branch: bzr merge lp:~paul-mccullagh/maria/maria-pbxt-rc3
Reviewer Review Type Date Requested Status
Kristian Nielsen Approve
Paul McCullagh Pending
Review via email: mp+15934@code.launchpad.net

This proposal supersedes a proposal from 2009-12-01.

To post a comment you must log in.
Revision history for this message
Paul McCullagh (paul-mccullagh) wrote : Posted in a previous version of this proposal
Download full text (3.5 KiB)

This is the 3rd RC release of PBXT. It includes a number of bug fixes (some specifically for MariaDB), and 2 features:

- XA/2-Phase commit support
- Online backup native driver for PBXT

The backup uses the MySQL backup API (MySQL 6.0/5.4), and is not yet available in MariaDB.

Release notes since the RC2 version already in MariaDB are as follows:

------- 1.0.09f RC3 - 2009-11-30

RN291: Fixed bug #489088: On shutdown MySQL reports: [Warning] Plugin 'PBXT' will be forced to shutdown.

RN290: Fixed bug #345524: pbxt does not compile on 64 bit windows. Currently atomic operations are not supported on this platform.

RN286: Fixed a bug introduced in RN281, which could cause an index scan to hang. The original change was to prevent a warning in Valgrind.

RN285: Merged changes required to compile with Drizzle.

RN284: Fixed bug that cause the error "[ERROR] Invalid (old?) table or database name 'mysqld.1'", when running temp_table.test under MariaDB (thanks to Monty for his initial bug fix). Added a fix for partition table names as well.

RN283: Added win_inttypes.h to the distribution. This file is only required for the Windows build.

RN282: Fixed bug #451101: jump or move depends on uninitialised value in myxt_get_key_length

RN281: Fixed bug #451080: Uninitialised memory write in XTDatabaseLog::xlog_append

RN280: Fixed bug #451085: jump or move depends on uninitialised value in my_type_to_string

RN279: Fixed bug #441000: xtstat crashes with segmentation fault on startup if max_pbxt_threads exceeded.

------- 1.0.09e RC3 - 2009-11-20

RN278: Fixed compile error with MySQL 5.1.41.

------- 1.0.09d RC3 - 2009-09-30

RN277: Added r/o flag to pbxt_max_threads server variable (this fix is related to bug #430637)

RN276: Added test case for replication on tables w/o PKs (see bug #430716)

RN275: Fixed bug #430600: 'Failed to read auto-increment value from storage engine' error.

RN274: Fixed bug #431240: This report is public edit xtstat fails if no PBXT table has been created. xtstat now accepts --database=information_schema or --database=pbxt. Depending on this setting PBXT will either use the information_schema.pbxt_statistics or the pbxt.statistics table. If information_schema is used, then the statistics are displayed even when no PBXT table exists. Recovery activity is also displayed, unless pbxt_support_xa=1, in which case MySQL will wait for PBXT recovery to complete before allowing connections.

RN273: Fixed bug #430633: XA_RBDEADLOCK is not returned on XA END after the transacting ended with a deadlock.

RN272: Fixed bug #430596: Backup/restore does not work well even on a basic PBXT table with auto-increment.

------- 1.0.09c RC3 - 2009-09-16

RN271: Windows build update: now you can simply put the pbxt directory under <mysql-root>/storage and build the PBXT engine as a part of the source tree. The engine will be linked statically. Be sure to specify the WITH_PBXT_STORAGE_ENGINE option when running win\configure.js

RN270: Correctly disabled PBMS so that this version now compiles under Windows. If PBMS_ENABLED is defined, PBXT will not compile under Windows becaause of a getpid() call in pbms.h.

------- 1.0.09 RC3 - 2009-09-09

RN26...

Read more...

Revision history for this message
Paul McCullagh (paul-mccullagh) wrote : Posted in a previous version of this proposal

This patch changes MariaDB code in one case:

File handler.cc, Line 1591

DBUG_ASSERT(total_ha_2pc == (ulong) opt_bin_log+1); // only InnoDB and binlog

This line has been commented out, because the assertions fails now that PBXT supports XA.

Although this assertion implies that not everything will work, I have not found any problem with the stability of MySQL due to the addition of PBXT XA.

PBXT XA can be disabled by setting pbxt_support_xa=0, it is enabled by default.

Revision history for this message
Paul McCullagh (paul-mccullagh) wrote : Posted in a previous version of this proposal

I have made 2 changes:

1. I have improved the bug fix in RN291 (bug #489088). The problem was: [Warning] Plugin 'PBXT' will be forced to shutdown. The bug fix caused a crash under certain circumstances. This has been fixed.

2. I have def'd out the following code (changed ifndef to ifdef):

#ifndef WILL_BE_DELETED_LATER
  /*
    for now, only InnoDB supports 2pc. It means we can always safely
    rollback all pending transactions, without risking inconsistent data
  */
  DBUG_ASSERT(total_ha_2pc == (ulong) opt_bin_log+1); // only InnoDB and binlog
  tc_heuristic_recover= TC_HEURISTIC_RECOVER_ROLLBACK; // forcing ROLLBACK
  info.dry_run=FALSE;
#endif

review: Needs Resubmitting
Revision history for this message
Paul McCullagh (paul-mccullagh) wrote :

I have made 2 changes to the original proposal:

1. I have improved the bug fix in RN291 (bug #489088). The problem was: [Warning] Plugin 'PBXT' will be forced to shutdown. The bug fix caused a crash under certain circumstances. This has been fixed.

2. I have def'd out the following code (changed ifndef to ifdef):

#ifndef WILL_BE_DELETED_LATER
  /*
    for now, only InnoDB supports 2pc. It means we can always safely
    rollback all pending transactions, without risking inconsistent data
  */
  DBUG_ASSERT(total_ha_2pc == (ulong) opt_bin_log+1); // only InnoDB and binlog
  tc_heuristic_recover= TC_HEURISTIC_RECOVER_ROLLBACK; // forcing ROLLBACK
  info.dry_run=FALSE;
#endif

Revision history for this message
Kristian Nielsen (knielsen) wrote :

Merged into lp:maria.

We are still working on solving the test failure in pbxt.join_nested. But I realised that this failure was introduced when we merged MySQL 5.1.41, not with this merge. So there was no reason to delay this merge. Thanks for your work!

review: Approve
Revision history for this message
Paul McCullagh (paul-mccullagh) wrote :

Hi Kristian,

We will also check this out as soon as the merge is complete. We have
just completed testing with MySQL 5.1.41, and have all tests running.

@Vlad: did we have any fixes for pbxt.join_nested during our testing
of RC4 and 5.1.41?

Best regards,

Paul

On Dec 21, 2009, at 10:44 AM, Kristian Nielsen wrote:

> Review: Approve
> Merged into lp:maria.
>
> We are still working on solving the test failure in
> pbxt.join_nested. But I realised that this failure was introduced
> when we merged MySQL 5.1.41, not with this merge. So there was no
> reason to delay this merge. Thanks for your work!
>
> --
> https://code.launchpad.net/~paul-mccullagh/maria/maria-pbxt-
> rc3/+merge/15934
> You are the owner of lp:~paul-mccullagh/maria/maria-pbxt-rc3.

--
Paul McCullagh
PrimeBase Technologies
www.primebase.org
www.blobstreaming.org
pbxt.blogspot.com

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'sql/handler.cc'
--- sql/handler.cc 2009-12-03 11:19:05 +0000
+++ sql/handler.cc 2009-12-10 11:57:20 +0000
@@ -1584,7 +1584,15 @@
1584 if (info.commit_list)1584 if (info.commit_list)
1585 sql_print_information("Starting crash recovery...");1585 sql_print_information("Starting crash recovery...");
15861586
1587#ifndef WILL_BE_DELETED_LATER1587/* With PBXT 1.0.09 2 engines now support XA. According to Sergei, this
1588 code below should therefore be removed. The code below
1589 handles the case when the engines report prepared transactions,
1590 but the binlogs are missing or have no recovery information.
1591 In this case the tc_heuristic_recover variable determines whether
1592 prepared transcations should be committed or rolled back.
1593 If there is only one engine, then rollback is safe.
1594 */
1595#ifdef WILL_BE_DELETED_LATER
1588 /*1596 /*
1589 for now, only InnoDB supports 2pc. It means we can always safely1597 for now, only InnoDB supports 2pc. It means we can always safely
1590 rollback all pending transactions, without risking inconsistent data1598 rollback all pending transactions, without risking inconsistent data
15911599
=== modified file 'storage/pbxt/ChangeLog'
--- storage/pbxt/ChangeLog 2009-09-03 06:15:03 +0000
+++ storage/pbxt/ChangeLog 2009-12-10 11:57:20 +0000
@@ -1,6 +1,58 @@
1PBXT Release Notes1PBXT Release Notes
2==================2==================
33
4------- 1.0.09f RC3 - 2009-11-30
5
6RN291: Fixed bug #489088: On shutdown MySQL reports: [Warning] Plugin 'PBXT' will be forced to shutdown.
7
8RN290: Fixed bug #345524: pbxt does not compile on 64 bit windows. Currently atomic operations are not supported on this platform.
9
10RN286: Fixed a bug introduced in RN281, which could cause an index scan to hang. The original change was to prevent a warning in Valgrind.
11
12RN285: Merged changes required to compile with Drizzle.
13
14RN284: Fixed bug that cause the error "[ERROR] Invalid (old?) table or database name 'mysqld.1'", when running temp_table.test under MariaDB (thanks to Monty for his initial bug fix). Added a fix for partition table names as well.
15
16RN283: Added win_inttypes.h to the distribution. This file is only required for the Windows build.
17
18RN282: Fixed bug #451101: jump or move depends on uninitialised value in myxt_get_key_length
19
20RN281: Fixed bug #451080: Uninitialised memory write in XTDatabaseLog::xlog_append
21
22RN280: Fixed bug #451085: jump or move depends on uninitialised value in my_type_to_string
23
24RN279: Fixed bug #441000: xtstat crashes with segmentation fault on startup if max_pbxt_threads exceeded.
25
26------- 1.0.09e RC3 - 2009-11-20
27
28RN278: Fixed compile error with MySQL 5.1.41.
29
30------- 1.0.09d RC3 - 2009-09-30
31
32RN277: Added r/o flag to pbxt_max_threads server variable (this fix is related to bug #430637)
33
34RN276: Added test case for replication on tables w/o PKs (see bug #430716)
35
36RN275: Fixed bug #430600: 'Failed to read auto-increment value from storage engine' error.
37
38RN274: Fixed bug #431240: This report is public edit xtstat fails if no PBXT table has been created. xtstat now accepts --database=information_schema or --database=pbxt. Depending on this setting PBXT will either use the information_schema.pbxt_statistics or the pbxt.statistics table. If information_schema is used, then the statistics are displayed even when no PBXT table exists. Recovery activity is also displayed, unless pbxt_support_xa=1, in which case MySQL will wait for PBXT recovery to complete before allowing connections.
39
40RN273: Fixed bug #430633: XA_RBDEADLOCK is not returned on XA END after the transacting ended with a deadlock.
41
42RN272: Fixed bug #430596: Backup/restore does not work well even on a basic PBXT table with auto-increment.
43
44------- 1.0.09c RC3 - 2009-09-16
45
46RN271: Windows build update: now you can simply put the pbxt directory under <mysql-root>/storage and build the PBXT engine as a part of the source tree. The engine will be linked statically. Be sure to specify the WITH_PBXT_STORAGE_ENGINE option when running win\configure.js
47
48RN270: Correctly disabled PBMS so that this version now compiles under Windows. If PBMS_ENABLED is defined, PBXT will not compile under Windows becaause of a getpid() call in pbms.h.
49
50------- 1.0.09 RC3 - 2009-09-09
51
52RN269: Implemented online backup. A native online backup driver now performs BACKUP and RESTORE DATABASE operations for PBXT. NOTE: This feature is only supported by MySQL 6.0.9 or later.
53
54RN268: Implemented XA support. PBXT now supports all XA related MySQL statements. The variable pbxt_support_xa determines if XA support is enabled. Note: due to MySQL bug #47134, enabling XA support could lead to a crash.
55
4------- 1.0.08d RC2 - 2009-09-0256------- 1.0.08d RC2 - 2009-09-02
557
6RN267: Fixed a bug that caused MySQL to crash on shutdown, after an incorrect command line parameter was given. The crash occurred because the background recovery task was not cleaned up before the PBXT engine was de-initialized.58RN267: Fixed a bug that caused MySQL to crash on shutdown, after an incorrect command line parameter was given. The crash occurred because the background recovery task was not cleaned up before the PBXT engine was de-initialized.
759
=== modified file 'storage/pbxt/src/Makefile.am'
--- storage/pbxt/src/Makefile.am 2009-10-07 07:40:56 +0000
+++ storage/pbxt/src/Makefile.am 2009-12-10 11:57:20 +0000
@@ -22,7 +22,7 @@
22 pbms_enabled.h sortedlist_xt.h strutil_xt.h \22 pbms_enabled.h sortedlist_xt.h strutil_xt.h \
23 tabcache_xt.h table_xt.h trace_xt.h thread_xt.h \23 tabcache_xt.h table_xt.h trace_xt.h thread_xt.h \
24 util_xt.h xaction_xt.h xactlog_xt.h lock_xt.h \24 util_xt.h xaction_xt.h xactlog_xt.h lock_xt.h \
25 systab_xt.h ha_xtsys.h discover_xt.h \25 systab_xt.h ha_xtsys.h discover_xt.h backup_xt.h \
26 pbms.h xt_config.h xt_defs.h xt_errno.h locklist_xt.h26 pbms.h xt_config.h xt_defs.h xt_errno.h locklist_xt.h
27EXTRA_LTLIBRARIES = libpbxt.la27EXTRA_LTLIBRARIES = libpbxt.la
2828
@@ -32,7 +32,7 @@
32 memory_xt.cc myxt_xt.cc pthread_xt.cc restart_xt.cc \32 memory_xt.cc myxt_xt.cc pthread_xt.cc restart_xt.cc \
33 sortedlist_xt.cc strutil_xt.cc \33 sortedlist_xt.cc strutil_xt.cc \
34 tabcache_xt.cc table_xt.cc trace_xt.cc thread_xt.cc \34 tabcache_xt.cc table_xt.cc trace_xt.cc thread_xt.cc \
35 systab_xt.cc ha_xtsys.cc discover_xt.cc \35 systab_xt.cc ha_xtsys.cc discover_xt.cc backup_xt.cc \
36 util_xt.cc xaction_xt.cc xactlog_xt.cc lock_xt.cc locklist_xt.cc36 util_xt.cc xaction_xt.cc xactlog_xt.cc lock_xt.cc locklist_xt.cc
3737
38libpbxt_la_LDFLAGS = -module38libpbxt_la_LDFLAGS = -module
3939
=== added file 'storage/pbxt/src/backup_xt.cc'
--- storage/pbxt/src/backup_xt.cc 1970-01-01 00:00:00 +0000
+++ storage/pbxt/src/backup_xt.cc 2009-12-10 11:57:20 +0000
@@ -0,0 +1,802 @@
1/* Copyright (c) 2009 PrimeBase Technologies GmbH
2 *
3 * PrimeBase XT
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * 2009-09-07 Paul McCullagh
20 *
21 * H&G2JCtL
22 */
23
24#include "xt_config.h"
25
26#ifdef MYSQL_SUPPORTS_BACKUP
27
28#include <string.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include <time.h>
32#include <ctype.h>
33
34#include "mysql_priv.h"
35#include <backup/api_types.h>
36#include <backup/backup_engine.h>
37#include <backup/backup_aux.h> // for build_table_list()
38#include <hash.h>
39
40#include "ha_pbxt.h"
41
42#include "backup_xt.h"
43#include "pthread_xt.h"
44#include "filesys_xt.h"
45#include "database_xt.h"
46#include "strutil_xt.h"
47#include "memory_xt.h"
48#include "trace_xt.h"
49#include "myxt_xt.h"
50
51#ifdef OK
52#undef OK
53#endif
54
55#ifdef byte
56#undef byte
57#endif
58
59#ifdef DEBUG
60//#define TRACE_BACKUP_CALLS
61//#define TEST_SMALL_BLOCK 100000
62#endif
63
64using backup::byte;
65using backup::result_t;
66using backup::version_t;
67using backup::Table_list;
68using backup::Table_ref;
69using backup::Buffer;
70
71#ifdef TRACE_BACKUP_CALLS
72#define XT_TRACE_CALL() ha_trace_function(__FUNC__, NULL)
73#else
74#define XT_TRACE_CALL()
75#endif
76
77#define XT_RESTORE_BATCH_SIZE 10000
78
79#define BUP_STATE_BEFORE_LOCK 0
80#define BUP_STATE_AFTER_LOCK 1
81
82#define BUP_STANDARD_VAR_RECORD 1
83#define BUP_RECORD_BLOCK_4_START 2 // Part of a record, with a 4 byte total length, and 4 byte data length
84#define BUP_RECORD_BLOCK_4 3 // Part of a record, with a 4 byte length
85#define BUP_RECORD_BLOCK_4_END 4 // Last part of a record with a 4 byte length
86
87/*
88 * -----------------------------------------------------------------------
89 * UTILITIES
90 */
91
92#ifdef TRACE_BACKUP_CALLS
93static void ha_trace_function(const char *function, char *table)
94{
95 char func_buf[50], *ptr;
96 XTThreadPtr thread = xt_get_self();
97
98 if ((ptr = strchr(function, '('))) {
99 ptr--;
100 while (ptr > function) {
101 if (!(isalnum(*ptr) || *ptr == '_'))
102 break;
103 ptr--;
104 }
105 ptr++;
106 xt_strcpy(50, func_buf, ptr);
107 if ((ptr = strchr(func_buf, '(')))
108 *ptr = 0;
109 }
110 else
111 xt_strcpy(50, func_buf, function);
112 if (table)
113 printf("%s %s (%s)\n", thread ? thread->t_name : "-unknown-", func_buf, table);
114 else
115 printf("%s %s\n", thread ? thread->t_name : "-unknown-", func_buf);
116}
117#endif
118
119/*
120 * -----------------------------------------------------------------------
121 * BACKUP DRIVER
122 */
123
124class PBXTBackupDriver: public Backup_driver
125{
126 public:
127 PBXTBackupDriver(const Table_list &);
128 virtual ~PBXTBackupDriver();
129
130 virtual size_t size();
131 virtual size_t init_size();
132 virtual result_t begin(const size_t);
133 virtual result_t end();
134 virtual result_t get_data(Buffer &);
135 virtual result_t prelock();
136 virtual result_t lock();
137 virtual result_t unlock();
138 virtual result_t cancel();
139 virtual void free();
140 void lock_tables_TL_READ_NO_INSERT();
141
142 private:
143 XTThreadPtr bd_thread;
144 int bd_state;
145 u_int bd_table_no;
146 XTOpenTablePtr bd_ot;
147 xtWord1 *bd_row_buf;
148
149 /* Non-zero if we last returned only part of
150 * a row.
151 */
152 xtWord1 *db_write_block(xtWord1 *buffer, xtWord1 bup_type, size_t *size, xtWord4 row_len);
153 xtWord1 *db_write_block(xtWord1 *buffer, xtWord1 bup_type, size_t *size, xtWord4 total_len, xtWord4 row_len);
154
155 xtWord4 bd_row_offset;
156 xtWord4 bd_row_size;
157};
158
159
160PBXTBackupDriver::PBXTBackupDriver(const Table_list &tables):
161Backup_driver(tables),
162bd_state(BUP_STATE_BEFORE_LOCK),
163bd_table_no(0),
164bd_ot(NULL),
165bd_row_buf(NULL),
166bd_row_offset(0),
167bd_row_size(0)
168{
169}
170
171PBXTBackupDriver::~PBXTBackupDriver()
172{
173}
174
175/** Estimates total size of backup. @todo improve it */
176size_t PBXTBackupDriver::size()
177{
178 XT_TRACE_CALL();
179 return UNKNOWN_SIZE;
180}
181
182/** Estimates size of backup before lock. @todo improve it */
183size_t PBXTBackupDriver::init_size()
184{
185 XT_TRACE_CALL();
186 return 0;
187}
188
189result_t PBXTBackupDriver::begin(const size_t)
190{
191 THD *thd = current_thd;
192 XTExceptionRec e;
193
194 XT_TRACE_CALL();
195
196 if (!(bd_thread = xt_ha_set_current_thread(thd, &e))) {
197 xt_log_exception(NULL, &e, XT_LOG_DEFAULT);
198 return backup::ERROR;
199 }
200
201 return backup::OK;
202}
203
204result_t PBXTBackupDriver::end()
205{
206 XT_TRACE_CALL();
207 if (bd_ot) {
208 xt_tab_seq_exit(bd_ot);
209 xt_db_return_table_to_pool_ns(bd_ot);
210 bd_ot = NULL;
211 }
212 if (bd_thread->st_xact_data) {
213 if (!xt_xn_commit(bd_thread))
214 return backup::ERROR;
215 }
216 return backup::OK;
217}
218
219xtWord1 *PBXTBackupDriver::db_write_block(xtWord1 *buffer, xtWord1 bup_type, size_t *ret_size, xtWord4 row_len)
220{
221 register size_t size = *ret_size;
222
223 *buffer = bup_type; // Record type identifier.
224 buffer++;
225 size--;
226 memcpy(buffer, bd_ot->ot_row_wbuffer, row_len);
227 buffer += row_len;
228 size -= row_len;
229 *ret_size = size;
230 return buffer;
231}
232
233xtWord1 *PBXTBackupDriver::db_write_block(xtWord1 *buffer, xtWord1 bup_type, size_t *ret_size, xtWord4 total_len, xtWord4 row_len)
234{
235 register size_t size = *ret_size;
236
237 *buffer = bup_type; // Record type identifier.
238 buffer++;
239 size--;
240 if (bup_type == BUP_RECORD_BLOCK_4_START) {
241 XT_SET_DISK_4(buffer, total_len);
242 buffer += 4;
243 size -= 4;
244 }
245 XT_SET_DISK_4(buffer, row_len);
246 buffer += 4;
247 size -= 4;
248 memcpy(buffer, bd_ot->ot_row_wbuffer+bd_row_offset, row_len);
249 buffer += row_len;
250 size -= row_len;
251 bd_row_size -= row_len;
252 bd_row_offset += row_len;
253 *ret_size = size;
254 return buffer;
255}
256
257result_t PBXTBackupDriver::get_data(Buffer &buf)
258{
259 xtBool eof = FALSE;
260 size_t size;
261 xtWord4 row_len;
262 xtWord1 *buffer;
263
264 XT_TRACE_CALL();
265
266 if (bd_state == BUP_STATE_BEFORE_LOCK) {
267 buf.table_num = 0;
268 buf.size = 0;
269 buf.last = FALSE;
270 return backup::READY;
271 }
272
273 /* Open the backup table: */
274 if (!bd_ot) {
275 XTThreadPtr self = bd_thread;
276 XTTableHPtr tab;
277 char path[PATH_MAX];
278
279 if (bd_table_no == m_tables.count()) {
280 buf.size = 0;
281 buf.table_num = 0;
282 buf.last = TRUE;
283 return backup::DONE;
284 }
285
286 m_tables[bd_table_no].internal_name(path, sizeof(path));
287 bd_table_no++;
288 try_(a) {
289 xt_ha_open_database_of_table(self, (XTPathStrPtr) path);
290 tab = xt_use_table(self, (XTPathStrPtr) path, FALSE, FALSE, NULL);
291 pushr_(xt_heap_release, tab);
292 if (!(bd_ot = xt_db_open_table_using_tab(tab, bd_thread)))
293 xt_throw(self);
294 freer_(); // xt_heap_release(tab)
295
296 /* Prepare the seqential scan: */
297 xt_tab_seq_exit(bd_ot);
298 if (!xt_tab_seq_init(bd_ot))
299 xt_throw(self);
300
301 if (bd_row_buf) {
302 xt_free(self, bd_row_buf);
303 bd_row_buf = NULL;
304 }
305 bd_row_buf = (xtWord1 *) xt_malloc(self, bd_ot->ot_table->tab_dic.dic_mysql_buf_size);
306 bd_ot->ot_cols_req = bd_ot->ot_table->tab_dic.dic_no_of_cols;
307 }
308 catch_(a) {
309 ;
310 }
311 cont_(a);
312
313 if (!bd_ot)
314 goto failed;
315 }
316
317 buf.table_num = bd_table_no;
318#ifdef TEST_SMALL_BLOCK
319 buf.size = TEST_SMALL_BLOCK;
320#endif
321 size = buf.size;
322 buffer = (xtWord1 *) buf.data;
323 ASSERT_NS(size > 9);
324
325 /* First check of a record was partically written
326 * last time.
327 */
328 write_row:
329 if (bd_row_size > 0) {
330 row_len = bd_row_size;
331 if (bd_row_offset == 0) {
332 if (row_len+1 > size) {
333 ASSERT_NS(size > 9);
334 row_len = size - 9;
335 buffer = db_write_block(buffer, BUP_RECORD_BLOCK_4_START, &size, bd_row_size, row_len);
336 goto done;
337 }
338 buffer = db_write_block(buffer, BUP_STANDARD_VAR_RECORD, &size, row_len);
339 bd_row_size = 0;
340 }
341 else {
342 if (row_len+5 > size) {
343 row_len = size - 5;
344 buffer = db_write_block(buffer, BUP_RECORD_BLOCK_4, &size, 0, row_len);
345 goto done;
346 }
347 buffer = db_write_block(buffer, BUP_RECORD_BLOCK_4_END, &size, 0, row_len);
348 }
349 }
350
351 /* Now continue with the sequential scan. */
352 while (size > 1) {
353 if (!xt_tab_seq_next(bd_ot, bd_row_buf, &eof))
354 goto failed;
355 if (eof) {
356 /* We will go the next table, on the next call. */
357 xt_tab_seq_exit(bd_ot);
358 xt_db_return_table_to_pool_ns(bd_ot);
359 bd_ot = NULL;
360 break;
361 }
362 if (!(row_len = myxt_store_row_data(bd_ot, 0, (char *) bd_row_buf)))
363 goto failed;
364 if (row_len+1 > size) {
365 /* Does not fit: */
366 bd_row_offset = 0;
367 bd_row_size = row_len;
368 /* Only add part of the row, if there is still
369 * quite a bit of space left:
370 */
371 if (size >= (32 * 1024))
372 goto write_row;
373 break;
374 }
375 buffer = db_write_block(buffer, BUP_STANDARD_VAR_RECORD, &size, row_len);
376 }
377
378 done:
379 buf.size = buf.size - size;
380 /* This indicates wnd of data for a table! */
381 buf.last = eof;
382
383 return backup::OK;
384
385 failed:
386 xt_log_and_clear_exception(bd_thread);
387 return backup::ERROR;
388}
389
390result_t PBXTBackupDriver::prelock()
391{
392 XT_TRACE_CALL();
393 return backup::READY;
394}
395
396result_t PBXTBackupDriver::lock()
397{
398 XT_TRACE_CALL();
399 bd_thread->st_xact_mode = XT_XACT_COMMITTED_READ;
400 bd_thread->st_ignore_fkeys = FALSE;
401 bd_thread->st_auto_commit = FALSE;
402 bd_thread->st_table_trans = FALSE;
403 bd_thread->st_abort_trans = FALSE;
404 bd_thread->st_stat_ended = FALSE;
405 bd_thread->st_stat_trans = FALSE;
406 bd_thread->st_is_update = FALSE;
407 if (!xt_xn_begin(bd_thread))
408 return backup::ERROR;
409 bd_state = BUP_STATE_AFTER_LOCK;
410 return backup::OK;
411}
412
413result_t PBXTBackupDriver::unlock()
414{
415 XT_TRACE_CALL();
416 return backup::OK;
417}
418
419result_t PBXTBackupDriver::cancel()
420{
421 XT_TRACE_CALL();
422 return backup::OK; // free() will be called and suffice
423}
424
425void PBXTBackupDriver::free()
426{
427 XT_TRACE_CALL();
428 if (bd_ot) {
429 xt_tab_seq_exit(bd_ot);
430 xt_db_return_table_to_pool_ns(bd_ot);
431 bd_ot = NULL;
432 }
433 if (bd_row_buf) {
434 xt_free_ns(bd_row_buf);
435 bd_row_buf = NULL;
436 }
437 if (bd_thread->st_xact_data)
438 xt_xn_rollback(bd_thread);
439 delete this;
440}
441
442void PBXTBackupDriver::lock_tables_TL_READ_NO_INSERT()
443{
444 XT_TRACE_CALL();
445}
446
447/*
448 * -----------------------------------------------------------------------
449 * BACKUP DRIVER
450 */
451
452class PBXTRestoreDriver: public Restore_driver
453{
454 public:
455 PBXTRestoreDriver(const Table_list &tables);
456 virtual ~PBXTRestoreDriver();
457
458 virtual result_t begin(const size_t);
459 virtual result_t end();
460 virtual result_t send_data(Buffer &buf);
461 virtual result_t cancel();
462 virtual void free();
463
464 private:
465 XTThreadPtr rd_thread;
466 u_int rd_table_no;
467 XTOpenTablePtr rd_ot;
468 STRUCT_TABLE *rd_my_table;
469 xtWord1 *rb_row_buf;
470 u_int rb_col_cnt;
471 u_int rb_insert_count;
472
473 /* Long rows are accumulated here: */
474 xtWord4 rb_row_len;
475 xtWord4 rb_data_size;
476 xtWord1 *rb_row_data;
477};
478
479PBXTRestoreDriver::PBXTRestoreDriver(const Table_list &tables):
480Restore_driver(tables),
481rd_thread(NULL),
482rd_table_no(0),
483rd_ot(NULL),
484rb_row_buf(NULL),
485rb_row_len(0),
486rb_data_size(0),
487rb_row_data(NULL)
488{
489}
490
491PBXTRestoreDriver::~PBXTRestoreDriver()
492{
493}
494
495result_t PBXTRestoreDriver::begin(const size_t)
496{
497 THD *thd = current_thd;
498 XTExceptionRec e;
499
500 XT_TRACE_CALL();
501
502 if (!(rd_thread = xt_ha_set_current_thread(thd, &e))) {
503 xt_log_exception(NULL, &e, XT_LOG_DEFAULT);
504 return backup::ERROR;
505 }
506
507 return backup::OK;
508}
509
510result_t PBXTRestoreDriver::end()
511{
512 XT_TRACE_CALL();
513 if (rd_ot) {
514 xt_db_return_table_to_pool_ns(rd_ot);
515 rd_ot = NULL;
516 }
517 //if (rb_row_buf) {
518 // xt_free_ns(rb_row_buf);
519 // rb_row_buf = NULL;
520 //}
521 if (rb_row_data) {
522 xt_free_ns(rb_row_data);
523 rb_row_data = NULL;
524 }
525 if (rd_thread->st_xact_data) {
526 if (!xt_xn_commit(rd_thread))
527 return backup::ERROR;
528 }
529 return backup::OK;
530}
531
532
533result_t PBXTRestoreDriver::send_data(Buffer &buf)
534{
535 size_t size;
536 xtWord1 type;
537 xtWord1 *buffer;
538 xtWord4 row_len;
539 xtWord1 *rec_data;
540
541 XT_TRACE_CALL();
542
543 if (buf.table_num != rd_table_no) {
544 XTThreadPtr self = rd_thread;
545 XTTableHPtr tab;
546 char path[PATH_MAX];
547
548 if (rd_ot) {
549 xt_db_return_table_to_pool_ns(rd_ot);
550 rd_ot = NULL;
551 }
552
553 if (rd_thread->st_xact_data) {
554 if (!xt_xn_commit(rd_thread))
555 goto failed;
556 }
557 if (!xt_xn_begin(rd_thread))
558 goto failed;
559 rb_insert_count = 0;
560
561 rd_table_no = buf.table_num;
562 m_tables[rd_table_no-1].internal_name(path, sizeof(path));
563 try_(a) {
564 xt_ha_open_database_of_table(self, (XTPathStrPtr) path);
565 tab = xt_use_table(self, (XTPathStrPtr) path, FALSE, FALSE, NULL);
566 pushr_(xt_heap_release, tab);
567 if (!(rd_ot = xt_db_open_table_using_tab(tab, rd_thread)))
568 xt_throw(self);
569 freer_(); // xt_heap_release(tab)
570
571 rd_my_table = rd_ot->ot_table->tab_dic.dic_my_table;
572 if (rd_my_table->found_next_number_field) {
573 rd_my_table->in_use = current_thd;
574 rd_my_table->next_number_field = rd_my_table->found_next_number_field;
575 rd_my_table->mark_columns_used_by_index_no_reset(rd_my_table->s->next_number_index, rd_my_table->read_set);
576 }
577
578 /* This is safe because only one thread can restore a table at
579 * a time!
580 */
581 rb_row_buf = (xtWord1 *) rd_my_table->record[0];
582 //if (rb_row_buf) {
583 // xt_free(self, rb_row_buf);
584 // rb_row_buf = NULL;
585 //}
586 //rb_row_buf = (xtWord1 *) xt_malloc(self, rd_ot->ot_table->tab_dic.dic_mysql_buf_size);
587
588 rb_col_cnt = rd_ot->ot_table->tab_dic.dic_no_of_cols;
589
590 }
591 catch_(a) {
592 ;
593 }
594 cont_(a);
595
596 if (!rd_ot)
597 goto failed;
598 }
599
600 buffer = (xtWord1 *) buf.data;
601 size = buf.size;
602
603 while (size > 0) {
604 type = *buffer;
605 switch (type) {
606 case BUP_STANDARD_VAR_RECORD:
607 rec_data = buffer + 1;
608 break;
609 case BUP_RECORD_BLOCK_4_START:
610 buffer++;
611 row_len = XT_GET_DISK_4(buffer);
612 buffer += 4;
613 if (rb_data_size < row_len) {
614 if (!xt_realloc_ns((void **) &rb_row_data, row_len))
615 goto failed;
616 rb_data_size = row_len;
617 }
618 row_len = XT_GET_DISK_4(buffer);
619 buffer += 4;
620 ASSERT_NS(row_len <= rb_data_size);
621 if (row_len > rb_data_size) {
622 xt_register_xterr(XT_REG_CONTEXT, XT_ERR_BAD_BACKUP_FORMAT);
623 goto failed;
624 }
625 memcpy(rb_row_data, buffer, row_len);
626 rb_row_len = row_len;
627 buffer += row_len;
628 if (row_len + 9 > size) {
629 xt_register_xterr(XT_REG_CONTEXT, XT_ERR_BAD_BACKUP_FORMAT);
630 goto failed;
631 }
632 size -= row_len + 9;
633 continue;
634 case BUP_RECORD_BLOCK_4:
635 buffer++;
636 row_len = XT_GET_DISK_4(buffer);
637 buffer += 4;
638 ASSERT_NS(rb_row_len + row_len <= rb_data_size);
639 if (rb_row_len + row_len > rb_data_size) {
640 xt_register_xterr(XT_REG_CONTEXT, XT_ERR_BAD_BACKUP_FORMAT);
641 goto failed;
642 }
643 memcpy(rb_row_data + rb_row_len, buffer, row_len);
644 rb_row_len += row_len;
645 buffer += row_len;
646 if (row_len + 5 > size) {
647 xt_register_xterr(XT_REG_CONTEXT, XT_ERR_BAD_BACKUP_FORMAT);
648 goto failed;
649 }
650 size -= row_len + 5;
651 continue;
652 case BUP_RECORD_BLOCK_4_END:
653 buffer++;
654 row_len = XT_GET_DISK_4(buffer);
655 buffer += 4;
656 ASSERT_NS(rb_row_len + row_len <= rb_data_size);
657 if (rb_row_len + row_len > rb_data_size) {
658 xt_register_xterr(XT_REG_CONTEXT, XT_ERR_BAD_BACKUP_FORMAT);
659 goto failed;
660 }
661 memcpy(rb_row_data + rb_row_len, buffer, row_len);
662 buffer += row_len;
663 if (row_len + 5 > size) {
664 xt_register_xterr(XT_REG_CONTEXT, XT_ERR_BAD_BACKUP_FORMAT);
665 goto failed;
666 }
667 size -= row_len + 5;
668 rec_data = rb_row_data;
669 break;
670 default:
671 xt_register_xterr(XT_REG_CONTEXT, XT_ERR_BAD_BACKUP_FORMAT);
672 goto failed;
673 }
674
675 if (!(row_len = myxt_load_row_data(rd_ot, rec_data, rb_row_buf, rb_col_cnt)))
676 goto failed;
677
678 if (rd_ot->ot_table->tab_dic.dic_my_table->found_next_number_field)
679 ha_set_auto_increment(rd_ot, rd_ot->ot_table->tab_dic.dic_my_table->found_next_number_field);
680
681 if (!xt_tab_new_record(rd_ot, rb_row_buf))
682 goto failed;
683
684 if (type == BUP_STANDARD_VAR_RECORD) {
685 buffer += row_len+1;
686 if (row_len + 1 > size) {
687 xt_register_xterr(XT_REG_CONTEXT, XT_ERR_BAD_BACKUP_FORMAT);
688 goto failed;
689 }
690 size -= row_len + 1;
691 }
692
693 rb_insert_count++;
694 if (rb_insert_count == XT_RESTORE_BATCH_SIZE) {
695 if (!xt_xn_commit(rd_thread))
696 goto failed;
697 if (!xt_xn_begin(rd_thread))
698 goto failed;
699 rb_insert_count = 0;
700 }
701 }
702
703 return backup::OK;
704
705 failed:
706 xt_log_and_clear_exception(rd_thread);
707 return backup::ERROR;
708}
709
710
711result_t PBXTRestoreDriver::cancel()
712{
713 XT_TRACE_CALL();
714 /* Nothing to do in cancel(); free() will suffice */
715 return backup::OK;
716}
717
718void PBXTRestoreDriver::free()
719{
720 XT_TRACE_CALL();
721 if (rd_ot) {
722 xt_db_return_table_to_pool_ns(rd_ot);
723 rd_ot = NULL;
724 }
725 //if (rb_row_buf) {
726 // xt_free_ns(rb_row_buf);
727 // rb_row_buf = NULL;
728 //}
729 if (rb_row_data) {
730 xt_free_ns(rb_row_data);
731 rb_row_data = NULL;
732 }
733 if (rd_thread->st_xact_data)
734 xt_xn_rollback(rd_thread);
735 delete this;
736}
737
738/*
739 * -----------------------------------------------------------------------
740 * BACKUP ENGINE FACTORY
741 */
742
743#define PBXT_BACKUP_VERSION 1
744
745
746class PBXTBackupEngine: public Backup_engine
747{
748 public:
749 PBXTBackupEngine() { };
750
751 virtual version_t version() const {
752 return PBXT_BACKUP_VERSION;
753 };
754
755 virtual result_t get_backup(const uint32, const Table_list &, Backup_driver* &);
756
757 virtual result_t get_restore(const version_t, const uint32, const Table_list &,Restore_driver* &);
758
759 virtual void free()
760 {
761 delete this;
762 }
763};
764
765result_t PBXTBackupEngine::get_backup(const u_int count, const Table_list &tables, Backup_driver* &drv)
766{
767 PBXTBackupDriver *ptr = new PBXTBackupDriver(tables);
768
769 if (!ptr)
770 return backup::ERROR;
771 drv = ptr;
772 return backup::OK;
773}
774
775result_t PBXTBackupEngine::get_restore(const version_t ver, const uint32,
776 const Table_list &tables, Restore_driver* &drv)
777{
778 if (ver > PBXT_BACKUP_VERSION)
779 {
780 return backup::ERROR;
781 }
782
783 PBXTRestoreDriver *ptr = new PBXTRestoreDriver(tables);
784
785 if (!ptr)
786 return backup::ERROR;
787 drv = (Restore_driver *) ptr;
788 return backup::OK;
789}
790
791
792Backup_result_t pbxt_backup_engine(handlerton *self, Backup_engine* &be)
793{
794 be = new PBXTBackupEngine();
795
796 if (!be)
797 return backup::ERROR;
798
799 return backup::OK;
800}
801
802#endif
0803
=== added file 'storage/pbxt/src/backup_xt.h'
--- storage/pbxt/src/backup_xt.h 1970-01-01 00:00:00 +0000
+++ storage/pbxt/src/backup_xt.h 2009-12-10 11:57:20 +0000
@@ -0,0 +1,34 @@
1/* Copyright (c) 2009 PrimeBase Technologies GmbH
2 *
3 * PrimeBase XT
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * 2009-09-07 Paul McCullagh
20 *
21 * H&G2JCtL
22 */
23
24#ifndef __backup_xt_h__
25#define __backup_xt_h__
26
27#include "xt_defs.h"
28
29#ifdef MYSQL_SUPPORTS_BACKUP
30
31Backup_result_t pbxt_backup_engine(handlerton *self, Backup_engine* &be);
32
33#endif
34#endif
035
=== modified file 'storage/pbxt/src/cache_xt.cc'
--- storage/pbxt/src/cache_xt.cc 2009-10-30 18:50:56 +0000
+++ storage/pbxt/src/cache_xt.cc 2009-12-10 11:57:20 +0000
@@ -73,7 +73,7 @@
73#define IDX_CAC_UNLOCK(i, o) xt_xsmutex_unlock(&(i)->cs_lock, (o)->t_id)73#define IDX_CAC_UNLOCK(i, o) xt_xsmutex_unlock(&(i)->cs_lock, (o)->t_id)
74#elif defined(IDX_CAC_USE_PTHREAD_RW)74#elif defined(IDX_CAC_USE_PTHREAD_RW)
75#define IDX_CAC_LOCK_TYPE xt_rwlock_type75#define IDX_CAC_LOCK_TYPE xt_rwlock_type
76#define IDX_CAC_INIT_LOCK(s, i) xt_init_rwlock(s, &(i)->cs_lock)76#define IDX_CAC_INIT_LOCK(s, i) xt_init_rwlock_with_autoname(s, &(i)->cs_lock)
77#define IDX_CAC_FREE_LOCK(s, i) xt_free_rwlock(&(i)->cs_lock) 77#define IDX_CAC_FREE_LOCK(s, i) xt_free_rwlock(&(i)->cs_lock)
78#define IDX_CAC_READ_LOCK(i, o) xt_slock_rwlock_ns(&(i)->cs_lock)78#define IDX_CAC_READ_LOCK(i, o) xt_slock_rwlock_ns(&(i)->cs_lock)
79#define IDX_CAC_WRITE_LOCK(i, o) xt_xlock_rwlock_ns(&(i)->cs_lock)79#define IDX_CAC_WRITE_LOCK(i, o) xt_xlock_rwlock_ns(&(i)->cs_lock)
@@ -94,8 +94,12 @@
94#define IDX_CAC_UNLOCK(i, s) xt_spinxslock_unlock(&(i)->cs_lock, (s)->t_id)94#define IDX_CAC_UNLOCK(i, s) xt_spinxslock_unlock(&(i)->cs_lock, (s)->t_id)
95#endif95#endif
9696
97#ifdef XT_NO_ATOMICS
98#define ID_HANDLE_USE_PTHREAD_RW
99#else
97#define ID_HANDLE_USE_SPINLOCK100#define ID_HANDLE_USE_SPINLOCK
98//#define ID_HANDLE_USE_PTHREAD_RW101//#define ID_HANDLE_USE_PTHREAD_RW
102#endif
99103
100#if defined(ID_HANDLE_USE_PTHREAD_RW)104#if defined(ID_HANDLE_USE_PTHREAD_RW)
101#define ID_HANDLE_LOCK_TYPE xt_mutex_type105#define ID_HANDLE_LOCK_TYPE xt_mutex_type
@@ -374,7 +378,7 @@
374{378{
375 DcHandleSlotPtr hs;379 DcHandleSlotPtr hs;
376 XTIndBlockPtr block = NULL;380 XTIndBlockPtr block = NULL;
377 u_int hash_idx = 0;381 u_int hash_idx = 0;
378 DcSegmentPtr seg = NULL;382 DcSegmentPtr seg = NULL;
379 XTIndBlockPtr xblock;383 XTIndBlockPtr xblock;
380384
@@ -1379,7 +1383,7 @@
1379 ASSERT_NS(iref->ir_xlock == 2);1383 ASSERT_NS(iref->ir_xlock == 2);
1380#endif1384#endif
1381 if (!(block = ind_cac_fetch(ot, ind, address, &seg, TRUE)))1385 if (!(block = ind_cac_fetch(ot, ind, address, &seg, TRUE)))
1382 return 0;1386 return FAILED;
13831387
1384 branch_size = XT_GET_DISK_2(((XTIdxBranchDPtr) block->cb_data)->tb_size_2);1388 branch_size = XT_GET_DISK_2(((XTIdxBranchDPtr) block->cb_data)->tb_size_2);
1385 if (XT_GET_INDEX_BLOCK_LEN(branch_size) < 2 || XT_GET_INDEX_BLOCK_LEN(branch_size) > XT_INDEX_PAGE_SIZE) {1389 if (XT_GET_INDEX_BLOCK_LEN(branch_size) < 2 || XT_GET_INDEX_BLOCK_LEN(branch_size) > XT_INDEX_PAGE_SIZE) {
13861390
=== modified file 'storage/pbxt/src/cache_xt.h'
--- storage/pbxt/src/cache_xt.h 2009-08-17 11:12:36 +0000
+++ storage/pbxt/src/cache_xt.h 2009-12-10 11:57:20 +0000
@@ -62,7 +62,7 @@
62#define XT_IPAGE_UNLOCK(i, x) xt_atomicrwlock_unlock(i, x)62#define XT_IPAGE_UNLOCK(i, x) xt_atomicrwlock_unlock(i, x)
63#elif defined(XT_IPAGE_USE_PTHREAD_RW)63#elif defined(XT_IPAGE_USE_PTHREAD_RW)
64#define XT_IPAGE_LOCK_TYPE xt_rwlock_type64#define XT_IPAGE_LOCK_TYPE xt_rwlock_type
65#define XT_IPAGE_INIT_LOCK(s, i) xt_init_rwlock(s, i)65#define XT_IPAGE_INIT_LOCK(s, i) xt_init_rwlock_with_autoname(s, i)
66#define XT_IPAGE_FREE_LOCK(s, i) xt_free_rwlock(i) 66#define XT_IPAGE_FREE_LOCK(s, i) xt_free_rwlock(i)
67#define XT_IPAGE_READ_LOCK(i) xt_slock_rwlock_ns(i)67#define XT_IPAGE_READ_LOCK(i) xt_slock_rwlock_ns(i)
68#define XT_IPAGE_WRITE_LOCK(i, s) xt_xlock_rwlock_ns(i)68#define XT_IPAGE_WRITE_LOCK(i, s) xt_xlock_rwlock_ns(i)
6969
=== modified file 'storage/pbxt/src/database_xt.cc'
--- storage/pbxt/src/database_xt.cc 2009-08-17 11:12:36 +0000
+++ storage/pbxt/src/database_xt.cc 2009-12-10 11:57:20 +0000
@@ -54,6 +54,8 @@
54 * GLOBALS54 * GLOBALS
55 */55 */
5656
57xtPublic XTDatabaseHPtr pbxt_database = NULL; // The global open database
58
57xtPublic xtLogOffset xt_db_log_file_threshold;59xtPublic xtLogOffset xt_db_log_file_threshold;
58xtPublic size_t xt_db_log_buffer_size;60xtPublic size_t xt_db_log_buffer_size;
59xtPublic size_t xt_db_transaction_buffer_size;61xtPublic size_t xt_db_transaction_buffer_size;
@@ -505,6 +507,15 @@
505 * all index entries that are not visible have507 * all index entries that are not visible have
506 * been removed.508 * been removed.
507 *509 *
510 * REASON WHY WE SET ROWID ON RECOVERY:
511 * The row ID is set on recovery because the
512 * change to the index may be lost after a crash.
513 * The change to the index is done by the sweeper, and
514 * there is no record of this change in the log.
515 * The sweeper will not "re-sweep" all transations
516 * that are recovered. As a result, this upadte
517 * of the index by the sweeper may be lost.
518 *
508 * {OPEN-DB-SWEEPER-WAIT}519 * {OPEN-DB-SWEEPER-WAIT}
509 * This has been moved to after the release of the open520 * This has been moved to after the release of the open
510 * database lock because:521 * database lock because:
@@ -518,9 +529,12 @@
518 * - To open the database it needs the open database529 * - To open the database it needs the open database
519 * lock.530 * lock.
520 */531 */
532 /*
533 * This has been moved, see: {WAIT-FOR-SW-AFTER-RECOV}
521 pushr_(xt_heap_release, db);534 pushr_(xt_heap_release, db);
522 xt_wait_for_sweeper(self, db, 0);535 xt_wait_for_sweeper(self, db, 0);
523 popr_();536 popr_();
537 */
524538
525 return db;539 return db;
526}540}
527541
=== modified file 'storage/pbxt/src/database_xt.h'
--- storage/pbxt/src/database_xt.h 2009-04-02 10:03:14 +0000
+++ storage/pbxt/src/database_xt.h 2009-12-10 11:57:20 +0000
@@ -105,6 +105,8 @@
105#define XT_THREAD_IDLE 1105#define XT_THREAD_IDLE 1
106#define XT_THREAD_INERR 2106#define XT_THREAD_INERR 2
107107
108#define XT_XA_HASH_TAB_SIZE 223
109
108typedef struct XTDatabase : public XTHeap {110typedef struct XTDatabase : public XTHeap {
109 char *db_name; /* The name of the database, last component of the path! */111 char *db_name; /* The name of the database, last component of the path! */
110 char *db_main_path;112 char *db_main_path;
@@ -131,6 +133,9 @@
131 u_int db_stat_sweep_waits; /* STATISTICS: count the sweeper waits. */133 u_int db_stat_sweep_waits; /* STATISTICS: count the sweeper waits. */
132 XTDatabaseLogRec db_xlog; /* The transaction log for this database. */134 XTDatabaseLogRec db_xlog; /* The transaction log for this database. */
133 XTXactRestartRec db_restart; /* Database recovery stuff. */135 XTXactRestartRec db_restart; /* Database recovery stuff. */
136 xt_mutex_type db_xn_xa_lock;
137 XTXactPreparePtr db_xn_xa_table[XT_XA_HASH_TAB_SIZE];
138 XTSortedListPtr db_xn_xa_list; /* The "wait-for" list, of transactions waiting for other transactions. */
134139
135 XTSortedListPtr db_xn_wait_for; /* The "wait-for" list, of transactions waiting for other transactions. */140 XTSortedListPtr db_xn_wait_for; /* The "wait-for" list, of transactions waiting for other transactions. */
136 u_int db_xn_call_start; /* Start of the post wait calls. */141 u_int db_xn_call_start; /* Start of the post wait calls. */
@@ -198,6 +203,7 @@
198203
199void xt_add_pbxt_file(size_t size, char *path, const char *file);204void xt_add_pbxt_file(size_t size, char *path, const char *file);
200void xt_add_location_file(size_t size, char *path);205void xt_add_location_file(size_t size, char *path);
206void xt_add_pbxt_dir(size_t size, char *path);
201void xt_add_system_dir(size_t size, char *path);207void xt_add_system_dir(size_t size, char *path);
202void xt_add_data_dir(size_t size, char *path);208void xt_add_data_dir(size_t size, char *path);
203209
@@ -244,4 +250,6 @@
244 }250 }
245}251}
246252
253extern XTDatabaseHPtr pbxt_database; // The global open database
254
247#endif255#endif
248256
=== modified file 'storage/pbxt/src/datadic_xt.cc'
--- storage/pbxt/src/datadic_xt.cc 2009-08-18 07:46:53 +0000
+++ storage/pbxt/src/datadic_xt.cc 2009-12-10 11:57:20 +0000
@@ -35,7 +35,7 @@
3535
36#ifdef DEBUG36#ifdef DEBUG
37#ifdef DRIZZLED37#ifdef DRIZZLED
38#include <drizzled/common_includes.h>38//#include <drizzled/common_includes.h>
39#else39#else
40#include "mysql_priv.h"40#include "mysql_priv.h"
41#endif41#endif
@@ -437,11 +437,6 @@
437 XTToken *nextToken(XTThreadPtr self, c_char *keyword, XTToken *tk);437 XTToken *nextToken(XTThreadPtr self, c_char *keyword, XTToken *tk);
438};438};
439439
440void ri_free_token(XTThreadPtr XT_UNUSED(self), XTToken *tk)
441{
442 delete tk;
443}
444
445XTToken *XTTokenizer::newToken(XTThreadPtr self, u_int type, char *start, char *end)440XTToken *XTTokenizer::newToken(XTThreadPtr self, u_int type, char *start, char *end)
446{441{
447 if (!tkn_current) {442 if (!tkn_current) {
448443
=== modified file 'storage/pbxt/src/datalog_xt.cc'
--- storage/pbxt/src/datalog_xt.cc 2009-09-04 07:29:34 +0000
+++ storage/pbxt/src/datalog_xt.cc 2009-12-10 11:57:20 +0000
@@ -410,7 +410,7 @@
410 ASSERT_NS(seq_read.sl_log_eof == seq_read.sl_rec_log_offset);410 ASSERT_NS(seq_read.sl_log_eof == seq_read.sl_rec_log_offset);
411 data_log->dlf_log_eof = seq_read.sl_rec_log_offset;411 data_log->dlf_log_eof = seq_read.sl_rec_log_offset;
412412
413 if ((size_t) data_log->dlf_log_eof < sizeof(XTXactLogHeaderDRec)) {413 if (data_log->dlf_log_eof < (off_t) sizeof(XTXactLogHeaderDRec)) {
414 data_log->dlf_log_eof = sizeof(XTXactLogHeaderDRec);414 data_log->dlf_log_eof = sizeof(XTXactLogHeaderDRec);
415 if (!dl_create_log_header(data_log, seq_read.sl_log_file, self))415 if (!dl_create_log_header(data_log, seq_read.sl_log_file, self))
416 xt_throw(self);416 xt_throw(self);
@@ -1162,7 +1162,7 @@
1162/* When I use 'thread' instead of 'self', this means1162/* When I use 'thread' instead of 'self', this means
1163 * that I will not throw an error.1163 * that I will not throw an error.
1164 */1164 */
1165xtBool XTDataLogBuffer::dlb_get_log_offset(xtLogID *log_id, xtLogOffset *out_offset, size_t req_size, struct XTThread *thread)1165xtBool XTDataLogBuffer::dlb_get_log_offset(xtLogID *log_id, xtLogOffset *out_offset, size_t XT_UNUSED(req_size), struct XTThread *thread)
1166{1166{
1167 /* Note, I am allowing a log to grow beyond the threshold.1167 /* Note, I am allowing a log to grow beyond the threshold.
1168 * The amount depends on the maximum extended record size.1168 * The amount depends on the maximum extended record size.
@@ -1757,7 +1757,7 @@
1757 freer_(); // xt_unlock_mutex(&db->db_co_dlog_lock)1757 freer_(); // xt_unlock_mutex(&db->db_co_dlog_lock)
17581758
1759 /* Flush the transaction log. */1759 /* Flush the transaction log. */
1760 if (!xt_xlog_flush_log(self))1760 if (!xt_xlog_flush_log(db, self))
1761 xt_throw(self);1761 xt_throw(self);
17621762
1763 xt_lock_mutex_ns(&db->db_datalogs.dlc_head_lock);1763 xt_lock_mutex_ns(&db->db_datalogs.dlc_head_lock);
@@ -1891,7 +1891,7 @@
1891 freer_(); // xt_unlock_mutex(&db->db_co_dlog_lock)1891 freer_(); // xt_unlock_mutex(&db->db_co_dlog_lock)
1892 1892
1893 /* Flush the transaction log. */1893 /* Flush the transaction log. */
1894 if (!xt_xlog_flush_log(self))1894 if (!xt_xlog_flush_log(db, self))
1895 xt_throw(self);1895 xt_throw(self);
18961896
1897 /* Save state in source log header. */1897 /* Save state in source log header. */
18981898
=== modified file 'storage/pbxt/src/discover_xt.cc'
--- storage/pbxt/src/discover_xt.cc 2009-12-03 11:19:05 +0000
+++ storage/pbxt/src/discover_xt.cc 2009-12-10 11:57:20 +0000
@@ -31,6 +31,9 @@
31#include <drizzled/session.h>31#include <drizzled/session.h>
32#include <drizzled/server_includes.h>32#include <drizzled/server_includes.h>
33#include <drizzled/sql_base.h>33#include <drizzled/sql_base.h>
34#include <drizzled/statement/alter_table.h>
35#include <algorithm>
36#include <sstream>
34#endif37#endif
3538
36#include "strutil_xt.h"39#include "strutil_xt.h"
@@ -39,18 +42,273 @@
39#include "ha_xtsys.h"42#include "ha_xtsys.h"
4043
41#ifndef DRIZZLED44#ifndef DRIZZLED
42#if MYSQL_VERSION_ID > 6000545#if MYSQL_VERSION_ID >= 50404
43#define DOT_STR(x) x.str46#define DOT_STR(x) x.str
44#else47#else
45#define DOT_STR(x) x48#define DOT_STR(x) x
46#endif49#endif
47#endif50#endif
4851
49#ifndef DRIZZLED52//#ifndef DRIZZLED
50#define LOCK_OPEN_HACK_REQUIRED53#define LOCK_OPEN_HACK_REQUIRED
51#endif // DRIZZLED54//#endif // DRIZZLED
5255
53#ifdef LOCK_OPEN_HACK_REQUIRED56#ifdef LOCK_OPEN_HACK_REQUIRED
57#ifdef DRIZZLED
58
59using namespace drizzled;
60using namespace std;
61
62#define mysql_create_table_no_lock hacked_mysql_create_table_no_lock
63
64namespace drizzled {
65
66int rea_create_table(Session *session, const char *path,
67 const char *db, const char *table_name,
68 message::Table *table_proto,
69 HA_CREATE_INFO *create_info,
70 List<CreateField> &create_field,
71 uint32_t key_count,KEY *key_info);
72}
73
74static uint32_t build_tmptable_filename(Session* session,
75 char *buff, size_t bufflen)
76{
77 uint32_t length;
78 ostringstream path_str, post_tmpdir_str;
79 string tmp;
80
81 path_str << drizzle_tmpdir;
82 post_tmpdir_str << "/" << TMP_FILE_PREFIX << current_pid;
83 post_tmpdir_str << session->thread_id << session->tmp_table++;
84 tmp= post_tmpdir_str.str();
85
86 transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower);
87
88 path_str << tmp;
89
90 if (bufflen < path_str.str().length())
91 length= 0;
92 else
93 length= unpack_filename(buff, path_str.str().c_str());
94
95 return length;
96}
97
98static bool mysql_create_table_no_lock(Session *session,
99 const char *db, const char *table_name,
100 HA_CREATE_INFO *create_info,
101 message::Table *table_proto,
102 AlterInfo *alter_info,
103 bool internal_tmp_table,
104 uint32_t select_field_count)
105{
106 char path[FN_REFLEN];
107 uint32_t path_length;
108 uint db_options, key_count;
109 KEY *key_info_buffer;
110 Cursor *file;
111 bool error= true;
112 /* Check for duplicate fields and check type of table to create */
113 if (!alter_info->create_list.elements)
114 {
115 my_message(ER_TABLE_MUST_HAVE_COLUMNS, ER(ER_TABLE_MUST_HAVE_COLUMNS),
116 MYF(0));
117 return true;
118 }
119 assert(strcmp(table_name,table_proto->name().c_str())==0);
120 if (check_engine(session, table_name, create_info))
121 return true;
122 db_options= create_info->table_options;
123 if (create_info->row_type == ROW_TYPE_DYNAMIC)
124 db_options|=HA_OPTION_PACK_RECORD;
125
126 /*if (!(file= create_info->db_type->getCursor((TableShare*) 0, session->mem_root)))
127 {
128 my_error(ER_OUTOFMEMORY, MYF(0), sizeof(Cursor));
129 return true;
130 }*/
131
132 /* PMC - Done to avoid getting the partition handler by mistake! */
133 if (!(file= new (session->mem_root) ha_xtsys(pbxt_hton, NULL)))
134 {
135 my_error(ER_OUTOFMEMORY, MYF(0), sizeof(Cursor));
136 return true;
137 }
138
139 set_table_default_charset(create_info, (char*) db);
140
141 if (mysql_prepare_create_table(session,
142 create_info,
143 table_proto,
144 alter_info,
145 internal_tmp_table,
146 &db_options, file,
147 &key_info_buffer, &key_count,
148 select_field_count))
149 goto err;
150
151 /* Check if table exists */
152 if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
153 {
154 path_length= build_tmptable_filename(session, path, sizeof(path));
155 }
156 else
157 {
158 #ifdef FN_DEVCHAR
159 /* check if the table name contains FN_DEVCHAR when defined */
160 if (strchr(table_name, FN_DEVCHAR))
161 {
162 my_error(ER_WRONG_TABLE_NAME, MYF(0), table_name);
163 return true;
164 }
165#endif
166 path_length= build_table_filename(path, sizeof(path), db, table_name, internal_tmp_table);
167 }
168
169 /* Check if table already exists */
170 if ((create_info->options & HA_LEX_CREATE_TMP_TABLE) &&
171 session->find_temporary_table(db, table_name))
172 {
173 if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
174 {
175 create_info->table_existed= 1; // Mark that table existed
176 push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
177 ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
178 table_name);
179 error= 0;
180 goto err;
181 }
182 my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name);
183 goto err;
184 }
185
186 //pthread_mutex_lock(&LOCK_open); /* CREATE TABLE (some confussion on naming, double check) */
187 if (!internal_tmp_table && !(create_info->options & HA_LEX_CREATE_TMP_TABLE))
188 {
189 if (plugin::StorageEngine::getTableDefinition(*session,
190 path,
191 db,
192 table_name,
193 internal_tmp_table) == EEXIST)
194 {
195 if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
196 {
197 error= false;
198 push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
199 ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
200 table_name);
201 create_info->table_existed= 1; // Mark that table existed
202 }
203 else
204 my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name);
205
206 goto unlock_and_end;
207 }
208 /*
209 * We don't assert here, but check the result, because the table could be
210 * in the table definition cache and in the same time the .frm could be
211 * missing from the disk, in case of manual intervention which deletes
212 * the .frm file. The user has to use FLUSH TABLES; to clear the cache.
213 * Then she could create the table. This case is pretty obscure and
214 * therefore we don't introduce a new error message only for it.
215 * */
216 if (TableShare::getShare(db, table_name))
217 {
218 my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name);
219 goto unlock_and_end;
220 }
221 }
222 /*
223 * Check that table with given name does not already
224 * exist in any storage engine. In such a case it should
225 * be discovered and the error ER_TABLE_EXISTS_ERROR be returned
226 * unless user specified CREATE TABLE IF EXISTS
227 * The LOCK_open mutex has been locked to make sure no
228 * one else is attempting to discover the table. Since
229 * it's not on disk as a frm file, no one could be using it!
230 * */
231 if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE))
232 {
233 bool create_if_not_exists =
234 create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS;
235
236 char table_path[FN_REFLEN];
237 uint32_t table_path_length;
238
239 table_path_length= build_table_filename(table_path, sizeof(table_path),
240 db, table_name, false);
241
242 int retcode= plugin::StorageEngine::getTableDefinition(*session,
243 table_path,
244 db,
245 table_name,
246 false);
247 switch (retcode)
248 {
249 case ENOENT:
250 /* Normal case, no table exists. we can go and create it */
251 break;
252 case EEXIST:
253 if (create_if_not_exists)
254 {
255 error= false;
256 push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
257 ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
258 table_name);
259 create_info->table_existed= 1; // Mark that table existed
260 goto unlock_and_end;
261 }
262 my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name);
263 goto unlock_and_end;
264 default:
265 my_error(retcode, MYF(0),table_name);
266 goto unlock_and_end;
267 }
268 }
269
270 session->set_proc_info("creating table");
271 create_info->table_existed= 0; // Mark that table is created
272
273 create_info->table_options=db_options;
274
275 if (rea_create_table(session, path, db, table_name,
276 table_proto,
277 create_info, alter_info->create_list,
278 key_count, key_info_buffer))
279 goto unlock_and_end;
280
281 if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
282 {
283 /* Open table and put in temporary table list */
284 if (!(session->open_temporary_table(path, db, table_name, 1, OTM_OPEN)))
285 {
286 (void) session->rm_temporary_table(create_info->db_type, path);
287 goto unlock_and_end;
288 }
289 }
290
291 /*
292 * Don't write statement if:
293 * - It is an internal temporary table,
294 * - Row-based logging is used and it we are creating a temporary table, or
295 * - The binary log is not open.
296 * Otherwise, the statement shall be binlogged.
297 * */
298 if (!internal_tmp_table &&
299 ((!(create_info->options & HA_LEX_CREATE_TMP_TABLE))))
300 write_bin_log(session, session->query, session->query_length);
301 error= false;
302unlock_and_end:
303 //pthread_mutex_unlock(&LOCK_open);
304
305err:
306 session->set_proc_info("After create");
307 delete file;
308 return(error);
309}
310
311#else // MySQL case
54///////////////////////////////312///////////////////////////////
55/*313/*
56 * Unfortunately I cannot use the standard mysql_create_table_no_lock() because it will lock "LOCK_open"314 * Unfortunately I cannot use the standard mysql_create_table_no_lock() because it will lock "LOCK_open"
@@ -1229,13 +1487,13 @@
1229 if (create_info->options & HA_LEX_CREATE_TMP_TABLE)1487 if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
1230 {1488 {
1231 /* Open table and put in temporary table list */1489 /* Open table and put in temporary table list */
1232#if MYSQL_VERSION_ID > 600051490#if MYSQL_VERSION_ID >= 50404
1233 if (!(open_temporary_table(thd, path, db, table_name, 1, OTM_OPEN)))1491 if (!(open_temporary_table(thd, path, db, table_name, 1, OTM_OPEN)))
1234#else1492#else
1235 if (!(open_temporary_table(thd, path, db, table_name, 1)))1493 if (!(open_temporary_table(thd, path, db, table_name, 1)))
1236#endif1494#endif
1237 {1495 {
1238#if MYSQL_VERSION_ID > 600051496#if MYSQL_VERSION_ID >= 50404
1239 (void) rm_temporary_table(create_info->db_type, path, false);1497 (void) rm_temporary_table(create_info->db_type, path, false);
1240#else1498#else
1241 (void) rm_temporary_table(create_info->db_type, path);1499 (void) rm_temporary_table(create_info->db_type, path);
@@ -1252,11 +1510,25 @@
1252 - The binary log is not open.1510 - The binary log is not open.
1253 Otherwise, the statement shall be binlogged.1511 Otherwise, the statement shall be binlogged.
1254 */1512 */
1513 /* PBXT 1.0.09e
1514 * Firstly we had a compile problem with MySQL 5.1.42 and
1515 * the write_bin_log() call below:
1516 * discover_xt.cc:1259: error: argument of type 'char* (Statement::)()' does not match 'const char*'
1517 *
1518 * And secondly, we should no write the BINLOG anyway because this is
1519 * an internal PBXT system table.
1520 *
1521 * So I am just commenting out the code altogether.
1255 if (!internal_tmp_table &&1522 if (!internal_tmp_table &&
1256 (!thd->current_stmt_binlog_row_based ||1523 (!thd->current_stmt_binlog_row_based ||
1257 (thd->current_stmt_binlog_row_based &&1524 (thd->current_stmt_binlog_row_based &&
1258 !(create_info->options & HA_LEX_CREATE_TMP_TABLE))))1525 !(create_info->options & HA_LEX_CREATE_TMP_TABLE))))
1526<<<<<<< TREE
1259 write_bin_log(thd, TRUE, thd->query(), thd->query_length());1527 write_bin_log(thd, TRUE, thd->query(), thd->query_length());
1528=======
1529 write_bin_log(thd, TRUE, thd->query, thd->query_length);
1530 */
1531>>>>>>> MERGE-SOURCE
1260 error= FALSE;1532 error= FALSE;
1261unlock_and_end:1533unlock_and_end:
1262 pthread_mutex_unlock(&LOCK_open);1534 pthread_mutex_unlock(&LOCK_open);
@@ -1279,37 +1551,51 @@
1279////// END OF CUT AND PASTES FROM sql_table.cc ////////1551////// END OF CUT AND PASTES FROM sql_table.cc ////////
1280////////////////////////////////////////////////////////1552////////////////////////////////////////////////////////
12811553
1554#endif // DRIZZLED
1282#endif // LOCK_OPEN_HACK_REQUIRED1555#endif // LOCK_OPEN_HACK_REQUIRED
12831556
1284//------------------------------1557//------------------------------
1285int xt_create_table_frm(handlerton *hton, THD* thd, const char *db, const char *name, DT_FIELD_INFO *info, DT_KEY_INFO *XT_UNUSED(keys), xtBool skip_existing)1558int xt_create_table_frm(handlerton *hton, THD* thd, const char *db, const char *name, DT_FIELD_INFO *info, DT_KEY_INFO *XT_UNUSED(keys), xtBool skip_existing)
1286{1559{
1287#ifdef DRIZZLED1560#ifdef DRIZZLED
1288 drizzled::message::Table table_proto;1561#define MYLEX_CREATE_INFO create_info
1562#else
1563#define MYLEX_CREATE_INFO mylex.create_info
1564#endif
1565
1566#ifdef DRIZZLED
1567 drizzled::statement::AlterTable *stmt = new drizzled::statement::AlterTable(thd);
1568 HA_CREATE_INFO create_info;
1569 //AlterInfo alter_info;
1570 drizzled::message::Table table_proto;
12891571
1290 static const char *ext = ".dfe";1572 static const char *ext = ".dfe";
1291 static const int ext_len = 4;1573 static const int ext_len = 4;
1574
1575 table_proto.mutable_engine()->mutable_name()->assign("PBXT");
1292#else1576#else
1293 static const char *ext = ".frm";1577 static const char *ext = ".frm";
1294 static const int ext_len = 4;1578 static const int ext_len = 4;
1295#endif1579#endif
1296 int err = 1;1580 int err = 1;
1297 //HA_CREATE_INFO create_info = {0};
1298 //Alter_info alter_info;
1299 char field_length_buffer[12], *field_length_ptr;1581 char field_length_buffer[12], *field_length_ptr;
1300 LEX *save_lex= thd->lex, mylex;1582 LEX *save_lex= thd->lex, mylex;
1301 1583
1302 memset(&mylex.create_info, 0, sizeof(HA_CREATE_INFO));1584 memset(&MYLEX_CREATE_INFO, 0, sizeof(HA_CREATE_INFO));
13031585
1304 thd->lex = &mylex;1586 thd->lex = &mylex;
1305 lex_start(thd);1587 lex_start(thd);
1588#ifdef DRIZZLED
1589 mylex.statement = stmt;
1590#endif
1306 1591
1307 /* setup the create info */1592 /* setup the create info */
1308 mylex.create_info.db_type = hton;1593 MYLEX_CREATE_INFO.db_type = hton;
1594
1309#ifndef DRIZZLED 1595#ifndef DRIZZLED
1310 mylex.create_info.frm_only = 1;1596 mylex.create_info.frm_only = 1;
1311#endif1597#endif
1312 mylex.create_info.default_table_charset = system_charset_info;1598 MYLEX_CREATE_INFO.default_table_charset = system_charset_info;
1313 1599
1314 /* setup the column info. */1600 /* setup the column info. */
1315 while (info->field_name) { 1601 while (info->field_name) {
@@ -1335,7 +1621,7 @@
1335#else1621#else
1336 if (add_field_to_list(thd, &field_name, info->field_type, field_length_ptr, info->field_decimal_length,1622 if (add_field_to_list(thd, &field_name, info->field_type, field_length_ptr, info->field_decimal_length,
1337 info->field_flags,1623 info->field_flags,
1338#if MYSQL_VERSION_ID > 600051624#if MYSQL_VERSION_ID >= 50404
1339 HA_SM_DISK,1625 HA_SM_DISK,
1340 COLUMN_FORMAT_TYPE_FIXED,1626 COLUMN_FORMAT_TYPE_FIXED,
1341#endif1627#endif
@@ -1369,7 +1655,7 @@
1369 table_proto.set_name(name);1655 table_proto.set_name(name);
1370 table_proto.set_type(drizzled::message::Table::STANDARD);1656 table_proto.set_type(drizzled::message::Table::STANDARD);
13711657
1372 if (mysql_create_table_no_lock(thd, db, name, &mylex.create_info, &table_proto, &mylex.alter_info, 1, 0, false)) 1658 if (mysql_create_table_no_lock(thd, db, name, &create_info, &table_proto, &stmt->alter_info, 1, 0))
1373 goto error;1659 goto error;
1374#else1660#else
1375 if (mysql_create_table_no_lock(thd, db, name, &mylex.create_info, &mylex.alter_info, 1, 0)) 1661 if (mysql_create_table_no_lock(thd, db, name, &mylex.create_info, &mylex.alter_info, 1, 0))
13761662
=== modified file 'storage/pbxt/src/filesys_xt.cc'
--- storage/pbxt/src/filesys_xt.cc 2009-09-03 06:15:03 +0000
+++ storage/pbxt/src/filesys_xt.cc 2009-12-10 11:57:20 +0000
@@ -56,6 +56,8 @@
56//#define DEBUG_TRACE_FILES56//#define DEBUG_TRACE_FILES
57//#define INJECT_WRITE_REMAP_ERROR57//#define INJECT_WRITE_REMAP_ERROR
58/* This is required to make testing on the Mac faster: */58/* This is required to make testing on the Mac faster: */
59/* It turns of full file sync. */
60#define DEBUG_FAST_MAC
59#endif61#endif
6062
61#ifdef DEBUG_TRACE_FILES63#ifdef DEBUG_TRACE_FILES
@@ -63,10 +65,6 @@
63#define PRINTF xt_trace65#define PRINTF xt_trace
64#endif66#endif
6567
66#if defined(XT_MAC) && defined(F_FULLFSYNC)
67#undef F_FULLFSYNC
68#endif
69
70#ifdef INJECT_WRITE_REMAP_ERROR68#ifdef INJECT_WRITE_REMAP_ERROR
71#define INJECT_REMAP_FILE_SIZE 100000069#define INJECT_REMAP_FILE_SIZE 1000000
72#define INJECT_REMAP_FILE_TYPE "xtd"70#define INJECT_REMAP_FILE_TYPE "xtd"
@@ -883,7 +881,7 @@
883 * fsync didn't really flush index pages to disk. fcntl(F_FULLFSYNC) is considered more effective 881 * fsync didn't really flush index pages to disk. fcntl(F_FULLFSYNC) is considered more effective
884 * in such case.882 * in such case.
885 */883 */
886#ifdef F_FULLFSYNC884#if defined(F_FULLFSYNC) && !defined(DEBUG_FAST_MAC)
887 if (fcntl(of->of_filedes, F_FULLFSYNC, 0) == -1) {885 if (fcntl(of->of_filedes, F_FULLFSYNC, 0) == -1) {
888 xt_register_ferrno(XT_REG_CONTEXT, errno, xt_file_path(of));886 xt_register_ferrno(XT_REG_CONTEXT, errno, xt_file_path(of));
889 goto failed;887 goto failed;
890888
=== modified file 'storage/pbxt/src/filesys_xt.h'
--- storage/pbxt/src/filesys_xt.h 2009-08-17 11:12:36 +0000
+++ storage/pbxt/src/filesys_xt.h 2009-12-10 11:57:20 +0000
@@ -102,7 +102,7 @@
102#define FILE_MAP_UNLOCK(i, o) xt_xsmutex_unlock(i, o)102#define FILE_MAP_UNLOCK(i, o) xt_xsmutex_unlock(i, o)
103#elif defined(FILE_MAP_USE_PTHREAD_RW)103#elif defined(FILE_MAP_USE_PTHREAD_RW)
104#define FILE_MAP_LOCK_TYPE xt_rwlock_type104#define FILE_MAP_LOCK_TYPE xt_rwlock_type
105#define FILE_MAP_INIT_LOCK(s, i) xt_init_rwlock(s, i)105#define FILE_MAP_INIT_LOCK(s, i) xt_init_rwlock_with_autoname(s, i)
106#define FILE_MAP_FREE_LOCK(s, i) xt_free_rwlock(i) 106#define FILE_MAP_FREE_LOCK(s, i) xt_free_rwlock(i)
107#define FILE_MAP_READ_LOCK(i, o) xt_slock_rwlock_ns(i)107#define FILE_MAP_READ_LOCK(i, o) xt_slock_rwlock_ns(i)
108#define FILE_MAP_WRITE_LOCK(i, o) xt_xlock_rwlock_ns(i)108#define FILE_MAP_WRITE_LOCK(i, o) xt_xlock_rwlock_ns(i)
109109
=== modified file 'storage/pbxt/src/ha_pbxt.cc'
--- storage/pbxt/src/ha_pbxt.cc 2009-09-03 06:15:03 +0000
+++ storage/pbxt/src/ha_pbxt.cc 2009-12-10 11:57:20 +0000
@@ -35,6 +35,7 @@
3535
36#include <stdlib.h>36#include <stdlib.h>
37#include <time.h>37#include <time.h>
38#include <ctype.h>
3839
39#ifdef DRIZZLED40#ifdef DRIZZLED
40#include <drizzled/common.h>41#include <drizzled/common.h>
@@ -42,14 +43,21 @@
42#include <mysys/my_alloc.h>43#include <mysys/my_alloc.h>
43#include <mysys/hash.h>44#include <mysys/hash.h>
44#include <drizzled/field.h>45#include <drizzled/field.h>
45#include <drizzled/current_session.h>46#include <drizzled/session.h>
46#include <drizzled/data_home.h>47#include <drizzled/data_home.h>
47#include <drizzled/error.h>48#include <drizzled/error.h>
48#include <drizzled/table.h>49#include <drizzled/table.h>
49#include <drizzled/field/timestamp.h>50#include <drizzled/field/timestamp.h>
50#include <drizzled/server_includes.h>51#include <drizzled/server_includes.h>
52#include <drizzled/plugin/info_schema_table.h>
51extern "C" char **session_query(Session *session);53extern "C" char **session_query(Session *session);
52#define my_strdup(a,b) strdup(a)54#define my_strdup(a,b) strdup(a)
55
56using drizzled::plugin::Registry;
57using drizzled::plugin::ColumnInfo;
58using drizzled::plugin::InfoSchemaTable;
59using drizzled::plugin::InfoSchemaMethods;
60
53#else61#else
54#include "mysql_priv.h"62#include "mysql_priv.h"
55#include <mysql/plugin.h>63#include <mysql/plugin.h>
@@ -71,7 +79,7 @@
71#include "tabcache_xt.h"79#include "tabcache_xt.h"
72#include "systab_xt.h"80#include "systab_xt.h"
73#include "xaction_xt.h"81#include "xaction_xt.h"
74#include "restart_xt.h"82#include "backup_xt.h"
7583
76#ifdef DEBUG84#ifdef DEBUG
77//#define XT_USE_SYS_PAR_DEBUG_SIZES85//#define XT_USE_SYS_PAR_DEBUG_SIZES
@@ -101,6 +109,10 @@
101static int pbxt_close_connection(handlerton *hton, THD* thd);109static int pbxt_close_connection(handlerton *hton, THD* thd);
102static int pbxt_commit(handlerton *hton, THD *thd, bool all);110static int pbxt_commit(handlerton *hton, THD *thd, bool all);
103static int pbxt_rollback(handlerton *hton, THD *thd, bool all);111static int pbxt_rollback(handlerton *hton, THD *thd, bool all);
112static int pbxt_prepare(handlerton *hton, THD *thd, bool all);
113static int pbxt_recover(handlerton *hton, XID *xid_list, uint len);
114static int pbxt_commit_by_xid(handlerton *hton, XID *xid);
115static int pbxt_rollback_by_xid(handlerton *hton, XID *xid);
104#endif116#endif
105static void ha_aquire_exclusive_use(XTThreadPtr self, XTSharePtr share, ha_pbxt *mine);117static void ha_aquire_exclusive_use(XTThreadPtr self, XTSharePtr share, ha_pbxt *mine);
106static void ha_release_exclusive_use(XTThreadPtr self, XTSharePtr share);118static void ha_release_exclusive_use(XTThreadPtr self, XTSharePtr share);
@@ -123,7 +135,9 @@
123#ifdef PBXT_HANDLER_TRACE135#ifdef PBXT_HANDLER_TRACE
124#define PBXT_ALLOW_PRINTING136#define PBXT_ALLOW_PRINTING
125137
126#define XT_TRACE_CALL() do { XTThreadPtr s = xt_get_self(); printf("%s %s\n", s ? s->t_name : "-unknown-", __FUNC__); } while (0)138#define XT_TRACE_CALL() ha_trace_function(__FUNC__, NULL)
139#define XT_TRACE_METHOD() ha_trace_function(__FUNC__, pb_share->sh_table_path->ps_path)
140
127#ifdef PBXT_TRACE_RETURN141#ifdef PBXT_TRACE_RETURN
128#define XT_RETURN(x) do { printf("%d\n", (int) (x)); return (x); } while (0)142#define XT_RETURN(x) do { printf("%d\n", (int) (x)); return (x); } while (0)
129#define XT_RETURN_VOID do { printf("out\n"); return; } while (0)143#define XT_RETURN_VOID do { printf("out\n"); return; } while (0)
@@ -135,6 +149,7 @@
135#else149#else
136150
137#define XT_TRACE_CALL()151#define XT_TRACE_CALL()
152#define XT_TRACE_METHOD()
138#define XT_RETURN(x) return (x)153#define XT_RETURN(x) return (x)
139#define XT_RETURN_VOID return154#define XT_RETURN_VOID return
140155
@@ -165,10 +180,10 @@
165xtBool pbxt_crash_debug = FALSE;180xtBool pbxt_crash_debug = FALSE;
166#endif181#endif
167182
183
168/* Variables for pbxt share methods */184/* Variables for pbxt share methods */
169static xt_mutex_type pbxt_database_mutex; // Prevent a database from being opened while it is being dropped185static xt_mutex_type pbxt_database_mutex; // Prevent a database from being opened while it is being dropped
170static XTHashTabPtr pbxt_share_tables; // Hash used to track open tables186static XTHashTabPtr pbxt_share_tables; // Hash used to track open tables
171XTDatabaseHPtr pbxt_database = NULL; // The global open database
172static char *pbxt_index_cache_size;187static char *pbxt_index_cache_size;
173static char *pbxt_record_cache_size;188static char *pbxt_record_cache_size;
174static char *pbxt_log_cache_size;189static char *pbxt_log_cache_size;
@@ -180,6 +195,12 @@
180static char *pbxt_data_file_grow_size;195static char *pbxt_data_file_grow_size;
181static char *pbxt_row_file_grow_size;196static char *pbxt_row_file_grow_size;
182static int pbxt_max_threads;197static int pbxt_max_threads;
198static my_bool pbxt_support_xa;
199
200#ifndef DRIZZLED
201// drizzle complains it's not used
202static XTXactEnumXARec pbxt_xa_enum;
203#endif
183204
184#ifdef DEBUG205#ifdef DEBUG
185#define XT_SHARE_LOCK_WAIT 5000206#define XT_SHARE_LOCK_WAIT 5000
@@ -259,6 +280,33 @@
259//#define XT_AUTO_INCREMENT_DEF 1280//#define XT_AUTO_INCREMENT_DEF 1
260#endif281#endif
261282
283#ifdef PBXT_HANDLER_TRACE
284static void ha_trace_function(const char *function, char *table)
285{
286 char func_buf[50], *ptr;
287 XTThreadPtr thread = xt_get_self();
288
289 if ((ptr = strchr(function, '('))) {
290 ptr--;
291 while (ptr > function) {
292 if (!(isalnum(*ptr) || *ptr == '_'))
293 break;
294 ptr--;
295 }
296 ptr++;
297 xt_strcpy(50, func_buf, ptr);
298 if ((ptr = strchr(func_buf, '(')))
299 *ptr = 0;
300 }
301 else
302 xt_strcpy(50, func_buf, function);
303 if (table)
304 printf("%s %s (%s)\n", thread ? thread->t_name : "-unknown-", func_buf, table);
305 else
306 printf("%s %s\n", thread ? thread->t_name : "-unknown-", func_buf);
307}
308#endif
309
262/*310/*
263 * -----------------------------------------------------------------------311 * -----------------------------------------------------------------------
264 * SHARED TABLE DATA312 * SHARED TABLE DATA
@@ -584,6 +632,9 @@
584/* The first bit is 1. */632/* The first bit is 1. */
585static u_int ha_get_max_bit(MX_BITMAP *map)633static u_int ha_get_max_bit(MX_BITMAP *map)
586{634{
635#ifdef DRIZZLED
636 return map->getFirstSet();
637#else
587 my_bitmap_map *data_ptr = map->bitmap;638 my_bitmap_map *data_ptr = map->bitmap;
588 my_bitmap_map *end_ptr = map->last_word_ptr;639 my_bitmap_map *end_ptr = map->last_word_ptr;
589 my_bitmap_map b;640 my_bitmap_map b;
@@ -612,6 +663,7 @@
612 cnt -= 32;663 cnt -= 32;
613 }664 }
614 return 0;665 return 0;
666#endif
615}667}
616668
617/*669/*
@@ -684,9 +736,10 @@
684 return(-1); // Unknown error736 return(-1); // Unknown error
685}737}
686738
687xtPublic int xt_ha_pbxt_thread_error_for_mysql(THD *XT_UNUSED(thd), const XTThreadPtr self, int ignore_dup_key)739xtPublic int xt_ha_pbxt_thread_error_for_mysql(THD *thd, const XTThreadPtr self, int ignore_dup_key)
688{740{
689 int xt_err = self->t_exception.e_xt_err;741 int xt_err = self->t_exception.e_xt_err;
742 xtBool dup_key = FALSE;
690743
691 XT_PRINT2(self, "xt_ha_pbxt_thread_error_for_mysql xt_err=%d auto commit=%d\n", (int) xt_err, (int) self->st_auto_commit);744 XT_PRINT2(self, "xt_ha_pbxt_thread_error_for_mysql xt_err=%d auto commit=%d\n", (int) xt_err, (int) self->st_auto_commit);
692 switch (xt_err) {745 switch (xt_err) {
@@ -725,6 +778,7 @@
725 /* If we are in auto-commit mode (and we are not ignoring778 /* If we are in auto-commit mode (and we are not ignoring
726 * duplicate keys) then rollback the transaction automatically.779 * duplicate keys) then rollback the transaction automatically.
727 */780 */
781 dup_key = TRUE;
728 if (!ignore_dup_key && self->st_auto_commit)782 if (!ignore_dup_key && self->st_auto_commit)
729 goto abort_transaction;783 goto abort_transaction;
730 break;784 break;
@@ -790,26 +844,20 @@
790 /* Locks are held on tables.844 /* Locks are held on tables.
791 * Only rollback after locks are released.845 * Only rollback after locks are released.
792 */846 */
793 self->st_auto_commit = TRUE;847 /* I do not think this is required, because
848 * I tell mysql to rollback below,
849 * besides it is a hack!
850 self->st_auto_commit = TRUE;
851 */
794 self->st_abort_trans = TRUE;852 self->st_abort_trans = TRUE;
795 }853 }
796#ifdef xxxx854 /* Only tell MySQL to rollback if we automatically rollback.
797/* DBUG_ASSERT(thd->transaction.stmt.ha_list == NULL ||855 * Note: calling this with (thd, FALSE), cause sp.test to fail.
798 trans == &thd->transaction.stmt); in handler.cc now856 */
799 * fails, and I don't know if this function can be called anymore! */857 if (!dup_key) {
800 /* Cause any other DBs to do a rollback as well... */858 if (thd)
801 if (thd) {859 thd_mark_transaction_to_rollback(thd, TRUE);
802 /*
803 * GOTCHA:
804 * This is a BUG in MySQL. I cannot rollback a transaction if
805 * pb_mysql_thd->in_sub_stmt! But I must....?!
806 */
807#ifdef MYSQL_SERVER
808 if (!thd->in_sub_stmt)
809 ha_rollback(thd);
810#endif
811 }860 }
812#endif
813 }861 }
814 break;862 break;
815 }863 }
@@ -908,7 +956,11 @@
908 xt_db_data_file_grow_size = (size_t) data_file_grow_size;956 xt_db_data_file_grow_size = (size_t) data_file_grow_size;
909 xt_db_row_file_grow_size = (size_t) row_file_grow_size;957 xt_db_row_file_grow_size = (size_t) row_file_grow_size;
910958
959#ifdef DRIZZLED
960 pbxt_ignore_case = TRUE;
961#else
911 pbxt_ignore_case = lower_case_table_names != 0;962 pbxt_ignore_case = lower_case_table_names != 0;
963#endif
912 if (pbxt_ignore_case)964 if (pbxt_ignore_case)
913 pbxt_share_tables = xt_new_hashtable(self, ha_hash_comp_ci, ha_hash_ci, ha_hash_free, TRUE, FALSE);965 pbxt_share_tables = xt_new_hashtable(self, ha_hash_comp_ci, ha_hash_ci, ha_hash_free, TRUE, FALSE);
914 else966 else
@@ -968,7 +1020,7 @@
968 */1020 */
969static void ha_exit(XTThreadPtr self)1021static void ha_exit(XTThreadPtr self)
970{1022{
971 xt_xres_wait_for_recovery(self);1023 xt_xres_terminate_recovery(self);
9721024
973 /* Wrap things up... */1025 /* Wrap things up... */
974 xt_unuse_database(self, self); /* Just in case the main thread has a database in use (for testing)? */1026 xt_unuse_database(self, self); /* Just in case the main thread has a database in use (for testing)? */
@@ -1024,7 +1076,7 @@
1024 cont_(a);1076 cont_(a);
10251077
1026 if (!not_ok) {1078 if (!not_ok) {
1027 if (stat_print(thd, "PBXT", 4, "", 0, strbuf.sb_cstring, strbuf.sb_len))1079 if (stat_print(thd, "PBXT", 4, "", 0, strbuf.sb_cstring, (uint) strbuf.sb_len))
1028 not_ok = TRUE;1080 not_ok = TRUE;
1029 }1081 }
1030 xt_sb_set_size(self, &strbuf, 0);1082 xt_sb_set_size(self, &strbuf, 0);
@@ -1038,14 +1090,14 @@
1038 * return 1 on error, else 0.1090 * return 1 on error, else 0.
1039 */1091 */
1040#ifdef DRIZZLED1092#ifdef DRIZZLED
1041static int pbxt_init(PluginRegistry &registry)1093static int pbxt_init(Registry &registry)
1042#else1094#else
1043static int pbxt_init(void *p)1095static int pbxt_init(void *p)
1044#endif1096#endif
1045{1097{
1046 int init_err = 0;1098 int init_err = 0;
10471099
1048 XT_TRACE_CALL();1100 XT_PRINT0(NULL, "pbxt_init\n");
10491101
1050 if (sizeof(xtWordPS) != sizeof(void *)) {1102 if (sizeof(xtWordPS) != sizeof(void *)) {
1051 printf("PBXT: This won't work, I require that sizeof(xtWordPS) == sizeof(void *)!\n");1103 printf("PBXT: This won't work, I require that sizeof(xtWordPS) == sizeof(void *)!\n");
@@ -1076,11 +1128,27 @@
1076 pbxt_hton->close_connection = pbxt_close_connection; /* close_connection, cleanup thread related data. */1128 pbxt_hton->close_connection = pbxt_close_connection; /* close_connection, cleanup thread related data. */
1077 pbxt_hton->commit = pbxt_commit; /* commit */1129 pbxt_hton->commit = pbxt_commit; /* commit */
1078 pbxt_hton->rollback = pbxt_rollback; /* rollback */1130 pbxt_hton->rollback = pbxt_rollback; /* rollback */
1131 if (pbxt_support_xa) {
1132 pbxt_hton->prepare = pbxt_prepare;
1133 pbxt_hton->recover = pbxt_recover;
1134 pbxt_hton->commit_by_xid = pbxt_commit_by_xid;
1135 pbxt_hton->rollback_by_xid = pbxt_rollback_by_xid;
1136 }
1137 else {
1138 pbxt_hton->prepare = NULL;
1139 pbxt_hton->recover = NULL;
1140 pbxt_hton->commit_by_xid = NULL;
1141 pbxt_hton->rollback_by_xid = NULL;
1142 }
1079 pbxt_hton->create = pbxt_create_handler; /* Create a new handler */1143 pbxt_hton->create = pbxt_create_handler; /* Create a new handler */
1080 pbxt_hton->drop_database = pbxt_drop_database; /* Drop a database */1144 pbxt_hton->drop_database = pbxt_drop_database; /* Drop a database */
1081 pbxt_hton->panic = pbxt_panic; /* Panic call */1145 pbxt_hton->panic = pbxt_panic; /* Panic call */
1082 pbxt_hton->show_status = pbxt_show_status;1146 pbxt_hton->show_status = pbxt_show_status;
1083 pbxt_hton->flags = HTON_NO_FLAGS; /* HTON_CAN_RECREATE - Without this flags TRUNCATE uses delete_all_rows() */1147 pbxt_hton->flags = HTON_NO_FLAGS; /* HTON_CAN_RECREATE - Without this flags TRUNCATE uses delete_all_rows() */
1148 pbxt_hton->slot = (uint)-1; /* assign invald value, so we know when it's inited later */
1149#if defined(MYSQL_SUPPORTS_BACKUP) && defined(XT_ENABLE_ONLINE_BACKUP)
1150 pbxt_hton->get_backup_engine = pbxt_backup_engine;
1151#endif
1084#endif1152#endif
1085 if (!xt_init_logging()) /* Initialize logging */1153 if (!xt_init_logging()) /* Initialize logging */
1086 goto error_1;1154 goto error_1;
@@ -1160,8 +1228,10 @@
1160 * Only real problem, 2 threads try to load the same1228 * Only real problem, 2 threads try to load the same
1161 * plugin at the same time.1229 * plugin at the same time.
1162 */1230 */
1231#if MYSQL_VERSION_ID < 60014
1163 myxt_mutex_unlock(&LOCK_plugin);1232 myxt_mutex_unlock(&LOCK_plugin);
1164#endif1233#endif
1234#endif
11651235
1166 /* Can't do this here yet, because I need a THD! */1236 /* Can't do this here yet, because I need a THD! */
1167 try_(b) {1237 try_(b) {
@@ -1195,8 +1265,10 @@
1195 if (thd)1265 if (thd)
1196 myxt_destroy_thread(thd, FALSE);1266 myxt_destroy_thread(thd, FALSE);
1197#ifndef DRIZZLED1267#ifndef DRIZZLED
1268#if MYSQL_VERSION_ID < 60014
1198 myxt_mutex_lock(&LOCK_plugin);1269 myxt_mutex_lock(&LOCK_plugin);
1199#endif1270#endif
1271#endif
1200 }1272 }
1201#endif1273#endif
1202 }1274 }
@@ -1262,7 +1334,7 @@
1262}1334}
12631335
1264#ifdef DRIZZLED1336#ifdef DRIZZLED
1265static int pbxt_end(PluginRegistry &registry)1337static int pbxt_end(Registry &registry)
1266#else1338#else
1267static int pbxt_end(void *)1339static int pbxt_end(void *)
1268#endif1340#endif
@@ -1378,7 +1450,7 @@
1378 * transaction (!all && !self->st_auto_commit).1450 * transaction (!all && !self->st_auto_commit).
1379 */1451 */
1380 if (all || self->st_auto_commit) {1452 if (all || self->st_auto_commit) {
1381 XT_PRINT0(self, "xt_xn_commit\n");1453 XT_PRINT0(self, "xt_xn_commit in pbxt_commit\n");
13821454
1383 if (!xt_xn_commit(self))1455 if (!xt_xn_commit(self))
1384 err = xt_ha_pbxt_thread_error_for_mysql(thd, self, FALSE);1456 err = xt_ha_pbxt_thread_error_for_mysql(thd, self, FALSE);
@@ -1402,7 +1474,7 @@
1402 XTThreadPtr self;1474 XTThreadPtr self;
14031475
1404 if ((self = (XTThreadPtr) *thd_ha_data(thd, hton))) {1476 if ((self = (XTThreadPtr) *thd_ha_data(thd, hton))) {
1405 XT_PRINT1(self, "pbxt_rollback all=%d\n", all);1477 XT_PRINT1(self, "pbxt_rollback all=%d in pbxt_commit\n", all);
14061478
1407 if (self->st_xact_data) {1479 if (self->st_xact_data) {
1408 /* There are no table locks, rollback immediately in all cases1480 /* There are no table locks, rollback immediately in all cases
@@ -1431,7 +1503,7 @@
1431}1503}
14321504
1433#ifdef DRIZZLED1505#ifdef DRIZZLED
1434handler *PBXTStorageEngine::create(TABLE_SHARE *table, MEM_ROOT *mem_root)1506Cursor *PBXTStorageEngine::create(TABLE_SHARE *table, MEM_ROOT *mem_root)
1435{1507{
1436 PBXTStorageEngine * const hton = this;1508 PBXTStorageEngine * const hton = this;
1437#else1509#else
@@ -1446,6 +1518,182 @@
14461518
1447/*1519/*
1448 * -----------------------------------------------------------------------1520 * -----------------------------------------------------------------------
1521 * 2-PHASE COMMIT
1522 *
1523 */
1524
1525#ifndef DRIZZLED
1526
1527static int pbxt_prepare(handlerton *hton, THD *thd, bool all)
1528{
1529 int err = 0;
1530 XTThreadPtr self;
1531
1532 XT_TRACE_CALL();
1533 if ((self = (XTThreadPtr) *thd_ha_data(thd, hton))) {
1534 XT_PRINT1(self, "pbxt_commit all=%d\n", all);
1535
1536 if (self->st_xact_data) {
1537 /* There are no table locks, commit immediately in all cases
1538 * except when this is a statement commit with an explicit
1539 * transaction (!all && !self->st_auto_commit).
1540 */
1541 if (all) {
1542 XID xid;
1543
1544 XT_PRINT0(self, "xt_xn_prepare in pbxt_prepare\n");
1545 thd_get_xid(thd, (MYSQL_XID*) &xid);
1546
1547 if (!xt_xn_prepare(xid.length(), (xtWord1 *) &xid, self))
1548 err = xt_ha_pbxt_thread_error_for_mysql(thd, self, FALSE);
1549 }
1550 }
1551 }
1552 return err;
1553}
1554
1555static XTThreadPtr ha_temp_open_global_database(handlerton *hton, THD **ret_thd, int *temp_thread, char *thread_name, int *err)
1556{
1557 THD *thd;
1558 XTThreadPtr self = NULL;
1559
1560 *temp_thread = 0;
1561 if ((thd = current_thd))
1562 self = (XTThreadPtr) *thd_ha_data(thd, hton);
1563 else {
1564 //thd = (THD *) myxt_create_thread();
1565 //*temp_thread |= 2;
1566 }
1567
1568 if (!self) {
1569 XTExceptionRec e;
1570
1571 if (!(self = xt_create_thread(thread_name, FALSE, TRUE, &e))) {
1572 *err = xt_ha_pbxt_to_mysql_error(e.e_xt_err);
1573 xt_log_exception(NULL, &e, XT_LOG_DEFAULT);
1574 return NULL;
1575 }
1576 *temp_thread |= 1;
1577 }
1578
1579 xt_xres_wait_for_recovery(self, XT_RECOVER_DONE);
1580
1581 try_(a) {
1582 xt_open_database(self, mysql_real_data_home, TRUE);
1583 }
1584 catch_(a) {
1585 *err = xt_ha_pbxt_thread_error_for_mysql(thd, self, FALSE);
1586 if ((*temp_thread & 1))
1587 xt_free_thread(self);
1588 if (*temp_thread & 2)
1589 myxt_destroy_thread(thd, FALSE);
1590 self = NULL;
1591 }
1592 cont_(a);
1593
1594 *ret_thd = thd;
1595 return self;
1596}
1597
1598static void ha_temp_close_database(XTThreadPtr self, THD *thd, int temp_thread)
1599{
1600 xt_unuse_database(self, self);
1601 if (temp_thread & 1)
1602 xt_free_thread(self);
1603 if (temp_thread & 2)
1604 myxt_destroy_thread(thd, TRUE);
1605}
1606
1607/* Return all prepared transactions, found during recovery.
1608 * This function returns a count. If len is returned, the
1609 * function will be called again.
1610 */
1611static int pbxt_recover(handlerton *hton, XID *xid_list, uint len)
1612{
1613 xtBool temp_thread;
1614 XTThreadPtr self;
1615 XTDatabaseHPtr db;
1616 uint count = 0;
1617 XTXactPreparePtr xap;
1618 int err;
1619 THD *thd;
1620
1621 if (!(self = ha_temp_open_global_database(hton, &thd, &temp_thread, "TempForRecover", &err)))
1622 return 0;
1623
1624 db = self->st_database;
1625
1626 for (count=0; count<len; count++) {
1627 xap = xt_xn_enum_xa_data(db, &pbxt_xa_enum);
1628 if (!xap)
1629 break;
1630 memcpy(&xid_list[count], xap->xp_xa_data, xap->xp_data_len);
1631 }
1632
1633 ha_temp_close_database(self, thd, temp_thread);
1634 return (int) count;
1635}
1636
1637static int pbxt_commit_by_xid(handlerton *hton, XID *xid)
1638{
1639 xtBool temp_thread;
1640 XTThreadPtr self;
1641 XTDatabaseHPtr db;
1642 int err = 0;
1643 XTXactPreparePtr xap;
1644 THD *thd;
1645
1646 XT_TRACE_CALL();
1647
1648 if (!(self = ha_temp_open_global_database(hton, &thd, &temp_thread, "TempForCommitXA", &err)))
1649 return err;
1650 db = self->st_database;
1651
1652 if ((xap = xt_xn_find_xa_data(db, xid->length(), (xtWord1 *) xid, TRUE, self))) {
1653 if ((self->st_xact_data = xt_xn_get_xact(db, xap->xp_xact_id, self))) {
1654 self->st_xact_data->xd_flags &= ~XT_XN_XAC_PREPARED; // Prepared transactions cannot be swept!
1655 if (!xt_xn_commit(self))
1656 err = xt_ha_pbxt_thread_error_for_mysql(thd, self, FALSE);
1657 }
1658 xt_xn_delete_xa_data(db, xap, TRUE, self);
1659 }
1660
1661 ha_temp_close_database(self, thd, temp_thread);
1662 return 0;
1663}
1664
1665static int pbxt_rollback_by_xid(handlerton *hton, XID *xid)
1666{
1667 int temp_thread;
1668 XTThreadPtr self;
1669 XTDatabaseHPtr db;
1670 int err = 0;
1671 XTXactPreparePtr xap;
1672 THD *thd;
1673
1674 XT_TRACE_CALL();
1675
1676 if (!(self = ha_temp_open_global_database(hton, &thd, &temp_thread, "TempForRollbackXA", &err)))
1677 return err;
1678 db = self->st_database;
1679
1680 if ((xap = xt_xn_find_xa_data(db, xid->length(), (xtWord1 *) xid, TRUE, self))) {
1681 if ((self->st_xact_data = xt_xn_get_xact(db, xap->xp_xact_id, self))) {
1682 self->st_xact_data->xd_flags &= ~XT_XN_XAC_PREPARED; // Prepared transactions cannot be swept!
1683 if (!xt_xn_rollback(self))
1684 err = xt_ha_pbxt_thread_error_for_mysql(thd, self, FALSE);
1685 }
1686 xt_xn_delete_xa_data(db, xap, TRUE, self);
1687 }
1688
1689 ha_temp_close_database(self, thd, temp_thread);
1690 return 0;
1691}
1692
1693#endif
1694
1695/*
1696 * -----------------------------------------------------------------------
1449 * HANDLER LOCKING FUNCTIONS1697 * HANDLER LOCKING FUNCTIONS
1450 *1698 *
1451 * These functions are used get a lock on all handles of a particular table.1699 * These functions are used get a lock on all handles of a particular table.
@@ -1497,7 +1745,7 @@
1497 ha_pbxt *handler;1745 ha_pbxt *handler;
1498 time_t end_time = time(NULL) + XT_SHARE_LOCK_TIMEOUT / 1000;1746 time_t end_time = time(NULL) + XT_SHARE_LOCK_TIMEOUT / 1000;
14991747
1500 XT_PRINT1(self, "ha_aquire_exclusive_use %s PBXT X lock\n", share->sh_table_path->ps_path);1748 XT_PRINT1(self, "ha_aquire_exclusive_use (%s) PBXT X lock\n", share->sh_table_path->ps_path);
1501 /* GOTCHA: It is possible to hang here, if you hold1749 /* GOTCHA: It is possible to hang here, if you hold
1502 * onto the sh_ex_mutex lock, before we really1750 * onto the sh_ex_mutex lock, before we really
1503 * have the exclusive lock (i.e. before all1751 * have the exclusive lock (i.e. before all
@@ -1578,7 +1826,7 @@
1578static void ha_release_exclusive_use(XTThreadPtr XT_UNUSED(self), XTSharePtr share)1826static void ha_release_exclusive_use(XTThreadPtr XT_UNUSED(self), XTSharePtr share)
1579#endif1827#endif
1580{1828{
1581 XT_PRINT1(self, "ha_release_exclusive_use %s PBXT X UNLOCK\n", share->sh_table_path->ps_path);1829 XT_PRINT1(self, "ha_release_exclusive_use (%s) PBXT X UNLOCK\n", share->sh_table_path->ps_path);
1582 xt_lock_mutex_ns((xt_mutex_type *) share->sh_ex_mutex);1830 xt_lock_mutex_ns((xt_mutex_type *) share->sh_ex_mutex);
1583 share->sh_table_lock = FALSE;1831 share->sh_table_lock = FALSE;
1584 xt_broadcast_cond_ns((xt_cond_type *) share->sh_ex_cond);1832 xt_broadcast_cond_ns((xt_cond_type *) share->sh_ex_cond);
@@ -1589,7 +1837,7 @@
1589{1837{
1590 time_t end_time = time(NULL) + XT_SHARE_LOCK_TIMEOUT / 1000;1838 time_t end_time = time(NULL) + XT_SHARE_LOCK_TIMEOUT / 1000;
15911839
1592 XT_PRINT1(xt_get_self(), "ha_wait_for_shared_use %s share lock wait...\n", share->sh_table_path->ps_path);1840 XT_PRINT1(xt_get_self(), "ha_wait_for_shared_use (%s) share lock wait...\n", share->sh_table_path->ps_path);
1593 mine->pb_ex_in_use = 0;1841 mine->pb_ex_in_use = 0;
1594 xt_lock_mutex_ns((xt_mutex_type *) share->sh_ex_mutex);1842 xt_lock_mutex_ns((xt_mutex_type *) share->sh_ex_mutex);
1595 while (share->sh_table_lock) {1843 while (share->sh_table_lock) {
@@ -1667,14 +1915,38 @@
1667 *1915 *
1668 */1916 */
16691917
1670int pbxt_statistics_fill_table(THD *thd, TABLE_LIST *tables, COND *cond)1918static int pbxt_statistics_fill_table(THD *thd, TABLE_LIST *tables, COND *cond)
1671{1919{
1672 XTThreadPtr self; 1920 XTThreadPtr self = NULL;
1673 int err = 0;1921 int err = 0;
16741922
1923 if (!pbxt_hton) {
1924 /* Can't do if PBXT is not loaded! */
1925 XTExceptionRec e;
1926
1927 xt_exception_xterr(&e, XT_CONTEXT, XT_ERR_PBXT_NOT_INSTALLED);
1928 xt_log_exception(NULL, &e, XT_LOG_DEFAULT);
1929 /* Just return an empty set: */
1930 return 0;
1931 }
1932
1675 if (!(self = ha_set_current_thread(thd, &err)))1933 if (!(self = ha_set_current_thread(thd, &err)))
1676 return xt_ha_pbxt_to_mysql_error(err);1934 return xt_ha_pbxt_to_mysql_error(err);
1935
1936
1677 try_(a) {1937 try_(a) {
1938 /* If the thread has no open database, and the global
1939 * database is already open, then open
1940 * the database. Otherwise the statement will be
1941 * executed without an open database, which means
1942 * that the related statistics will be missing.
1943 *
1944 * This includes all background threads.
1945 */
1946 if (!self->st_database && pbxt_database) {
1947 xt_ha_open_database_of_table(self, (XTPathStrPtr) NULL);
1948 }
1949
1678 err = myxt_statistics_fill_table(self, thd, tables, cond, system_charset_info);1950 err = myxt_statistics_fill_table(self, thd, tables, cond, system_charset_info);
1679 }1951 }
1680 catch_(a) {1952 catch_(a) {
@@ -1684,6 +1956,24 @@
1684 return err;1956 return err;
1685}1957}
16861958
1959#ifdef DRIZZLED
1960ColumnInfo pbxt_statistics_fields_info[]=
1961{
1962 ColumnInfo("ID", 4, MYSQL_TYPE_LONG, 0, 0, "The ID of the statistic", SKIP_OPEN_TABLE),
1963 ColumnInfo("Name", 40, MYSQL_TYPE_STRING, 0, 0, "The name of the statistic", SKIP_OPEN_TABLE),
1964 ColumnInfo("Value", 8, MYSQL_TYPE_LONGLONG, 0, 0, "The accumulated value", SKIP_OPEN_TABLE),
1965 ColumnInfo()
1966};
1967
1968class PBXTStatisticsMethods : public InfoSchemaMethods
1969{
1970public:
1971 int fillTable(Session *session, TableList *tables, COND *cond)
1972 {
1973 return pbxt_statistics_fill_table(session, tables, cond);
1974 }
1975};
1976#else
1687ST_FIELD_INFO pbxt_statistics_fields_info[]=1977ST_FIELD_INFO pbxt_statistics_fields_info[]=
1688{1978{
1689 { "ID", 4, MYSQL_TYPE_LONG, 0, 0, "The ID of the statistic", SKIP_OPEN_TABLE},1979 { "ID", 4, MYSQL_TYPE_LONG, 0, 0, "The ID of the statistic", SKIP_OPEN_TABLE},
@@ -1691,24 +1981,28 @@
1691 { "Value", 8, MYSQL_TYPE_LONGLONG, 0, 0, "The accumulated value", SKIP_OPEN_TABLE},1981 { "Value", 8, MYSQL_TYPE_LONGLONG, 0, 0, "The accumulated value", SKIP_OPEN_TABLE},
1692 { 0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}1982 { 0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
1693};1983};
1984#endif
16941985
1695#ifdef DRIZZLED1986#ifdef DRIZZLED
1696static InfoSchemaTable *pbxt_statistics_table;1987static InfoSchemaTable *pbxt_statistics_table;
16971988static PBXTStatisticsMethods pbxt_statistics_methods;
1698int pbxt_init_statitics(PluginRegistry &registry)1989static int pbxt_init_statistics(Registry &registry)
1699#else1990#else
1700int pbxt_init_statitics(void *p)1991static int pbxt_init_statistics(void *p)
1701#endif1992#endif
1702{1993{
1703#ifdef DRIZZLED1994#ifdef DRIZZLED
1704 pbxt_statistics_table = (InfoSchemaTable *)xt_calloc_ns(sizeof(InfoSchemaTable));1995 //pbxt_statistics_table = (InfoSchemaTable *)xt_calloc_ns(sizeof(InfoSchemaTable));
1705 pbxt_statistics_table->table_name= "PBXT_STATISTICS";1996 //pbxt_statistics_table->table_name= "PBXT_STATISTICS";
1997 pbxt_statistics_table = new InfoSchemaTable("PBXT_STATISTICS");
1998 pbxt_statistics_table->setColumnInfo(pbxt_statistics_fields_info);
1999 pbxt_statistics_table->setInfoSchemaMethods(&pbxt_statistics_methods);
1706 registry.add(pbxt_statistics_table);2000 registry.add(pbxt_statistics_table);
1707#else2001#else
1708 ST_SCHEMA_TABLE *pbxt_statistics_table = (ST_SCHEMA_TABLE *) p;2002 ST_SCHEMA_TABLE *pbxt_statistics_table = (ST_SCHEMA_TABLE *) p;
1709#endif
1710 pbxt_statistics_table->fields_info = pbxt_statistics_fields_info;2003 pbxt_statistics_table->fields_info = pbxt_statistics_fields_info;
1711 pbxt_statistics_table->fill_table = pbxt_statistics_fill_table;2004 pbxt_statistics_table->fill_table = pbxt_statistics_fill_table;
2005#endif
17122006
1713#if defined(XT_WIN) && defined(XT_COREDUMP)2007#if defined(XT_WIN) && defined(XT_COREDUMP)
1714 void register_crash_filter();2008 void register_crash_filter();
@@ -1721,14 +2015,14 @@
1721}2015}
17222016
1723#ifdef DRIZZLED2017#ifdef DRIZZLED
1724int pbxt_exit_statitics(PluginRegistry &registry)2018static int pbxt_exit_statistics(Registry &registry)
1725#else2019#else
1726int pbxt_exit_statitics(void *XT_UNUSED(p))2020static int pbxt_exit_statistics(void *XT_UNUSED(p))
1727#endif2021#endif
1728{2022{
1729#ifdef DRIZZLED2023#ifdef DRIZZLED
1730 registry.remove(pbxt_statistics_table);2024 registry.remove(pbxt_statistics_table);
1731 xt_free_ns(pbxt_statistics_table);2025 delete pbxt_statistics_table;
1732#endif2026#endif
1733 return(0);2027 return(0);
1734}2028}
@@ -1758,7 +2052,11 @@
1758 * exist for the storage engine. This is also used by the default rename_table and2052 * exist for the storage engine. This is also used by the default rename_table and
1759 * delete_table method in handler.cc.2053 * delete_table method in handler.cc.
1760 */2054 */
2055#ifdef DRIZZLED
2056const char **PBXTStorageEngine::bas_ext() const
2057#else
1761const char **ha_pbxt::bas_ext() const2058const char **ha_pbxt::bas_ext() const
2059#endif
1762{2060{
1763 return pbxt_extensions;2061 return pbxt_extensions;
1764}2062}
@@ -1800,11 +2098,13 @@
1800 * purposes!2098 * purposes!
1801 HA_NOT_EXACT_COUNT |2099 HA_NOT_EXACT_COUNT |
1802 */2100 */
2101#ifndef DRIZZLED
1803 /*2102 /*
1804 * This basically means we have a file with the name of2103 * This basically means we have a file with the name of
1805 * database table (which we do).2104 * database table (which we do).
1806 */2105 */
1807 HA_FILE_BASED |2106 HA_FILE_BASED |
2107#endif
1808 /*2108 /*
1809 * Not sure what this does (but MyISAM and InnoDB have it)?!2109 * Not sure what this does (but MyISAM and InnoDB have it)?!
1810 * Could it mean that we support the handler functions.2110 * Could it mean that we support the handler functions.
@@ -1971,7 +2271,7 @@
1971 if (!(self = ha_set_current_thread(thd, &err)))2271 if (!(self = ha_set_current_thread(thd, &err)))
1972 return xt_ha_pbxt_to_mysql_error(err);2272 return xt_ha_pbxt_to_mysql_error(err);
19732273
1974 XT_PRINT1(self, "ha_pbxt::open %s\n", table_path);2274 XT_PRINT1(self, "open (%s)\n", table_path);
19752275
1976 pb_ex_in_use = 1;2276 pb_ex_in_use = 1;
1977 try_(a) {2277 try_(a) {
@@ -2049,7 +2349,7 @@
2049 }2349 }
2050 }2350 }
20512351
2052 XT_PRINT1(self, "ha_pbxt::close %s\n", pb_share && pb_share->sh_table_path->ps_path ? pb_share->sh_table_path->ps_path : "unknown");2352 XT_PRINT1(self, "close (%s)\n", pb_share && pb_share->sh_table_path->ps_path ? pb_share->sh_table_path->ps_path : "unknown");
20532353
2054 if (self) {2354 if (self) {
2055 try_(a) {2355 try_(a) {
@@ -2125,9 +2425,10 @@
2125 if (!TS(table)->next_number_key_offset) {2425 if (!TS(table)->next_number_key_offset) {
2126 // Autoincrement at key-start2426 // Autoincrement at key-start
2127 err = index_last(table->record[1]);2427 err = index_last(table->record[1]);
2128 if (!err)2428 if (!err && !table->next_number_field->is_null(TS(table)->rec_buff_length)) {
2129 /* {PRE-INC} */2429 /* {PRE-INC} */
2130 nr = (xtWord8) table->next_number_field->val_int_offset(TS(table)->rec_buff_length);2430 nr = (xtWord8) table->next_number_field->val_int_offset(TS(table)->rec_buff_length);
2431 }
2131 }2432 }
2132 else {2433 else {
2133 /* Do an index scan to find the largest value! */2434 /* Do an index scan to find the largest value! */
@@ -2180,8 +2481,10 @@
2180 table->next_number_field = tmp_fie;2481 table->next_number_field = tmp_fie;
2181 table->in_use = tmp_thd;2482 table->in_use = tmp_thd;
21822483
2183 if (xn_started)2484 if (xn_started) {
2485 XT_PRINT0(self, "xt_xn_commit in init_auto_increment\n");
2184 xt_xn_commit(self);2486 xt_xn_commit(self);
2487 }
2185 }2488 }
2186 xt_spinlock_unlock(&tab->tab_ainc_lock);2489 xt_spinlock_unlock(&tab->tab_ainc_lock);
2187}2490}
@@ -2228,13 +2531,13 @@
2228 * insert into t1 values (-1);2531 * insert into t1 values (-1);
2229 * insert into t1 values (NULL);2532 * insert into t1 values (NULL);
2230 */2533 */
2231void ha_pbxt::set_auto_increment(Field *nr)2534xtPublic void ha_set_auto_increment(XTOpenTablePtr ot, Field *nr)
2232{2535{
2233 register XTTableHPtr tab;2536 register XTTableHPtr tab;
2234 MX_ULONGLONG_T nr_int_val;2537 MX_ULONGLONG_T nr_int_val;
2235 2538
2236 nr_int_val = nr->val_int();2539 nr_int_val = nr->val_int();
2237 tab = pb_open_tab->ot_table;2540 tab = ot->ot_table;
22382541
2239 if (nr->cmp((const unsigned char *)&tab->tab_auto_inc) > 0) {2542 if (nr->cmp((const unsigned char *)&tab->tab_auto_inc) > 0) {
2240 xt_spinlock_lock(&tab->tab_ainc_lock);2543 xt_spinlock_lock(&tab->tab_ainc_lock);
@@ -2260,9 +2563,9 @@
2260#else2563#else
2261 tab->tab_dic.dic_min_auto_inc = nr_int_val + 100;2564 tab->tab_dic.dic_min_auto_inc = nr_int_val + 100;
2262#endif2565#endif
2263 pb_open_tab->ot_thread = xt_get_self();2566 ot->ot_thread = xt_get_self();
2264 if (!xt_tab_write_min_auto_inc(pb_open_tab))2567 if (!xt_tab_write_min_auto_inc(ot))
2265 xt_log_and_clear_exception(pb_open_tab->ot_thread);2568 xt_log_and_clear_exception(ot->ot_thread);
2266 }2569 }
2267 }2570 }
2268}2571}
@@ -2305,7 +2608,7 @@
23052608
2306 ASSERT_NS(pb_ex_in_use);2609 ASSERT_NS(pb_ex_in_use);
23072610
2308 XT_PRINT1(pb_open_tab->ot_thread, "ha_pbxt::write_row %s\n", pb_share->sh_table_path->ps_path);2611 XT_PRINT1(pb_open_tab->ot_thread, "write_row (%s)\n", pb_share->sh_table_path->ps_path);
2309 XT_DISABLED_TRACE(("INSERT tx=%d val=%d\n", (int) pb_open_tab->ot_thread->st_xact_data->xd_start_xn_id, (int) XT_GET_DISK_4(&buf[1])));2612 XT_DISABLED_TRACE(("INSERT tx=%d val=%d\n", (int) pb_open_tab->ot_thread->st_xact_data->xd_start_xn_id, (int) XT_GET_DISK_4(&buf[1])));
2310 //statistic_increment(ha_write_count,&LOCK_status);2613 //statistic_increment(ha_write_count,&LOCK_status);
2311#ifdef PBMS_ENABLED2614#ifdef PBMS_ENABLED
@@ -2350,7 +2653,7 @@
2350 err = update_err;2653 err = update_err;
2351 goto done;2654 goto done;
2352 }2655 }
2353 set_auto_increment(table->next_number_field);2656 ha_set_auto_increment(pb_open_tab, table->next_number_field);
2354 }2657 }
23552658
2356 if (!xt_tab_new_record(pb_open_tab, (xtWord1 *) buf)) {2659 if (!xt_tab_new_record(pb_open_tab, (xtWord1 *) buf)) {
@@ -2423,7 +2726,7 @@
24232726
2424 ASSERT_NS(pb_ex_in_use);2727 ASSERT_NS(pb_ex_in_use);
24252728
2426 XT_PRINT1(self, "ha_pbxt::update_row %s\n", pb_share->sh_table_path->ps_path);2729 XT_PRINT1(self, "update_row (%s)\n", pb_share->sh_table_path->ps_path);
2427 XT_DISABLED_TRACE(("UPDATE tx=%d val=%d\n", (int) self->st_xact_data->xd_start_xn_id, (int) XT_GET_DISK_4(&new_data[1])));2730 XT_DISABLED_TRACE(("UPDATE tx=%d val=%d\n", (int) self->st_xact_data->xd_start_xn_id, (int) XT_GET_DISK_4(&new_data[1])));
2428 //statistic_increment(ha_update_count,&LOCK_status);2731 //statistic_increment(ha_update_count,&LOCK_status);
24292732
@@ -2472,7 +2775,7 @@
24722775
2473 old_map = mx_tmp_use_all_columns(table, table->read_set);2776 old_map = mx_tmp_use_all_columns(table, table->read_set);
2474 nr = table->found_next_number_field->val_int();2777 nr = table->found_next_number_field->val_int();
2475 set_auto_increment(table->found_next_number_field);2778 ha_set_auto_increment(pb_open_tab, table->found_next_number_field);
2476 mx_tmp_restore_column_map(table, old_map);2779 mx_tmp_restore_column_map(table, old_map);
2477 }2780 }
24782781
@@ -2504,7 +2807,7 @@
25042807
2505 ASSERT_NS(pb_ex_in_use);2808 ASSERT_NS(pb_ex_in_use);
25062809
2507 XT_PRINT1(pb_open_tab->ot_thread, "ha_pbxt::delete_row %s\n", pb_share->sh_table_path->ps_path);2810 XT_PRINT1(pb_open_tab->ot_thread, "delete_row (%s)\n", pb_share->sh_table_path->ps_path);
2508 XT_DISABLED_TRACE(("DELETE tx=%d val=%d\n", (int) pb_open_tab->ot_thread->st_xact_data->xd_start_xn_id, (int) XT_GET_DISK_4(&buf[1])));2811 XT_DISABLED_TRACE(("DELETE tx=%d val=%d\n", (int) pb_open_tab->ot_thread->st_xact_data->xd_start_xn_id, (int) XT_GET_DISK_4(&buf[1])));
2509 //statistic_increment(ha_delete_count,&LOCK_status);2812 //statistic_increment(ha_delete_count,&LOCK_status);
25102813
@@ -2829,7 +3132,8 @@
28293132
2830int ha_pbxt::index_init(uint idx, bool XT_UNUSED(sorted))3133int ha_pbxt::index_init(uint idx, bool XT_UNUSED(sorted))
2831{3134{
2832 XTIndexPtr ind;3135 XTIndexPtr ind;
3136 XTThreadPtr thread = pb_open_tab->ot_thread;
28333137
2834 /* select count(*) from smalltab_PBXT;3138 /* select count(*) from smalltab_PBXT;
2835 * ignores the error below, and continues to3139 * ignores the error below, and continues to
@@ -2851,6 +3155,15 @@
28513155
2852 printf("index_init %s index %d cols req=%d/%d read_bits=%X write_bits=%X index_bits=%X\n", pb_open_tab->ot_table->tab_name->ps_path, (int) idx, pb_open_tab->ot_cols_req, pb_open_tab->ot_cols_req, (int) *table->read_set->bitmap, (int) *table->write_set->bitmap, (int) *ind->mi_col_map.bitmap);3156 printf("index_init %s index %d cols req=%d/%d read_bits=%X write_bits=%X index_bits=%X\n", pb_open_tab->ot_table->tab_name->ps_path, (int) idx, pb_open_tab->ot_cols_req, pb_open_tab->ot_cols_req, (int) *table->read_set->bitmap, (int) *table->write_set->bitmap, (int) *ind->mi_col_map.bitmap);
2853#endif3157#endif
3158 /* Start a statement based transaction as soon
3159 * as a read is done for a modify type statement!
3160 * Previously, this was done too late!
3161 */
3162 if (!thread->st_stat_trans) {
3163 trans_register_ha(pb_mysql_thd, FALSE, pbxt_hton);
3164 XT_PRINT0(thread, "ha_pbxt::update_row trans_register_ha all=FALSE\n");
3165 thread->st_stat_trans = TRUE;
3166 }
2854 }3167 }
2855 else {3168 else {
2856 pb_open_tab->ot_cols_req = ha_get_max_bit(table->read_set);3169 pb_open_tab->ot_cols_req = ha_get_max_bit(table->read_set);
@@ -2901,7 +3214,7 @@
2901#endif3214#endif
2902 }3215 }
2903 3216
2904 xt_xlog_check_long_writer(pb_open_tab->ot_thread);3217 xt_xlog_check_long_writer(thread);
29053218
2906 pb_open_tab->ot_thread->st_statistics.st_scan_index++;3219 pb_open_tab->ot_thread->st_statistics.st_scan_index++;
2907 return 0;3220 return 0;
@@ -2911,7 +3224,7 @@
2911{3224{
2912 int err = 0;3225 int err = 0;
29133226
2914 XT_TRACE_CALL();3227 XT_TRACE_METHOD();
29153228
2916 XTThreadPtr thread = pb_open_tab->ot_thread;3229 XTThreadPtr thread = pb_open_tab->ot_thread;
29173230
@@ -2991,7 +3304,7 @@
29913304
2992 ASSERT_NS(pb_ex_in_use);3305 ASSERT_NS(pb_ex_in_use);
29933306
2994 XT_PRINT1(pb_open_tab->ot_thread, "ha_pbxt::index_read_xt %s\n", pb_share->sh_table_path->ps_path);3307 XT_PRINT1(pb_open_tab->ot_thread, "index_read_xt (%s)\n", pb_share->sh_table_path->ps_path);
2995 XT_DISABLED_TRACE(("search tx=%d val=%d update=%d\n", (int) pb_open_tab->ot_thread->st_xact_data->xd_start_xn_id, (int) XT_GET_DISK_4(key), pb_modified));3308 XT_DISABLED_TRACE(("search tx=%d val=%d update=%d\n", (int) pb_open_tab->ot_thread->st_xact_data->xd_start_xn_id, (int) XT_GET_DISK_4(key), pb_modified));
2996 ind = (XTIndexPtr) pb_share->sh_dic_keys[idx];3309 ind = (XTIndexPtr) pb_share->sh_dic_keys[idx];
29973310
@@ -3072,7 +3385,7 @@
3072 int err = 0;3385 int err = 0;
3073 XTIndexPtr ind;3386 XTIndexPtr ind;
30743387
3075 XT_TRACE_CALL();3388 XT_TRACE_METHOD();
3076 //statistic_increment(ha_read_next_count,&LOCK_status);3389 //statistic_increment(ha_read_next_count,&LOCK_status);
3077 ASSERT_NS(pb_ex_in_use);3390 ASSERT_NS(pb_ex_in_use);
30783391
@@ -3114,7 +3427,7 @@
3114 XTIndexPtr ind;3427 XTIndexPtr ind;
3115 XTIdxSearchKeyRec search_key;3428 XTIdxSearchKeyRec search_key;
31163429
3117 XT_TRACE_CALL();3430 XT_TRACE_METHOD();
3118 //statistic_increment(ha_read_next_count,&LOCK_status);3431 //statistic_increment(ha_read_next_count,&LOCK_status);
3119 ASSERT_NS(pb_ex_in_use);3432 ASSERT_NS(pb_ex_in_use);
31203433
@@ -3154,7 +3467,7 @@
3154 int err = 0;3467 int err = 0;
3155 XTIndexPtr ind;3468 XTIndexPtr ind;
31563469
3157 XT_TRACE_CALL();3470 XT_TRACE_METHOD();
3158 //statistic_increment(ha_read_prev_count,&LOCK_status);3471 //statistic_increment(ha_read_prev_count,&LOCK_status);
3159 ASSERT_NS(pb_ex_in_use);3472 ASSERT_NS(pb_ex_in_use);
31603473
@@ -3188,7 +3501,7 @@
3188 XTIndexPtr ind;3501 XTIndexPtr ind;
3189 XTIdxSearchKeyRec search_key;3502 XTIdxSearchKeyRec search_key;
31903503
3191 XT_TRACE_CALL();3504 XT_TRACE_METHOD();
3192 //statistic_increment(ha_read_first_count,&LOCK_status);3505 //statistic_increment(ha_read_first_count,&LOCK_status);
3193 ASSERT_NS(pb_ex_in_use);3506 ASSERT_NS(pb_ex_in_use);
31943507
@@ -3228,7 +3541,7 @@
3228 XTIndexPtr ind;3541 XTIndexPtr ind;
3229 XTIdxSearchKeyRec search_key;3542 XTIdxSearchKeyRec search_key;
32303543
3231 XT_TRACE_CALL();3544 XT_TRACE_METHOD();
3232 //statistic_increment(ha_read_last_count,&LOCK_status);3545 //statistic_increment(ha_read_last_count,&LOCK_status);
3233 ASSERT_NS(pb_ex_in_use);3546 ASSERT_NS(pb_ex_in_use);
32343547
@@ -3275,10 +3588,11 @@
3275 */3588 */
3276int ha_pbxt::rnd_init(bool scan)3589int ha_pbxt::rnd_init(bool scan)
3277{3590{
3278 int err = 0;3591 int err = 0;
3592 XTThreadPtr thread = pb_open_tab->ot_thread;
32793593
3280 XT_PRINT1(pb_open_tab->ot_thread, "ha_pbxt::rnd_init %s\n", pb_share->sh_table_path->ps_path);3594 XT_PRINT1(thread, "rnd_init (%s)\n", pb_share->sh_table_path->ps_path);
3281 XT_DISABLED_TRACE(("seq scan tx=%d\n", (int) pb_open_tab->ot_thread->st_xact_data->xd_start_xn_id));3595 XT_DISABLED_TRACE(("seq scan tx=%d\n", (int) thread->st_xact_data->xd_start_xn_id));
32823596
3283 /* Call xt_tab_seq_exit() to make sure the resources used by the previous3597 /* Call xt_tab_seq_exit() to make sure the resources used by the previous
3284 * scan are freed. In particular make sure cache page ref count is decremented.3598 * scan are freed. In particular make sure cache page ref count is decremented.
@@ -3296,8 +3610,18 @@
3296 xt_tab_seq_exit(pb_open_tab);3610 xt_tab_seq_exit(pb_open_tab);
32973611
3298 /* The number of columns required: */3612 /* The number of columns required: */
3299 if (pb_open_tab->ot_is_modify)3613 if (pb_open_tab->ot_is_modify) {
3300 pb_open_tab->ot_cols_req = table->read_set->MX_BIT_SIZE();3614 pb_open_tab->ot_cols_req = table->read_set->MX_BIT_SIZE();
3615 /* Start a statement based transaction as soon
3616 * as a read is done for a modify type statement!
3617 * Previously, this was done too late!
3618 */
3619 if (!thread->st_stat_trans) {
3620 trans_register_ha(pb_mysql_thd, FALSE, pbxt_hton);
3621 XT_PRINT0(thread, "ha_pbxt::update_row trans_register_ha all=FALSE\n");
3622 thread->st_stat_trans = TRUE;
3623 }
3624 }
3301 else {3625 else {
3302 pb_open_tab->ot_cols_req = ha_get_max_bit(table->read_set);3626 pb_open_tab->ot_cols_req = ha_get_max_bit(table->read_set);
33033627
@@ -3322,14 +3646,14 @@
3322 else3646 else
3323 xt_tab_seq_reset(pb_open_tab);3647 xt_tab_seq_reset(pb_open_tab);
33243648
3325 xt_xlog_check_long_writer(pb_open_tab->ot_thread);3649 xt_xlog_check_long_writer(thread);
33263650
3327 return err;3651 return err;
3328}3652}
33293653
3330int ha_pbxt::rnd_end()3654int ha_pbxt::rnd_end()
3331{3655{
3332 XT_TRACE_CALL();3656 XT_TRACE_METHOD();
33333657
3334 /*3658 /*
3335 * make permanent the lock for the last scanned row3659 * make permanent the lock for the last scanned row
@@ -3358,7 +3682,7 @@
3358 int err = 0;3682 int err = 0;
3359 xtBool eof;3683 xtBool eof;
33603684
3361 XT_TRACE_CALL();3685 XT_TRACE_METHOD();
3362 ASSERT_NS(pb_ex_in_use);3686 ASSERT_NS(pb_ex_in_use);
3363 //statistic_increment(ha_read_rnd_next_count, &LOCK_status);3687 //statistic_increment(ha_read_rnd_next_count, &LOCK_status);
3364 xt_xlog_check_long_writer(pb_open_tab->ot_thread);3688 xt_xlog_check_long_writer(pb_open_tab->ot_thread);
@@ -3393,7 +3717,7 @@
3393 */3717 */
3394void ha_pbxt::position(const byte *XT_UNUSED(record))3718void ha_pbxt::position(const byte *XT_UNUSED(record))
3395{3719{
3396 XT_TRACE_CALL();3720 XT_TRACE_METHOD();
3397 ASSERT_NS(pb_ex_in_use);3721 ASSERT_NS(pb_ex_in_use);
3398 /*3722 /*
3399 * I changed this from using little endian to big endian.3723 * I changed this from using little endian to big endian.
@@ -3429,10 +3753,10 @@
3429{3753{
3430 int err = 0;3754 int err = 0;
34313755
3432 XT_TRACE_CALL();3756 XT_TRACE_METHOD();
3433 ASSERT_NS(pb_ex_in_use);3757 ASSERT_NS(pb_ex_in_use);
3434 //statistic_increment(ha_read_rnd_count, &LOCK_status);3758 //statistic_increment(ha_read_rnd_count, &LOCK_status);
3435 XT_PRINT1(pb_open_tab->ot_thread, "ha_pbxt::rnd_pos %s\n", pb_share->sh_table_path->ps_path);3759 XT_PRINT1(pb_open_tab->ot_thread, "rnd_pos (%s)\n", pb_share->sh_table_path->ps_path);
34363760
3437 pb_open_tab->ot_curr_rec_id = mi_uint4korr((xtWord1 *) pos);3761 pb_open_tab->ot_curr_rec_id = mi_uint4korr((xtWord1 *) pos);
3438 switch (xt_tab_dirty_read_record(pb_open_tab, (xtWord1 *) buf)) {3762 switch (xt_tab_dirty_read_record(pb_open_tab, (xtWord1 *) buf)) {
@@ -3509,7 +3833,7 @@
3509 XTOpenTablePtr ot;3833 XTOpenTablePtr ot;
3510 int in_use;3834 int in_use;
35113835
3512 XT_TRACE_CALL();3836 XT_TRACE_METHOD();
3513 3837
3514 if (!(in_use = pb_ex_in_use)) {3838 if (!(in_use = pb_ex_in_use)) {
3515 pb_ex_in_use = 1;3839 pb_ex_in_use = 1;
@@ -3535,7 +3859,7 @@
3535 stats.index_file_length = xt_ind_node_to_offset(ot->ot_table, ot->ot_table->tab_ind_eof);3859 stats.index_file_length = xt_ind_node_to_offset(ot->ot_table, ot->ot_table->tab_ind_eof);
3536 stats.delete_length = ot->ot_table->tab_rec_fnum * ot->ot_rec_size;3860 stats.delete_length = ot->ot_table->tab_rec_fnum * ot->ot_rec_size;
3537 //check_time = info.check_time;3861 //check_time = info.check_time;
3538 stats.mean_rec_length = ot->ot_rec_size;3862 stats.mean_rec_length = (ulong) ot->ot_rec_size;
3539 }3863 }
35403864
3541 if (flag & HA_STATUS_CONST) {3865 if (flag & HA_STATUS_CONST) {
@@ -3551,7 +3875,9 @@
3551 stats.block_size = XT_INDEX_PAGE_SIZE;3875 stats.block_size = XT_INDEX_PAGE_SIZE;
35523876
3553 if (share->tmp_table == NO_TMP_TABLE)3877 if (share->tmp_table == NO_TMP_TABLE)
3554#if MYSQL_VERSION_ID > 600053878#ifdef DRIZZLED
3879#define WHICH_MUTEX mutex
3880#elif MYSQL_VERSION_ID >= 50404
3555#define WHICH_MUTEX LOCK_ha_data3881#define WHICH_MUTEX LOCK_ha_data
3556#else3882#else
3557#define WHICH_MUTEX mutex3883#define WHICH_MUTEX mutex
@@ -3559,19 +3885,15 @@
35593885
3560#ifdef SAFE_MUTEX3886#ifdef SAFE_MUTEX
35613887
3562#if MYSQL_VERSION_ID < 600003888#if MYSQL_VERSION_ID < 50404
3563#if MYSQL_VERSION_ID < 501233889#if MYSQL_VERSION_ID < 50123
3564 safe_mutex_lock(&share->mutex,__FILE__,__LINE__);3890 safe_mutex_lock(&share->mutex,__FILE__,__LINE__);
3565#else3891#else
3566 safe_mutex_lock(&share->mutex,0,__FILE__,__LINE__);3892 safe_mutex_lock(&share->mutex,0,__FILE__,__LINE__);
3567#endif3893#endif
3568#else3894#else
3569#if MYSQL_VERSION_ID < 60004
3570 safe_mutex_lock(&share->mutex,__FILE__,__LINE__);
3571#else
3572 safe_mutex_lock(&share->WHICH_MUTEX,0,__FILE__,__LINE__);3895 safe_mutex_lock(&share->WHICH_MUTEX,0,__FILE__,__LINE__);
3573#endif3896#endif
3574#endif
35753897
3576#else // SAFE_MUTEX3898#else // SAFE_MUTEX
35773899
@@ -3675,7 +3997,7 @@
3675{3997{
3676 int err = 0;3998 int err = 0;
36773999
3678 XT_PRINT2(xt_get_self(), "ha_pbxt::extra %s operation=%d\n", pb_share->sh_table_path->ps_path, operation);4000 XT_PRINT2(xt_get_self(), "ha_pbxt::extra (%s) operation=%d\n", pb_share->sh_table_path->ps_path, operation);
36794001
3680 switch (operation) {4002 switch (operation) {
3681 case HA_EXTRA_RESET_STATE:4003 case HA_EXTRA_RESET_STATE:
@@ -3771,14 +4093,14 @@
3771 */4093 */
3772int ha_pbxt::reset(void)4094int ha_pbxt::reset(void)
3773{4095{
3774 XT_TRACE_CALL();4096 XT_TRACE_METHOD();
3775 extra(HA_EXTRA_RESET_STATE);4097 extra(HA_EXTRA_RESET_STATE);
3776 XT_RETURN(0);4098 XT_RETURN(0);
3777}4099}
37784100
3779void ha_pbxt::unlock_row()4101void ha_pbxt::unlock_row()
3780{4102{
3781 XT_TRACE_CALL();4103 XT_TRACE_METHOD();
3782 if (pb_open_tab)4104 if (pb_open_tab)
3783 pb_open_tab->ot_table->tab_locks.xt_remove_temp_lock(pb_open_tab, FALSE);4105 pb_open_tab->ot_table->tab_locks.xt_remove_temp_lock(pb_open_tab, FALSE);
3784}4106}
@@ -3802,7 +4124,7 @@
3802 XTDDTable *tab_def = NULL;4124 XTDDTable *tab_def = NULL;
3803 char path[PATH_MAX];4125 char path[PATH_MAX];
38044126
3805 XT_TRACE_CALL();4127 XT_TRACE_METHOD();
38064128
3807 if (thd_sql_command(thd) != SQLCOM_TRUNCATE) {4129 if (thd_sql_command(thd) != SQLCOM_TRUNCATE) {
3808 /* Just like InnoDB we only handle TRUNCATE TABLE4130 /* Just like InnoDB we only handle TRUNCATE TABLE
@@ -3906,7 +4228,7 @@
3906 xtXactID clean_xn_id = 0;4228 xtXactID clean_xn_id = 0;
3907 uint cnt = 10;4229 uint cnt = 10;
39084230
3909 XT_TRACE_CALL();4231 XT_TRACE_METHOD();
39104232
3911 if (!pb_open_tab) {4233 if (!pb_open_tab) {
3912 if ((err = reopen()))4234 if ((err = reopen()))
@@ -4056,7 +4378,7 @@
4056 ASSERT_NS(pb_ex_in_use);4378 ASSERT_NS(pb_ex_in_use);
4057 */4379 */
40584380
4059 XT_PRINT1(self, "ha_pbxt::EXTERNAL_LOCK %s lock_type=UNLOCK\n", pb_share->sh_table_path->ps_path);4381 XT_PRINT1(self, "EXTERNAL_LOCK (%s) lock_type=UNLOCK\n", pb_share->sh_table_path->ps_path);
40604382
4061 /* Make any temporary locks on this table permanent.4383 /* Make any temporary locks on this table permanent.
4062 *4384 *
@@ -4189,10 +4511,9 @@
4189 xt_broadcast_cond_ns((xt_cond_type *) pb_share->sh_ex_cond);4511 xt_broadcast_cond_ns((xt_cond_type *) pb_share->sh_ex_cond);
4190 }4512 }
4191 else {4513 else {
4192 XT_PRINT2(self, "ha_pbxt::EXTERNAL_LOCK %s lock_type=%d\n", pb_share->sh_table_path->ps_path, lock_type);4514 XT_PRINT2(self, "ha_pbxt::EXTERNAL_LOCK (%s) lock_type=%d\n", pb_share->sh_table_path->ps_path, lock_type);
4193 4515
4194 if (pb_lock_table) {4516 if (pb_lock_table) {
4195
4196 pb_ex_in_use = 1;4517 pb_ex_in_use = 1;
4197 try_(a) {4518 try_(a) {
4198 if (!pb_table_locked)4519 if (!pb_table_locked)
@@ -4243,14 +4564,18 @@
4243 if ((pb_open_tab->ot_for_update = (lock_type == F_WRLCK))) {4564 if ((pb_open_tab->ot_for_update = (lock_type == F_WRLCK))) {
4244 switch ((int) thd_sql_command(thd)) {4565 switch ((int) thd_sql_command(thd)) {
4245 case SQLCOM_DELETE:4566 case SQLCOM_DELETE:
4567#ifndef DRIZZLED
4246 case SQLCOM_DELETE_MULTI:4568 case SQLCOM_DELETE_MULTI:
4569#endif
4247 /* turn DELETE IGNORE into normal DELETE. The IGNORE option causes problems because 4570 /* turn DELETE IGNORE into normal DELETE. The IGNORE option causes problems because
4248 * when a record is deleted we add an xlog record which we cannot "rollback" later4571 * when a record is deleted we add an xlog record which we cannot "rollback" later
4249 * when we find that an FK-constraint has failed. 4572 * when we find that an FK-constraint has failed.
4250 */4573 */
4251 thd->lex->ignore = false;4574 thd->lex->ignore = false;
4252 case SQLCOM_UPDATE:4575 case SQLCOM_UPDATE:
4576#ifndef DRIZZLED
4253 case SQLCOM_UPDATE_MULTI:4577 case SQLCOM_UPDATE_MULTI:
4578#endif
4254 case SQLCOM_REPLACE:4579 case SQLCOM_REPLACE:
4255 case SQLCOM_REPLACE_SELECT:4580 case SQLCOM_REPLACE_SELECT:
4256 case SQLCOM_INSERT:4581 case SQLCOM_INSERT:
@@ -4265,7 +4590,9 @@
4265 case SQLCOM_DROP_TABLE:4590 case SQLCOM_DROP_TABLE:
4266 case SQLCOM_DROP_INDEX:4591 case SQLCOM_DROP_INDEX:
4267 case SQLCOM_LOAD:4592 case SQLCOM_LOAD:
4593#ifndef DRIZZLED
4268 case SQLCOM_REPAIR:4594 case SQLCOM_REPAIR:
4595#endif
4269 case SQLCOM_OPTIMIZE:4596 case SQLCOM_OPTIMIZE:
4270 self->st_stat_modify = TRUE;4597 self->st_stat_modify = TRUE;
4271 break;4598 break;
@@ -4316,11 +4643,16 @@
4316 self->st_xact_mode = thd_tx_isolation(thd) <= ISO_READ_COMMITTED ? XT_XACT_COMMITTED_READ : XT_XACT_REPEATABLE_READ;4643 self->st_xact_mode = thd_tx_isolation(thd) <= ISO_READ_COMMITTED ? XT_XACT_COMMITTED_READ : XT_XACT_REPEATABLE_READ;
4317 self->st_ignore_fkeys = (thd_test_options(thd,OPTION_NO_FOREIGN_KEY_CHECKS)) != 0;4644 self->st_ignore_fkeys = (thd_test_options(thd,OPTION_NO_FOREIGN_KEY_CHECKS)) != 0;
4318 self->st_auto_commit = (thd_test_options(thd, (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) == 0;4645 self->st_auto_commit = (thd_test_options(thd, (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) == 0;
4646#ifdef DRIZZLED
4647 self->st_table_trans = FALSE;
4648#else
4319 self->st_table_trans = thd_sql_command(thd) == SQLCOM_LOCK_TABLES;4649 self->st_table_trans = thd_sql_command(thd) == SQLCOM_LOCK_TABLES;
4650#endif
4320 self->st_abort_trans = FALSE;4651 self->st_abort_trans = FALSE;
4321 self->st_stat_ended = FALSE;4652 self->st_stat_ended = FALSE;
4322 self->st_stat_trans = FALSE;4653 self->st_stat_trans = FALSE;
4323 XT_PRINT0(self, "xt_xn_begin\n");4654 XT_PRINT0(self, "xt_xn_begin\n");
4655 xt_xres_wait_for_recovery(self, XT_RECOVER_SWEPT);
4324 if (!xt_xn_begin(self)) {4656 if (!xt_xn_begin(self)) {
4325 err = xt_ha_pbxt_thread_error_for_mysql(thd, self, pb_ignore_dup_key);4657 err = xt_ha_pbxt_thread_error_for_mysql(thd, self, pb_ignore_dup_key);
4326 pb_ex_in_use = 0;4658 pb_ex_in_use = 0;
@@ -4404,7 +4736,7 @@
4404 if (!(self = ha_set_current_thread(thd, &err)))4736 if (!(self = ha_set_current_thread(thd, &err)))
4405 return xt_ha_pbxt_to_mysql_error(err);4737 return xt_ha_pbxt_to_mysql_error(err);
44064738
4407 XT_PRINT2(self, "ha_pbxt::start_stmt %s lock_type=%d\n", pb_share->sh_table_path->ps_path, (int) lock_type);4739 XT_PRINT2(self, "ha_pbxt::start_stmt (%s) lock_type=%d\n", pb_share->sh_table_path->ps_path, (int) lock_type);
44084740
4409 if (!pb_open_tab) {4741 if (!pb_open_tab) {
4410 if ((err = reopen()))4742 if ((err = reopen()))
@@ -4430,12 +4762,12 @@
4430 /* This section handles "auto-commit"... */4762 /* This section handles "auto-commit"... */
4431 if (self->st_xact_data && self->st_auto_commit && self->st_table_trans) {4763 if (self->st_xact_data && self->st_auto_commit && self->st_table_trans) {
4432 if (self->st_abort_trans) {4764 if (self->st_abort_trans) {
4433 XT_PRINT0(self, "xt_xn_rollback\n");4765 XT_PRINT0(self, "xt_xn_rollback in start_stmt\n");
4434 if (!xt_xn_rollback(self))4766 if (!xt_xn_rollback(self))
4435 err = xt_ha_pbxt_thread_error_for_mysql(pb_mysql_thd, self, pb_ignore_dup_key);4767 err = xt_ha_pbxt_thread_error_for_mysql(pb_mysql_thd, self, pb_ignore_dup_key);
4436 }4768 }
4437 else {4769 else {
4438 XT_PRINT0(self, "xt_xn_commit\n");4770 XT_PRINT0(self, "xt_xn_commit in start_stmt\n");
4439 if (!xt_xn_commit(self))4771 if (!xt_xn_commit(self))
4440 err = xt_ha_pbxt_thread_error_for_mysql(pb_mysql_thd, self, pb_ignore_dup_key);4772 err = xt_ha_pbxt_thread_error_for_mysql(pb_mysql_thd, self, pb_ignore_dup_key);
4441 }4773 }
@@ -4466,9 +4798,11 @@
4466 if (pb_open_tab->ot_for_update) {4798 if (pb_open_tab->ot_for_update) {
4467 switch ((int) thd_sql_command(thd)) {4799 switch ((int) thd_sql_command(thd)) {
4468 case SQLCOM_UPDATE:4800 case SQLCOM_UPDATE:
4801 case SQLCOM_DELETE:
4802#ifndef DRIZZLED
4469 case SQLCOM_UPDATE_MULTI:4803 case SQLCOM_UPDATE_MULTI:
4470 case SQLCOM_DELETE:
4471 case SQLCOM_DELETE_MULTI:4804 case SQLCOM_DELETE_MULTI:
4805#endif
4472 case SQLCOM_REPLACE:4806 case SQLCOM_REPLACE:
4473 case SQLCOM_REPLACE_SELECT:4807 case SQLCOM_REPLACE_SELECT:
4474 case SQLCOM_INSERT:4808 case SQLCOM_INSERT:
@@ -4483,14 +4817,15 @@
4483 case SQLCOM_DROP_TABLE:4817 case SQLCOM_DROP_TABLE:
4484 case SQLCOM_DROP_INDEX:4818 case SQLCOM_DROP_INDEX:
4485 case SQLCOM_LOAD:4819 case SQLCOM_LOAD:
4820#ifndef DRIZZLED
4486 case SQLCOM_REPAIR:4821 case SQLCOM_REPAIR:
4822#endif
4487 case SQLCOM_OPTIMIZE:4823 case SQLCOM_OPTIMIZE:
4488 self->st_stat_modify = TRUE;4824 self->st_stat_modify = TRUE;
4489 break;4825 break;
4490 }4826 }
4491 }4827 }
44924828
4493
4494 /* (***) This is required at this level!4829 /* (***) This is required at this level!
4495 * No matter how often it is called, it is still the start of a4830 * No matter how often it is called, it is still the start of a
4496 * statement. We need to make sure statements that are NOT mistaken4831 * statement. We need to make sure statements that are NOT mistaken
@@ -4516,6 +4851,7 @@
4516 self->st_stat_ended = FALSE;4851 self->st_stat_ended = FALSE;
4517 self->st_stat_trans = FALSE;4852 self->st_stat_trans = FALSE;
4518 XT_PRINT0(self, "xt_xn_begin\n");4853 XT_PRINT0(self, "xt_xn_begin\n");
4854 xt_xres_wait_for_recovery(self, XT_RECOVER_SWEPT);
4519 if (!xt_xn_begin(self)) {4855 if (!xt_xn_begin(self)) {
4520 err = xt_ha_pbxt_thread_error_for_mysql(thd, self, pb_ignore_dup_key);4856 err = xt_ha_pbxt_thread_error_for_mysql(thd, self, pb_ignore_dup_key);
4521 goto complete;4857 goto complete;
@@ -4673,7 +5009,9 @@
4673 * 5009 *
4674 */5010 */
4675 if ((lock_type >= TL_WRITE_CONCURRENT_INSERT && lock_type <= TL_WRITE) && 5011 if ((lock_type >= TL_WRITE_CONCURRENT_INSERT && lock_type <= TL_WRITE) &&
5012#ifndef DRIZZLED
4676 !(thd_in_lock_tables(thd) && thd_sql_command(thd) == SQLCOM_LOCK_TABLES) &&5013 !(thd_in_lock_tables(thd) && thd_sql_command(thd) == SQLCOM_LOCK_TABLES) &&
5014#endif
4677 !thd_tablespace_op(thd) &&5015 !thd_tablespace_op(thd) &&
4678 thd_sql_command(thd) != SQLCOM_TRUNCATE &&5016 thd_sql_command(thd) != SQLCOM_TRUNCATE &&
4679 thd_sql_command(thd) != SQLCOM_OPTIMIZE &&5017 thd_sql_command(thd) != SQLCOM_OPTIMIZE &&
@@ -4691,22 +5029,23 @@
46915029
4692 * Stewart: removed SQLCOM_CALL, not sure of implications.5030 * Stewart: removed SQLCOM_CALL, not sure of implications.
4693 */5031 */
4694 if (lock_type == TL_READ_NO_INSERT &&5032 if (lock_type == TL_READ_NO_INSERT
4695 (!thd_in_lock_tables(thd)
4696#ifndef DRIZZLED5033#ifndef DRIZZLED
5034 && (!thd_in_lock_tables(thd)
4697 || thd_sql_command(thd) == SQLCOM_CALL5035 || thd_sql_command(thd) == SQLCOM_CALL
5036 )
4698#endif5037#endif
4699 ))5038 )
4700 {5039 {
4701 lock_type = TL_READ;5040 lock_type = TL_READ;
4702 }5041 }
47035042
4704 XT_PRINT3(xt_get_self(), "ha_pbxt::store_lock %s %d->%d\n", pb_share->sh_table_path->ps_path, pb_lock.type, lock_type);5043 XT_PRINT3(xt_get_self(), "store_lock (%s) %d->%d\n", pb_share->sh_table_path->ps_path, pb_lock.type, lock_type);
4705 pb_lock.type = lock_type;5044 pb_lock.type = lock_type;
4706 }5045 }
4707#ifdef PBXT_HANDLER_TRACE5046#ifdef PBXT_HANDLER_TRACE
4708 else {5047 else {
4709 XT_PRINT3(xt_get_self(), "ha_pbxt::store_lock %s %d->%d (ignore/unlock)\n", pb_share->sh_table_path->ps_path, lock_type, lock_type);5048 XT_PRINT3(xt_get_self(), "store_lock (%s) %d->%d (ignore/unlock)\n", pb_share->sh_table_path->ps_path, lock_type, lock_type);
4710 }5049 }
4711#endif5050#endif
4712 *to++= &pb_lock;5051 *to++= &pb_lock;
@@ -4723,15 +5062,23 @@
4723 * during create if the table_flag HA_DROP_BEFORE_CREATE was specified for5062 * during create if the table_flag HA_DROP_BEFORE_CREATE was specified for
4724 * the storage engine.5063 * the storage engine.
4725*/5064*/
5065#ifdef DRIZZLED
5066int PBXTStorageEngine::doDropTable(Session &, std::string table_path_str)
5067#else
4726int ha_pbxt::delete_table(const char *table_path)5068int ha_pbxt::delete_table(const char *table_path)
5069#endif
4727{5070{
4728 THD *thd = current_thd;5071 THD *thd = current_thd;
4729 int err = 0;5072 int err = 0;
4730 XTThreadPtr self = NULL;5073 XTThreadPtr self = NULL;
4731 XTSharePtr share;5074 XTSharePtr share;
47325075
5076#ifdef DRIZZLED
5077 const char *table_path = table_path_str.c_str();
5078#endif
5079
4733 STAT_TRACE(self, *thd_query(thd));5080 STAT_TRACE(self, *thd_query(thd));
4734 XT_PRINT1(self, "ha_pbxt::delete_table %s\n", table_path);5081 XT_PRINT1(self, "delete_table (%s)\n", table_path);
47355082
4736 if (XTSystemTableShare::isSystemTable(table_path))5083 if (XTSystemTableShare::isSystemTable(table_path))
4737 return delete_system_table(table_path);5084 return delete_system_table(table_path);
@@ -4795,7 +5142,7 @@
4795#endif5142#endif
4796 }5143 }
4797 catch_(a) {5144 catch_(a) {
4798 err = xt_ha_pbxt_thread_error_for_mysql(thd, self, pb_ignore_dup_key);5145 err = xt_ha_pbxt_thread_error_for_mysql(thd, self, FALSE);
4799#ifdef DRIZZLED5146#ifdef DRIZZLED
4800 if (err == HA_ERR_NO_SUCH_TABLE)5147 if (err == HA_ERR_NO_SUCH_TABLE)
4801 err = ENOENT;5148 err = ENOENT;
@@ -4819,7 +5166,11 @@
4819 return err;5166 return err;
4820}5167}
48215168
5169#ifdef DRIZZLED
5170int PBXTStorageEngine::delete_system_table(const char *table_path)
5171#else
4822int ha_pbxt::delete_system_table(const char *table_path)5172int ha_pbxt::delete_system_table(const char *table_path)
5173#endif
4823{5174{
4824 THD *thd = current_thd;5175 THD *thd = current_thd;
4825 XTExceptionRec e;5176 XTExceptionRec e;
@@ -4857,7 +5208,13 @@
4857 * This function can be used to move a table from one database to5208 * This function can be used to move a table from one database to
4858 * another.5209 * another.
4859 */5210 */
5211#ifdef DRIZZLED
5212int PBXTStorageEngine::doRenameTable(Session *,
5213 const char *from,
5214 const char *to)
5215#else
4860int ha_pbxt::rename_table(const char *from, const char *to)5216int ha_pbxt::rename_table(const char *from, const char *to)
5217#endif
4861{5218{
4862 THD *thd = current_thd;5219 THD *thd = current_thd;
4863 int err = 0;5220 int err = 0;
@@ -4865,15 +5222,13 @@
4865 XTSharePtr share;5222 XTSharePtr share;
4866 XTDatabaseHPtr to_db;5223 XTDatabaseHPtr to_db;
48675224
4868 XT_TRACE_CALL();
4869
4870 if (XTSystemTableShare::isSystemTable(from))5225 if (XTSystemTableShare::isSystemTable(from))
4871 return rename_system_table(from, to);5226 return rename_system_table(from, to);
48725227
4873 if (!(self = ha_set_current_thread(thd, &err)))5228 if (!(self = ha_set_current_thread(thd, &err)))
4874 return xt_ha_pbxt_to_mysql_error(err);5229 return xt_ha_pbxt_to_mysql_error(err);
48755230
4876 XT_PRINT2(self, "ha_pbxt::rename_table %s -> %s\n", from, to);5231 XT_PRINT2(self, "rename_table (%s -> %s)\n", from, to);
48775232
4878#ifdef PBMS_ENABLED5233#ifdef PBMS_ENABLED
4879 PBMSResultRec result;5234 PBMSResultRec result;
@@ -4929,7 +5284,7 @@
4929#endif5284#endif
4930 }5285 }
4931 catch_(a) {5286 catch_(a) {
4932 err = xt_ha_pbxt_thread_error_for_mysql(thd, self, pb_ignore_dup_key);5287 err = xt_ha_pbxt_thread_error_for_mysql(thd, self, FALSE);
4933 }5288 }
4934 cont_(a);5289 cont_(a);
4935 5290
@@ -4940,7 +5295,11 @@
4940 XT_RETURN(err);5295 XT_RETURN(err);
4941}5296}
49425297
5298#ifdef DRIZZLED
5299int PBXTStorageEngine::rename_system_table(const char *XT_UNUSED(from), const char *XT_UNUSED(to))
5300#else
4943int ha_pbxt::rename_system_table(const char *XT_UNUSED(from), const char *XT_UNUSED(to))5301int ha_pbxt::rename_system_table(const char *XT_UNUSED(from), const char *XT_UNUSED(to))
5302#endif
4944{5303{
4945 return ER_NOT_SUPPORTED_YET;5304 return ER_NOT_SUPPORTED_YET;
4946}5305}
@@ -5029,7 +5388,15 @@
50295388
5030 * Called from handle.cc by ha_create_table().5389 * Called from handle.cc by ha_create_table().
5031*/5390*/
5391#ifdef DRIZZLED
5392int PBXTStorageEngine::doCreateTable(Session *,
5393 const char *table_path,
5394 Table &table_arg,
5395 HA_CREATE_INFO &create_info,
5396 drizzled::message::Table &XT_UNUSED(proto))
5397#else
5032int ha_pbxt::create(const char *table_path, TABLE *table_arg, HA_CREATE_INFO *create_info)5398int ha_pbxt::create(const char *table_path, TABLE *table_arg, HA_CREATE_INFO *create_info)
5399#endif
5033{5400{
5034 THD *thd = current_thd;5401 THD *thd = current_thd;
5035 int err = 0;5402 int err = 0;
@@ -5037,37 +5404,61 @@
5037 XTDDTable *tab_def = NULL;5404 XTDDTable *tab_def = NULL;
5038 XTDictionaryRec dic;5405 XTDictionaryRec dic;
50395406
5407 if ((strcmp(table_path, "./pbxt/location") == 0) || (strcmp(table_path, "./pbxt/statistics") == 0))
5408 return 0;
5409
5040 memset(&dic, 0, sizeof(dic));5410 memset(&dic, 0, sizeof(dic));
50415411
5042 XT_TRACE_CALL();
5043
5044 if (!(self = ha_set_current_thread(thd, &err)))5412 if (!(self = ha_set_current_thread(thd, &err)))
5045 return xt_ha_pbxt_to_mysql_error(err);5413 return xt_ha_pbxt_to_mysql_error(err);
5414#ifdef DRIZZLED
5415 XT_PRINT2(self, "create (%s) %s\n", table_path, (create_info.options & HA_LEX_CREATE_TMP_TABLE) ? "temporary" : "");
5416#else
5417 XT_PRINT2(self, "create (%s) %s\n", table_path, (create_info->options & HA_LEX_CREATE_TMP_TABLE) ? "temporary" : "");
5418#endif
50465419
5047 STAT_TRACE(self, *thd_query(thd));5420 STAT_TRACE(self, *thd_query(thd));
5048 XT_PRINT1(self, "ha_pbxt::create %s\n", table_path);
50495421
5050 try_(a) {5422 try_(a) {
5051 xt_ha_open_database_of_table(self, (XTPathStrPtr) table_path);5423 xt_ha_open_database_of_table(self, (XTPathStrPtr) table_path);
50525424
5425#ifdef DRIZZLED
5426 for (uint i=0; i<TS(&table_arg)->keys; i++) {
5427 if (table_arg.key_info[i].key_length > XT_INDEX_MAX_KEY_SIZE)
5428 xt_throw_sulxterr(XT_CONTEXT, XT_ERR_KEY_TOO_LARGE, table_arg.key_info[i].name, (u_long) XT_INDEX_MAX_KEY_SIZE);
5429 }
5430#else
5053 for (uint i=0; i<TS(table_arg)->keys; i++) {5431 for (uint i=0; i<TS(table_arg)->keys; i++) {
5054 if (table_arg->key_info[i].key_length > XT_INDEX_MAX_KEY_SIZE)5432 if (table_arg->key_info[i].key_length > XT_INDEX_MAX_KEY_SIZE)
5055 xt_throw_sulxterr(XT_CONTEXT, XT_ERR_KEY_TOO_LARGE, table_arg->key_info[i].name, (u_long) XT_INDEX_MAX_KEY_SIZE);5433 xt_throw_sulxterr(XT_CONTEXT, XT_ERR_KEY_TOO_LARGE, table_arg->key_info[i].name, (u_long) XT_INDEX_MAX_KEY_SIZE);
5056 }5434 }
5435#endif
50575436
5058 /* ($) auto_increment_value will be zero if 5437 /* ($) auto_increment_value will be zero if
5059 * AUTO_INCREMENT is not used. Otherwise5438 * AUTO_INCREMENT is not used. Otherwise
5060 * Query was ALTER TABLE ... AUTO_INCREMENT = x; or 5439 * Query was ALTER TABLE ... AUTO_INCREMENT = x; or
5061 * CREATE TABLE ... AUTO_INCREMENT = x;5440 * CREATE TABLE ... AUTO_INCREMENT = x;
5062 */5441 */
5442#ifdef DRIZZLED
5443 tab_def = xt_ri_create_table(self, true, (XTPathStrPtr) table_path, *thd_query(thd), myxt_create_table_from_table(self, &table_arg));
5444 tab_def->checkForeignKeys(self, create_info.options & HA_LEX_CREATE_TMP_TABLE);
5445#else
5063 tab_def = xt_ri_create_table(self, true, (XTPathStrPtr) table_path, *thd_query(thd), myxt_create_table_from_table(self, table_arg));5446 tab_def = xt_ri_create_table(self, true, (XTPathStrPtr) table_path, *thd_query(thd), myxt_create_table_from_table(self, table_arg));
5064 tab_def->checkForeignKeys(self, create_info->options & HA_LEX_CREATE_TMP_TABLE);5447 tab_def->checkForeignKeys(self, create_info->options & HA_LEX_CREATE_TMP_TABLE);
5448#endif
50655449
5066 dic.dic_table = tab_def;5450 dic.dic_table = tab_def;
5451#ifdef DRIZZLED
5452 dic.dic_my_table = &table_arg;
5453 dic.dic_tab_flags = (create_info.options & HA_LEX_CREATE_TMP_TABLE) ? XT_TAB_FLAGS_TEMP_TAB : 0;
5454 dic.dic_min_auto_inc = (xtWord8) create_info.auto_increment_value; /* ($) */
5455 dic.dic_def_ave_row_size = table_arg.s->getAvgRowLength();
5456#else
5067 dic.dic_my_table = table_arg;5457 dic.dic_my_table = table_arg;
5068 dic.dic_tab_flags = (create_info->options & HA_LEX_CREATE_TMP_TABLE) ? XT_TAB_FLAGS_TEMP_TAB : 0;5458 dic.dic_tab_flags = (create_info->options & HA_LEX_CREATE_TMP_TABLE) ? XT_TAB_FLAGS_TEMP_TAB : 0;
5069 dic.dic_min_auto_inc = (xtWord8) create_info->auto_increment_value; /* ($) */5459 dic.dic_min_auto_inc = (xtWord8) create_info->auto_increment_value; /* ($) */
5070 dic.dic_def_ave_row_size = (xtWord8) table_arg->s->avg_row_length;5460 dic.dic_def_ave_row_size = (xtWord8) table_arg->s->avg_row_length;
5461#endif
5071 myxt_setup_dictionary(self, &dic);5462 myxt_setup_dictionary(self, &dic);
50725463
5073 /*5464 /*
@@ -5089,7 +5480,7 @@
5089 if (tab_def)5480 if (tab_def)
5090 tab_def->finalize(self);5481 tab_def->finalize(self);
5091 dic.dic_table = NULL;5482 dic.dic_table = NULL;
5092 err = xt_ha_pbxt_thread_error_for_mysql(thd, self, pb_ignore_dup_key);5483 err = xt_ha_pbxt_thread_error_for_mysql(thd, self, FALSE);
5093 }5484 }
5094 cont_(a);5485 cont_(a);
50955486
@@ -5161,7 +5552,7 @@
5161 if (!self->t_exception.e_xt_err)5552 if (!self->t_exception.e_xt_err)
5162 return FALSE;5553 return FALSE;
51635554
5164 buf->copy(self->t_exception.e_err_msg, strlen(self->t_exception.e_err_msg), system_charset_info);5555 buf->copy(self->t_exception.e_err_msg, (uint32) strlen(self->t_exception.e_err_msg), system_charset_info);
5165 return TRUE;5556 return TRUE;
5166}5557}
51675558
@@ -5421,16 +5812,31 @@
54215812
5422#ifdef DRIZZLED5813#ifdef DRIZZLED
5423static MYSQL_SYSVAR_INT(max_threads, pbxt_max_threads,5814static MYSQL_SYSVAR_INT(max_threads, pbxt_max_threads,
5424 PLUGIN_VAR_OPCMDARG,5815 PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
5425 "The maximum number of threads used by PBXT",5816 "The maximum number of threads used by PBXT",
5426 NULL, NULL, 500, 20, 20000, 1);5817 NULL, NULL, 500, 20, 20000, 1);
5427#else5818#else
5428static MYSQL_SYSVAR_INT(max_threads, pbxt_max_threads,5819static MYSQL_SYSVAR_INT(max_threads, pbxt_max_threads,
5429 PLUGIN_VAR_OPCMDARG,5820 PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
5430 "The maximum number of threads used by PBXT, 0 = set according to MySQL max_connections.",5821 "The maximum number of threads used by PBXT, 0 = set according to MySQL max_connections.",
5431 NULL, NULL, 0, 0, 20000, 1);5822 NULL, NULL, 0, 0, 20000, 1);
5432#endif5823#endif
54335824
5825#ifndef DEBUG
5826static MYSQL_SYSVAR_BOOL(support_xa, pbxt_support_xa,
5827 PLUGIN_VAR_OPCMDARG,
5828 "Enable PBXT support for the XA two-phase commit, default is enabled",
5829 NULL, NULL, TRUE);
5830#else
5831static MYSQL_SYSVAR_BOOL(support_xa, pbxt_support_xa,
5832 PLUGIN_VAR_OPCMDARG,
5833 "Enable PBXT support for the XA two-phase commit, default is disabled (due to assertion failure in MySQL)",
5834 /* The problem is, in MySQL an assertion fails in debug mode:
5835 * Assertion failed: (total_ha_2pc == (ulong) opt_bin_log+1), function ha_recover, file handler.cc, line 1557.
5836 */
5837 NULL, NULL, FALSE);
5838#endif
5839
5434static struct st_mysql_sys_var* pbxt_system_variables[] = {5840static struct st_mysql_sys_var* pbxt_system_variables[] = {
5435 MYSQL_SYSVAR(index_cache_size),5841 MYSQL_SYSVAR(index_cache_size),
5436 MYSQL_SYSVAR(record_cache_size),5842 MYSQL_SYSVAR(record_cache_size),
@@ -5448,6 +5854,7 @@
5448 MYSQL_SYSVAR(offline_log_function),5854 MYSQL_SYSVAR(offline_log_function),
5449 MYSQL_SYSVAR(sweeper_priority),5855 MYSQL_SYSVAR(sweeper_priority),
5450 MYSQL_SYSVAR(max_threads),5856 MYSQL_SYSVAR(max_threads),
5857 MYSQL_SYSVAR(support_xa),
5451 NULL5858 NULL
5452};5859};
5453#endif5860#endif
@@ -5494,8 +5901,8 @@
5494 "Paul McCullagh, PrimeBase Technologies GmbH",5901 "Paul McCullagh, PrimeBase Technologies GmbH",
5495 "PBXT internal system statitics",5902 "PBXT internal system statitics",
5496 PLUGIN_LICENSE_GPL,5903 PLUGIN_LICENSE_GPL,
5497 pbxt_init_statitics, /* plugin init */5904 pbxt_init_statistics, /* plugin init */
5498 pbxt_exit_statitics, /* plugin deinit */5905 pbxt_exit_statistics, /* plugin deinit */
5499#ifndef DRIZZLED5906#ifndef DRIZZLED
5500 0x0005,5907 0x0005,
5501#endif5908#endif
55025909
=== modified file 'storage/pbxt/src/ha_pbxt.h'
--- storage/pbxt/src/ha_pbxt.h 2009-08-17 11:12:36 +0000
+++ storage/pbxt/src/ha_pbxt.h 2009-12-10 11:57:20 +0000
@@ -27,9 +27,9 @@
2727
28#ifdef DRIZZLED28#ifdef DRIZZLED
29#include <drizzled/common.h>29#include <drizzled/common.h>
30#include <drizzled/handler.h>
31#include <drizzled/plugin/storage_engine.h>
32#include <mysys/thr_lock.h>30#include <mysys/thr_lock.h>
31#include <drizzled/cursor.h>
32
33#else33#else
34#include "mysql_priv.h"34#include "mysql_priv.h"
35#endif35#endif
@@ -53,17 +53,31 @@
5353
54#ifdef DRIZZLED54#ifdef DRIZZLED
5555
56class PBXTStorageEngine : public StorageEngine {56class PBXTStorageEngine : public drizzled::plugin::StorageEngine
57{
58
59 int delete_system_table(const char *table_path);
60 int rename_system_table(const char * from, const char * to);
61
57public:62public:
58 PBXTStorageEngine(std::string name_arg)63 PBXTStorageEngine(std::string name_arg)
59 : StorageEngine(name_arg, HTON_NO_FLAGS) {}64 : drizzled::plugin::StorageEngine(name_arg, HTON_NO_FLAGS) {}
65
66 void operator delete(void *) {}
67 void operator delete[] (void *) {}
6068
61 /* override */ int close_connection(Session *);69 /* override */ int close_connection(Session *);
62 /* override */ int commit(Session *, bool);70 /* override */ int commit(Session *, bool);
63 /* override */ int rollback(Session *, bool);71 /* override */ int rollback(Session *, bool);
64 /* override */ handler *create(TABLE_SHARE *, MEM_ROOT *);72 /* override */ Cursor *create(TABLE_SHARE *, MEM_ROOT *);
65 /* override */ void drop_database(char *);73 /* override */ void drop_database(char *);
66 /* override */ bool show_status(Session *, stat_print_fn *, enum ha_stat_type);74 /* override */ bool show_status(Session *, stat_print_fn *, enum ha_stat_type);
75 /* override */ const char **bas_ext() const;
76 /* override */ int doCreateTable(Session *session, const char *table_name,
77 Table &table_arg, HA_CREATE_INFO
78 &create_info, drizzled::message::Table &proto);
79 /* override */ int doRenameTable(Session *, const char *from, const char *to);
80 /* override */ int doDropTable(Session &session, std::string table_path);
67};81};
6882
69typedef PBXTStorageEngine handlerton;83typedef PBXTStorageEngine handlerton;
@@ -139,9 +153,9 @@
139 * don't implement this method unless you really have indexes.153 * don't implement this method unless you really have indexes.
140 */154 */
141 const char *index_type(uint inx) { (void) inx; return "BTREE"; }155 const char *index_type(uint inx) { (void) inx; return "BTREE"; }
142156#ifndef DRIZZLED
143 const char **bas_ext() const;157 const char **bas_ext() const;
144158#endif
145 MX_UINT8_T table_cache_type();159 MX_UINT8_T table_cache_type();
146160
147 /*161 /*
@@ -241,11 +255,13 @@
241 int optimize(THD* thd, HA_CHECK_OPT* check_opt);255 int optimize(THD* thd, HA_CHECK_OPT* check_opt);
242 int check(THD* thd, HA_CHECK_OPT* check_opt);256 int check(THD* thd, HA_CHECK_OPT* check_opt);
243 ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key);257 ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key);
258#ifndef DRIZZLED
259 int delete_system_table(const char *table_path);
244 int delete_table(const char *from);260 int delete_table(const char *from);
245 int delete_system_table(const char *table_path);261 int rename_system_table(const char * from, const char * to);
246 int rename_table(const char * from, const char * to);262 int rename_table(const char * from, const char * to);
247 int rename_system_table(const char * from, const char * to);
248 int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info); //required263 int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info); //required
264#endif
249 void update_create_info(HA_CREATE_INFO *create_info);265 void update_create_info(HA_CREATE_INFO *create_info);
250266
251 THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, enum thr_lock_type lock_type); //required267 THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, enum thr_lock_type lock_type); //required
@@ -277,6 +293,7 @@
277int xt_ha_pbxt_to_mysql_error(int xt_err);293int xt_ha_pbxt_to_mysql_error(int xt_err);
278int xt_ha_pbxt_thread_error_for_mysql(THD *thd, const XTThreadPtr self, int ignore_dup_key);294int xt_ha_pbxt_thread_error_for_mysql(THD *thd, const XTThreadPtr self, int ignore_dup_key);
279void xt_ha_all_threads_close_database(XTThreadPtr self, XTDatabase *db);295void xt_ha_all_threads_close_database(XTThreadPtr self, XTDatabase *db);
296void ha_set_auto_increment(XTOpenTablePtr ot, Field *nr);
280297
281/*298/*
282 * These hooks are suppossed to only be used by InnoDB:299 * These hooks are suppossed to only be used by InnoDB:
283300
=== modified file 'storage/pbxt/src/ha_xtsys.h'
--- storage/pbxt/src/ha_xtsys.h 2009-08-17 11:12:36 +0000
+++ storage/pbxt/src/ha_xtsys.h 2009-12-10 11:57:20 +0000
@@ -30,8 +30,9 @@
3030
31#ifdef DRIZZLED31#ifdef DRIZZLED
32#include <drizzled/common.h>32#include <drizzled/common.h>
33#include <drizzled/handler.h>33#include <drizzled/handler_structs.h>
34#include <drizzled/current_session.h>34#include <drizzled/current_session.h>
35#include <drizzled/cursor.h>
35#else36#else
36#include "mysql_priv.h"37#include "mysql_priv.h"
37#endif38#endif
3839
=== modified file 'storage/pbxt/src/heap_xt.cc'
--- storage/pbxt/src/heap_xt.cc 2009-08-17 11:12:36 +0000
+++ storage/pbxt/src/heap_xt.cc 2009-12-10 11:57:20 +0000
@@ -73,7 +73,7 @@
73}73}
7474
75#ifdef DEBUG_MEMORY75#ifdef DEBUG_MEMORY
76xtPublic void xt_mm_heap_reference(XTThreadPtr self, XTHeapPtr hp, u_int line, c_char *file)76xtPublic void xt_mm_heap_reference(XTThreadPtr XT_UNUSED(self), XTHeapPtr hp, u_int line, c_char *file)
77#else77#else
78xtPublic void xt_heap_reference(XTThreadPtr, XTHeapPtr hp)78xtPublic void xt_heap_reference(XTThreadPtr, XTHeapPtr hp)
79#endif79#endif
8080
=== modified file 'storage/pbxt/src/index_xt.cc'
--- storage/pbxt/src/index_xt.cc 2009-08-18 07:46:53 +0000
+++ storage/pbxt/src/index_xt.cc 2009-12-10 11:57:20 +0000
@@ -829,14 +829,25 @@
829829
830 result->sr_item.i_item_offset += result->sr_item.i_item_size + result->sr_item.i_node_ref_size;830 result->sr_item.i_item_offset += result->sr_item.i_item_size + result->sr_item.i_node_ref_size;
831 bitem = branch->tb_data + result->sr_item.i_item_offset;831 bitem = branch->tb_data + result->sr_item.i_item_offset;
832 if (ind->mi_fix_key)832 if (result->sr_item.i_item_offset < result->sr_item.i_total_size) {
833 ilen = result->sr_item.i_item_size;833 if (ind->mi_fix_key)
834 ilen = result->sr_item.i_item_size;
835 else {
836 ilen = myxt_get_key_length(ind, bitem) + XT_RECORD_REF_SIZE;
837 result->sr_item.i_item_size = ilen;
838 }
839 xt_get_res_record_ref(bitem + ilen - XT_RECORD_REF_SIZE, result); /* (Only valid if i_item_offset < i_total_size) */
840 }
834 else {841 else {
835 ilen = myxt_get_key_length(ind, bitem) + XT_RECORD_REF_SIZE;842 result->sr_item.i_item_size = 0;
836 result->sr_item.i_item_size = ilen;843 result->sr_rec_id = 0;
844 result->sr_row_id = 0;
837 }845 }
838 xt_get_res_record_ref(bitem + ilen - XT_RECORD_REF_SIZE, result); /* (Only valid if i_item_offset < i_total_size) */846 if (result->sr_item.i_node_ref_size)
839 result->sr_branch = IDX_GET_NODE_REF(tab, bitem, result->sr_item.i_node_ref_size);847 /* IDX_GET_NODE_REF() loads the branch reference to the LEFT of the item. */
848 result->sr_branch = IDX_GET_NODE_REF(tab, bitem, result->sr_item.i_node_ref_size);
849 else
850 result->sr_branch = 0;
840}851}
841852
842xtPublic void xt_prev_branch_item_fix(XTTableHPtr XT_UNUSED(tab), XTIndexPtr XT_UNUSED(ind), XTIdxBranchDPtr branch, register XTIdxResultRec *result)853xtPublic void xt_prev_branch_item_fix(XTTableHPtr XT_UNUSED(tab), XTIndexPtr XT_UNUSED(ind), XTIdxBranchDPtr branch, register XTIdxResultRec *result)
@@ -3987,7 +3998,7 @@
3987 * here.3998 * here.
3988 */3999 */
3989 if (!(tab->tab_dic.dic_tab_flags & XT_TAB_FLAGS_TEMP_TAB)) {4000 if (!(tab->tab_dic.dic_tab_flags & XT_TAB_FLAGS_TEMP_TAB)) {
3990 if (!xt_xlog_flush_log(ot->ot_thread))4001 if (!xt_xlog_flush_log(tab->tab_db, ot->ot_thread))
3991 goto failed_2;4002 goto failed_2;
3992 if (!il->il_flush(ot))4003 if (!il->il_flush(ot))
3993 goto failed_2;4004 goto failed_2;
39944005
=== modified file 'storage/pbxt/src/lock_xt.cc'
--- storage/pbxt/src/lock_xt.cc 2009-08-17 11:12:36 +0000
+++ storage/pbxt/src/lock_xt.cc 2009-12-10 11:57:20 +0000
@@ -1246,7 +1246,7 @@
1246 (void) self;1246 (void) self;
1247 spl->spl_lock = 0;1247 spl->spl_lock = 0;
1248#ifdef XT_NO_ATOMICS1248#ifdef XT_NO_ATOMICS
1249 xt_init_mutex(self, &spl->spl_mutex);1249 xt_init_mutex_with_autoname(self, &spl->spl_mutex);
1250#endif1250#endif
1251#ifdef DEBUG1251#ifdef DEBUG
1252 spl->spl_locker = 0;1252 spl->spl_locker = 0;
12531253
=== modified file 'storage/pbxt/src/locklist_xt.h'
--- storage/pbxt/src/locklist_xt.h 2009-08-17 11:12:36 +0000
+++ storage/pbxt/src/locklist_xt.h 2009-12-10 11:57:20 +0000
@@ -24,11 +24,16 @@
24#ifndef __xt_locklist_h__24#ifndef __xt_locklist_h__
25#define __xt_locklist_h__25#define __xt_locklist_h__
2626
27/*
28 * XT_THREAD_LOCK_INFO and DEBUG_LOCKING code must be updated to avoid calls to xt_get_self() as it can be called before hton->slot is
29 * assigned by MySQL which is used by xt_get_self()
30 */
31
27#ifdef DEBUG32#ifdef DEBUG
28#define XT_THREAD_LOCK_INFO33//#define XT_THREAD_LOCK_INFO
29#ifndef XT_WIN34#ifndef XT_WIN
30/* We need DEBUG_LOCKING in order to enable pthread function wrappers */35/* We need DEBUG_LOCKING in order to enable pthread function wrappers */
31#define DEBUG_LOCKING36//#define DEBUG_LOCKING
32#endif37#endif
33#endif38#endif
3439
3540
=== modified file 'storage/pbxt/src/memory_xt.cc'
--- storage/pbxt/src/memory_xt.cc 2009-09-03 06:15:03 +0000
+++ storage/pbxt/src/memory_xt.cc 2009-12-10 11:57:20 +0000
@@ -34,7 +34,7 @@
34#include "trace_xt.h"34#include "trace_xt.h"
3535
36#ifdef DEBUG36#ifdef DEBUG
37//#define RECORD_MM37#define RECORD_MM
38#endif38#endif
3939
40#ifdef DEBUG40#ifdef DEBUG
@@ -367,9 +367,8 @@
367 return(-1);367 return(-1);
368}368}
369369
370static long mm_add_pointer(void *ptr, u_int id)370static long mm_add_pointer(void *ptr, u_int XT_UNUSED(id))
371{371{
372#pragma unused(id)
373 register int i, n, guess;372 register int i, n, guess;
374373
375 if (mm_nr_in_use == mm_total_allocated) {374 if (mm_nr_in_use == mm_total_allocated) {
376375
=== modified file 'storage/pbxt/src/myxt_xt.cc'
--- storage/pbxt/src/myxt_xt.cc 2009-09-03 06:15:03 +0000
+++ storage/pbxt/src/myxt_xt.cc 2009-12-10 11:57:20 +0000
@@ -36,7 +36,7 @@
36#include <drizzled/current_session.h>36#include <drizzled/current_session.h>
37#include <drizzled/sql_lex.h>37#include <drizzled/sql_lex.h>
38#include <drizzled/session.h>38#include <drizzled/session.h>
39extern "C" struct charset_info_st *session_charset(Session *session);39//extern "C" struct charset_info_st *session_charset(Session *session);
40extern pthread_key_t THR_Session;40extern pthread_key_t THR_Session;
41#else41#else
42#include "mysql_priv.h"42#include "mysql_priv.h"
@@ -171,7 +171,9 @@
171171
172 for (u_int i=0; i<ind->mi_seg_count && (int) k_length > 0; i++, old += keyseg->length, keyseg++)172 for (u_int i=0; i<ind->mi_seg_count && (int) k_length > 0; i++, old += keyseg->length, keyseg++)
173 {173 {
174#ifndef DRIZZLED
174 enum ha_base_keytype type = (enum ha_base_keytype) keyseg->type;175 enum ha_base_keytype type = (enum ha_base_keytype) keyseg->type;
176#endif
175 u_int length = keyseg->length < k_length ? keyseg->length : k_length;177 u_int length = keyseg->length < k_length ? keyseg->length : k_length;
176 u_int char_length;178 u_int char_length;
177 xtWord1 *pos;179 xtWord1 *pos;
@@ -192,14 +194,18 @@
192 pos = old;194 pos = old;
193 if (keyseg->flag & HA_SPACE_PACK) {195 if (keyseg->flag & HA_SPACE_PACK) {
194 uchar *end = pos + length;196 uchar *end = pos + length;
197#ifndef DRIZZLED
195 if (type != HA_KEYTYPE_NUM) {198 if (type != HA_KEYTYPE_NUM) {
199#endif
196 while (end > pos && end[-1] == ' ')200 while (end > pos && end[-1] == ' ')
197 end--;201 end--;
202#ifndef DRIZZLED
198 }203 }
199 else {204 else {
200 while (pos < end && pos[0] == ' ')205 while (pos < end && pos[0] == ' ')
201 pos++;206 pos++;
202 }207 }
208#endif
203 k_length -= length;209 k_length -= length;
204 length = (u_int) (end-pos);210 length = (u_int) (end-pos);
205 FIX_LENGTH(cs, pos, length, char_length);211 FIX_LENGTH(cs, pos, length, char_length);
@@ -276,6 +282,7 @@
276 char_length= ((cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen : length);282 char_length= ((cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen : length);
277283
278 pos = record + keyseg->start;284 pos = record + keyseg->start;
285#ifndef DRIZZLED
279 if (type == HA_KEYTYPE_BIT)286 if (type == HA_KEYTYPE_BIT)
280 {287 {
281 if (keyseg->bit_length)288 if (keyseg->bit_length)
@@ -289,17 +296,22 @@
289 key+= length;296 key+= length;
290 continue;297 continue;
291 }298 }
299#endif
292 if (keyseg->flag & HA_SPACE_PACK)300 if (keyseg->flag & HA_SPACE_PACK)
293 {301 {
294 end = pos + length;302 end = pos + length;
303#ifndef DRIZZLED
295 if (type != HA_KEYTYPE_NUM) {304 if (type != HA_KEYTYPE_NUM) {
305#endif
296 while (end > pos && end[-1] == ' ')306 while (end > pos && end[-1] == ' ')
297 end--;307 end--;
308#ifndef DRIZZLED
298 }309 }
299 else {310 else {
300 while (pos < end && pos[0] == ' ')311 while (pos < end && pos[0] == ' ')
301 pos++;312 pos++;
302 }313 }
314#endif
303 length = (u_int) (end-pos);315 length = (u_int) (end-pos);
304 FIX_LENGTH(cs, pos, length, char_length);316 FIX_LENGTH(cs, pos, length, char_length);
305 store_key_length_inc(key,char_length);317 store_key_length_inc(key,char_length);
@@ -333,6 +345,7 @@
333 if (keyseg->flag & HA_SWAP_KEY)345 if (keyseg->flag & HA_SWAP_KEY)
334 { /* Numerical column */346 { /* Numerical column */
335#ifdef HAVE_ISNAN347#ifdef HAVE_ISNAN
348#ifndef DRIZZLED
336 if (type == HA_KEYTYPE_FLOAT)349 if (type == HA_KEYTYPE_FLOAT)
337 {350 {
338 float nr;351 float nr;
@@ -345,7 +358,9 @@
345 continue;358 continue;
346 }359 }
347 }360 }
348 else if (type == HA_KEYTYPE_DOUBLE) {361 else
362#endif
363 if (type == HA_KEYTYPE_DOUBLE) {
349 double nr;364 double nr;
350365
351 float8get(nr,pos);366 float8get(nr,pos);
@@ -414,6 +429,7 @@
414 char_length= ((cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen : length);429 char_length= ((cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen : length);
415430
416 pos = record + keyseg->start;431 pos = record + keyseg->start;
432#ifndef DRIZZLED
417 if (type == HA_KEYTYPE_BIT)433 if (type == HA_KEYTYPE_BIT)
418 {434 {
419 if (keyseg->bit_length)435 if (keyseg->bit_length)
@@ -427,17 +443,22 @@
427 key+= length;443 key+= length;
428 continue;444 continue;
429 }445 }
446#endif
430 if (keyseg->flag & HA_SPACE_PACK)447 if (keyseg->flag & HA_SPACE_PACK)
431 {448 {
432 end = pos + length;449 end = pos + length;
450#ifndef DRIZZLED
433 if (type != HA_KEYTYPE_NUM) {451 if (type != HA_KEYTYPE_NUM) {
452#endif
434 while (end > pos && end[-1] == ' ')453 while (end > pos && end[-1] == ' ')
435 end--;454 end--;
455#ifndef DRIZZLED
436 }456 }
437 else {457 else {
438 while (pos < end && pos[0] == ' ')458 while (pos < end && pos[0] == ' ')
439 pos++;459 pos++;
440 }460 }
461#endif
441 length = (u_int) (end-pos);462 length = (u_int) (end-pos);
442 FIX_LENGTH(cs, pos, length, char_length);463 FIX_LENGTH(cs, pos, length, char_length);
443 store_key_length_inc(key,char_length);464 store_key_length_inc(key,char_length);
@@ -471,6 +492,7 @@
471 if (keyseg->flag & HA_SWAP_KEY)492 if (keyseg->flag & HA_SWAP_KEY)
472 { /* Numerical column */493 { /* Numerical column */
473#ifdef HAVE_ISNAN494#ifdef HAVE_ISNAN
495#ifndef DRIZZLED
474 if (type == HA_KEYTYPE_FLOAT)496 if (type == HA_KEYTYPE_FLOAT)
475 {497 {
476 float nr;498 float nr;
@@ -483,7 +505,9 @@
483 continue;505 continue;
484 }506 }
485 }507 }
486 else if (type == HA_KEYTYPE_DOUBLE) {508 else
509#endif
510 if (type == HA_KEYTYPE_DOUBLE) {
487 double nr;511 double nr;
488512
489 float8get(nr,pos);513 float8get(nr,pos);
@@ -622,7 +646,6 @@
622 case MYSQL_TYPE_SET:646 case MYSQL_TYPE_SET:
623 case MYSQL_TYPE_GEOMETRY:647 case MYSQL_TYPE_GEOMETRY:
624#else648#else
625 case DRIZZLE_TYPE_TINY:
626 case DRIZZLE_TYPE_LONG:649 case DRIZZLE_TYPE_LONG:
627 case DRIZZLE_TYPE_DOUBLE:650 case DRIZZLE_TYPE_DOUBLE:
628 case DRIZZLE_TYPE_NULL:651 case DRIZZLE_TYPE_NULL:
@@ -740,7 +763,6 @@
740 case MYSQL_TYPE_SET:763 case MYSQL_TYPE_SET:
741 case MYSQL_TYPE_GEOMETRY:764 case MYSQL_TYPE_GEOMETRY:
742#else765#else
743 case DRIZZLE_TYPE_TINY:
744 case DRIZZLE_TYPE_LONG:766 case DRIZZLE_TYPE_LONG:
745 case DRIZZLE_TYPE_DOUBLE:767 case DRIZZLE_TYPE_DOUBLE:
746 case DRIZZLE_TYPE_NULL:768 case DRIZZLE_TYPE_NULL:
@@ -825,6 +847,7 @@
825 }847 }
826 record[keyseg->null_pos] &= ~keyseg->null_bit;848 record[keyseg->null_pos] &= ~keyseg->null_bit;
827 }849 }
850#ifndef DRIZZLED
828 if (keyseg->type == HA_KEYTYPE_BIT)851 if (keyseg->type == HA_KEYTYPE_BIT)
829 {852 {
830 uint length = keyseg->length;853 uint length = keyseg->length;
@@ -845,6 +868,7 @@
845 key+= length;868 key+= length;
846 continue;869 continue;
847 }870 }
871#endif
848 if (keyseg->flag & HA_SPACE_PACK)872 if (keyseg->flag & HA_SPACE_PACK)
849 {873 {
850 uint length;874 uint length;
@@ -854,16 +878,20 @@
854 goto err;878 goto err;
855#endif879#endif
856 pos = record+keyseg->start;880 pos = record+keyseg->start;
881#ifndef DRIZZLED
857 if (keyseg->type != (int) HA_KEYTYPE_NUM)882 if (keyseg->type != (int) HA_KEYTYPE_NUM)
858 {883 {
884#endif
859 memcpy(pos,key,(size_t) length);885 memcpy(pos,key,(size_t) length);
860 bfill(pos+length,keyseg->length-length,' ');886 bfill(pos+length,keyseg->length-length,' ');
887#ifndef DRIZZLED
861 }888 }
862 else889 else
863 {890 {
864 bfill(pos,keyseg->length-length,' ');891 bfill(pos,keyseg->length-length,' ');
865 memcpy(pos+keyseg->length-length,key,(size_t) length);892 memcpy(pos+keyseg->length-length,key,(size_t) length);
866 }893 }
894#endif
867 key+=length;895 key+=length;
868 continue;896 continue;
869 }897 }
@@ -945,7 +973,7 @@
945static int my_compare_bin(uchar *a, uint a_length, uchar *b, uint b_length,973static int my_compare_bin(uchar *a, uint a_length, uchar *b, uint b_length,
946 my_bool part_key, my_bool skip_end_space)974 my_bool part_key, my_bool skip_end_space)
947{975{
948 uint length= min(a_length,b_length);976 uint length= a_length < b_length ? a_length : b_length;
949 uchar *end= a+ length;977 uchar *end= a+ length;
950 int flag;978 int flag;
951979
@@ -1023,6 +1051,7 @@
1023 get_key_pack_length(seg_len, pack_len, key_data);1051 get_key_pack_length(seg_len, pack_len, key_data);
1024 key_data += seg_len;1052 key_data += seg_len;
1025 break;1053 break;
1054#ifndef DRIZZLED
1026 case HA_KEYTYPE_NUM: {1055 case HA_KEYTYPE_NUM: {
1027 /* Numeric key */1056 /* Numeric key */
1028 if (keyseg->flag & HA_SPACE_PACK)1057 if (keyseg->flag & HA_SPACE_PACK)
@@ -1035,15 +1064,16 @@
1035 case HA_KEYTYPE_INT8:1064 case HA_KEYTYPE_INT8:
1036 case HA_KEYTYPE_SHORT_INT:1065 case HA_KEYTYPE_SHORT_INT:
1037 case HA_KEYTYPE_USHORT_INT:1066 case HA_KEYTYPE_USHORT_INT:
1067 case HA_KEYTYPE_INT24:
1068 case HA_KEYTYPE_FLOAT:
1069 case HA_KEYTYPE_BIT:
1070#endif
1038 case HA_KEYTYPE_LONG_INT:1071 case HA_KEYTYPE_LONG_INT:
1039 case HA_KEYTYPE_ULONG_INT:1072 case HA_KEYTYPE_ULONG_INT:
1040 case HA_KEYTYPE_INT24:
1041 case HA_KEYTYPE_UINT24:1073 case HA_KEYTYPE_UINT24:
1042 case HA_KEYTYPE_FLOAT:
1043 case HA_KEYTYPE_DOUBLE:1074 case HA_KEYTYPE_DOUBLE:
1044 case HA_KEYTYPE_LONGLONG:1075 case HA_KEYTYPE_LONGLONG:
1045 case HA_KEYTYPE_ULONGLONG:1076 case HA_KEYTYPE_ULONGLONG:
1046 case HA_KEYTYPE_BIT:
1047 key_data += keyseg->length;1077 key_data += keyseg->length;
1048 break;1078 break;
1049 case HA_KEYTYPE_END:1079 case HA_KEYTYPE_END:
@@ -1190,6 +1220,7 @@
1190 b += b_length;1220 b += b_length;
1191 break;1221 break;
1192 }1222 }
1223#ifndef DRIZZLED
1193 case HA_KEYTYPE_INT8:1224 case HA_KEYTYPE_INT8:
1194 {1225 {
1195 int i_1 = (int) *((signed char *) a);1226 int i_1 = (int) *((signed char *) a);
@@ -1218,6 +1249,7 @@
1218 b += keyseg->length;1249 b += keyseg->length;
1219 break;1250 break;
1220 }1251 }
1252#endif
1221 case HA_KEYTYPE_LONG_INT: {1253 case HA_KEYTYPE_LONG_INT: {
1222 int32 l_1 = sint4korr(a);1254 int32 l_1 = sint4korr(a);
1223 int32 l_2 = sint4korr(b);1255 int32 l_2 = sint4korr(b);
@@ -1236,6 +1268,7 @@
1236 b += keyseg->length;1268 b += keyseg->length;
1237 break;1269 break;
1238 }1270 }
1271#ifndef DRIZZLED
1239 case HA_KEYTYPE_INT24: {1272 case HA_KEYTYPE_INT24: {
1240 int32 l_1 = sint3korr(a);1273 int32 l_1 = sint3korr(a);
1241 int32 l_2 = sint3korr(b);1274 int32 l_2 = sint3korr(b);
@@ -1245,6 +1278,7 @@
1245 b += keyseg->length;1278 b += keyseg->length;
1246 break;1279 break;
1247 }1280 }
1281#endif
1248 case HA_KEYTYPE_UINT24: {1282 case HA_KEYTYPE_UINT24: {
1249 int32 l_1 = uint3korr(a);1283 int32 l_1 = uint3korr(a);
1250 int32 l_2 = uint3korr(b);1284 int32 l_2 = uint3korr(b);
@@ -1254,6 +1288,7 @@
1254 b += keyseg->length;1288 b += keyseg->length;
1255 break;1289 break;
1256 }1290 }
1291#ifndef DRIZZLED
1257 case HA_KEYTYPE_FLOAT: {1292 case HA_KEYTYPE_FLOAT: {
1258 float f_1, f_2;1293 float f_1, f_2;
12591294
@@ -1270,6 +1305,7 @@
1270 b += keyseg->length;1305 b += keyseg->length;
1271 break;1306 break;
1272 }1307 }
1308#endif
1273 case HA_KEYTYPE_DOUBLE: {1309 case HA_KEYTYPE_DOUBLE: {
1274 double d_1, d_2;1310 double d_1, d_2;
12751311
@@ -1286,6 +1322,7 @@
1286 b += keyseg->length;1322 b += keyseg->length;
1287 break;1323 break;
1288 }1324 }
1325#ifndef DRIZZLED
1289 case HA_KEYTYPE_NUM: {1326 case HA_KEYTYPE_NUM: {
1290 /* Numeric key */1327 /* Numeric key */
1291 if (keyseg->flag & HA_SPACE_PACK) {1328 if (keyseg->flag & HA_SPACE_PACK) {
@@ -1339,6 +1376,7 @@
1339 b += b_length;1376 b += b_length;
1340 break;1377 break;
1341 }1378 }
1379#endif
1342#ifdef HAVE_LONG_LONG1380#ifdef HAVE_LONG_LONG
1343 case HA_KEYTYPE_LONGLONG: {1381 case HA_KEYTYPE_LONGLONG: {
1344 longlong ll_a = sint8korr(a);1382 longlong ll_a = sint8korr(a);
@@ -1359,9 +1397,11 @@
1359 break;1397 break;
1360 }1398 }
1361#endif1399#endif
1400#ifndef DRIZZLED
1362 case HA_KEYTYPE_BIT:1401 case HA_KEYTYPE_BIT:
1363 /* TODO: What here? */1402 /* TODO: What here? */
1364 break;1403 break;
1404#endif
1365 case HA_KEYTYPE_END: /* Ready */1405 case HA_KEYTYPE_END: /* Ready */
1366 goto end;1406 goto end;
1367 }1407 }
@@ -1410,16 +1450,19 @@
1410 key_length = has_null + a_length + pack_len;1450 key_length = has_null + a_length + pack_len;
1411 break;1451 break;
1412 }1452 }
1453#ifndef DRIZZLED
1413 case HA_KEYTYPE_INT8:1454 case HA_KEYTYPE_INT8:
1414 case HA_KEYTYPE_SHORT_INT:1455 case HA_KEYTYPE_SHORT_INT:
1415 case HA_KEYTYPE_USHORT_INT:1456 case HA_KEYTYPE_USHORT_INT:
1457 case HA_KEYTYPE_INT24:
1458 case HA_KEYTYPE_FLOAT:
1459#endif
1416 case HA_KEYTYPE_LONG_INT:1460 case HA_KEYTYPE_LONG_INT:
1417 case HA_KEYTYPE_ULONG_INT:1461 case HA_KEYTYPE_ULONG_INT:
1418 case HA_KEYTYPE_INT24:
1419 case HA_KEYTYPE_UINT24:1462 case HA_KEYTYPE_UINT24:
1420 case HA_KEYTYPE_FLOAT:
1421 case HA_KEYTYPE_DOUBLE:1463 case HA_KEYTYPE_DOUBLE:
1422 break;1464 break;
1465#ifndef DRIZZLED
1423 case HA_KEYTYPE_NUM: {1466 case HA_KEYTYPE_NUM: {
1424 /* Numeric key */1467 /* Numeric key */
1425 if (keyseg->flag & HA_SPACE_PACK) {1468 if (keyseg->flag & HA_SPACE_PACK) {
@@ -1428,14 +1471,17 @@
1428 }1471 }
1429 break;1472 break;
1430 }1473 }
1474#endif
1431#ifdef HAVE_LONG_LONG1475#ifdef HAVE_LONG_LONG
1432 case HA_KEYTYPE_LONGLONG:1476 case HA_KEYTYPE_LONGLONG:
1433 case HA_KEYTYPE_ULONGLONG:1477 case HA_KEYTYPE_ULONGLONG:
1434 break;1478 break;
1435#endif1479#endif
1480#ifndef DRIZZLED
1436 case HA_KEYTYPE_BIT:1481 case HA_KEYTYPE_BIT:
1437 /* TODO: What here? */1482 /* TODO: What here? */
1438 break;1483 break;
1484#endif
1439 case HA_KEYTYPE_END: /* Ready */1485 case HA_KEYTYPE_END: /* Ready */
1440 break;1486 break;
1441 }1487 }
@@ -1486,7 +1532,7 @@
1486 return row_size;1532 return row_size;
1487}1533}
14881534
1489static xtWord4 mx_store_row(XTOpenTablePtr ot, xtWord4 row_size, char *rec_buff)1535xtPublic xtWord4 myxt_store_row_data(XTOpenTablePtr ot, xtWord4 row_size, char *rec_buff)
1490{1536{
1491 TABLE *table = ot->ot_table->tab_dic.dic_my_table;1537 TABLE *table = ot->ot_table->tab_dic.dic_my_table;
1492 char *sdata;1538 char *sdata;
@@ -1614,8 +1660,9 @@
1614}1660}
16151661
1616/* Unload from PBXT variable length format to the MySQL row format. */1662/* Unload from PBXT variable length format to the MySQL row format. */
1617xtPublic xtBool myxt_load_row(XTOpenTablePtr ot, xtWord1 *source_buf, xtWord1 *dest_buff, u_int col_cnt)1663xtPublic xtWord4 myxt_load_row_data(XTOpenTablePtr ot, xtWord1 *source_buf, xtWord1 *dest_buff, u_int col_cnt)
1618{1664{
1665 xtWord1 *input_buf = source_buf;
1619 TABLE *table;1666 TABLE *table;
1620 xtWord4 len;1667 xtWord4 len;
1621 Field *curr_field;1668 Field *curr_field;
@@ -1624,7 +1671,7 @@
16241671
1625 if (!(table = ot->ot_table->tab_dic.dic_my_table)) {1672 if (!(table = ot->ot_table->tab_dic.dic_my_table)) {
1626 xt_register_taberr(XT_REG_CONTEXT, XT_ERR_NO_DICTIONARY, ot->ot_table->tab_name);1673 xt_register_taberr(XT_REG_CONTEXT, XT_ERR_NO_DICTIONARY, ot->ot_table->tab_name);
1627 return FAILED;1674 return 0;
1628 }1675 }
16291676
1630 /* According to the InnoDB implementation:1677 /* According to the InnoDB implementation:
@@ -1657,7 +1704,7 @@
1657 default: // Length byte1704 default: // Length byte
1658 if (*source_buf > 240) {1705 if (*source_buf > 240) {
1659 xt_register_xterr(XT_REG_CONTEXT, XT_ERR_BAD_RECORD_FORMAT);1706 xt_register_xterr(XT_REG_CONTEXT, XT_ERR_BAD_RECORD_FORMAT);
1660 return FAILED;1707 return 0;
1661 }1708 }
1662 len = *source_buf;1709 len = *source_buf;
1663 source_buf++;1710 source_buf++;
@@ -1671,7 +1718,12 @@
16711718
1672 source_buf += len;1719 source_buf += len;
1673 }1720 }
1674 return OK;1721 return (xtWord4) (source_buf - input_buf);
1722}
1723
1724xtPublic xtBool myxt_load_row(XTOpenTablePtr ot, xtWord1 *source_buf, xtWord1 *dest_buff, u_int col_cnt)
1725{
1726 return myxt_load_row_data(ot, source_buf, dest_buff, col_cnt) != 0;
1675}1727}
16761728
1677xtPublic xtBool myxt_find_column(XTOpenTablePtr ot, u_int *col_idx, const char *col_name)1729xtPublic xtBool myxt_find_column(XTOpenTablePtr ot, u_int *col_idx, const char *col_name)
@@ -1784,7 +1836,7 @@
1784 else {1836 else {
1785 xtWord4 row_size;1837 xtWord4 row_size;
17861838
1787 if (!(row_size = mx_store_row(ot, XT_REC_EXT_HEADER_SIZE, rec_buff)))1839 if (!(row_size = myxt_store_row_data(ot, XT_REC_EXT_HEADER_SIZE, rec_buff)))
1788 return FAILED;1840 return FAILED;
1789 if (row_size - XT_REC_FIX_EXT_HEADER_DIFF <= ot->ot_rec_size) { 1841 if (row_size - XT_REC_FIX_EXT_HEADER_DIFF <= ot->ot_rec_size) {
1790 rec_info->ri_fix_rec_buf = (XTTabRecFixDPtr) &ot->ot_row_wbuffer[XT_REC_FIX_EXT_HEADER_DIFF];1842 rec_info->ri_fix_rec_buf = (XTTabRecFixDPtr) &ot->ot_row_wbuffer[XT_REC_FIX_EXT_HEADER_DIFF];
@@ -1951,7 +2003,7 @@
19512003
1952#ifdef DRIZZLED2004#ifdef DRIZZLED
1953 share->init(db_name, 0, name, path);2005 share->init(db_name, 0, name, path);
1954 if ((error = open_table_def(thd, share)) ||2006 if ((error = open_table_def(*thd, share)) ||
1955 (error = open_table_from_share(thd, share, "", 0, (uint32_t) READ_ALL, 0, table, OTM_OPEN)))2007 (error = open_table_from_share(thd, share, "", 0, (uint32_t) READ_ALL, 0, table, OTM_OPEN)))
1956 {2008 {
1957 xt_free(self, table);2009 xt_free(self, table);
@@ -1995,7 +2047,7 @@
1995 return NULL;2047 return NULL;
1996 }2048 }
19972049
1998#if MYSQL_VERSION_ID >= 600032050#if MYSQL_VERSION_ID >= 50404
1999 if ((error = open_table_from_share(thd, share, "", 0, (uint) READ_ALL, 0, table, OTM_OPEN)))2051 if ((error = open_table_from_share(thd, share, "", 0, (uint) READ_ALL, 0, table, OTM_OPEN)))
2000#else2052#else
2001 if ((error = open_table_from_share(thd, share, "", 0, (uint) READ_ALL, 0, table, FALSE)))2053 if ((error = open_table_from_share(thd, share, "", 0, (uint) READ_ALL, 0, table, FALSE)))
@@ -2145,7 +2197,10 @@
2145 if (options & HA_OPTION_PACK_KEYS ||2197 if (options & HA_OPTION_PACK_KEYS ||
2146 (index->flags & (HA_PACK_KEY | HA_BINARY_PACK_KEY | HA_SPACE_PACK_USED)))2198 (index->flags & (HA_PACK_KEY | HA_BINARY_PACK_KEY | HA_SPACE_PACK_USED)))
2147 {2199 {
2148 if (key_part->length > 8 && (type == HA_KEYTYPE_TEXT || type == HA_KEYTYPE_NUM ||2200 if (key_part->length > 8 && (type == HA_KEYTYPE_TEXT ||
2201#ifndef DRIZZLED
2202 type == HA_KEYTYPE_NUM ||
2203#endif
2149 (type == HA_KEYTYPE_BINARY && !field->zero_pack())))2204 (type == HA_KEYTYPE_BINARY && !field->zero_pack())))
2150 {2205 {
2151 /* No blobs here */2206 /* No blobs here */
@@ -2213,8 +2268,12 @@
2213 else if (field->type() == MYSQL_TYPE_ENUM) {2268 else if (field->type() == MYSQL_TYPE_ENUM) {
2214 switch (seg->length) {2269 switch (seg->length) {
2215 case 2: 2270 case 2:
2271#ifdef DRIZZLED
2272 ASSERT_NS(FALSE);
2273#else
2216 seg->type = HA_KEYTYPE_USHORT_INT;2274 seg->type = HA_KEYTYPE_USHORT_INT;
2217 break;2275 break;
2276#endif
2218 case 3:2277 case 3:
2219 seg->type = HA_KEYTYPE_UINT24;2278 seg->type = HA_KEYTYPE_UINT24;
2220 break;2279 break;
@@ -2675,7 +2734,11 @@
2675 if (!(my_tab = my_open_table(self, db, tab_path)))2734 if (!(my_tab = my_open_table(self, db, tab_path)))
2676 return FAILED;2735 return FAILED;
2677 dic->dic_my_table = my_tab;2736 dic->dic_my_table = my_tab;
2737#ifdef DRIZZLED
2738 dic->dic_def_ave_row_size = (xtWord8) my_tab->s->getAvgRowLength();
2739#else
2678 dic->dic_def_ave_row_size = (xtWord8) my_tab->s->avg_row_length;2740 dic->dic_def_ave_row_size = (xtWord8) my_tab->s->avg_row_length;
2741#endif
2679 myxt_setup_dictionary(self, dic);2742 myxt_setup_dictionary(self, dic);
2680 dic->dic_keys = (XTIndexPtr *) xt_calloc(self, sizeof(XTIndexPtr) * TS(my_tab)->keys);2743 dic->dic_keys = (XTIndexPtr *) xt_calloc(self, sizeof(XTIndexPtr) * TS(my_tab)->keys);
2681 for (uint i=0; i<TS(my_tab)->keys; i++)2744 for (uint i=0; i<TS(my_tab)->keys; i++)
@@ -2805,8 +2868,10 @@
28052868
2806static char *my_type_to_string(XTThreadPtr self, Field *field, TABLE *XT_UNUSED(my_tab))2869static char *my_type_to_string(XTThreadPtr self, Field *field, TABLE *XT_UNUSED(my_tab))
2807{2870{
2808 char buffer[MAX_FIELD_WIDTH + 400], *ptr;2871 char buffer[MAX_FIELD_WIDTH + 400];
2872 const char *ptr;
2809 String type((char *) buffer, sizeof(buffer), system_charset_info);2873 String type((char *) buffer, sizeof(buffer), system_charset_info);
2874 xtWord4 len;
28102875
2811 /* GOTCHA:2876 /* GOTCHA:
2812 * - Above sets the string length to the same as the buffer,2877 * - Above sets the string length to the same as the buffer,
@@ -2817,10 +2882,17 @@
2817 */2882 */
2818 type.length(0);2883 type.length(0);
2819 field->sql_type(type);2884 field->sql_type(type);
2820 ptr = type.c_ptr();2885 ptr = type.ptr();
2886 len = type.length();
2887
2888 if (len >= sizeof(buffer))
2889 len = sizeof(buffer)-1;
2890
2821 if (ptr != buffer)2891 if (ptr != buffer)
2822 xt_strcpy(sizeof(buffer), buffer, ptr); 2892 xt_strcpy(sizeof(buffer), buffer, ptr);
28232893
2894 buffer[len] = 0;
2895
2824 if (field->has_charset()) {2896 if (field->has_charset()) {
2825 /* Always include the charset so that we can compare types2897 /* Always include the charset so that we can compare types
2826 * for FK/PK releations.2898 * for FK/PK releations.
@@ -2877,6 +2949,10 @@
28772949
2878xtPublic void myxt_static_convert_identifier(XTThreadPtr XT_UNUSED(self), MX_CHARSET_INFO *cs, char *from, char *to, size_t to_len)2950xtPublic void myxt_static_convert_identifier(XTThreadPtr XT_UNUSED(self), MX_CHARSET_INFO *cs, char *from, char *to, size_t to_len)
2879{2951{
2952#ifdef DRIZZLED
2953 ((void *)cs);
2954 xt_strcpy(to_len, to, from);
2955#else
2880 uint errors;2956 uint errors;
28812957
2882 /*