~drizzle-trunk/drizzle/development

641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
1
/*****************************************************************************
2
3
Copyright (c) 2000, 2009, MySQL AB & Innobase Oy. All Rights Reserved.
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4
Copyright (c) 2008, 2009 Google Inc.
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
5
6
Portions of this file contain modifications contributed and copyrighted by
7
Google, Inc. Those modifications are gratefully acknowledged and are described
8
briefly in the InnoDB documentation. The contributions by Google are
9
incorporated with their permission, and subject to the conditions contained in
10
the file COPYING.Google.
11
12
This program is free software; you can redistribute it and/or modify it under
13
the terms of the GNU General Public License as published by the Free Software
14
Foundation; version 2 of the License.
15
16
This program is distributed in the hope that it will be useful, but WITHOUT
17
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
19
20
You should have received a copy of the GNU General Public License along with
21
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
22
Place, Suite 330, Boston, MA 02111-1307 USA
23
24
*****************************************************************************/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
25
/***********************************************************************
26
27
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
28
Copyright (c) 2009, Percona Inc.
29
30
Portions of this file contain modifications contributed and copyrighted
31
by Percona Inc.. Those modifications are
32
gratefully acknowledged and are described briefly in the InnoDB
33
documentation. The contributions by Percona Inc. are incorporated with
34
their permission, and subject to the conditions contained in the file
35
COPYING.Percona.
36
37
This program is free software; you can redistribute it and/or modify it
38
under the terms of the GNU General Public License as published by the
39
Free Software Foundation; version 2 of the License.
40
41
This program is distributed in the hope that it will be useful, but
42
WITHOUT ANY WARRANTY; without even the implied warranty of
43
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
44
Public License for more details.
45
46
You should have received a copy of the GNU General Public License along
47
with this program; if not, write to the Free Software Foundation, Inc.,
48
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
49
50
***********************************************************************/
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
51
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
52
/* TODO list for the InnoDB Cursor in 5.0:
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
53
  - Remove the flag trx->active_trans and look at trx->conc_state
54
  - fix savepoint functions to use savepoint storage area
55
  - Find out what kind of problems the OS X case-insensitivity causes to
56
    table and database names; should we 'normalize' the names like we do
57
    in Windows?
58
*/
59
1114.1.3 by Monty Taylor
A few cleanups for sending back upstream.
60
#include "drizzled/server_includes.h"
61
#include "drizzled/error.h"
62
#include "drizzled/errmsg_print.h"
63
#include "mystrings/m_ctype.h"
64
#include "mysys/my_sys.h"
65
#include "mysys/hash.h"
66
#include "mysys/mysys_err.h"
67
#include "drizzled/plugin.h"
68
#include "drizzled/show.h"
69
#include "drizzled/data_home.h"
70
#include "drizzled/error.h"
71
#include "drizzled/field.h"
72
#include "drizzled/session.h"
73
#include "drizzled/current_session.h"
74
#include "drizzled/table.h"
75
#include "drizzled/field/blob.h"
76
#include "drizzled/field/varstring.h"
77
#include "drizzled/field/timestamp.h"
78
#include "drizzled/plugin/storage_engine.h"
1130.3.8 by Monty Taylor
Merged latest plugin-slot-reorg changes.
79
#include "drizzled/plugin/info_schema_table.h"
1130.3.1 by Monty Taylor
Moved multi_malloc into drizzled since it's not going away any time soon. Also,
80
#include "drizzled/memory/multi_malloc.h"
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
81
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
82
/** @file ha_innodb.cc */
83
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
84
/* Include necessary InnoDB headers */
85
extern "C" {
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
86
#include "univ.i"
87
#include "btr0sea.h"
88
#include "os0file.h"
89
#include "os0thread.h"
90
#include "srv0start.h"
91
#include "srv0srv.h"
92
#include "trx0roll.h"
93
#include "trx0trx.h"
94
#include "trx0sys.h"
95
#include "mtr0mtr.h"
96
#include "row0ins.h"
97
#include "row0mysql.h"
98
#include "row0sel.h"
99
#include "row0upd.h"
100
#include "log0log.h"
101
#include "lock0lock.h"
102
#include "dict0crea.h"
103
#include "btr0cur.h"
104
#include "btr0btr.h"
105
#include "fsp0fsp.h"
106
#include "sync0sync.h"
107
#include "fil0fil.h"
108
#include "trx0xa.h"
109
#include "row0merge.h"
110
#include "thr0loc.h"
111
#include "dict0boot.h"
112
#include "ha_prototypes.h"
113
#include "ut0mem.h"
933.1.1 by Monty Taylor
Merged in InnoDB Plugin 1.0.3
114
#include "ibuf0ibuf.h"
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
115
}
116
117
#include "ha_innodb.h"
118
#include "i_s.h"
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
119
#include "handler0vars.h"
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
120
960.2.41 by Monty Taylor
Made StorageEngine name private. Added constructor param and accessor method.
121
#include <string>
122
123
using namespace std;
124
125
641.1.4 by Monty Taylor
Merged in InnoDB changes.
126
#ifndef DRIZZLE_SERVER
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
127
/* This is needed because of Bug #3596.  Let us hope that pthread_mutex_t
128
is defined the same in both builds: the MySQL server and the InnoDB plugin. */
129
extern pthread_mutex_t LOCK_thread_count;
130
641.1.4 by Monty Taylor
Merged in InnoDB changes.
131
#endif /* DRIZZLE_SERVER */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
132
133
/** to protect innobase_open_files */
134
static pthread_mutex_t innobase_share_mutex;
135
/** to force correct commit order in binlog */
136
static pthread_mutex_t prepare_commit_mutex;
137
static ulong commit_threads = 0;
138
static pthread_mutex_t commit_threads_m;
139
static pthread_cond_t commit_cond;
140
static pthread_mutex_t commit_cond_m;
141
static bool innodb_inited = 0;
142
143
#define INSIDE_HA_INNOBASE_CC
144
641.1.5 by Monty Taylor
Merged in innodb plugin 1.0.2
145
/* In the Windows plugin, the return value of current_session is
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
146
undefined.  Map it to NULL. */
147
#if defined MYSQL_DYNAMIC_PLUGIN && defined __WIN__
641.1.5 by Monty Taylor
Merged in innodb plugin 1.0.2
148
# undef current_session
149
# define current_session NULL
150
# define EQ_CURRENT_SESSION(session) TRUE
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
151
#else /* MYSQL_DYNAMIC_PLUGIN && __WIN__ */
641.1.5 by Monty Taylor
Merged in innodb plugin 1.0.2
152
# define EQ_CURRENT_SESSION(session) ((session) == current_session)
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
153
#endif /* MYSQL_DYNAMIC_PLUGIN && __WIN__ */
641.1.4 by Monty Taylor
Merged in InnoDB changes.
154
1114.1.5 by Monty Taylor
Merged up with trunk.
155
static drizzled::plugin::StorageEngine* innodb_engine_ptr= NULL;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
156
157
static const long AUTOINC_OLD_STYLE_LOCKING = 0;
158
static const long AUTOINC_NEW_STYLE_LOCKING = 1;
159
static const long AUTOINC_NO_LOCKING = 2;
160
161
static long innobase_mirrored_log_groups, innobase_log_files_in_group,
162
	innobase_log_buffer_size,
163
	innobase_additional_mem_pool_size, innobase_file_io_threads,
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
164
	innobase_force_recovery, innobase_open_files,
165
	innobase_autoinc_lock_mode;
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
166
static ulong innobase_commit_concurrency = 0;
167
static ulong innobase_read_io_threads;
168
static ulong innobase_write_io_threads;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
169
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
170
/**
171
 * @TODO: Turn this into size_t as soon as we have a Variable<size_t>
172
 */
641.1.4 by Monty Taylor
Merged in InnoDB changes.
173
static int64_t innobase_buffer_pool_size, innobase_log_file_size;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
174
175
/* The default values for the following char* start-up parameters
176
are determined in innobase_init below: */
177
178
static char*	innobase_data_home_dir			= NULL;
179
static char*	innobase_data_file_path			= NULL;
180
static char*	innobase_log_group_home_dir		= NULL;
181
static char*	innobase_file_format_name		= NULL;
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
182
static char*	innobase_change_buffering		= NULL;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
183
184
/* Note: This variable can be set to on/off and any of the supported
185
file formats in the configuration file, but can only be set to any
186
of the supported file formats during runtime. */
187
static char*	innobase_file_format_check		= NULL;
188
189
/* The following has a misleading name: starting from 4.0.5, this also
190
affects Windows: */
191
static char*	innobase_unix_file_flush_method		= NULL;
192
193
/* Below we have boolean-valued start-up parameters, and their default
194
values */
195
196
static ulong	innobase_fast_shutdown			= 1;
197
#ifdef UNIV_LOG_ARCHIVE
198
static my_bool	innobase_log_archive			= FALSE;
199
static char*	innobase_log_arch_dir			= NULL;
200
#endif /* UNIV_LOG_ARCHIVE */
201
static my_bool	innobase_use_doublewrite		= TRUE;
202
static my_bool	innobase_use_checksums			= TRUE;
884 by Brian Aker
Fix for bad default value for Drizzle
203
static my_bool	innobase_locks_unsafe_for_binlog	= TRUE;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
204
static my_bool	innobase_rollback_on_timeout		= FALSE;
205
static my_bool	innobase_create_status_file		= FALSE;
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
206
static my_bool	innobase_stats_on_metadata		= TRUE;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
207
208
static char*	internal_innobase_data_file_path	= NULL;
209
210
static char*	innodb_version_str = (char*) INNODB_VERSION_STR;
211
212
/* The following counter is used to convey information to InnoDB
213
about server activity: in selects it is not sensible to call
214
srv_active_wake_master_thread after each fetch or search, we only do
215
it every INNOBASE_WAKE_INTERVAL'th step. */
216
217
#define INNOBASE_WAKE_INTERVAL	32
218
static ulong	innobase_active_counter	= 0;
219
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
220
static hash_table_t*	innobase_open_tables;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
221
222
#ifdef __NETWARE__	/* some special cleanup for NetWare */
223
bool nw_panic = FALSE;
224
#endif
225
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
226
/** Allowed values of innodb_change_buffering */
227
static const char* innobase_change_buffering_values[IBUF_USE_COUNT] = {
228
	"none",		/* IBUF_USE_NONE */
229
	"inserts"	/* IBUF_USE_INSERT */
230
};
231
1039.3.1 by Stewart Smith
move bas_ext to StorageEngine instead of handler
232
/********************************************************************
233
Gives the file extension of an InnoDB single-table tablespace. */
234
static const char* ha_innobase_exts[] = {
235
  ".ibd",
236
  NULL
237
};
238
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
239
static INNOBASE_SHARE *get_share(const char *table_name);
240
static void free_share(INNOBASE_SHARE *share);
960.2.32 by Monty Taylor
Converted Innodb handlerton.
241
1130.1.4 by Monty Taylor
Moved StorageEngine into plugin namespace.
242
class InnobaseEngine : public drizzled::plugin::StorageEngine
960.2.32 by Monty Taylor
Converted Innodb handlerton.
243
{
960.2.34 by Monty Taylor
Fixed some innodb oopses.
244
public:
964.1.6 by Monty Taylor
Moved savepoint stuff to protected virtual methods, moved the offset to private, and moved the logic about adding the offset to the passed-in pointer and adding the offset to the global offset inside of the class.
245
  InnobaseEngine(string name_arg)
1130.1.4 by Monty Taylor
Moved StorageEngine into plugin namespace.
246
   : drizzled::plugin::StorageEngine(name_arg,
1183.1.17 by Brian Aker
Added Innodb specific vector (well... for any engine)
247
                                     HTON_HAS_DOES_TRANSACTIONS, sizeof(trx_named_savept_t))
971.1.25 by Monty Taylor
Moved StorageEngine onto drizzled::Registry.
248
  {
1183.1.27 by Brian Aker
Fix issue where there are too many files in data directory. We now only
249
    table_definition_ext= drizzled::plugin::DEFAULT_DEFINITION_FILE_EXT;
971.1.25 by Monty Taylor
Moved StorageEngine onto drizzled::Registry.
250
    addAlias("INNOBASE");
251
  }
960.2.34 by Monty Taylor
Fixed some innodb oopses.
252
1220.2.1 by Brian Aker
Move cursor flags up to storage engine flags. These need to be merged.
253
  uint64_t table_flags() const
254
  {
255
    return (HA_NULL_IN_KEY |
256
            HA_CAN_INDEX_BLOBS |
257
            HA_PRIMARY_KEY_REQUIRED_FOR_POSITION |
258
            HA_PRIMARY_KEY_IN_READ_INDEX |
259
            HA_PARTIAL_COLUMN_READ |
260
            HA_TABLE_SCAN_ON_INDEX | 
261
            HA_MRR_CANT_SORT);
262
  }
263
960.2.34 by Monty Taylor
Fixed some innodb oopses.
264
  virtual
265
  int
266
  close_connection(
267
/*======================*/
268
			/* out: 0 or error number */
269
	Session*	session);	/* in: handle to the MySQL thread of the user
270
			whose resources should be free'd */
271
964.1.6 by Monty Taylor
Moved savepoint stuff to protected virtual methods, moved the offset to private, and moved the logic about adding the offset to the passed-in pointer and adding the offset to the global offset inside of the class.
272
  virtual int savepoint_set_hook(Session* session,
273
                                 void *savepoint);
274
  virtual int savepoint_rollback_hook(Session* session, 
275
                                      void *savepoint);
276
  virtual int savepoint_release_hook(Session* session, 
277
                                     void *savepoint);
960.2.38 by Monty Taylor
Removed extraneous send myself to myself argument.
278
  virtual int commit(Session* session, bool all);
279
  virtual int rollback(Session* session, bool all);
960.2.32 by Monty Taylor
Converted Innodb handlerton.
280
281
  /***********************************************************************
282
  This function is used to prepare X/Open XA distributed transaction   */
283
  virtual
284
  int
960.2.34 by Monty Taylor
Fixed some innodb oopses.
285
  prepare(
960.2.32 by Monty Taylor
Converted Innodb handlerton.
286
  /*================*/
287
  			/* out: 0 or error number */
288
  	Session*	session,	/* in: handle to the MySQL thread of the user
289
  			whose XA transaction should be prepared */
290
  	bool	all);	/* in: TRUE - commit transaction
291
  			FALSE - the current SQL statement ended */
292
  /***********************************************************************
293
  This function is used to recover X/Open XA distributed transactions   */
294
  virtual
295
  int
960.2.34 by Monty Taylor
Fixed some innodb oopses.
296
  recover(
960.2.32 by Monty Taylor
Converted Innodb handlerton.
297
  /*================*/
298
  				/* out: number of prepared transactions
299
  				stored in xid_list */
300
  	XID*	xid_list,	/* in/out: prepared transactions */
301
  	uint	len);		/* in: number of slots in xid_list */
302
  /***********************************************************************
303
  This function is used to commit one X/Open XA distributed transaction
304
  which is in the prepared state */
305
  virtual
306
  int
307
  commit_by_xid(
308
  /*===================*/
309
  			/* out: 0 or error number */
310
  	XID*	xid);	/* in: X/Open XA transaction identification */
311
  /***********************************************************************
312
  This function is used to rollback one X/Open XA distributed transaction
313
  which is in the prepared state */
314
  virtual
315
  int
316
  rollback_by_xid(
317
  /*=====================*/
318
  			/* out: 0 or error number */
319
  	XID	*xid);	/* in: X/Open XA transaction identification */
960.2.34 by Monty Taylor
Fixed some innodb oopses.
320
1208.3.2 by brian
Update for Cursor renaming.
321
  virtual Cursor *create(TableShare &table,
960.2.34 by Monty Taylor
Fixed some innodb oopses.
322
                          MEM_ROOT *mem_root)
323
  {
1208.3.2 by brian
Update for Cursor renaming.
324
    return new (mem_root) ha_innobase(*this, table);
960.2.34 by Monty Taylor
Fixed some innodb oopses.
325
  }
326
960.2.32 by Monty Taylor
Converted Innodb handlerton.
327
  /*********************************************************************
328
  Removes all tables in the named database inside InnoDB. */
329
  virtual
330
  void
331
  drop_database(
332
  /*===================*/
333
  			/* out: error number */
334
  	char*	path);	/* in: database path; inside InnoDB the name
335
  			of the last directory in the path is used as
336
  			the database name: for example, in 'mysql/data/test'
337
  			the database name is 'test' */
338
339
  /*********************************************************************
340
  Creates an InnoDB transaction struct for the session if it does not yet have one.
341
  Starts a new InnoDB transaction if a transaction is not yet started. And
342
  assigns a new snapshot for a consistent read if the transaction does not yet
343
  have one. */
344
  virtual
345
  int
346
  start_consistent_snapshot(
347
  /*====================================*/
348
  			/* out: 0 */
349
  	Session*	session);	/* in: MySQL thread handle of the user for whom
350
  			the transaction should be committed */
351
  /********************************************************************
352
  Flushes InnoDB logs to disk and makes a checkpoint. Really, a commit flushes
353
  the logs, and the name of this function should be innobase_checkpoint. */
354
  virtual
355
  bool
960.2.38 by Monty Taylor
Removed extraneous send myself to myself argument.
356
  flush_logs();
960.2.32 by Monty Taylor
Converted Innodb handlerton.
357
  /*================*/
358
  				/* out: TRUE if error */
359
  
360
  /****************************************************************************
361
  Implements the SHOW INNODB STATUS command. Sends the output of the InnoDB
362
  Monitor to the client. */
363
  virtual
364
  bool
365
  show_status(
366
  /*===============*/
367
  	Session*	session,	/* in: the MySQL query thread of the caller */
368
  	stat_print_fn *stat_print,
369
	enum ha_stat_type stat_type);
370
371
  virtual
372
  int
373
  release_temporary_latches(
374
  /*===============================*/
375
				/* out: 0 */
376
	Session*		session);	/* in: MySQL thread */
377
1039.3.1 by Stewart Smith
move bas_ext to StorageEngine instead of handler
378
379
  const char** bas_ext() const {
380
	return(ha_innobase_exts);
381
  }
382
1183.1.6 by Brian Aker
Simplify createTable()
383
  UNIV_INTERN int doCreateTable(Session *session, 
384
                                const char *table_name,
1183.1.18 by Brian Aker
Fixed references to doCreateTable()
385
                                Table& form,
386
                                drizzled::message::Table&);
1183.1.7 by Brian Aker
Fix name conventions for rename table
387
  UNIV_INTERN int doRenameTable(Session* session,
388
                                const char* from, 
389
                                const char* to);
1183.1.29 by Brian Aker
Clean up interface so that Truncate sets the propper engine when
390
  UNIV_INTERN int doDropTable(Session& session, const string table_path);
1216.1.1 by Brian Aker
Move print_error up to Engine.
391
392
  UNIV_INTERN virtual bool get_error_message(int error, String *buf);
393
960.2.32 by Monty Taylor
Converted Innodb handlerton.
394
};
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
395
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
396
/** @brief Initialize the default value of innodb_commit_concurrency.
397
398
Once InnoDB is running, the innodb_commit_concurrency must not change
399
from zero to nonzero. (Bug #42101)
400
401
The initial default value is 0, and without this extra initialization,
402
SET GLOBAL innodb_commit_concurrency=DEFAULT would set the parameter
403
to 0, even if it was initially set to nonzero at the command line
404
or configuration file. */
405
static
406
void
407
innobase_commit_concurrency_init_default(void);
408
/*==========================================*/
409
410
/************************************************************//**
411
Validate the file format name and return its corresponding id.
412
@return	valid file format id */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
413
static
414
uint
415
innobase_file_format_name_lookup(
416
/*=============================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
417
	const char*	format_name);		/*!< in: pointer to file format
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
418
						name */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
419
/************************************************************//**
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
420
Validate the file format check config parameters, as a side effect it
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
421
sets the srv_check_file_format_at_startup variable.
422
@return	true if one of  "on" or "off" */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
423
static
424
bool
425
innobase_file_format_check_on_off(
426
/*==============================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
427
	const char*	format_check);		/*!< in: parameter value */
428
/************************************************************//**
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
429
Validate the file format check config parameters, as a side effect it
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
430
sets the srv_check_file_format_at_startup variable.
431
@return	true if valid config value */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
432
static
433
bool
434
innobase_file_format_check_validate(
435
/*================================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
436
	const char*	format_check);		/*!< in: parameter value */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
437
960.2.36 by Monty Taylor
More hton renaming.
438
static const char innobase_engine_name[]= "InnoDB";
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
439
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
440
/*************************************************************//**
441
Check for a valid value of innobase_commit_concurrency.
442
@return	0 for valid innodb_commit_concurrency */
443
static
444
int
445
innobase_commit_concurrency_validate(
446
/*=================================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
447
	Session*			,	/*!< in: thread handle */
448
	struct st_mysql_sys_var*	,	/*!< in: pointer to system
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
449
						variable */
450
	void*				save,	/*!< out: immediate result
451
						for update function */
452
	struct st_mysql_value*		value)	/*!< in: incoming string */
453
{
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
454
	int64_t 	intbuf;
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
455
	ulong		commit_concurrency;
456
457
	if (value->val_int(value, &intbuf)) {
458
		/* The value is NULL. That is invalid. */
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
459
		return(1);
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
460
	}
461
462
	*reinterpret_cast<ulong*>(save) = commit_concurrency
463
		= static_cast<ulong>(intbuf);
464
465
	/* Allow the value to be updated, as long as it remains zero
466
	or nonzero. */
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
467
	return(!(!commit_concurrency == !innobase_commit_concurrency));
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
468
}
960.2.41 by Monty Taylor
Made StorageEngine name private. Added constructor param and accessor method.
469
641.1.4 by Monty Taylor
Merged in InnoDB changes.
470
static DRIZZLE_SessionVAR_BOOL(support_xa, PLUGIN_VAR_OPCMDARG,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
471
  "Enable InnoDB support for the XA two-phase commit",
472
  /* check_func */ NULL, /* update_func */ NULL,
473
  /* default */ TRUE);
474
641.1.4 by Monty Taylor
Merged in InnoDB changes.
475
static DRIZZLE_SessionVAR_BOOL(table_locks, PLUGIN_VAR_OPCMDARG,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
476
  "Enable InnoDB locking in LOCK TABLES",
477
  /* check_func */ NULL, /* update_func */ NULL,
478
  /* default */ TRUE);
479
641.1.5 by Monty Taylor
Merged in innodb plugin 1.0.2
480
static DRIZZLE_SessionVAR_BOOL(strict_mode, PLUGIN_VAR_OPCMDARG,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
481
  "Use strict mode when evaluating create options.",
482
  NULL, NULL, FALSE);
483
641.1.5 by Monty Taylor
Merged in innodb plugin 1.0.2
484
static DRIZZLE_SessionVAR_ULONG(lock_wait_timeout, PLUGIN_VAR_RQCMDARG,
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
485
  "Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout.",
486
  NULL, NULL, 50, 1, 1024 * 1024 * 1024, 0);
487
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
488
489
/***********************************************************************
490
Closes an InnoDB database. */
491
static
492
int
1110.1.5 by Monty Taylor
Renamed PluginRegistry to plugin::Registry.
493
innobase_deinit(drizzled::plugin::Registry &registry);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
494
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
495
/*****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
496
Commits a transaction in an InnoDB database. */
497
static
498
void
499
innobase_commit_low(
500
/*================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
501
	trx_t*	trx);	/*!< in: transaction handle */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
502
503
static SHOW_VAR innodb_status_variables[]= {
504
  {"buffer_pool_pages_data",
505
  (char*) &export_vars.innodb_buffer_pool_pages_data,	  SHOW_LONG},
506
  {"buffer_pool_pages_dirty",
507
  (char*) &export_vars.innodb_buffer_pool_pages_dirty,	  SHOW_LONG},
508
  {"buffer_pool_pages_flushed",
509
  (char*) &export_vars.innodb_buffer_pool_pages_flushed,  SHOW_LONG},
510
  {"buffer_pool_pages_free",
511
  (char*) &export_vars.innodb_buffer_pool_pages_free,	  SHOW_LONG},
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
512
#ifdef UNIV_DEBUG
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
513
  {"buffer_pool_pages_latched",
514
  (char*) &export_vars.innodb_buffer_pool_pages_latched,  SHOW_LONG},
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
515
#endif /* UNIV_DEBUG */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
516
  {"buffer_pool_pages_misc",
517
  (char*) &export_vars.innodb_buffer_pool_pages_misc,	  SHOW_LONG},
518
  {"buffer_pool_pages_total",
519
  (char*) &export_vars.innodb_buffer_pool_pages_total,	  SHOW_LONG},
520
  {"buffer_pool_read_ahead_rnd",
521
  (char*) &export_vars.innodb_buffer_pool_read_ahead_rnd, SHOW_LONG},
522
  {"buffer_pool_read_ahead_seq",
523
  (char*) &export_vars.innodb_buffer_pool_read_ahead_seq, SHOW_LONG},
524
  {"buffer_pool_read_requests",
525
  (char*) &export_vars.innodb_buffer_pool_read_requests,  SHOW_LONG},
526
  {"buffer_pool_reads",
527
  (char*) &export_vars.innodb_buffer_pool_reads,	  SHOW_LONG},
528
  {"buffer_pool_wait_free",
529
  (char*) &export_vars.innodb_buffer_pool_wait_free,	  SHOW_LONG},
530
  {"buffer_pool_write_requests",
531
  (char*) &export_vars.innodb_buffer_pool_write_requests, SHOW_LONG},
532
  {"data_fsyncs",
533
  (char*) &export_vars.innodb_data_fsyncs,		  SHOW_LONG},
534
  {"data_pending_fsyncs",
535
  (char*) &export_vars.innodb_data_pending_fsyncs,	  SHOW_LONG},
536
  {"data_pending_reads",
537
  (char*) &export_vars.innodb_data_pending_reads,	  SHOW_LONG},
538
  {"data_pending_writes",
539
  (char*) &export_vars.innodb_data_pending_writes,	  SHOW_LONG},
540
  {"data_read",
541
  (char*) &export_vars.innodb_data_read,		  SHOW_LONG},
542
  {"data_reads",
543
  (char*) &export_vars.innodb_data_reads,		  SHOW_LONG},
544
  {"data_writes",
545
  (char*) &export_vars.innodb_data_writes,		  SHOW_LONG},
546
  {"data_written",
547
  (char*) &export_vars.innodb_data_written,		  SHOW_LONG},
548
  {"dblwr_pages_written",
549
  (char*) &export_vars.innodb_dblwr_pages_written,	  SHOW_LONG},
550
  {"dblwr_writes",
551
  (char*) &export_vars.innodb_dblwr_writes,		  SHOW_LONG},
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
552
  {"have_atomic_builtins",
553
  (char*) &export_vars.innodb_have_atomic_builtins,	  SHOW_BOOL},
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
554
  {"log_waits",
555
  (char*) &export_vars.innodb_log_waits,		  SHOW_LONG},
556
  {"log_write_requests",
557
  (char*) &export_vars.innodb_log_write_requests,	  SHOW_LONG},
558
  {"log_writes",
559
  (char*) &export_vars.innodb_log_writes,		  SHOW_LONG},
560
  {"os_log_fsyncs",
561
  (char*) &export_vars.innodb_os_log_fsyncs,		  SHOW_LONG},
562
  {"os_log_pending_fsyncs",
563
  (char*) &export_vars.innodb_os_log_pending_fsyncs,	  SHOW_LONG},
564
  {"os_log_pending_writes",
565
  (char*) &export_vars.innodb_os_log_pending_writes,	  SHOW_LONG},
566
  {"os_log_written",
567
  (char*) &export_vars.innodb_os_log_written,		  SHOW_LONG},
568
  {"page_size",
569
  (char*) &export_vars.innodb_page_size,		  SHOW_LONG},
570
  {"pages_created",
571
  (char*) &export_vars.innodb_pages_created,		  SHOW_LONG},
572
  {"pages_read",
573
  (char*) &export_vars.innodb_pages_read,		  SHOW_LONG},
574
  {"pages_written",
575
  (char*) &export_vars.innodb_pages_written,		  SHOW_LONG},
576
  {"row_lock_current_waits",
577
  (char*) &export_vars.innodb_row_lock_current_waits,	  SHOW_LONG},
578
  {"row_lock_time",
579
  (char*) &export_vars.innodb_row_lock_time,		  SHOW_LONGLONG},
580
  {"row_lock_time_avg",
581
  (char*) &export_vars.innodb_row_lock_time_avg,	  SHOW_LONG},
582
  {"row_lock_time_max",
583
  (char*) &export_vars.innodb_row_lock_time_max,	  SHOW_LONG},
584
  {"row_lock_waits",
585
  (char*) &export_vars.innodb_row_lock_waits,		  SHOW_LONG},
586
  {"rows_deleted",
587
  (char*) &export_vars.innodb_rows_deleted,		  SHOW_LONG},
588
  {"rows_inserted",
589
  (char*) &export_vars.innodb_rows_inserted,		  SHOW_LONG},
590
  {"rows_read",
591
  (char*) &export_vars.innodb_rows_read,		  SHOW_LONG},
592
  {"rows_updated",
593
  (char*) &export_vars.innodb_rows_updated,		  SHOW_LONG},
641.1.4 by Monty Taylor
Merged in InnoDB changes.
594
  {NULL, NULL, SHOW_LONG}
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
595
};
596
597
/* General functions */
598
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
599
/******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
600
Returns true if the thread is the replication thread on the slave
601
server. Used in srv_conc_enter_innodb() to determine if the thread
602
should be allowed to enter InnoDB - the replication thread is treated
603
differently than other threads. Also used in
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
604
srv_conc_force_exit_innodb().
641.1.4 by Monty Taylor
Merged in InnoDB changes.
605
606
DRIZZLE: Note, we didn't change this name to avoid more ifdef forking 
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
607
         in non-Cursor code.
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
608
@return	true if session is the replication thread */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
609
extern "C" UNIV_INTERN
610
ibool
611
thd_is_replication_slave_thread(
612
/*============================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
613
	void*	)	/*!< in: thread handle (Session*) */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
614
{
808 by Brian Aker
Move number of threads to use for pool of threads to module. Removed slave
615
	return false;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
616
}
617
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
618
/******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
619
Save some CPU by testing the value of srv_thread_concurrency in inline
620
functions. */
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
621
static inline
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
622
void
623
innodb_srv_conc_enter_innodb(
624
/*=========================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
625
	trx_t*	trx)	/*!< in: transaction handle */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
626
{
627
	if (UNIV_LIKELY(!srv_thread_concurrency)) {
628
629
		return;
630
	}
631
632
	srv_conc_enter_innodb(trx);
633
}
634
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
635
/******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
636
Save some CPU by testing the value of srv_thread_concurrency in inline
637
functions. */
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
638
static inline
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
639
void
640
innodb_srv_conc_exit_innodb(
641
/*========================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
642
	trx_t*	trx)	/*!< in: transaction handle */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
643
{
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
644
	if (UNIV_LIKELY(!trx->declared_to_be_inside_innodb)) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
645
646
		return;
647
	}
648
649
	srv_conc_exit_innodb(trx);
650
}
651
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
652
/******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
653
Releases possible search latch and InnoDB thread FIFO ticket. These should
654
be released at each SQL statement end, and also when mysqld passes the
655
control to the client. It does no harm to release these also in the middle
656
of an SQL statement. */
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
657
static inline
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
658
void
659
innobase_release_stat_resources(
660
/*============================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
661
	trx_t*	trx)	/*!< in: transaction object */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
662
{
663
	if (trx->has_search_latch) {
664
		trx_search_latch_release_if_reserved(trx);
665
	}
666
667
	if (trx->declared_to_be_inside_innodb) {
668
		/* Release our possible ticket in the FIFO */
669
670
		srv_conc_force_exit_innodb(trx);
671
	}
672
}
673
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
674
/******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
675
Returns true if the transaction this thread is processing has edited
676
non-transactional tables. Used by the deadlock detector when deciding
677
which transaction to rollback in case of a deadlock - we try to avoid
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
678
rolling back transactions that have edited non-transactional tables.
641.1.4 by Monty Taylor
Merged in InnoDB changes.
679
680
DRIZZLE: Note, we didn't change this name to avoid more ifdef forking 
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
681
         in non-Cursor code.
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
682
@return	true if non-transactional tables have been edited */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
683
extern "C" UNIV_INTERN
684
ibool
685
thd_has_edited_nontrans_tables(
686
/*===========================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
687
	void*		session)	/*!< in: thread handle (Session*) */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
688
{
641.1.4 by Monty Taylor
Merged in InnoDB changes.
689
	return((ibool) session_non_transactional_update((Session*) session));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
690
}
691
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
692
/******************************************************************//**
693
Returns true if the thread is executing a SELECT statement.
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
694
@return	true if session is executing SELECT */
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
695
extern "C" UNIV_INTERN
696
ibool
697
thd_is_select(
698
/*==========*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
699
	const void*	session)	/*!< in: thread handle (Session*) */
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
700
{
641.1.5 by Monty Taylor
Merged in innodb plugin 1.0.2
701
	return(session_sql_command((const Session*) session) == SQLCOM_SELECT);
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
702
}
703
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
704
/******************************************************************//**
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
705
Returns true if the thread supports XA,
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
706
global value of innodb_supports_xa if session is NULL.
707
@return	true if session has XA support */
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
708
extern "C" UNIV_INTERN
709
ibool
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
710
thd_supports_xa(
711
/*============*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
712
	void*	session)	/*!< in: thread handle (Session*), or NULL to query
713
				the global innodb_supports_xa */
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
714
{
933.1.1 by Monty Taylor
Merged in InnoDB Plugin 1.0.3
715
	return(SessionVAR((Session*) session, support_xa));
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
716
}
717
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
718
/******************************************************************//**
719
Returns the lock wait timeout for the current connection.
720
@return	the lock wait timeout, in seconds */
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
721
extern "C" UNIV_INTERN
722
ulong
723
thd_lock_wait_timeout(
724
/*==================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
725
	void*	session)	/*!< in: thread handle (Session*), or NULL to query
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
726
			the global innodb_lock_wait_timeout */
727
{
641.1.5 by Monty Taylor
Merged in innodb plugin 1.0.2
728
	/* According to <drizzle/plugin.h>, passing session == NULL
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
729
	returns the global value of the session variable. */
641.1.5 by Monty Taylor
Merged in innodb plugin 1.0.2
730
	return(SessionVAR((Session*) session, lock_wait_timeout));
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
731
}
732
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
733
/********************************************************************//**
734
Obtain the InnoDB transaction of a MySQL thread.
735
@return	reference to transaction pointer */
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
736
static inline
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
737
trx_t*&
641.1.4 by Monty Taylor
Merged in InnoDB changes.
738
session_to_trx(
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
739
/*=======*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
740
	Session*	session)	/*!< in: Drizzle Session */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
741
{
960.2.36 by Monty Taylor
More hton renaming.
742
	return(*(trx_t**) session_ha_data(session, innodb_engine_ptr));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
743
}
744
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
745
/********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
746
Call this function when mysqld passes control to the client. That is to
641.1.4 by Monty Taylor
Merged in InnoDB changes.
747
avoid deadlocks on the adaptive hash S-latch possibly held by session. For more
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
748
documentation, see Cursor.cc.
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
749
@return	0 */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
750
int
960.2.32 by Monty Taylor
Converted Innodb handlerton.
751
InnobaseEngine::release_temporary_latches(
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
752
/*===============================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
753
	Session*		session)	/*!< in: MySQL thread */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
754
{
755
	trx_t*	trx;
756
960.2.38 by Monty Taylor
Removed extraneous send myself to myself argument.
757
	assert(this == innodb_engine_ptr);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
758
759
	if (!innodb_inited) {
760
761
		return(0);
762
	}
763
641.1.4 by Monty Taylor
Merged in InnoDB changes.
764
	trx = session_to_trx(session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
765
766
	if (trx) {
767
		innobase_release_stat_resources(trx);
768
	}
769
	return(0);
770
}
771
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
772
/********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
773
Increments innobase_active_counter and every INNOBASE_WAKE_INTERVALth
774
time calls srv_active_wake_master_thread. This function should be used
775
when a single database operation may introduce a small need for
776
server utility activity, like checkpointing. */
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
777
static inline
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
778
void
779
innobase_active_small(void)
780
/*=======================*/
781
{
782
	innobase_active_counter++;
783
784
	if ((innobase_active_counter % INNOBASE_WAKE_INTERVAL) == 0) {
785
		srv_active_wake_master_thread();
786
	}
787
}
788
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
789
/********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
790
Converts an InnoDB error code to a MySQL error code and also tells to MySQL
791
about a possible transaction rollback inside InnoDB caused by a lock wait
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
792
timeout or a deadlock.
793
@return	MySQL error code */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
794
extern "C" UNIV_INTERN
795
int
796
convert_error_code_to_mysql(
797
/*========================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
798
	int		error,	/*!< in: InnoDB error code */
799
	ulint		flags,	/*!< in: InnoDB table flags, or 0 */
800
	Session*	session)/*!< in: user thread handle or NULL */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
801
{
802
	switch (error) {
803
	case DB_SUCCESS:
804
		return(0);
805
806
	case DB_ERROR:
807
	default:
808
		return(-1); /* unspecified error */
809
810
	case DB_DUPLICATE_KEY:
811
		return(HA_ERR_FOUND_DUPP_KEY);
812
813
	case DB_FOREIGN_DUPLICATE_KEY:
814
		return(HA_ERR_FOREIGN_DUPLICATE_KEY);
815
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
816
	case DB_MISSING_HISTORY:
817
		return(HA_ERR_TABLE_DEF_CHANGED);
818
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
819
	case DB_RECORD_NOT_FOUND:
820
		return(HA_ERR_NO_ACTIVE_RECORD);
821
822
	case DB_DEADLOCK:
823
		/* Since we rolled back the whole transaction, we must
824
		tell it also to MySQL so that MySQL knows to empty the
825
		cached binlog for this transaction */
826
641.1.4 by Monty Taylor
Merged in InnoDB changes.
827
                session_mark_transaction_to_rollback(session, TRUE);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
828
829
		return(HA_ERR_LOCK_DEADLOCK);
830
831
	case DB_LOCK_WAIT_TIMEOUT:
832
		/* Starting from 5.0.13, we let MySQL just roll back the
833
		latest SQL statement in a lock wait timeout. Previously, we
834
		rolled back the whole transaction. */
835
641.1.4 by Monty Taylor
Merged in InnoDB changes.
836
                session_mark_transaction_to_rollback(session,
837
                                             (bool)row_rollback_on_timeout);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
838
839
		return(HA_ERR_LOCK_WAIT_TIMEOUT);
840
841
	case DB_NO_REFERENCED_ROW:
842
		return(HA_ERR_NO_REFERENCED_ROW);
843
844
	case DB_ROW_IS_REFERENCED:
845
		return(HA_ERR_ROW_IS_REFERENCED);
846
847
	case DB_CANNOT_ADD_CONSTRAINT:
848
		return(HA_ERR_CANNOT_ADD_FOREIGN);
849
850
	case DB_CANNOT_DROP_CONSTRAINT:
851
852
		return(HA_ERR_ROW_IS_REFERENCED); /* TODO: This is a bit
853
						misleading, a new MySQL error
854
						code should be introduced */
855
856
	case DB_COL_APPEARS_TWICE_IN_INDEX:
857
	case DB_CORRUPTION:
858
		return(HA_ERR_CRASHED);
859
860
	case DB_OUT_OF_FILE_SPACE:
861
		return(HA_ERR_RECORD_FILE_FULL);
862
863
	case DB_TABLE_IS_BEING_USED:
864
		return(HA_ERR_WRONG_COMMAND);
865
866
	case DB_TABLE_NOT_FOUND:
867
		return(HA_ERR_NO_SUCH_TABLE);
868
869
	case DB_TOO_BIG_RECORD:
870
		my_error(ER_TOO_BIG_ROWSIZE, MYF(0),
871
			 page_get_free_space_of_empty(flags
872
						      & DICT_TF_COMPACT) / 2);
873
		return(HA_ERR_TO_BIG_ROW);
874
875
	case DB_NO_SAVEPOINT:
876
		return(HA_ERR_NO_SAVEPOINT);
877
878
	case DB_LOCK_TABLE_FULL:
879
		/* Since we rolled back the whole transaction, we must
880
		tell it also to MySQL so that MySQL knows to empty the
881
		cached binlog for this transaction */
882
641.1.4 by Monty Taylor
Merged in InnoDB changes.
883
		session_mark_transaction_to_rollback(session, TRUE);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
884
885
		return(HA_ERR_LOCK_TABLE_FULL);
886
887
	case DB_PRIMARY_KEY_IS_NULL:
888
		return(ER_PRIMARY_CANT_HAVE_NULL);
889
890
	case DB_TOO_MANY_CONCURRENT_TRXS:
641.1.4 by Monty Taylor
Merged in InnoDB changes.
891
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
892
		/* Once MySQL add the appropriate code to errmsg.txt then
893
		we can get rid of this #ifdef. NOTE: The code checked by
894
		the #ifdef is the suggested name for the error condition
895
		and the actual error code name could very well be different.
896
		This will require some monitoring, ie. the status
897
		of this request on our part.*/
898
#ifdef ER_TOO_MANY_CONCURRENT_TRXS
899
		return(ER_TOO_MANY_CONCURRENT_TRXS);
900
#else
901
		return(HA_ERR_RECORD_FILE_FULL);
902
#endif
903
	case DB_UNSUPPORTED:
904
		return(HA_ERR_UNSUPPORTED);
905
	}
906
}
907
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
908
/*************************************************************//**
641.1.4 by Monty Taylor
Merged in InnoDB changes.
909
If you want to print a session that is not associated with the current thread,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
910
you must call this function before reserving the InnoDB kernel_mutex, to
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
911
protect Drizzle from setting session->query NULL. If you print a session of the
641.1.4 by Monty Taylor
Merged in InnoDB changes.
912
current thread, we know that Drizzle cannot modify sesion->query, and it is
913
not necessary to call this. Call innobase_mysql_end_print_arbitrary_thd()
914
after you release the kernel_mutex.
915
916
DRIZZLE: Note, we didn't change this name to avoid more ifdef forking 
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
917
         in non-Cursor code.
641.1.4 by Monty Taylor
Merged in InnoDB changes.
918
 */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
919
extern "C" UNIV_INTERN
920
void
921
innobase_mysql_prepare_print_arbitrary_thd(void)
922
/*============================================*/
923
{
924
	ut_ad(!mutex_own(&kernel_mutex));
641.1.4 by Monty Taylor
Merged in InnoDB changes.
925
	pthread_mutex_lock(&LOCK_thread_count);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
926
}
927
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
928
/*************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
929
Releases the mutex reserved by innobase_mysql_prepare_print_arbitrary_thd().
930
In the InnoDB latching order, the mutex sits right above the
931
kernel_mutex.  In debug builds, we assert that the kernel_mutex is
641.1.4 by Monty Taylor
Merged in InnoDB changes.
932
released before this function is invoked. 
933
934
DRIZZLE: Note, we didn't change this name to avoid more ifdef forking 
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
935
         in non-Cursor code.
641.1.4 by Monty Taylor
Merged in InnoDB changes.
936
*/
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
937
extern "C" UNIV_INTERN
938
void
939
innobase_mysql_end_print_arbitrary_thd(void)
940
/*========================================*/
941
{
942
	ut_ad(!mutex_own(&kernel_mutex));
641.1.4 by Monty Taylor
Merged in InnoDB changes.
943
	pthread_mutex_unlock(&LOCK_thread_count);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
944
}
945
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
946
/*************************************************************//**
641.1.4 by Monty Taylor
Merged in InnoDB changes.
947
Prints info of a Session object (== user session thread) to the given file. */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
948
extern "C" UNIV_INTERN
949
void
950
innobase_mysql_print_thd(
951
/*=====================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
952
	FILE*	f,		/*!< in: output stream */
1126.14.3 by Diego Medina
merge from trunk
953
	void * in_session,	/*!< in: pointer to a Drizzle Session object */
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
954
	uint	)		/*!< in: max query length to print, or 0 to
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
955
				   use the default max length */
956
{
1126.14.2 by Diego Medina
* Replaced some ugly code for nicer one :)
957
  Session *session= reinterpret_cast<Session *>(in_session);
1126.14.1 by Diego Medina
Add Thread ID, Query ID, Hostname, Client IP and Username to show engine innodb status
958
  fprintf(f,
959
          "Drizzle thread %"PRIu64", query id %"PRIu64", %s, %s, %s ",
1126.14.2 by Diego Medina
* Replaced some ugly code for nicer one :)
960
          static_cast<uint64_t>(session_get_thread_id( session)),
961
          static_cast<uint64_t>(session->getQueryId()),
1126.14.1 by Diego Medina
Add Thread ID, Query ID, Hostname, Client IP and Username to show engine innodb status
962
          glob_hostname,
1126.14.2 by Diego Medina
* Replaced some ugly code for nicer one :)
963
          session->security_ctx.ip.c_str(),
964
          session->security_ctx.user.c_str()
1126.14.1 by Diego Medina
Add Thread ID, Query ID, Hostname, Client IP and Username to show engine innodb status
965
  );
966
  fprintf(f,
1126.14.2 by Diego Medina
* Replaced some ugly code for nicer one :)
967
          "\n%s", session->getQueryString()
1126.14.1 by Diego Medina
Add Thread ID, Query ID, Hostname, Client IP and Username to show engine innodb status
968
  );
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
969
	putc('\n', f);
970
}
971
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
972
/******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
973
Get the variable length bounds of the given character set. */
974
extern "C" UNIV_INTERN
975
void
976
innobase_get_cset_width(
977
/*====================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
978
	ulint	cset,		/*!< in: MySQL charset-collation code */
979
	ulint*	mbminlen,	/*!< out: minimum length of a char (in bytes) */
980
	ulint*	mbmaxlen)	/*!< out: maximum length of a char (in bytes) */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
981
{
982
	CHARSET_INFO*	cs;
983
	ut_ad(cset < 256);
984
	ut_ad(mbminlen);
985
	ut_ad(mbmaxlen);
986
987
	cs = all_charsets[cset];
988
	if (cs) {
989
		*mbminlen = cs->mbminlen;
990
		*mbmaxlen = cs->mbmaxlen;
991
	} else {
992
		ut_a(cset == 0);
993
		*mbminlen = *mbmaxlen = 0;
994
	}
995
}
996
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
997
/******************************************************************//**
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
998
Converts an identifier to a table name. */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
999
extern "C" UNIV_INTERN
1000
void
1001
innobase_convert_from_table_id(
1002
/*===========================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
1003
	const struct charset_info_st*,	/*!< in: the 'from' character set */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1004
	char*			to,	/*!< out: converted identifier */
1005
	const char*		from,	/*!< in: identifier to convert */
1006
	ulint			len)	/*!< in: length of 'to', in bytes */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1007
{
1054.2.12 by Monty Taylor
First pass at removing strconvert.
1008
	strncpy(to, from, len);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1009
}
1010
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1011
/******************************************************************//**
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
1012
Converts an identifier to UTF-8. */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1013
extern "C" UNIV_INTERN
1014
void
1015
innobase_convert_from_id(
1016
/*=====================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
1017
	const struct charset_info_st*,	/*!< in: the 'from' character set */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1018
	char*			to,	/*!< out: converted identifier */
1019
	const char*		from,	/*!< in: identifier to convert */
1020
	ulint			len)	/*!< in: length of 'to', in bytes */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1021
{
1054.2.12 by Monty Taylor
First pass at removing strconvert.
1022
	strncpy(to, from, len);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1023
}
1024
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1025
/******************************************************************//**
1026
Compares NUL-terminated UTF-8 strings case insensitively.
1027
@return	0 if a=b, <0 if a<b, >1 if a>b */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1028
extern "C" UNIV_INTERN
1029
int
1030
innobase_strcasecmp(
1031
/*================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1032
	const char*	a,	/*!< in: first string to compare */
1033
	const char*	b)	/*!< in: second string to compare */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1034
{
1035
	return(my_strcasecmp(system_charset_info, a, b));
1036
}
1037
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1038
/******************************************************************//**
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
1039
Makes all characters in a NUL-terminated UTF-8 string lower case. */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1040
extern "C" UNIV_INTERN
1041
void
1042
innobase_casedn_str(
1043
/*================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1044
	char*	a)	/*!< in/out: string to put in lower case */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1045
{
1046
	my_casedn_str(system_charset_info, a);
1047
}
1048
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1049
/**********************************************************************//**
1050
Determines the connection character set.
1051
@return	connection character set */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1052
extern "C" UNIV_INTERN
1085.1.2 by Monty Taylor
Fixed -Wmissing-declarations
1053
const charset_info_st*
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1054
innobase_get_charset(
1055
/*=================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
1056
	void*	mysql_session)	/*!< in: MySQL thread handle */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1057
{
1085.1.2 by Monty Taylor
Fixed -Wmissing-declarations
1058
	return(session_charset(static_cast<Session*>(mysql_session)));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1059
}
1060
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
1061
#if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1062
/*******************************************************************//**
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
1063
Map an OS error to an errno value. The OS error number is stored in
1064
_doserrno and the mapped value is stored in errno) */
1065
extern "C"
1066
void __cdecl
1067
_dosmaperr(
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1068
	unsigned long);	/*!< in: OS error value */
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
1069
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1070
/*********************************************************************//**
1071
Creates a temporary file.
1072
@return	temporary file descriptor, or < 0 on error */
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
1073
extern "C" UNIV_INTERN
1074
int
1075
innobase_mysql_tmpfile(void)
1076
/*========================*/
1077
{
1078
	int	fd;				/* handle of opened file */
1079
	HANDLE	osfh;				/* OS handle of opened file */
1080
	char*	tmpdir;				/* point to the directory
1081
						where to create file */
1082
	TCHAR	path_buf[MAX_PATH - 14];	/* buffer for tmp file path.
1083
						The length cannot be longer
1084
						than MAX_PATH - 14, or
1085
						GetTempFileName will fail. */
1086
	char	filename[MAX_PATH];		/* name of the tmpfile */
1087
	DWORD	fileaccess = GENERIC_READ	/* OS file access */
1088
			     | GENERIC_WRITE
1089
			     | DELETE;
1090
	DWORD	fileshare = FILE_SHARE_READ	/* OS file sharing mode */
1091
			    | FILE_SHARE_WRITE
1092
			    | FILE_SHARE_DELETE;
1093
	DWORD	filecreate = CREATE_ALWAYS;	/* OS method of open/create */
1094
	DWORD	fileattrib =			/* OS file attribute flags */
1095
			     FILE_ATTRIBUTE_NORMAL
1096
			     | FILE_FLAG_DELETE_ON_CLOSE
1097
			     | FILE_ATTRIBUTE_TEMPORARY
1098
			     | FILE_FLAG_SEQUENTIAL_SCAN;
1099
1100
	tmpdir = my_tmpdir(&mysql_tmpdir_list);
1101
1102
	/* The tmpdir parameter can not be NULL for GetTempFileName. */
1103
	if (!tmpdir) {
1104
		uint	ret;
1105
1106
		/* Use GetTempPath to determine path for temporary files. */
1107
		ret = GetTempPath(sizeof(path_buf), path_buf);
1108
		if (ret > sizeof(path_buf) || (ret == 0)) {
1109
1110
			_dosmaperr(GetLastError());	/* map error */
933.1.2 by Monty Taylor
Fixed merge weirdness errors.
1111
			return(-1);
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
1112
		}
1113
1114
		tmpdir = path_buf;
1115
	}
1116
1117
	/* Use GetTempFileName to generate a unique filename. */
1118
	if (!GetTempFileName(tmpdir, "ib", 0, filename)) {
1119
1120
		_dosmaperr(GetLastError());	/* map error */
933.1.2 by Monty Taylor
Fixed merge weirdness errors.
1121
		return(-1);
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
1122
	}
1123
1124
	/* Open/Create the file. */
1125
	osfh = CreateFile(filename, fileaccess, fileshare, NULL,
1126
			  filecreate, fileattrib, NULL);
1127
	if (osfh == INVALID_HANDLE_VALUE) {
1128
1129
		/* open/create file failed! */
1130
		_dosmaperr(GetLastError());	/* map error */
933.1.2 by Monty Taylor
Fixed merge weirdness errors.
1131
		return(-1);
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
1132
	}
1133
1134
	do {
1135
		/* Associates a CRT file descriptor with the OS file handle. */
1136
		fd = _open_osfhandle((intptr_t) osfh, 0);
1137
	} while (fd == -1 && errno == EINTR);
1138
1139
	if (fd == -1) {
1140
		/* Open failed, close the file handle. */
1141
1142
		_dosmaperr(GetLastError());	/* map error */
1143
		CloseHandle(osfh);		/* no need to check if
1144
						CloseHandle fails */
1145
	}
1146
933.1.2 by Monty Taylor
Fixed merge weirdness errors.
1147
	return(fd);
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
1148
}
1149
#else
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1150
/*********************************************************************//**
1151
Creates a temporary file.
1152
@return	temporary file descriptor, or < 0 on error */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1153
extern "C" UNIV_INTERN
1154
int
1155
innobase_mysql_tmpfile(void)
1156
/*========================*/
1157
{
1158
	int	fd2 = -1;
1159
	File	fd = mysql_tmpfile("ib");
1160
	if (fd >= 0) {
1161
		/* Copy the file descriptor, so that the additional resources
1162
		allocated by create_temp_file() can be freed by invoking
1163
		my_close().
1164
1165
		Because the file descriptor returned by this function
1166
		will be passed to fdopen(), it will be closed by invoking
1167
		fclose(), which in turn will invoke close() instead of
1168
		my_close(). */
1169
		fd2 = dup(fd);
1170
		if (fd2 < 0) {
1171
			my_errno=errno;
1172
			my_error(EE_OUT_OF_FILERESOURCES,
1173
				 MYF(ME_BELL+ME_WAITTANG),
1174
				 "ib*", my_errno);
1175
		}
1176
		my_close(fd, MYF(MY_WME));
1177
	}
1178
	return(fd2);
1179
}
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
1180
#endif /* defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN) */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1181
1182
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1183
/*******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1184
Formats the raw data in "data" (in InnoDB on-disk format) that is of
641.1.4 by Monty Taylor
Merged in InnoDB changes.
1185
type DATA_(CHAR|VARCHAR|DRIZZLE|VARDRIZZLE) using "charset_coll" and writes
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1186
the result to "buf". The result is converted to "system_charset_info".
1187
Not more than "buf_size" bytes are written to "buf".
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1188
The result is always NUL-terminated (provided buf_size > 0) and the
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1189
number of bytes that were written to "buf" is returned (including the
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1190
terminating NUL).
1191
@return	number of bytes that were written */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1192
extern "C" UNIV_INTERN
1193
ulint
1194
innobase_raw_format(
1195
/*================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1196
	const char*	data,		/*!< in: raw data */
1197
	ulint		data_len,	/*!< in: raw data length
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1198
					in bytes */
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
1199
	ulint		,		/*!< in: charset collation */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1200
	char*		buf,		/*!< out: output buffer */
1201
	ulint		buf_size)	/*!< in: output buffer size
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1202
					in bytes */
1203
{
1054.2.11 by Monty Taylor
Removed copy_and_convert.
1204
	return(ut_str_sql_format(data, data_len, buf, buf_size));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1205
}
1206
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1207
/*********************************************************************//**
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
1208
Compute the next autoinc value.
1209
1210
For MySQL replication the autoincrement values can be partitioned among
1211
the nodes. The offset is the start or origin of the autoincrement value
1212
for a particular node. For n nodes the increment will be n and the offset
1213
will be in the interval [1, n]. The formula tries to allocate the next
1214
value for a particular node.
1215
1216
Note: This function is also called with increment set to the number of
1217
values we want to reserve for multi-value inserts e.g.,
1218
1219
	INSERT INTO T VALUES(), (), ();
1220
1221
innobase_next_autoinc() will be called with increment set to
1222
n * 3 where autoinc_lock_mode != TRADITIONAL because we want
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1223
to reserve 3 values for the multi-value INSERT above.
1224
@return	the next value */
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
1225
static
641.1.5 by Monty Taylor
Merged in innodb plugin 1.0.2
1226
uint64_t
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
1227
innobase_next_autoinc(
1228
/*==================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
1229
	uint64_t	current,	/*!< in: Current value */
1230
	uint64_t	increment,	/*!< in: increment current by */
1231
	uint64_t	offset,		/*!< in: AUTOINC offset */
1232
	uint64_t	max_value)	/*!< in: max value for type */
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
1233
{
641.1.5 by Monty Taylor
Merged in innodb plugin 1.0.2
1234
	uint64_t	next_value;
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
1235
1236
	/* Should never be 0. */
1237
	ut_a(increment > 0);
1238
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
1239
	/* According to MySQL documentation, if the offset is greater than
1240
	the increment then the offset is ignored. */
1241
	if (offset > increment) {
1242
		offset = 0;
1243
	}
1244
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
1245
	if (max_value <= current) {
1246
		next_value = max_value;
1247
	} else if (offset <= 1) {
1248
		/* Offset 0 and 1 are the same, because there must be at
1249
		least one node in the system. */
1250
		if (max_value - current <= increment) {
1251
			next_value = max_value;
1252
		} else {
1253
			next_value = current + increment;
1254
		}
1255
	} else if (max_value > current) {
1256
		if (current > offset) {
1257
			next_value = ((current - offset) / increment) + 1;
1258
		} else {
1259
			next_value = ((offset - current) / increment) + 1;
1260
		}
1261
1262
		ut_a(increment > 0);
1263
		ut_a(next_value > 0);
1264
1265
		/* Check for multiplication overflow. */
1266
		if (increment > (max_value / next_value)) {
1267
1268
			next_value = max_value;
1269
		} else {
1270
			next_value *= increment;
1271
1272
			ut_a(max_value >= next_value);
1273
1274
			/* Check for overflow. */
1275
			if (max_value - next_value <= offset) {
1276
				next_value = max_value;
1277
			} else {
1278
				next_value += offset;
1279
			}
1280
		}
1281
	} else {
1282
		next_value = max_value;
1283
	}
1284
1285
	ut_a(next_value <= max_value);
1286
1287
	return(next_value);
1288
}
1289
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1290
/*********************************************************************//**
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
1291
Initializes some fields in an InnoDB transaction object. */
1292
static
1293
void
1294
innobase_trx_init(
1295
/*==============*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
1296
	Session*	session,	/*!< in: user thread handle */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1297
	trx_t*	trx)	/*!< in/out: InnoDB transaction handle */
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
1298
{
933.1.2 by Monty Taylor
Fixed merge weirdness errors.
1299
	assert(session == trx->mysql_thd);
1300
1301
	trx->check_foreigns = !session_test_options(
1302
		session, OPTION_NO_FOREIGN_KEY_CHECKS);
1303
1304
	trx->check_unique_secondary = !session_test_options(
1305
		session, OPTION_RELAXED_UNIQUE_CHECKS);
1306
1307
	return;
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
1308
}
1309
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1310
/*********************************************************************//**
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
1311
Allocates an InnoDB transaction for a MySQL Cursor object.
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1312
@return	InnoDB transaction handle */
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
1313
extern "C" UNIV_INTERN
1314
trx_t*
1315
innobase_trx_allocate(
1316
/*==================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
1317
	Session*	session)	/*!< in: user thread handle */
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
1318
{
1319
	trx_t*	trx;
1320
933.1.2 by Monty Taylor
Fixed merge weirdness errors.
1321
	assert(session != NULL);
1322
	assert(EQ_CURRENT_SESSION(session));
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
1323
1324
	trx = trx_allocate_for_mysql();
1325
933.1.2 by Monty Taylor
Fixed merge weirdness errors.
1326
	trx->mysql_thd = session;
1327
	trx->mysql_query_str = session_query(session);
1328
1329
	innobase_trx_init(session, trx);
1330
1331
	return(trx);
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
1332
}
1333
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1334
/*********************************************************************//**
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
1335
Gets the InnoDB transaction handle for a MySQL Cursor object, creates
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1336
an InnoDB transaction struct if the corresponding MySQL thread struct still
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1337
lacks one.
1338
@return	InnoDB transaction handle */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1339
static
1340
trx_t*
1341
check_trx_exists(
1342
/*=============*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
1343
	Session*	session)	/*!< in: user thread handle */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1344
{
641.1.4 by Monty Taylor
Merged in InnoDB changes.
1345
	trx_t*&	trx = session_to_trx(session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1346
641.1.5 by Monty Taylor
Merged in innodb plugin 1.0.2
1347
	ut_ad(EQ_CURRENT_SESSION(session));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1348
1349
	if (trx == NULL) {
933.1.1 by Monty Taylor
Merged in InnoDB Plugin 1.0.3
1350
		trx = innobase_trx_allocate(session);
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
1351
	} else if (UNIV_UNLIKELY(trx->magic_n != TRX_MAGIC_N)) {
1352
		mem_analyze_corruption(trx);
1353
		ut_error;
1354
	}
1355
933.1.1 by Monty Taylor
Merged in InnoDB Plugin 1.0.3
1356
	innobase_trx_init(session, trx);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1357
1358
	return(trx);
1359
}
1360
1361
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1362
/*********************************************************************//**
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
1363
Construct ha_innobase Cursor. */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1364
UNIV_INTERN
1208.3.2 by brian
Update for Cursor renaming.
1365
ha_innobase::ha_innobase(drizzled::plugin::StorageEngine &engine_arg,
1366
                         TableShare &table_arg)
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
1367
  :Cursor(engine_arg, table_arg),
641.1.4 by Monty Taylor
Merged in InnoDB changes.
1368
  primary_key(0), /* needs initialization because index_flags() may be called 
1369
                     before this is set to the real value. It's ok to have any 
1370
                     value here because it doesn't matter if we return the
1371
                     HA_DO_INDEX_COND_PUSHDOWN bit from those "early" calls */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1372
  start_of_scan(0),
1373
  num_write_row(0)
1374
{}
1375
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1376
/*********************************************************************//**
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
1377
Destruct ha_innobase Cursor. */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1378
UNIV_INTERN
1379
ha_innobase::~ha_innobase()
1380
{
1381
}
1382
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1383
/*********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1384
Updates the user_thd field in a handle and also allocates a new InnoDB
1385
transaction handle if needed, and updates the transaction fields in the
1386
prebuilt struct. */
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
1387
UNIV_INTERN inline
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1388
void
641.1.4 by Monty Taylor
Merged in InnoDB changes.
1389
ha_innobase::update_session(
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1390
/*====================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
1391
	Session*	session)	/*!< in: thd to use the handle */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1392
{
1393
	trx_t*		trx;
1394
641.1.4 by Monty Taylor
Merged in InnoDB changes.
1395
	trx = check_trx_exists(session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1396
1397
	if (prebuilt->trx != trx) {
1398
1399
		row_update_prebuilt_trx(prebuilt, trx);
1400
	}
1401
641.1.4 by Monty Taylor
Merged in InnoDB changes.
1402
	user_session = session;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1403
}
1404
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1405
/*********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1406
Updates the user_thd field in a handle and also allocates a new InnoDB
1407
transaction handle if needed, and updates the transaction fields in the
1408
prebuilt struct. */
1409
UNIV_INTERN
1410
void
641.1.4 by Monty Taylor
Merged in InnoDB changes.
1411
ha_innobase::update_session()
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1412
/*=====================*/
1413
{
641.1.4 by Monty Taylor
Merged in InnoDB changes.
1414
	Session*	session = ha_session();
641.1.5 by Monty Taylor
Merged in innodb plugin 1.0.2
1415
	ut_ad(EQ_CURRENT_SESSION(session));
641.1.4 by Monty Taylor
Merged in InnoDB changes.
1416
	update_session(session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1417
}
1418
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1419
/*********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1420
Registers that InnoDB takes part in an SQL statement, so that MySQL knows to
1421
roll back the statement if the statement results in an error. This MUST be
1422
called for every SQL statement that may be rolled back by MySQL. Calling this
1423
several times to register the same statement is allowed, too. */
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
1424
static inline
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1425
void
1426
innobase_register_stmt(
1427
/*===================*/
1114.1.5 by Monty Taylor
Merged up with trunk.
1428
        drizzled::plugin::StorageEngine*	engine,	/*!< in: Innobase hton */
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
1429
	Session*	session)	/*!< in: MySQL thd (connection) object */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1430
{
960.2.36 by Monty Taylor
More hton renaming.
1431
	assert(engine == innodb_engine_ptr);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1432
	/* Register the statement */
960.2.26 by Monty Taylor
Rename hton to engine.
1433
	trans_register_ha(session, FALSE, engine);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1434
}
1435
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1436
/*********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1437
Registers an InnoDB transaction in MySQL, so that the MySQL XA code knows
1438
to call the InnoDB prepare and commit, or rollback for the transaction. This
1439
MUST be called for every transaction for which the user may call commit or
1440
rollback. Calling this several times to register the same transaction is
1441
allowed, too.
1442
This function also registers the current SQL statement. */
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
1443
static inline
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1444
void
1445
innobase_register_trx_and_stmt(
1446
/*===========================*/
1114.1.5 by Monty Taylor
Merged up with trunk.
1447
        drizzled::plugin::StorageEngine *engine, /*!< in: Innobase StorageEngine */
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
1448
	Session*	session)	/*!< in: MySQL thd (connection) object */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1449
{
1450
	/* NOTE that actually innobase_register_stmt() registers also
1451
	the transaction in the AUTOCOMMIT=1 mode. */
1452
960.2.26 by Monty Taylor
Rename hton to engine.
1453
	innobase_register_stmt(engine, session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1454
641.1.4 by Monty Taylor
Merged in InnoDB changes.
1455
	if (session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1456
1457
		/* No autocommit mode, register for a transaction */
960.2.26 by Monty Taylor
Rename hton to engine.
1458
		trans_register_ha(session, TRUE, engine);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1459
	}
1460
}
1461
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1462
/*****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1463
Convert an SQL identifier to the MySQL system_charset_info (UTF-8)
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1464
and quote it if needed.
1465
@return	pointer to the end of buf */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1466
static
1467
char*
1468
innobase_convert_identifier(
1469
/*========================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1470
	char*		buf,	/*!< out: buffer for converted identifier */
1471
	ulint		buflen,	/*!< in: length of buf, in bytes */
1472
	const char*	id,	/*!< in: identifier to convert */
1473
	ulint		idlen,	/*!< in: length of id, in bytes */
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
1474
	void*		session,/*!< in: MySQL connection thread, or NULL */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1475
	ibool		file_id)/*!< in: TRUE=id is a table or database name;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1476
				FALSE=id is an UTF-8 string */
1477
{
1478
	char nz[NAME_LEN + 1];
1479
	char nz2[NAME_LEN + 1 + sizeof srv_mysql50_table_name_prefix];
1480
1481
	const char*	s	= id;
1482
	int		q;
1483
1484
	if (file_id) {
1485
		/* Decode the table name.  The filename_to_tablename()
1486
		function expects a NUL-terminated string.  The input and
1487
		output strings buffers must not be shared. */
1488
1489
		if (UNIV_UNLIKELY(idlen > (sizeof nz) - 1)) {
1490
			idlen = (sizeof nz) - 1;
1491
		}
1492
1493
		memcpy(nz, id, idlen);
1494
		nz[idlen] = 0;
1495
1496
		s = nz2;
1497
		idlen = filename_to_tablename(nz, nz2, sizeof nz2);
1498
	}
1499
1500
	/* See if the identifier needs to be quoted. */
641.1.4 by Monty Taylor
Merged in InnoDB changes.
1501
	if (UNIV_UNLIKELY(!session)) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1502
		q = '"';
1503
	} else {
1014.3.4 by Brian Aker
Remove dead session calls.
1504
		q = get_quote_char_for_identifier();
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1505
	}
1506
1507
	if (q == EOF) {
1508
		if (UNIV_UNLIKELY(idlen > buflen)) {
1509
			idlen = buflen;
1510
		}
1511
		memcpy(buf, s, idlen);
1512
		return(buf + idlen);
1513
	}
1514
1515
	/* Quote the identifier. */
1516
	if (buflen < 2) {
1517
		return(buf);
1518
	}
1519
1520
	*buf++ = q;
1521
	buflen--;
1522
1523
	for (; idlen; idlen--) {
1524
		int	c = *s++;
1525
		if (UNIV_UNLIKELY(c == q)) {
1526
			if (UNIV_UNLIKELY(buflen < 3)) {
1527
				break;
1528
			}
1529
1530
			*buf++ = c;
1531
			*buf++ = c;
1532
			buflen -= 2;
1533
		} else {
1534
			if (UNIV_UNLIKELY(buflen < 2)) {
1535
				break;
1536
			}
1537
1538
			*buf++ = c;
1539
			buflen--;
1540
		}
1541
	}
1542
1543
	*buf++ = q;
1544
	return(buf);
1545
}
1546
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1547
/*****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1548
Convert a table or index name to the MySQL system_charset_info (UTF-8)
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1549
and quote it if needed.
1550
@return	pointer to the end of buf */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1551
extern "C" UNIV_INTERN
1552
char*
1553
innobase_convert_name(
1554
/*==================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1555
	char*		buf,	/*!< out: buffer for converted identifier */
1556
	ulint		buflen,	/*!< in: length of buf, in bytes */
1557
	const char*	id,	/*!< in: identifier to convert */
1558
	ulint		idlen,	/*!< in: length of id, in bytes */
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
1559
	void*		session,/*!< in: MySQL connection thread, or NULL */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1560
	ibool		table_id)/*!< in: TRUE=id is a table or database name;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1561
				FALSE=id is an index name */
1562
{
1563
	char*		s	= buf;
1564
	const char*	bufend	= buf + buflen;
1565
1566
	if (table_id) {
1567
		const char*	slash = (const char*) memchr(id, '/', idlen);
1568
		if (!slash) {
1569
1570
			goto no_db_name;
1571
		}
1572
1573
		/* Print the database name and table name separately. */
1574
		s = innobase_convert_identifier(s, bufend - s, id, slash - id,
641.1.4 by Monty Taylor
Merged in InnoDB changes.
1575
						session, TRUE);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1576
		if (UNIV_LIKELY(s < bufend)) {
1577
			*s++ = '.';
1578
			s = innobase_convert_identifier(s, bufend - s,
1579
							slash + 1, idlen
1580
							- (slash - id) - 1,
641.1.4 by Monty Taylor
Merged in InnoDB changes.
1581
							session, TRUE);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1582
		}
1583
	} else if (UNIV_UNLIKELY(*id == TEMP_INDEX_PREFIX)) {
1584
		/* Temporary index name (smart ALTER TABLE) */
1585
		const char temp_index_suffix[]= "--temporary--";
1586
1587
		s = innobase_convert_identifier(buf, buflen, id + 1, idlen - 1,
641.1.4 by Monty Taylor
Merged in InnoDB changes.
1588
						session, FALSE);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1589
		if (s - buf + (sizeof temp_index_suffix - 1) < buflen) {
1590
			memcpy(s, temp_index_suffix,
1591
			       sizeof temp_index_suffix - 1);
1592
			s += sizeof temp_index_suffix - 1;
1593
		}
1594
	} else {
1595
no_db_name:
1596
		s = innobase_convert_identifier(buf, buflen, id, idlen,
641.1.4 by Monty Taylor
Merged in InnoDB changes.
1597
						session, table_id);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1598
	}
1599
1600
	return(s);
1601
1602
}
1603
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1604
/**********************************************************************//**
1605
Determines if the currently running transaction has been interrupted.
1606
@return	TRUE if interrupted */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1607
extern "C" UNIV_INTERN
1608
ibool
1609
trx_is_interrupted(
1610
/*===============*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1611
	trx_t*	trx)	/*!< in: transaction */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1612
{
641.1.4 by Monty Taylor
Merged in InnoDB changes.
1613
	return(trx && trx->mysql_thd && session_killed((Session*) trx->mysql_thd));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1614
}
1615
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1616
/**************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1617
Resets some fields of a prebuilt struct. The template is used in fast
1618
retrieval of just those column values MySQL needs in its processing. */
1619
static
1620
void
1621
reset_template(
1622
/*===========*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1623
	row_prebuilt_t*	prebuilt)	/*!< in/out: prebuilt struct */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1624
{
1625
	prebuilt->keep_other_fields_on_keyread = 0;
1626
	prebuilt->read_just_key = 0;
1627
}
1628
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1629
/*****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1630
Call this when you have opened a new table handle in HANDLER, before you
1631
call index_read_idx() etc. Actually, we can let the cursor stay open even
1632
over a transaction commit! Then you should call this before every operation,
1633
fetch next etc. This function inits the necessary things even after a
1634
transaction commit. */
1635
UNIV_INTERN
1636
void
1637
ha_innobase::init_table_handle_for_HANDLER(void)
1638
/*============================================*/
1639
{
641.1.4 by Monty Taylor
Merged in InnoDB changes.
1640
	/* If current session does not yet have a trx struct, create one.
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1641
	If the current handle does not yet have a prebuilt struct, create
1642
	one. Update the trx pointers in the prebuilt struct. Normally
1643
	this operation is done in external_lock. */
1644
641.1.4 by Monty Taylor
Merged in InnoDB changes.
1645
	update_session(ha_session());
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1646
1647
	/* Initialize the prebuilt struct much like it would be inited in
1648
	external_lock */
1649
1650
	innobase_release_stat_resources(prebuilt->trx);
1651
1652
	/* If the transaction is not started yet, start it */
1653
1654
	trx_start_if_not_started(prebuilt->trx);
1655
1656
	/* Assign a read view if the transaction does not have it yet */
1657
1658
	trx_assign_read_view(prebuilt->trx);
1659
1660
	/* Set the MySQL flag to mark that there is an active transaction */
1661
1662
	if (prebuilt->trx->active_trans == 0) {
1663
960.2.37 by Monty Taylor
More naming fixes.
1664
		innobase_register_trx_and_stmt(engine, user_session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1665
1666
		prebuilt->trx->active_trans = 1;
1667
	}
1668
1669
	/* We did the necessary inits in this function, no need to repeat them
1670
	in row_search_for_mysql */
1671
1672
	prebuilt->sql_stat_start = FALSE;
1673
1674
	/* We let HANDLER always to do the reads as consistent reads, even
1675
	if the trx isolation level would have been specified as SERIALIZABLE */
1676
1677
	prebuilt->select_lock_type = LOCK_NONE;
1678
	prebuilt->stored_select_lock_type = LOCK_NONE;
1679
1680
	/* Always fetch all columns in the index record */
1681
1682
	prebuilt->hint_need_to_fetch_extra_cols = ROW_RETRIEVE_ALL_COLS;
1683
1684
	/* We want always to fetch all columns in the whole row? Or do
1685
	we???? */
1686
1687
	prebuilt->used_in_HANDLER = TRUE;
1688
	reset_template(prebuilt);
1689
}
1690
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1691
/*********************************************************************//**
1692
Opens an InnoDB database.
1693
@return	0 on success, error code on failure */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1694
static
1695
int
1696
innobase_init(
1697
/*==========*/
1114.1.5 by Monty Taylor
Merged up with trunk.
1698
	drizzled::plugin::Registry	&registry)	/*!< in: Drizzle Plugin Registry */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1699
{
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1700
	static char	current_dir[3];		/*!< Set if using current lib */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1701
	int		err;
1702
	bool		ret;
1703
	char		*default_path;
1704
	uint		format_id;
1705
971.1.51 by Monty Taylor
New-style plugin registration now works.
1706
	innodb_engine_ptr= new InnobaseEngine(innobase_engine_name);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1707
1708
641.1.4 by Monty Taylor
Merged in InnoDB changes.
1709
	ut_a(DATA_MYSQL_TRUE_VARCHAR == (ulint)DRIZZLE_TYPE_VARCHAR);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1710
1711
#ifdef UNIV_DEBUG
1712
	static const char	test_filename[] = "-@";
1713
	char			test_tablename[sizeof test_filename
1714
				+ sizeof srv_mysql50_table_name_prefix];
1715
	if ((sizeof test_tablename) - 1
1716
			!= filename_to_tablename(test_filename, test_tablename,
1717
			sizeof test_tablename)
1718
			|| strncmp(test_tablename,
1719
			srv_mysql50_table_name_prefix,
1720
			sizeof srv_mysql50_table_name_prefix)
1721
			|| strcmp(test_tablename
1722
			+ sizeof srv_mysql50_table_name_prefix,
1723
			test_filename)) {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
1724
		errmsg_printf(ERRMSG_LVL_ERROR, "tablename encoding has been changed");
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1725
		goto error;
1726
	}
1727
#endif /* UNIV_DEBUG */
1728
1729
	/* Check that values don't overflow on 32-bit systems. */
1730
	if (sizeof(ulint) == 4) {
641.1.4 by Monty Taylor
Merged in InnoDB changes.
1731
		if (innobase_buffer_pool_size > UINT32_MAX) {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
1732
			errmsg_printf(ERRMSG_LVL_ERROR, 
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1733
				"innobase_buffer_pool_size can't be over 4GB"
1734
				" on 32-bit systems");
1735
1736
			goto error;
1737
		}
1738
641.1.4 by Monty Taylor
Merged in InnoDB changes.
1739
		if (innobase_log_file_size > UINT32_MAX) {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
1740
			errmsg_printf(ERRMSG_LVL_ERROR, 
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1741
				"innobase_log_file_size can't be over 4GB"
1742
				" on 32-bit systems");
1743
1744
			goto error;
1745
		}
1746
	}
1747
1748
	os_innodb_umask = (ulint)my_umask;
1749
1750
	/* First calculate the default path for innodb_data_home_dir etc.,
1751
	in case the user has not given any value.
1752
1753
	Note that when using the embedded server, the datadirectory is not
1754
	necessarily the current directory of this program. */
1755
641.1.4 by Monty Taylor
Merged in InnoDB changes.
1756
	/* It's better to use current lib, to keep paths short */
1757
	current_dir[0] = FN_CURLIB;
1758
	current_dir[1] = FN_LIBCHAR;
1759
	current_dir[2] = 0;
1760
	default_path = current_dir;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1761
1762
	ut_a(default_path);
1763
641.1.4 by Monty Taylor
Merged in InnoDB changes.
1764
	srv_set_thread_priorities = TRUE;
1765
	srv_query_thread_priority = QUERY_PRIOR;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1766
1767
	/* Set InnoDB initialization parameters according to the values
1768
	read from MySQL .cnf file */
1769
1770
	/*--------------- Data files -------------------------*/
1771
1772
	/* The default dir for data files is the datadir of MySQL */
1773
1774
	srv_data_home = (innobase_data_home_dir ? innobase_data_home_dir :
1775
			 default_path);
1776
1777
	/* Set default InnoDB data file size to 10 MB and let it be
1778
	auto-extending. Thus users can use InnoDB in >= 4.0 without having
1779
	to specify any startup options. */
1780
1781
	if (!innobase_data_file_path) {
1782
		innobase_data_file_path = (char*) "ibdata1:10M:autoextend";
1783
	}
1784
1785
	/* Since InnoDB edits the argument in the next call, we make another
1786
	copy of it: */
1787
656.1.25 by Monty Taylor
Removed my_malloc stuff from storage/
1788
	internal_innobase_data_file_path = strdup(innobase_data_file_path);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1789
1790
	ret = (bool) srv_parse_data_file_paths_and_sizes(
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
1791
		internal_innobase_data_file_path);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1792
	if (ret == FALSE) {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
1793
		errmsg_printf(ERRMSG_LVL_ERROR, 
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1794
			"InnoDB: syntax error in innodb_data_file_path");
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
1795
mem_free_and_error:
1796
		srv_free_paths_and_sizes();
641.1.4 by Monty Taylor
Merged in InnoDB changes.
1797
		if (internal_innobase_data_file_path)
1798
		  free(internal_innobase_data_file_path);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1799
		goto error;
1800
	}
1801
1802
	/* -------------- Log files ---------------------------*/
1803
1804
	/* The default dir for log files is the datadir of MySQL */
1805
1806
	if (!innobase_log_group_home_dir) {
1807
		innobase_log_group_home_dir = default_path;
1808
	}
1809
1810
#ifdef UNIV_LOG_ARCHIVE
1811
	/* Since innodb_log_arch_dir has no relevance under MySQL,
1812
	starting from 4.0.6 we always set it the same as
1813
	innodb_log_group_home_dir: */
1814
1815
	innobase_log_arch_dir = innobase_log_group_home_dir;
1816
1817
	srv_arch_dir = innobase_log_arch_dir;
1818
#endif /* UNIG_LOG_ARCHIVE */
1819
1820
	ret = (bool)
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
1821
		srv_parse_log_group_home_dirs(innobase_log_group_home_dir);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1822
1823
	if (ret == FALSE || innobase_mirrored_log_groups != 1) {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
1824
	  errmsg_printf(ERRMSG_LVL_ERROR, "syntax error in innodb_log_group_home_dir, or a "
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1825
			  "wrong number of mirrored log groups");
1826
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
1827
		goto mem_free_and_error;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1828
	}
1829
1830
	/* Validate the file format by animal name */
1831
	if (innobase_file_format_name != NULL) {
1832
1833
		format_id = innobase_file_format_name_lookup(
1834
			innobase_file_format_name);
1835
1836
		if (format_id > DICT_TF_FORMAT_MAX) {
1837
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
1838
			errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB: wrong innodb_file_format.");
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1839
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
1840
			goto mem_free_and_error;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1841
		}
1842
	} else {
1843
		/* Set it to the default file format id. Though this
1844
		should never happen. */
1845
		format_id = 0;
1846
	}
1847
1848
	srv_file_format = format_id;
1849
1850
	/* Given the type of innobase_file_format_name we have little
1851
	choice but to cast away the constness from the returned name.
1852
	innobase_file_format_name is used in the MySQL set variable
1853
	interface and so can't be const. */
1854
1855
	innobase_file_format_name = 
1856
		(char*) trx_sys_file_format_id_to_name(format_id);
1857
1858
	/* Process innobase_file_format_check variable */
1859
	ut_a(innobase_file_format_check != NULL);
1860
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
1861
	/* As a side effect it will set srv_check_file_format_at_startup
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1862
	on valid input. First we check for "on"/"off". */
1863
	if (!innobase_file_format_check_on_off(innobase_file_format_check)) {
1864
1865
		/* Did the user specify a format name that we support ?
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
1866
		As a side effect it will update the variable
1867
		srv_check_file_format_at_startup */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1868
		if (!innobase_file_format_check_validate(
1869
			innobase_file_format_check)) {
1870
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
1871
			errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB: invalid "
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1872
					"innodb_file_format_check value: "
1873
					"should be either 'on' or 'off' or "
1874
					"any value up to %s or its "
1875
					"equivalent numeric id",
1876
					trx_sys_file_format_id_to_name(
1877
						DICT_TF_FORMAT_MAX));
1878
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
1879
			goto mem_free_and_error;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1880
		}
1881
	}
1882
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1883
	if (innobase_change_buffering) {
1884
		ulint	use;
1885
1886
		for (use = 0;
1887
		     use < UT_ARR_SIZE(innobase_change_buffering_values);
1888
		     use++) {
1889
			if (!innobase_strcasecmp(
1890
				    innobase_change_buffering,
1891
				    innobase_change_buffering_values[use])) {
1892
				ibuf_use = (ibuf_use_t) use;
1893
				goto innobase_change_buffering_inited_ok;
1894
			}
1895
		}
1896
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
1897
		errmsg_printf(ERRMSG_LVL_ERROR,
1898
				"InnoDB: invalid value "
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1899
				"innodb_file_format_check=%s",
1900
				innobase_change_buffering);
1901
		goto mem_free_and_error;
1902
	}
1903
1904
innobase_change_buffering_inited_ok:
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
1905
	ut_a((ulint) ibuf_use < UT_ARR_SIZE(innobase_change_buffering_values));
1906
	innobase_change_buffering = (char*)
1907
		innobase_change_buffering_values[ibuf_use];
1908
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1909
	/* --------------------------------------------------*/
1910
1911
	srv_file_flush_method_str = innobase_unix_file_flush_method;
1912
1913
	srv_n_log_groups = (ulint) innobase_mirrored_log_groups;
1914
	srv_n_log_files = (ulint) innobase_log_files_in_group;
1915
	srv_log_file_size = (ulint) innobase_log_file_size;
1916
1917
#ifdef UNIV_LOG_ARCHIVE
1918
	srv_log_archive_on = (ulint) innobase_log_archive;
1919
#endif /* UNIV_LOG_ARCHIVE */
1920
	srv_log_buffer_size = (ulint) innobase_log_buffer_size;
1921
1922
	srv_buf_pool_size = (ulint) innobase_buffer_pool_size;
1923
1924
	srv_mem_pool_size = (ulint) innobase_additional_mem_pool_size;
1925
1926
	srv_n_file_io_threads = (ulint) innobase_file_io_threads;
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1927
	srv_n_read_io_threads = (ulint) innobase_read_io_threads;
1928
	srv_n_write_io_threads = (ulint) innobase_write_io_threads;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1929
1930
	srv_force_recovery = (ulint) innobase_force_recovery;
1931
1932
	srv_use_doublewrite_buf = (ibool) innobase_use_doublewrite;
1933
	srv_use_checksums = (ibool) innobase_use_checksums;
1934
1935
#ifdef HAVE_LARGE_PAGES
1936
        if ((os_use_large_pages = (ibool) my_use_large_pages))
1937
		os_large_page_size = (ulint) opt_large_page_size;
1938
#endif
1939
1940
	row_rollback_on_timeout = (ibool) innobase_rollback_on_timeout;
1941
1942
	srv_locks_unsafe_for_binlog = (ibool) innobase_locks_unsafe_for_binlog;
1943
1944
	srv_max_n_open_files = (ulint) innobase_open_files;
1945
	srv_innodb_status = (ibool) innobase_create_status_file;
1946
641.1.4 by Monty Taylor
Merged in InnoDB changes.
1947
	srv_print_verbose_log = true;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1948
1949
	/* Store the default charset-collation number of this MySQL
1950
	installation */
1951
1952
	data_mysql_default_charset_coll = (ulint)default_charset_info->number;
1953
1954
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1955
	innobase_commit_concurrency_init_default();
1956
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1957
	/* Since we in this module access directly the fields of a trx
1958
	struct, and due to different headers and flags it might happen that
1959
	mutex_t has a different size in this module and in InnoDB
1960
	modules, we check at run time that the size is the same in
1961
	these compilation modules. */
1962
1963
	err = innobase_start_or_create_for_mysql();
1964
1965
	if (err != DB_SUCCESS) {
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
1966
		goto mem_free_and_error;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1967
	}
1968
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
1969
	innobase_open_tables = hash_create(200);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1970
	pthread_mutex_init(&innobase_share_mutex, MY_MUTEX_INIT_FAST);
1971
	pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST);
1972
	pthread_mutex_init(&commit_threads_m, MY_MUTEX_INIT_FAST);
1973
	pthread_mutex_init(&commit_cond_m, MY_MUTEX_INIT_FAST);
1974
	pthread_cond_init(&commit_cond, NULL);
1975
	innodb_inited= 1;
960.2.32 by Monty Taylor
Converted Innodb handlerton.
1976
971.1.65 by Monty Taylor
Changed plugin registration of I_S tables in innodb.
1977
	if (innodb_locks_init() ||
1978
		innodb_trx_init() ||
1979
		innodb_lock_waits_init() ||
1980
		i_s_cmp_init() ||
1981
		i_s_cmp_reset_init() ||
1982
		i_s_cmpmem_init() ||
1983
		i_s_cmpmem_reset_init())
1984
		goto error;
1985
1130.1.8 by Monty Taylor
Added polymorphic add/remove methods around slot add/remove methods.
1986
	registry.add(innodb_engine_ptr);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1987
1130.1.8 by Monty Taylor
Added polymorphic add/remove methods around slot add/remove methods.
1988
	registry.add(innodb_trx_schema_table);
1989
	registry.add(innodb_locks_schema_table);
1990
	registry.add(innodb_lock_waits_schema_table);	
1991
	registry.add(innodb_cmp_schema_table);
1992
	registry.add(innodb_cmp_reset_schema_table);
1993
	registry.add(innodb_cmpmem_schema_table);
1994
	registry.add(innodb_cmpmem_reset_schema_table);
971.1.65 by Monty Taylor
Changed plugin registration of I_S tables in innodb.
1995
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1996
	/* Get the current high water mark format. */
1997
	innobase_file_format_check = (char*) trx_sys_file_format_max_get();
1998
641.1.4 by Monty Taylor
Merged in InnoDB changes.
1999
	return(FALSE);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2000
error:
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2001
	return(TRUE);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2002
}
2003
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2004
/*******************************************************************//**
2005
Closes an InnoDB database.
2006
@return	TRUE if error */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2007
static
2008
int
1110.1.5 by Monty Taylor
Renamed PluginRegistry to plugin::Registry.
2009
innobase_deinit(drizzled::plugin::Registry &registry)
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2010
{
2011
	int	err= 0;
971.1.65 by Monty Taylor
Changed plugin registration of I_S tables in innodb.
2012
	i_s_common_deinit(registry);
1130.1.8 by Monty Taylor
Added polymorphic add/remove methods around slot add/remove methods.
2013
	registry.remove(innodb_engine_ptr);
971.1.51 by Monty Taylor
New-style plugin registration now works.
2014
 	delete innodb_engine_ptr;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2015
2016
	if (innodb_inited) {
2017
2018
		srv_fast_shutdown = (ulint) innobase_fast_shutdown;
2019
		innodb_inited = 0;
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
2020
		hash_table_free(innobase_open_tables);
2021
		innobase_open_tables = NULL;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2022
		if (innobase_shutdown_for_mysql() != DB_SUCCESS) {
2023
			err = 1;
2024
		}
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
2025
		srv_free_paths_and_sizes();
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2026
		if (internal_innobase_data_file_path)
2027
		  free(internal_innobase_data_file_path);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2028
		pthread_mutex_destroy(&innobase_share_mutex);
2029
		pthread_mutex_destroy(&prepare_commit_mutex);
2030
		pthread_mutex_destroy(&commit_threads_m);
2031
		pthread_mutex_destroy(&commit_cond_m);
2032
		pthread_cond_destroy(&commit_cond);
2033
	}
2034
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2035
	return(err);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2036
}
2037
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2038
/****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2039
Flushes InnoDB logs to disk and makes a checkpoint. Really, a commit flushes
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2040
the logs, and the name of this function should be innobase_checkpoint.
2041
@return	TRUE if error */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2042
bool
960.2.38 by Monty Taylor
Removed extraneous send myself to myself argument.
2043
InnobaseEngine::flush_logs()
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2044
/*=====================*/
2045
{
2046
	bool	result = 0;
2047
960.2.38 by Monty Taylor
Removed extraneous send myself to myself argument.
2048
	assert(this == innodb_engine_ptr);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2049
2050
	log_buffer_flush_to_disk();
2051
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2052
	return(result);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2053
}
2054
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2055
/*****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2056
Commits a transaction in an InnoDB database. */
2057
static
2058
void
2059
innobase_commit_low(
2060
/*================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2061
	trx_t*	trx)	/*!< in: transaction handle */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2062
{
2063
	if (trx->conc_state == TRX_NOT_STARTED) {
2064
2065
		return;
2066
	}
2067
2068
	trx_commit_for_mysql(trx);
2069
}
2070
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2071
/*****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2072
Creates an InnoDB transaction struct for the thd if it does not yet have one.
2073
Starts a new InnoDB transaction if a transaction is not yet started. And
2074
assigns a new snapshot for a consistent read if the transaction does not yet
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2075
have one.
2076
@return	0 */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2077
int
960.2.32 by Monty Taylor
Converted Innodb handlerton.
2078
InnobaseEngine::start_consistent_snapshot(
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2079
/*====================================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
2080
	Session*	session)	/*!< in: MySQL thread handle of the user for whom
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2081
			the transaction should be committed */
2082
{
2083
	trx_t*	trx;
2084
960.2.38 by Monty Taylor
Removed extraneous send myself to myself argument.
2085
	assert(this == innodb_engine_ptr);
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2086
2087
	/* Create a new trx struct for session, if it does not yet have one */
2088
2089
	trx = check_trx_exists(session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2090
2091
	/* This is just to play safe: release a possible FIFO ticket and
2092
	search latch. Since we will reserve the kernel mutex, we have to
2093
	release the search system latch first to obey the latching order. */
2094
2095
	innobase_release_stat_resources(trx);
2096
2097
	/* If the transaction is not started yet, start it */
2098
2099
	trx_start_if_not_started(trx);
2100
2101
	/* Assign a read view if the transaction does not have it yet */
2102
2103
	trx_assign_read_view(trx);
2104
2105
	/* Set the MySQL flag to mark that there is an active transaction */
2106
2107
	if (trx->active_trans == 0) {
960.2.38 by Monty Taylor
Removed extraneous send myself to myself argument.
2108
		innobase_register_trx_and_stmt(this, current_session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2109
		trx->active_trans = 1;
2110
	}
2111
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2112
	return(0);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2113
}
2114
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2115
/*****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2116
Commits a transaction in an InnoDB database or marks an SQL statement
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2117
ended.
2118
@return	0 */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2119
int
960.2.32 by Monty Taylor
Converted Innodb handlerton.
2120
InnobaseEngine::commit(
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2121
/*============*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
2122
	Session* 	session,	/*!< in: MySQL thread handle of the user for whom
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2123
			the transaction should be committed */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2124
	bool	all)	/*!< in:	TRUE - commit transaction
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2125
				FALSE - the current SQL statement ended */
2126
{
2127
	trx_t*		trx;
2128
960.2.38 by Monty Taylor
Removed extraneous send myself to myself argument.
2129
	assert(this == innodb_engine_ptr);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2130
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2131
	trx = check_trx_exists(session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2132
2133
	/* Since we will reserve the kernel mutex, we have to release
2134
	the search system latch first to obey the latching order. */
2135
2136
	if (trx->has_search_latch) {
2137
		trx_search_latch_release_if_reserved(trx);
2138
	}
2139
2140
	/* The flag trx->active_trans is set to 1 in
2141
2142
	1. ::external_lock(),
2143
	2. ::start_stmt(),
2144
	3. innobase_query_caching_of_table_permitted(),
960.2.32 by Monty Taylor
Converted Innodb handlerton.
2145
	4. InnobaseEngine::savepoint_set(),
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2146
	5. ::init_table_handle_for_HANDLER(),
960.2.32 by Monty Taylor
Converted Innodb handlerton.
2147
	6. InnobaseEngine::start_consistent_snapshot(),
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2148
2149
	and it is only set to 0 in a commit or a rollback. If it is 0 we know
2150
	there cannot be resources to be freed and we could return immediately.
2151
	For the time being, we play safe and do the cleanup though there should
2152
	be nothing to clean up. */
2153
2154
	if (trx->active_trans == 0
2155
		&& trx->conc_state != TRX_NOT_STARTED) {
2156
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
2157
		errmsg_printf(ERRMSG_LVL_ERROR, "trx->active_trans == 0, but"
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2158
			" trx->conc_state != TRX_NOT_STARTED");
2159
	}
2160
	if (all
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2161
		|| (!session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2162
2163
		/* We were instructed to commit the whole transaction, or
2164
		this is an SQL statement end and autocommit is on */
2165
2166
		/* We need current binlog position for ibbackup to work.
2167
		Note, the position is current because of
2168
		prepare_commit_mutex */
2169
retry:
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2170
		if (innobase_commit_concurrency > 0) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2171
			pthread_mutex_lock(&commit_cond_m);
2172
			commit_threads++;
2173
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2174
			if (commit_threads > innobase_commit_concurrency) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2175
				commit_threads--;
2176
				pthread_cond_wait(&commit_cond,
2177
					&commit_cond_m);
2178
				pthread_mutex_unlock(&commit_cond_m);
2179
				goto retry;
2180
			}
2181
			else {
2182
				pthread_mutex_unlock(&commit_cond_m);
2183
			}
2184
		}
2185
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
2186
                /* Store transaction point for binlog
2187
		Later logic tests that this is set to _something_. We need
2188
		that logic to fire, even though we do not have a real name. */
2189
		trx->mysql_log_file_name = "UNUSED";
798.2.31 by Brian Aker
Vast majority of the replication code removed, new plugin points now
2190
		trx->mysql_log_offset = 0;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2191
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2192
		/* Don't do write + flush right now. For group commit
2193
		to work we want to do the flush after releasing the
2194
		prepare_commit_mutex. */
2195
		trx->flush_log_later = TRUE;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2196
		innobase_commit_low(trx);
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2197
		trx->flush_log_later = FALSE;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2198
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2199
		if (innobase_commit_concurrency > 0) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2200
			pthread_mutex_lock(&commit_cond_m);
2201
			commit_threads--;
2202
			pthread_cond_signal(&commit_cond);
2203
			pthread_mutex_unlock(&commit_cond_m);
2204
		}
2205
2206
		if (trx->active_trans == 2) {
2207
2208
			pthread_mutex_unlock(&prepare_commit_mutex);
2209
		}
2210
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2211
		/* Now do a write + flush of logs. */
2212
		trx_commit_complete_for_mysql(trx);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2213
		trx->active_trans = 0;
2214
2215
	} else {
2216
		/* We just mark the SQL statement ended and do not do a
2217
		transaction commit */
2218
2219
		/* If we had reserved the auto-inc lock for some
2220
		table in this SQL statement we release it now */
2221
2222
		row_unlock_table_autoinc_for_mysql(trx);
2223
2224
		/* Store the current undo_no of the transaction so that we
2225
		know where to roll back if we have to roll back the next
2226
		SQL statement */
2227
2228
		trx_mark_sql_stat_end(trx);
2229
	}
2230
2231
	trx->n_autoinc_rows = 0; /* Reset the number AUTO-INC rows required */
2232
2233
	if (trx->declared_to_be_inside_innodb) {
2234
		/* Release our possible ticket in the FIFO */
2235
2236
		srv_conc_force_exit_innodb(trx);
2237
	}
2238
2239
	/* Tell the InnoDB server that there might be work for utility
2240
	threads: */
2241
	srv_active_wake_master_thread();
2242
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2243
	return(0);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2244
}
2245
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2246
/*****************************************************************//**
2247
Rolls back a transaction or the latest SQL statement.
2248
@return	0 or error number */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2249
int
960.2.32 by Monty Taylor
Converted Innodb handlerton.
2250
InnobaseEngine::rollback(
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2251
/*==============*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
2252
	Session*	session,/*!< in: handle to the MySQL thread of the user
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2253
			whose transaction should be rolled back */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2254
	bool	all)	/*!< in:	TRUE - commit transaction
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2255
				FALSE - the current SQL statement ended */
2256
{
2257
	int	error = 0;
2258
	trx_t*	trx;
2259
960.2.38 by Monty Taylor
Removed extraneous send myself to myself argument.
2260
	assert(this == innodb_engine_ptr);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2261
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2262
	trx = check_trx_exists(session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2263
2264
	/* Release a possible FIFO ticket and search latch. Since we will
2265
	reserve the kernel mutex, we have to release the search system latch
2266
	first to obey the latching order. */
2267
2268
	innobase_release_stat_resources(trx);
2269
2270
	/* If we had reserved the auto-inc lock for some table (if
2271
	we come here to roll back the latest SQL statement) we
2272
	release it now before a possibly lengthy rollback */
2273
2274
	row_unlock_table_autoinc_for_mysql(trx);
2275
2276
	if (all
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2277
		|| !session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2278
2279
		error = trx_rollback_for_mysql(trx);
2280
		trx->active_trans = 0;
2281
	} else {
2282
		error = trx_rollback_last_sql_stat_for_mysql(trx);
2283
	}
2284
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2285
	return(convert_error_code_to_mysql(error, 0, NULL));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2286
}
2287
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2288
/*****************************************************************//**
2289
Rolls back a transaction
2290
@return	0 or error number */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2291
static
2292
int
2293
innobase_rollback_trx(
2294
/*==================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2295
	trx_t*	trx)	/*!< in: transaction */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2296
{
2297
	int	error = 0;
2298
2299
	/* Release a possible FIFO ticket and search latch. Since we will
2300
	reserve the kernel mutex, we have to release the search system latch
2301
	first to obey the latching order. */
2302
2303
	innobase_release_stat_resources(trx);
2304
2305
	/* If we had reserved the auto-inc lock for some table (if
2306
	we come here to roll back the latest SQL statement) we
2307
	release it now before a possibly lengthy rollback */
2308
2309
	row_unlock_table_autoinc_for_mysql(trx);
2310
2311
	error = trx_rollback_for_mysql(trx);
2312
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2313
	return(convert_error_code_to_mysql(error, 0, NULL));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2314
}
2315
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2316
/*****************************************************************//**
2317
Rolls back a transaction to a savepoint.
2318
@return 0 if success, HA_ERR_NO_SAVEPOINT if no savepoint with the
2319
given name */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2320
int
964.1.6 by Monty Taylor
Moved savepoint stuff to protected virtual methods, moved the offset to private, and moved the logic about adding the offset to the passed-in pointer and adding the offset to the global offset inside of the class.
2321
InnobaseEngine::savepoint_rollback_hook(
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2322
/*===========================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
2323
	Session*	session,		/*!< in: handle to the MySQL thread of the user
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2324
				whose transaction should be rolled back */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2325
	void*	savepoint)	/*!< in: savepoint data */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2326
{
2327
	ib_int64_t	mysql_binlog_cache_pos;
2328
	int		error = 0;
2329
	trx_t*		trx;
960.2.32 by Monty Taylor
Converted Innodb handlerton.
2330
	char		sp_name[64];
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2331
960.2.38 by Monty Taylor
Removed extraneous send myself to myself argument.
2332
	assert(this == innodb_engine_ptr);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2333
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2334
	trx = check_trx_exists(session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2335
2336
	/* Release a possible FIFO ticket and search latch. Since we will
2337
	reserve the kernel mutex, we have to release the search system latch
2338
	first to obey the latching order. */
2339
2340
	innobase_release_stat_resources(trx);
2341
2342
	/* TODO: use provided savepoint data area to store savepoint data */
2343
960.2.32 by Monty Taylor
Converted Innodb handlerton.
2344
	int64_t2str((ulint)savepoint, sp_name, 36);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2345
960.2.32 by Monty Taylor
Converted Innodb handlerton.
2346
	error = (int) trx_rollback_to_savepoint_for_mysql(trx, sp_name,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2347
						&mysql_binlog_cache_pos);
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2348
	return(convert_error_code_to_mysql(error, 0, NULL));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2349
}
2350
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2351
/*****************************************************************//**
2352
Release transaction savepoint name.
2353
@return 0 if success, HA_ERR_NO_SAVEPOINT if no savepoint with the
2354
given name */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2355
int
964.1.6 by Monty Taylor
Moved savepoint stuff to protected virtual methods, moved the offset to private, and moved the logic about adding the offset to the passed-in pointer and adding the offset to the global offset inside of the class.
2356
InnobaseEngine::savepoint_release_hook(
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2357
/*=======================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
2358
	Session*	session,		/*!< in: handle to the MySQL thread of the user
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2359
				whose transaction should be rolled back */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2360
	void*	savepoint)	/*!< in: savepoint data */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2361
{
2362
	int		error = 0;
2363
	trx_t*		trx;
960.2.32 by Monty Taylor
Converted Innodb handlerton.
2364
	char		sp_name[64];
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2365
960.2.38 by Monty Taylor
Removed extraneous send myself to myself argument.
2366
	assert(this == innodb_engine_ptr);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2367
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2368
	trx = check_trx_exists(session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2369
2370
	/* TODO: use provided savepoint data area to store savepoint data */
2371
960.2.32 by Monty Taylor
Converted Innodb handlerton.
2372
	int64_t2str((ulint)savepoint, sp_name, 36);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2373
960.2.32 by Monty Taylor
Converted Innodb handlerton.
2374
	error = (int) trx_release_savepoint_for_mysql(trx, sp_name);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2375
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2376
	return(convert_error_code_to_mysql(error, 0, NULL));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2377
}
2378
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2379
/*****************************************************************//**
2380
Sets a transaction savepoint.
2381
@return	always 0, that is, always succeeds */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2382
int
964.1.6 by Monty Taylor
Moved savepoint stuff to protected virtual methods, moved the offset to private, and moved the logic about adding the offset to the passed-in pointer and adding the offset to the global offset inside of the class.
2383
InnobaseEngine::savepoint_set_hook(
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2384
/*===============*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
2385
	Session*	session,/*!< in: handle to the MySQL thread */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2386
	void*	savepoint)	/*!< in: savepoint data */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2387
{
2388
	int	error = 0;
2389
	trx_t*	trx;
2390
960.2.38 by Monty Taylor
Removed extraneous send myself to myself argument.
2391
	assert(this == innodb_engine_ptr);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2392
2393
	/*
2394
	  In the autocommit mode there is no sense to set a savepoint
2395
	  (unless we are in sub-statement), so SQL layer ensures that
2396
	  this method is never called in such situation.
2397
	*/
2398
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2399
	trx = check_trx_exists(session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2400
2401
	/* Release a possible FIFO ticket and search latch. Since we will
2402
	reserve the kernel mutex, we have to release the search system latch
2403
	first to obey the latching order. */
2404
2405
	innobase_release_stat_resources(trx);
2406
2407
	/* cannot happen outside of transaction */
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2408
	assert(trx->active_trans);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2409
2410
	/* TODO: use provided savepoint data area to store savepoint data */
960.2.32 by Monty Taylor
Converted Innodb handlerton.
2411
	char sp_name[64];
2412
	int64_t2str((ulint)savepoint,sp_name,36);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2413
960.2.32 by Monty Taylor
Converted Innodb handlerton.
2414
	error = (int) trx_savepoint_for_mysql(trx, sp_name, (ib_int64_t)0);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2415
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2416
	return(convert_error_code_to_mysql(error, 0, NULL));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2417
}
2418
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2419
/*****************************************************************//**
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
2420
Frees a possible InnoDB trx object associated with the current Session.
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2421
@return	0 or error number */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2422
int
960.2.32 by Monty Taylor
Converted Innodb handlerton.
2423
InnobaseEngine::close_connection(
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2424
/*======================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
2425
	Session*	session)/*!< in: handle to the MySQL thread of the user
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2426
			whose resources should be free'd */
2427
{
2428
	trx_t*	trx;
2429
960.2.38 by Monty Taylor
Removed extraneous send myself to myself argument.
2430
	assert(this == innodb_engine_ptr);
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2431
	trx = session_to_trx(session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2432
2433
	ut_a(trx);
2434
2435
	if (trx->active_trans == 0
2436
		&& trx->conc_state != TRX_NOT_STARTED) {
2437
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
2438
		errmsg_printf(ERRMSG_LVL_ERROR, "trx->active_trans == 0, but"
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2439
			" trx->conc_state != TRX_NOT_STARTED");
2440
	}
2441
2442
2443
	if (trx->conc_state != TRX_NOT_STARTED &&
2444
		global_system_variables.log_warnings) {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
2445
		errmsg_printf(ERRMSG_LVL_WARN, 
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2446
			"MySQL is closing a connection that has an active "
2447
			"InnoDB transaction.  %lu row modifications will "
2448
			"roll back.",
2449
			(ulong) trx->undo_no.low);
2450
	}
2451
2452
	innobase_rollback_trx(trx);
2453
2454
	thr_local_free(trx->mysql_thread_id);
2455
	trx_free_for_mysql(trx);
2456
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2457
	return(0);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2458
}
2459
2460
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2461
/*************************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2462
** InnoDB database tables
2463
*****************************************************************************/
2464
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2465
/****************************************************************//**
2466
Get the record format from the data dictionary.
2467
@return one of ROW_TYPE_REDUNDANT, ROW_TYPE_COMPACT,
2468
ROW_TYPE_COMPRESSED, ROW_TYPE_DYNAMIC */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2469
UNIV_INTERN
2470
enum row_type
2471
ha_innobase::get_row_type() const
2472
/*=============================*/
2473
{
2474
	if (prebuilt && prebuilt->table) {
2475
		const ulint	flags = prebuilt->table->flags;
2476
2477
		if (UNIV_UNLIKELY(!flags)) {
2478
			return(ROW_TYPE_REDUNDANT);
2479
		}
2480
2481
		ut_ad(flags & DICT_TF_COMPACT);
2482
2483
		switch (flags & DICT_TF_FORMAT_MASK) {
2484
		case DICT_TF_FORMAT_51 << DICT_TF_FORMAT_SHIFT:
2485
			return(ROW_TYPE_COMPACT);
2486
		case DICT_TF_FORMAT_ZIP << DICT_TF_FORMAT_SHIFT:
2487
			if (flags & DICT_TF_ZSSIZE_MASK) {
2488
				return(ROW_TYPE_COMPRESSED);
2489
			} else {
2490
				return(ROW_TYPE_DYNAMIC);
2491
			}
2492
#if DICT_TF_FORMAT_ZIP != DICT_TF_FORMAT_MAX
2493
# error "DICT_TF_FORMAT_ZIP != DICT_TF_FORMAT_MAX"
2494
#endif
2495
		}
2496
	}
2497
	ut_ad(0);
2498
	return(ROW_TYPE_NOT_USED);
2499
}
2500
2501
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2502
/****************************************************************//**
2503
Returns the index type. */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2504
UNIV_INTERN
2505
const char*
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2506
ha_innobase::index_type(
2507
/*====================*/
2508
	uint)
2509
				/*!< out: index type */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2510
{
2511
	return("BTREE");
2512
}
2513
2514
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2515
/****************************************************************//**
2516
Returns the operations supported for indexes.
2517
@return	flags of supported operations */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2518
UNIV_INTERN
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2519
uint32_t
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2520
ha_innobase::index_flags(
2521
/*=====================*/
2522
	uint,
2523
	uint,
2524
	bool)
2525
const
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2526
{
2527
	return(HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER
2528
	       | HA_READ_RANGE | HA_KEYREAD_ONLY);
2529
}
2530
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2531
/****************************************************************//**
2532
Returns the maximum number of keys.
2533
@return	MAX_KEY */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2534
UNIV_INTERN
2535
uint
2536
ha_innobase::max_supported_keys() const
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2537
/*===================================*/
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2538
{
2539
	return(MAX_KEY);
2540
}
2541
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2542
/****************************************************************//**
2543
Returns the maximum key length.
2544
@return	maximum supported key length, in bytes */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2545
UNIV_INTERN
869.1.19 by Stewart Smith
small semantic fix in innodb handler for handler method return types.
2546
uint32_t
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2547
ha_innobase::max_supported_key_length() const
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2548
/*=========================================*/
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2549
{
2550
	/* An InnoDB page must store >= 2 keys; a secondary key record
2551
	must also contain the primary key value: max key length is
2552
	therefore set to slightly less than 1 / 4 of page size which
2553
	is 16 kB; but currently MySQL does not work with keys whose
2554
	size is > MAX_KEY_LENGTH */
2555
	return(3500);
2556
}
2557
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2558
/****************************************************************//**
2559
Returns the key map of keys that are usable for scanning.
2560
@return	key_map_full */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2561
UNIV_INTERN
2562
const key_map*
2563
ha_innobase::keys_to_use_for_scanning()
2564
{
2565
	return(&key_map_full);
2566
}
2567
2568
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2569
/****************************************************************//**
2570
Determines if the primary key is clustered index.
2571
@return	true */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2572
UNIV_INTERN
2573
bool
2574
ha_innobase::primary_key_is_clustered()
2575
{
2576
	return(true);
2577
}
2578
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2579
/*****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2580
Normalizes a table name string. A normalized name consists of the
2581
database name catenated to '/' and table name. An example:
2582
test/mytable. On Windows normalization puts both the database name and the
2583
table name always to lower case. */
2584
static
2585
void
2586
normalize_table_name(
2587
/*=================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2588
	char*		norm_name,	/*!< out: normalized name as a
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2589
					null-terminated string */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2590
	const char*	name)		/*!< in: table name string */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2591
{
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2592
	const char*	name_ptr;
2593
	const char*	db_ptr;
2594
	const char*	ptr;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2595
2596
	/* Scan name from the end */
2597
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2598
	ptr = strchr(name, '\0')-1;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2599
2600
	while (ptr >= name && *ptr != '\\' && *ptr != '/') {
2601
		ptr--;
2602
	}
2603
2604
	name_ptr = ptr + 1;
2605
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2606
	assert(ptr > name);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2607
2608
	ptr--;
2609
2610
	while (ptr >= name && *ptr != '\\' && *ptr != '/') {
2611
		ptr--;
2612
	}
2613
2614
	db_ptr = ptr + 1;
2615
2616
	memcpy(norm_name, db_ptr, strlen(name) + 1 - (db_ptr - name));
2617
2618
	norm_name[name_ptr - db_ptr - 1] = '/';
2619
2620
#ifdef __WIN__
2621
	innobase_casedn_str(norm_name);
2622
#endif
2623
}
2624
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2625
/********************************************************************//**
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
2626
Set the autoinc column max value. This should only be called once from
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2627
ha_innobase::open(). Therefore there's no need for a covering lock.
2628
@return	DB_SUCCESS or error code */
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
2629
UNIV_INTERN
2630
ulint
2631
ha_innobase::innobase_initialize_autoinc()
2632
/*======================================*/
2633
{
2634
	dict_index_t*	index;
641.1.5 by Monty Taylor
Merged in innodb plugin 1.0.2
2635
	uint64_t	auto_inc;
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
2636
	const char*	col_name;
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2637
	ulint		error;
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
2638
2639
	col_name = table->found_next_number_field->field_name;
2640
	index = innobase_get_index(table->s->next_number_index);
2641
2642
	/* Execute SELECT MAX(col_name) FROM TABLE; */
2643
	error = row_search_max_autoinc(index, col_name, &auto_inc);
2644
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2645
	switch (error) {
2646
	case DB_SUCCESS:
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
2647
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2648
		/* At the this stage we don't know the increment
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
2649
		or the offset, so use default inrement of 1. */
2650
		++auto_inc;
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2651
		break;
2652
2653
	case DB_RECORD_NOT_FOUND:
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
2654
		ut_print_timestamp(stderr);
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2655
		fprintf(stderr, "  InnoDB: MySQL and InnoDB data "
2656
			"dictionaries are out of sync.\n"
2657
			"InnoDB: Unable to find the AUTOINC column %s in the "
2658
			"InnoDB table %s.\n"
2659
			"InnoDB: We set the next AUTOINC column value to the "
2660
			"maximum possible value,\n"
2661
			"InnoDB: in effect disabling the AUTOINC next value "
2662
			"generation.\n"
2663
			"InnoDB: You can either set the next AUTOINC value "
2664
			"explicitly using ALTER TABLE\n"
2665
			"InnoDB: or fix the data dictionary by recreating "
2666
			"the table.\n",
2667
			col_name, index->table->name);
2668
2669
		auto_inc = 0xFFFFFFFFFFFFFFFFULL;
2670
		break;
2671
2672
	default:
2673
		return(error);
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
2674
	}
2675
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2676
	dict_table_autoinc_initialize(prebuilt->table, auto_inc);
2677
2678
	return(DB_SUCCESS);
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
2679
}
2680
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2681
/*****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2682
Creates and opens a handle to a table which already exists in an InnoDB
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2683
database.
2684
@return	1 if error, 0 if success */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2685
UNIV_INTERN
2686
int
2687
ha_innobase::open(
2688
/*==============*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2689
	const char*	name,		/*!< in: table name */
2690
	int		mode,		/*!< in: not used */
2691
	uint		test_if_locked)	/*!< in: not used */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2692
{
2693
	dict_table_t*	ib_table;
2694
	char		norm_name[1000];
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2695
	Session*		session;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2696
	ulint		retries = 0;
2697
	char*		is_part = NULL;
2698
2699
	UT_NOT_USED(mode);
2700
	UT_NOT_USED(test_if_locked);
2701
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2702
	session = ha_session();
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
2703
641.1.5 by Monty Taylor
Merged in innodb plugin 1.0.2
2704
	/* Under some cases Drizzle seems to call this function while
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
2705
	holding btr_search_latch. This breaks the latching order as
2706
	we acquire dict_sys->mutex below and leads to a deadlock. */
641.1.5 by Monty Taylor
Merged in innodb plugin 1.0.2
2707
	if (session != NULL) {
960.2.38 by Monty Taylor
Removed extraneous send myself to myself argument.
2708
		engine->release_temporary_latches(session);
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
2709
	}
2710
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2711
	normalize_table_name(norm_name, name);
2712
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2713
	user_session = NULL;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2714
2715
	if (!(share=get_share(name))) {
2716
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2717
		return(1);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2718
	}
2719
2720
	/* Create buffers for packing the fields of a record. Why
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2721
	table->stored_rec_length did not work here? Obviously, because char
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2722
	fields when packed actually became 1 byte longer, when we also
2723
	stored the string length as the first byte. */
2724
2725
	upd_and_key_val_buff_len =
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2726
				table->s->stored_rec_length
2727
				+ table->s->max_key_length
2728
				+ MAX_REF_PARTS * 3;
1130.3.1 by Monty Taylor
Moved multi_malloc into drizzled since it's not going away any time soon. Also,
2729
	if (!(unsigned char*) drizzled::memory::multi_malloc(false,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2730
			&upd_buff, upd_and_key_val_buff_len,
2731
			&key_val_buff, upd_and_key_val_buff_len,
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2732
			NULL)) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2733
		free_share(share);
2734
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2735
		return(1);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2736
	}
2737
2738
	/* We look for pattern #P# to see if the table is partitioned
2739
	MySQL table. The retry logic for partitioned tables is a
2740
	workaround for http://bugs.mysql.com/bug.php?id=33349. Look
2741
	at support issue https://support.mysql.com/view.php?id=21080
2742
	for more details. */
2743
	is_part = strstr(norm_name, "#P#");
2744
retry:
2745
	/* Get pointer to a table object in InnoDB dictionary cache */
2746
	ib_table = dict_table_get(norm_name, TRUE);
2747
	
2748
	if (NULL == ib_table) {
2749
		if (is_part && retries < 10) {
2750
			++retries;
2751
			os_thread_sleep(100000);
2752
			goto retry;
2753
		}
2754
2755
		if (is_part) {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
2756
			errmsg_printf(ERRMSG_LVL_ERROR, "Failed to open table %s after "
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2757
					"%lu attemtps.\n", norm_name,
2758
					retries);
2759
		}
2760
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
2761
		errmsg_printf(ERRMSG_LVL_ERROR, "Cannot find or open table %s from\n"
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2762
				"the internal data dictionary of InnoDB "
2763
				"though the .frm file for the\n"
2764
				"table exists. Maybe you have deleted and "
2765
				"recreated InnoDB data\n"
2766
				"files but have forgotten to delete the "
2767
				"corresponding .frm files\n"
2768
				"of InnoDB tables, or you have moved .frm "
2769
				"files to another database?\n"
2770
				"or, the table contains indexes that this "
2771
				"version of the engine\n"
2772
				"doesn't support.\n"
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2773
				"See " REFMAN "innodb-troubleshooting.html\n"
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2774
				"how you can resolve the problem.\n",
2775
				norm_name);
2776
		free_share(share);
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2777
		free(upd_buff);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2778
		my_errno = ENOENT;
2779
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2780
		return(HA_ERR_NO_SUCH_TABLE);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2781
	}
2782
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2783
	if (ib_table->ibd_file_missing && !session_tablespace_op(session)) {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
2784
		errmsg_printf(ERRMSG_LVL_ERROR, "MySQL is trying to open a table handle but "
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2785
				"the .ibd file for\ntable %s does not exist.\n"
2786
				"Have you deleted the .ibd file from the "
2787
				"database directory under\nthe MySQL datadir, "
2788
				"or have you used DISCARD TABLESPACE?\n"
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2789
				"See " REFMAN "innodb-troubleshooting.html\n"
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2790
				"how you can resolve the problem.\n",
2791
				norm_name);
2792
		free_share(share);
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2793
		free(upd_buff);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2794
		my_errno = ENOENT;
2795
2796
		dict_table_decrement_handle_count(ib_table, FALSE);
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2797
		return(HA_ERR_NO_SUCH_TABLE);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2798
	}
2799
2800
	prebuilt = row_create_prebuilt(ib_table);
2801
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2802
	prebuilt->mysql_row_len = table->s->stored_rec_length;
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
2803
	prebuilt->default_rec = table->s->default_values;
2804
	ut_ad(prebuilt->default_rec);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2805
2806
	/* Looks like MySQL-3.23 sometimes has primary key number != 0 */
2807
2808
	primary_key = table->s->primary_key;
2809
	key_used_on_scan = primary_key;
2810
2811
	/* Allocate a buffer for a 'row reference'. A row reference is
2812
	a string of bytes of length ref_length which uniquely specifies
2813
	a row in our table. Note that MySQL may also compare two row
2814
	references for equality by doing a simple memcmp on the strings
2815
	of length ref_length! */
2816
2817
	if (!row_table_got_default_clust_index(ib_table)) {
2818
		if (primary_key >= MAX_KEY) {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
2819
		  errmsg_printf(ERRMSG_LVL_ERROR, "Table %s has a primary key in InnoDB data "
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2820
				  "dictionary, but not in MySQL!", name);
2821
		}
2822
2823
		prebuilt->clust_index_was_generated = FALSE;
2824
2825
		/* MySQL allocates the buffer for ref. key_info->key_length
2826
		includes space for all key columns + one byte for each column
2827
		that may be NULL. ref_length must be as exact as possible to
2828
		save space, because all row reference buffers are allocated
2829
		based on ref_length. */
2830
2831
		ref_length = table->key_info[primary_key].key_length;
2832
	} else {
2833
		if (primary_key != MAX_KEY) {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
2834
		  errmsg_printf(ERRMSG_LVL_ERROR, "Table %s has no primary key in InnoDB data "
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2835
				  "dictionary, but has one in MySQL! If you "
2836
				  "created the table with a MySQL version < "
2837
				  "3.23.54 and did not define a primary key, "
2838
				  "but defined a unique key with all non-NULL "
2839
				  "columns, then MySQL internally treats that "
2840
				  "key as the primary key. You can fix this "
2841
				  "error by dump + DROP + CREATE + reimport "
2842
				  "of the table.", name);
2843
		}
2844
2845
		prebuilt->clust_index_was_generated = TRUE;
2846
2847
		ref_length = DATA_ROW_ID_LEN;
2848
2849
		/* If we automatically created the clustered index, then
2850
		MySQL does not know about it, and MySQL must NOT be aware
2851
		of the index used on scan, to make it avoid checking if we
2852
		update the column of the index. That is why we assert below
2853
		that key_used_on_scan is the undefined value MAX_KEY.
2854
		The column is the row id in the automatical generation case,
2855
		and it will never be updated anyway. */
2856
2857
		if (key_used_on_scan != MAX_KEY) {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
2858
			errmsg_printf(ERRMSG_LVL_WARN, 
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2859
				"Table %s key_used_on_scan is %lu even "
2860
				"though there is no primary key inside "
2861
				"InnoDB.", name, (ulong) key_used_on_scan);
2862
		}
2863
	}
2864
2865
	/* Index block size in InnoDB: used by MySQL in query optimization */
2866
	stats.block_size = 16 * 1024;
2867
2868
	/* Init table lock structure */
2869
	thr_lock_data_init(&share->lock,&lock,(void*) 0);
2870
2871
	if (prebuilt->table) {
2872
		/* We update the highest file format in the system table
2873
		space, if this table has higher file format setting. */
2874
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
2875
		trx_sys_file_format_max_upgrade(
2876
			(const char**) &innobase_file_format_check,
2877
			dict_table_get_format(prebuilt->table));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2878
	}
2879
2880
	info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
2881
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
2882
	/* Only if the table has an AUTOINC column. */
2883
	if (prebuilt->table != NULL && table->found_next_number_field != NULL) {
2884
		ulint	error;
2885
2886
		dict_table_autoinc_lock(prebuilt->table);
2887
2888
		/* Since a table can already be "open" in InnoDB's internal
2889
		data dictionary, we only init the autoinc counter once, the
2890
		first time the table is loaded. We can safely reuse the
641.1.5 by Monty Taylor
Merged in innodb plugin 1.0.2
2891
		autoinc value from a previous Drizzle open. */
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
2892
		if (dict_table_autoinc_read(prebuilt->table) == 0) {
2893
2894
			error = innobase_initialize_autoinc();
2895
			ut_a(error == DB_SUCCESS);
2896
		}
2897
2898
		dict_table_autoinc_unlock(prebuilt->table);
2899
	}
2900
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2901
	return(0);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2902
}
2903
2904
UNIV_INTERN
869.1.19 by Stewart Smith
small semantic fix in innodb handler for handler method return types.
2905
uint32_t
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2906
ha_innobase::max_supported_key_part_length() const
2907
{
2908
	return(DICT_MAX_INDEX_COL_LEN - 1);
2909
}
2910
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2911
/******************************************************************//**
2912
Closes a handle to an InnoDB table.
2913
@return	0 */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2914
UNIV_INTERN
2915
int
2916
ha_innobase::close(void)
2917
/*====================*/
2918
{
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2919
	Session*	session;
2920
641.1.5 by Monty Taylor
Merged in innodb plugin 1.0.2
2921
	session = ha_session();
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2922
	if (session != NULL) {
960.2.38 by Monty Taylor
Removed extraneous send myself to myself argument.
2923
		engine->release_temporary_latches(session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2924
	}
2925
2926
	row_prebuilt_free(prebuilt, FALSE);
2927
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2928
	free(upd_buff);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2929
	free_share(share);
2930
2931
	/* Tell InnoDB server that there might be work for
2932
	utility threads: */
2933
2934
	srv_active_wake_master_thread();
2935
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2936
	return(0);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2937
}
2938
2939
/* The following accessor functions should really be inside MySQL code! */
2940
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2941
/**************************************************************//**
2942
Gets field offset for a field in a table.
2943
@return	offset */
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
2944
static inline
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2945
uint
2946
get_field_offset(
2947
/*=============*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
2948
	Table*	table,	/*!< in: MySQL table object */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2949
	Field*	field)	/*!< in: MySQL field object */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2950
{
2951
	return((uint) (field->ptr - table->record[0]));
2952
}
2953
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2954
/**************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2955
Checks if a field in a record is SQL NULL. Uses the record format
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2956
information in table to track the null bit in record.
2957
@return	1 if NULL, 0 otherwise */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2958
static inline
2959
uint
2960
field_in_record_is_null(
2961
/*====================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
2962
	Table*	table,	/*!< in: MySQL table object */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2963
	Field*	field,	/*!< in: MySQL field object */
2964
	char*	record)	/*!< in: a row in MySQL format */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2965
{
2966
	int	null_offset;
2967
2968
	if (!field->null_ptr) {
2969
2970
		return(0);
2971
	}
2972
2973
	null_offset = (uint) ((char*) field->null_ptr
2974
					- (char*) table->record[0]);
2975
2976
	if (record[null_offset] & field->null_bit) {
2977
2978
		return(1);
2979
	}
2980
2981
	return(0);
2982
}
2983
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2984
/**************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2985
Sets a field in a record to SQL NULL. Uses the record format
2986
information in table to track the null bit in record. */
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
2987
static inline
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2988
void
2989
set_field_in_record_to_null(
2990
/*========================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
2991
	Table*	table,	/*!< in: MySQL table object */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2992
	Field*	field,	/*!< in: MySQL field object */
2993
	char*	record)	/*!< in: a row in MySQL format */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2994
{
2995
	int	null_offset;
2996
2997
	null_offset = (uint) ((char*) field->null_ptr
2998
					- (char*) table->record[0]);
2999
3000
	record[null_offset] = record[null_offset] | field->null_bit;
3001
}
3002
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
3003
/*************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3004
InnoDB uses this function to compare two data fields for which the data type
3005
is such that we must use MySQL code to compare them. NOTE that the prototype
3006
of this function is in rem0cmp.c in InnoDB source code! If you change this
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
3007
function, remember to update the prototype there!
3008
@return	1, 0, -1, if a is greater, equal, less than b, respectively */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3009
extern "C" UNIV_INTERN
3010
int
3011
innobase_mysql_cmp(
3012
/*===============*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
3013
	int		mysql_type,	/*!< in: MySQL type */
3014
	uint		charset_number,	/*!< in: number of the charset */
3015
	const unsigned char* a,		/*!< in: data field */
3016
	unsigned int	a_length,	/*!< in: data field length,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3017
					not UNIV_SQL_NULL */
3018
	const unsigned char* b,		/* in: data field */
1085.1.2 by Monty Taylor
Fixed -Wmissing-declarations
3019
	unsigned int	b_length);	/* in: data field length,
3020
					not UNIV_SQL_NULL */
3021
3022
int
3023
innobase_mysql_cmp(
3024
/*===============*/
3025
					/* out: 1, 0, -1, if a is greater,
3026
					equal, less than b, respectively */
3027
	int		mysql_type,	/* in: MySQL type */
3028
	uint		charset_number,	/* in: number of the charset */
3029
	const unsigned char* a,		/* in: data field */
3030
	unsigned int	a_length,	/* in: data field length,
3031
					not UNIV_SQL_NULL */
3032
	const unsigned char* b,		/* in: data field */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3033
	unsigned int	b_length)	/* in: data field length,
3034
					not UNIV_SQL_NULL */
3035
{
641.1.4 by Monty Taylor
Merged in InnoDB changes.
3036
	const CHARSET_INFO*	charset;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3037
	enum_field_types	mysql_tp;
3038
	int			ret;
3039
641.1.4 by Monty Taylor
Merged in InnoDB changes.
3040
	assert(a_length != UNIV_SQL_NULL);
3041
	assert(b_length != UNIV_SQL_NULL);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3042
3043
	mysql_tp = (enum_field_types) mysql_type;
3044
3045
	switch (mysql_tp) {
3046
641.1.4 by Monty Taylor
Merged in InnoDB changes.
3047
	case DRIZZLE_TYPE_BLOB:
3048
	case DRIZZLE_TYPE_VARCHAR:
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3049
		/* Use the charset number to pick the right charset struct for
3050
		the comparison. Since the MySQL function get_charset may be
3051
		slow before Bar removes the mutex operation there, we first
3052
		look at 2 common charsets directly. */
3053
3054
		if (charset_number == default_charset_info->number) {
3055
			charset = default_charset_info;
3056
		} else {
862 by Brian Aker
Remove charset directory code.
3057
			charset = get_charset(charset_number);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3058
3059
			if (charset == NULL) {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
3060
			  errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB needs charset %lu for doing "
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3061
					  "a comparison, but MySQL cannot "
3062
					  "find that charset.",
3063
					  (ulong) charset_number);
3064
				ut_a(0);
3065
			}
3066
		}
3067
3068
		/* Starting from 4.1.3, we use strnncollsp() in comparisons of
3069
		non-latin1_swedish_ci strings. NOTE that the collation order
3070
		changes then: 'b\0\0...' is ordered BEFORE 'b  ...'. Users
3071
		having indexes on such data need to rebuild their tables! */
3072
3073
		ret = charset->coll->strnncollsp(charset,
3074
				  a, a_length,
3075
						 b, b_length, 0);
3076
		if (ret < 0) {
3077
			return(-1);
3078
		} else if (ret > 0) {
3079
			return(1);
3080
		} else {
3081
			return(0);
3082
		}
3083
	default:
3084
		ut_error;
3085
	}
3086
3087
	return(0);
3088
}
3089
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
3090
/**************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3091
Converts a MySQL type to an InnoDB type. Note that this function returns
3092
the 'mtype' of InnoDB. InnoDB differentiates between MySQL's old <= 4.1
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
3093
VARCHAR and the new true VARCHAR in >= 5.0.3 by the 'prtype'.
3094
@return	DATA_BINARY, DATA_VARCHAR, ... */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3095
extern "C" UNIV_INTERN
3096
ulint
3097
get_innobase_type_from_mysql_type(
3098
/*==============================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
3099
	ulint*		unsigned_flag,	/*!< out: DATA_UNSIGNED if an
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3100
					'unsigned type';
3101
					at least ENUM and SET,
3102
					and unsigned integer
3103
					types are 'unsigned types' */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
3104
	const void*	f)		/*!< in: MySQL Field */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3105
{
3106
	const class Field* field = reinterpret_cast<const class Field*>(f);
3107
3108
	/* The following asserts try to check that the MySQL type code fits in
3109
	8 bits: this is used in ibuf and also when DATA_NOT_NULL is ORed to
3110
	the type */
3111
641.1.4 by Monty Taylor
Merged in InnoDB changes.
3112
	assert((ulint)DRIZZLE_TYPE_DOUBLE < 256);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3113
3114
	if (field->flags & UNSIGNED_FLAG) {
3115
3116
		*unsigned_flag = DATA_UNSIGNED;
3117
	} else {
3118
		*unsigned_flag = 0;
3119
	}
3120
641.1.4 by Monty Taylor
Merged in InnoDB changes.
3121
	if (field->real_type() == DRIZZLE_TYPE_ENUM)
3122
	{
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3123
		/* MySQL has field->type() a string type for these, but the
3124
		data is actually internally stored as an unsigned integer
3125
		code! */
3126
3127
		*unsigned_flag = DATA_UNSIGNED; /* MySQL has its own unsigned
3128
						flag set to zero, even though
3129
						internally this is an unsigned
3130
						integer type */
3131
		return(DATA_INT);
3132
	}
3133
3134
	switch (field->type()) {
641.1.4 by Monty Taylor
Merged in InnoDB changes.
3135
		/* NOTE that we only allow string types in DATA_DRIZZLE and
3136
		DATA_VARDRIZZLE */
3137
	case DRIZZLE_TYPE_VARCHAR:    /* new >= 5.0.3 true VARCHAR */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3138
		if (field->binary()) {
3139
			return(DATA_BINARY);
3140
		} else {
3141
			return(DATA_VARMYSQL);
3142
		}
1211.1.1 by Brian Aker
Updating with my change to to DECIMAL from NEWDECIMAL and Stewart's update
3143
	case DRIZZLE_TYPE_DECIMAL:
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3144
		return(DATA_FIXBINARY);
641.1.4 by Monty Taylor
Merged in InnoDB changes.
3145
	case DRIZZLE_TYPE_LONG:
3146
	case DRIZZLE_TYPE_LONGLONG:
3147
	case DRIZZLE_TYPE_DATETIME:
3148
	case DRIZZLE_TYPE_DATE:
3149
	case DRIZZLE_TYPE_TIMESTAMP:
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3150
		return(DATA_INT);
641.1.4 by Monty Taylor
Merged in InnoDB changes.
3151
	case DRIZZLE_TYPE_DOUBLE:
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3152
		return(DATA_DOUBLE);
641.1.4 by Monty Taylor
Merged in InnoDB changes.
3153
	case DRIZZLE_TYPE_BLOB:
3154
                return(DATA_BLOB);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3155
	default:
3156
		ut_error;
3157
	}
3158
3159
	return(0);
3160
}
3161
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
3162
/*******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3163
Writes an unsigned integer value < 64k to 2 bytes, in the little-endian
3164
storage format. */
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
3165
static inline
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3166
void
3167
innobase_write_to_2_little_endian(
3168
/*==============================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
3169
	byte*	buf,	/*!< in: where to store */
3170
	ulint	val)	/*!< in: value to write, must be < 64k */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3171
{
3172
	ut_a(val < 256 * 256);
3173
3174
	buf[0] = (byte)(val & 0xFF);
3175
	buf[1] = (byte)(val / 256);
3176
}
3177
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
3178
/*******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3179
Reads an unsigned integer value < 64k from 2 bytes, in the little-endian
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
3180
storage format.
3181
@return	value */
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
3182
static inline
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3183
uint
3184
innobase_read_from_2_little_endian(
3185
/*===============================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
3186
	const unsigned char*	buf)	/*!< in: from where to read */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3187
{
3188
	return (uint) ((ulint)(buf[0]) + 256 * ((ulint)(buf[1])));
3189
}
3190
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
3191
/*******************************************************************//**
3192
Stores a key value for a row to a buffer.
3193
@return	key value length as stored in buff */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3194
UNIV_INTERN
3195
uint
3196
ha_innobase::store_key_val_for_row(
3197
/*===============================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
3198
	uint		keynr,	/*!< in: key number */
3199
	char*		buff,	/*!< in/out: buffer for the key value (in MySQL
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3200
				format) */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
3201
	uint		buff_len,/*!< in: buffer length */
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
3202
	const unsigned char*	record)/*!< in: row in MySQL format */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3203
{
3204
	KEY*		key_info	= table->key_info + keynr;
3205
	KEY_PART_INFO*	key_part	= key_info->key_part;
3206
	KEY_PART_INFO*	end		= key_part + key_info->key_parts;
3207
	char*		buff_start	= buff;
3208
	enum_field_types mysql_type;
3209
	Field*		field;
3210
	ibool		is_null;
3211
3212
	/* The format for storing a key field in MySQL is the following:
3213
3214
	1. If the column can be NULL, then in the first byte we put 1 if the
3215
	field value is NULL, 0 otherwise.
3216
3217
	2. If the column is of a BLOB type (it must be a column prefix field
3218
	in this case), then we put the length of the data in the field to the
3219
	next 2 bytes, in the little-endian format. If the field is SQL NULL,
3220
	then these 2 bytes are set to 0. Note that the length of data in the
3221
	field is <= column prefix length.
3222
3223
	3. In a column prefix field, prefix_len next bytes are reserved for
3224
	data. In a normal field the max field length next bytes are reserved
3225
	for data. For a VARCHAR(n) the max field length is n. If the stored
3226
	value is the SQL NULL then these data bytes are set to 0.
3227
3228
	4. We always use a 2 byte length for a true >= 5.0.3 VARCHAR. Note that
3229
	in the MySQL row format, the length is stored in 1 or 2 bytes,
3230
	depending on the maximum allowed length. But in the MySQL key value
3231
	format, the length always takes 2 bytes.
3232
3233
	We have to zero-fill the buffer so that MySQL is able to use a
3234
	simple memcmp to compare two key values to determine if they are
3235
	equal. MySQL does this to compare contents of two 'ref' values. */
3236
3237
	bzero(buff, buff_len);
3238
3239
	for (; key_part != end; key_part++) {
3240
		is_null = FALSE;
3241
3242
		if (key_part->null_bit) {
3243
			if (record[key_part->null_offset]
3244
						& key_part->null_bit) {
3245
				*buff = 1;
3246
				is_null = TRUE;
3247
			} else {
3248
				*buff = 0;
3249
			}
3250
			buff++;
3251
		}
3252
3253
		field = key_part->field;
3254
		mysql_type = field->type();
3255
641.1.4 by Monty Taylor
Merged in InnoDB changes.
3256
		if (mysql_type == DRIZZLE_TYPE_VARCHAR) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3257
						/* >= 5.0.3 true VARCHAR */
3258
			ulint		lenlen;
3259
			ulint		len;
3260
			const byte*	data;
3261
			ulint		key_len;
3262
			ulint		true_len;
641.1.4 by Monty Taylor
Merged in InnoDB changes.
3263
			const CHARSET_INFO*	cs;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3264
			int		error=0;
3265
3266
			key_len = key_part->length;
3267
3268
			if (is_null) {
3269
				buff += key_len + 2;
3270
3271
				continue;
3272
			}
3273
			cs = field->charset();
3274
3275
			lenlen = (ulint)
3276
				(((Field_varstring*)field)->length_bytes);
3277
3278
			data = row_mysql_read_true_varchar(&len,
3279
				(byte*) (record
3280
				+ (ulint)get_field_offset(table, field)),
3281
				lenlen);
3282
3283
			true_len = len;
3284
3285
			/* For multi byte character sets we need to calculate
3286
			the true length of the key */
3287
3288
			if (len > 0 && cs->mbmaxlen > 1) {
3289
				true_len = (ulint) cs->cset->well_formed_len(cs,
3290
						(const char *) data,
3291
						(const char *) data + len,
3292
                                                (uint) (key_len /
3293
                                                        cs->mbmaxlen),
3294
						&error);
3295
			}
3296
3297
			/* In a column prefix index, we may need to truncate
3298
			the stored value: */
3299
3300
			if (true_len > key_len) {
3301
				true_len = key_len;
3302
			}
3303
3304
			/* The length in a key value is always stored in 2
3305
			bytes */
3306
3307
			row_mysql_store_true_var_len((byte*)buff, true_len, 2);
3308
			buff += 2;
3309
3310
			memcpy(buff, data, true_len);
3311
3312
			/* Note that we always reserve the maximum possible
3313
			length of the true VARCHAR in the key value, though
3314
			only len first bytes after the 2 length bytes contain
3315
			actual data. The rest of the space was reset to zero
3316
			in the bzero() call above. */
3317
3318
			buff += key_len;
3319
641.1.4 by Monty Taylor
Merged in InnoDB changes.
3320
		} else if (mysql_type == DRIZZLE_TYPE_BLOB) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3321
641.1.4 by Monty Taylor
Merged in InnoDB changes.
3322
			const CHARSET_INFO*	cs;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3323
			ulint		key_len;
3324
			ulint		true_len;
3325
			int		error=0;
3326
			ulint		blob_len;
3327
			const byte*	blob_data;
3328
3329
			ut_a(key_part->key_part_flag & HA_PART_KEY_SEG);
3330
3331
			key_len = key_part->length;
3332
3333
			if (is_null) {
3334
				buff += key_len + 2;
3335
3336
				continue;
3337
			}
3338
3339
			cs = field->charset();
3340
3341
			blob_data = row_mysql_read_blob_ref(&blob_len,
3342
				(byte*) (record
3343
				+ (ulint)get_field_offset(table, field)),
3344
					(ulint) field->pack_length());
3345
3346
			true_len = blob_len;
3347
3348
			ut_a(get_field_offset(table, field)
3349
				== key_part->offset);
3350
3351
			/* For multi byte character sets we need to calculate
3352
			the true length of the key */
3353
3354
			if (blob_len > 0 && cs->mbmaxlen > 1) {
3355
				true_len = (ulint) cs->cset->well_formed_len(cs,
3356
						(const char *) blob_data,
3357
						(const char *) blob_data
3358
							+ blob_len,
3359
                                                (uint) (key_len /
3360
                                                        cs->mbmaxlen),
3361
						&error);
3362
			}
3363
3364
			/* All indexes on BLOB and TEXT are column prefix
3365
			indexes, and we may need to truncate the data to be
3366
			stored in the key value: */
3367
3368
			if (true_len > key_len) {
3369
				true_len = key_len;
3370
			}
3371
3372
			/* MySQL reserves 2 bytes for the length and the
3373
			storage of the number is little-endian */
3374
3375
			innobase_write_to_2_little_endian(
3376
					(byte*)buff, true_len);
3377
			buff += 2;
3378
3379
			memcpy(buff, blob_data, true_len);
3380
3381
			/* Note that we always reserve the maximum possible
3382
			length of the BLOB prefix in the key value. */
3383
3384
			buff += key_len;
3385
		} else {
3386
			/* Here we handle all other data types except the
3387
			true VARCHAR, BLOB and TEXT. Note that the column
3388
			value we store may be also in a column prefix
3389
			index. */
3390
3391
			ulint			true_len;
3392
			ulint			key_len;
641.1.4 by Monty Taylor
Merged in InnoDB changes.
3393
			const unsigned char*		src_start;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3394
			enum_field_types	real_type;
3395
3396
			key_len = key_part->length;
3397
3398
			if (is_null) {
3399
				 buff += key_len;
3400
3401
				 continue;
3402
			}
3403
3404
			src_start = record + key_part->offset;
3405
			real_type = field->real_type();
3406
			true_len = key_len;
3407
3408
			/* Character set for the field is defined only
3409
			to fields whose type is string and real field
3410
			type is not enum or set. For these fields check
3411
			if character set is multi byte. */
3412
3413
			memcpy(buff, src_start, true_len);
3414
			buff += true_len;
3415
3416
			/* Pad the unused space with spaces. Note that no
3417
			padding is ever needed for UCS-2 because in MySQL,
3418
			all UCS2 characters are 2 bytes, as MySQL does not
3419
			support surrogate pairs, which are needed to represent
3420
			characters in the range U+10000 to U+10FFFF. */
3421
3422
			if (true_len < key_len) {
3423
				ulint pad_len = key_len - true_len;
3424
				memset(buff, ' ', pad_len);
3425
				buff += pad_len;
3426
			}
3427
		}
3428
	}
3429
3430
	ut_a(buff <= buff_start + buff_len);
3431
641.1.4 by Monty Taylor
Merged in InnoDB changes.
3432
	return((uint)(buff - buff_start));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3433
}
3434
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
3435
/**************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3436
Builds a 'template' to the prebuilt struct. The template is used in fast
3437
retrieval of just those column values MySQL needs in its processing. */
3438
static
3439
void
3440
build_template(
3441
/*===========*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
3442
	row_prebuilt_t*	prebuilt,	/*!< in/out: prebuilt struct */
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
3443
	Session*	,		/*!< in: current user thread, used
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3444
					only if templ_type is
641.1.4 by Monty Taylor
Merged in InnoDB changes.
3445
					ROW_DRIZZLE_REC_FIELDS */
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
3446
	Table*		table,		/*!< in: MySQL table */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
3447
	uint		templ_type)	/*!< in: ROW_MYSQL_WHOLE_ROW or
641.1.4 by Monty Taylor
Merged in InnoDB changes.
3448
					ROW_DRIZZLE_REC_FIELDS */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3449
{
3450
	dict_index_t*	index;
3451
	dict_index_t*	clust_index;
3452
	mysql_row_templ_t* templ;
3453
	Field*		field;
3454
	ulint		n_fields;
3455
	ulint		n_requested_fields	= 0;
3456
	ibool		fetch_all_in_key	= FALSE;
3457
	ibool		fetch_primary_key_cols	= FALSE;
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
3458
	ulint		i= 0;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3459
	/* byte offset of the end of last requested column */
3460
	ulint		mysql_prefix_len	= 0;
3461
3462
	if (prebuilt->select_lock_type == LOCK_X) {
3463
		/* We always retrieve the whole clustered index record if we
3464
		use exclusive row level locks, for example, if the read is
3465
		done in an UPDATE statement. */
3466
3467
		templ_type = ROW_MYSQL_WHOLE_ROW;
3468
	}
3469
3470
	if (templ_type == ROW_MYSQL_REC_FIELDS) {
3471
		if (prebuilt->hint_need_to_fetch_extra_cols
3472
			== ROW_RETRIEVE_ALL_COLS) {
3473
3474
			/* We know we must at least fetch all columns in the
3475
			key, or all columns in the table */
3476
3477
			if (prebuilt->read_just_key) {
3478
				/* MySQL has instructed us that it is enough
3479
				to fetch the columns in the key; looks like
3480
				MySQL can set this flag also when there is
3481
				only a prefix of the column in the key: in
3482
				that case we retrieve the whole column from
3483
				the clustered index */
3484
3485
				fetch_all_in_key = TRUE;
3486
			} else {
3487
				templ_type = ROW_MYSQL_WHOLE_ROW;
3488
			}
3489
		} else if (prebuilt->hint_need_to_fetch_extra_cols
3490
			== ROW_RETRIEVE_PRIMARY_KEY) {
3491
			/* We must at least fetch all primary key cols. Note
3492
			   that if the clustered index was internally generated
3493
			   by InnoDB on the row id (no primary key was
3494
			   defined), then row_search_for_mysql() will always
3495
			   retrieve the row id to a special buffer in the
3496
			   prebuilt struct. */
3497
3498
			fetch_primary_key_cols = TRUE;
3499
		}
3500
	}
3501
3502
	clust_index = dict_table_get_first_index(prebuilt->table);
3503
3504
	if (templ_type == ROW_MYSQL_REC_FIELDS) {
3505
		index = prebuilt->index;
3506
	} else {
3507
		index = clust_index;
3508
	}
3509
3510
	if (index == clust_index) {
3511
		prebuilt->need_to_access_clustered = TRUE;
3512
	} else {
3513
		prebuilt->need_to_access_clustered = FALSE;
3514
		/* Below we check column by column if we need to access
3515
		the clustered index */
3516
	}
3517
3518
	n_fields = (ulint)table->s->fields; /* number of columns */
3519
3520
	if (!prebuilt->mysql_template) {
3521
		prebuilt->mysql_template = (mysql_row_templ_t*)
3522
			mem_alloc(n_fields * sizeof(mysql_row_templ_t));
3523
	}
3524
3525
	prebuilt->template_type = templ_type;
3526
	prebuilt->null_bitmap_len = table->s->null_bytes;
3527
3528
	prebuilt->templ_contains_blob = FALSE;
3529
3530
	/* Note that in InnoDB, i is the column number. MySQL calls columns
3531
	'fields'. */
3532
	for (i = 0; i < n_fields; i++) {
3533
		templ = prebuilt->mysql_template + n_requested_fields;
3534
		field = table->field[i];
3535
3536
		if (UNIV_LIKELY(templ_type == ROW_MYSQL_REC_FIELDS)) {
3537
			/* Decide which columns we should fetch
3538
			and which we can skip. */
3539
			register const ibool	index_contains_field =
3540
				dict_index_contains_col_or_prefix(index, i);
3541
3542
			if (!index_contains_field && prebuilt->read_just_key) {
3543
				/* If this is a 'key read', we do not need
3544
				columns that are not in the key */
3545
3546
				goto skip_field;
3547
			}
3548
3549
			if (index_contains_field && fetch_all_in_key) {
3550
				/* This field is needed in the query */
3551
3552
				goto include_field;
3553
			}
3554
1003.1.9 by Brian Aker
Patches for Jay (aka name changes)
3555
                        if (field->isReadSet() || field->isWriteSet())
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3556
				/* This field is needed in the query */
3557
				goto include_field;
1003.1.6 by Brian Aker
Added interface for field to get read/write on its own.
3558
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
3559
                        assert(table->isReadSet(i) == field->isReadSet());
3560
                        assert(table->isWriteSet(i) == field->isWriteSet());
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3561
3562
			if (fetch_primary_key_cols
3563
				&& dict_table_col_in_clustered_key(
3564
					index->table, i)) {
3565
				/* This field is needed in the query */
3566
3567
				goto include_field;
3568
			}
3569
3570
			/* This field is not needed in the query, skip it */
3571
3572
			goto skip_field;
3573
		}
3574
include_field:
3575
		n_requested_fields++;
3576
3577
		templ->col_no = i;
3578
3579
		if (index == clust_index) {
3580
			templ->rec_field_no = dict_col_get_clust_pos(
3581
				&index->table->cols[i], index);
3582
		} else {
3583
			templ->rec_field_no = dict_index_get_nth_col_pos(
3584
								index, i);
3585
		}
3586
3587
		if (templ->rec_field_no == ULINT_UNDEFINED) {
3588
			prebuilt->need_to_access_clustered = TRUE;
3589
		}
3590
3591
		if (field->null_ptr) {
3592
			templ->mysql_null_byte_offset =
3593
				(ulint) ((char*) field->null_ptr
3594
					- (char*) table->record[0]);
3595
3596
			templ->mysql_null_bit_mask = (ulint) field->null_bit;
3597
		} else {
3598
			templ->mysql_null_bit_mask = 0;
3599
		}
3600
3601
		templ->mysql_col_offset = (ulint)
3602
					get_field_offset(table, field);
3603
3604
		templ->mysql_col_len = (ulint) field->pack_length();
3605
		if (mysql_prefix_len < templ->mysql_col_offset
3606
				+ templ->mysql_col_len) {
3607
			mysql_prefix_len = templ->mysql_col_offset
3608
				+ templ->mysql_col_len;
3609
		}
3610
		templ->type = index->table->cols[i].mtype;
3611
		templ->mysql_type = (ulint)field->type();
3612
3613
		if (templ->mysql_type == DATA_MYSQL_TRUE_VARCHAR) {
3614
			templ->mysql_length_bytes = (ulint)
3615
				(((Field_varstring*)field)->length_bytes);
3616
		}
3617
3618
		templ->charset = dtype_get_charset_coll(
3619
			index->table->cols[i].prtype);
3620
		templ->mbminlen = index->table->cols[i].mbminlen;
3621
		templ->mbmaxlen = index->table->cols[i].mbmaxlen;
3622
		templ->is_unsigned = index->table->cols[i].prtype
3623
							& DATA_UNSIGNED;
3624
		if (templ->type == DATA_BLOB) {
3625
			prebuilt->templ_contains_blob = TRUE;
3626
		}
3627
skip_field:
3628
		;
3629
	}
3630
3631
	prebuilt->n_template = n_requested_fields;
3632
	prebuilt->mysql_prefix_len = mysql_prefix_len;
3633
3634
	if (index != clust_index && prebuilt->need_to_access_clustered) {
3635
		/* Change rec_field_no's to correspond to the clustered index
3636
		record */
3637
		for (i = 0; i < n_requested_fields; i++) {
3638
			templ = prebuilt->mysql_template + i;
3639
3640
			templ->rec_field_no = dict_col_get_clust_pos(
3641
				&index->table->cols[templ->col_no],
3642
				clust_index);
3643
		}
3644
	}
3645
}
3646
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
3647
/********************************************************************//**
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
3648
Get the upper limit of the MySQL integral and floating-point type. */
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
3649
UNIV_INTERN
641.1.5 by Monty Taylor
Merged in innodb plugin 1.0.2
3650
uint64_t
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
3651
ha_innobase::innobase_get_int_col_max_value(
3652
/*========================================*/
3653
	const Field*	field)
3654
{
641.1.5 by Monty Taylor
Merged in innodb plugin 1.0.2
3655
	uint64_t	max_value = 0;
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
3656
3657
	switch(field->key_type()) {
3658
	/* TINY */
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
3659
	case HA_KEYTYPE_BINARY:
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
3660
		max_value = 0xFFULL;
3661
		break;
3662
	/* MEDIUM */
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
3663
	case HA_KEYTYPE_UINT24:
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
3664
		max_value = 0xFFFFFFULL;
3665
		break;
3666
	/* LONG */
3667
	case HA_KEYTYPE_ULONG_INT:
3668
		max_value = 0xFFFFFFFFULL;
3669
		break;
3670
	case HA_KEYTYPE_LONG_INT:
3671
		max_value = 0x7FFFFFFFULL;
3672
		break;
3673
	/* BIG */
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
3674
	case HA_KEYTYPE_ULONGLONG:
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
3675
		max_value = 0xFFFFFFFFFFFFFFFFULL;
3676
		break;
3677
	case HA_KEYTYPE_LONGLONG:
3678
		max_value = 0x7FFFFFFFFFFFFFFFULL;
3679
		break;
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
3680
	case HA_KEYTYPE_DOUBLE:
3681
		/* We use the maximum as per IEEE754-2008 standard, 2^53 */
3682
		max_value = 0x20000000000000ULL;
3683
		break;
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
3684
	default:
3685
		ut_error;
3686
	}
3687
3688
	return(max_value);
3689
}
3690
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
3691
/********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3692
This special handling is really to overcome the limitations of MySQL's
3693
binlogging. We need to eliminate the non-determinism that will arise in
3694
INSERT ... SELECT type of statements, since MySQL binlog only stores the
3695
min value of the autoinc interval. Once that is fixed we can get rid of
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
3696
the special lock handling.
3697
@return	DB_SUCCESS if all OK else error code */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3698
UNIV_INTERN
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
3699
ulint
3700
ha_innobase::innobase_lock_autoinc(void)
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3701
/*====================================*/
3702
{
3703
	ulint		error = DB_SUCCESS;
3704
3705
	switch (innobase_autoinc_lock_mode) {
3706
	case AUTOINC_NO_LOCKING:
3707
		/* Acquire only the AUTOINC mutex. */
3708
		dict_table_autoinc_lock(prebuilt->table);
3709
		break;
3710
3711
	case AUTOINC_NEW_STYLE_LOCKING:
3712
		/* For simple (single/multi) row INSERTs, we fallback to the
3713
		old style only if another transaction has already acquired
3714
		the AUTOINC lock on behalf of a LOAD FILE or INSERT ... SELECT
3715
		etc. type of statement. */
641.1.5 by Monty Taylor
Merged in innodb plugin 1.0.2
3716
		if (session_sql_command(user_session) == SQLCOM_INSERT
3717
		    || session_sql_command(user_session) == SQLCOM_REPLACE) {
779.3.10 by Monty Taylor
Turned on -Wshadow.
3718
			dict_table_t*	d_table = prebuilt->table;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3719
3720
			/* Acquire the AUTOINC mutex. */
779.3.10 by Monty Taylor
Turned on -Wshadow.
3721
			dict_table_autoinc_lock(d_table);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3722
3723
			/* We need to check that another transaction isn't
3724
			already holding the AUTOINC lock on the table. */
779.3.10 by Monty Taylor
Turned on -Wshadow.
3725
			if (d_table->n_waiting_or_granted_auto_inc_locks) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3726
				/* Release the mutex to avoid deadlocks. */
779.3.10 by Monty Taylor
Turned on -Wshadow.
3727
				dict_table_autoinc_unlock(d_table);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3728
			} else {
3729
				break;
3730
			}
3731
		}
3732
		/* Fall through to old style locking. */
3733
3734
	case AUTOINC_OLD_STYLE_LOCKING:
3735
		error = row_lock_table_autoinc_for_mysql(prebuilt);
3736
3737
		if (error == DB_SUCCESS) {
3738
3739
			/* Acquire the AUTOINC mutex. */
3740
			dict_table_autoinc_lock(prebuilt->table);
3741
		}
3742
		break;
3743
3744
	default:
3745
		ut_error;
3746
	}
3747
3748
	return(ulong(error));
3749
}
3750
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
3751
/********************************************************************//**
3752
Reset the autoinc value in the table.
3753
@return	DB_SUCCESS if all went well else error code */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3754
UNIV_INTERN
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
3755
ulint
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3756
ha_innobase::innobase_reset_autoinc(
3757
/*================================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
3758
	uint64_t	autoinc)	/*!< in: value to store */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3759
{
3760
	ulint		error;
3761
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
3762
	error = innobase_lock_autoinc();
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3763
3764
	if (error == DB_SUCCESS) {
3765
3766
		dict_table_autoinc_initialize(prebuilt->table, autoinc);
3767
3768
		dict_table_autoinc_unlock(prebuilt->table);
3769
	}
3770
3771
	return(ulong(error));
3772
}
3773
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
3774
/********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3775
Store the autoinc value in the table. The autoinc value is only set if
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
3776
it's greater than the existing autoinc value in the table.
3777
@return	DB_SUCCESS if all went well else error code */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3778
UNIV_INTERN
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
3779
ulint
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3780
ha_innobase::innobase_set_max_autoinc(
3781
/*==================================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
3782
	uint64_t	auto_inc)	/*!< in: value to store */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3783
{
3784
	ulint		error;
3785
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
3786
	error = innobase_lock_autoinc();
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3787
3788
	if (error == DB_SUCCESS) {
3789
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
3790
		dict_table_autoinc_update_if_greater(prebuilt->table, auto_inc);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3791
3792
		dict_table_autoinc_unlock(prebuilt->table);
3793
	}
3794
3795
	return(ulong(error));
3796
}
3797
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
3798
/********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3799
Stores a row in an InnoDB database, to the table specified in this
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
3800
handle.
3801
@return	error code */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3802
UNIV_INTERN
3803
int
3804
ha_innobase::write_row(
3805
/*===================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
3806
	unsigned char*	record)	/*!< in: a row in MySQL format */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3807
{
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
3808
	ulint		error = 0;
3809
        int             error_result= 0;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3810
	ibool		auto_inc_used= FALSE;
3811
	ulint		sql_command;
641.1.4 by Monty Taylor
Merged in InnoDB changes.
3812
	trx_t*		trx = session_to_trx(user_session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3813
3814
	if (prebuilt->trx != trx) {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
3815
	  errmsg_printf(ERRMSG_LVL_ERROR, "The transaction object for the table handle is at "
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3816
			  "%p, but for the current thread it is at %p",
3817
			  (const void*) prebuilt->trx, (const void*) trx);
3818
3819
		fputs("InnoDB: Dump of 200 bytes around prebuilt: ", stderr);
3820
		ut_print_buf(stderr, ((const byte*)prebuilt) - 100, 200);
3821
		fputs("\n"
3822
			"InnoDB: Dump of 200 bytes around ha_data: ",
3823
			stderr);
3824
		ut_print_buf(stderr, ((const byte*) trx) - 100, 200);
3825
		putc('\n', stderr);
3826
		ut_error;
3827
	}
3828
3829
	ha_statistic_increment(&SSV::ha_write_count);
3830
641.1.4 by Monty Taylor
Merged in InnoDB changes.
3831
	sql_command = session_sql_command(user_session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3832
3833
	if ((sql_command == SQLCOM_ALTER_TABLE
3834
	     || sql_command == SQLCOM_CREATE_INDEX
3835
	     || sql_command == SQLCOM_DROP_INDEX)
3836
	    && num_write_row >= 10000) {
3837
		/* ALTER TABLE is COMMITted at every 10000 copied rows.
3838
		The IX table lock for the original table has to be re-issued.
3839
		As this method will be called on a temporary table where the
3840
		contents of the original table is being copied to, it is
3841
		a bit tricky to determine the source table.  The cursor
3842
		position in the source table need not be adjusted after the
3843
		intermediate COMMIT, since writes by other transactions are
3844
		being blocked by a MySQL table lock TL_WRITE_ALLOW_READ. */
3845
3846
		dict_table_t*	src_table;
3847
		enum lock_mode	mode;
3848
3849
		num_write_row = 0;
3850
3851
		/* Commit the transaction.  This will release the table
3852
		locks, so they have to be acquired again. */
3853
3854
		/* Altering an InnoDB table */
3855
		/* Get the source table. */
3856
		src_table = lock_get_src_table(
3857
				prebuilt->trx, prebuilt->table, &mode);
3858
		if (!src_table) {
3859
no_commit:
3860
			/* Unknown situation: do not commit */
3861
			/*
3862
			ut_print_timestamp(stderr);
3863
			fprintf(stderr,
3864
				"  InnoDB: ALTER TABLE is holding lock"
3865
				" on %lu tables!\n",
3866
				prebuilt->trx->mysql_n_tables_locked);
3867
			*/
3868
			;
3869
		} else if (src_table == prebuilt->table) {
3870
			/* Source table is not in InnoDB format:
3871
			no need to re-acquire locks on it. */
3872
3873
			/* Altering to InnoDB format */
960.2.38 by Monty Taylor
Removed extraneous send myself to myself argument.
3874
			engine->commit(user_session, 1);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3875
			/* Note that this transaction is still active. */
3876
			prebuilt->trx->active_trans = 1;
3877
			/* We will need an IX lock on the destination table. */
3878
			prebuilt->sql_stat_start = TRUE;
3879
		} else {
3880
			/* Ensure that there are no other table locks than
3881
			LOCK_IX and LOCK_AUTO_INC on the destination table. */
3882
3883
			if (!lock_is_table_exclusive(prebuilt->table,
3884
							prebuilt->trx)) {
3885
				goto no_commit;
3886
			}
3887
3888
			/* Commit the transaction.  This will release the table
3889
			locks, so they have to be acquired again. */
960.2.38 by Monty Taylor
Removed extraneous send myself to myself argument.
3890
			engine->commit(user_session, 1);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3891
			/* Note that this transaction is still active. */
3892
			prebuilt->trx->active_trans = 1;
3893
			/* Re-acquire the table lock on the source table. */
3894
			row_lock_table_for_mysql(prebuilt, src_table, mode);
3895
			/* We will need an IX lock on the destination table. */
3896
			prebuilt->sql_stat_start = TRUE;
3897
		}
3898
	}
3899
3900
	num_write_row++;
3901
3902
	/* This is the case where the table has an auto-increment column */
3903
	if (table->next_number_field && record == table->record[0]) {
3904
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
3905
		/* Reset the error code before calling
3906
		innobase_get_auto_increment(). */
3907
		prebuilt->autoinc_error = DB_SUCCESS;
3908
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3909
		if ((error = update_auto_increment())) {
3910
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
3911
			/* We don't want to mask autoinc overflow errors. */
3912
			if (prebuilt->autoinc_error != DB_SUCCESS) {
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
3913
				error = (int) prebuilt->autoinc_error;
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
3914
3915
				goto report_error;
3916
			}
3917
3918
			/* MySQL errors are passed straight back. */
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
3919
			error_result = (int) error;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3920
			goto func_exit;
3921
		}
3922
3923
		auto_inc_used = TRUE;
3924
	}
3925
3926
	if (prebuilt->mysql_template == NULL
3927
	    || prebuilt->template_type != ROW_MYSQL_WHOLE_ROW) {
3928
3929
		/* Build the template used in converting quickly between
3930
		the two database formats */
3931
641.1.4 by Monty Taylor
Merged in InnoDB changes.
3932
		build_template(prebuilt, NULL, table,
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
3933
			       ROW_MYSQL_WHOLE_ROW);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3934
	}
3935
3936
	innodb_srv_conc_enter_innodb(prebuilt->trx);
3937
3938
	error = row_insert_for_mysql((byte*) record, prebuilt);
3939
3940
	/* Handle duplicate key errors */
3941
	if (auto_inc_used) {
3942
		ulint		err;
641.1.4 by Monty Taylor
Merged in InnoDB changes.
3943
		uint64_t	auto_inc;
641.1.5 by Monty Taylor
Merged in innodb plugin 1.0.2
3944
		uint64_t	col_max_value;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3945
3946
		/* Note the number of rows processed for this statement, used
3947
		by get_auto_increment() to determine the number of AUTO-INC
3948
		values to reserve. This is only useful for a mult-value INSERT
3949
		and is a statement level counter.*/
3950
		if (trx->n_autoinc_rows > 0) {
3951
			--trx->n_autoinc_rows;
3952
		}
3953
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
3954
		/* We need the upper limit of the col type to check for
3955
		whether we update the table autoinc counter or not. */
3956
		col_max_value = innobase_get_int_col_max_value(
3957
			table->next_number_field);
3958
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3959
		/* Get the value that MySQL attempted to store in the table.*/
3960
		auto_inc = table->next_number_field->val_int();
3961
3962
		switch (error) {
3963
		case DB_DUPLICATE_KEY:
3964
3965
			/* A REPLACE command and LOAD DATA INFILE REPLACE
3966
			handle a duplicate key error themselves, but we
3967
			must update the autoinc counter if we are performing
3968
			those statements. */
3969
3970
			switch (sql_command) {
3971
			case SQLCOM_LOAD:
3972
				if ((trx->duplicates
3973
				    & (TRX_DUP_IGNORE | TRX_DUP_REPLACE))) {
3974
3975
					goto set_max_autoinc;
3976
				}
3977
				break;
3978
3979
			case SQLCOM_REPLACE:
3980
			case SQLCOM_INSERT_SELECT:
3981
			case SQLCOM_REPLACE_SELECT:
3982
				goto set_max_autoinc;
3983
3984
			default:
3985
				break;
3986
			}
3987
3988
			break;
3989
3990
		case DB_SUCCESS:
3991
			/* If the actual value inserted is greater than
3992
			the upper limit of the interval, then we try and
3993
			update the table upper limit. Note: last_value
3994
			will be 0 if get_auto_increment() was not called.*/
3995
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
3996
			if (auto_inc <= col_max_value
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
3997
			    && auto_inc >= prebuilt->autoinc_last_value) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3998
set_max_autoinc:
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
3999
				ut_a(prebuilt->autoinc_increment > 0);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4000
641.1.4 by Monty Taylor
Merged in InnoDB changes.
4001
				uint64_t	need;
641.1.5 by Monty Taylor
Merged in innodb plugin 1.0.2
4002
				uint64_t	offset;
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
4003
4004
				offset = prebuilt->autoinc_offset;
4005
				need = prebuilt->autoinc_increment;
4006
4007
				auto_inc = innobase_next_autoinc(
4008
					auto_inc, need, offset, col_max_value);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4009
4010
				err = innobase_set_max_autoinc(auto_inc);
4011
4012
				if (err != DB_SUCCESS) {
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
4013
					error = err;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4014
				}
4015
			}
4016
			break;
4017
		}
4018
	}
4019
4020
	innodb_srv_conc_exit_innodb(prebuilt->trx);
4021
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
4022
report_error:
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
4023
	error_result = convert_error_code_to_mysql((int) error,
4024
						   prebuilt->table->flags,
933.1.1 by Monty Taylor
Merged in InnoDB Plugin 1.0.3
4025
						   user_session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4026
4027
func_exit:
4028
	innobase_active_small();
4029
933.1.1 by Monty Taylor
Merged in InnoDB Plugin 1.0.3
4030
	return(error_result);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4031
}
4032
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4033
/**********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4034
Checks which fields have changed in a row and stores information
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4035
of them to an update vector.
4036
@return	error number or 0 */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4037
static
4038
int
4039
calc_row_difference(
4040
/*================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4041
	upd_t*		uvect,		/*!< in/out: update vector */
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
4042
	unsigned char*		old_row,	/*!< in: old row in MySQL format */
4043
	unsigned char*		new_row,	/*!< in: new row in MySQL format */
4044
	Table* table,		/*!< in: table in MySQL data
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4045
					dictionary */
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
4046
	unsigned char*	upd_buff,	/*!< in: buffer to use */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4047
	ulint		buff_len,	/*!< in: buffer length */
4048
	row_prebuilt_t*	prebuilt,	/*!< in: InnoDB prebuilt struct */
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
4049
	Session*	)		/*!< in: user thread */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4050
{
641.1.4 by Monty Taylor
Merged in InnoDB changes.
4051
	unsigned char*		original_upd_buff = upd_buff;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4052
	Field*		field;
4053
	enum_field_types field_mysql_type;
4054
	uint		n_fields;
4055
	ulint		o_len;
4056
	ulint		n_len;
4057
	ulint		col_pack_len;
4058
	const byte*	new_mysql_row_col;
4059
	const byte*	o_ptr;
4060
	const byte*	n_ptr;
4061
	byte*		buf;
4062
	upd_field_t*	ufield;
4063
	ulint		col_type;
4064
	ulint		n_changed = 0;
4065
	dfield_t	dfield;
4066
	dict_index_t*	clust_index;
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
4067
	uint		i= 0;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4068
4069
	n_fields = table->s->fields;
4070
	clust_index = dict_table_get_first_index(prebuilt->table);
4071
4072
	/* We use upd_buff to convert changed fields */
4073
	buf = (byte*) upd_buff;
4074
4075
	for (i = 0; i < n_fields; i++) {
4076
		field = table->field[i];
4077
4078
		o_ptr = (const byte*) old_row + get_field_offset(table, field);
4079
		n_ptr = (const byte*) new_row + get_field_offset(table, field);
4080
4081
		/* Use new_mysql_row_col and col_pack_len save the values */
4082
4083
		new_mysql_row_col = n_ptr;
4084
		col_pack_len = field->pack_length();
4085
4086
		o_len = col_pack_len;
4087
		n_len = col_pack_len;
4088
4089
		/* We use o_ptr and n_ptr to dig up the actual data for
4090
		comparison. */
4091
4092
		field_mysql_type = field->type();
4093
4094
		col_type = prebuilt->table->cols[i].mtype;
4095
4096
		switch (col_type) {
4097
4098
		case DATA_BLOB:
4099
			o_ptr = row_mysql_read_blob_ref(&o_len, o_ptr, o_len);
4100
			n_ptr = row_mysql_read_blob_ref(&n_len, n_ptr, n_len);
4101
4102
			break;
4103
4104
		case DATA_VARCHAR:
4105
		case DATA_BINARY:
4106
		case DATA_VARMYSQL:
641.1.4 by Monty Taylor
Merged in InnoDB changes.
4107
			if (field_mysql_type == DRIZZLE_TYPE_VARCHAR) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4108
				/* This is a >= 5.0.3 type true VARCHAR where
4109
				the real payload data length is stored in
4110
				1 or 2 bytes */
4111
4112
				o_ptr = row_mysql_read_true_varchar(
4113
					&o_len, o_ptr,
4114
					(ulint)
4115
					(((Field_varstring*)field)->length_bytes));
4116
4117
				n_ptr = row_mysql_read_true_varchar(
4118
					&n_len, n_ptr,
4119
					(ulint)
4120
					(((Field_varstring*)field)->length_bytes));
4121
			}
4122
4123
			break;
4124
		default:
4125
			;
4126
		}
4127
4128
		if (field->null_ptr) {
4129
			if (field_in_record_is_null(table, field,
4130
							(char*) old_row)) {
4131
				o_len = UNIV_SQL_NULL;
4132
			}
4133
4134
			if (field_in_record_is_null(table, field,
4135
							(char*) new_row)) {
4136
				n_len = UNIV_SQL_NULL;
4137
			}
4138
		}
4139
4140
		if (o_len != n_len || (o_len != UNIV_SQL_NULL &&
4141
					0 != memcmp(o_ptr, n_ptr, o_len))) {
4142
			/* The field has changed */
4143
4144
			ufield = uvect->fields + n_changed;
4145
4146
			/* Let us use a dummy dfield to make the conversion
4147
			from the MySQL column format to the InnoDB format */
4148
4149
			dict_col_copy_type(prebuilt->table->cols + i,
641.1.4 by Monty Taylor
Merged in InnoDB changes.
4150
						     &dfield.type);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4151
4152
			if (n_len != UNIV_SQL_NULL) {
4153
				buf = row_mysql_store_col_in_innobase_format(
4154
					&dfield,
4155
					(byte*)buf,
4156
					TRUE,
4157
					new_mysql_row_col,
4158
					col_pack_len,
4159
					dict_table_is_comp(prebuilt->table));
4160
				dfield_copy_data(&ufield->new_val, &dfield);
4161
			} else {
4162
				dfield_set_null(&ufield->new_val);
4163
			}
4164
4165
			ufield->exp = NULL;
4166
			ufield->orig_len = 0;
4167
			ufield->field_no = dict_col_get_clust_pos(
4168
				&prebuilt->table->cols[i], clust_index);
4169
			n_changed++;
4170
		}
4171
	}
4172
4173
	uvect->n_fields = n_changed;
4174
	uvect->info_bits = 0;
4175
4176
	ut_a(buf <= (byte*)original_upd_buff + buff_len);
4177
4178
	return(0);
4179
}
4180
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4181
/**********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4182
Updates a row given as a parameter to a new value. Note that we are given
4183
whole rows, not just the fields which are updated: this incurs some
4184
overhead for CPU when we check which fields are actually updated.
4185
TODO: currently InnoDB does not prevent the 'Halloween problem':
4186
in a searched update a single row can get updated several times
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4187
if its index columns are updated!
4188
@return	error number or 0 */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4189
UNIV_INTERN
4190
int
4191
ha_innobase::update_row(
4192
/*====================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
4193
	const unsigned char*	old_row,/*!< in: old row in MySQL format */
4194
	unsigned char*		new_row)/*!< in: new row in MySQL format */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4195
{
4196
	upd_t*		uvect;
4197
	int		error = 0;
641.1.4 by Monty Taylor
Merged in InnoDB changes.
4198
	trx_t*		trx = session_to_trx(user_session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4199
4200
	ut_a(prebuilt->trx == trx);
4201
4202
	ha_statistic_increment(&SSV::ha_update_count);
4203
4204
	if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
4205
		table->timestamp_field->set_time();
4206
4207
	if (prebuilt->upd_node) {
4208
		uvect = prebuilt->upd_node->update;
4209
	} else {
4210
		uvect = row_get_prebuilt_update_vector(prebuilt);
4211
	}
4212
4213
	/* Build an update vector from the modified fields in the rows
4214
	(uses upd_buff of the handle) */
4215
641.1.4 by Monty Taylor
Merged in InnoDB changes.
4216
	calc_row_difference(uvect, (unsigned char*) old_row, new_row, table,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4217
			upd_buff, (ulint)upd_and_key_val_buff_len,
641.1.4 by Monty Taylor
Merged in InnoDB changes.
4218
			prebuilt, user_session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4219
4220
	/* This is not a delete */
4221
	prebuilt->upd_node->is_delete = FALSE;
4222
4223
	ut_a(prebuilt->template_type == ROW_MYSQL_WHOLE_ROW);
4224
4225
	innodb_srv_conc_enter_innodb(trx);
4226
4227
	error = row_update_for_mysql((byte*) old_row, prebuilt);
4228
4229
	/* We need to do some special AUTOINC handling for the following case:
4230
4231
	INSERT INTO t (c1,c2) VALUES(x,y) ON DUPLICATE KEY UPDATE ...
4232
4233
	We need to use the AUTOINC counter that was actually used by
4234
	MySQL in the UPDATE statement, which can be different from the
4235
	value used in the INSERT statement.*/
4236
4237
	if (error == DB_SUCCESS
4238
	    && table->next_number_field
4239
	    && new_row == table->record[0]
641.1.4 by Monty Taylor
Merged in InnoDB changes.
4240
	    && session_sql_command(user_session) == SQLCOM_INSERT
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4241
	    && (trx->duplicates & (TRX_DUP_IGNORE | TRX_DUP_REPLACE))
4242
		== TRX_DUP_IGNORE)  {
4243
641.1.5 by Monty Taylor
Merged in innodb plugin 1.0.2
4244
		uint64_t	auto_inc;
4245
		uint64_t	col_max_value;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4246
4247
		auto_inc = table->next_number_field->val_int();
4248
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
4249
		/* We need the upper limit of the col type to check for
4250
		whether we update the table autoinc counter or not. */
4251
		col_max_value = innobase_get_int_col_max_value(
4252
			table->next_number_field);
4253
4254
		if (auto_inc <= col_max_value && auto_inc != 0) {
4255
641.1.5 by Monty Taylor
Merged in innodb plugin 1.0.2
4256
			uint64_t	need;
4257
			uint64_t	offset;
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
4258
4259
			offset = prebuilt->autoinc_offset;
4260
			need = prebuilt->autoinc_increment;
4261
4262
			auto_inc = innobase_next_autoinc(
4263
				auto_inc, need, offset, col_max_value);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4264
4265
			error = innobase_set_max_autoinc(auto_inc);
4266
		}
4267
	}
4268
4269
	innodb_srv_conc_exit_innodb(trx);
4270
4271
	error = convert_error_code_to_mysql(error,
641.1.4 by Monty Taylor
Merged in InnoDB changes.
4272
					    prebuilt->table->flags,
4273
                                            user_session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4274
4275
	if (error == 0 /* success */
4276
	    && uvect->n_fields == 0 /* no columns were updated */) {
4277
4278
		/* This is the same as success, but instructs
4279
		MySQL that the row is not really updated and it
4280
		should not increase the count of updated rows.
4281
		This is fix for http://bugs.mysql.com/29157 */
4282
		error = HA_ERR_RECORD_IS_THE_SAME;
4283
	}
4284
4285
	/* Tell InnoDB server that there might be work for
4286
	utility threads: */
4287
4288
	innobase_active_small();
4289
641.1.4 by Monty Taylor
Merged in InnoDB changes.
4290
	return(error);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4291
}
4292
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4293
/**********************************************************************//**
4294
Deletes a row given as the parameter.
4295
@return	error number or 0 */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4296
UNIV_INTERN
4297
int
4298
ha_innobase::delete_row(
4299
/*====================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
4300
	const unsigned char*	record)	/*!< in: a row in MySQL format */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4301
{
4302
	int		error = 0;
641.1.4 by Monty Taylor
Merged in InnoDB changes.
4303
	trx_t*		trx = session_to_trx(user_session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4304
4305
	ut_a(prebuilt->trx == trx);
4306
4307
	ha_statistic_increment(&SSV::ha_delete_count);
4308
4309
	if (!prebuilt->upd_node) {
4310
		row_get_prebuilt_update_vector(prebuilt);
4311
	}
4312
4313
	/* This is a delete */
4314
4315
	prebuilt->upd_node->is_delete = TRUE;
4316
4317
	innodb_srv_conc_enter_innodb(trx);
4318
4319
	error = row_update_for_mysql((byte*) record, prebuilt);
4320
4321
	innodb_srv_conc_exit_innodb(trx);
4322
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
4323
	error = convert_error_code_to_mysql(
641.1.5 by Monty Taylor
Merged in innodb plugin 1.0.2
4324
		error, prebuilt->table->flags, user_session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4325
4326
	/* Tell the InnoDB server that there might be work for
4327
	utility threads: */
4328
4329
	innobase_active_small();
4330
641.1.4 by Monty Taylor
Merged in InnoDB changes.
4331
	return(error);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4332
}
4333
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4334
/**********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4335
Removes a new lock set on a row, if it was not read optimistically. This can
4336
be called after a row has been read in the processing of an UPDATE or a DELETE
4337
query, if the option innodb_locks_unsafe_for_binlog is set. */
4338
UNIV_INTERN
4339
void
4340
ha_innobase::unlock_row(void)
4341
/*=========================*/
4342
{
4343
	/* Consistent read does not take any locks, thus there is
4344
	nothing to unlock. */
4345
4346
	if (prebuilt->select_lock_type == LOCK_NONE) {
641.1.4 by Monty Taylor
Merged in InnoDB changes.
4347
	  return;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4348
	}
4349
4350
	switch (prebuilt->row_read_type) {
4351
	case ROW_READ_WITH_LOCKS:
4352
		if (!srv_locks_unsafe_for_binlog
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
4353
		    && prebuilt->trx->isolation_level
4354
		    != TRX_ISO_READ_COMMITTED) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4355
			break;
4356
		}
4357
		/* fall through */
4358
	case ROW_READ_TRY_SEMI_CONSISTENT:
4359
		row_unlock_for_mysql(prebuilt, FALSE);
4360
		break;
4361
	case ROW_READ_DID_SEMI_CONSISTENT:
4362
		prebuilt->row_read_type = ROW_READ_TRY_SEMI_CONSISTENT;
4363
		break;
4364
	}
4365
641.1.4 by Monty Taylor
Merged in InnoDB changes.
4366
	return;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4367
}
4368
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
4369
/* See Cursor.h and row0mysql.h for docs on this function. */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4370
UNIV_INTERN
4371
bool
4372
ha_innobase::was_semi_consistent_read(void)
4373
/*=======================================*/
4374
{
4375
	return(prebuilt->row_read_type == ROW_READ_DID_SEMI_CONSISTENT);
4376
}
4377
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
4378
/* See Cursor.h and row0mysql.h for docs on this function. */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4379
UNIV_INTERN
4380
void
4381
ha_innobase::try_semi_consistent_read(bool yes)
4382
/*===========================================*/
4383
{
641.1.4 by Monty Taylor
Merged in InnoDB changes.
4384
	ut_a(prebuilt->trx == session_to_trx(ha_session()));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4385
4386
	/* Row read type is set to semi consistent read if this was
4387
	requested by the MySQL and either innodb_locks_unsafe_for_binlog
4388
	option is used or this session is using READ COMMITTED isolation
4389
	level. */
4390
4391
	if (yes
4392
	    && (srv_locks_unsafe_for_binlog
4393
		|| prebuilt->trx->isolation_level == TRX_ISO_READ_COMMITTED)) {
4394
		prebuilt->row_read_type = ROW_READ_TRY_SEMI_CONSISTENT;
4395
	} else {
4396
		prebuilt->row_read_type = ROW_READ_WITH_LOCKS;
4397
	}
4398
}
4399
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4400
/******************************************************************//**
4401
Initializes a handle to use an index.
4402
@return	0 or error number */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4403
UNIV_INTERN
4404
int
4405
ha_innobase::index_init(
4406
/*====================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4407
	uint	keynr,	/*!< in: key (index) number */
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
4408
	bool )		/*!< in: 1 if result MUST be sorted according to index */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4409
{
641.1.4 by Monty Taylor
Merged in InnoDB changes.
4410
	return(change_active_index(keynr));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4411
}
4412
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4413
/******************************************************************//**
4414
Currently does nothing.
4415
@return	0 */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4416
UNIV_INTERN
4417
int
4418
ha_innobase::index_end(void)
4419
/*========================*/
4420
{
4421
	int	error	= 0;
4422
	active_index=MAX_KEY;
641.1.4 by Monty Taylor
Merged in InnoDB changes.
4423
	return(error);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4424
}
4425
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4426
/*********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4427
Converts a search mode flag understood by MySQL to a flag understood
4428
by InnoDB. */
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
4429
static inline
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4430
ulint
4431
convert_search_mode_to_innobase(
4432
/*============================*/
4433
	enum ha_rkey_function	find_flag)
4434
{
4435
	switch (find_flag) {
4436
	case HA_READ_KEY_EXACT:
4437
		/* this does not require the index to be UNIQUE */
4438
		return(PAGE_CUR_GE);
4439
	case HA_READ_KEY_OR_NEXT:
4440
		return(PAGE_CUR_GE);
4441
	case HA_READ_KEY_OR_PREV:
4442
		return(PAGE_CUR_LE);
4443
	case HA_READ_AFTER_KEY:	
4444
		return(PAGE_CUR_G);
4445
	case HA_READ_BEFORE_KEY:
4446
		return(PAGE_CUR_L);
4447
	case HA_READ_PREFIX:
4448
		return(PAGE_CUR_GE);
4449
	case HA_READ_PREFIX_LAST:
4450
		return(PAGE_CUR_LE);
4451
	case HA_READ_PREFIX_LAST_OR_PREV:
4452
		return(PAGE_CUR_LE);
4453
		/* In MySQL-4.0 HA_READ_PREFIX and HA_READ_PREFIX_LAST always
4454
		pass a complete-field prefix of a key value as the search
4455
		tuple. I.e., it is not allowed that the last field would
4456
		just contain n first bytes of the full field value.
4457
		MySQL uses a 'padding' trick to convert LIKE 'abc%'
4458
		type queries so that it can use as a search tuple
4459
		a complete-field-prefix of a key value. Thus, the InnoDB
4460
		search mode PAGE_CUR_LE_OR_EXTENDS is never used.
4461
		TODO: when/if MySQL starts to use also partial-field
4462
		prefixes, we have to deal with stripping of spaces
4463
		and comparison of non-latin1 char type fields in
4464
		innobase_mysql_cmp() to get PAGE_CUR_LE_OR_EXTENDS to
4465
		work correctly. */
4466
	case HA_READ_MBR_CONTAIN:
4467
	case HA_READ_MBR_INTERSECT:
4468
	case HA_READ_MBR_WITHIN:
4469
	case HA_READ_MBR_DISJOINT:
4470
	case HA_READ_MBR_EQUAL:
4471
		return(PAGE_CUR_UNSUPP);
4472
	/* do not use "default:" in order to produce a gcc warning:
4473
	enumeration value '...' not handled in switch
4474
	(if -Wswitch or -Wall is used) */
4475
	}
4476
4477
	my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), "this functionality");
4478
4479
	return(PAGE_CUR_UNSUPP);
4480
}
4481
4482
/*
4483
   BACKGROUND INFO: HOW A SELECT SQL QUERY IS EXECUTED
4484
   ---------------------------------------------------
4485
The following does not cover all the details, but explains how we determine
4486
the start of a new SQL statement, and what is associated with it.
4487
4488
For each table in the database the MySQL interpreter may have several
4489
table handle instances in use, also in a single SQL query. For each table
4490
handle instance there is an InnoDB  'prebuilt' struct which contains most
4491
of the InnoDB data associated with this table handle instance.
4492
4493
  A) if the user has not explicitly set any MySQL table level locks:
4494
4495
  1) MySQL calls ::external_lock to set an 'intention' table level lock on
4496
the table of the handle instance. There we set
4497
prebuilt->sql_stat_start = TRUE. The flag sql_stat_start should be set
4498
true if we are taking this table handle instance to use in a new SQL
4499
statement issued by the user. We also increment trx->n_mysql_tables_in_use.
4500
4501
  2) If prebuilt->sql_stat_start == TRUE we 'pre-compile' the MySQL search
4502
instructions to prebuilt->template of the table handle instance in
4503
::index_read. The template is used to save CPU time in large joins.
4504
4505
  3) In row_search_for_mysql, if prebuilt->sql_stat_start is true, we
4506
allocate a new consistent read view for the trx if it does not yet have one,
4507
or in the case of a locking read, set an InnoDB 'intention' table level
4508
lock on the table.
4509
4510
  4) We do the SELECT. MySQL may repeatedly call ::index_read for the
4511
same table handle instance, if it is a join.
4512
4513
  5) When the SELECT ends, MySQL removes its intention table level locks
4514
in ::external_lock. When trx->n_mysql_tables_in_use drops to zero,
4515
 (a) we execute a COMMIT there if the autocommit is on,
4516
 (b) we also release possible 'SQL statement level resources' InnoDB may
4517
have for this SQL statement. The MySQL interpreter does NOT execute
4518
autocommit for pure read transactions, though it should. That is why the
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
4519
table Cursor in that case has to execute the COMMIT in ::external_lock.
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4520
4521
  B) If the user has explicitly set MySQL table level locks, then MySQL
4522
does NOT call ::external_lock at the start of the statement. To determine
4523
when we are at the start of a new SQL statement we at the start of
4524
::index_read also compare the query id to the latest query id where the
4525
table handle instance was used. If it has changed, we know we are at the
4526
start of a new SQL statement. Since the query id can theoretically
4527
overwrap, we use this test only as a secondary way of determining the
4528
start of a new SQL statement. */
4529
4530
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4531
/**********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4532
Positions an index cursor to the index specified in the handle. Fetches the
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4533
row if any.
4534
@return	0, HA_ERR_KEY_NOT_FOUND, or error number */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4535
UNIV_INTERN
4536
int
4537
ha_innobase::index_read(
4538
/*====================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
4539
	unsigned char*		buf,	/*!< in/out: buffer for the returned
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4540
					row */
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
4541
	const unsigned char*	key_ptr,/*!< in: key value; if this is NULL
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4542
					we position the cursor at the
4543
					start or end of index; this can
4544
					also contain an InnoDB row id, in
4545
					which case key_len is the InnoDB
4546
					row id length; the key value can
4547
					also be a prefix of a full key value,
4548
					and the last column can be a prefix
4549
					of a full column */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4550
	uint			key_len,/*!< in: key value length */
4551
	enum ha_rkey_function find_flag)/*!< in: search flags from my_base.h */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4552
{
4553
	ulint		mode;
4554
	dict_index_t*	index;
4555
	ulint		match_mode	= 0;
4556
	int		error;
4557
	ulint		ret;
4558
641.1.4 by Monty Taylor
Merged in InnoDB changes.
4559
	ut_a(prebuilt->trx == session_to_trx(user_session));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4560
4561
	ha_statistic_increment(&SSV::ha_read_key_count);
4562
4563
	index = prebuilt->index;
4564
4565
	/* Note that if the index for which the search template is built is not
4566
	necessarily prebuilt->index, but can also be the clustered index */
4567
4568
	if (prebuilt->sql_stat_start) {
641.1.4 by Monty Taylor
Merged in InnoDB changes.
4569
		build_template(prebuilt, user_session, table,
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
4570
			       ROW_MYSQL_REC_FIELDS);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4571
	}
4572
4573
	if (key_ptr) {
4574
		/* Convert the search key value to InnoDB format into
4575
		prebuilt->search_tuple */
4576
4577
		row_sel_convert_mysql_key_to_innobase(
4578
			prebuilt->search_tuple,
4579
			(byte*) key_val_buff,
4580
			(ulint)upd_and_key_val_buff_len,
4581
			index,
4582
			(byte*) key_ptr,
4583
			(ulint) key_len,
4584
			prebuilt->trx);
4585
	} else {
4586
		/* We position the cursor to the last or the first entry
4587
		in the index */
4588
4589
		dtuple_set_n_fields(prebuilt->search_tuple, 0);
4590
	}
4591
4592
	mode = convert_search_mode_to_innobase(find_flag);
4593
4594
	match_mode = 0;
4595
4596
	if (find_flag == HA_READ_KEY_EXACT) {
4597
4598
		match_mode = ROW_SEL_EXACT;
4599
4600
	} else if (find_flag == HA_READ_PREFIX
4601
		   || find_flag == HA_READ_PREFIX_LAST) {
4602
4603
		match_mode = ROW_SEL_EXACT_PREFIX;
4604
	}
4605
4606
	last_match_mode = (uint) match_mode;
4607
4608
	if (mode != PAGE_CUR_UNSUPP) {
4609
4610
		innodb_srv_conc_enter_innodb(prebuilt->trx);
4611
4612
		ret = row_search_for_mysql((byte*) buf, mode, prebuilt,
4613
					   match_mode, 0);
4614
4615
		innodb_srv_conc_exit_innodb(prebuilt->trx);
4616
	} else {
4617
4618
		ret = DB_UNSUPPORTED;
4619
	}
4620
4621
	switch (ret) {
4622
	case DB_SUCCESS:
4623
		error = 0;
4624
		table->status = 0;
4625
		break;
4626
	case DB_RECORD_NOT_FOUND:
4627
		error = HA_ERR_KEY_NOT_FOUND;
4628
		table->status = STATUS_NOT_FOUND;
4629
		break;
4630
	case DB_END_OF_INDEX:
4631
		error = HA_ERR_KEY_NOT_FOUND;
4632
		table->status = STATUS_NOT_FOUND;
4633
		break;
4634
	default:
4635
		error = convert_error_code_to_mysql((int) ret,
4636
						    prebuilt->table->flags,
641.1.4 by Monty Taylor
Merged in InnoDB changes.
4637
						    user_session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4638
		table->status = STATUS_NOT_FOUND;
4639
		break;
4640
	}
4641
641.1.4 by Monty Taylor
Merged in InnoDB changes.
4642
	return(error);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4643
}
4644
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4645
/*******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4646
The following functions works like index_read, but it find the last
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4647
row with the current key value or prefix.
4648
@return	0, HA_ERR_KEY_NOT_FOUND, or an error code */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4649
UNIV_INTERN
4650
int
4651
ha_innobase::index_read_last(
4652
/*=========================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
4653
	unsigned char*	buf,	/*!< out: fetched row */
4654
	const unsigned char*	key_ptr,/*!< in: key value, or a prefix of a full
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4655
				key value */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4656
	uint		key_len)/*!< in: length of the key val or prefix
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4657
				in bytes */
4658
{
4659
	return(index_read(buf, key_ptr, key_len, HA_READ_PREFIX_LAST));
4660
}
4661
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4662
/********************************************************************//**
4663
Get the index for a handle. Does not change active index.
4664
@return	NULL or index instance. */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4665
UNIV_INTERN
4666
dict_index_t*
4667
ha_innobase::innobase_get_index(
4668
/*============================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4669
	uint		keynr)	/*!< in: use this index; MAX_KEY means always
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4670
				clustered index, even if it was internally
4671
				generated by InnoDB */
4672
{
4673
	KEY*		key = 0;
4674
	dict_index_t*	index = 0;
4675
4676
	ha_statistic_increment(&SSV::ha_read_key_count);
4677
641.1.4 by Monty Taylor
Merged in InnoDB changes.
4678
	ut_ad(user_session == ha_session());
4679
	ut_a(prebuilt->trx == session_to_trx(user_session));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4680
4681
	if (keynr != MAX_KEY && table->s->keys > 0) {
4682
		key = table->key_info + keynr;
4683
4684
		index = dict_table_get_index_on_name(prebuilt->table,
4685
						     key->name);
4686
	} else {
4687
		index = dict_table_get_first_index(prebuilt->table);
4688
	}
4689
4690
	if (!index) {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
4691
		errmsg_printf(ERRMSG_LVL_ERROR, 
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4692
			"Innodb could not find key n:o %u with name %s "
4693
			"from dict cache for table %s",
4694
			keynr, key ? key->name : "NULL",
4695
			prebuilt->table->name);
4696
	}
4697
641.1.4 by Monty Taylor
Merged in InnoDB changes.
4698
	return(index);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4699
}
4700
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4701
/********************************************************************//**
4702
Changes the active index of a handle.
4703
@return	0 or error code */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4704
UNIV_INTERN
4705
int
4706
ha_innobase::change_active_index(
4707
/*=============================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4708
	uint	keynr)	/*!< in: use this index; MAX_KEY means always clustered
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4709
			index, even if it was internally generated by
4710
			InnoDB */
4711
{
641.1.4 by Monty Taylor
Merged in InnoDB changes.
4712
	ut_ad(user_session == ha_session());
4713
	ut_a(prebuilt->trx == session_to_trx(user_session));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4714
4715
	active_index = keynr;
4716
4717
	prebuilt->index = innobase_get_index(keynr);
4718
4719
	if (UNIV_UNLIKELY(!prebuilt->index)) {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
4720
		errmsg_printf(ERRMSG_LVL_WARN, "InnoDB: change_active_index(%u) failed",
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4721
				  keynr);
641.1.4 by Monty Taylor
Merged in InnoDB changes.
4722
		return(1);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4723
	}
4724
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4725
	prebuilt->index_usable = row_merge_is_index_usable(prebuilt->trx,
4726
							   prebuilt->index);
4727
4728
	if (UNIV_UNLIKELY(!prebuilt->index_usable)) {
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
4729
		errmsg_printf(ERRMSG_LVL_WARN,
4730
				 "InnoDB: insufficient history for index %u",
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4731
				  keynr);
4732
		/* The caller seems to ignore this.  Thus, we must check
4733
		this again in row_search_for_mysql(). */
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
4734
		return(2);
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4735
	}
4736
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4737
	ut_a(prebuilt->search_tuple != 0);
4738
4739
	dtuple_set_n_fields(prebuilt->search_tuple, prebuilt->index->n_fields);
4740
4741
	dict_index_copy_types(prebuilt->search_tuple, prebuilt->index,
4742
			prebuilt->index->n_fields);
4743
4744
	/* MySQL changes the active index for a handle also during some
4745
	queries, for example SELECT MAX(a), SUM(a) first retrieves the MAX()
4746
	and then calculates the sum. Previously we played safe and used
4747
	the flag ROW_MYSQL_WHOLE_ROW below, but that caused unnecessary
4748
	copying. Starting from MySQL-4.1 we use a more efficient flag here. */
4749
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
4750
	build_template(prebuilt, user_session, table, ROW_MYSQL_REC_FIELDS);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4751
641.1.4 by Monty Taylor
Merged in InnoDB changes.
4752
	return(0);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4753
}
4754
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4755
/**********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4756
Positions an index cursor to the index specified in keynr. Fetches the
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4757
row if any.
4758
??? This is only used to read whole keys ???
4759
@return	error number or 0 */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4760
UNIV_INTERN
4761
int
4762
ha_innobase::index_read_idx(
4763
/*========================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
4764
	unsigned char*	buf,		/*!< in/out: buffer for the returned
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4765
					row */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4766
	uint		keynr,		/*!< in: use this index */
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
4767
	const unsigned char*	key,	/*!< in: key value; if this is NULL
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4768
					we position the cursor at the
4769
					start or end of index */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4770
	uint		key_len,	/*!< in: key value length */
4771
	enum ha_rkey_function find_flag)/*!< in: search flags from my_base.h */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4772
{
4773
	if (change_active_index(keynr)) {
4774
4775
		return(1);
4776
	}
4777
4778
	return(index_read(buf, key, key_len, find_flag));
4779
}
4780
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4781
/***********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4782
Reads the next or previous row from a cursor, which must have previously been
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4783
positioned using index_read.
4784
@return	0, HA_ERR_END_OF_FILE, or error number */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4785
UNIV_INTERN
4786
int
4787
ha_innobase::general_fetch(
4788
/*=======================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
4789
	unsigned char*	buf,	/*!< in/out: buffer for next row in MySQL
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4790
				format */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4791
	uint	direction,	/*!< in: ROW_SEL_NEXT or ROW_SEL_PREV */
4792
	uint	match_mode)	/*!< in: 0, ROW_SEL_EXACT, or
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4793
				ROW_SEL_EXACT_PREFIX */
4794
{
4795
	ulint		ret;
4796
	int		error	= 0;
4797
641.1.4 by Monty Taylor
Merged in InnoDB changes.
4798
	ut_a(prebuilt->trx == session_to_trx(user_session));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4799
4800
	innodb_srv_conc_enter_innodb(prebuilt->trx);
4801
4802
	ret = row_search_for_mysql(
4803
		(byte*)buf, 0, prebuilt, match_mode, direction);
4804
4805
	innodb_srv_conc_exit_innodb(prebuilt->trx);
4806
4807
	switch (ret) {
4808
	case DB_SUCCESS:
4809
		error = 0;
4810
		table->status = 0;
4811
		break;
4812
	case DB_RECORD_NOT_FOUND:
4813
		error = HA_ERR_END_OF_FILE;
4814
		table->status = STATUS_NOT_FOUND;
4815
		break;
4816
	case DB_END_OF_INDEX:
4817
		error = HA_ERR_END_OF_FILE;
4818
		table->status = STATUS_NOT_FOUND;
4819
		break;
4820
	default:
4821
		error = convert_error_code_to_mysql(
641.1.4 by Monty Taylor
Merged in InnoDB changes.
4822
			(int) ret, prebuilt->table->flags, user_session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4823
		table->status = STATUS_NOT_FOUND;
4824
		break;
4825
	}
4826
641.1.4 by Monty Taylor
Merged in InnoDB changes.
4827
	return(error);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4828
}
4829
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4830
/***********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4831
Reads the next row from a cursor, which must have previously been
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4832
positioned using index_read.
4833
@return	0, HA_ERR_END_OF_FILE, or error number */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4834
UNIV_INTERN
4835
int
4836
ha_innobase::index_next(
4837
/*====================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
4838
	unsigned char*	buf)	/*!< in/out: buffer for next row in MySQL
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4839
				format */
4840
{
4841
	ha_statistic_increment(&SSV::ha_read_next_count);
4842
4843
	return(general_fetch(buf, ROW_SEL_NEXT, 0));
4844
}
4845
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4846
/*******************************************************************//**
4847
Reads the next row matching to the key value given as the parameter.
4848
@return	0, HA_ERR_END_OF_FILE, or error number */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4849
UNIV_INTERN
4850
int
4851
ha_innobase::index_next_same(
4852
/*=========================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
4853
	unsigned char*		buf,	/*!< in/out: buffer for the row */
4854
	const unsigned char*	,	/*!< in: key value */
4855
	uint		)	/*!< in: key value length */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4856
{
4857
	ha_statistic_increment(&SSV::ha_read_next_count);
4858
4859
	return(general_fetch(buf, ROW_SEL_NEXT, last_match_mode));
4860
}
4861
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4862
/***********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4863
Reads the previous row from a cursor, which must have previously been
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4864
positioned using index_read.
4865
@return	0, HA_ERR_END_OF_FILE, or error number */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4866
UNIV_INTERN
4867
int
4868
ha_innobase::index_prev(
4869
/*====================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
4870
	unsigned char*	buf)	/*!< in/out: buffer for previous row in MySQL format */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4871
{
4872
	ha_statistic_increment(&SSV::ha_read_prev_count);
4873
4874
	return(general_fetch(buf, ROW_SEL_PREV, 0));
4875
}
4876
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4877
/********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4878
Positions a cursor on the first record in an index and reads the
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4879
corresponding row to buf.
4880
@return	0, HA_ERR_END_OF_FILE, or error code */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4881
UNIV_INTERN
4882
int
4883
ha_innobase::index_first(
4884
/*=====================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
4885
	unsigned char*	buf)	/*!< in/out: buffer for the row */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4886
{
4887
	int	error;
4888
4889
	ha_statistic_increment(&SSV::ha_read_first_count);
4890
4891
	error = index_read(buf, NULL, 0, HA_READ_AFTER_KEY);
4892
4893
	/* MySQL does not seem to allow this to return HA_ERR_KEY_NOT_FOUND */
4894
4895
	if (error == HA_ERR_KEY_NOT_FOUND) {
4896
		error = HA_ERR_END_OF_FILE;
4897
	}
4898
641.1.4 by Monty Taylor
Merged in InnoDB changes.
4899
	return(error);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4900
}
4901
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4902
/********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4903
Positions a cursor on the last record in an index and reads the
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4904
corresponding row to buf.
4905
@return	0, HA_ERR_END_OF_FILE, or error code */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4906
UNIV_INTERN
4907
int
4908
ha_innobase::index_last(
4909
/*====================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
4910
	unsigned char*	buf)	/*!< in/out: buffer for the row */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4911
{
4912
	int	error;
4913
4914
	ha_statistic_increment(&SSV::ha_read_last_count);
4915
4916
	error = index_read(buf, NULL, 0, HA_READ_BEFORE_KEY);
4917
4918
	/* MySQL does not seem to allow this to return HA_ERR_KEY_NOT_FOUND */
4919
4920
	if (error == HA_ERR_KEY_NOT_FOUND) {
4921
		error = HA_ERR_END_OF_FILE;
4922
	}
4923
641.1.4 by Monty Taylor
Merged in InnoDB changes.
4924
	return(error);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4925
}
4926
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4927
/****************************************************************//**
4928
Initialize a table scan.
4929
@return	0 or error number */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4930
UNIV_INTERN
4931
int
4932
ha_innobase::rnd_init(
4933
/*==================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4934
	bool	scan)	/*!< in: TRUE if table/index scan FALSE otherwise */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4935
{
4936
	int	err;
4937
4938
	/* Store the active index value so that we can restore the original
4939
	value after a scan */
4940
4941
	if (prebuilt->clust_index_was_generated) {
4942
		err = change_active_index(MAX_KEY);
4943
	} else {
4944
		err = change_active_index(primary_key);
4945
	}
4946
4947
	/* Don't use semi-consistent read in random row reads (by position).
4948
	This means we must disable semi_consistent_read if scan is false */
4949
4950
	if (!scan) {
4951
		try_semi_consistent_read(0);
4952
	}
4953
4954
	start_of_scan = 1;
4955
4956
	return(err);
4957
}
4958
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4959
/*****************************************************************//**
4960
Ends a table scan.
4961
@return	0 or error number */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4962
UNIV_INTERN
4963
int
4964
ha_innobase::rnd_end(void)
4965
/*======================*/
4966
{
4967
	return(index_end());
4968
}
4969
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4970
/*****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4971
Reads the next row in a table scan (also used to read the FIRST row
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4972
in a table scan).
4973
@return	0, HA_ERR_END_OF_FILE, or error number */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4974
UNIV_INTERN
4975
int
4976
ha_innobase::rnd_next(
4977
/*==================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
4978
	unsigned char*	buf)	/*!< in/out: returns the row in this buffer,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4979
			in MySQL format */
4980
{
4981
	int	error;
4982
4983
	ha_statistic_increment(&SSV::ha_read_rnd_next_count);
4984
4985
	if (start_of_scan) {
4986
		error = index_first(buf);
4987
4988
		if (error == HA_ERR_KEY_NOT_FOUND) {
4989
			error = HA_ERR_END_OF_FILE;
4990
		}
4991
4992
		start_of_scan = 0;
4993
	} else {
4994
		error = general_fetch(buf, ROW_SEL_NEXT, 0);
4995
	}
4996
641.1.4 by Monty Taylor
Merged in InnoDB changes.
4997
	return(error);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
4998
}
4999
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
5000
/**********************************************************************//**
5001
Fetches a row from the table based on a row reference.
5002
@return	0, HA_ERR_KEY_NOT_FOUND, or error code */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5003
UNIV_INTERN
5004
int
5005
ha_innobase::rnd_pos(
5006
/*=================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
5007
	unsigned char*	buf,	/*!< in/out: buffer for the row */
5008
	unsigned char*	pos)	/*!< in: primary key value of the row in the
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5009
			MySQL format, or the row id if the clustered
5010
			index was internally generated by InnoDB; the
5011
			length of data in pos has to be ref_length */
5012
{
5013
	int		error;
5014
	uint		keynr	= active_index;
5015
5016
	ha_statistic_increment(&SSV::ha_read_rnd_count);
5017
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5018
	ut_a(prebuilt->trx == session_to_trx(ha_session()));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5019
5020
	if (prebuilt->clust_index_was_generated) {
5021
		/* No primary key was defined for the table and we
5022
		generated the clustered index from the row id: the
5023
		row reference is the row id, not any key value
5024
		that MySQL knows of */
5025
5026
		error = change_active_index(MAX_KEY);
5027
	} else {
5028
		error = change_active_index(primary_key);
5029
	}
5030
5031
	if (error) {
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5032
		return(error);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5033
	}
5034
5035
	/* Note that we assume the length of the row reference is fixed
5036
	for the table, and it is == ref_length */
5037
5038
	error = index_read(buf, pos, ref_length, HA_READ_KEY_EXACT);
5039
5040
	if (error) {
5041
	}
5042
5043
	change_active_index(keynr);
5044
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5045
	return(error);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5046
}
5047
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
5048
/*********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5049
Stores a reference to the current row to 'ref' field of the handle. Note
5050
that in the case where we have generated the clustered index for the
5051
table, the function parameter is illogical: we MUST ASSUME that 'record'
5052
is the current 'position' of the handle, because if row ref is actually
5053
the row id internally generated in InnoDB, then 'record' does not contain
5054
it. We just guess that the row id must be for the record where the handle
5055
was positioned the last time. */
5056
UNIV_INTERN
5057
void
5058
ha_innobase::position(
5059
/*==================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
5060
	const unsigned char*	record)	/*!< in: row in MySQL format */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5061
{
5062
	uint		len;
5063
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5064
	ut_a(prebuilt->trx == session_to_trx(ha_session()));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5065
5066
	if (prebuilt->clust_index_was_generated) {
5067
		/* No primary key was defined for the table and we
5068
		generated the clustered index from row id: the
5069
		row reference will be the row id, not any key value
5070
		that MySQL knows of */
5071
5072
		len = DATA_ROW_ID_LEN;
5073
5074
		memcpy(ref, prebuilt->row_id, len);
5075
	} else {
5076
		len = store_key_val_for_row(primary_key, (char*)ref,
5077
							 ref_length, record);
5078
	}
5079
5080
	/* We assume that the 'ref' value len is always fixed for the same
5081
	table. */
5082
5083
	if (len != ref_length) {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
5084
	  errmsg_printf(ERRMSG_LVL_ERROR, "Stored ref len is %lu, but table ref len is %lu",
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5085
			  (ulong) len, (ulong) ref_length);
5086
	}
5087
}
5088
5089
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
5090
/*****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5091
Creates a table definition to an InnoDB database. */
5092
static
5093
int
5094
create_table_def(
5095
/*=============*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
5096
	trx_t*		trx,		/*!< in: InnoDB transaction handle */
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
5097
	Table*		form,		/*!< in: information on table
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5098
					columns and indexes */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
5099
	const char*	table_name,	/*!< in: table name */
5100
	const char*	path_of_temp_table,/*!< in: if this is a table explicitly
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5101
					created by the user with the
5102
					TEMPORARY keyword, then this
5103
					parameter is the dir path where the
5104
					table should be placed if we create
5105
					an .ibd file for it (no .ibd extension
5106
					in the path, though); otherwise this
5107
					is NULL */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
5108
	ulint		flags)		/*!< in: table flags */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5109
{
5110
	Field*		field;
5111
	dict_table_t*	table;
5112
	ulint		n_cols;
5113
	int		error;
5114
	ulint		col_type;
5115
	ulint		col_len;
5116
	ulint		nulls_allowed;
5117
	ulint		unsigned_type;
5118
	ulint		binary_type;
5119
	ulint		long_true_varchar;
5120
	ulint		charset_no;
5121
	ulint		i;
5122
5123
	n_cols = form->s->fields;
5124
5125
	/* We pass 0 as the space id, and determine at a lower level the space
5126
	id where to store the table */
5127
5128
	table = dict_mem_table_create(table_name, 0, n_cols, flags);
5129
5130
	if (path_of_temp_table) {
5131
		table->dir_path_of_temp_table =
5132
			mem_heap_strdup(table->heap, path_of_temp_table);
5133
	}
5134
5135
	for (i = 0; i < n_cols; i++) {
5136
		field = form->field[i];
5137
5138
		col_type = get_innobase_type_from_mysql_type(&unsigned_type,
5139
									field);
5140
		if (field->null_ptr) {
5141
			nulls_allowed = 0;
5142
		} else {
5143
			nulls_allowed = DATA_NOT_NULL;
5144
		}
5145
5146
		if (field->binary()) {
5147
			binary_type = DATA_BINARY_TYPE;
5148
		} else {
5149
			binary_type = 0;
5150
		}
5151
5152
		charset_no = 0;
5153
5154
		if (dtype_is_string_type(col_type)) {
5155
5156
			charset_no = (ulint)field->charset()->number;
5157
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
5158
			if (UNIV_UNLIKELY(charset_no >= 256)) {
5159
				/* in data0type.h we assume that the
5160
				number fits in one byte in prtype */
5161
				push_warning_printf(
933.1.2 by Monty Taylor
Fixed merge weirdness errors.
5162
					(Session*) trx->mysql_thd,
5163
					DRIZZLE_ERROR::WARN_LEVEL_ERROR,
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
5164
					ER_CANT_CREATE_TABLE,
5165
					"In InnoDB, charset-collation codes"
5166
					" must be below 256."
5167
					" Unsupported code %lu.",
5168
					(ulong) charset_no);
933.1.2 by Monty Taylor
Fixed merge weirdness errors.
5169
				return(ER_CANT_CREATE_TABLE);
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
5170
			}
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5171
		}
5172
5173
		ut_a(field->type() < 256); /* we assume in dtype_form_prtype()
5174
					   that this fits in one byte */
5175
		col_len = field->pack_length();
5176
5177
		/* The MySQL pack length contains 1 or 2 bytes length field
5178
		for a true VARCHAR. Let us subtract that, so that the InnoDB
5179
		column length in the InnoDB data dictionary is the real
5180
		maximum byte length of the actual data. */
5181
5182
		long_true_varchar = 0;
5183
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5184
		if (field->type() == DRIZZLE_TYPE_VARCHAR) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5185
			col_len -= ((Field_varstring*)field)->length_bytes;
5186
5187
			if (((Field_varstring*)field)->length_bytes == 2) {
5188
				long_true_varchar = DATA_LONG_TRUE_VARCHAR;
5189
			}
5190
		}
5191
5192
		dict_mem_table_add_col(table, table->heap,
5193
			(char*) field->field_name,
5194
			col_type,
5195
			dtype_form_prtype(
5196
				(ulint)field->type()
5197
				| nulls_allowed | unsigned_type
5198
				| binary_type | long_true_varchar,
5199
				charset_no),
5200
			col_len);
5201
	}
5202
5203
	error = row_create_table_for_mysql(table, trx);
5204
5205
	error = convert_error_code_to_mysql(error, flags, NULL);
5206
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5207
	return(error);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5208
}
5209
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
5210
/*****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5211
Creates an index in an InnoDB database. */
5212
static
5213
int
5214
create_index(
5215
/*=========*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
5216
	trx_t*		trx,		/*!< in: InnoDB transaction handle */
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
5217
	Table*		form,		/*!< in: information on table
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5218
					columns and indexes */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
5219
	ulint		flags,		/*!< in: InnoDB table flags */
5220
	const char*	table_name,	/*!< in: table name */
5221
	uint		key_num)	/*!< in: index number */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5222
{
5223
	Field*		field;
5224
	dict_index_t*	index;
5225
	int		error;
5226
	ulint		n_fields;
5227
	KEY*		key;
5228
	KEY_PART_INFO*	key_part;
5229
	ulint		ind_type;
5230
	ulint		col_type;
5231
	ulint		prefix_len;
5232
	ulint		is_unsigned;
5233
	ulint		i;
5234
	ulint		j;
5235
	ulint*		field_lengths;
5236
5237
	key = form->key_info + key_num;
5238
5239
	n_fields = key->key_parts;
5240
5241
	ind_type = 0;
5242
5243
	if (key_num == form->s->primary_key) {
5244
		ind_type = ind_type | DICT_CLUSTERED;
5245
	}
5246
5247
	if (key->flags & HA_NOSAME ) {
5248
		ind_type = ind_type | DICT_UNIQUE;
5249
	}
5250
5251
	/* We pass 0 as the space id, and determine at a lower level the space
5252
	id where to store the table */
5253
5254
	index = dict_mem_index_create(table_name, key->name, 0,
5255
				      ind_type, n_fields);
5256
641.3.6 by Monty Taylor
Removed some my_malloc calls.
5257
	field_lengths = (ulint*) malloc(sizeof(ulint) * n_fields);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5258
5259
	for (i = 0; i < n_fields; i++) {
5260
		key_part = key->key_part + i;
5261
5262
		/* (The flag HA_PART_KEY_SEG denotes in MySQL a column prefix
5263
		field in an index: we only store a specified number of first
5264
		bytes of the column to the index field.) The flag does not
5265
		seem to be properly set by MySQL. Let us fall back on testing
5266
		the length of the key part versus the column. */
5267
5268
		field = NULL;
5269
		for (j = 0; j < form->s->fields; j++) {
5270
5271
			field = form->field[j];
5272
5273
			if (0 == innobase_strcasecmp(
5274
					field->field_name,
5275
					key_part->field->field_name)) {
5276
				/* Found the corresponding column */
5277
5278
				break;
5279
			}
5280
		}
5281
5282
		ut_a(j < form->s->fields);
5283
5284
		col_type = get_innobase_type_from_mysql_type(
5285
					&is_unsigned, key_part->field);
5286
5287
		if (DATA_BLOB == col_type
5288
			|| (key_part->length < field->pack_length()
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5289
				&& field->type() != DRIZZLE_TYPE_VARCHAR)
5290
			|| (field->type() == DRIZZLE_TYPE_VARCHAR
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5291
				&& key_part->length < field->pack_length()
5292
				- ((Field_varstring*)field)->length_bytes)) {
5293
5294
			prefix_len = key_part->length;
5295
5296
			if (col_type == DATA_INT
5297
				|| col_type == DATA_FLOAT
5298
				|| col_type == DATA_DOUBLE
5299
				|| col_type == DATA_DECIMAL) {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
5300
				errmsg_printf(ERRMSG_LVL_ERROR, 
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5301
					"MySQL is trying to create a column "
5302
					"prefix index field, on an "
5303
					"inappropriate data type. Table "
5304
					"name %s, column name %s.",
5305
					table_name,
5306
					key_part->field->field_name);
5307
5308
				prefix_len = 0;
5309
			}
5310
		} else {
5311
			prefix_len = 0;
5312
		}
5313
5314
		field_lengths[i] = key_part->length;
5315
5316
		dict_mem_index_add_field(index,
5317
			(char*) key_part->field->field_name, prefix_len);
5318
	}
5319
5320
	/* Even though we've defined max_supported_key_part_length, we
5321
	still do our own checking using field_lengths to be absolutely
5322
	sure we don't create too long indexes. */
5323
	error = row_create_index_for_mysql(index, trx, field_lengths);
5324
5325
	error = convert_error_code_to_mysql(error, flags, NULL);
5326
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5327
	free(field_lengths);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5328
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5329
	return(error);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5330
}
5331
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
5332
/*****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5333
Creates an index to an InnoDB table when the user has defined no
5334
primary index. */
5335
static
5336
int
5337
create_clustered_index_when_no_primary(
5338
/*===================================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
5339
	trx_t*		trx,		/*!< in: InnoDB transaction handle */
5340
	ulint		flags,		/*!< in: InnoDB table flags */
5341
	const char*	table_name)	/*!< in: table name */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5342
{
5343
	dict_index_t*	index;
5344
	int		error;
5345
5346
	/* We pass 0 as the space id, and determine at a lower level the space
5347
	id where to store the table */
5348
5349
	index = dict_mem_index_create(table_name, "GEN_CLUST_INDEX",
5350
				      0, DICT_CLUSTERED, 0);
5351
5352
	error = row_create_index_for_mysql(index, trx, NULL);
5353
5354
	error = convert_error_code_to_mysql(error, flags, NULL);
5355
5356
	return(error);
5357
}
5358
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
5359
/*****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5360
Validates the create options. We may build on this function
5361
in future. For now, it checks two specifiers:
5362
KEY_BLOCK_SIZE and ROW_FORMAT
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
5363
If innodb_strict_mode is not set then this function is a no-op
5364
@return	TRUE if valid. */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5365
static
5366
ibool
5367
create_options_are_valid(
5368
/*=====================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
5369
	Session*	session,	/*!< in: connection thread. */
1198 by Brian Aker
Merge Brian
5370
	Table&		form,		/*!< in: information on table
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5371
					columns and indexes */
1198 by Brian Aker
Merge Brian
5372
        drizzled::message::Table& create_proto)
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5373
{
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5374
	ibool	kbs_specified	= FALSE;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5375
	ibool	ret		= TRUE;
5376
5377
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5378
	ut_ad(session != NULL);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5379
5380
	/* If innodb_strict_mode is not set don't do any validation. */
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5381
	if (!(SessionVAR(session, strict_mode))) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5382
		return(TRUE);
5383
	}
5384
5385
	/* First check if KEY_BLOCK_SIZE was specified. */
1198 by Brian Aker
Merge Brian
5386
	if (create_proto.options().has_key_block_size()) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5387
5388
		kbs_specified = TRUE;
1198 by Brian Aker
Merge Brian
5389
		switch (create_proto.options().key_block_size()) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5390
		case 1:
5391
		case 2:
5392
		case 4:
5393
		case 8:
5394
		case 16:
5395
			/* Valid value. */
5396
			break;
5397
		default:
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5398
			push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5399
					    ER_ILLEGAL_HA_CREATE_OPTION,
5400
					    "InnoDB: invalid"
5401
					    " KEY_BLOCK_SIZE = %lu."
5402
					    " Valid values are"
5403
					    " [1, 2, 4, 8, 16]",
1198 by Brian Aker
Merge Brian
5404
					    create_proto.options().key_block_size());
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5405
			ret = FALSE;
5406
		}
5407
	}
5408
	
5409
	/* If KEY_BLOCK_SIZE was specified, check for its
5410
	dependencies. */
5411
	if (kbs_specified && !srv_file_per_table) {
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5412
		push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5413
			     ER_ILLEGAL_HA_CREATE_OPTION,
5414
			     "InnoDB: KEY_BLOCK_SIZE"
5415
			     " requires innodb_file_per_table.");
5416
		ret = FALSE;
5417
	}
5418
5419
	if (kbs_specified && srv_file_format < DICT_TF_FORMAT_ZIP) {
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5420
		push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5421
			     ER_ILLEGAL_HA_CREATE_OPTION,
5422
			     "InnoDB: KEY_BLOCK_SIZE"
5423
			     " requires innodb_file_format >"
5424
			     " Antelope.");
5425
		ret = FALSE;
5426
	}
5427
5428
	/* Now check for ROW_FORMAT specifier. */
1222.1.6 by Brian Aker
Fix engines to not rely on HA_CREATE_INFO.
5429
	if (create_proto.options().has_row_type()) {
1198 by Brian Aker
Merge Brian
5430
		switch (form.s->row_type) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5431
			const char* row_format_name;
5432
		case ROW_TYPE_COMPRESSED:
5433
		case ROW_TYPE_DYNAMIC:
5434
			row_format_name
1198 by Brian Aker
Merge Brian
5435
				= form.s->row_type == ROW_TYPE_COMPRESSED
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5436
				? "COMPRESSED"
5437
				: "DYNAMIC";
5438
5439
			/* These two ROW_FORMATs require
5440
			srv_file_per_table and srv_file_format */
5441
			if (!srv_file_per_table) {
5442
				push_warning_printf(
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5443
					session,
5444
					DRIZZLE_ERROR::WARN_LEVEL_ERROR,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5445
					ER_ILLEGAL_HA_CREATE_OPTION,
5446
					"InnoDB: ROW_FORMAT=%s"
5447
					" requires innodb_file_per_table.",
5448
					row_format_name);
5449
					ret = FALSE;
5450
5451
			}
5452
5453
			if (srv_file_format < DICT_TF_FORMAT_ZIP) {
5454
				push_warning_printf(
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5455
					session,
5456
					DRIZZLE_ERROR::WARN_LEVEL_ERROR,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5457
					ER_ILLEGAL_HA_CREATE_OPTION,
5458
					"InnoDB: ROW_FORMAT=%s"
5459
					" requires innodb_file_format >"
5460
					" Antelope.",
5461
					row_format_name);
5462
					ret = FALSE;
5463
			}
5464
5465
			/* Cannot specify KEY_BLOCK_SIZE with
5466
			ROW_FORMAT = DYNAMIC.
5467
			However, we do allow COMPRESSED to be
5468
			specified with KEY_BLOCK_SIZE. */
5469
			if (kbs_specified
1198 by Brian Aker
Merge Brian
5470
			    && form.s->row_type == ROW_TYPE_DYNAMIC) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5471
				push_warning_printf(
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5472
					session,
5473
					DRIZZLE_ERROR::WARN_LEVEL_ERROR,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5474
					ER_ILLEGAL_HA_CREATE_OPTION,
5475
					"InnoDB: cannot specify"
5476
					" ROW_FORMAT = DYNAMIC with"
5477
					" KEY_BLOCK_SIZE.");
5478
					ret = FALSE;
5479
			}
5480
5481
			break;
5482
5483
		case ROW_TYPE_REDUNDANT:
5484
		case ROW_TYPE_COMPACT:
5485
		case ROW_TYPE_DEFAULT:
5486
			/* Default is COMPACT. */
5487
			row_format_name
1198 by Brian Aker
Merge Brian
5488
				= form.s->row_type == ROW_TYPE_REDUNDANT
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5489
				? "REDUNDANT"
5490
				: "COMPACT";
5491
5492
			/* Cannot specify KEY_BLOCK_SIZE with these
5493
			format specifiers. */
5494
			if (kbs_specified) {
5495
				push_warning_printf(
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5496
					session,
5497
					DRIZZLE_ERROR::WARN_LEVEL_ERROR,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5498
					ER_ILLEGAL_HA_CREATE_OPTION,
5499
					"InnoDB: cannot specify"
5500
					" ROW_FORMAT = %s with"
5501
					" KEY_BLOCK_SIZE.",
5502
					row_format_name);
5503
					ret = FALSE;
5504
			}
5505
5506
			break;
5507
5508
		default:
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5509
			push_warning(session,
5510
				     DRIZZLE_ERROR::WARN_LEVEL_ERROR,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5511
				     ER_ILLEGAL_HA_CREATE_OPTION,
5512
				     "InnoDB: invalid ROW_FORMAT specifier.");
5513
			ret = FALSE;
5514
5515
		}
5516
	}
5517
5518
	return(ret);
5519
}
5520
5521
/*********************************************************************
5522
Creates a new table to an InnoDB database. */
5523
UNIV_INTERN
5524
int
1183.1.6 by Brian Aker
Simplify createTable()
5525
InnobaseEngine::doCreateTable(
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5526
/*================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
5527
	Session*	session,	/*!< in: Session */
5528
	const char*	table_name,	/*!< in: table name */
1183.1.18 by Brian Aker
Fixed references to doCreateTable()
5529
	Table&		form,		/*!< in: information on table
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5530
					columns and indexes */
1198 by Brian Aker
Merge Brian
5531
        drizzled::message::Table& create_proto)
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5532
{
5533
	int		error;
5534
	dict_table_t*	innobase_table;
5535
	trx_t*		parent_trx;
5536
	trx_t*		trx;
5537
	int		primary_key_no;
5538
	uint		i;
5539
	char		name2[FN_REFLEN];
5540
	char		norm_name[FN_REFLEN];
5541
	ib_int64_t	auto_inc_value;
1053 by Brian Aker
Merge Stewart, fix LOCK (it was dead, only for dead RENAME SCHEMA code), and
5542
	ulint		iflags;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5543
	/* Cache the value of innodb_file_format, in case it is
5544
	modified by another thread while the table is being created. */
5545
	const ulint	file_format = srv_file_format;
1222.2.1 by Brian Aker
Takes the majority usage of parser based HA_CREATE_INFO usage around
5546
        bool lex_identified_temp_table= (create_proto.type() == drizzled::message::Table::TEMPORARY);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5547
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5548
	assert(session != NULL);
5549
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
5550
#ifdef __WIN__
5551
	/* Names passed in from server are in two formats:
5552
	1. <database_name>/<table_name>: for normal table creation
5553
	2. full path: for temp table creation, or sym link
5554
5555
	When srv_file_per_table is on, check for full path pattern, i.e.
5556
	X:\dir\...,		X is a driver letter, or
5557
	\\dir1\dir2\...,	UNC path
5558
	returns error if it is in full path format, but not creating a temp.
5559
	table. Currently InnoDB does not support symbolic link on Windows. */
5560
5561
	if (srv_file_per_table
1222.2.1 by Brian Aker
Takes the majority usage of parser based HA_CREATE_INFO usage around
5562
	    && (! lex_identified_temp_table)) {
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
5563
1039.3.3 by Stewart Smith
Move handler::create to StorageEngine::create_table
5564
		if ((table_name[1] == ':')
5565
		    || (table_name[0] == '\\' && table_name[1] == '\\')) {
5566
			errmsg_printf(ERRMSG_LVL_ERROR, "Cannot create table %s\n", table_name);
933.1.2 by Monty Taylor
Fixed merge weirdness errors.
5567
			return(HA_ERR_GENERIC);
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
5568
		}
5569
	}
5570
#endif
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5571
1183.1.18 by Brian Aker
Fixed references to doCreateTable()
5572
	if (form.s->fields > 1000) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5573
		/* The limit probably should be REC_MAX_N_FIELDS - 3 = 1020,
5574
		but we play safe here */
5575
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5576
		return(HA_ERR_TO_BIG_ROW);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5577
	}
5578
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5579
	/* Get the transaction associated with the current session, or create one
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5580
	if not yet created */
5581
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5582
	parent_trx = check_trx_exists(session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5583
5584
	/* In case MySQL calls this in the middle of a SELECT query, release
5585
	possible adaptive hash latch to avoid deadlocks of threads */
5586
5587
	trx_search_latch_release_if_reserved(parent_trx);
5588
933.1.1 by Monty Taylor
Merged in InnoDB Plugin 1.0.3
5589
	trx = innobase_trx_allocate(session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5590
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
5591
	srv_lower_case_table_names = TRUE;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5592
1039.3.3 by Stewart Smith
Move handler::create to StorageEngine::create_table
5593
	strcpy(name2, table_name);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5594
5595
	normalize_table_name(norm_name, name2);
5596
5597
	/* Latch the InnoDB data dictionary exclusively so that no deadlocks
5598
	or lock waits can happen in it during a table create operation.
5599
	Drop table etc. do this latching in row0mysql.c. */
5600
5601
	row_mysql_lock_data_dictionary(trx);
5602
5603
	/* Create the table definition in InnoDB */
5604
1053 by Brian Aker
Merge Stewart, fix LOCK (it was dead, only for dead RENAME SCHEMA code), and
5605
	iflags = 0;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5606
5607
	/* Validate create options if innodb_strict_mode is set. */
1222.1.6 by Brian Aker
Fix engines to not rely on HA_CREATE_INFO.
5608
	if (! create_options_are_valid(session, form, create_proto)) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5609
		error = ER_ILLEGAL_HA_CREATE_OPTION;
5610
		goto cleanup;
5611
	}
5612
1198 by Brian Aker
Merge Brian
5613
	if (create_proto.options().has_key_block_size()) {
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
5614
		/* Determine the page_zip.ssize corresponding to the
5615
		requested page size (key_block_size) in kilobytes. */
5616
5617
		ulint	ssize, ksize;
1198 by Brian Aker
Merge Brian
5618
		ulint	key_block_size = create_proto.options().key_block_size();
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
5619
5620
		for (ssize = ksize = 1; ssize <= DICT_TF_ZSSIZE_MAX;
5621
		     ssize++, ksize <<= 1) {
5622
			if (key_block_size == ksize) {
1053 by Brian Aker
Merge Stewart, fix LOCK (it was dead, only for dead RENAME SCHEMA code), and
5623
				iflags = ssize << DICT_TF_ZSSIZE_SHIFT
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
5624
					| DICT_TF_COMPACT
5625
					| DICT_TF_FORMAT_ZIP
5626
					  << DICT_TF_FORMAT_SHIFT;
5627
				break;
5628
			}
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5629
		}
5630
5631
		if (!srv_file_per_table) {
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5632
			push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5633
				     ER_ILLEGAL_HA_CREATE_OPTION,
5634
				     "InnoDB: KEY_BLOCK_SIZE"
5635
				     " requires innodb_file_per_table.");
1053 by Brian Aker
Merge Stewart, fix LOCK (it was dead, only for dead RENAME SCHEMA code), and
5636
			iflags = 0;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5637
		}
5638
5639
		if (file_format < DICT_TF_FORMAT_ZIP) {
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5640
			push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5641
				     ER_ILLEGAL_HA_CREATE_OPTION,
5642
				     "InnoDB: KEY_BLOCK_SIZE"
5643
				     " requires innodb_file_format >"
5644
				     " Antelope.");
1053 by Brian Aker
Merge Stewart, fix LOCK (it was dead, only for dead RENAME SCHEMA code), and
5645
			iflags = 0;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5646
		}
5647
1053 by Brian Aker
Merge Stewart, fix LOCK (it was dead, only for dead RENAME SCHEMA code), and
5648
		if (!iflags) {
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5649
			push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5650
					    ER_ILLEGAL_HA_CREATE_OPTION,
5651
					    "InnoDB: ignoring"
5652
					    " KEY_BLOCK_SIZE=%lu.",
1198 by Brian Aker
Merge Brian
5653
					    create_proto.options().key_block_size());
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5654
		}
5655
	}
5656
1222.1.6 by Brian Aker
Fix engines to not rely on HA_CREATE_INFO.
5657
	if (create_proto.options().has_row_type()) {
1053 by Brian Aker
Merge Stewart, fix LOCK (it was dead, only for dead RENAME SCHEMA code), and
5658
		if (iflags) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5659
			/* KEY_BLOCK_SIZE was specified. */
1183.1.18 by Brian Aker
Fixed references to doCreateTable()
5660
			if (form.s->row_type != ROW_TYPE_COMPRESSED) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5661
				/* ROW_FORMAT other than COMPRESSED
5662
				ignores KEY_BLOCK_SIZE.  It does not
5663
				make sense to reject conflicting
5664
				KEY_BLOCK_SIZE and ROW_FORMAT, because
5665
				such combinations can be obtained
5666
				with ALTER TABLE anyway. */
5667
				push_warning_printf(
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5668
					session,
5669
					DRIZZLE_ERROR::WARN_LEVEL_WARN,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5670
					ER_ILLEGAL_HA_CREATE_OPTION,
5671
					"InnoDB: ignoring KEY_BLOCK_SIZE=%lu"
5672
					" unless ROW_FORMAT=COMPRESSED.",
1198 by Brian Aker
Merge Brian
5673
					create_proto.options().key_block_size());
1053 by Brian Aker
Merge Stewart, fix LOCK (it was dead, only for dead RENAME SCHEMA code), and
5674
				iflags = 0;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5675
			}
5676
		} else {
5677
			/* No KEY_BLOCK_SIZE */
1183.1.18 by Brian Aker
Fixed references to doCreateTable()
5678
			if (form.s->row_type == ROW_TYPE_COMPRESSED) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5679
				/* ROW_FORMAT=COMPRESSED without
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
5680
				KEY_BLOCK_SIZE implies half the
5681
				maximum KEY_BLOCK_SIZE. */
1053 by Brian Aker
Merge Stewart, fix LOCK (it was dead, only for dead RENAME SCHEMA code), and
5682
				iflags = (DICT_TF_ZSSIZE_MAX - 1)
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
5683
					<< DICT_TF_ZSSIZE_SHIFT
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5684
					| DICT_TF_COMPACT
5685
					| DICT_TF_FORMAT_ZIP
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
5686
					<< DICT_TF_FORMAT_SHIFT;
5687
#if DICT_TF_ZSSIZE_MAX < 1
5688
# error "DICT_TF_ZSSIZE_MAX < 1"
5689
#endif
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5690
			}
5691
		}
5692
1183.1.18 by Brian Aker
Fixed references to doCreateTable()
5693
		switch (form.s->row_type) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5694
			const char* row_format_name;
5695
		case ROW_TYPE_REDUNDANT:
5696
			break;
5697
		case ROW_TYPE_COMPRESSED:
5698
		case ROW_TYPE_DYNAMIC:
5699
			row_format_name
1183.1.18 by Brian Aker
Fixed references to doCreateTable()
5700
				= form.s->row_type == ROW_TYPE_COMPRESSED
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5701
				? "COMPRESSED"
5702
				: "DYNAMIC";
5703
5704
			if (!srv_file_per_table) {
5705
				push_warning_printf(
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5706
					session,
5707
					DRIZZLE_ERROR::WARN_LEVEL_WARN,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5708
					ER_ILLEGAL_HA_CREATE_OPTION,
5709
					"InnoDB: ROW_FORMAT=%s"
5710
					" requires innodb_file_per_table.",
5711
					row_format_name);
5712
			} else if (file_format < DICT_TF_FORMAT_ZIP) {
5713
				push_warning_printf(
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5714
					session,
5715
					DRIZZLE_ERROR::WARN_LEVEL_WARN,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5716
					ER_ILLEGAL_HA_CREATE_OPTION,
5717
					"InnoDB: ROW_FORMAT=%s"
5718
					" requires innodb_file_format >"
5719
					" Antelope.",
5720
					row_format_name);
5721
			} else {
1053 by Brian Aker
Merge Stewart, fix LOCK (it was dead, only for dead RENAME SCHEMA code), and
5722
				iflags |= DICT_TF_COMPACT
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5723
					| (DICT_TF_FORMAT_ZIP
5724
					   << DICT_TF_FORMAT_SHIFT);
5725
				break;
5726
			}
5727
5728
			/* fall through */
5729
		case ROW_TYPE_NOT_USED:
5730
		case ROW_TYPE_FIXED:
5731
		default:
1222.1.6 by Brian Aker
Fix engines to not rely on HA_CREATE_INFO.
5732
                        error = ER_ILLEGAL_HA_CREATE_OPTION;
5733
                        goto cleanup;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5734
		case ROW_TYPE_DEFAULT:
5735
		case ROW_TYPE_COMPACT:
1053 by Brian Aker
Merge Stewart, fix LOCK (it was dead, only for dead RENAME SCHEMA code), and
5736
			iflags = DICT_TF_COMPACT;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5737
			break;
5738
		}
1053 by Brian Aker
Merge Stewart, fix LOCK (it was dead, only for dead RENAME SCHEMA code), and
5739
	} else if (!iflags) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5740
		/* No KEY_BLOCK_SIZE or ROW_FORMAT specified:
5741
		use ROW_FORMAT=COMPACT by default. */
1053 by Brian Aker
Merge Stewart, fix LOCK (it was dead, only for dead RENAME SCHEMA code), and
5742
		iflags = DICT_TF_COMPACT;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5743
	}
5744
1183.1.18 by Brian Aker
Fixed references to doCreateTable()
5745
	error = create_table_def(trx, &form, norm_name,
1222.2.1 by Brian Aker
Takes the majority usage of parser based HA_CREATE_INFO usage around
5746
		lex_identified_temp_table ? name2 : NULL,
1053 by Brian Aker
Merge Stewart, fix LOCK (it was dead, only for dead RENAME SCHEMA code), and
5747
		iflags);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5748
5749
	if (error) {
5750
		goto cleanup;
5751
	}
5752
5753
	/* Look for a primary key */
5754
1183.1.18 by Brian Aker
Fixed references to doCreateTable()
5755
	primary_key_no= (form.s->primary_key != MAX_KEY ?
5756
			 (int) form.s->primary_key :
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5757
			 -1);
5758
5759
	/* Our function row_get_mysql_key_number_for_index assumes
5760
	the primary key is always number 0, if it exists */
5761
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5762
	assert(primary_key_no == -1 || primary_key_no == 0);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5763
5764
	/* Create the keys */
5765
1183.1.18 by Brian Aker
Fixed references to doCreateTable()
5766
	if (form.s->keys == 0 || primary_key_no == -1) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5767
		/* Create an index which is used as the clustered index;
5768
		order the rows by their row id which is internally generated
5769
		by InnoDB */
5770
5771
		error = create_clustered_index_when_no_primary(
1053 by Brian Aker
Merge Stewart, fix LOCK (it was dead, only for dead RENAME SCHEMA code), and
5772
			trx, iflags, norm_name);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5773
		if (error) {
5774
			goto cleanup;
5775
		}
5776
	}
5777
5778
	if (primary_key_no != -1) {
5779
		/* In InnoDB the clustered index must always be created
5780
		first */
1183.1.18 by Brian Aker
Fixed references to doCreateTable()
5781
		if ((error = create_index(trx, &form, iflags, norm_name,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5782
					  (uint) primary_key_no))) {
5783
			goto cleanup;
5784
		}
5785
	}
5786
1183.1.18 by Brian Aker
Fixed references to doCreateTable()
5787
	for (i = 0; i < form.s->keys; i++) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5788
5789
		if (i != (uint) primary_key_no) {
5790
1183.1.18 by Brian Aker
Fixed references to doCreateTable()
5791
			if ((error = create_index(trx, &form, iflags, norm_name,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5792
						  i))) {
5793
				goto cleanup;
5794
			}
5795
		}
5796
	}
5797
5798
	if (*trx->mysql_query_str) {
5799
		error = row_table_add_foreign_constraints(trx,
5800
			*trx->mysql_query_str, norm_name,
1222.2.1 by Brian Aker
Takes the majority usage of parser based HA_CREATE_INFO usage around
5801
			lex_identified_temp_table);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5802
1053 by Brian Aker
Merge Stewart, fix LOCK (it was dead, only for dead RENAME SCHEMA code), and
5803
		error = convert_error_code_to_mysql(error, iflags, NULL);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5804
5805
		if (error) {
5806
			goto cleanup;
5807
		}
5808
	}
5809
5810
	innobase_commit_low(trx);
5811
5812
	row_mysql_unlock_data_dictionary(trx);
5813
5814
	/* Flush the log to reduce probability that the .frm files and
5815
	the InnoDB data dictionary get out-of-sync if the user runs
5816
	with innodb_flush_log_at_trx_commit = 0 */
5817
5818
	log_buffer_flush_to_disk();
5819
5820
	innobase_table = dict_table_get(norm_name, FALSE);
5821
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5822
	assert(innobase_table != 0);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5823
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
5824
	if (innobase_table) {
5825
		/* We update the highest file format in the system table
5826
		space, if this table has higher file format setting. */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5827
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
5828
		trx_sys_file_format_max_upgrade(
5829
			(const char**) &innobase_file_format_check,
5830
			dict_table_get_format(innobase_table));
5831
	}
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5832
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5833
	/* Note: We can't call update_session() as prebuilt will not be
5834
	setup at this stage and so we use session. */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5835
5836
	/* We need to copy the AUTOINC value from the old table if
5837
	this is an ALTER TABLE. */
5838
1222.1.5 by Brian Aker
Remove dependency in engines for auto_increment primer to be passed in by
5839
	if ((create_proto.options().has_auto_increment_value()
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5840
	    || session_sql_command(session) == SQLCOM_ALTER_TABLE)
1222.1.5 by Brian Aker
Remove dependency in engines for auto_increment primer to be passed in by
5841
	    && create_proto.options().auto_increment_value() != 0) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5842
5843
		/* Query was ALTER TABLE...AUTO_INCREMENT = x; or
5844
		CREATE TABLE ...AUTO_INCREMENT = x; Find out a table
5845
		definition from the dictionary and get the current value
5846
		of the auto increment field. Set a new value to the
5847
		auto increment field if the value is greater than the
5848
		maximum value in the column. */
5849
1222.1.5 by Brian Aker
Remove dependency in engines for auto_increment primer to be passed in by
5850
		auto_inc_value = create_proto.options().auto_increment_value();
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5851
5852
		dict_table_autoinc_lock(innobase_table);
5853
		dict_table_autoinc_initialize(innobase_table, auto_inc_value);
5854
		dict_table_autoinc_unlock(innobase_table);
5855
	}
5856
5857
	/* Tell the InnoDB server that there might be work for
5858
	utility threads: */
5859
5860
	srv_active_wake_master_thread();
5861
5862
	trx_free_for_mysql(trx);
5863
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5864
	return(0);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5865
5866
cleanup:
5867
	innobase_commit_low(trx);
5868
5869
	row_mysql_unlock_data_dictionary(trx);
5870
5871
	trx_free_for_mysql(trx);
5872
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5873
	return(error);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5874
}
5875
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
5876
/*****************************************************************//**
5877
Discards or imports an InnoDB tablespace.
5878
@return	0 == success, -1 == error */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5879
UNIV_INTERN
5880
int
5881
ha_innobase::discard_or_import_tablespace(
5882
/*======================================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
5883
	my_bool discard)	/*!< in: TRUE if discard, else import */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5884
{
5885
	dict_table_t*	dict_table;
5886
	trx_t*		trx;
5887
	int		err;
5888
5889
	ut_a(prebuilt->trx);
5890
	ut_a(prebuilt->trx->magic_n == TRX_MAGIC_N);
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5891
	ut_a(prebuilt->trx == session_to_trx(ha_session()));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5892
5893
	dict_table = prebuilt->table;
5894
	trx = prebuilt->trx;
5895
5896
	if (discard) {
5897
		err = row_discard_tablespace_for_mysql(dict_table->name, trx);
5898
	} else {
5899
		err = row_import_tablespace_for_mysql(dict_table->name, trx);
5900
	}
5901
5902
	err = convert_error_code_to_mysql(err, dict_table->flags, NULL);
5903
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5904
	return(err);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5905
}
5906
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
5907
/*****************************************************************//**
5908
Deletes all rows of an InnoDB table.
5909
@return	error number */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5910
UNIV_INTERN
5911
int
5912
ha_innobase::delete_all_rows(void)
5913
/*==============================*/
5914
{
5915
	int		error;
5916
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5917
	/* Get the transaction associated with the current session, or create one
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5918
	if not yet created, and update prebuilt->trx */
5919
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5920
	update_session(ha_session());
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5921
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5922
	if (session_sql_command(user_session) != SQLCOM_TRUNCATE) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5923
	fallback:
5924
		/* We only handle TRUNCATE TABLE t as a special case.
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
5925
		DELETE FROM t will have to use ha_innobase::delete_row(),
5926
		because DELETE is transactional while TRUNCATE is not. */
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5927
		return(my_errno=HA_ERR_WRONG_COMMAND);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5928
	}
5929
5930
	/* Truncate the table in InnoDB */
5931
5932
	error = row_truncate_table_for_mysql(prebuilt->table, prebuilt->trx);
5933
	if (error == DB_ERROR) {
5934
		/* Cannot truncate; resort to ha_innobase::delete_row() */
5935
		goto fallback;
5936
	}
5937
5938
	error = convert_error_code_to_mysql(error, prebuilt->table->flags,
5939
					    NULL);
5940
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5941
	return(error);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5942
}
5943
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
5944
/*****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5945
Drops a table from an InnoDB database. Before calling this function,
5946
MySQL calls innobase_commit to commit the transaction of the current user.
5947
Then the current user cannot have locks set on the table. Drop table
5948
operation inside InnoDB will remove all locks any user has on the table
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
5949
inside InnoDB.
5950
@return	error number */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5951
UNIV_INTERN
5952
int
1183.1.22 by Brian Aker
Merge Name changes
5953
InnobaseEngine::doDropTable(
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5954
/*======================*/
1183.1.29 by Brian Aker
Clean up interface so that Truncate sets the propper engine when
5955
        Session& session,
5956
	const string table_path)	/* in: table name */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5957
{
5958
	int	error;
5959
	trx_t*	parent_trx;
5960
	trx_t*	trx;
5961
	char	norm_name[1000];
5962
1039.3.2 by Stewart Smith
move delete_table out of handler and up into StorageEngine where it belongs.
5963
	ut_a(table_path.length() < 1000);
5964
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5965
	/* Strangely, MySQL passes the table name without the '.frm'
5966
	extension, in contrast to ::create */
1039.3.2 by Stewart Smith
move delete_table out of handler and up into StorageEngine where it belongs.
5967
	normalize_table_name(norm_name, table_path.c_str());
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5968
641.1.4 by Monty Taylor
Merged in InnoDB changes.
5969
	/* Get the transaction associated with the current session, or create one
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5970
	if not yet created */
5971
1183.1.29 by Brian Aker
Clean up interface so that Truncate sets the propper engine when
5972
	parent_trx = check_trx_exists(&session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5973
5974
	/* In case MySQL calls this in the middle of a SELECT query, release
5975
	possible adaptive hash latch to avoid deadlocks of threads */
5976
5977
	trx_search_latch_release_if_reserved(parent_trx);
5978
1183.1.29 by Brian Aker
Clean up interface so that Truncate sets the propper engine when
5979
	trx = innobase_trx_allocate(&session);
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
5980
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
5981
	srv_lower_case_table_names = TRUE;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5982
5983
	/* Drop the table in InnoDB */
5984
5985
	error = row_drop_table_for_mysql(norm_name, trx,
1183.1.29 by Brian Aker
Clean up interface so that Truncate sets the propper engine when
5986
					 session_sql_command(&session)
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
5987
					 == SQLCOM_DROP_DB);
5988
5989
	/* Flush the log to reduce probability that the .frm files and
5990
	the InnoDB data dictionary get out-of-sync if the user runs
5991
	with innodb_flush_log_at_trx_commit = 0 */
5992
5993
	log_buffer_flush_to_disk();
5994
5995
	/* Tell the InnoDB server that there might be work for
5996
	utility threads: */
5997
5998
	srv_active_wake_master_thread();
5999
6000
	innobase_commit_low(trx);
6001
6002
	trx_free_for_mysql(trx);
6003
811.1.3 by Stewart Smith
Fix InnoDB drop table code path, handler drop table code path to deal with bad FRMs.
6004
	if(error!=ENOENT)
6005
	  error = convert_error_code_to_mysql(error, 0, NULL);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6006
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6007
	return(error);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6008
}
6009
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
6010
/*****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6011
Removes all tables in the named database inside InnoDB. */
6012
void
960.2.32 by Monty Taylor
Converted Innodb handlerton.
6013
InnobaseEngine::drop_database(
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6014
/*===================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
6015
	char*	path)	/*!< in: database path; inside InnoDB the name
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6016
			of the last directory in the path is used as
6017
			the database name: for example, in 'mysql/data/test'
6018
			the database name is 'test' */
6019
{
6020
	ulint	len		= 0;
6021
	trx_t*	trx;
6022
	char*	ptr;
6023
	int	error;
6024
	char*	namebuf;
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6025
	Session*	session		= current_session;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6026
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6027
	/* Get the transaction associated with the current session, or create one
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6028
	if not yet created */
6029
960.2.38 by Monty Taylor
Removed extraneous send myself to myself argument.
6030
	assert(this == innodb_engine_ptr);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6031
641.1.5 by Monty Taylor
Merged in innodb plugin 1.0.2
6032
	/* In the Windows plugin, session = current_session is always NULL */
6033
	if (session) {
6034
		trx_t*	parent_trx = check_trx_exists(session);
6035
6036
		/* In case Drizzle calls this in the middle of a SELECT
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
6037
		query, release possible adaptive hash latch to avoid
6038
		deadlocks of threads */
6039
6040
		trx_search_latch_release_if_reserved(parent_trx);
6041
	}
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6042
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6043
	ptr = strchr(path, '\0') - 2;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6044
6045
	while (ptr >= path && *ptr != '\\' && *ptr != '/') {
6046
		ptr--;
6047
		len++;
6048
	}
6049
6050
	ptr++;
641.3.6 by Monty Taylor
Removed some my_malloc calls.
6051
	namebuf = (char*) malloc((uint) len + 2);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6052
6053
	memcpy(namebuf, ptr, len);
6054
	namebuf[len] = '/';
6055
	namebuf[len + 1] = '\0';
6056
#ifdef	__WIN__
6057
	innobase_casedn_str(namebuf);
6058
#endif
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
6059
#if defined __WIN__ && !defined MYSQL_SERVER
6060
	/* In the Windows plugin, thd = current_thd is always NULL */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6061
	trx = trx_allocate_for_mysql();
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
6062
	trx->mysql_thd = NULL;
6063
	trx->mysql_query_str = NULL;
6064
#else
933.1.1 by Monty Taylor
Merged in InnoDB Plugin 1.0.3
6065
	trx = innobase_trx_allocate(session);
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
6066
#endif
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6067
	error = row_drop_database_for_mysql(namebuf, trx);
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6068
	free(namebuf);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6069
6070
	/* Flush the log to reduce probability that the .frm files and
6071
	the InnoDB data dictionary get out-of-sync if the user runs
6072
	with innodb_flush_log_at_trx_commit = 0 */
6073
6074
	log_buffer_flush_to_disk();
6075
6076
	/* Tell the InnoDB server that there might be work for
6077
	utility threads: */
6078
6079
	srv_active_wake_master_thread();
6080
6081
	innobase_commit_low(trx);
6082
	trx_free_for_mysql(trx);
6083
}
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
6084
/*********************************************************************//**
6085
Renames an InnoDB table.
6086
@return	0 or error code */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6087
static
6088
int
6089
innobase_rename_table(
6090
/*==================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
6091
	trx_t*		trx,	/*!< in: transaction */
6092
	const char*	from,	/*!< in: old name of the table */
6093
	const char*	to,	/*!< in: new name of the table */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6094
	ibool		lock_and_commit)
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
6095
				/*!< in: TRUE=lock data dictionary and commit */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6096
{
6097
	int	error;
6098
	char*	norm_to;
6099
	char*	norm_from;
6100
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
6101
	srv_lower_case_table_names = TRUE;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6102
6103
	// Magic number 64 arbitrary
641.3.6 by Monty Taylor
Removed some my_malloc calls.
6104
	norm_to = (char*) malloc(strlen(to) + 64);
6105
	norm_from = (char*) malloc(strlen(from) + 64);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6106
6107
	normalize_table_name(norm_to, to);
6108
	normalize_table_name(norm_from, from);
6109
6110
	/* Serialize data dictionary operations with dictionary mutex:
6111
	no deadlocks can occur then in these operations */
6112
6113
	if (lock_and_commit) {
6114
		row_mysql_lock_data_dictionary(trx);
6115
	}
6116
6117
	error = row_rename_table_for_mysql(
6118
		norm_from, norm_to, trx, lock_and_commit);
6119
6120
	if (error != DB_SUCCESS) {
6121
		FILE* ef = dict_foreign_err_file;
6122
6123
		fputs("InnoDB: Renaming table ", ef);
6124
		ut_print_name(ef, trx, TRUE, norm_from);
6125
		fputs(" to ", ef);
6126
		ut_print_name(ef, trx, TRUE, norm_to);
6127
		fputs(" failed!\n", ef);
6128
	}
6129
6130
	if (lock_and_commit) {
6131
		row_mysql_unlock_data_dictionary(trx);
6132
6133
		/* Flush the log to reduce probability that the .frm
6134
		files and the InnoDB data dictionary get out-of-sync
6135
		if the user runs with innodb_flush_log_at_trx_commit = 0 */
6136
6137
		log_buffer_flush_to_disk();
6138
	}
6139
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6140
	free(norm_to);
6141
	free(norm_from);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6142
6143
	return error;
6144
}
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
6145
/*********************************************************************//**
6146
Renames an InnoDB table.
6147
@return	0 or error code */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6148
UNIV_INTERN
6149
int
1183.1.7 by Brian Aker
Fix name conventions for rename table
6150
InnobaseEngine::doRenameTable(
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6151
/*======================*/
1039.3.5 by Stewart Smith
move handler::rename_table to StorageEngine
6152
	Session*	session,
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
6153
	const char*	from,	/*!< in: old name of the table */
6154
	const char*	to)	/*!< in: new name of the table */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6155
{
6156
	trx_t*	trx;
6157
	int	error;
6158
	trx_t*	parent_trx;
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6159
6160
	/* Get the transaction associated with the current session, or create one
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6161
	if not yet created */
6162
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6163
	parent_trx = check_trx_exists(session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6164
6165
	/* In case MySQL calls this in the middle of a SELECT query, release
6166
	possible adaptive hash latch to avoid deadlocks of threads */
6167
6168
	trx_search_latch_release_if_reserved(parent_trx);
6169
933.1.1 by Monty Taylor
Merged in InnoDB Plugin 1.0.3
6170
	trx = innobase_trx_allocate(session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6171
6172
	error = innobase_rename_table(trx, from, to, TRUE);
6173
6174
	/* Tell the InnoDB server that there might be work for
6175
	utility threads: */
6176
6177
	srv_active_wake_master_thread();
6178
6179
	innobase_commit_low(trx);
6180
	trx_free_for_mysql(trx);
6181
6182
	error = convert_error_code_to_mysql(error, 0, NULL);
6183
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6184
	return(error);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6185
}
6186
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
6187
/*********************************************************************//**
6188
Estimates the number of index records in a range.
6189
@return	estimated number of rows */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6190
UNIV_INTERN
6191
ha_rows
6192
ha_innobase::records_in_range(
6193
/*==========================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
6194
	uint			keynr,		/*!< in: index number */
6195
	key_range		*min_key,	/*!< in: start key value of the
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6196
						   range, may also be 0 */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
6197
	key_range		*max_key)	/*!< in: range end key val, may
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6198
						   also be 0 */
6199
{
6200
	KEY*		key;
6201
	dict_index_t*	index;
641.3.6 by Monty Taylor
Removed some my_malloc calls.
6202
	unsigned char*		key_val_buff2	= (unsigned char*) malloc(
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6203
						  table->s->stored_rec_length
641.3.6 by Monty Taylor
Removed some my_malloc calls.
6204
					+ table->s->max_key_length + 100);
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6205
	ulint		buff2_len = table->s->stored_rec_length
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6206
					+ table->s->max_key_length + 100;
6207
	dtuple_t*	range_start;
6208
	dtuple_t*	range_end;
6209
	ib_int64_t	n_rows;
6210
	ulint		mode1;
6211
	ulint		mode2;
6212
	mem_heap_t*	heap;
6213
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6214
	ut_a(prebuilt->trx == session_to_trx(ha_session()));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6215
6216
	prebuilt->trx->op_info = (char*)"estimating records in index range";
6217
6218
	/* In case MySQL calls this in the middle of a SELECT query, release
6219
	possible adaptive hash latch to avoid deadlocks of threads */
6220
6221
	trx_search_latch_release_if_reserved(prebuilt->trx);
6222
6223
	active_index = keynr;
6224
6225
	key = table->key_info + active_index;
6226
6227
	index = dict_table_get_index_on_name(prebuilt->table, key->name);
6228
6229
	/* MySQL knows about this index and so we must be able to find it.*/
6230
	ut_a(index);
6231
6232
	heap = mem_heap_create(2 * (key->key_parts * sizeof(dfield_t)
6233
				    + sizeof(dtuple_t)));
6234
6235
	range_start = dtuple_create(heap, key->key_parts);
6236
	dict_index_copy_types(range_start, index, key->key_parts);
6237
6238
	range_end = dtuple_create(heap, key->key_parts);
6239
	dict_index_copy_types(range_end, index, key->key_parts);
6240
6241
	row_sel_convert_mysql_key_to_innobase(
6242
				range_start, (byte*) key_val_buff,
6243
				(ulint)upd_and_key_val_buff_len,
6244
				index,
6245
				(byte*) (min_key ? min_key->key :
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6246
					 (const unsigned char*) 0),
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6247
				(ulint) (min_key ? min_key->length : 0),
6248
				prebuilt->trx);
6249
6250
	row_sel_convert_mysql_key_to_innobase(
6251
				range_end, (byte*) key_val_buff2,
6252
				buff2_len, index,
6253
				(byte*) (max_key ? max_key->key :
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6254
					 (const unsigned char*) 0),
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6255
				(ulint) (max_key ? max_key->length : 0),
6256
				prebuilt->trx);
6257
6258
	mode1 = convert_search_mode_to_innobase(min_key ? min_key->flag :
6259
						HA_READ_KEY_EXACT);
6260
	mode2 = convert_search_mode_to_innobase(max_key ? max_key->flag :
6261
						HA_READ_KEY_EXACT);
6262
6263
	if (mode1 != PAGE_CUR_UNSUPP && mode2 != PAGE_CUR_UNSUPP) {
6264
6265
		n_rows = btr_estimate_n_rows_in_range(index, range_start,
6266
						      mode1, range_end,
6267
						      mode2);
6268
	} else {
6269
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
6270
		n_rows = HA_POS_ERROR;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6271
	}
6272
6273
	mem_heap_free(heap);
6274
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6275
	free(key_val_buff2);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6276
6277
	prebuilt->trx->op_info = (char*)"";
6278
6279
	/* The MySQL optimizer seems to believe an estimate of 0 rows is
6280
	always accurate and may return the result 'Empty set' based on that.
6281
	The accuracy is not guaranteed, and even if it were, for a locking
6282
	read we should anyway perform the search to set the next-key lock.
6283
	Add 1 to the value to make sure MySQL does not make the assumption! */
6284
6285
	if (n_rows == 0) {
6286
		n_rows = 1;
6287
	}
6288
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6289
	return((ha_rows) n_rows);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6290
}
6291
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
6292
/*********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6293
Gives an UPPER BOUND to the number of rows in a table. This is used in
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
6294
filesort.cc.
6295
@return	upper bound of rows */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6296
UNIV_INTERN
6297
ha_rows
6298
ha_innobase::estimate_rows_upper_bound(void)
6299
/*======================================*/
6300
{
6301
	dict_index_t*	index;
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6302
	uint64_t	estimate;
6303
	uint64_t	local_data_file_length;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6304
6305
	/* We do not know if MySQL can call this function before calling
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6306
	external_lock(). To be safe, update the session of the current table
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6307
	handle. */
6308
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6309
	update_session(ha_session());
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6310
6311
	prebuilt->trx->op_info = (char*)
6312
				 "calculating upper bound for table rows";
6313
6314
	/* In case MySQL calls this in the middle of a SELECT query, release
6315
	possible adaptive hash latch to avoid deadlocks of threads */
6316
6317
	trx_search_latch_release_if_reserved(prebuilt->trx);
6318
6319
	index = dict_table_get_first_index(prebuilt->table);
6320
6321
	ut_a(index->stat_n_leaf_pages > 0);
6322
6323
	local_data_file_length =
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6324
		((uint64_t) index->stat_n_leaf_pages) * UNIV_PAGE_SIZE;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6325
6326
6327
	/* Calculate a minimum length for a clustered index record and from
6328
	that an upper bound for the number of rows. Since we only calculate
6329
	new statistics in row0mysql.c when a table has grown by a threshold
6330
	factor, we must add a safety factor 2 in front of the formula below. */
6331
6332
	estimate = 2 * local_data_file_length /
6333
					 dict_index_calc_min_rec_len(index);
6334
6335
	prebuilt->trx->op_info = (char*)"";
6336
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6337
	return((ha_rows) estimate);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6338
}
6339
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
6340
/*********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6341
How many seeks it will take to read through the table. This is to be
6342
comparable to the number returned by records_in_range so that we can
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
6343
decide if we should scan the table or use keys.
6344
@return	estimated time measured in disk seeks */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6345
UNIV_INTERN
6346
double
6347
ha_innobase::scan_time()
6348
/*====================*/
6349
{
6350
	/* Since MySQL seems to favor table scans too much over index
6351
	searches, we pretend that a sequential read takes the same time
6352
	as a random disk read, that is, we do not divide the following
6353
	by 10, which would be physically realistic. */
6354
6355
	return((double) (prebuilt->table->stat_clustered_index_size));
6356
}
6357
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
6358
/******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6359
Calculate the time it takes to read a set of ranges through an index
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
6360
This enables us to optimise reads for clustered indexes.
6361
@return	estimated time measured in disk seeks */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6362
UNIV_INTERN
6363
double
6364
ha_innobase::read_time(
6365
/*===================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
6366
	uint	index,	/*!< in: key number */
6367
	uint	ranges,	/*!< in: how many ranges */
6368
	ha_rows rows)	/*!< in: estimated number of rows in the ranges */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6369
{
6370
	ha_rows total_rows;
6371
	double	time_for_scan;
6372
6373
	if (index != table->s->primary_key) {
6374
		/* Not clustered */
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
6375
		return(Cursor::read_time(index, ranges, rows));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6376
	}
6377
6378
	if (rows <= 2) {
6379
6380
		return((double) rows);
6381
	}
6382
6383
	/* Assume that the read time is proportional to the scan time for all
6384
	rows + at most one seek per range. */
6385
6386
	time_for_scan = scan_time();
6387
6388
	if ((total_rows = estimate_rows_upper_bound()) < rows) {
6389
6390
		return(time_for_scan);
6391
	}
6392
6393
	return(ranges + (double) rows / (double) total_rows * time_for_scan);
6394
}
6395
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
6396
/*********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6397
Returns statistics information of the table to the MySQL interpreter,
6398
in various fields of the handle object. */
6399
UNIV_INTERN
6400
int
6401
ha_innobase::info(
6402
/*==============*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
6403
	uint flag)	/*!< in: what information MySQL requests */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6404
{
6405
	dict_table_t*	ib_table;
6406
	dict_index_t*	index;
6407
	ha_rows		rec_per_key;
6408
	ib_int64_t	n_rows;
6409
	ulong		j;
6410
	ulong		i;
6411
	char		path[FN_REFLEN];
6412
	os_file_stat_t	stat_info;
6413
6414
	/* If we are forcing recovery at a high level, we will suppress
6415
	statistics calculation on tables, because that may crash the
6416
	server if an index is badly corrupted. */
6417
6418
	if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
6419
6420
		/* We return success (0) instead of HA_ERR_CRASHED,
6421
		because we want MySQL to process this query and not
6422
		stop, like it would do if it received the error code
6423
		HA_ERR_CRASHED. */
6424
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6425
		return(0);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6426
	}
6427
6428
	/* We do not know if MySQL can call this function before calling
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6429
	external_lock(). To be safe, update the session of the current table
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6430
	handle. */
6431
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6432
	update_session(ha_session());
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6433
6434
	/* In case MySQL calls this in the middle of a SELECT query, release
6435
	possible adaptive hash latch to avoid deadlocks of threads */
6436
6437
	prebuilt->trx->op_info = (char*)"returning various info to MySQL";
6438
6439
	trx_search_latch_release_if_reserved(prebuilt->trx);
6440
6441
	ib_table = prebuilt->table;
6442
6443
	if (flag & HA_STATUS_TIME) {
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
6444
		if (innobase_stats_on_metadata) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6445
			/* In sql_show we call with this flag: update
6446
			then statistics so that they are up-to-date */
6447
6448
			prebuilt->trx->op_info = "updating table statistics";
6449
6450
			dict_update_statistics(ib_table);
6451
6452
			prebuilt->trx->op_info = "returning various info to MySQL";
6453
		}
6454
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6455
		snprintf(path, sizeof(path), "%s/%s%s",
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
6456
			       drizzle_data_home, ib_table->name, ".dfe");
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6457
6458
		unpack_filename(path,path);
6459
6460
		/* Note that we do not know the access time of the table,
6461
		nor the CHECK TABLE time, nor the UPDATE or INSERT time. */
6462
6463
		if (os_file_get_status(path,&stat_info)) {
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
6464
			stats.create_time = (ulong) stat_info.ctime;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6465
		}
6466
	}
6467
6468
	if (flag & HA_STATUS_VARIABLE) {
6469
		n_rows = ib_table->stat_n_rows;
6470
6471
		/* Because we do not protect stat_n_rows by any mutex in a
6472
		delete, it is theoretically possible that the value can be
6473
		smaller than zero! TODO: fix this race.
6474
6475
		The MySQL optimizer seems to assume in a left join that n_rows
6476
		is an accurate estimate if it is zero. Of course, it is not,
6477
		since we do not have any locks on the rows yet at this phase.
6478
		Since SHOW TABLE STATUS seems to call this function with the
6479
		HA_STATUS_TIME flag set, while the left join optimizer does not
6480
		set that flag, we add one to a zero value if the flag is not
6481
		set. That way SHOW TABLE STATUS will show the best estimate,
6482
		while the optimizer never sees the table empty. */
6483
6484
		if (n_rows < 0) {
6485
			n_rows = 0;
6486
		}
6487
6488
		if (n_rows == 0 && !(flag & HA_STATUS_TIME)) {
6489
			n_rows++;
6490
		}
6491
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
6492
		/* Fix bug#40386: Not flushing query cache after truncate.
6493
		n_rows can not be 0 unless the table is empty, set to 1
6494
		instead. The original problem of bug#29507 is actually
6495
		fixed in the server code. */
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6496
		if (session_sql_command(user_session) == SQLCOM_TRUNCATE) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6497
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
6498
			n_rows = 1;
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
6499
6500
			/* We need to reset the prebuilt value too, otherwise
6501
			checks for values greater than the last value written
6502
			to the table will fail and the autoinc counter will
6503
			not be updated. This will force write_row() into
6504
			attempting an update of the table's AUTOINC counter. */
6505
6506
			prebuilt->autoinc_last_value = 0;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6507
		}
6508
6509
		stats.records = (ha_rows)n_rows;
6510
		stats.deleted = 0;
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6511
		stats.data_file_length = ((uint64_t)
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6512
				ib_table->stat_clustered_index_size)
6513
					* UNIV_PAGE_SIZE;
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6514
		stats.index_file_length = ((uint64_t)
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6515
				ib_table->stat_sum_of_other_index_sizes)
6516
					* UNIV_PAGE_SIZE;
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
6517
6518
		/* Since fsp_get_available_space_in_free_extents() is
6519
		acquiring latches inside InnoDB, we do not call it if we
6520
		are asked by MySQL to avoid locking. Another reason to
6521
		avoid the call is that it uses quite a lot of CPU.
6522
		See Bug#38185.
6523
		We do not update delete_length if no locking is requested
6524
		so the "old" value can remain. delete_length is initialized
6525
		to 0 in the ha_statistics' constructor. */
6526
		if (!(flag & HA_STATUS_NO_LOCK)) {
6527
6528
			/* lock the data dictionary to avoid races with
6529
			ibd_file_missing and tablespace_discarded */
6530
			row_mysql_lock_data_dictionary(prebuilt->trx);
6531
6532
			/* ib_table->space must be an existent tablespace */
6533
			if (!ib_table->ibd_file_missing
6534
			    && !ib_table->tablespace_discarded) {
6535
6536
				stats.delete_length =
6537
					fsp_get_available_space_in_free_extents(
6538
						ib_table->space) * 1024;
6539
			} else {
6540
641.1.5 by Monty Taylor
Merged in innodb plugin 1.0.2
6541
				Session*	session;
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
6542
641.1.5 by Monty Taylor
Merged in innodb plugin 1.0.2
6543
				session = ha_session();
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
6544
6545
				push_warning_printf(
641.1.5 by Monty Taylor
Merged in innodb plugin 1.0.2
6546
					session,
6547
					DRIZZLE_ERROR::WARN_LEVEL_WARN,
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
6548
					ER_CANT_GET_STAT,
6549
					"InnoDB: Trying to get the free "
6550
					"space for table %s but its "
6551
					"tablespace has been discarded or "
6552
					"the .ibd file is missing. Setting "
6553
					"the free space to zero.",
6554
					ib_table->name);
6555
6556
				stats.delete_length = 0;
6557
			}
6558
6559
			row_mysql_unlock_data_dictionary(prebuilt->trx);
6560
		}
6561
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6562
		stats.check_time = 0;
6563
6564
		if (stats.records == 0) {
6565
			stats.mean_rec_length = 0;
6566
		} else {
6567
			stats.mean_rec_length = (ulong) (stats.data_file_length / stats.records);
6568
		}
6569
	}
6570
6571
	if (flag & HA_STATUS_CONST) {
6572
		index = dict_table_get_first_index(ib_table);
6573
6574
		if (prebuilt->clust_index_was_generated) {
6575
			index = dict_table_get_next_index(index);
6576
		}
6577
6578
		for (i = 0; i < table->s->keys; i++) {
6579
			if (index == NULL) {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
6580
				errmsg_printf(ERRMSG_LVL_ERROR, "Table %s contains fewer "
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6581
						"indexes inside InnoDB than "
6582
						"are defined in the MySQL "
6583
						".frm file. Have you mixed up "
6584
						".frm files from different "
6585
						"installations? See "
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
6586
						REFMAN
6587
						"innodb-troubleshooting.html\n",
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6588
						ib_table->name);
6589
				break;
6590
			}
6591
6592
			for (j = 0; j < table->key_info[i].key_parts; j++) {
6593
6594
				if (j + 1 > index->n_uniq) {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
6595
					errmsg_printf(ERRMSG_LVL_ERROR, 
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6596
"Index %s of %s has %lu columns unique inside InnoDB, but MySQL is asking "
6597
"statistics for %lu columns. Have you mixed up .frm files from different "
6598
"installations? "
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
6599
"See " REFMAN "innodb-troubleshooting.html\n",
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6600
							index->name,
6601
							ib_table->name,
6602
							(unsigned long)
6603
							index->n_uniq, j + 1);
6604
					break;
6605
				}
6606
6607
				if (index->stat_n_diff_key_vals[j + 1] == 0) {
6608
6609
					rec_per_key = stats.records;
6610
				} else {
6611
					rec_per_key = (ha_rows)(stats.records /
6612
					 index->stat_n_diff_key_vals[j + 1]);
6613
				}
6614
6615
				/* Since MySQL seems to favor table scans
6616
				too much over index searches, we pretend
6617
				index selectivity is 2 times better than
6618
				our estimate: */
6619
6620
				rec_per_key = rec_per_key / 2;
6621
6622
				if (rec_per_key == 0) {
6623
					rec_per_key = 1;
6624
				}
6625
6626
				table->key_info[i].rec_per_key[j]=
6627
				  rec_per_key >= ~(ulong) 0 ? ~(ulong) 0 :
6628
				  (ulong) rec_per_key;
6629
			}
6630
6631
			index = dict_table_get_next_index(index);
6632
		}
6633
	}
6634
6635
	if (flag & HA_STATUS_ERRKEY) {
6636
		const dict_index_t*	err_index;
6637
6638
		ut_a(prebuilt->trx);
6639
		ut_a(prebuilt->trx->magic_n == TRX_MAGIC_N);
6640
6641
		err_index = trx_get_error_info(prebuilt->trx);
6642
6643
		if (err_index) {
6644
			errkey = (unsigned int)
6645
				row_get_mysql_key_number_for_index(err_index);
6646
		} else {
6647
			errkey = (unsigned int) prebuilt->trx->error_key_num;
6648
		}
6649
	}
6650
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
6651
	if ((flag & HA_STATUS_AUTO) && table->found_next_number_field) {
6652
		stats.auto_increment_value = innobase_peek_autoinc();
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6653
	}
6654
6655
	prebuilt->trx->op_info = (char*)"";
6656
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6657
	return(0);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6658
}
6659
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
6660
/**********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6661
Updates index cardinalities of the table, based on 8 random dives into
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
6662
each index tree. This does NOT calculate exact statistics on the table.
6663
@return	returns always 0 (success) */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6664
UNIV_INTERN
6665
int
6666
ha_innobase::analyze(
6667
/*=================*/
1222.1.10 by Brian Aker
Removes options from DDL left in Cursor for admin operations (they were
6668
	Session*)		/*!< in: connection thread handle */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6669
{
6670
	/* Simply call ::info() with all the flags */
6671
	info(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE);
6672
6673
	return(0);
6674
}
6675
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
6676
/*******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6677
Tries to check that an InnoDB table is not corrupted. If corruption is
6678
noticed, prints to stderr information about it. In case of corruption
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
6679
may also assert a failure and crash the server.
6680
@return	HA_ADMIN_CORRUPT or HA_ADMIN_OK */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6681
UNIV_INTERN
6682
int
6683
ha_innobase::check(
6684
/*===============*/
1222.1.10 by Brian Aker
Removes options from DDL left in Cursor for admin operations (they were
6685
	Session*	session)	/*!< in: user thread handle */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6686
{
6687
	ulint		ret;
6688
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6689
	assert(session == ha_session());
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6690
	ut_a(prebuilt->trx);
6691
	ut_a(prebuilt->trx->magic_n == TRX_MAGIC_N);
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6692
	ut_a(prebuilt->trx == session_to_trx(session));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6693
6694
	if (prebuilt->mysql_template == NULL) {
6695
		/* Build the template; we will use a dummy template
6696
		in index scans done in checking */
6697
6698
		build_template(prebuilt, NULL, table, ROW_MYSQL_WHOLE_ROW);
6699
	}
6700
6701
	ret = row_check_table_for_mysql(prebuilt);
6702
6703
	if (ret == DB_SUCCESS) {
6704
		return(HA_ADMIN_OK);
6705
	}
6706
6707
	return(HA_ADMIN_CORRUPT);
6708
}
6709
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
6710
/*************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6711
Adds information about free space in the InnoDB tablespace to a table comment
6712
which is printed out when a user calls SHOW TABLE STATUS. Adds also info on
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
6713
foreign keys.
6714
@return	table comment + InnoDB free space + info on foreign keys */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6715
UNIV_INTERN
6716
char*
6717
ha_innobase::update_table_comment(
6718
/*==============================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
6719
	const char*	comment)/*!< in: table comment defined by user */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6720
{
6721
	uint	length = (uint) strlen(comment);
6722
	char*	str;
6723
	long	flen;
6724
6725
	/* We do not know if MySQL can call this function before calling
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6726
	external_lock(). To be safe, update the session of the current table
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6727
	handle. */
6728
6729
	if (length > 64000 - 3) {
6730
		return((char*)comment); /* string too long */
6731
	}
6732
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6733
	update_session(ha_session());
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6734
6735
	prebuilt->trx->op_info = (char*)"returning table comment";
6736
6737
	/* In case MySQL calls this in the middle of a SELECT query, release
6738
	possible adaptive hash latch to avoid deadlocks of threads */
6739
6740
	trx_search_latch_release_if_reserved(prebuilt->trx);
6741
	str = NULL;
6742
6743
	/* output the data to a temporary file */
6744
6745
	mutex_enter(&srv_dict_tmpfile_mutex);
6746
	rewind(srv_dict_tmpfile);
6747
6748
	fprintf(srv_dict_tmpfile, "InnoDB free: %llu kB",
6749
		fsp_get_available_space_in_free_extents(
6750
			prebuilt->table->space));
6751
6752
	dict_print_info_on_foreign_keys(FALSE, srv_dict_tmpfile,
6753
				prebuilt->trx, prebuilt->table);
6754
	flen = ftell(srv_dict_tmpfile);
6755
	if (flen < 0) {
6756
		flen = 0;
6757
	} else if (length + flen + 3 > 64000) {
6758
		flen = 64000 - 3 - length;
6759
	}
6760
6761
	/* allocate buffer for the full string, and
6762
	read the contents of the temporary file */
6763
641.3.9 by Monty Taylor
More removal of my_malloc.
6764
	str = (char*) malloc(length + flen + 3);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6765
6766
	if (str) {
6767
		char* pos	= str + length;
6768
		if (length) {
6769
			memcpy(str, comment, length);
6770
			*pos++ = ';';
6771
			*pos++ = ' ';
6772
		}
6773
		rewind(srv_dict_tmpfile);
6774
		flen = (uint) fread(pos, 1, flen, srv_dict_tmpfile);
6775
		pos[flen] = 0;
6776
	}
6777
6778
	mutex_exit(&srv_dict_tmpfile_mutex);
6779
6780
	prebuilt->trx->op_info = (char*)"";
6781
6782
	return(str ? str : (char*) comment);
6783
}
6784
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
6785
/*******************************************************************//**
6786
Gets the foreign key create info for a table stored in InnoDB.
6787
@return own: character string in the form which can be inserted to the
6788
CREATE TABLE statement, MUST be freed with
6789
ha_innobase::free_foreign_key_create_info */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6790
UNIV_INTERN
6791
char*
6792
ha_innobase::get_foreign_key_create_info(void)
6793
/*==========================================*/
6794
{
6795
	char*	str	= 0;
6796
	long	flen;
6797
6798
	ut_a(prebuilt != NULL);
6799
6800
	/* We do not know if MySQL can call this function before calling
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6801
	external_lock(). To be safe, update the session of the current table
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6802
	handle. */
6803
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6804
	update_session(ha_session());
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6805
6806
	prebuilt->trx->op_info = (char*)"getting info on foreign keys";
6807
6808
	/* In case MySQL calls this in the middle of a SELECT query,
6809
	release possible adaptive hash latch to avoid
6810
	deadlocks of threads */
6811
6812
	trx_search_latch_release_if_reserved(prebuilt->trx);
6813
6814
	mutex_enter(&srv_dict_tmpfile_mutex);
6815
	rewind(srv_dict_tmpfile);
6816
6817
	/* output the data to a temporary file */
6818
	dict_print_info_on_foreign_keys(TRUE, srv_dict_tmpfile,
6819
				prebuilt->trx, prebuilt->table);
6820
	prebuilt->trx->op_info = (char*)"";
6821
6822
	flen = ftell(srv_dict_tmpfile);
6823
	if (flen < 0) {
6824
		flen = 0;
6825
	} else if (flen > 64000 - 1) {
6826
		flen = 64000 - 1;
6827
	}
6828
6829
	/* allocate buffer for the string, and
6830
	read the contents of the temporary file */
6831
641.3.6 by Monty Taylor
Removed some my_malloc calls.
6832
	str = (char*) malloc(flen + 1);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6833
6834
	if (str) {
6835
		rewind(srv_dict_tmpfile);
6836
		flen = (uint) fread(str, 1, flen, srv_dict_tmpfile);
6837
		str[flen] = 0;
6838
	}
6839
6840
	mutex_exit(&srv_dict_tmpfile_mutex);
6841
6842
	return(str);
6843
}
6844
6845
6846
UNIV_INTERN
6847
int
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6848
ha_innobase::get_foreign_key_list(Session *session, List<FOREIGN_KEY_INFO> *f_key_list)
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6849
{
6850
  dict_foreign_t* foreign;
6851
6852
  ut_a(prebuilt != NULL);
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6853
  update_session(ha_session());
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6854
  prebuilt->trx->op_info = (char*)"getting list of foreign keys";
6855
  trx_search_latch_release_if_reserved(prebuilt->trx);
6856
  mutex_enter(&(dict_sys->mutex));
6857
  foreign = UT_LIST_GET_FIRST(prebuilt->table->foreign_list);
6858
6859
  while (foreign != NULL) {
6860
	  uint i;
6861
	  FOREIGN_KEY_INFO f_key_info;
6862
	  LEX_STRING *name= 0;
6863
          uint ulen;
6864
          char uname[NAME_LEN+1];           /* Unencoded name */
6865
          char db_name[NAME_LEN+1];
6866
	  const char *tmp_buff;
6867
6868
	  tmp_buff= foreign->id;
6869
	  i= 0;
6870
	  while (tmp_buff[i] != '/')
6871
		  i++;
6872
	  tmp_buff+= i + 1;
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6873
	  f_key_info.forein_id = session_make_lex_string(session, 0,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6874
		  tmp_buff, (uint) strlen(tmp_buff), 1);
6875
	  tmp_buff= foreign->referenced_table_name;
6876
6877
          /* Database name */
6878
	  i= 0;
6879
	  while (tmp_buff[i] != '/')
6880
          {
6881
            db_name[i]= tmp_buff[i];
6882
            i++;
6883
          }
6884
          db_name[i]= 0;
6885
          ulen= filename_to_tablename(db_name, uname, sizeof(uname));
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6886
	  f_key_info.referenced_db = session_make_lex_string(session, 0,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6887
		  uname, ulen, 1);
6888
6889
          /* Table name */
6890
	  tmp_buff+= i + 1;
6891
          ulen= filename_to_tablename(tmp_buff, uname, sizeof(uname));
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6892
	  f_key_info.referenced_table = session_make_lex_string(session, 0,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6893
		  uname, ulen, 1);
6894
6895
	  for (i= 0;;) {
6896
		  tmp_buff= foreign->foreign_col_names[i];
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6897
		  name = session_make_lex_string(session, name,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6898
			  tmp_buff, (uint) strlen(tmp_buff), 1);
6899
		  f_key_info.foreign_fields.push_back(name);
6900
		  tmp_buff= foreign->referenced_col_names[i];
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6901
		  name = session_make_lex_string(session, name,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6902
			tmp_buff, (uint) strlen(tmp_buff), 1);
6903
		  f_key_info.referenced_fields.push_back(name);
6904
		  if (++i >= foreign->n_fields)
6905
			  break;
6906
	  }
6907
6908
          ulong length;
6909
          if (foreign->type & DICT_FOREIGN_ON_DELETE_CASCADE)
6910
          {
6911
            length=7;
6912
            tmp_buff= "CASCADE";
6913
          }
6914
          else if (foreign->type & DICT_FOREIGN_ON_DELETE_SET_NULL)
6915
          {
6916
            length=8;
6917
            tmp_buff= "SET NULL";
6918
          }
6919
          else if (foreign->type & DICT_FOREIGN_ON_DELETE_NO_ACTION)
6920
          {
6921
            length=9;
6922
            tmp_buff= "NO ACTION";
6923
          }
6924
          else
6925
          {
6926
            length=8;
6927
            tmp_buff= "RESTRICT";
6928
          }
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6929
	  f_key_info.delete_method = session_make_lex_string(
6930
		  session, f_key_info.delete_method, tmp_buff, length, 1);
6931
 
6932
 
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6933
          if (foreign->type & DICT_FOREIGN_ON_UPDATE_CASCADE)
6934
          {
6935
            length=7;
6936
            tmp_buff= "CASCADE";
6937
          }
6938
          else if (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL)
6939
          {
6940
            length=8;
6941
            tmp_buff= "SET NULL";
6942
          }
6943
          else if (foreign->type & DICT_FOREIGN_ON_UPDATE_NO_ACTION)
6944
          {
6945
            length=9;
6946
            tmp_buff= "NO ACTION";
6947
          }
6948
          else
6949
          {
6950
            length=8;
6951
            tmp_buff= "RESTRICT";
6952
          }
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6953
	  f_key_info.update_method = session_make_lex_string(
6954
		  session, f_key_info.update_method, tmp_buff, length, 1);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6955
          if (foreign->referenced_index &&
6956
              foreign->referenced_index->name)
6957
          {
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6958
	    f_key_info.referenced_key_name = session_make_lex_string(
6959
		    session, f_key_info.referenced_key_name,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6960
		    foreign->referenced_index->name,
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
6961
		    (uint) strlen(foreign->referenced_index->name), 1);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6962
          }
6963
          else
6964
            f_key_info.referenced_key_name= 0;
6965
6966
	  FOREIGN_KEY_INFO *pf_key_info = (FOREIGN_KEY_INFO *)
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6967
		  session_memdup(session, &f_key_info, sizeof(FOREIGN_KEY_INFO));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6968
	  f_key_list->push_back(pf_key_info);
6969
	  foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
6970
  }
6971
  mutex_exit(&(dict_sys->mutex));
6972
  prebuilt->trx->op_info = (char*)"";
6973
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6974
  return(0);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6975
}
6976
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
6977
/*****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6978
Checks if ALTER TABLE may change the storage engine of the table.
6979
Changing storage engines is not allowed for tables for which there
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
6980
are foreign key constraints (parent or child tables).
6981
@return	TRUE if can switch engines */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6982
UNIV_INTERN
6983
bool
6984
ha_innobase::can_switch_engines(void)
6985
/*=================================*/
6986
{
6987
	bool	can_switch;
6988
641.1.4 by Monty Taylor
Merged in InnoDB changes.
6989
	ut_a(prebuilt->trx == session_to_trx(ha_session()));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
6990
6991
	prebuilt->trx->op_info =
6992
			"determining if there are foreign key constraints";
6993
	row_mysql_lock_data_dictionary(prebuilt->trx);
6994
6995
	can_switch = !UT_LIST_GET_FIRST(prebuilt->table->referenced_list)
6996
			&& !UT_LIST_GET_FIRST(prebuilt->table->foreign_list);
6997
6998
	row_mysql_unlock_data_dictionary(prebuilt->trx);
6999
	prebuilt->trx->op_info = "";
7000
641.1.4 by Monty Taylor
Merged in InnoDB changes.
7001
	return(can_switch);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7002
}
7003
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
7004
/*******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7005
Checks if a table is referenced by a foreign key. The MySQL manual states that
7006
a REPLACE is either equivalent to an INSERT, or DELETE(s) + INSERT. Only a
7007
delete is then allowed internally to resolve a duplicate key conflict in
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
7008
REPLACE, not an update.
7009
@return	> 0 if referenced by a FOREIGN KEY */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7010
UNIV_INTERN
7011
uint
7012
ha_innobase::referenced_by_foreign_key(void)
7013
/*========================================*/
7014
{
7015
	if (dict_table_is_referenced_by_foreign_key(prebuilt->table)) {
7016
7017
		return(1);
7018
	}
7019
7020
	return(0);
7021
}
7022
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
7023
/*******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7024
Frees the foreign key create info for a table stored in InnoDB, if it is
7025
non-NULL. */
7026
UNIV_INTERN
7027
void
7028
ha_innobase::free_foreign_key_create_info(
7029
/*======================================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
7030
	char*	str)	/*!< in, own: create info string to free */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7031
{
7032
	if (str) {
641.1.4 by Monty Taylor
Merged in InnoDB changes.
7033
		free(str);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7034
	}
7035
}
7036
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
7037
/*******************************************************************//**
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
7038
Tells something additional to the Cursor about how to do things.
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
7039
@return	0 or error number */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7040
UNIV_INTERN
7041
int
7042
ha_innobase::extra(
7043
/*===============*/
7044
	enum ha_extra_function operation)
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
7045
			   /*!< in: HA_EXTRA_FLUSH or some other flag */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7046
{
7047
	/* Warning: since it is not sure that MySQL calls external_lock
7048
	before calling this function, the trx field in prebuilt can be
7049
	obsolete! */
7050
7051
	switch (operation) {
7052
		case HA_EXTRA_FLUSH:
7053
			if (prebuilt->blob_heap) {
7054
				row_mysql_prebuilt_free_blob_heap(prebuilt);
7055
			}
7056
			break;
7057
		case HA_EXTRA_RESET_STATE:
7058
			reset_template(prebuilt);
7059
			break;
7060
		case HA_EXTRA_NO_KEYREAD:
7061
			prebuilt->read_just_key = 0;
7062
			break;
7063
		case HA_EXTRA_KEYREAD:
7064
			prebuilt->read_just_key = 1;
7065
			break;
7066
		case HA_EXTRA_KEYREAD_PRESERVE_FIELDS:
7067
			prebuilt->keep_other_fields_on_keyread = 1;
7068
			break;
7069
7070
			/* IMPORTANT: prebuilt->trx can be obsolete in
7071
			this method, because it is not sure that MySQL
7072
			calls external_lock before this method with the
641.1.4 by Monty Taylor
Merged in InnoDB changes.
7073
			parameters below.  We must not invoke update_session()
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7074
			either, because the calling threads may change.
7075
			CAREFUL HERE, OR MEMORY CORRUPTION MAY OCCUR! */
7076
		case HA_EXTRA_IGNORE_DUP_KEY:
641.1.4 by Monty Taylor
Merged in InnoDB changes.
7077
			session_to_trx(ha_session())->duplicates |= TRX_DUP_IGNORE;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7078
			break;
7079
		case HA_EXTRA_WRITE_CAN_REPLACE:
641.1.4 by Monty Taylor
Merged in InnoDB changes.
7080
			session_to_trx(ha_session())->duplicates |= TRX_DUP_REPLACE;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7081
			break;
7082
		case HA_EXTRA_WRITE_CANNOT_REPLACE:
641.1.4 by Monty Taylor
Merged in InnoDB changes.
7083
			session_to_trx(ha_session())->duplicates &= ~TRX_DUP_REPLACE;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7084
			break;
7085
		case HA_EXTRA_NO_IGNORE_DUP_KEY:
641.1.4 by Monty Taylor
Merged in InnoDB changes.
7086
			session_to_trx(ha_session())->duplicates &=
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7087
				~(TRX_DUP_IGNORE | TRX_DUP_REPLACE);
7088
			break;
7089
		default:/* Do nothing */
7090
			;
7091
	}
7092
7093
	return(0);
7094
}
7095
7096
UNIV_INTERN
7097
int
7098
ha_innobase::reset()
7099
{
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
7100
	if (prebuilt->blob_heap) {
7101
		row_mysql_prebuilt_free_blob_heap(prebuilt);
7102
	}
7103
7104
	reset_template(prebuilt);
7105
7106
	/* TODO: This should really be reset in reset_template() but for now
7107
	it's safer to do it explicitly here. */
7108
7109
	/* This is a statement level counter. */
7110
	prebuilt->autoinc_last_value = 0;
7111
7112
	return(0);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7113
}
7114
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
7115
/******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7116
MySQL calls this function at the start of each SQL statement inside LOCK
7117
TABLES. Inside LOCK TABLES the ::external_lock method does not work to
7118
mark SQL statement borders. Note also a special case: if a temporary table
7119
is created inside LOCK TABLES, MySQL has not called external_lock() at all
7120
on that table.
7121
MySQL-5.0 also calls this before each statement in an execution of a stored
7122
procedure. To make the execution more deterministic for binlogging, MySQL-5.0
7123
locks all tables involved in a stored procedure with full explicit table
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
7124
locks (session_in_lock_tables(session) holds in store_lock()) before executing
7125
the procedure.
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
7126
@return	0 or error code */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7127
UNIV_INTERN
7128
int
7129
ha_innobase::start_stmt(
7130
/*====================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
7131
	Session*	session,	/*!< in: handle to the user thread */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7132
	thr_lock_type	lock_type)
7133
{
7134
	trx_t*		trx;
7135
641.1.4 by Monty Taylor
Merged in InnoDB changes.
7136
	update_session(session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7137
7138
	trx = prebuilt->trx;
7139
7140
	/* Here we release the search latch and the InnoDB thread FIFO ticket
7141
	if they were reserved. They should have been released already at the
7142
	end of the previous statement, but because inside LOCK TABLES the
7143
	lock count method does not work to mark the end of a SELECT statement,
7144
	that may not be the case. We MUST release the search latch before an
7145
	INSERT, for example. */
7146
7147
	innobase_release_stat_resources(trx);
7148
7149
	/* Reset the AUTOINC statement level counter for multi-row INSERTs. */
7150
	trx->n_autoinc_rows = 0;
7151
7152
	prebuilt->sql_stat_start = TRUE;
7153
	prebuilt->hint_need_to_fetch_extra_cols = 0;
7154
	reset_template(prebuilt);
7155
7156
	if (!prebuilt->mysql_has_locked) {
7157
		/* This handle is for a temporary table created inside
7158
		this same LOCK TABLES; since MySQL does NOT call external_lock
7159
		in this case, we must use x-row locks inside InnoDB to be
7160
		prepared for an update of a row */
7161
7162
		prebuilt->select_lock_type = LOCK_X;
7163
	} else {
7164
		if (trx->isolation_level != TRX_ISO_SERIALIZABLE
641.1.4 by Monty Taylor
Merged in InnoDB changes.
7165
			&& session_sql_command(session) == SQLCOM_SELECT
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7166
			&& lock_type == TL_READ) {
7167
7168
			/* For other than temporary tables, we obtain
7169
			no lock for consistent read (plain SELECT). */
7170
7171
			prebuilt->select_lock_type = LOCK_NONE;
7172
		} else {
7173
			/* Not a consistent read: restore the
7174
			select_lock_type value. The value of
7175
			stored_select_lock_type was decided in:
7176
			1) ::store_lock(),
7177
			2) ::external_lock(),
7178
			3) ::init_table_handle_for_HANDLER(), and
1054.1.6 by Brian Aker
Removed internal logic/dead variables for LOCK TABLES.
7179
                      */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7180
7181
			prebuilt->select_lock_type =
7182
				prebuilt->stored_select_lock_type;
7183
		}
7184
	}
7185
7186
	trx->detailed_error[0] = '\0';
7187
7188
	/* Set the MySQL flag to mark that there is an active transaction */
7189
	if (trx->active_trans == 0) {
7190
960.2.37 by Monty Taylor
More naming fixes.
7191
		innobase_register_trx_and_stmt(engine, session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7192
		trx->active_trans = 1;
7193
	} else {
960.2.37 by Monty Taylor
More naming fixes.
7194
		innobase_register_stmt(engine, session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7195
	}
7196
7197
	return(0);
7198
}
7199
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
7200
/******************************************************************//**
7201
Maps a MySQL trx isolation level code to the InnoDB isolation level code
7202
@return	InnoDB isolation level */
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
7203
static inline
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7204
ulint
7205
innobase_map_isolation_level(
7206
/*=========================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
7207
	enum_tx_isolation	iso)	/*!< in: MySQL isolation level code */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7208
{
7209
	switch(iso) {
7210
		case ISO_REPEATABLE_READ: return(TRX_ISO_REPEATABLE_READ);
7211
		case ISO_READ_COMMITTED: return(TRX_ISO_READ_COMMITTED);
7212
		case ISO_SERIALIZABLE: return(TRX_ISO_SERIALIZABLE);
7213
		case ISO_READ_UNCOMMITTED: return(TRX_ISO_READ_UNCOMMITTED);
7214
		default: ut_a(0); return(0);
7215
	}
7216
}
7217
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
7218
/******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7219
As MySQL will execute an external lock for every new table it uses when it
7220
starts to process an SQL statement (an exception is when MySQL calls
7221
start_stmt for the handle) we can use this function to store the pointer to
641.1.4 by Monty Taylor
Merged in InnoDB changes.
7222
the Session in the handle. We will also use this function to communicate
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7223
to InnoDB that a new SQL statement has started and that we must store a
7224
savepoint to our transaction handle, so that we are able to roll back
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
7225
the SQL statement in case of an error.
7226
@return	0 */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7227
UNIV_INTERN
7228
int
7229
ha_innobase::external_lock(
7230
/*=======================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
7231
	Session*	session,	/*!< in: handle to the user thread */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
7232
	int	lock_type)	/*!< in: lock type */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7233
{
7234
	trx_t*		trx;
7235
7236
933.1.2 by Monty Taylor
Fixed merge weirdness errors.
7237
	update_session(session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7238
7239
	trx = prebuilt->trx;
7240
7241
	prebuilt->sql_stat_start = TRUE;
7242
	prebuilt->hint_need_to_fetch_extra_cols = 0;
7243
7244
	reset_template(prebuilt);
7245
7246
	if (lock_type == F_WRLCK) {
7247
7248
		/* If this is a SELECT, then it is in UPDATE TABLE ...
7249
		or SELECT ... FOR UPDATE */
7250
		prebuilt->select_lock_type = LOCK_X;
7251
		prebuilt->stored_select_lock_type = LOCK_X;
7252
	}
7253
7254
	if (lock_type != F_UNLCK) {
7255
		/* MySQL is setting a new table lock */
7256
7257
		trx->detailed_error[0] = '\0';
7258
7259
		/* Set the MySQL flag to mark that there is an active
7260
		transaction */
7261
		if (trx->active_trans == 0) {
7262
960.2.37 by Monty Taylor
More naming fixes.
7263
			innobase_register_trx_and_stmt(engine, session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7264
			trx->active_trans = 1;
7265
		} else if (trx->n_mysql_tables_in_use == 0) {
960.2.37 by Monty Taylor
More naming fixes.
7266
			innobase_register_stmt(engine, session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7267
		}
7268
7269
		if (trx->isolation_level == TRX_ISO_SERIALIZABLE
7270
			&& prebuilt->select_lock_type == LOCK_NONE
641.1.4 by Monty Taylor
Merged in InnoDB changes.
7271
			&& session_test_options(session,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7272
				OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
7273
7274
			/* To get serializable execution, we let InnoDB
7275
			conceptually add 'LOCK IN SHARE MODE' to all SELECTs
7276
			which otherwise would have been consistent reads. An
7277
			exception is consistent reads in the AUTOCOMMIT=1 mode:
7278
			we know that they are read-only transactions, and they
7279
			can be serialized also if performed as consistent
7280
			reads. */
7281
7282
			prebuilt->select_lock_type = LOCK_S;
7283
			prebuilt->stored_select_lock_type = LOCK_S;
7284
		}
7285
7286
		/* Starting from 4.1.9, no InnoDB table lock is taken in LOCK
7287
		TABLES if AUTOCOMMIT=1. It does not make much sense to acquire
7288
		an InnoDB table lock if it is released immediately at the end
7289
		of LOCK TABLES, and InnoDB's table locks in that case cause
7290
		VERY easily deadlocks.
7291
7292
		We do not set InnoDB table locks if user has not explicitly
641.1.4 by Monty Taylor
Merged in InnoDB changes.
7293
		requested a table lock. Note that session_in_lock_tables(session)
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7294
		can hold in some cases, e.g., at the start of a stored
7295
		procedure call (SQLCOM_CALL). */
7296
7297
		if (prebuilt->select_lock_type != LOCK_NONE) {
7298
			trx->mysql_n_tables_locked++;
7299
		}
7300
7301
		trx->n_mysql_tables_in_use++;
7302
		prebuilt->mysql_has_locked = TRUE;
7303
641.1.4 by Monty Taylor
Merged in InnoDB changes.
7304
		return(0);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7305
	}
7306
7307
	/* MySQL is releasing a table lock */
7308
7309
	trx->n_mysql_tables_in_use--;
7310
	prebuilt->mysql_has_locked = FALSE;
7311
7312
	/* Release a possible FIFO ticket and search latch. Since we
7313
	may reserve the kernel mutex, we have to release the search
7314
	system latch first to obey the latching order. */
7315
7316
	innobase_release_stat_resources(trx);
7317
7318
	/* If the MySQL lock count drops to zero we know that the current SQL
7319
	statement has ended */
7320
7321
	if (trx->n_mysql_tables_in_use == 0) {
7322
7323
		trx->mysql_n_tables_locked = 0;
7324
		prebuilt->used_in_HANDLER = FALSE;
7325
641.1.4 by Monty Taylor
Merged in InnoDB changes.
7326
		if (!session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7327
			if (trx->active_trans != 0) {
960.2.38 by Monty Taylor
Removed extraneous send myself to myself argument.
7328
				engine->commit(session, TRUE);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7329
			}
7330
		} else {
7331
			if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
7332
						&& trx->global_read_view) {
7333
7334
				/* At low transaction isolation levels we let
7335
				each consistent read set its own snapshot */
7336
7337
				read_view_close_for_mysql(trx);
7338
			}
7339
		}
7340
	}
7341
641.1.4 by Monty Taylor
Merged in InnoDB changes.
7342
	return(0);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7343
}
7344
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
7345
/************************************************************************//**
7346
Here we export InnoDB status variables to MySQL. */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7347
static
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
7348
void
7349
innodb_export_status(void)
7350
/*======================*/
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7351
{
7352
	if (innodb_inited) {
7353
		srv_export_innodb_status();
7354
	}
7355
}
7356
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
7357
/************************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7358
Implements the SHOW INNODB STATUS command. Sends the output of the InnoDB
7359
Monitor to the client. */
7360
static
7361
bool
7362
innodb_show_status(
7363
/*===============*/
1114.1.5 by Monty Taylor
Merged up with trunk.
7364
	drizzled::plugin::StorageEngine*	engine,	/*!< in: the innodb StorageEngine */
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
7365
	Session*	session,/*!< in: the MySQL query thread of the caller */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7366
	stat_print_fn *stat_print)
7367
{
7368
	trx_t*			trx;
7369
	static const char	truncated_msg[] = "... truncated...\n";
7370
	const long		MAX_STATUS_SIZE = 64000;
7371
	ulint			trx_list_start = ULINT_UNDEFINED;
7372
	ulint			trx_list_end = ULINT_UNDEFINED;
7373
960.2.36 by Monty Taylor
More hton renaming.
7374
	assert(engine == innodb_engine_ptr);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7375
641.1.4 by Monty Taylor
Merged in InnoDB changes.
7376
	trx = check_trx_exists(session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7377
7378
	innobase_release_stat_resources(trx);
7379
7380
	/* We let the InnoDB Monitor to output at most MAX_STATUS_SIZE
7381
	bytes of text. */
7382
7383
	long	flen, usable_len;
7384
	char*	str;
7385
7386
	mutex_enter(&srv_monitor_file_mutex);
7387
	rewind(srv_monitor_file);
7388
	srv_printf_innodb_monitor(srv_monitor_file,
7389
				&trx_list_start, &trx_list_end);
7390
	flen = ftell(srv_monitor_file);
7391
	os_file_set_eof(srv_monitor_file);
7392
7393
	if (flen < 0) {
7394
		flen = 0;
7395
	}
7396
7397
	if (flen > MAX_STATUS_SIZE) {
7398
		usable_len = MAX_STATUS_SIZE;
7399
	} else {
7400
		usable_len = flen;
7401
	}
7402
7403
	/* allocate buffer for the string, and
7404
	read the contents of the temporary file */
7405
641.3.6 by Monty Taylor
Removed some my_malloc calls.
7406
	if (!(str = (char*) malloc(usable_len + 1))) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7407
	  mutex_exit(&srv_monitor_file_mutex);
641.1.4 by Monty Taylor
Merged in InnoDB changes.
7408
	  return(TRUE);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7409
	}
7410
7411
	rewind(srv_monitor_file);
7412
	if (flen < MAX_STATUS_SIZE) {
7413
		/* Display the entire output. */
7414
		flen = (long) fread(str, 1, flen, srv_monitor_file);
7415
	} else if (trx_list_end < (ulint) flen
7416
			&& trx_list_start < trx_list_end
7417
			&& trx_list_start + (flen - trx_list_end)
7418
			< MAX_STATUS_SIZE - sizeof truncated_msg - 1) {
7419
		/* Omit the beginning of the list of active transactions. */
7420
		long len = (long) fread(str, 1, trx_list_start, srv_monitor_file);
7421
		memcpy(str + len, truncated_msg, sizeof truncated_msg - 1);
7422
		len += sizeof truncated_msg - 1;
7423
		usable_len = (MAX_STATUS_SIZE - 1) - len;
7424
		fseek(srv_monitor_file, flen - usable_len, SEEK_SET);
7425
		len += (long) fread(str + len, 1, usable_len, srv_monitor_file);
7426
		flen = len;
7427
	} else {
7428
		/* Omit the end of the output. */
7429
		flen = (long) fread(str, 1, MAX_STATUS_SIZE - 1, srv_monitor_file);
7430
	}
7431
7432
	mutex_exit(&srv_monitor_file_mutex);
7433
7434
	bool result = FALSE;
7435
960.2.36 by Monty Taylor
More hton renaming.
7436
	if (stat_print(session, innobase_engine_name, strlen(innobase_engine_name),
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7437
			STRING_WITH_LEN(""), str, flen)) {
7438
		result= TRUE;
7439
	}
641.1.4 by Monty Taylor
Merged in InnoDB changes.
7440
	free(str);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7441
641.1.4 by Monty Taylor
Merged in InnoDB changes.
7442
	return(FALSE);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7443
}
7444
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
7445
/************************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7446
Implements the SHOW MUTEX STATUS command. . */
7447
static
7448
bool
7449
innodb_mutex_show_status(
7450
/*=====================*/
1114.1.5 by Monty Taylor
Merged up with trunk.
7451
	drizzled::plugin::StorageEngine*	engine,		/*!< in: the innodb StorageEngine */
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
7452
	Session*	session,	/*!< in: the MySQL query thread of the
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7453
					caller */
7454
	stat_print_fn*	stat_print)
7455
{
7456
	char buf1[IO_SIZE], buf2[IO_SIZE];
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
7457
	mutex_t*	mutex;
7458
	rw_lock_t*	lock;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7459
#ifdef UNIV_DEBUG
7460
	ulint	  rw_lock_count= 0;
7461
	ulint	  rw_lock_count_spin_loop= 0;
7462
	ulint	  rw_lock_count_spin_rounds= 0;
7463
	ulint	  rw_lock_count_os_wait= 0;
7464
	ulint	  rw_lock_count_os_yield= 0;
641.1.4 by Monty Taylor
Merged in InnoDB changes.
7465
	uint64_t rw_lock_wait_time= 0;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7466
#endif /* UNIV_DEBUG */
960.2.36 by Monty Taylor
More hton renaming.
7467
	uint	  engine_name_len= strlen(innobase_engine_name), buf1len, buf2len;
7468
	assert(engine == innodb_engine_ptr);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7469
7470
	mutex_enter(&mutex_list_mutex);
7471
7472
	mutex = UT_LIST_GET_FIRST(mutex_list);
7473
7474
	while (mutex != NULL) {
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
7475
		if (mutex->count_os_wait == 0
7476
		    || buf_pool_is_block_mutex(mutex)) {
7477
			goto next_mutex;
7478
		}
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7479
#ifdef UNIV_DEBUG
7480
		if (mutex->mutex_type != 1) {
7481
			if (mutex->count_using > 0) {
7482
				buf1len= my_snprintf(buf1, sizeof(buf1),
7483
					"%s:%s",
7484
					mutex->cmutex_name, mutex->cfile_name);
7485
				buf2len= my_snprintf(buf2, sizeof(buf2),
7486
					"count=%lu, spin_waits=%lu,"
7487
					" spin_rounds=%lu, "
7488
					"os_waits=%lu, os_yields=%lu,"
7489
					" os_wait_times=%lu",
7490
					mutex->count_using,
7491
					mutex->count_spin_loop,
7492
					mutex->count_spin_rounds,
7493
					mutex->count_os_wait,
7494
					mutex->count_os_yield,
7495
					(ulong) (mutex->lspent_time/1000));
7496
960.2.36 by Monty Taylor
More hton renaming.
7497
				if (stat_print(session, innobase_engine_name,
7498
						engine_name_len, buf1, buf1len,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7499
						buf2, buf2len)) {
7500
					mutex_exit(&mutex_list_mutex);
641.1.4 by Monty Taylor
Merged in InnoDB changes.
7501
					return(1);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7502
				}
7503
			}
7504
		}
7505
		else {
7506
			rw_lock_count += mutex->count_using;
7507
			rw_lock_count_spin_loop += mutex->count_spin_loop;
7508
			rw_lock_count_spin_rounds += mutex->count_spin_rounds;
7509
			rw_lock_count_os_wait += mutex->count_os_wait;
7510
			rw_lock_count_os_yield += mutex->count_os_yield;
7511
			rw_lock_wait_time += mutex->lspent_time;
7512
		}
7513
#else /* UNIV_DEBUG */
641.1.4 by Monty Taylor
Merged in InnoDB changes.
7514
		buf1len= snprintf(buf1, sizeof(buf1), "%s:%lu",
7515
				  mutex->cfile_name, (ulong) mutex->cline);
7516
		buf2len= snprintf(buf2, sizeof(buf2), "os_waits=%lu",
7517
				  mutex->count_os_wait);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7518
960.2.36 by Monty Taylor
More hton renaming.
7519
		if (stat_print(session, innobase_engine_name,
7520
			       engine_name_len, buf1, buf1len,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7521
			       buf2, buf2len)) {
7522
			mutex_exit(&mutex_list_mutex);
641.1.4 by Monty Taylor
Merged in InnoDB changes.
7523
			return(1);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7524
		}
7525
#endif /* UNIV_DEBUG */
7526
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
7527
next_mutex:
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7528
		mutex = UT_LIST_GET_NEXT(list, mutex);
7529
	}
7530
7531
	mutex_exit(&mutex_list_mutex);
7532
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
7533
	mutex_enter(&rw_lock_list_mutex);
7534
7535
	lock = UT_LIST_GET_FIRST(rw_lock_list);
7536
7537
	while (lock != NULL) {
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
7538
		if (lock->count_os_wait
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
7539
                    && !buf_pool_is_block_lock(lock)) {
933.1.2 by Monty Taylor
Fixed merge weirdness errors.
7540
			buf1len= snprintf(buf1, sizeof(buf1), "%s:%lu",
7541
                                    lock->cfile_name, (unsigned long) lock->cline);
7542
			buf2len= snprintf(buf2, sizeof(buf2),
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
7543
                                    "os_waits=%lu", lock->count_os_wait);
7544
960.2.36 by Monty Taylor
More hton renaming.
7545
			if (stat_print(session, innobase_engine_name,
7546
				       engine_name_len, buf1, buf1len,
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
7547
				       buf2, buf2len)) {
7548
				mutex_exit(&rw_lock_list_mutex);
933.1.2 by Monty Taylor
Fixed merge weirdness errors.
7549
				return(1);
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
7550
			}
7551
		}
7552
		lock = UT_LIST_GET_NEXT(list, lock);
7553
	}
7554
7555
	mutex_exit(&rw_lock_list_mutex);
7556
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7557
#ifdef UNIV_DEBUG
7558
	buf2len= my_snprintf(buf2, sizeof(buf2),
7559
		"count=%lu, spin_waits=%lu, spin_rounds=%lu, "
7560
		"os_waits=%lu, os_yields=%lu, os_wait_times=%lu",
7561
		rw_lock_count, rw_lock_count_spin_loop,
7562
		rw_lock_count_spin_rounds,
7563
		rw_lock_count_os_wait, rw_lock_count_os_yield,
7564
		(ulong) (rw_lock_wait_time/1000));
7565
960.2.36 by Monty Taylor
More hton renaming.
7566
	if (stat_print(session, innobase_engine_name, engine_name_len,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7567
			STRING_WITH_LEN("rw_lock_mutexes"), buf2, buf2len)) {
641.1.4 by Monty Taylor
Merged in InnoDB changes.
7568
		return(1);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7569
	}
7570
#endif /* UNIV_DEBUG */
7571
641.1.4 by Monty Taylor
Merged in InnoDB changes.
7572
	return(FALSE);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7573
}
7574
960.2.38 by Monty Taylor
Removed extraneous send myself to myself argument.
7575
bool InnobaseEngine::show_status(Session* session, 
960.2.32 by Monty Taylor
Converted Innodb handlerton.
7576
                                 stat_print_fn* stat_print,
7577
                                 enum ha_stat_type stat_type)
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7578
{
960.2.38 by Monty Taylor
Removed extraneous send myself to myself argument.
7579
	assert(this == innodb_engine_ptr);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7580
7581
	switch (stat_type) {
7582
	case HA_ENGINE_STATUS:
960.2.38 by Monty Taylor
Removed extraneous send myself to myself argument.
7583
		return innodb_show_status(this, session, stat_print);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7584
	case HA_ENGINE_MUTEX:
960.2.38 by Monty Taylor
Removed extraneous send myself to myself argument.
7585
		return innodb_mutex_show_status(this, session, stat_print);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7586
	default:
7587
		return(FALSE);
7588
	}
7589
}
7590
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
7591
/************************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7592
 Handling the shared INNOBASE_SHARE structure that is needed to provide table
7593
 locking.
7594
****************************************************************************/
7595
7596
static INNOBASE_SHARE* get_share(const char* table_name)
7597
{
7598
	INNOBASE_SHARE *share;
7599
	pthread_mutex_lock(&innobase_share_mutex);
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
7600
7601
	ulint	fold = ut_fold_string(table_name);
7602
7603
	HASH_SEARCH(table_name_hash, innobase_open_tables, fold,
7604
		    INNOBASE_SHARE*, share,
7605
		    ut_ad(share->use_count > 0),
7606
		    !strcmp(share->table_name, table_name));
7607
7608
	if (!share) {
7609
7610
		uint length = (uint) strlen(table_name);
7611
7612
		/* TODO: invoke HASH_MIGRATE if innobase_open_tables
7613
		grows too big */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7614
641.3.6 by Monty Taylor
Removed some my_malloc calls.
7615
		share = (INNOBASE_SHARE *) malloc(sizeof(*share)+length+1);
7616
                memset(share, 0, sizeof(*share)+length+1);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7617
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
7618
		share->table_name = (char*) memcpy(share + 1,
7619
						   table_name, length + 1);
7620
7621
		HASH_INSERT(INNOBASE_SHARE, table_name_hash,
7622
			    innobase_open_tables, fold, share);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7623
7624
		thr_lock_init(&share->lock);
7625
	}
7626
7627
	share->use_count++;
7628
	pthread_mutex_unlock(&innobase_share_mutex);
7629
7630
	return(share);
7631
}
7632
7633
static void free_share(INNOBASE_SHARE* share)
7634
{
7635
	pthread_mutex_lock(&innobase_share_mutex);
7636
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
7637
#ifdef UNIV_DEBUG
7638
	INNOBASE_SHARE* share2;
7639
	ulint	fold = ut_fold_string(share->table_name);
7640
7641
	HASH_SEARCH(table_name_hash, innobase_open_tables, fold,
7642
		    INNOBASE_SHARE*, share2,
7643
		    ut_ad(share->use_count > 0),
7644
		    !strcmp(share->table_name, share2->table_name));
7645
7646
	ut_a(share2 == share);
7647
#endif /* UNIV_DEBUG */
7648
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7649
	if (!--share->use_count) {
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
7650
		ulint	fold = ut_fold_string(share->table_name);
7651
7652
		HASH_DELETE(INNOBASE_SHARE, table_name_hash,
7653
			    innobase_open_tables, fold, share);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7654
		thr_lock_delete(&share->lock);
641.1.4 by Monty Taylor
Merged in InnoDB changes.
7655
		free(share);
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
7656
7657
		/* TODO: invoke HASH_MIGRATE if innobase_open_tables
7658
		shrinks too much */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7659
	}
7660
7661
	pthread_mutex_unlock(&innobase_share_mutex);
7662
}
7663
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
7664
/*****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7665
Converts a MySQL table lock stored in the 'lock' field of the handle to
7666
a proper type before storing pointer to the lock into an array of pointers.
7667
MySQL also calls this if it wants to reset some table locks to a not-locked
7668
state during the processing of an SQL query. An example is that during a
7669
SELECT the read lock is released early on the 'const' tables where we only
7670
fetch one row. MySQL does not call this when it releases all locks at the
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
7671
end of an SQL statement.
7672
@return	pointer to the next element in the 'to' array */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7673
UNIV_INTERN
7674
THR_LOCK_DATA**
7675
ha_innobase::store_lock(
7676
/*====================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
7677
	Session*		session,	/*!< in: user thread handle */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
7678
	THR_LOCK_DATA**		to,		/*!< in: pointer to an array
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7679
						of pointers to lock structs;
7680
						pointer to the 'lock' field
7681
						of current handle is stored
7682
						next to this array */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
7683
	enum thr_lock_type	lock_type)	/*!< in: lock type to store in
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7684
						'lock'; this may also be
7685
						TL_IGNORE */
7686
{
7687
	trx_t*		trx;
7688
7689
	/* Note that trx in this function is NOT necessarily prebuilt->trx
641.1.4 by Monty Taylor
Merged in InnoDB changes.
7690
	because we call update_session() later, in ::external_lock()! Failure to
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7691
	understand this caused a serious memory corruption bug in 5.1.11. */
7692
641.1.4 by Monty Taylor
Merged in InnoDB changes.
7693
	trx = check_trx_exists(session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7694
7695
	/* NOTE: MySQL can call this function with lock 'type' TL_IGNORE!
7696
	Be careful to ignore TL_IGNORE if we are going to do something with
7697
	only 'real' locks! */
7698
7699
	/* If no MySQL table is in use, we need to set the isolation level
7700
	of the transaction. */
7701
7702
	if (lock_type != TL_IGNORE
7703
	    && trx->n_mysql_tables_in_use == 0) {
7704
		trx->isolation_level = innobase_map_isolation_level(
641.1.4 by Monty Taylor
Merged in InnoDB changes.
7705
			(enum_tx_isolation) session_tx_isolation(session));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7706
7707
		if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
7708
		    && trx->global_read_view) {
7709
7710
			/* At low transaction isolation levels we let
7711
			each consistent read set its own snapshot */
7712
7713
			read_view_close_for_mysql(trx);
7714
		}
7715
	}
7716
641.1.5 by Monty Taylor
Merged in innodb plugin 1.0.2
7717
	assert(EQ_CURRENT_SESSION(session));
641.1.4 by Monty Taylor
Merged in InnoDB changes.
7718
	const uint32_t sql_command = session_sql_command(session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7719
7720
	if (sql_command == SQLCOM_DROP_TABLE) {
7721
641.1.4 by Monty Taylor
Merged in InnoDB changes.
7722
		/* MySQL calls this function in DROP Table though this table
7723
		handle may belong to another session that is running a query.
7724
		Let us in that case skip any changes to the prebuilt struct. */ 
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7725
1054.1.6 by Brian Aker
Removed internal logic/dead variables for LOCK TABLES.
7726
	} else if (lock_type == TL_READ_WITH_SHARED_LOCKS
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7727
		   || lock_type == TL_READ_NO_INSERT
7728
		   || (lock_type != TL_IGNORE
7729
		       && sql_command != SQLCOM_SELECT)) {
7730
7731
		/* The OR cases above are in this order:
7732
		1) MySQL is doing LOCK TABLES ... READ LOCAL, or we
7733
		are processing a stored procedure or function, or
7734
		2) (we do not know when TL_READ_HIGH_PRIORITY is used), or
7735
		3) this is a SELECT ... IN SHARE MODE, or
7736
		4) we are doing a complex SQL statement like
7737
		INSERT INTO ... SELECT ... and the logical logging (MySQL
7738
		binlog) requires the use of a locking read, or
7739
		MySQL is doing LOCK TABLES ... READ.
7740
		5) we let InnoDB do locking reads for all SQL statements that
7741
		are not simple SELECTs; note that select_lock_type in this
7742
		case may get strengthened in ::external_lock() to LOCK_X.
7743
		Note that we MUST use a locking read in all data modifying
7744
		SQL statements, because otherwise the execution would not be
7745
		serializable, and also the results from the update could be
7746
		unexpected if an obsolete consistent read view would be
7747
		used. */
7748
7749
		ulint	isolation_level;
7750
7751
		isolation_level = trx->isolation_level;
7752
7753
		if ((srv_locks_unsafe_for_binlog
7754
		     || isolation_level == TRX_ISO_READ_COMMITTED)
7755
		    && isolation_level != TRX_ISO_SERIALIZABLE
7756
		    && (lock_type == TL_READ || lock_type == TL_READ_NO_INSERT)
7757
		    && (sql_command == SQLCOM_INSERT_SELECT
7758
			|| sql_command == SQLCOM_UPDATE
7759
			|| sql_command == SQLCOM_CREATE_TABLE)) {
7760
7761
			/* If we either have innobase_locks_unsafe_for_binlog
7762
			option set or this session is using READ COMMITTED
7763
			isolation level and isolation level of the transaction
7764
			is not set to serializable and MySQL is doing
7765
			INSERT INTO...SELECT or UPDATE ... = (SELECT ...) or
7766
			CREATE  ... SELECT... without FOR UPDATE or
7767
			IN SHARE MODE in select, then we use consistent
7768
			read for select. */
7769
7770
			prebuilt->select_lock_type = LOCK_NONE;
7771
			prebuilt->stored_select_lock_type = LOCK_NONE;
7772
		} else if (sql_command == SQLCOM_CHECKSUM) {
7773
			/* Use consistent read for checksum table */
7774
7775
			prebuilt->select_lock_type = LOCK_NONE;
7776
			prebuilt->stored_select_lock_type = LOCK_NONE;
7777
		} else {
7778
			prebuilt->select_lock_type = LOCK_S;
7779
			prebuilt->stored_select_lock_type = LOCK_S;
7780
		}
7781
7782
	} else if (lock_type != TL_IGNORE) {
7783
7784
		/* We set possible LOCK_X value in external_lock, not yet
7785
		here even if this would be SELECT ... FOR UPDATE */
7786
7787
		prebuilt->select_lock_type = LOCK_NONE;
7788
		prebuilt->stored_select_lock_type = LOCK_NONE;
7789
	}
7790
7791
	if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK) {
7792
7793
		/* If we are not doing a LOCK TABLE, DISCARD/IMPORT
7794
		TABLESPACE or TRUNCATE TABLE then allow multiple
7795
		writers. Note that ALTER TABLE uses a TL_WRITE_ALLOW_READ
7796
		< TL_WRITE_CONCURRENT_INSERT.
7797
7798
		We especially allow multiple writers if MySQL is at the
7799
		start of a stored procedure call (SQLCOM_CALL) or a
7800
		stored function call (MySQL does have in_lock_tables
7801
		TRUE there). */
7802
7803
		if ((lock_type >= TL_WRITE_CONCURRENT_INSERT
7804
		     && lock_type <= TL_WRITE)
641.1.4 by Monty Taylor
Merged in InnoDB changes.
7805
		    && !session_tablespace_op(session)
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7806
		    && sql_command != SQLCOM_TRUNCATE
7807
		    && sql_command != SQLCOM_CREATE_TABLE) {
7808
7809
			lock_type = TL_WRITE_ALLOW_WRITE;
7810
		}
7811
7812
		/* In queries of type INSERT INTO t1 SELECT ... FROM t2 ...
7813
		MySQL would use the lock TL_READ_NO_INSERT on t2, and that
7814
		would conflict with TL_WRITE_ALLOW_WRITE, blocking all inserts
7815
		to t2. Convert the lock to a normal read lock to allow
7816
		concurrent inserts to t2.
7817
7818
		We especially allow concurrent inserts if MySQL is at the
7819
		start of a stored procedure call (SQLCOM_CALL)
641.1.4 by Monty Taylor
Merged in InnoDB changes.
7820
		(MySQL does have session_in_lock_tables() TRUE there). */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7821
1054.1.2 by Brian Aker
Remove SQLCOM_LOCK_TABLES
7822
		if (lock_type == TL_READ_NO_INSERT) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7823
7824
			lock_type = TL_READ;
7825
		}
7826
7827
		lock.type = lock_type;
7828
	}
7829
7830
	*to++= &lock;
7831
7832
	return(to);
7833
}
7834
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
7835
/*********************************************************************//**
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
7836
Read the next autoinc value. Acquire the relevant locks before reading
7837
the AUTOINC value. If SUCCESS then the table AUTOINC mutex will be locked
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
7838
on return and all relevant locks acquired.
7839
@return	DB_SUCCESS or error code */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7840
UNIV_INTERN
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
7841
ulint
7842
ha_innobase::innobase_get_autoinc(
7843
/*==============================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
7844
	uint64_t*	value)		/*!< out: autoinc value */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7845
{
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
7846
 	*value = 0;
7847
 
7848
	prebuilt->autoinc_error = innobase_lock_autoinc();
7849
7850
	if (prebuilt->autoinc_error == DB_SUCCESS) {
7851
7852
		/* Determine the first value of the interval */
7853
		*value = dict_table_autoinc_read(prebuilt->table);
7854
7855
		/* It should have been initialized during open. */
7856
		ut_a(*value != 0);
7857
	}
7858
7859
	return(prebuilt->autoinc_error);
7860
}
7861
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
7862
/*******************************************************************//**
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
7863
This function reads the global auto-inc counter. It doesn't use the 
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
7864
AUTOINC lock even if the lock mode is set to TRADITIONAL.
7865
@return	the autoinc value */
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
7866
UNIV_INTERN
641.1.5 by Monty Taylor
Merged in innodb plugin 1.0.2
7867
uint64_t
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
7868
ha_innobase::innobase_peek_autoinc(void)
7869
/*====================================*/
7870
{
641.1.5 by Monty Taylor
Merged in innodb plugin 1.0.2
7871
	uint64_t	auto_inc;
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
7872
	dict_table_t*	innodb_table;
7873
7874
	ut_a(prebuilt != NULL);
7875
	ut_a(prebuilt->table != NULL);
7876
7877
	innodb_table = prebuilt->table;
7878
7879
	dict_table_autoinc_lock(innodb_table);
7880
7881
	auto_inc = dict_table_autoinc_read(innodb_table);
7882
7883
	ut_a(auto_inc > 0);
7884
7885
	dict_table_autoinc_unlock(innodb_table);
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
7886
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
7887
	return(auto_inc);
7888
}
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
7889
7890
/*********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7891
This function initializes the auto-inc counter if it has not been
7892
initialized yet. This function does not change the value of the auto-inc
7893
counter if it already has been initialized. Returns the value of the
641.1.4 by Monty Taylor
Merged in InnoDB changes.
7894
auto-inc counter in *first_value, and UINT64_T_MAX in *nb_reserved_values (as
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7895
we have a table-level lock). offset, increment, nb_desired_values are ignored.
7896
*first_value is set to -1 if error (deadlock or lock wait timeout) */
7897
UNIV_INTERN
7898
void
7899
ha_innobase::get_auto_increment(
7900
/*============================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
7901
        uint64_t	offset,              /*!< in: table autoinc offset */
7902
        uint64_t	increment,           /*!< in: table autoinc increment */
7903
        uint64_t	nb_desired_values,   /*!< in: number of values reqd */
7904
        uint64_t	*first_value,        /*!< out: the autoinc value */
7905
        uint64_t	*nb_reserved_values) /*!< out: count of reserved values */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7906
{
7907
	trx_t*		trx;
7908
	ulint		error;
641.1.4 by Monty Taylor
Merged in InnoDB changes.
7909
	uint64_t	autoinc = 0;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7910
7911
	/* Prepare prebuilt->trx in the table handle */
641.1.4 by Monty Taylor
Merged in InnoDB changes.
7912
	update_session(ha_session());
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7913
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
7914
	error = innobase_get_autoinc(&autoinc);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7915
7916
	if (error != DB_SUCCESS) {
641.1.4 by Monty Taylor
Merged in InnoDB changes.
7917
		*first_value = (~(uint64_t) 0);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7918
		return;
7919
	}
7920
7921
	/* This is a hack, since nb_desired_values seems to be accurate only
7922
	for the first call to get_auto_increment() for multi-row INSERT and
7923
	meaningless for other statements e.g, LOAD etc. Subsequent calls to
7924
	this method for the same statement results in different values which
7925
	don't make sense. Therefore we store the value the first time we are
7926
	called and count down from that as rows are written (see write_row()).
7927
	*/
7928
7929
	trx = prebuilt->trx;
7930
7931
	/* Note: We can't rely on *first_value since some MySQL engines,
7932
	in particular the partition engine, don't initialize it to 0 when
7933
	invoking this method. So we are not sure if it's guaranteed to
7934
	be 0 or not. */
7935
7936
	/* Called for the first time ? */
7937
	if (trx->n_autoinc_rows == 0) {
7938
7939
		trx->n_autoinc_rows = (ulint) nb_desired_values;
7940
7941
		/* It's possible for nb_desired_values to be 0:
7942
		e.g., INSERT INTO T1(C) SELECT C FROM T2; */
7943
		if (nb_desired_values == 0) {
7944
7945
			trx->n_autoinc_rows = 1;
7946
		}
7947
7948
		set_if_bigger(*first_value, autoinc);
7949
	/* Not in the middle of a mult-row INSERT. */
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
7950
	} else if (prebuilt->autoinc_last_value == 0) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7951
		set_if_bigger(*first_value, autoinc);
7952
	}
7953
7954
	*nb_reserved_values = trx->n_autoinc_rows;
7955
7956
	/* With old style AUTOINC locking we only update the table's
7957
	AUTOINC counter after attempting to insert the row. */
7958
	if (innobase_autoinc_lock_mode != AUTOINC_OLD_STYLE_LOCKING) {
641.1.4 by Monty Taylor
Merged in InnoDB changes.
7959
		uint64_t	need;
641.1.5 by Monty Taylor
Merged in innodb plugin 1.0.2
7960
		uint64_t	next_value;
7961
		uint64_t	col_max_value;
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
7962
7963
		/* We need the upper limit of the col type to check for
7964
		whether we update the table autoinc counter or not. */
7965
		col_max_value = innobase_get_int_col_max_value(
7966
			table->next_number_field);
7967
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7968
		need = *nb_reserved_values * increment;
7969
7970
		/* Compute the last value in the interval */
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
7971
		next_value = innobase_next_autoinc(
7972
			*first_value, need, offset, col_max_value);
7973
7974
		prebuilt->autoinc_last_value = next_value;
7975
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
7976
		if (prebuilt->autoinc_last_value < *first_value) {
933.1.2 by Monty Taylor
Fixed merge weirdness errors.
7977
			*first_value = (~(unsigned long long) 0);
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
7978
		} else {
7979
			/* Update the table autoinc variable */
7980
			dict_table_autoinc_update_if_greater(
7981
				prebuilt->table, prebuilt->autoinc_last_value);
7982
		}
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7983
	} else {
7984
		/* This will force write_row() into attempting an update
7985
		of the table's AUTOINC counter. */
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
7986
		prebuilt->autoinc_last_value = 0;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7987
	}
7988
7989
	/* The increment to be used to increase the AUTOINC value, we use
7990
	this in write_row() and update_row() to increase the autoinc counter
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
7991
	for columns that are filled by the user. We need the offset and
7992
	the increment. */
7993
	prebuilt->autoinc_offset = offset;
7994
	prebuilt->autoinc_increment = increment;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
7995
7996
	dict_table_autoinc_unlock(prebuilt->table);
7997
}
7998
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
7999
/*******************************************************************//**
8000
Reset the auto-increment counter to the given value, i.e. the next row
8001
inserted will get the given value. This is called e.g. after TRUNCATE
8002
is emulated by doing a 'DELETE FROM t'. HA_ERR_WRONG_COMMAND is
8003
returned by storage engines that don't support this operation.
8004
@return	0 or error code */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8005
UNIV_INTERN
8006
int
8007
ha_innobase::reset_auto_increment(
8008
/*==============================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
8009
	uint64_t	value)		/*!< in: new value for table autoinc */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8010
{
8011
	int	error;
8012
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8013
	update_session(ha_session());
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8014
8015
	error = row_lock_table_autoinc_for_mysql(prebuilt);
8016
8017
	if (error != DB_SUCCESS) {
8018
		error = convert_error_code_to_mysql(error,
8019
						    prebuilt->table->flags,
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8020
						    user_session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8021
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8022
		return(error);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8023
	}
8024
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
8025
	/* The next value can never be 0. */
8026
	if (value == 0) {
8027
		value = 1;
8028
	}
8029
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8030
	innobase_reset_autoinc(value);
8031
1216.1.1 by Brian Aker
Move print_error up to Engine.
8032
	return 0;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8033
}
8034
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
8035
/* See comment in Cursor.cc */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8036
UNIV_INTERN
8037
bool
1216.1.1 by Brian Aker
Move print_error up to Engine.
8038
InnobaseEngine::get_error_message(int, String *buf)
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8039
{
1216.1.1 by Brian Aker
Move print_error up to Engine.
8040
	trx_t*	trx = check_trx_exists(current_session);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8041
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8042
	buf->copy(trx->detailed_error, (uint) strlen(trx->detailed_error),
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8043
		system_charset_info);
8044
8045
	return(FALSE);
8046
}
8047
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8048
/*******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8049
Compares two 'refs'. A 'ref' is the (internal) primary key value of the row.
8050
If there is no explicitly declared non-null unique key or a primary key, then
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8051
InnoDB internally uses the row id as the primary key.
8052
@return	< 0 if ref1 < ref2, 0 if equal, else > 0 */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8053
UNIV_INTERN
8054
int
8055
ha_innobase::cmp_ref(
8056
/*=================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
8057
	const unsigned char*	ref1,	/*!< in: an (internal) primary key value in the
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8058
				MySQL key value format */
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
8059
	const unsigned char*	ref2)	/*!< in: an (internal) primary key value in the
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8060
				MySQL key value format */
8061
{
8062
	enum_field_types mysql_type;
8063
	Field*		field;
8064
	KEY_PART_INFO*	key_part;
8065
	KEY_PART_INFO*	key_part_end;
8066
	uint		len1;
8067
	uint		len2;
8068
	int		result;
8069
8070
	if (prebuilt->clust_index_was_generated) {
8071
		/* The 'ref' is an InnoDB row id */
8072
8073
		return(memcmp(ref1, ref2, DATA_ROW_ID_LEN));
8074
	}
8075
8076
	/* Do a type-aware comparison of primary key fields. PK fields
8077
	are always NOT NULL, so no checks for NULL are performed. */
8078
8079
	key_part = table->key_info[table->s->primary_key].key_part;
8080
8081
	key_part_end = key_part
8082
			+ table->key_info[table->s->primary_key].key_parts;
8083
8084
	for (; key_part != key_part_end; ++key_part) {
8085
		field = key_part->field;
8086
		mysql_type = field->type();
8087
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8088
		if (mysql_type == DRIZZLE_TYPE_BLOB) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8089
8090
			/* In the MySQL key value format, a column prefix of
8091
			a BLOB is preceded by a 2-byte length field */
8092
8093
			len1 = innobase_read_from_2_little_endian(ref1);
8094
			len2 = innobase_read_from_2_little_endian(ref2);
8095
8096
			ref1 += 2;
8097
			ref2 += 2;
8098
			result = ((Field_blob*)field)->cmp( ref1, len1,
8099
                                                            ref2, len2);
8100
		} else {
8101
			result = field->key_cmp(ref1, ref2);
8102
		}
8103
8104
		if (result) {
8105
8106
			return(result);
8107
		}
8108
8109
		ref1 += key_part->store_length;
8110
		ref2 += key_part->store_length;
8111
	}
8112
8113
	return(0);
8114
}
8115
8116
/**********************************************************************
8117
This function is used to find the storage length in bytes of the first n
8118
characters for prefix indexes using a multibyte character set. The function
8119
finds charset information and returns length of prefix_len characters in the
8120
index field in bytes.
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8121
@return	number of bytes occupied by the first n characters */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8122
extern "C" UNIV_INTERN
8123
ulint
8124
innobase_get_at_most_n_mbchars(
8125
/*===========================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8126
	ulint charset_id,	/*!< in: character set id */
8127
	ulint prefix_len,	/*!< in: prefix length in bytes of the index
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8128
				(this has to be divided by mbmaxlen to get the
8129
				number of CHARACTERS n in the prefix) */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8130
	ulint data_len,		/*!< in: length of the string in bytes */
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
8131
	const char* str);	/*!< in: character string */
1085.1.2 by Monty Taylor
Fixed -Wmissing-declarations
8132
8133
ulint
8134
innobase_get_at_most_n_mbchars(
8135
/*===========================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
8136
	ulint charset_id,	/*!< in: character set id */
8137
	ulint prefix_len,	/*!< in: prefix length in bytes of the index
1085.1.2 by Monty Taylor
Fixed -Wmissing-declarations
8138
				(this has to be divided by mbmaxlen to get the
8139
				number of CHARACTERS n in the prefix) */
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
8140
	ulint data_len,		/*!< in: length of the string in bytes */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8141
	const char* str)	/*!< in: character string */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8142
{
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
8143
	ulint char_length;		/*!< character length in bytes */
8144
	ulint n_chars;			/*!< number of characters in prefix */
8145
	const CHARSET_INFO* charset;	/*!< charset used in the field */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8146
862 by Brian Aker
Remove charset directory code.
8147
	charset = get_charset((uint) charset_id);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8148
8149
	ut_ad(charset);
8150
	ut_ad(charset->mbmaxlen);
8151
8152
	/* Calculate how many characters at most the prefix index contains */
8153
8154
	n_chars = prefix_len / charset->mbmaxlen;
8155
8156
	/* If the charset is multi-byte, then we must find the length of the
8157
	first at most n chars in the string. If the string contains less
8158
	characters than n, then we return the length to the end of the last
8159
	character. */
8160
8161
	if (charset->mbmaxlen > 1) {
8162
		/* my_charpos() returns the byte length of the first n_chars
8163
		characters, or a value bigger than the length of str, if
8164
		there were not enough full characters in str.
8165
8166
		Why does the code below work:
8167
		Suppose that we are looking for n UTF-8 characters.
8168
8169
		1) If the string is long enough, then the prefix contains at
8170
		least n complete UTF-8 characters + maybe some extra
8171
		characters + an incomplete UTF-8 character. No problem in
8172
		this case. The function returns the pointer to the
8173
		end of the nth character.
8174
8175
		2) If the string is not long enough, then the string contains
8176
		the complete value of a column, that is, only complete UTF-8
8177
		characters, and we can store in the column prefix index the
8178
		whole string. */
8179
8180
		char_length = my_charpos(charset, str,
8181
						str + data_len, (int) n_chars);
8182
		if (char_length > data_len) {
8183
			char_length = data_len;
8184
		}
8185
	} else {
8186
		if (data_len < prefix_len) {
8187
			char_length = data_len;
8188
		} else {
8189
			char_length = prefix_len;
8190
		}
8191
	}
8192
8193
	return(char_length);
8194
}
8195
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8196
/*******************************************************************//**
8197
This function is used to prepare an X/Open XA distributed transaction.
8198
@return	0 or error number */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8199
int
960.2.34 by Monty Taylor
Fixed some innodb oopses.
8200
InnobaseEngine::prepare(
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8201
/*================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
8202
	Session*	session,/*!< in: handle to the MySQL thread of
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8203
				the user whose XA transaction should
8204
				be prepared */
8205
	bool		all)	/*!< in: TRUE - commit transaction
8206
				FALSE - the current SQL statement
8207
				ended */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8208
{
8209
	int error = 0;
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8210
	trx_t* trx = check_trx_exists(session);
8211
960.2.38 by Monty Taylor
Removed extraneous send myself to myself argument.
8212
	assert(this == innodb_engine_ptr);
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8213
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8214
	/* we use support_xa value as it was seen at transaction start
8215
	time, not the current session variable value. Any possible changes
8216
	to the session variable take effect only in the next transaction */
8217
	if (!trx->support_xa) {
8218
8219
		return(0);
8220
	}
8221
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
8222
	session_get_xid(session, reinterpret_cast<DRIZZLE_XID*>(&trx->xid));
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8223
8224
	/* Release a possible FIFO ticket and search latch. Since we will
8225
	reserve the kernel mutex, we have to release the search system latch
8226
	first to obey the latching order. */
8227
8228
	innobase_release_stat_resources(trx);
8229
8230
	if (trx->active_trans == 0 && trx->conc_state != TRX_NOT_STARTED) {
8231
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
8232
	  errmsg_printf(ERRMSG_LVL_ERROR,
8233
			"trx->active_trans == 0, but trx->conc_state != "
8234
			"TRX_NOT_STARTED");
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8235
	}
8236
8237
	if (all
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
8238
		|| (!session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8239
8240
		/* We were instructed to prepare the whole transaction, or
8241
		this is an SQL statement end and autocommit is on */
8242
8243
		ut_ad(trx->active_trans);
8244
8245
		error = (int) trx_prepare_for_mysql(trx);
8246
	} else {
8247
		/* We just mark the SQL statement ended and do not do a
8248
		transaction prepare */
8249
8250
		/* If we had reserved the auto-inc lock for some
8251
		table in this SQL statement we release it now */
8252
8253
		row_unlock_table_autoinc_for_mysql(trx);
8254
8255
		/* Store the current undo_no of the transaction so that we
8256
		know where to roll back if we have to roll back the next
8257
		SQL statement */
8258
8259
		trx_mark_sql_stat_end(trx);
8260
	}
8261
8262
	/* Tell the InnoDB server that there might be work for utility
8263
	threads: */
8264
8265
	srv_active_wake_master_thread();
8266
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8267
	if (all || !session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8268
	{
8269
8270
		/* For ibbackup to work the order of transactions in binlog
8271
		and InnoDB must be the same. Consider the situation
8272
8273
		  thread1> prepare; write to binlog; ...
8274
			  <context switch>
8275
		  thread2> prepare; write to binlog; commit
8276
		  thread1>			     ... commit
8277
8278
		To ensure this will not happen we're taking the mutex on
8279
		prepare, and releasing it on commit.
8280
8281
		Note: only do it for normal commits, done via ha_commit_trans.
8282
		If 2pc protocol is executed by external transaction
8283
		coordinator, it will be just a regular MySQL client
8284
		executing XA PREPARE and XA COMMIT commands.
8285
		In this case we cannot know how many minutes or hours
8286
		will be between XA PREPARE and XA COMMIT, and we don't want
8287
		to block for undefined period of time.
8288
		*/
8289
		pthread_mutex_lock(&prepare_commit_mutex);
8290
		trx->active_trans = 2;
8291
	}
8292
	return(error);
8293
}
8294
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8295
/*******************************************************************//**
8296
This function is used to recover X/Open XA distributed transactions.
8297
@return	number of prepared transactions stored in xid_list */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8298
int
960.2.34 by Monty Taylor
Fixed some innodb oopses.
8299
InnobaseEngine::recover(
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8300
/*================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8301
	XID*		xid_list,/*!< in/out: prepared transactions */
8302
	uint		len)	/*!< in: number of slots in xid_list */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8303
{
960.2.38 by Monty Taylor
Removed extraneous send myself to myself argument.
8304
	assert(this == innodb_engine_ptr);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8305
8306
	if (len == 0 || xid_list == NULL) {
8307
8308
		return(0);
8309
	}
8310
8311
	return(trx_recover_for_mysql(xid_list, len));
8312
}
8313
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8314
/*******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8315
This function is used to commit one X/Open XA distributed transaction
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8316
which is in the prepared state
8317
@return	0 or error number */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8318
int
960.2.32 by Monty Taylor
Converted Innodb handlerton.
8319
InnobaseEngine::commit_by_xid(
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8320
/*===================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8321
	XID*	xid)	/*!< in: X/Open XA transaction identification */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8322
{
8323
	trx_t*	trx;
8324
960.2.38 by Monty Taylor
Removed extraneous send myself to myself argument.
8325
	assert(this == innodb_engine_ptr);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8326
8327
	trx = trx_get_trx_by_xid(xid);
8328
8329
	if (trx) {
8330
		innobase_commit_low(trx);
8331
8332
		return(XA_OK);
8333
	} else {
8334
		return(XAER_NOTA);
8335
	}
8336
}
8337
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8338
/*******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8339
This function is used to rollback one X/Open XA distributed transaction
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8340
which is in the prepared state
8341
@return	0 or error number */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8342
int
960.2.32 by Monty Taylor
Converted Innodb handlerton.
8343
InnobaseEngine::rollback_by_xid(
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8344
/*=====================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8345
	XID*		xid)	/*!< in: X/Open XA transaction
8346
				identification */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8347
{
8348
	trx_t*	trx;
8349
960.2.38 by Monty Taylor
Removed extraneous send myself to myself argument.
8350
	assert(this == innodb_engine_ptr);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8351
8352
	trx = trx_get_trx_by_xid(xid);
8353
8354
	if (trx) {
8355
		return(innobase_rollback_trx(trx));
8356
	} else {
8357
		return(XAER_NOTA);
8358
	}
8359
}
8360
8361
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8362
/************************************************************//**
8363
Validate the file format name and return its corresponding id.
8364
@return	valid file format id */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8365
static
8366
uint
8367
innobase_file_format_name_lookup(
8368
/*=============================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8369
	const char*	format_name)	/*!< in: pointer to file format name */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8370
{
8371
	char*	endp;
8372
	uint	format_id;
8373
8374
	ut_a(format_name != NULL);
8375
8376
	/* The format name can contain the format id itself instead of
8377
	the name and we check for that. */
8378
	format_id = (uint) strtoul(format_name, &endp, 10);
8379
8380
	/* Check for valid parse. */
8381
	if (*endp == '\0' && *format_name != '\0') {
8382
8383
		if (format_id <= DICT_TF_FORMAT_MAX) {
8384
8385
			return(format_id);
8386
		}
8387
	} else {
8388
8389
		for (format_id = 0; format_id <= DICT_TF_FORMAT_MAX;
8390
		     format_id++) {
8391
			const char*	name;
8392
8393
			name = trx_sys_file_format_id_to_name(format_id);
8394
8395
			if (!innobase_strcasecmp(format_name, name)) {
8396
8397
				return(format_id);
8398
			}
8399
		}
8400
	}
8401
8402
	return(DICT_TF_FORMAT_MAX + 1);
8403
}
8404
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8405
/************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8406
Validate the file format check value, is it one of "on" or "off",
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8407
as a side effect it sets the srv_check_file_format_at_startup variable.
8408
@return	true if config value one of "on" or  "off" */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8409
static
8410
bool
8411
innobase_file_format_check_on_off(
8412
/*==============================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8413
	const char*	format_check)	/*!< in: parameter value */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8414
{
8415
	bool		ret = true;
8416
8417
	if (!innobase_strcasecmp(format_check, "off")) {
8418
8419
		/* Set the value to disable checking. */
8420
		srv_check_file_format_at_startup = DICT_TF_FORMAT_MAX + 1;
8421
8422
	} else if (!innobase_strcasecmp(format_check, "on")) {
8423
8424
		/* Set the value to the lowest supported format. */
8425
		srv_check_file_format_at_startup = DICT_TF_FORMAT_51;
8426
	} else {
8427
		ret = FALSE;
8428
	}
8429
8430
	return(ret);
8431
}
8432
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8433
/************************************************************//**
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
8434
Validate the file format check config parameters, as a side effect it
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8435
sets the srv_check_file_format_at_startup variable.
8436
@return	true if valid config value */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8437
static
8438
bool
8439
innobase_file_format_check_validate(
8440
/*================================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8441
	const char*	format_check)	/*!< in: parameter value */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8442
{
8443
	uint		format_id;
8444
	bool		ret = true;
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
8445
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8446
	format_id = innobase_file_format_name_lookup(format_check);
8447
8448
	if (format_id < DICT_TF_FORMAT_MAX + 1) {
8449
		srv_check_file_format_at_startup = format_id;
8450
	} else {
8451
		ret = false;
8452
	}
8453
8454
	return(ret);
8455
}
8456
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8457
/*************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8458
Check if it is a valid file format. This function is registered as
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8459
a callback with MySQL.
8460
@return	0 for valid file format */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8461
static
8462
int
8463
innodb_file_format_name_validate(
8464
/*=============================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
8465
	Session*			,	/*!< in: thread handle */
8466
	struct st_mysql_sys_var*	,	/*!< in: pointer to system
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8467
						variable */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8468
	void*				save,	/*!< out: immediate result
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8469
						for update function */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8470
	struct st_mysql_value*		value)	/*!< in: incoming string */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8471
{
8472
	const char*	file_format_input;
8473
	char		buff[STRING_BUFFER_USUAL_SIZE];
8474
	int		len = sizeof(buff);
8475
8476
	ut_a(save != NULL);
8477
	ut_a(value != NULL);
8478
8479
	file_format_input = value->val_str(value, buff, &len);
8480
8481
	if (file_format_input != NULL) {
8482
		uint	format_id;
8483
8484
		format_id = innobase_file_format_name_lookup(
8485
			file_format_input);
8486
8487
		if (format_id <= DICT_TF_FORMAT_MAX) {
8488
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8489
			*static_cast<const char**>(save) = file_format_input;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8490
			return(0);
8491
		}
8492
	}
8493
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8494
	*static_cast<const char**>(save) = NULL;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8495
	return(1);
8496
}
8497
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8498
/****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8499
Update the system variable innodb_file_format using the "saved"
8500
value. This function is registered as a callback with MySQL. */
8501
static
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
8502
void
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8503
innodb_file_format_name_update(
8504
/*===========================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
8505
	Session*			,		/*!< in: thread handle */
8506
	struct st_mysql_sys_var*	,		/*!< in: pointer to
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8507
							system variable */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8508
	void*				var_ptr,	/*!< out: where the
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8509
							formal string goes */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8510
	const void*			save)		/*!< in: immediate result
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8511
							from check function */
8512
{
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8513
	const char* format_name;
8514
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8515
	ut_a(var_ptr != NULL);
8516
	ut_a(save != NULL);
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8517
8518
	format_name = *static_cast<const char*const*>(save);
8519
8520
	if (format_name) {
8521
		uint	format_id;
8522
8523
		format_id = innobase_file_format_name_lookup(format_name);
8524
8525
		if (format_id <= DICT_TF_FORMAT_MAX) {
8526
			srv_file_format = format_id;
8527
		}
8528
	}
8529
8530
	*static_cast<const char**>(var_ptr)
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
8531
		= trx_sys_file_format_id_to_name(srv_file_format);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8532
}
8533
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8534
/*************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8535
Check if valid argument to innodb_file_format_check. This
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8536
function is registered as a callback with MySQL.
8537
@return	0 for valid file format */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8538
static
8539
int
8540
innodb_file_format_check_validate(
8541
/*==============================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
8542
	Session*			,	/*!< in: thread handle */
8543
	struct st_mysql_sys_var*	,	/*!< in: pointer to system
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8544
						variable */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8545
	void*				save,	/*!< out: immediate result
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8546
						for update function */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8547
	struct st_mysql_value*		value)	/*!< in: incoming string */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8548
{
8549
	const char*	file_format_input;
8550
	char		buff[STRING_BUFFER_USUAL_SIZE];
8551
	int		len = sizeof(buff);
8552
8553
	ut_a(save != NULL);
8554
	ut_a(value != NULL);
8555
8556
	file_format_input = value->val_str(value, buff, &len);
8557
8558
	if (file_format_input != NULL) {
8559
8560
		/* Check if user set on/off, we want to print a suitable
8561
		message if they did so. */
8562
8563
		if (innobase_file_format_check_on_off(file_format_input)) {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
8564
			errmsg_printf(ERRMSG_LVL_WARN, 
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
8565
				"InnoDB: invalid innodb_file_format_check "
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8566
				"value; on/off can only be set at startup or "
8567
				"in the configuration file");
8568
		} else if (innobase_file_format_check_validate(
8569
				file_format_input)) {
8570
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8571
			*static_cast<const char**>(save) = file_format_input;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8572
8573
			return(0);
8574
8575
		} else {
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
8576
			errmsg_printf(ERRMSG_LVL_WARN, 
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8577
				"InnoDB: invalid innodb_file_format_check "
8578
				"value; can be any format up to %s "
8579
				"or its equivalent numeric id",
8580
				trx_sys_file_format_id_to_name(
8581
					DICT_TF_FORMAT_MAX));
8582
		}
8583
	}
8584
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8585
	*static_cast<const char**>(save) = NULL;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8586
	return(1);
8587
}
8588
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8589
/****************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8590
Update the system variable innodb_file_format_check using the "saved"
8591
value. This function is registered as a callback with MySQL. */
8592
static
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
8593
void
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8594
innodb_file_format_check_update(
8595
/*============================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
8596
	Session*			session,	/*!< in: thread handle */
8597
	struct st_mysql_sys_var*	,		/*!< in: pointer to
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8598
							system variable */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8599
	void*				var_ptr,	/*!< out: where the
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8600
							formal string goes */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8601
	const void*			save)		/*!< in: immediate result
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8602
							from check function */
8603
{
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8604
	const char*	format_name_in;
8605
	const char**	format_name_out;
8606
	uint		format_id;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8607
8608
	ut_a(save != NULL);
8609
	ut_a(var_ptr != NULL);
8610
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8611
	format_name_in = *static_cast<const char*const*>(save);
8612
8613
	if (!format_name_in) {
8614
8615
		return;
8616
	}
8617
8618
	format_id = innobase_file_format_name_lookup(format_name_in);
8619
8620
	if (format_id > DICT_TF_FORMAT_MAX) {
8621
		/* DEFAULT is "on", which is invalid at runtime. */
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
8622
		push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8623
				    ER_WRONG_ARGUMENTS,
8624
				    "Ignoring SET innodb_file_format=%s",
8625
				    format_name_in);
8626
		return;
8627
	}
8628
8629
	format_name_out = static_cast<const char**>(var_ptr);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8630
8631
	/* Update the max format id in the system tablespace. */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8632
	if (trx_sys_file_format_max_set(format_id, format_name_out)) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8633
		ut_print_timestamp(stderr);
8634
		fprintf(stderr,
8635
			" [Info] InnoDB: the file format in the system "
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8636
			"tablespace is now set to %s.\n", *format_name_out);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8637
	}
8638
}
8639
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8640
/****************************************************************//**
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
8641
Update the system variable innodb_adaptive_hash_index using the "saved"
8642
value. This function is registered as a callback with MySQL. */
8643
static
8644
void
8645
innodb_adaptive_hash_index_update(
8646
/*==============================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
8647
	Session*			,		/*!< in: thread handle */
8648
	struct st_mysql_sys_var*	,		/*!< in: pointer to
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
8649
							system variable */
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
8650
	void*				,	/*!< out: where the
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
8651
							formal string goes */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8652
	const void*			save)		/*!< in: immediate result
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
8653
							from check function */
8654
{
933.1.1 by Monty Taylor
Merged in InnoDB Plugin 1.0.3
8655
	if (*(bool*) save) {
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
8656
		btr_search_enable();
8657
	} else {
8658
		btr_search_disable();
8659
	}
8660
}
8661
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8662
/*************************************************************//**
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
8663
Check if it is a valid value of innodb_change_buffering.  This function is
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8664
registered as a callback with MySQL.
8665
@return	0 for valid innodb_change_buffering */
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
8666
static
8667
int
8668
innodb_change_buffering_validate(
8669
/*=============================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
8670
	Session*			,	/*!< in: thread handle */
8671
	struct st_mysql_sys_var*	,	/*!< in: pointer to system
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
8672
						variable */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8673
	void*				save,	/*!< out: immediate result
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
8674
						for update function */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8675
	struct st_mysql_value*		value)	/*!< in: incoming string */
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
8676
{
8677
	const char*	change_buffering_input;
8678
	char		buff[STRING_BUFFER_USUAL_SIZE];
8679
	int		len = sizeof(buff);
8680
8681
	ut_a(save != NULL);
8682
	ut_a(value != NULL);
8683
8684
	change_buffering_input = value->val_str(value, buff, &len);
8685
8686
	if (change_buffering_input != NULL) {
8687
		ulint	use;
8688
8689
		for (use = 0; use < UT_ARR_SIZE(innobase_change_buffering_values);
8690
		     use++) {
8691
			if (!innobase_strcasecmp(
8692
				    change_buffering_input,
8693
				    innobase_change_buffering_values[use])) {
8694
				*(ibuf_use_t*) save = (ibuf_use_t) use;
8695
				return(0);
8696
			}
8697
		}
8698
	}
8699
8700
	return(1);
8701
}
8702
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8703
/****************************************************************//**
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
8704
Update the system variable innodb_change_buffering using the "saved"
8705
value. This function is registered as a callback with MySQL. */
8706
static
8707
void
8708
innodb_change_buffering_update(
8709
/*===========================*/
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
8710
	Session*			,		/*!< in: thread handle */
8711
	struct st_mysql_sys_var*	,		/*!< in: pointer to
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
8712
							system variable */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8713
	void*				var_ptr,	/*!< out: where the
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
8714
							formal string goes */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8715
	const void*			save)		/*!< in: immediate result
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
8716
							from check function */
8717
{
8718
	ut_a(var_ptr != NULL);
8719
	ut_a(save != NULL);
8720
	ut_a((*(ibuf_use_t*) save) < IBUF_USE_COUNT);
8721
8722
	ibuf_use = *(const ibuf_use_t*) save;
8723
8724
	*(const char**) var_ptr = innobase_change_buffering_values[ibuf_use];
8725
}
8726
1019.1.1 by Brian Aker
Merge (also removes session from show variables).
8727
static int show_innodb_vars(SHOW_VAR *var, char *)
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8728
{
8729
  innodb_export_status();
8730
  var->type= SHOW_ARRAY;
8731
  var->value= (char *) &innodb_status_variables;
8732
  return 0;
8733
}
8734
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8735
static st_show_var_func_container
8736
show_innodb_vars_cont = { &show_innodb_vars };
8737
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8738
static SHOW_VAR innodb_status_variables_export[]= {
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8739
  {"Innodb",                   (char*) &show_innodb_vars_cont, SHOW_FUNC},
8740
  {NULL, NULL, SHOW_LONG}
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8741
};
8742
8743
8744
/* plugin options */
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8745
static DRIZZLE_SYSVAR_BOOL(checksums, innobase_use_checksums,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8746
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
8747
  "Enable InnoDB checksums validation (enabled by default). "
8748
  "Disable with --skip-innodb-checksums.",
8749
  NULL, NULL, TRUE);
8750
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8751
static DRIZZLE_SYSVAR_STR(data_home_dir, innobase_data_home_dir,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8752
  PLUGIN_VAR_READONLY,
8753
  "The common part for InnoDB table spaces.",
8754
  NULL, NULL, NULL);
8755
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8756
static DRIZZLE_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8757
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
8758
  "Enable InnoDB doublewrite buffer (enabled by default). "
8759
  "Disable with --skip-innodb-doublewrite.",
8760
  NULL, NULL, TRUE);
8761
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
8762
static DRIZZLE_SYSVAR_ULONG(io_capacity, srv_io_capacity,
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8763
  PLUGIN_VAR_RQCMDARG,
8764
  "Number of IOPs the server can do. Tunes the background IO rate",
8765
  NULL, NULL, 200, 100, ~0L, 0);
8766
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8767
static DRIZZLE_SYSVAR_ULONG(fast_shutdown, innobase_fast_shutdown,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8768
  PLUGIN_VAR_OPCMDARG,
8769
  "Speeds up the shutdown process of the InnoDB storage engine. Possible "
8770
  "values are 0, 1 (faster)"
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8771
  " or 2 (fastest - crash-like)"
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8772
  ".",
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8773
  NULL, NULL, 1, 0, 2, 0);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8774
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8775
static DRIZZLE_SYSVAR_BOOL(file_per_table, srv_file_per_table,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8776
  PLUGIN_VAR_NOCMDARG,
8777
  "Stores each InnoDB table to an .ibd file in the database dir.",
8778
  NULL, NULL, FALSE);
8779
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8780
static DRIZZLE_SYSVAR_STR(file_format, innobase_file_format_name,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8781
  PLUGIN_VAR_RQCMDARG,
8782
  "File format to use for new tables in .ibd files.",
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
8783
  innodb_file_format_name_validate,
8784
  innodb_file_format_name_update, "Antelope");
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8785
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8786
static DRIZZLE_SYSVAR_STR(file_format_check, innobase_file_format_check,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8787
  PLUGIN_VAR_OPCMDARG,
8788
  "The highest file format in the tablespace.",
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
8789
  innodb_file_format_check_validate,
8790
  innodb_file_format_check_update,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8791
  "on");
8792
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8793
static DRIZZLE_SYSVAR_ULONG(flush_log_at_trx_commit, srv_flush_log_at_trx_commit,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8794
  PLUGIN_VAR_OPCMDARG,
8795
  "Set to 0 (write and flush once per second),"
8796
  " 1 (write and flush at each commit)"
8797
  " or 2 (write at commit, flush once per second).",
8798
  NULL, NULL, 1, 0, 2, 0);
8799
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8800
static DRIZZLE_SYSVAR_STR(flush_method, innobase_unix_file_flush_method,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8801
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
8802
  "With which method to flush data.", NULL, NULL, NULL);
8803
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8804
static DRIZZLE_SYSVAR_BOOL(locks_unsafe_for_binlog, innobase_locks_unsafe_for_binlog,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8805
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
8806
  "Force InnoDB to not use next-key locking, to use only row-level locking.",
884 by Brian Aker
Fix for bad default value for Drizzle
8807
  NULL, NULL, TRUE);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8808
8809
#ifdef UNIV_LOG_ARCHIVE
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8810
static DRIZZLE_SYSVAR_STR(log_arch_dir, innobase_log_arch_dir,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8811
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
8812
  "Where full logs should be archived.", NULL, NULL, NULL);
8813
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8814
static DRIZZLE_SYSVAR_BOOL(log_archive, innobase_log_archive,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8815
  PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
8816
  "Set to 1 if you want to have logs archived.", NULL, NULL, FALSE);
8817
#endif /* UNIV_LOG_ARCHIVE */
8818
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8819
static DRIZZLE_SYSVAR_STR(log_group_home_dir, innobase_log_group_home_dir,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8820
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
8821
  "Path to InnoDB log files.", NULL, NULL, NULL);
8822
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8823
static DRIZZLE_SYSVAR_ULONG(max_dirty_pages_pct, srv_max_buf_pool_modified_pct,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8824
  PLUGIN_VAR_RQCMDARG,
8825
  "Percentage of dirty pages allowed in bufferpool.",
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8826
  NULL, NULL, 75, 0, 99, 0);
8827
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
8828
static DRIZZLE_SYSVAR_BOOL(adaptive_flushing, srv_adaptive_flushing,
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8829
  PLUGIN_VAR_NOCMDARG,
8830
  "Attempt flushing dirty pages to avoid IO bursts at checkpoints.",
8831
  NULL, NULL, TRUE);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8832
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8833
static DRIZZLE_SYSVAR_ULONG(max_purge_lag, srv_max_purge_lag,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8834
  PLUGIN_VAR_RQCMDARG,
8835
  "Desired maximum length of the purge queue (0 = no limit)",
8836
  NULL, NULL, 0, 0, ~0L, 0);
8837
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8838
static DRIZZLE_SYSVAR_BOOL(rollback_on_timeout, innobase_rollback_on_timeout,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8839
  PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
8840
  "Roll back the complete transaction on lock wait timeout, for 4.x compatibility (disabled by default)",
8841
  NULL, NULL, FALSE);
8842
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8843
static DRIZZLE_SYSVAR_BOOL(status_file, innobase_create_status_file,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8844
  PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_NOSYSVAR,
8845
  "Enable SHOW INNODB STATUS output in the innodb_status.<pid> file",
8846
  NULL, NULL, FALSE);
8847
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8848
static DRIZZLE_SYSVAR_BOOL(stats_on_metadata, innobase_stats_on_metadata,
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
8849
  PLUGIN_VAR_OPCMDARG,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8850
  "Enable statistics gathering for metadata commands such as SHOW TABLE STATUS (on by default)",
8851
  NULL, NULL, TRUE);
8852
641.1.5 by Monty Taylor
Merged in innodb plugin 1.0.2
8853
static DRIZZLE_SYSVAR_ULONGLONG(stats_sample_pages, srv_stats_sample_pages,
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
8854
  PLUGIN_VAR_RQCMDARG,
8855
  "The number of index pages to sample when calculating statistics (default 8)",
8856
  NULL, NULL, 8, 1, ~0ULL, 0);
8857
933.1.1 by Monty Taylor
Merged in InnoDB Plugin 1.0.3
8858
static DRIZZLE_SYSVAR_BOOL(adaptive_hash_index, btr_search_enabled,
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
8859
  PLUGIN_VAR_OPCMDARG,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8860
  "Enable InnoDB adaptive hash index (enabled by default).  "
8861
  "Disable with --skip-innodb-adaptive-hash-index.",
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
8862
  NULL, innodb_adaptive_hash_index_update, TRUE);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8863
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8864
static DRIZZLE_SYSVAR_ULONG(replication_delay, srv_replication_delay,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8865
  PLUGIN_VAR_RQCMDARG,
8866
  "Replication thread delay (ms) on the slave server if "
8867
  "innodb_thread_concurrency is reached (0 by default)",
8868
  NULL, NULL, 0, 0, ~0UL, 0);
8869
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8870
static DRIZZLE_SYSVAR_LONG(additional_mem_pool_size, innobase_additional_mem_pool_size,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8871
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
8872
  "Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.",
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8873
  NULL, NULL, 8*1024*1024L, 512*1024L, LONG_MAX, 1024);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8874
937.3.4 by Stewart Smith
fix innodb_autoextend_increment for sparc
8875
static DRIZZLE_SYSVAR_UINT(autoextend_increment, srv_auto_extend_increment,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8876
  PLUGIN_VAR_RQCMDARG,
8877
  "Data file autoextend increment in megabytes",
8878
  NULL, NULL, 8L, 1L, 1000L, 0);
8879
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8880
static DRIZZLE_SYSVAR_LONGLONG(buffer_pool_size, innobase_buffer_pool_size,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8881
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
8882
  "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.",
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
8883
  NULL, NULL, 128*1024*1024L, 5*1024*1024L, INT64_MAX, 1024*1024L);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8884
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
8885
static DRIZZLE_SYSVAR_ULONG(commit_concurrency, innobase_commit_concurrency,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8886
  PLUGIN_VAR_RQCMDARG,
8887
  "Helps in performance tuning in heavily concurrent environments.",
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8888
  innobase_commit_concurrency_validate, NULL, 0, 0, 1000, 0);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8889
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8890
static DRIZZLE_SYSVAR_ULONG(concurrency_tickets, srv_n_free_tickets_to_enter,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8891
  PLUGIN_VAR_RQCMDARG,
8892
  "Number of times a thread is allowed to enter InnoDB within the same SQL query after it has once got the ticket",
8893
  NULL, NULL, 500L, 1L, ~0L, 0);
8894
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8895
static DRIZZLE_SYSVAR_LONG(file_io_threads, innobase_file_io_threads,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8896
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
8897
  "Number of file I/O threads in InnoDB.",
8898
  NULL, NULL, 4, 4, 64, 0);
8899
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
8900
static DRIZZLE_SYSVAR_ULONG(read_io_threads, innobase_read_io_threads,
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8901
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
8902
  "Number of background read I/O threads in InnoDB.",
8903
  NULL, NULL, 4, 1, 64, 0);
8904
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
8905
static DRIZZLE_SYSVAR_ULONG(write_io_threads, innobase_write_io_threads,
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8906
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
8907
  "Number of background write I/O threads in InnoDB.",
8908
  NULL, NULL, 4, 1, 64, 0);
8909
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8910
static DRIZZLE_SYSVAR_LONG(force_recovery, innobase_force_recovery,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8911
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
8912
  "Helps to save your data in case the disk image of the database becomes corrupt.",
8913
  NULL, NULL, 0, 0, 6, 0);
8914
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8915
static DRIZZLE_SYSVAR_LONG(log_buffer_size, innobase_log_buffer_size,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8916
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
8917
  "The size of the buffer which InnoDB uses to write log to the log files on disk.",
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8918
  NULL, NULL, 8*1024*1024L, 256*1024L, LONG_MAX, 1024);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8919
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8920
static DRIZZLE_SYSVAR_LONGLONG(log_file_size, innobase_log_file_size,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8921
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
8922
  "Size of each log file in a log group.",
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8923
  NULL, NULL, 5*1024*1024L, 1*1024*1024L, INT64_MAX, 1024*1024L);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8924
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8925
static DRIZZLE_SYSVAR_LONG(log_files_in_group, innobase_log_files_in_group,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8926
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
8927
  "Number of log files in the log group. InnoDB writes to the files in a circular fashion. Value 3 is recommended here.",
8928
  NULL, NULL, 2, 2, 100, 0);
8929
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8930
static DRIZZLE_SYSVAR_LONG(mirrored_log_groups, innobase_mirrored_log_groups,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8931
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
8932
  "Number of identical copies of log groups we keep for the database. Currently this should be set to 1.",
8933
  NULL, NULL, 1, 1, 10, 0);
8934
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8935
static DRIZZLE_SYSVAR_LONG(open_files, innobase_open_files,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8936
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
8937
  "How many files at the maximum InnoDB keeps open at the same time.",
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
8938
  NULL, NULL, 300L, 10L, LONG_MAX, 0);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8939
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8940
static DRIZZLE_SYSVAR_ULONG(sync_spin_loops, srv_n_spin_wait_rounds,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8941
  PLUGIN_VAR_RQCMDARG,
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8942
  "Count of spin-loop rounds in InnoDB mutexes (30 by default)",
8943
  NULL, NULL, 30L, 0L, ~0L, 0);
8944
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
8945
static DRIZZLE_SYSVAR_ULONG(spin_wait_delay, srv_spin_wait_delay,
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8946
  PLUGIN_VAR_OPCMDARG,
8947
  "Maximum delay between polling for a spin lock (6 by default)",
8948
  NULL, NULL, 6L, 0L, ~0L, 0);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8949
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8950
static DRIZZLE_SYSVAR_ULONG(thread_concurrency, srv_thread_concurrency,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8951
  PLUGIN_VAR_RQCMDARG,
8952
  "Helps in performance tuning in heavily concurrent environments. Sets the maximum number of threads allowed inside InnoDB. Value 0 will disable the thread throttling.",
869 by Brian Aker
Fix concurrency issue (remove dead variables)
8953
  NULL, NULL, 0, 0, 1000, 0);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8954
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8955
static DRIZZLE_SYSVAR_ULONG(thread_sleep_delay, srv_thread_sleep_delay,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8956
  PLUGIN_VAR_RQCMDARG,
8957
  "Time of innodb thread sleeping before joining InnoDB queue (usec). Value 0 disable a sleep",
8958
  NULL, NULL, 10000L, 0L, ~0L, 0);
8959
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8960
static DRIZZLE_SYSVAR_STR(data_file_path, innobase_data_file_path,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8961
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
8962
  "Path to individual files and their sizes.",
8963
  NULL, NULL, NULL);
8964
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8965
static DRIZZLE_SYSVAR_LONG(autoinc_lock_mode, innobase_autoinc_lock_mode,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8966
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
8967
  "The AUTOINC lock modes supported by InnoDB:               "
8968
  "0 => Old style AUTOINC locking (for backward"
8969
  " compatibility)                                           "
8970
  "1 => New style AUTOINC locking                            "
8971
  "2 => No AUTOINC locking (unsafe for SBR)",
8972
  NULL, NULL,
1182.1.1 by Brian Aker
Updated Innodb
8973
  AUTOINC_NO_LOCKING,	/* Default setting */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8974
  AUTOINC_OLD_STYLE_LOCKING,	/* Minimum value */
8975
  AUTOINC_NO_LOCKING, 0);	/* Maximum value */
8976
641.1.4 by Monty Taylor
Merged in InnoDB changes.
8977
static DRIZZLE_SYSVAR_STR(version, innodb_version_str,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8978
  PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_READONLY,
8979
  "InnoDB version", NULL, NULL, INNODB_VERSION_STR);
8980
933.1.2 by Monty Taylor
Fixed merge weirdness errors.
8981
static DRIZZLE_SYSVAR_BOOL(use_sys_malloc, srv_use_sys_malloc,
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
8982
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
8983
  "Use OS memory allocator instead of InnoDB's internal memory allocator",
8984
  NULL, NULL, TRUE);
8985
933.1.2 by Monty Taylor
Fixed merge weirdness errors.
8986
static DRIZZLE_SYSVAR_STR(change_buffering, innobase_change_buffering,
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
8987
  PLUGIN_VAR_RQCMDARG,
8988
  "Buffer changes to reduce random access: "
8989
  "OFF, ON, inserting, deleting, changing, or purging.",
8990
  innodb_change_buffering_validate,
8991
  innodb_change_buffering_update, NULL);
8992
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
8993
static DRIZZLE_SYSVAR_ULONG(read_ahead_threshold, srv_read_ahead_threshold,
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
8994
  PLUGIN_VAR_RQCMDARG,
8995
  "Number of pages that must be accessed sequentially for InnoDB to"
8996
  "trigger a readahead.",
8997
  NULL, NULL, 56, 0, 64, 0);
8998
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
8999
static struct st_mysql_sys_var* innobase_system_variables[]= {
641.1.4 by Monty Taylor
Merged in InnoDB changes.
9000
  DRIZZLE_SYSVAR(additional_mem_pool_size),
9001
  DRIZZLE_SYSVAR(autoextend_increment),
9002
  DRIZZLE_SYSVAR(buffer_pool_size),
9003
  DRIZZLE_SYSVAR(checksums),
9004
  DRIZZLE_SYSVAR(commit_concurrency),
9005
  DRIZZLE_SYSVAR(concurrency_tickets),
9006
  DRIZZLE_SYSVAR(data_file_path),
9007
  DRIZZLE_SYSVAR(data_home_dir),
9008
  DRIZZLE_SYSVAR(doublewrite),
9009
  DRIZZLE_SYSVAR(fast_shutdown),
9010
  DRIZZLE_SYSVAR(file_io_threads),
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
9011
  DRIZZLE_SYSVAR(read_io_threads),
9012
  DRIZZLE_SYSVAR(write_io_threads),
641.1.4 by Monty Taylor
Merged in InnoDB changes.
9013
  DRIZZLE_SYSVAR(file_per_table),
9014
  DRIZZLE_SYSVAR(file_format),
9015
  DRIZZLE_SYSVAR(file_format_check),
9016
  DRIZZLE_SYSVAR(flush_log_at_trx_commit),
9017
  DRIZZLE_SYSVAR(flush_method),
9018
  DRIZZLE_SYSVAR(force_recovery),
9019
  DRIZZLE_SYSVAR(locks_unsafe_for_binlog),
9020
  DRIZZLE_SYSVAR(lock_wait_timeout),
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
9021
#ifdef UNIV_LOG_ARCHIVE
641.1.4 by Monty Taylor
Merged in InnoDB changes.
9022
  DRIZZLE_SYSVAR(log_arch_dir),
9023
  DRIZZLE_SYSVAR(log_archive),
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
9024
#endif /* UNIV_LOG_ARCHIVE */
641.1.4 by Monty Taylor
Merged in InnoDB changes.
9025
  DRIZZLE_SYSVAR(log_buffer_size),
9026
  DRIZZLE_SYSVAR(log_file_size),
9027
  DRIZZLE_SYSVAR(log_files_in_group),
9028
  DRIZZLE_SYSVAR(log_group_home_dir),
9029
  DRIZZLE_SYSVAR(max_dirty_pages_pct),
9030
  DRIZZLE_SYSVAR(max_purge_lag),
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
9031
  DRIZZLE_SYSVAR(adaptive_flushing),
641.1.4 by Monty Taylor
Merged in InnoDB changes.
9032
  DRIZZLE_SYSVAR(mirrored_log_groups),
9033
  DRIZZLE_SYSVAR(open_files),
9034
  DRIZZLE_SYSVAR(rollback_on_timeout),
9035
  DRIZZLE_SYSVAR(stats_on_metadata),
641.1.5 by Monty Taylor
Merged in innodb plugin 1.0.2
9036
  DRIZZLE_SYSVAR(stats_sample_pages),
641.1.4 by Monty Taylor
Merged in InnoDB changes.
9037
  DRIZZLE_SYSVAR(adaptive_hash_index),
9038
  DRIZZLE_SYSVAR(replication_delay),
9039
  DRIZZLE_SYSVAR(status_file),
9040
  DRIZZLE_SYSVAR(strict_mode),
9041
  DRIZZLE_SYSVAR(support_xa),
9042
  DRIZZLE_SYSVAR(sync_spin_loops),
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
9043
  DRIZZLE_SYSVAR(spin_wait_delay),
641.1.4 by Monty Taylor
Merged in InnoDB changes.
9044
  DRIZZLE_SYSVAR(table_locks),
9045
  DRIZZLE_SYSVAR(thread_concurrency),
9046
  DRIZZLE_SYSVAR(thread_sleep_delay),
9047
  DRIZZLE_SYSVAR(autoinc_lock_mode),
9048
  DRIZZLE_SYSVAR(version),
933.1.1 by Monty Taylor
Merged in InnoDB Plugin 1.0.3
9049
  DRIZZLE_SYSVAR(use_sys_malloc),
9050
  DRIZZLE_SYSVAR(change_buffering),
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
9051
  DRIZZLE_SYSVAR(read_ahead_threshold),
9052
  DRIZZLE_SYSVAR(io_capacity),
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
9053
  NULL
9054
};
9055
1192.3.7 by Monty Taylor
Added code necessary for building plugins dynamically.
9056
drizzle_declare_plugin
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
9057
{
960.2.36 by Monty Taylor
More hton renaming.
9058
  innobase_engine_name,
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
9059
  INNODB_VERSION_STR,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
9060
  "Innobase Oy",
9061
  "Supports transactions, row-level locking, and foreign keys",
9062
  PLUGIN_LICENSE_GPL,
9063
  innobase_init, /* Plugin Init */
641.1.4 by Monty Taylor
Merged in InnoDB changes.
9064
  innobase_deinit, /* Plugin Deinit */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
9065
  innodb_status_variables_export,/* status variables             */
9066
  innobase_system_variables, /* system variables */
9067
  NULL /* reserved */
971.1.65 by Monty Taylor
Changed plugin registration of I_S tables in innodb.
9068
}
813.2.2 by Toru Maesaka
Renamed mysql_declare_plugin_end to drizzle_declare_plugin_end
9069
drizzle_declare_plugin_end;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
9070
641.1.4 by Monty Taylor
Merged in InnoDB changes.
9071
int ha_innobase::read_range_first(const key_range *start_key,
9072
				  const key_range *end_key,
9073
				  bool eq_range_arg,
9074
				  bool sorted)
9075
{
9076
  int res;
9077
  //if (!eq_range_arg)
9078
    //in_range_read= TRUE;
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
9079
  res= Cursor::read_range_first(start_key, end_key, eq_range_arg, sorted);
641.1.4 by Monty Taylor
Merged in InnoDB changes.
9080
  //if (res)
9081
  //  in_range_read= FALSE;
9082
  return res;
9083
}
9084
9085
9086
int ha_innobase::read_range_next()
9087
{
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
9088
  int res= Cursor::read_range_next();
641.1.4 by Monty Taylor
Merged in InnoDB changes.
9089
  //if (res)
9090
  //  in_range_read= FALSE;
9091
  return res;
9092
}
9093
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
9094
/** @brief Initialize the default value of innodb_commit_concurrency.
9095
9096
Once InnoDB is running, the innodb_commit_concurrency must not change
9097
from zero to nonzero. (Bug #42101)
9098
9099
The initial default value is 0, and without this extra initialization,
9100
SET GLOBAL innodb_commit_concurrency=DEFAULT would set the parameter
9101
to 0, even if it was initially set to nonzero at the command line
9102
or configuration file. */
9103
static
9104
void
9105
innobase_commit_concurrency_init_default(void)
9106
/*==========================================*/
9107
{
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
9108
	DRIZZLE_SYSVAR_NAME(commit_concurrency).def_val
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
9109
		= innobase_commit_concurrency;
9110
}
9111
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
9112
#ifdef UNIV_COMPILE_TEST_FUNCS
9113
9114
typedef struct innobase_convert_name_test_struct {
9115
	char*		buf;
9116
	ulint		buflen;
9117
	const char*	id;
9118
	ulint		idlen;
641.1.4 by Monty Taylor
Merged in InnoDB changes.
9119
	void*		session;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
9120
	ibool		file_id;
9121
9122
	const char*	expected;
9123
} innobase_convert_name_test_t;
9124
9125
void
9126
test_innobase_convert_name()
9127
{
9128
	char	buf[1024];
9129
	ulint	i;
9130
9131
	innobase_convert_name_test_t test_input[] = {
9132
		{buf, sizeof(buf), "abcd", 4, NULL, TRUE, "\"abcd\""},
9133
		{buf, 7, "abcd", 4, NULL, TRUE, "\"abcd\""},
9134
		{buf, 6, "abcd", 4, NULL, TRUE, "\"abcd\""},
9135
		{buf, 5, "abcd", 4, NULL, TRUE, "\"abc\""},
9136
		{buf, 4, "abcd", 4, NULL, TRUE, "\"ab\""},
9137
9138
		{buf, sizeof(buf), "ab@0060cd", 9, NULL, TRUE, "\"ab`cd\""},
9139
		{buf, 9, "ab@0060cd", 9, NULL, TRUE, "\"ab`cd\""},
9140
		{buf, 8, "ab@0060cd", 9, NULL, TRUE, "\"ab`cd\""},
9141
		{buf, 7, "ab@0060cd", 9, NULL, TRUE, "\"ab`cd\""},
9142
		{buf, 6, "ab@0060cd", 9, NULL, TRUE, "\"ab`c\""},
9143
		{buf, 5, "ab@0060cd", 9, NULL, TRUE, "\"ab`\""},
9144
		{buf, 4, "ab@0060cd", 9, NULL, TRUE, "\"ab\""},
9145
9146
		{buf, sizeof(buf), "ab\"cd", 5, NULL, TRUE,
9147
			"\"#mysql50#ab\"\"cd\""},
9148
		{buf, 17, "ab\"cd", 5, NULL, TRUE,
9149
			"\"#mysql50#ab\"\"cd\""},
9150
		{buf, 16, "ab\"cd", 5, NULL, TRUE,
9151
			"\"#mysql50#ab\"\"c\""},
9152
		{buf, 15, "ab\"cd", 5, NULL, TRUE,
9153
			"\"#mysql50#ab\"\"\""},
9154
		{buf, 14, "ab\"cd", 5, NULL, TRUE,
9155
			"\"#mysql50#ab\""},
9156
		{buf, 13, "ab\"cd", 5, NULL, TRUE,
9157
			"\"#mysql50#ab\""},
9158
		{buf, 12, "ab\"cd", 5, NULL, TRUE,
9159
			"\"#mysql50#a\""},
9160
		{buf, 11, "ab\"cd", 5, NULL, TRUE,
9161
			"\"#mysql50#\""},
9162
		{buf, 10, "ab\"cd", 5, NULL, TRUE,
9163
			"\"#mysql50\""},
9164
9165
		{buf, sizeof(buf), "ab/cd", 5, NULL, TRUE, "\"ab\".\"cd\""},
9166
		{buf, 9, "ab/cd", 5, NULL, TRUE, "\"ab\".\"cd\""},
9167
		{buf, 8, "ab/cd", 5, NULL, TRUE, "\"ab\".\"c\""},
9168
		{buf, 7, "ab/cd", 5, NULL, TRUE, "\"ab\".\"\""},
9169
		{buf, 6, "ab/cd", 5, NULL, TRUE, "\"ab\"."},
9170
		{buf, 5, "ab/cd", 5, NULL, TRUE, "\"ab\"."},
9171
		{buf, 4, "ab/cd", 5, NULL, TRUE, "\"ab\""},
9172
		{buf, 3, "ab/cd", 5, NULL, TRUE, "\"a\""},
9173
		{buf, 2, "ab/cd", 5, NULL, TRUE, "\"\""},
9174
		/* XXX probably "" is a better result in this case
9175
		{buf, 1, "ab/cd", 5, NULL, TRUE, "."},
9176
		*/
9177
		{buf, 0, "ab/cd", 5, NULL, TRUE, ""},
9178
	};
9179
9180
	for (i = 0; i < sizeof(test_input) / sizeof(test_input[0]); i++) {
9181
9182
		char*	end;
9183
		ibool	ok = TRUE;
9184
		size_t	res_len;
9185
9186
		fprintf(stderr, "TESTING %lu, %s, %lu, %s\n",
9187
			test_input[i].buflen,
9188
			test_input[i].id,
9189
			test_input[i].idlen,
9190
			test_input[i].expected);
9191
9192
		end = innobase_convert_name(
9193
			test_input[i].buf,
9194
			test_input[i].buflen,
9195
			test_input[i].id,
9196
			test_input[i].idlen,
641.1.4 by Monty Taylor
Merged in InnoDB changes.
9197
			test_input[i].session,
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
9198
			test_input[i].file_id);
9199
9200
		res_len = (size_t) (end - test_input[i].buf);
9201
9202
		if (res_len != strlen(test_input[i].expected)) {
9203
9204
			fprintf(stderr, "unexpected len of the result: %u, "
9205
				"expected: %u\n", (unsigned) res_len,
9206
				(unsigned) strlen(test_input[i].expected));
9207
			ok = FALSE;
9208
		}
9209
9210
		if (memcmp(test_input[i].buf,
9211
			   test_input[i].expected,
9212
			   strlen(test_input[i].expected)) != 0
9213
		    || !ok) {
9214
9215
			fprintf(stderr, "unexpected result: %.*s, "
9216
				"expected: %s\n", (int) res_len,
9217
				test_input[i].buf,
9218
				test_input[i].expected);
9219
			ok = FALSE;
9220
		}
9221
9222
		if (ok) {
9223
			fprintf(stderr, "OK: res: %.*s\n\n", (int) res_len,
9224
				buf);
9225
		} else {
9226
			fprintf(stderr, "FAILED\n\n");
9227
			return;
9228
		}
9229
	}
9230
}
9231
9232
#endif /* UNIV_COMPILE_TEST_FUNCS */