~drizzle-trunk/drizzle/development

1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 *
1999.6.1 by kalebral at gmail
update Copyright strings to a more common format to help with creating the master debian copyright file
4
 *  Copyright (C) 2008 Sun Microsystems, Inc.
5
 *  Copyright (C) 2010 Jay Pipes <jaypipes@gmail.com>
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
6
 *
7
 *  This program is free software; you can redistribute it and/or modify
8
 *  it under the terms of the GNU General Public License as published by
9
 *  the Free Software Foundation; version 2 of the License.
10
 *
11
 *  This program is distributed in the hope that it will be useful,
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *  GNU General Public License for more details.
15
 *
16
 *  You should have received a copy of the GNU General Public License
17
 *  along with this program; if not, write to the Free Software
18
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19
 */
20
21
/**
22
 * @file Transaction processing code
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
23
 *
24
 * @note
25
 *
26
 * The TransactionServices component takes internal events (for instance the start of a 
27
 * transaction, the changing of a record, or the rollback of a transaction) 
28
 * and constructs GPB Messages that are passed to the ReplicationServices
29
 * component and used during replication.
30
 *
31
 * The reason for this functionality is to encapsulate all communication
32
 * between the kernel and the replicator/applier plugins into GPB Messages.
33
 * Instead of the plugin having to understand the (often fluidly changing)
34
 * mechanics of the kernel, all the plugin needs to understand is the message
35
 * format, and GPB messages provide a nice, clear, and versioned format for 
36
 * these messages.
37
 *
38
 * @see /drizzled/message/transaction.proto
39
 *
40
 * @todo
41
 *
42
 * We really should store the raw bytes in the messages, not the
43
 * String value of the Field.  But, to do that, the
44
 * statement_transform library needs first to be updated
45
 * to include the transformation code to convert raw
46
 * Drizzle-internal Field byte representation into something
47
 * plugins can understand.
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
48
 */
49
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
50
#include <config.h>
2154.2.24 by Brian Aker
Merge in all changes for current_session, etc.
51
#include <drizzled/current_session.h>
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
52
#include <drizzled/error.h>
53
#include <drizzled/gettext.h>
54
#include <drizzled/probes.h>
55
#include <drizzled/sql_parse.h>
56
#include <drizzled/session.h>
2269.1.5 by Olaf van der Spek
Session Times
57
#include <drizzled/session/times.h>
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
58
#include <drizzled/sql_base.h>
59
#include <drizzled/replication_services.h>
60
#include <drizzled/transaction_services.h>
61
#include <drizzled/transaction_context.h>
62
#include <drizzled/message/transaction.pb.h>
63
#include <drizzled/message/statement_transform.h>
64
#include <drizzled/resource_context.h>
65
#include <drizzled/lock.h>
66
#include <drizzled/item/int.h>
67
#include <drizzled/item/empty_string.h>
68
#include <drizzled/field/epoch.h>
69
#include <drizzled/plugin/client.h>
70
#include <drizzled/plugin/monitored_in_transaction.h>
71
#include <drizzled/plugin/transactional_storage_engine.h>
72
#include <drizzled/plugin/xa_resource_manager.h>
73
#include <drizzled/plugin/xa_storage_engine.h>
74
#include <drizzled/internal/my_sys.h>
2241.3.1 by Olaf van der Spek
Refactor Session::status_var
75
#include <drizzled/statistics_variables.h>
2241.3.2 by Olaf van der Spek
Refactor Session::variables
76
#include <drizzled/system_variables.h>
2241.3.4 by Olaf van der Spek
Refactor Session::transaction
77
#include <drizzled/session/transactions.h>
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
78
1273.1.10 by Jay Pipes
* Renames Ha_trx_info to drizzled::ResourceContext
79
#include <vector>
80
#include <algorithm>
81
#include <functional>
1861.6.3 by David Shrewsbury
Move GPB manipulation code out of Session and into TransactionServices.
82
#include <google/protobuf/repeated_field.h>
83
84
using namespace std;
85
using namespace google;
1273.1.10 by Jay Pipes
* Renames Ha_trx_info to drizzled::ResourceContext
86
2241.3.1 by Olaf van der Spek
Refactor Session::status_var
87
namespace drizzled {
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
88
89
/**
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
90
 * @defgroup Transactions
91
 *
92
 * @brief
93
 *
94
 * Transaction handling in the server
95
 *
96
 * @detail
97
 *
98
 * In each client connection, Drizzle maintains two transaction
99
 * contexts representing the state of the:
100
 *
101
 * 1) Statement Transaction
102
 * 2) Normal Transaction
103
 *
104
 * These two transaction contexts represent the transactional
105
 * state of a Session's SQL and XA transactions for a single
106
 * SQL statement or a series of SQL statements.
107
 *
108
 * When the Session's connection is in AUTOCOMMIT mode, there
109
 * is no practical difference between the statement and the
110
 * normal transaction, as each SQL statement is committed or
111
 * rolled back depending on the success or failure of the
112
 * indvidual SQL statement.
113
 *
114
 * When the Session's connection is NOT in AUTOCOMMIT mode, OR
115
 * the Session has explicitly begun a normal SQL transaction using
116
 * a BEGIN WORK/START TRANSACTION statement, then the normal
117
 * transaction context tracks the aggregate transaction state of
118
 * the SQL transaction's individual statements, and the SQL
119
 * transaction's commit or rollback is done atomically for all of
120
 * the SQL transaction's statement's data changes.
121
 *
122
 * Technically, a statement transaction can be viewed as a savepoint 
123
 * which is maintained automatically in order to make effects of one
124
 * statement atomic.
125
 *
126
 * The normal transaction is started by the user and is typically
127
 * ended (COMMIT or ROLLBACK) upon an explicity user request as well.
128
 * The exception to this is that DDL statements implicitly COMMIT
129
 * any previously active normal transaction before they begin executing.
130
 *
131
 * In Drizzle, unlike MySQL, plugins other than a storage engine
132
 * may participate in a transaction.  All plugin::TransactionalStorageEngine
133
 * plugins will automatically be monitored by Drizzle's transaction 
134
 * manager (implemented in this source file), as will all plugins which
135
 * implement plugin::XaResourceManager and register with the transaction
136
 * manager.
137
 *
138
 * If Drizzle's transaction manager sees that more than one resource
139
 * manager (transactional storage engine or XA resource manager) has modified
140
 * data state during a statement or normal transaction, the transaction
141
 * manager will automatically use a two-phase commit protocol for all
142
 * resources which support XA's distributed transaction protocol.  Unlike
143
 * MySQL, storage engines need not manually register with the transaction
144
 * manager during a statement's execution.  Previously, in MySQL, all
145
 * handlertons would have to call trans_register_ha() at some point after
146
 * modifying data state in order to have MySQL include that handler in
147
 * an XA transaction.  Drizzle does all of this grunt work behind the
148
 * scenes for the storage engine implementers.
149
 *
150
 * When a connection is closed, the current normal transaction, if
151
 * any is currently active, is rolled back.
152
 *
153
 * Transaction life cycle
154
 * ----------------------
155
 *
156
 * When a new connection is established, session->transaction
157
 * members are initialized to an empty state. If a statement uses any tables, 
158
 * all affected engines are registered in the statement engine list automatically
159
 * in plugin::StorageEngine::startStatement() and 
160
 * plugin::TransactionalStorageEngine::startTransaction().
161
 *
162
 * You can view the lifetime of a normal transaction in the following
163
 * call-sequence:
164
 *
165
 * drizzled::statement::Statement::execute()
166
 *   drizzled::plugin::TransactionalStorageEngine::startTransaction()
167
 *     drizzled::TransactionServices::registerResourceForTransaction()
168
 *     drizzled::TransactionServices::registerResourceForStatement()
169
 *     drizzled::plugin::StorageEngine::startStatement()
170
 *       drizzled::Cursor::write_row() <-- example...could be update_row(), etc
171
 *     drizzled::plugin::StorageEngine::endStatement()
172
 *   drizzled::TransactionServices::autocommitOrRollback()
173
 *     drizzled::TransactionalStorageEngine::commit() <-- or ::rollback()
174
 *     drizzled::XaResourceManager::xaCommit() <-- or rollback()
175
 *
176
 * Roles and responsibilities
177
 * --------------------------
178
 *
179
 * Beginning of SQL Statement (and Statement Transaction)
180
 * ------------------------------------------------------
181
 *
182
 * At the start of each SQL statement, for each storage engine
183
 * <strong>that is involved in the SQL statement</strong>, the kernel 
184
 * calls the engine's plugin::StoragEngine::startStatement() method.  If the
185
 * engine needs to track some data for the statement, it should use
186
 * this method invocation to initialize this data.  This is the
187
 * beginning of what is called the "statement transaction".
188
 *
189
 * <strong>For transaction storage engines (those storage engines
190
 * that inherit from plugin::TransactionalStorageEngine)</strong>, the
191
 * kernel automatically determines if the start of the SQL statement 
192
 * transaction should <em>also</em> begin the normal SQL transaction.
193
 * This occurs when the connection is in NOT in autocommit mode. If
194
 * the kernel detects this, then the kernel automatically starts the
195
 * normal transaction w/ plugin::TransactionalStorageEngine::startTransaction()
196
 * method and then calls plugin::StorageEngine::startStatement()
197
 * afterwards.
198
 *
199
 * Beginning of an SQL "Normal" Transaction
200
 * ----------------------------------------
201
 *
202
 * As noted above, a "normal SQL transaction" may be started when
203
 * an SQL statement is started in a connection and the connection is
204
 * NOT in AUTOCOMMIT mode.  This is automatically done by the kernel.
205
 *
206
 * In addition, when a user executes a START TRANSACTION or
207
 * BEGIN WORK statement in a connection, the kernel explicitly
208
 * calls each transactional storage engine's startTransaction() method.
209
 *
210
 * Ending of an SQL Statement (and Statement Transaction)
211
 * ------------------------------------------------------
212
 *
213
 * At the end of each SQL statement, for each of the aforementioned
214
 * involved storage engines, the kernel calls the engine's
215
 * plugin::StorageEngine::endStatement() method.  If the engine
216
 * has initialized or modified some internal data about the
217
 * statement transaction, it should use this method to reset or destroy
218
 * this data appropriately.
219
 *
220
 * Ending of an SQL "Normal" Transaction
221
 * -------------------------------------
222
 *
223
 * The end of a normal transaction is either a ROLLBACK or a COMMIT, 
224
 * depending on the success or failure of the statement transaction(s) 
225
 * it encloses.
226
 *
227
 * The end of a "normal transaction" occurs when any of the following
228
 * occurs:
229
 *
230
 * 1) If a statement transaction has completed and AUTOCOMMIT is ON,
231
 *    then the normal transaction which encloses the statement
232
 *    transaction ends
233
 * 2) If a COMMIT or ROLLBACK statement occurs on the connection
234
 * 3) Just before a DDL operation occurs, the kernel will implicitly
235
 *    commit the active normal transaction
236
 *
237
 * Transactions and Non-transactional Storage Engines
238
 * --------------------------------------------------
239
 *
240
 * For non-transactional engines, this call can be safely ignored, an
241
 * the kernel tracks whether a non-transactional engine has changed
242
 * any data state, and warns the user appropriately if a transaction
243
 * (statement or normal) is rolled back after such non-transactional
244
 * data changes have been made.
245
 *
246
 * XA Two-phase Commit Protocol
247
 * ----------------------------
248
 *
249
 * During statement execution, whenever any of data-modifying
250
 * PSEA API methods is used, e.g. Cursor::write_row() or
251
 * Cursor::update_row(), the read-write flag is raised in the
252
 * statement transaction for the involved engine.
253
 * Currently All PSEA calls are "traced", and the data can not be
254
 * changed in a way other than issuing a PSEA call. Important:
255
 * unless this invariant is preserved the server will not know that
256
 * a transaction in a given engine is read-write and will not
257
 * involve the two-phase commit protocol!
258
 *
259
 * At the end of a statement, TransactionServices::autocommitOrRollback()
260
 * is invoked. This call in turn
261
 * invokes plugin::XaResourceManager::xapPepare() for every involved XA
262
 * resource manager.
263
 *
264
 * Prepare is followed by a call to plugin::TransactionalStorageEngine::commit()
265
 * or plugin::XaResourceManager::xaCommit() (depending on what the resource
266
 * is...)
267
 * 
268
 * If a one-phase commit will suffice, plugin::StorageEngine::prepare() is not
269
 * invoked and the server only calls plugin::StorageEngine::commit_one_phase().
270
 * At statement commit, the statement-related read-write engine
271
 * flag is propagated to the corresponding flag in the normal
272
 * transaction.  When the commit is complete, the list of registered
273
 * engines is cleared.
274
 *
275
 * Rollback is handled in a similar fashion.
276
 *
277
 * Additional notes on DDL and the normal transaction.
278
 * ---------------------------------------------------
279
 *
280
 * CREATE TABLE .. SELECT can start a *new* normal transaction
281
 * because of the fact that SELECTs on a transactional storage
282
 * engine participate in the normal SQL transaction (due to
283
 * isolation level issues and consistent read views).
284
 *
285
 * Behaviour of the server in this case is currently badly
286
 * defined.
287
 *
288
 * DDL statements use a form of "semantic" logging
289
 * to maintain atomicity: if CREATE TABLE .. SELECT failed,
290
 * the newly created table is deleted.
291
 * 
292
 * In addition, some DDL statements issue interim transaction
293
 * commits: e.g. ALTER TABLE issues a COMMIT after data is copied
294
 * from the original table to the internal temporary table. Other
295
 * statements, e.g. CREATE TABLE ... SELECT do not always commit
296
 * after itself.
297
 *
298
 * And finally there is a group of DDL statements such as
299
 * RENAME/DROP TABLE that doesn't start a new transaction
300
 * and doesn't commit.
301
 *
302
 * A consistent behaviour is perhaps to always commit the normal
303
 * transaction after all DDLs, just like the statement transaction
304
 * is always committed at the end of all statements.
305
 */
2318.6.60 by Olaf van der Spek
Refactor
306
2318.6.62 by Olaf van der Spek
Refactor
307
static plugin::XaStorageEngine& xa_storage_engine()
1856.2.6 by Joseph Daly
merge trunk
308
{
2318.6.62 by Olaf van der Spek
Refactor
309
  static plugin::XaStorageEngine& engine= static_cast<plugin::XaStorageEngine&>(*plugin::StorageEngine::findByName("InnoDB"));
310
  return engine;
1856.2.6 by Joseph Daly
merge trunk
311
}
312
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
313
void TransactionServices::registerResourceForStatement(Session& session,
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
314
                                                       plugin::MonitoredInTransaction *monitored,
1273.1.22 by Jay Pipes
Automates registration of statement transaction resources. No more need for storage engines to call TransactionServices::trans_register_ha(session, false, engine). yeah \o/
315
                                                       plugin::TransactionalStorageEngine *engine)
316
{
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
317
  if (session_test_options(&session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
1273.1.27 by Jay Pipes
Completes the work of removing the weirdness around transaction
318
  {
319
    /* 
320
     * Now we automatically register this resource manager for the
321
     * normal transaction.  This is fine because a statement
322
     * transaction registration should always enlist the resource
323
     * in the normal transaction which contains the statement
324
     * transaction.
325
     */
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
326
    registerResourceForTransaction(session, monitored, engine);
327
  }
328
2318.6.62 by Olaf van der Spek
Refactor
329
  TransactionContext& trans= session.transaction.stmt;
2241.2.9 by Olaf van der Spek
Refactor
330
  ResourceContext& resource_context= session.getResourceContext(*monitored, 0);
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
331
2241.2.8 by Olaf van der Spek
Refactor
332
  if (resource_context.isStarted())
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
333
    return; /* already registered, return */
334
335
  assert(monitored->participatesInSqlTransaction());
336
  assert(not monitored->participatesInXaTransaction());
337
2241.2.8 by Olaf van der Spek
Refactor
338
  resource_context.setMonitored(monitored);
339
  resource_context.setTransactionalStorageEngine(engine);
2318.6.62 by Olaf van der Spek
Refactor
340
  trans.registerResource(&resource_context);
341
  trans.no_2pc= true;
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
342
}
343
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
344
void TransactionServices::registerResourceForStatement(Session& session,
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
345
                                                       plugin::MonitoredInTransaction *monitored,
346
                                                       plugin::TransactionalStorageEngine *engine,
347
                                                       plugin::XaResourceManager *resource_manager)
348
{
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
349
  if (session_test_options(&session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
350
  {
351
    /* 
352
     * Now we automatically register this resource manager for the
353
     * normal transaction.  This is fine because a statement
354
     * transaction registration should always enlist the resource
355
     * in the normal transaction which contains the statement
356
     * transaction.
357
     */
358
    registerResourceForTransaction(session, monitored, engine, resource_manager);
359
  }
360
2318.6.62 by Olaf van der Spek
Refactor
361
  TransactionContext& trans= session.transaction.stmt;
2241.2.9 by Olaf van der Spek
Refactor
362
  ResourceContext& resource_context= session.getResourceContext(*monitored, 0);
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
363
2241.2.8 by Olaf van der Spek
Refactor
364
  if (resource_context.isStarted())
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
365
    return; /* already registered, return */
366
367
  assert(monitored->participatesInXaTransaction());
368
  assert(monitored->participatesInSqlTransaction());
369
2241.2.8 by Olaf van der Spek
Refactor
370
  resource_context.setMonitored(monitored);
371
  resource_context.setTransactionalStorageEngine(engine);
372
  resource_context.setXaResourceManager(resource_manager);
2318.6.62 by Olaf van der Spek
Refactor
373
  trans.registerResource(&resource_context);
1273.1.22 by Jay Pipes
Automates registration of statement transaction resources. No more need for storage engines to call TransactionServices::trans_register_ha(session, false, engine). yeah \o/
374
}
375
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
376
void TransactionServices::registerResourceForTransaction(Session& session,
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
377
                                                         plugin::MonitoredInTransaction *monitored,
1273.1.27 by Jay Pipes
Completes the work of removing the weirdness around transaction
378
                                                         plugin::TransactionalStorageEngine *engine)
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
379
{
2318.6.62 by Olaf van der Spek
Refactor
380
  TransactionContext& trans= session.transaction.all;
2241.2.9 by Olaf van der Spek
Refactor
381
  ResourceContext& resource_context= session.getResourceContext(*monitored, 1);
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
382
2241.2.9 by Olaf van der Spek
Refactor
383
  if (resource_context.isStarted())
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
384
    return; /* already registered, return */
385
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
386
  session.server_status|= SERVER_STATUS_IN_TRANS;
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
387
2318.6.62 by Olaf van der Spek
Refactor
388
  trans.registerResource(&resource_context);
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
389
390
  assert(monitored->participatesInSqlTransaction());
391
  assert(not monitored->participatesInXaTransaction());
392
2241.2.9 by Olaf van der Spek
Refactor
393
  resource_context.setMonitored(monitored);
394
  resource_context.setTransactionalStorageEngine(engine);
2318.6.62 by Olaf van der Spek
Refactor
395
  trans.no_2pc= true;
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
396
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
397
  if (session.transaction.xid_state.xid.is_null())
398
    session.transaction.xid_state.xid.set(session.getQueryId());
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
399
400
  /* Only true if user is executing a BEGIN WORK/START TRANSACTION */
2241.2.9 by Olaf van der Spek
Refactor
401
  if (not session.getResourceContext(*monitored, 0).isStarted())
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
402
    registerResourceForStatement(session, monitored, engine);
403
}
404
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
405
void TransactionServices::registerResourceForTransaction(Session& session,
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
406
                                                         plugin::MonitoredInTransaction *monitored,
407
                                                         plugin::TransactionalStorageEngine *engine,
408
                                                         plugin::XaResourceManager *resource_manager)
409
{
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
410
  TransactionContext *trans= &session.transaction.all;
2241.2.9 by Olaf van der Spek
Refactor
411
  ResourceContext& resource_context= session.getResourceContext(*monitored, 1);
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
412
2241.2.9 by Olaf van der Spek
Refactor
413
  if (resource_context.isStarted())
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
414
    return; /* already registered, return */
415
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
416
  session.server_status|= SERVER_STATUS_IN_TRANS;
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
417
2241.2.9 by Olaf van der Spek
Refactor
418
  trans->registerResource(&resource_context);
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
419
420
  assert(monitored->participatesInSqlTransaction());
421
2241.2.9 by Olaf van der Spek
Refactor
422
  resource_context.setMonitored(monitored);
423
  resource_context.setXaResourceManager(resource_manager);
424
  resource_context.setTransactionalStorageEngine(engine);
2297.1.1 by Olaf van der Spek
Fix weird bool assignments
425
  trans->no_2pc= true;
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
426
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
427
  if (session.transaction.xid_state.xid.is_null())
428
    session.transaction.xid_state.xid.set(session.getQueryId());
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
429
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
430
  engine->startTransaction(&session, START_TRANS_NO_OPTIONS);
1333.1.1 by Jay Pipes
Manually issue a call to TransactionStorageEngine::startTransaction() inside
431
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
432
  /* Only true if user is executing a BEGIN WORK/START TRANSACTION */
2241.2.9 by Olaf van der Spek
Refactor
433
  if (! session.getResourceContext(*monitored, 0).isStarted())
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
434
    registerResourceForStatement(session, monitored, engine, resource_manager);
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
435
}
436
1856.2.8 by Joseph Daly
working alter, drop, create schema
437
void TransactionServices::allocateNewTransactionId()
1856.2.7 by Joseph Daly
create schema changes
438
{
2318.6.73 by Olaf van der Spek
Refactor
439
  if (! ReplicationServices::isActive())
1856.2.8 by Joseph Daly
working alter, drop, create schema
440
  {
441
    return;
442
  }
443
444
  Session *my_session= current_session;
2318.6.62 by Olaf van der Spek
Refactor
445
  uint64_t xa_id= xa_storage_engine().getNewTransactionId(my_session);
1856.2.8 by Joseph Daly
working alter, drop, create schema
446
  my_session->setXaId(xa_id);
1856.2.7 by Joseph Daly
create schema changes
447
}
448
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
449
uint64_t TransactionServices::getCurrentTransactionId(Session& session)
1856.2.1 by Joseph Daly
use transaction_id in innodb for transaction log
450
{
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
451
  if (session.getXaId() == 0)
1856.2.1 by Joseph Daly
use transaction_id in innodb for transaction log
452
  {
2318.6.62 by Olaf van der Spek
Refactor
453
    session.setXaId(xa_storage_engine().getNewTransactionId(&session)); 
1856.2.1 by Joseph Daly
use transaction_id in innodb for transaction log
454
  }
1856.2.9 by Joseph Daly
zero out transaction id after its set in the GPB message
455
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
456
  return session.getXaId();
1856.2.1 by Joseph Daly
use transaction_id in innodb for transaction log
457
}
458
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
459
int TransactionServices::commitTransaction(Session& session,
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
460
                                           bool normal_transaction)
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
461
{
462
  int error= 0, cookie= 0;
463
  /*
464
    'all' means that this is either an explicit commit issued by
465
    user, or an implicit commit issued by a DDL.
466
  */
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
467
  TransactionContext *trans= normal_transaction ? &session.transaction.all : &session.transaction.stmt;
1273.1.10 by Jay Pipes
* Renames Ha_trx_info to drizzled::ResourceContext
468
  TransactionContext::ResourceContexts &resource_contexts= trans->getResourceContexts();
469
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
470
  bool is_real_trans= normal_transaction || session.transaction.all.getResourceContexts().empty();
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
471
472
  /*
473
    We must not commit the normal transaction if a statement
474
    transaction is pending. Otherwise statement transaction
475
    flags will not get propagated to its normal transaction's
476
    counterpart.
477
  */
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
478
  assert(session.transaction.stmt.getResourceContexts().empty() ||
479
              trans == &session.transaction.stmt);
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
480
1273.1.10 by Jay Pipes
* Renames Ha_trx_info to drizzled::ResourceContext
481
  if (resource_contexts.empty() == false)
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
482
  {
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
483
    if (is_real_trans && session.wait_if_global_read_lock(false, false))
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
484
    {
1405.3.5 by Jay Pipes
TransactionServices method names now meet code style guidelines.
485
      rollbackTransaction(session, normal_transaction);
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
486
      return 1;
487
    }
488
1405.3.6 by Jay Pipes
Here, we do two main things:
489
    /*
490
     * If replication is on, we do a PREPARE on the resource managers, push the
491
     * Transaction message across the replication stream, and then COMMIT if the
492
     * replication stream returned successfully.
493
     */
494
    if (shouldConstructMessages())
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
495
    {
2318.6.64 by Olaf van der Spek
Refactor
496
      BOOST_FOREACH(TransactionContext::ResourceContexts::reference resource_context, resource_contexts)
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
497
      {
2318.6.64 by Olaf van der Spek
Refactor
498
        if (error)
499
          break;
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
500
        /*
501
          Do not call two-phase commit if this particular
502
          transaction is read-only. This allows for simpler
503
          implementation in engines that are always read-only.
504
        */
1273.1.12 by Jay Pipes
Cleanup style and documentation for ResourceContext and setTransactionReadWrite
505
        if (! resource_context->hasModifiedData())
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
506
          continue;
1273.1.15 by Jay Pipes
This patch completes the first step in the splitting of
507
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
508
        plugin::MonitoredInTransaction *resource= resource_context->getMonitored();
509
510
        if (resource->participatesInXaTransaction())
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
511
        {
2318.6.64 by Olaf van der Spek
Refactor
512
          if (int err= resource_context->getXaResourceManager()->xaPrepare(&session, normal_transaction))
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
513
          {
514
            my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
515
            error= 1;
516
          }
517
          else
518
          {
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
519
            session.status_var.ha_prepare_count++;
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
520
          }
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
521
        }
522
      }
1405.3.6 by Jay Pipes
Here, we do two main things:
523
      if (error == 0 && is_real_trans)
524
      {
525
        /*
526
         * Push the constructed Transaction messages across to
527
         * replicators and appliers.
528
         */
529
        error= commitTransactionMessage(session);
530
      }
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
531
      if (error)
532
      {
1405.3.5 by Jay Pipes
TransactionServices method names now meet code style guidelines.
533
        rollbackTransaction(session, normal_transaction);
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
534
        error= 1;
535
        goto end;
536
      }
537
    }
1405.3.5 by Jay Pipes
TransactionServices method names now meet code style guidelines.
538
    error= commitPhaseOne(session, normal_transaction) ? (cookie ? 2 : 1) : 0;
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
539
end:
540
    if (is_real_trans)
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
541
      session.startWaitingGlobalReadLock();
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
542
  }
543
  return error;
544
}
545
546
/**
547
  @note
548
  This function does not care about global read lock. A caller should.
549
*/
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
550
int TransactionServices::commitPhaseOne(Session& session,
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
551
                                        bool normal_transaction)
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
552
{
553
  int error=0;
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
554
  TransactionContext *trans= normal_transaction ? &session.transaction.all : &session.transaction.stmt;
1273.1.10 by Jay Pipes
* Renames Ha_trx_info to drizzled::ResourceContext
555
  TransactionContext::ResourceContexts &resource_contexts= trans->getResourceContexts();
556
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
557
  bool is_real_trans= normal_transaction || session.transaction.all.getResourceContexts().empty();
2070.5.1 by Stewart Smith
make the all parameter in TransactionalStorageEngine::doCommit() not be a lie. In Transactionservices, work out if we're commiting the full transaction instead of each engine having to do session_test_options for autocommit/begin.
558
  bool all= normal_transaction;
559
560
  /* If we're in autocommit then we have a real transaction to commit
561
     (except if it's BEGIN)
562
  */
2096.2.3 by David Shrewsbury
Merge with trunk and fix conflicts
563
  if (! session_test_options(&session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
2070.5.1 by Stewart Smith
make the all parameter in TransactionalStorageEngine::doCommit() not be a lie. In Transactionservices, work out if we're commiting the full transaction instead of each engine having to do session_test_options for autocommit/begin.
564
    all= true;
1273.1.10 by Jay Pipes
* Renames Ha_trx_info to drizzled::ResourceContext
565
566
  if (resource_contexts.empty() == false)
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
567
  {
2318.6.64 by Olaf van der Spek
Refactor
568
    BOOST_FOREACH(TransactionContext::ResourceContexts::reference resource_context, resource_contexts)
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
569
    {
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
570
      plugin::MonitoredInTransaction *resource= resource_context->getMonitored();
571
572
      if (resource->participatesInXaTransaction())
573
      {
2318.6.64 by Olaf van der Spek
Refactor
574
        if (int err= resource_context->getXaResourceManager()->xaCommit(&session, all))
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
575
        {
576
          my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
577
          error= 1;
578
        }
1324.1.1 by Jay Pipes
Fixes Bug #535296 by only incrementing ha_commit_count when its a normal transaction commit.
579
        else if (normal_transaction)
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
580
        {
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
581
          session.status_var.ha_commit_count++;
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
582
        }
583
      }
584
      else if (resource->participatesInSqlTransaction())
585
      {
2318.6.64 by Olaf van der Spek
Refactor
586
        if (int err= resource_context->getTransactionalStorageEngine()->commit(&session, all))
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
587
        {
588
          my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
589
          error= 1;
590
        }
1324.1.1 by Jay Pipes
Fixes Bug #535296 by only incrementing ha_commit_count when its a normal transaction commit.
591
        else if (normal_transaction)
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
592
        {
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
593
          session.status_var.ha_commit_count++;
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
594
        }
595
      }
1273.1.10 by Jay Pipes
* Renames Ha_trx_info to drizzled::ResourceContext
596
      resource_context->reset(); /* keep it conveniently zero-filled */
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
597
    }
1273.1.10 by Jay Pipes
* Renames Ha_trx_info to drizzled::ResourceContext
598
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
599
    if (is_real_trans)
2281.4.7 by Olaf van der Spek
XID
600
      session.transaction.xid_state.xid.set_null();
1273.1.10 by Jay Pipes
* Renames Ha_trx_info to drizzled::ResourceContext
601
602
    if (normal_transaction)
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
603
    {
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
604
      session.variables.tx_isolation= session.session_tx_isolation;
605
      session.transaction.cleanup();
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
606
    }
607
  }
1273.1.27 by Jay Pipes
Completes the work of removing the weirdness around transaction
608
  trans->reset();
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
609
  return error;
610
}
611
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
612
int TransactionServices::rollbackTransaction(Session& session,
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
613
                                             bool normal_transaction)
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
614
{
1273.1.10 by Jay Pipes
* Renames Ha_trx_info to drizzled::ResourceContext
615
  int error= 0;
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
616
  TransactionContext *trans= normal_transaction ? &session.transaction.all : &session.transaction.stmt;
1273.1.10 by Jay Pipes
* Renames Ha_trx_info to drizzled::ResourceContext
617
  TransactionContext::ResourceContexts &resource_contexts= trans->getResourceContexts();
618
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
619
  bool is_real_trans= normal_transaction || session.transaction.all.getResourceContexts().empty();
2096.2.3 by David Shrewsbury
Merge with trunk and fix conflicts
620
  bool all = normal_transaction || !session_test_options(&session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN);
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
621
622
  /*
623
    We must not rollback the normal transaction if a statement
624
    transaction is pending.
625
  */
2318.6.64 by Olaf van der Spek
Refactor
626
  assert(session.transaction.stmt.getResourceContexts().empty() || trans == &session.transaction.stmt);
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
627
1273.1.10 by Jay Pipes
* Renames Ha_trx_info to drizzled::ResourceContext
628
  if (resource_contexts.empty() == false)
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
629
  {
2318.6.64 by Olaf van der Spek
Refactor
630
    BOOST_FOREACH(TransactionContext::ResourceContexts::reference resource_context, resource_contexts)
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
631
    {
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
632
      plugin::MonitoredInTransaction *resource= resource_context->getMonitored();
633
634
      if (resource->participatesInXaTransaction())
635
      {
2318.6.64 by Olaf van der Spek
Refactor
636
        if (int err= resource_context->getXaResourceManager()->xaRollback(&session, all))
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
637
        {
638
          my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err);
639
          error= 1;
640
        }
1324.1.1 by Jay Pipes
Fixes Bug #535296 by only incrementing ha_commit_count when its a normal transaction commit.
641
        else if (normal_transaction)
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
642
        {
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
643
          session.status_var.ha_rollback_count++;
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
644
        }
645
      }
646
      else if (resource->participatesInSqlTransaction())
647
      {
2318.6.64 by Olaf van der Spek
Refactor
648
        if (int err= resource_context->getTransactionalStorageEngine()->rollback(&session, all))
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
649
        {
650
          my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err);
651
          error= 1;
652
        }
1324.1.1 by Jay Pipes
Fixes Bug #535296 by only incrementing ha_commit_count when its a normal transaction commit.
653
        else if (normal_transaction)
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
654
        {
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
655
          session.status_var.ha_rollback_count++;
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
656
        }
657
      }
1273.1.10 by Jay Pipes
* Renames Ha_trx_info to drizzled::ResourceContext
658
      resource_context->reset(); /* keep it conveniently zero-filled */
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
659
    }
660
    
661
    /* 
662
     * We need to signal the ROLLBACK to ReplicationServices here
663
     * BEFORE we set the transaction ID to NULL.  This is because
664
     * if a bulk segment was sent to replicators, we need to send
665
     * a rollback statement with the corresponding transaction ID
666
     * to rollback.
667
     */
2070.6.1 by Stewart Smith
make the all parameter in TransactionalStorageEngine::doRollback() not be a lie. In Transactionservices, work out if we're commiting the full transaction instead of each engine having to do session_test_options for rollback.
668
    if (all)
1796.3.1 by David Shrewsbury
Fix for accidentally deleting all GPB Transaction message contents recorded before a single failing statement contained within the transaction.
669
      rollbackTransactionMessage(session);
1976.8.1 by David Shrewsbury
Add ability to rollback a statement, change to use 1 GPB Statement message per SQL statement. NOTE: segmented statements not handled yet.
670
    else
671
      rollbackStatementMessage(session);
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
672
673
    if (is_real_trans)
2281.4.7 by Olaf van der Spek
XID
674
      session.transaction.xid_state.xid.set_null();
1273.1.10 by Jay Pipes
* Renames Ha_trx_info to drizzled::ResourceContext
675
    if (normal_transaction)
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
676
    {
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
677
      session.variables.tx_isolation=session.session_tx_isolation;
678
      session.transaction.cleanup();
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
679
    }
680
  }
1273.1.10 by Jay Pipes
* Renames Ha_trx_info to drizzled::ResourceContext
681
  if (normal_transaction)
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
682
    session.transaction_rollback_request= false;
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
683
684
  /*
1273.1.27 by Jay Pipes
Completes the work of removing the weirdness around transaction
685
   * If a non-transactional table was updated, warn the user
686
   */
1273.1.10 by Jay Pipes
* Renames Ha_trx_info to drizzled::ResourceContext
687
  if (is_real_trans &&
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
688
      session.transaction.all.hasModifiedNonTransData() &&
689
      session.getKilled() != Session::KILL_CONNECTION)
1273.1.10 by Jay Pipes
* Renames Ha_trx_info to drizzled::ResourceContext
690
  {
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
691
    push_warning(&session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
692
                 ER_WARNING_NOT_COMPLETE_ROLLBACK,
693
                 ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
1273.1.10 by Jay Pipes
* Renames Ha_trx_info to drizzled::ResourceContext
694
  }
1273.1.27 by Jay Pipes
Completes the work of removing the weirdness around transaction
695
  trans->reset();
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
696
  return error;
697
}
698
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
699
int TransactionServices::autocommitOrRollback(Session& session,
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
700
                                              int error)
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
701
{
1976.8.1 by David Shrewsbury
Add ability to rollback a statement, change to use 1 GPB Statement message per SQL statement. NOTE: segmented statements not handled yet.
702
  /* One GPB Statement message per SQL statement */
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
703
  message::Statement *statement= session.getStatementMessage();
1976.8.1 by David Shrewsbury
Add ability to rollback a statement, change to use 1 GPB Statement message per SQL statement. NOTE: segmented statements not handled yet.
704
  if ((statement != NULL) && (! error))
705
    finalizeStatementMessage(*statement, session);
1860.2.9 by Stewart Smith
endStatement() not being called at end of statement, breaking READ COMMITTED isolation level in innobase plugin
706
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
707
  if (session.transaction.stmt.getResourceContexts().empty() == false)
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
708
  {
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
709
    TransactionContext *trans = &session.transaction.stmt;
1860.2.9 by Stewart Smith
endStatement() not being called at end of statement, breaking READ COMMITTED isolation level in innobase plugin
710
    TransactionContext::ResourceContexts &resource_contexts= trans->getResourceContexts();
2318.6.64 by Olaf van der Spek
Refactor
711
    BOOST_FOREACH(TransactionContext::ResourceContexts::reference resource_context, resource_contexts)
1860.2.9 by Stewart Smith
endStatement() not being called at end of statement, breaking READ COMMITTED isolation level in innobase plugin
712
    {
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
713
      resource_context->getTransactionalStorageEngine()->endStatement(&session);
1860.2.9 by Stewart Smith
endStatement() not being called at end of statement, breaking READ COMMITTED isolation level in innobase plugin
714
    }
715
1273.1.10 by Jay Pipes
* Renames Ha_trx_info to drizzled::ResourceContext
716
    if (! error)
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
717
    {
1405.3.5 by Jay Pipes
TransactionServices method names now meet code style guidelines.
718
      if (commitTransaction(session, false))
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
719
        error= 1;
720
    }
721
    else
722
    {
1405.3.5 by Jay Pipes
TransactionServices method names now meet code style guidelines.
723
      (void) rollbackTransaction(session, false);
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
724
      if (session.transaction_rollback_request)
2140.2.5 by Stewart Smith
fix SERVER_STATUS_IN_TRANS for rollback in autocommitOrRollback
725
      {
1405.3.5 by Jay Pipes
TransactionServices method names now meet code style guidelines.
726
        (void) rollbackTransaction(session, true);
2140.2.5 by Stewart Smith
fix SERVER_STATUS_IN_TRANS for rollback in autocommitOrRollback
727
        session.server_status&= ~SERVER_STATUS_IN_TRANS;
728
      }
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
729
    }
730
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
731
    session.variables.tx_isolation= session.session_tx_isolation;
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
732
  }
2140.2.5 by Stewart Smith
fix SERVER_STATUS_IN_TRANS for rollback in autocommitOrRollback
733
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
734
  return error;
735
}
736
1273.1.10 by Jay Pipes
* Renames Ha_trx_info to drizzled::ResourceContext
737
struct ResourceContextCompare : public std::binary_function<ResourceContext *, ResourceContext *, bool>
738
{
739
  result_type operator()(const ResourceContext *lhs, const ResourceContext *rhs) const
740
  {
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
741
    /* The below is perfectly fine, since we're simply comparing addresses for the underlying
742
     * resources aren't the same... */
743
    return reinterpret_cast<uint64_t>(lhs->getMonitored()) < reinterpret_cast<uint64_t>(rhs->getMonitored());
1273.1.10 by Jay Pipes
* Renames Ha_trx_info to drizzled::ResourceContext
744
  }
745
};
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
746
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
747
int TransactionServices::rollbackToSavepoint(Session& session,
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
748
                                             NamedSavepoint &sv)
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
749
{
750
  int error= 0;
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
751
  TransactionContext *trans= &session.transaction.all;
1273.1.10 by Jay Pipes
* Renames Ha_trx_info to drizzled::ResourceContext
752
  TransactionContext::ResourceContexts &tran_resource_contexts= trans->getResourceContexts();
753
  TransactionContext::ResourceContexts &sv_resource_contexts= sv.getResourceContexts();
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
754
1273.1.10 by Jay Pipes
* Renames Ha_trx_info to drizzled::ResourceContext
755
  trans->no_2pc= false;
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
756
  /*
757
    rolling back to savepoint in all storage engines that were part of the
758
    transaction when the savepoint was set
759
  */
2318.6.64 by Olaf van der Spek
Refactor
760
  BOOST_FOREACH(TransactionContext::ResourceContexts::reference resource_context, sv_resource_contexts)
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
761
  {
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
762
    plugin::MonitoredInTransaction *resource= resource_context->getMonitored();
763
764
    if (resource->participatesInSqlTransaction())
765
    {
2318.6.64 by Olaf van der Spek
Refactor
766
      if (int err= resource_context->getTransactionalStorageEngine()->rollbackToSavepoint(&session, sv))
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
767
      {
768
        my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err);
769
        error= 1;
770
      }
771
      else
772
      {
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
773
        session.status_var.ha_savepoint_rollback_count++;
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
774
      }
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
775
    }
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
776
    trans->no_2pc|= not resource->participatesInXaTransaction();
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
777
  }
778
  /*
779
    rolling back the transaction in all storage engines that were not part of
780
    the transaction when the savepoint was set
781
  */
782
  {
1273.1.10 by Jay Pipes
* Renames Ha_trx_info to drizzled::ResourceContext
783
    TransactionContext::ResourceContexts sorted_tran_resource_contexts(tran_resource_contexts);
784
    TransactionContext::ResourceContexts sorted_sv_resource_contexts(sv_resource_contexts);
785
    TransactionContext::ResourceContexts set_difference_contexts;
786
1491.2.3 by Jay Pipes
Fix for Bug #542299. The cause of the segfault was no pre-allocation of the target vector in set_difference(). Depending on STL implementations, set_difference() calls the STL's copy(), which requires pre-allocation of all targets and destinations. This meant the default constructor for set_difference_contexts was not adequate, and we should call vector<>::reserve() to allocate enough memory for pointers to the target elements.
787
    /* 
788
     * Bug #542299: segfault during set_difference() below.  copy<>() requires pre-allocation
789
     * of all elements, including the target, which is why we pre-allocate the set_difference_contexts
790
     * here
791
     */
792
    set_difference_contexts.reserve(max(tran_resource_contexts.size(), sv_resource_contexts.size()));
793
1273.1.10 by Jay Pipes
* Renames Ha_trx_info to drizzled::ResourceContext
794
    sort(sorted_tran_resource_contexts.begin(),
795
         sorted_tran_resource_contexts.end(),
796
         ResourceContextCompare());
797
    sort(sorted_sv_resource_contexts.begin(),
798
         sorted_sv_resource_contexts.end(),
799
         ResourceContextCompare());
800
    set_difference(sorted_tran_resource_contexts.begin(),
801
                   sorted_tran_resource_contexts.end(),
802
                   sorted_sv_resource_contexts.begin(),
803
                   sorted_sv_resource_contexts.end(),
804
                   set_difference_contexts.begin(),
805
                   ResourceContextCompare());
806
    /* 
807
     * set_difference_contexts now contains all resource contexts
808
     * which are in the transaction context but were NOT in the
809
     * savepoint's resource contexts.
810
     */
811
        
2318.6.64 by Olaf van der Spek
Refactor
812
    BOOST_FOREACH(TransactionContext::ResourceContexts::reference resource_context, set_difference_contexts)
1273.1.10 by Jay Pipes
* Renames Ha_trx_info to drizzled::ResourceContext
813
    {
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
814
      plugin::MonitoredInTransaction *resource= resource_context->getMonitored();
815
816
      if (resource->participatesInSqlTransaction())
817
      {
2318.6.64 by Olaf van der Spek
Refactor
818
        if (int err= resource_context->getTransactionalStorageEngine()->rollback(&session, true))
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
819
        {
820
          my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err);
821
          error= 1;
822
        }
823
        else
824
        {
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
825
          session.status_var.ha_rollback_count++;
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
826
        }
1273.1.10 by Jay Pipes
* Renames Ha_trx_info to drizzled::ResourceContext
827
      }
828
      resource_context->reset(); /* keep it conveniently zero-filled */
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
829
    }
830
  }
1273.1.10 by Jay Pipes
* Renames Ha_trx_info to drizzled::ResourceContext
831
  trans->setResourceContexts(sv_resource_contexts);
1746.7.1 by Joseph Daly
handle rollback to savepoint properly 600032
832
1746.7.4 by Joseph Daly
add test, and use shouldConstructMessages() rather then calling the singleton each time
833
  if (shouldConstructMessages())
1746.7.1 by Joseph Daly
handle rollback to savepoint properly 600032
834
  {
835
    cleanupTransactionMessage(getActiveTransactionMessage(session), session);
1762.2.1 by Joseph Daly
fix up bugs 638518, and memory leak problems
836
    message::Transaction *savepoint_transaction= sv.getTransactionMessage();
837
    if (savepoint_transaction != NULL)
1746.7.1 by Joseph Daly
handle rollback to savepoint properly 600032
838
    {
1762.2.5 by Joseph Daly
add descriptive comments and use savepoint_transaction_copy to determine statement size
839
      /* Make a copy of the savepoint transaction, this is necessary to assure proper cleanup. 
840
         Upon commit the savepoint_transaction_copy will be cleaned up by a call to 
841
         cleanupTransactionMessage(). The Transaction message in NamedSavepoint will be cleaned
842
         up when the savepoint is cleaned up. This avoids calling delete twice on the Transaction.
843
      */ 
1762.2.1 by Joseph Daly
fix up bugs 638518, and memory leak problems
844
      message::Transaction *savepoint_transaction_copy= new message::Transaction(*sv.getTransactionMessage());
1762.2.5 by Joseph Daly
add descriptive comments and use savepoint_transaction_copy to determine statement size
845
      uint32_t num_statements = savepoint_transaction_copy->statement_size();
1762.2.1 by Joseph Daly
fix up bugs 638518, and memory leak problems
846
      if (num_statements == 0)
847
      {    
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
848
        session.setStatementMessage(NULL);
1762.2.1 by Joseph Daly
fix up bugs 638518, and memory leak problems
849
      }    
850
      else 
1746.7.1 by Joseph Daly
handle rollback to savepoint properly 600032
851
      {
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
852
        session.setStatementMessage(savepoint_transaction_copy->mutable_statement(num_statements - 1));    
1762.2.1 by Joseph Daly
fix up bugs 638518, and memory leak problems
853
      }    
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
854
      session.setTransactionMessage(savepoint_transaction_copy);
1746.7.1 by Joseph Daly
handle rollback to savepoint properly 600032
855
    }
856
  }
1762.2.1 by Joseph Daly
fix up bugs 638518, and memory leak problems
857
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
858
  return error;
859
}
860
861
/**
862
  @note
863
  according to the sql standard (ISO/IEC 9075-2:2003)
864
  section "4.33.4 SQL-statements and transaction states",
1273.1.4 by Jay Pipes
This patch significantly reworks the way that
865
  NamedSavepoint is *not* transaction-initiating SQL-statement
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
866
*/
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
867
int TransactionServices::setSavepoint(Session& session,
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
868
                                      NamedSavepoint &sv)
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
869
{
870
  int error= 0;
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
871
  TransactionContext *trans= &session.transaction.all;
1273.1.10 by Jay Pipes
* Renames Ha_trx_info to drizzled::ResourceContext
872
  TransactionContext::ResourceContexts &resource_contexts= trans->getResourceContexts();
873
874
  if (resource_contexts.empty() == false)
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
875
  {
2318.6.64 by Olaf van der Spek
Refactor
876
    BOOST_FOREACH(TransactionContext::ResourceContexts::reference resource_context, resource_contexts)
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
877
    {
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
878
      plugin::MonitoredInTransaction *resource= resource_context->getMonitored();
879
880
      if (resource->participatesInSqlTransaction())
881
      {
2318.6.64 by Olaf van der Spek
Refactor
882
        if (int err= resource_context->getTransactionalStorageEngine()->setSavepoint(&session, sv))
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
883
        {
884
          my_error(ER_GET_ERRNO, MYF(0), err);
885
          error= 1;
886
        }
887
        else
888
        {
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
889
          session.status_var.ha_savepoint_count++;
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
890
        }
1273.1.10 by Jay Pipes
* Renames Ha_trx_info to drizzled::ResourceContext
891
      }
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
892
    }
893
  }
894
  /*
1273.1.10 by Jay Pipes
* Renames Ha_trx_info to drizzled::ResourceContext
895
    Remember the list of registered storage engines.
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
896
  */
1273.1.10 by Jay Pipes
* Renames Ha_trx_info to drizzled::ResourceContext
897
  sv.setResourceContexts(resource_contexts);
1746.7.1 by Joseph Daly
handle rollback to savepoint properly 600032
898
1746.7.4 by Joseph Daly
add test, and use shouldConstructMessages() rather then calling the singleton each time
899
  if (shouldConstructMessages())
1746.7.1 by Joseph Daly
handle rollback to savepoint properly 600032
900
  {
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
901
    message::Transaction *transaction= session.getTransactionMessage();
1746.7.5 by Joseph Daly
fix to get tests working with release savepoint
902
                  
903
    if (transaction != NULL)
904
    {
905
      message::Transaction *transaction_savepoint= 
906
        new message::Transaction(*transaction);
1762.2.1 by Joseph Daly
fix up bugs 638518, and memory leak problems
907
      sv.setTransactionMessage(transaction_savepoint);
1746.7.5 by Joseph Daly
fix to get tests working with release savepoint
908
    }
1746.7.1 by Joseph Daly
handle rollback to savepoint properly 600032
909
  } 
910
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
911
  return error;
912
}
913
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
914
int TransactionServices::releaseSavepoint(Session& session,
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
915
                                          NamedSavepoint &sv)
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
916
{
917
  int error= 0;
1273.1.10 by Jay Pipes
* Renames Ha_trx_info to drizzled::ResourceContext
918
919
  TransactionContext::ResourceContexts &resource_contexts= sv.getResourceContexts();
920
2318.6.64 by Olaf van der Spek
Refactor
921
  BOOST_FOREACH(TransactionContext::ResourceContexts::reference resource_context, resource_contexts)
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
922
  {
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
923
    plugin::MonitoredInTransaction *resource= resource_context->getMonitored();
924
925
    if (resource->participatesInSqlTransaction())
926
    {
2318.6.64 by Olaf van der Spek
Refactor
927
      if (int err= resource_context->getTransactionalStorageEngine()->releaseSavepoint(&session, sv))
1273.1.30 by Jay Pipes
* Completes the blueprint for splitting the XA Resource Manager
928
      {
929
        my_error(ER_GET_ERRNO, MYF(0), err);
930
        error= 1;
931
      }
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
932
    }
933
  }
1746.7.4 by Joseph Daly
add test, and use shouldConstructMessages() rather then calling the singleton each time
934
  
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
935
  return error;
936
}
937
1405.4.10 by Jay Pipes
OK, Sun Studio still didn't like that...seems to think that inline means something different than other compilers think it is...
938
bool TransactionServices::shouldConstructMessages()
939
{
2318.6.73 by Olaf van der Spek
Refactor
940
  return ReplicationServices::isActive();
1405.4.10 by Jay Pipes
OK, Sun Studio still didn't like that...seems to think that inline means something different than other compilers think it is...
941
}
942
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
943
message::Transaction *TransactionServices::getActiveTransactionMessage(Session& session,
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
944
                                                                       bool should_inc_trx_id)
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
945
{
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
946
  message::Transaction *transaction= session.getTransactionMessage();
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
947
948
  if (unlikely(transaction == NULL))
949
  {
950
    /* 
951
     * Allocate and initialize a new transaction message 
952
     * for this Session object.  Session is responsible for
953
     * deleting transaction message when done with it.
954
     */
2246.3.1 by Olaf van der Spek
Remove std::nothrow from new()
955
    transaction= new message::Transaction();
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
956
    initTransactionMessage(*transaction, session, should_inc_trx_id);
957
    session.setTransactionMessage(transaction);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
958
  }
2246.3.1 by Olaf van der Spek
Remove std::nothrow from new()
959
  return transaction;
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
960
}
961
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
962
void TransactionServices::initTransactionMessage(message::Transaction &transaction,
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
963
                                                 Session& session,
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
964
                                                 bool should_inc_trx_id)
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
965
{
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
966
  message::TransactionContext *trx= transaction.mutable_transaction_context();
967
  trx->set_server_id(session.getServerId());
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
968
969
  if (should_inc_trx_id)
1856.2.9 by Joseph Daly
zero out transaction id after its set in the GPB message
970
  {
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
971
    trx->set_transaction_id(getCurrentTransactionId(session));
972
    session.setXaId(0);
2069.3.1 by David Shrewsbury
Add segment info to Transaction message and re-record tests.
973
  }
1856.2.9 by Joseph Daly
zero out transaction id after its set in the GPB message
974
  else
2069.3.1 by David Shrewsbury
Add segment info to Transaction message and re-record tests.
975
  {
976
    /* trx and seg id will get set properly elsewhere */
1856.2.7 by Joseph Daly
create schema changes
977
    trx->set_transaction_id(0);
1856.2.9 by Joseph Daly
zero out transaction id after its set in the GPB message
978
  }
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
979
2269.1.5 by Olaf van der Spek
Session Times
980
  trx->set_start_timestamp(session.times.getCurrentTimestamp());
2069.3.1 by David Shrewsbury
Add segment info to Transaction message and re-record tests.
981
  
982
  /* segment info may get set elsewhere as needed */
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
983
  transaction.set_segment_id(1);
984
  transaction.set_end_segment(true);
985
}
986
987
void TransactionServices::finalizeTransactionMessage(message::Transaction &transaction,
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
988
                                                     const Session& session)
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
989
{
990
  message::TransactionContext *trx= transaction.mutable_transaction_context();
2269.1.5 by Olaf van der Spek
Session Times
991
  trx->set_end_timestamp(session.times.getCurrentTimestamp());
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
992
}
993
994
void TransactionServices::cleanupTransactionMessage(message::Transaction *transaction,
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
995
                                                    Session& session)
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
996
{
997
  delete transaction;
998
  session.setStatementMessage(NULL);
999
  session.setTransactionMessage(NULL);
1000
  session.setXaId(0);
1001
}
1002
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
1003
int TransactionServices::commitTransactionMessage(Session& session)
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1004
{
2318.6.73 by Olaf van der Spek
Refactor
1005
  if (! ReplicationServices::isActive())
1405.3.6 by Jay Pipes
Here, we do two main things:
1006
    return 0;
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1007
1976.8.1 by David Shrewsbury
Add ability to rollback a statement, change to use 1 GPB Statement message per SQL statement. NOTE: segmented statements not handled yet.
1008
  /*
1009
   * If no Transaction message was ever created, then no data modification
1010
   * occurred inside the transaction, so nothing to do.
1011
   */
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1012
  if (session.getTransactionMessage() == NULL)
1976.8.1 by David Shrewsbury
Add ability to rollback a statement, change to use 1 GPB Statement message per SQL statement. NOTE: segmented statements not handled yet.
1013
    return 0;
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1014
  
1976.8.2 by David Shrewsbury
Support rollback of segmented statements ; removed unnecessary code for --replicate-query (didn't work correctly anyway).
1015
  /* If there is an active statement message, finalize it. */
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1016
  message::Statement *statement= session.getStatementMessage();
1976.8.2 by David Shrewsbury
Support rollback of segmented statements ; removed unnecessary code for --replicate-query (didn't work correctly anyway).
1017
1018
  if (statement != NULL)
1019
  {
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1020
    finalizeStatementMessage(*statement, session);
1976.8.2 by David Shrewsbury
Support rollback of segmented statements ; removed unnecessary code for --replicate-query (didn't work correctly anyway).
1021
  }
1022
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1023
  message::Transaction* transaction= getActiveTransactionMessage(session);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1024
1976.8.2 by David Shrewsbury
Support rollback of segmented statements ; removed unnecessary code for --replicate-query (didn't work correctly anyway).
1025
  /*
1026
   * It is possible that we could have a Transaction without any Statements
1027
   * if we had created a Statement but had to roll it back due to it failing
1028
   * mid-execution, and no subsequent Statements were added to the Transaction
1029
   * message. In this case, we simply clean up the message and not push it.
1030
   */
1031
  if (transaction->statement_size() == 0)
1032
  {
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1033
    cleanupTransactionMessage(transaction, session);
1976.8.2 by David Shrewsbury
Support rollback of segmented statements ; removed unnecessary code for --replicate-query (didn't work correctly anyway).
1034
    return 0;
1035
  }
1036
  
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1037
  finalizeTransactionMessage(*transaction, session);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1038
  
2318.6.73 by Olaf van der Spek
Refactor
1039
  plugin::ReplicationReturnCode result= ReplicationServices::pushTransactionMessage(session, *transaction);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1040
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1041
  cleanupTransactionMessage(transaction, session);
1405.3.6 by Jay Pipes
Here, we do two main things:
1042
1043
  return static_cast<int>(result);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1044
}
1045
1046
void TransactionServices::initStatementMessage(message::Statement &statement,
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1047
                                               message::Statement::Type type,
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
1048
                                               const Session& session)
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1049
{
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1050
  statement.set_type(type);
2269.1.5 by Olaf van der Spek
Session Times
1051
  statement.set_start_timestamp(session.times.getCurrentTimestamp());
1938.3.1 by David Shrewsbury
Add --replicate-query option.
1052
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1053
  if (session.variables.replicate_query)
1054
    statement.set_sql(session.getQueryString()->c_str());
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1055
}
1056
1057
void TransactionServices::finalizeStatementMessage(message::Statement &statement,
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
1058
                                                   Session& session)
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1059
{
2269.1.5 by Olaf van der Spek
Session Times
1060
  statement.set_end_timestamp(session.times.getCurrentTimestamp());
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1061
  session.setStatementMessage(NULL);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1062
}
1063
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
1064
void TransactionServices::rollbackTransactionMessage(Session& session)
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1065
{
2318.6.73 by Olaf van der Spek
Refactor
1066
  if (! ReplicationServices::isActive())
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1067
    return;
1068
  
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1069
  message::Transaction *transaction= getActiveTransactionMessage(session);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1070
1071
  /*
1072
   * OK, so there are two situations that we need to deal with here:
1073
   *
1074
   * 1) We receive an instruction to ROLLBACK the current transaction
1075
   *    and the currently-stored Transaction message is *self-contained*, 
1076
   *    meaning that no Statement messages in the Transaction message
1077
   *    contain a message having its segment_id member greater than 1.  If
1078
   *    no non-segment ID 1 members are found, we can simply clear the
1079
   *    current Transaction message and remove it from memory.
1080
   *
1081
   * 2) If the Transaction message does indeed have a non-end segment, that
1082
   *    means that a bulk update/delete/insert Transaction message segment
1083
   *    has previously been sent over the wire to replicators.  In this case, 
1084
   *    we need to package a Transaction with a Statement message of type
1085
   *    ROLLBACK to indicate to replicators that previously-transmitted
1086
   *    messages must be un-applied.
1087
   */
1088
  if (unlikely(message::transactionContainsBulkSegment(*transaction)))
1089
  {
1780.1.1 by David Shrewsbury
Set transaction ID properly on large, multi-Transaction message transactions. Also add bulk load tests.
1090
    /* Remember the transaction ID so we can re-use it */
1091
    uint64_t trx_id= transaction->transaction_context().transaction_id();
2069.3.1 by David Shrewsbury
Add segment info to Transaction message and re-record tests.
1092
    uint32_t seg_id= transaction->segment_id();
1780.1.1 by David Shrewsbury
Set transaction ID properly on large, multi-Transaction message transactions. Also add bulk load tests.
1093
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1094
    /*
1095
     * Clear the transaction, create a Rollback statement message, 
1096
     * attach it to the transaction, and push it to replicators.
1097
     */
1098
    transaction->Clear();
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1099
    initTransactionMessage(*transaction, session, false);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1100
1780.1.1 by David Shrewsbury
Set transaction ID properly on large, multi-Transaction message transactions. Also add bulk load tests.
1101
    /* Set the transaction ID to match the previous messages */
1102
    transaction->mutable_transaction_context()->set_transaction_id(trx_id);
2069.3.1 by David Shrewsbury
Add segment info to Transaction message and re-record tests.
1103
    transaction->set_segment_id(seg_id);
1104
    transaction->set_end_segment(true);
1780.1.1 by David Shrewsbury
Set transaction ID properly on large, multi-Transaction message transactions. Also add bulk load tests.
1105
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1106
    message::Statement *statement= transaction->add_statement();
1107
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1108
    initStatementMessage(*statement, message::Statement::ROLLBACK, session);
1109
    finalizeStatementMessage(*statement, session);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1110
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1111
    finalizeTransactionMessage(*transaction, session);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1112
    
2318.6.73 by Olaf van der Spek
Refactor
1113
    (void) ReplicationServices::pushTransactionMessage(session, *transaction);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1114
  }
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1115
1116
  cleanupTransactionMessage(transaction, session);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1117
}
1118
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
1119
void TransactionServices::rollbackStatementMessage(Session& session)
1976.8.1 by David Shrewsbury
Add ability to rollback a statement, change to use 1 GPB Statement message per SQL statement. NOTE: segmented statements not handled yet.
1120
{
2318.6.73 by Olaf van der Spek
Refactor
1121
  if (! ReplicationServices::isActive())
1976.8.1 by David Shrewsbury
Add ability to rollback a statement, change to use 1 GPB Statement message per SQL statement. NOTE: segmented statements not handled yet.
1122
    return;
1123
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1124
  message::Statement *current_statement= session.getStatementMessage();
1976.8.2 by David Shrewsbury
Support rollback of segmented statements ; removed unnecessary code for --replicate-query (didn't work correctly anyway).
1125
1976.8.1 by David Shrewsbury
Add ability to rollback a statement, change to use 1 GPB Statement message per SQL statement. NOTE: segmented statements not handled yet.
1126
  /* If we never added a Statement message, nothing to undo. */
1976.8.2 by David Shrewsbury
Support rollback of segmented statements ; removed unnecessary code for --replicate-query (didn't work correctly anyway).
1127
  if (current_statement == NULL)
1976.8.1 by David Shrewsbury
Add ability to rollback a statement, change to use 1 GPB Statement message per SQL statement. NOTE: segmented statements not handled yet.
1128
    return;
1129
1976.8.2 by David Shrewsbury
Support rollback of segmented statements ; removed unnecessary code for --replicate-query (didn't work correctly anyway).
1130
  /*
1131
   * If the Statement has been segmented, then we've already pushed a portion
1132
   * of this Statement's row changes through the replication stream and we
1133
   * need to send a ROLLBACK_STATEMENT message. Otherwise, we can simply
1134
   * delete the current Statement message.
1135
   */
1136
  bool is_segmented= false;
1137
1138
  switch (current_statement->type())
1139
  {
1140
    case message::Statement::INSERT:
1141
      if (current_statement->insert_data().segment_id() > 1)
1142
        is_segmented= true;
1143
      break;
1144
1145
    case message::Statement::UPDATE:
1146
      if (current_statement->update_data().segment_id() > 1)
1147
        is_segmented= true;
1148
      break;
1149
1150
    case message::Statement::DELETE:
1151
      if (current_statement->delete_data().segment_id() > 1)
1152
        is_segmented= true;
1153
      break;
1154
1155
    default:
1156
      break;
1157
  }
1158
1159
  /*
1160
   * Remove the Statement message we've been working with (same as
1161
   * current_statement).
1162
   */
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1163
  message::Transaction *transaction= getActiveTransactionMessage(session);
1976.8.1 by David Shrewsbury
Add ability to rollback a statement, change to use 1 GPB Statement message per SQL statement. NOTE: segmented statements not handled yet.
1164
  google::protobuf::RepeatedPtrField<message::Statement> *statements_in_txn;
1165
  statements_in_txn= transaction->mutable_statement();
1166
  statements_in_txn->RemoveLast();
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1167
  session.setStatementMessage(NULL);
1976.8.2 by David Shrewsbury
Support rollback of segmented statements ; removed unnecessary code for --replicate-query (didn't work correctly anyway).
1168
  
1169
  /*
1170
   * Create the ROLLBACK_STATEMENT message, if we need to. This serves as
1171
   * an indicator to cancel the previous Statement message which should have
1172
   * had its end_segment attribute set to false.
1173
   */
1174
  if (is_segmented)
1175
  {
1176
    current_statement= transaction->add_statement();
1177
    initStatementMessage(*current_statement,
1178
                         message::Statement::ROLLBACK_STATEMENT,
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1179
                         session);
1180
    finalizeStatementMessage(*current_statement, session);
1976.8.2 by David Shrewsbury
Support rollback of segmented statements ; removed unnecessary code for --replicate-query (didn't work correctly anyway).
1181
  }
1976.8.1 by David Shrewsbury
Add ability to rollback a statement, change to use 1 GPB Statement message per SQL statement. NOTE: segmented statements not handled yet.
1182
}
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1183
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
1184
message::Transaction *TransactionServices::segmentTransactionMessage(Session& session,
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1185
                                                                     message::Transaction *transaction)
1186
{
1187
  uint64_t trx_id= transaction->transaction_context().transaction_id();
1188
  uint32_t seg_id= transaction->segment_id();
1189
  
1190
  transaction->set_end_segment(false);
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1191
  commitTransactionMessage(session);
1192
  transaction= getActiveTransactionMessage(session, false);
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1193
  
1194
  /* Set the transaction ID to match the previous messages */
1195
  transaction->mutable_transaction_context()->set_transaction_id(trx_id);
1196
  transaction->set_segment_id(seg_id + 1);
1197
  transaction->set_end_segment(true);
1198
1199
  return transaction;
1200
}
1201
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
1202
message::Statement &TransactionServices::getInsertStatement(Session& session,
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1203
                                                            Table &table,
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1204
                                                            uint32_t *next_segment_id)
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1205
{
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1206
  message::Statement *statement= session.getStatementMessage();
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1207
  message::Transaction *transaction= NULL;
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1208
  
1209
  /*
1210
   * If statement is NULL, this is a new statement.
1211
   * If statement is NOT NULL, this a continuation of the same statement.
1212
   * This is because autocommitOrRollback() finalizes the statement so that
1213
   * we guarantee only one Statement message per statement (i.e., we no longer
1214
   * share a single GPB message for multiple statements).
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1215
   */
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1216
  if (statement == NULL)
1217
  {
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1218
    transaction= getActiveTransactionMessage(session);
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1219
1220
    if (static_cast<size_t>(transaction->ByteSize()) >= 
2132.3.1 by Andrew Hutchings
Make transaction_message_threshold a read-only global variable instead of a per-session variable
1221
        transaction_message_threshold)
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1222
    {
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1223
      transaction= segmentTransactionMessage(session, transaction);
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1224
    }
1225
1226
    statement= transaction->add_statement();
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1227
    setInsertHeader(*statement, session, table);
1228
    session.setStatementMessage(statement);
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1229
  }
1230
  else
1231
  {
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1232
    transaction= getActiveTransactionMessage(session);
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1233
    
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1234
    /*
1235
     * If we've passed our threshold for the statement size (possible for
1236
     * a bulk insert), we'll finalize the Statement and Transaction (doing
1237
     * the Transaction will keep it from getting huge).
1238
     */
1802.14.1 by Joseph Daly
add variable for gpb size
1239
    if (static_cast<size_t>(transaction->ByteSize()) >= 
2132.3.1 by Andrew Hutchings
Make transaction_message_threshold a read-only global variable instead of a per-session variable
1240
        transaction_message_threshold)
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1241
    {
1780.1.1 by David Shrewsbury
Set transaction ID properly on large, multi-Transaction message transactions. Also add bulk load tests.
1242
      /* Remember the transaction ID so we can re-use it */
1243
      uint64_t trx_id= transaction->transaction_context().transaction_id();
2069.3.1 by David Shrewsbury
Add segment info to Transaction message and re-record tests.
1244
      uint32_t seg_id= transaction->segment_id();
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1245
      
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1246
      message::InsertData *current_data= statement->mutable_insert_data();
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1247
      
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1248
      /* Caller should use this value when adding a new record */
1249
      *next_segment_id= current_data->segment_id() + 1;
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1250
      
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1251
      current_data->set_end_segment(false);
2069.3.1 by David Shrewsbury
Add segment info to Transaction message and re-record tests.
1252
      transaction->set_end_segment(false);
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1253
      
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1254
      /* 
1255
       * Send the trx message to replicators after finalizing the 
1256
       * statement and transaction. This will also set the Transaction
1257
       * and Statement objects in Session to NULL.
1258
       */
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1259
      commitTransactionMessage(session);
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1260
      
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1261
      /*
1262
       * Statement and Transaction should now be NULL, so new ones will get
1263
       * created. We reuse the transaction id since we are segmenting
1264
       * one transaction.
1265
       */
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1266
      transaction= getActiveTransactionMessage(session, false);
1780.1.1 by David Shrewsbury
Set transaction ID properly on large, multi-Transaction message transactions. Also add bulk load tests.
1267
      assert(transaction != NULL);
1268
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1269
      statement= transaction->add_statement();
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1270
      setInsertHeader(*statement, session, table);
1271
      session.setStatementMessage(statement);
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1272
            
1780.1.1 by David Shrewsbury
Set transaction ID properly on large, multi-Transaction message transactions. Also add bulk load tests.
1273
      /* Set the transaction ID to match the previous messages */
1274
      transaction->mutable_transaction_context()->set_transaction_id(trx_id);
2069.3.1 by David Shrewsbury
Add segment info to Transaction message and re-record tests.
1275
      transaction->set_segment_id(seg_id + 1);
1276
      transaction->set_end_segment(true);
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1277
    }
1278
    else
1279
    {
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1280
      /*
1281
       * Continuation of the same statement. Carry forward the existing
1282
       * segment id.
1283
       */
1284
      const message::InsertData &current_data= statement->insert_data();
1285
      *next_segment_id= current_data.segment_id();
1662.3.1 by Joe Daly
fix a problem with multiple tables being updated in the same transaction these should go into seperate records
1286
    }
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1287
  }
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1288
  
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1289
  return *statement;
1290
}
1291
1292
void TransactionServices::setInsertHeader(message::Statement &statement,
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
1293
                                          const Session& session,
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1294
                                          Table &table)
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1295
{
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1296
  initStatementMessage(statement, message::Statement::INSERT, session);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1297
1298
  /* 
1299
   * Now we construct the specialized InsertHeader message inside
1300
   * the generalized message::Statement container...
1301
   */
1302
  /* Set up the insert header */
1303
  message::InsertHeader *header= statement.mutable_insert_header();
1304
  message::TableMetadata *table_metadata= header->mutable_table_metadata();
1305
2385.1.5 by Olaf van der Spek
Refactor
1306
  table_metadata->set_schema_name(table.getShare()->getSchemaName());
1307
  table_metadata->set_table_name(table.getShare()->getTableName());
1308
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1309
  Field **table_fields= table.getFields();
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1310
1311
  message::FieldMetadata *field_metadata;
1312
1313
  /* We will read all the table's fields... */
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1314
  table.setReadSet();
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1315
2385.1.5 by Olaf van der Spek
Refactor
1316
  while (Field* current_field= *table_fields++) 
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1317
  {
1318
    field_metadata= header->add_field_metadata();
1319
    field_metadata->set_name(current_field->field_name);
1320
    field_metadata->set_type(message::internalFieldTypeToFieldProtoType(current_field->type()));
1321
  }
1322
}
1323
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
1324
bool TransactionServices::insertRecord(Session& session,
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1325
                                       Table &table)
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1326
{
2318.6.73 by Olaf van der Spek
Refactor
1327
  if (! ReplicationServices::isActive())
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1328
    return false;
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1329
2187.7.5 by Brian Aker
Merge in modifications such that we check both schema and table for
1330
  if (not table.getShare()->is_replicated())
2154.3.1 by David Shrewsbury
Add mechanism to have list of schemas that will never reach replication stream.
1331
    return false;
1332
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1333
  /**
1334
   * We do this check here because we don't want to even create a 
1335
   * statement if there isn't a primary key on the table...
1336
   *
1337
   * @todo
1338
   *
1339
   * Multi-column primary keys are handled how exactly?
1340
   */
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1341
  if (not table.getShare()->hasPrimaryKey())
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1342
  {
1343
    my_error(ER_NO_PRIMARY_KEY_ON_REPLICATED_TABLE, MYF(0));
1344
    return true;
1345
  }
1346
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1347
  uint32_t next_segment_id= 1;
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1348
  message::Statement &statement= getInsertStatement(session, table, &next_segment_id);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1349
1350
  message::InsertData *data= statement.mutable_insert_data();
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1351
  data->set_segment_id(next_segment_id);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1352
  data->set_end_segment(true);
1353
  message::InsertRecord *record= data->add_record();
1354
1355
  Field *current_field;
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1356
  Field **table_fields= table.getFields();
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1357
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1358
  String *string_value= new (session.mem_root) String(TransactionServices::DEFAULT_RECORD_SIZE);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1359
  string_value->set_charset(system_charset_info);
1360
1361
  /* We will read all the table's fields... */
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1362
  table.setReadSet();
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1363
1364
  while ((current_field= *table_fields++) != NULL) 
1365
  {
1667.3.6 by Joe Daly
bug 594873 fix null handling in enum in the transaction log
1366
    if (current_field->is_null())
1367
    {
1368
      record->add_is_null(true);
1667.3.7 by Joe Daly
merge trunk
1369
      record->add_insert_value("", 0);
1667.3.6 by Joe Daly
bug 594873 fix null handling in enum in the transaction log
1370
    } 
1371
    else 
1372
    {
1996.2.1 by Brian Aker
uuid type code.
1373
      string_value= current_field->val_str_internal(string_value);
1667.3.6 by Joe Daly
bug 594873 fix null handling in enum in the transaction log
1374
      record->add_is_null(false);
1375
      record->add_insert_value(string_value->c_ptr(), string_value->length());
1376
      string_value->free();
1377
    }
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1378
  }
1379
  return false;
1380
}
1381
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
1382
message::Statement &TransactionServices::getUpdateStatement(Session& session,
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1383
                                                            Table &table,
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1384
                                                            const unsigned char *old_record, 
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1385
                                                            const unsigned char *new_record,
1386
                                                            uint32_t *next_segment_id)
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1387
{
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1388
  message::Statement *statement= session.getStatementMessage();
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1389
  message::Transaction *transaction= NULL;
1662.3.1 by Joe Daly
fix a problem with multiple tables being updated in the same transaction these should go into seperate records
1390
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1391
  /*
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1392
   * If statement is NULL, this is a new statement.
1393
   * If statement is NOT NULL, this a continuation of the same statement.
1394
   * This is because autocommitOrRollback() finalizes the statement so that
1395
   * we guarantee only one Statement message per statement (i.e., we no longer
1396
   * share a single GPB message for multiple statements).
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1397
   */
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1398
  if (statement == NULL)
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1399
  {
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1400
    transaction= getActiveTransactionMessage(session);
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1401
    
1402
    if (static_cast<size_t>(transaction->ByteSize()) >= 
2132.3.1 by Andrew Hutchings
Make transaction_message_threshold a read-only global variable instead of a per-session variable
1403
        transaction_message_threshold)
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1404
    {
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1405
      transaction= segmentTransactionMessage(session, transaction);
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1406
    }
1407
    
1408
    statement= transaction->add_statement();
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1409
    setUpdateHeader(*statement, session, table, old_record, new_record);
1410
    session.setStatementMessage(statement);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1411
  }
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1412
  else
1662.3.1 by Joe Daly
fix a problem with multiple tables being updated in the same transaction these should go into seperate records
1413
  {
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1414
    transaction= getActiveTransactionMessage(session);
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1415
    
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1416
    /*
1417
     * If we've passed our threshold for the statement size (possible for
1418
     * a bulk insert), we'll finalize the Statement and Transaction (doing
1419
     * the Transaction will keep it from getting huge).
1420
     */
1802.14.1 by Joseph Daly
add variable for gpb size
1421
    if (static_cast<size_t>(transaction->ByteSize()) >= 
2132.3.1 by Andrew Hutchings
Make transaction_message_threshold a read-only global variable instead of a per-session variable
1422
        transaction_message_threshold)
1662.3.1 by Joe Daly
fix a problem with multiple tables being updated in the same transaction these should go into seperate records
1423
    {
1780.1.1 by David Shrewsbury
Set transaction ID properly on large, multi-Transaction message transactions. Also add bulk load tests.
1424
      /* Remember the transaction ID so we can re-use it */
1425
      uint64_t trx_id= transaction->transaction_context().transaction_id();
2069.3.1 by David Shrewsbury
Add segment info to Transaction message and re-record tests.
1426
      uint32_t seg_id= transaction->segment_id();
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1427
      
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1428
      message::UpdateData *current_data= statement->mutable_update_data();
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1429
      
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1430
      /* Caller should use this value when adding a new record */
1431
      *next_segment_id= current_data->segment_id() + 1;
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1432
      
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1433
      current_data->set_end_segment(false);
2069.3.1 by David Shrewsbury
Add segment info to Transaction message and re-record tests.
1434
      transaction->set_end_segment(false);
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1435
      
1436
      /* 
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1437
       * Send the trx message to replicators after finalizing the 
1438
       * statement and transaction. This will also set the Transaction
1439
       * and Statement objects in Session to NULL.
1440
       */
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1441
      commitTransactionMessage(session);
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1442
      
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1443
      /*
1444
       * Statement and Transaction should now be NULL, so new ones will get
1445
       * created. We reuse the transaction id since we are segmenting
1446
       * one transaction.
1447
       */
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1448
      transaction= getActiveTransactionMessage(session, false);
1780.1.1 by David Shrewsbury
Set transaction ID properly on large, multi-Transaction message transactions. Also add bulk load tests.
1449
      assert(transaction != NULL);
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1450
      
1451
      statement= transaction->add_statement();
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1452
      setUpdateHeader(*statement, session, table, old_record, new_record);
1453
      session.setStatementMessage(statement);
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1454
      
1780.1.1 by David Shrewsbury
Set transaction ID properly on large, multi-Transaction message transactions. Also add bulk load tests.
1455
      /* Set the transaction ID to match the previous messages */
1456
      transaction->mutable_transaction_context()->set_transaction_id(trx_id);
2069.3.1 by David Shrewsbury
Add segment info to Transaction message and re-record tests.
1457
      transaction->set_segment_id(seg_id + 1);
1458
      transaction->set_end_segment(true);
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1459
    }
1460
    else
1461
    {
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1462
      /*
1463
       * Continuation of the same statement. Carry forward the existing
1464
       * segment id.
1465
       */
1466
      const message::UpdateData &current_data= statement->update_data();
1467
      *next_segment_id= current_data.segment_id();
1662.3.1 by Joe Daly
fix a problem with multiple tables being updated in the same transaction these should go into seperate records
1468
    }
1469
  }
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1470
  
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1471
  return *statement;
1472
}
1473
1474
void TransactionServices::setUpdateHeader(message::Statement &statement,
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
1475
                                          const Session& session,
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1476
                                          Table &table,
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1477
                                          const unsigned char *old_record, 
1478
                                          const unsigned char *new_record)
1479
{
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1480
  initStatementMessage(statement, message::Statement::UPDATE, session);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1481
1482
  /* 
1483
   * Now we construct the specialized UpdateHeader message inside
1484
   * the generalized message::Statement container...
1485
   */
1486
  /* Set up the update header */
1487
  message::UpdateHeader *header= statement.mutable_update_header();
1488
  message::TableMetadata *table_metadata= header->mutable_table_metadata();
1489
2385.1.5 by Olaf van der Spek
Refactor
1490
  table_metadata->set_schema_name(table.getShare()->getSchemaName());
1491
  table_metadata->set_table_name(table.getShare()->getTableName());
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1492
1493
  Field *current_field;
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1494
  Field **table_fields= table.getFields();
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1495
1496
  message::FieldMetadata *field_metadata;
1497
1498
  /* We will read all the table's fields... */
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1499
  table.setReadSet();
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1500
1501
  while ((current_field= *table_fields++) != NULL) 
1502
  {
1503
    /*
1504
     * We add the "key field metadata" -- i.e. the fields which is
1505
     * the primary key for the table.
1506
     */
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1507
    if (table.getShare()->fieldInPrimaryKey(current_field))
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1508
    {
1509
      field_metadata= header->add_key_field_metadata();
1510
      field_metadata->set_name(current_field->field_name);
1511
      field_metadata->set_type(message::internalFieldTypeToFieldProtoType(current_field->type()));
1512
    }
1513
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1514
    if (isFieldUpdated(current_field, table, old_record, new_record))
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1515
    {
1516
      /* Field is changed from old to new */
1517
      field_metadata= header->add_set_field_metadata();
1518
      field_metadata->set_name(current_field->field_name);
1519
      field_metadata->set_type(message::internalFieldTypeToFieldProtoType(current_field->type()));
1520
    }
1521
  }
1522
}
2154.3.1 by David Shrewsbury
Add mechanism to have list of schemas that will never reach replication stream.
1523
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
1524
void TransactionServices::updateRecord(Session& session,
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1525
                                       Table &table, 
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1526
                                       const unsigned char *old_record, 
1527
                                       const unsigned char *new_record)
1528
{
2318.6.73 by Olaf van der Spek
Refactor
1529
  if (! ReplicationServices::isActive())
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1530
    return;
1531
2187.7.5 by Brian Aker
Merge in modifications such that we check both schema and table for
1532
  if (not table.getShare()->is_replicated())
2154.3.1 by David Shrewsbury
Add mechanism to have list of schemas that will never reach replication stream.
1533
    return;
1534
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1535
  uint32_t next_segment_id= 1;
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1536
  message::Statement &statement= getUpdateStatement(session, table, old_record, new_record, &next_segment_id);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1537
1538
  message::UpdateData *data= statement.mutable_update_data();
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1539
  data->set_segment_id(next_segment_id);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1540
  data->set_end_segment(true);
1541
  message::UpdateRecord *record= data->add_record();
1542
1543
  Field *current_field;
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1544
  Field **table_fields= table.getFields();
1545
  String *string_value= new (session.mem_root) String(TransactionServices::DEFAULT_RECORD_SIZE);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1546
  string_value->set_charset(system_charset_info);
1547
1548
  while ((current_field= *table_fields++) != NULL) 
1549
  {
1550
    /*
1551
     * Here, we add the SET field values.  We used to do this in the setUpdateHeader() method, 
1552
     * but then realized that an UPDATE statement could potentially have different values for
1553
     * the SET field.  For instance, imagine this SQL scenario:
1554
     *
1555
     * CREATE TABLE t1 (id INT NOT NULL PRIMARY KEY, count INT NOT NULL);
1556
     * INSERT INTO t1 (id, counter) VALUES (1,1),(2,2),(3,3);
1557
     * UPDATE t1 SET counter = counter + 1 WHERE id IN (1,2);
1558
     *
1559
     * We will generate two UpdateRecord messages with different set_value byte arrays.
1560
     */
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1561
    if (isFieldUpdated(current_field, table, old_record, new_record))
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1562
    {
1563
      /* Store the original "read bit" for this field */
1564
      bool is_read_set= current_field->isReadSet();
1565
1566
      /* We need to mark that we will "read" this field... */
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1567
      table.setReadSet(current_field->position());
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1568
1569
      /* Read the string value of this field's contents */
1996.2.1 by Brian Aker
uuid type code.
1570
      string_value= current_field->val_str_internal(string_value);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1571
1572
      /* 
1573
       * Reset the read bit after reading field to its original state.  This 
1574
       * prevents the field from being included in the WHERE clause
1575
       */
1576
      current_field->setReadSet(is_read_set);
1577
1667.3.6 by Joe Daly
bug 594873 fix null handling in enum in the transaction log
1578
      if (current_field->is_null())
1579
      {
1580
        record->add_is_null(true);
1667.3.7 by Joe Daly
merge trunk
1581
        record->add_after_value("", 0);
1667.3.6 by Joe Daly
bug 594873 fix null handling in enum in the transaction log
1582
      }
1583
      else
1584
      {
1585
        record->add_is_null(false);
1586
        record->add_after_value(string_value->c_ptr(), string_value->length());
1587
      }
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1588
      string_value->free();
1589
    }
1590
1591
    /* 
1592
     * Add the WHERE clause values now...for now, this means the
1593
     * primary key field value.  Replication only supports tables
1594
     * with a primary key.
1595
     */
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1596
    if (table.getShare()->fieldInPrimaryKey(current_field))
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1597
    {
1598
      /**
1599
       * To say the below is ugly is an understatement. But it works.
1600
       * 
1601
       * @todo Move this crap into a real Record API.
1602
       */
1996.2.1 by Brian Aker
uuid type code.
1603
      string_value= current_field->val_str_internal(string_value,
1604
                                                    old_record + 
1605
                                                    current_field->offset(const_cast<unsigned char *>(new_record)));
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1606
      record->add_key_value(string_value->c_ptr(), string_value->length());
1607
      string_value->free();
1608
    }
1609
1610
  }
1611
}
1612
1795.2.2 by Joseph Daly
add test and add isFieldUpdated function
1613
bool TransactionServices::isFieldUpdated(Field *current_field,
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1614
                                         Table &table,
1795.2.2 by Joseph Daly
add test and add isFieldUpdated function
1615
                                         const unsigned char *old_record,
1616
                                         const unsigned char *new_record)
1617
{
1618
  /*
1619
   * The below really should be moved into the Field API and Record API.  But for now
1620
   * we do this crazy pointer fiddling to figure out if the current field
1621
   * has been updated in the supplied record raw byte pointers.
1622
   */
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1623
  const unsigned char *old_ptr= (const unsigned char *) old_record + (ptrdiff_t) (current_field->ptr - table.getInsertRecord());
1624
  const unsigned char *new_ptr= (const unsigned char *) new_record + (ptrdiff_t) (current_field->ptr - table.getInsertRecord());
1795.2.2 by Joseph Daly
add test and add isFieldUpdated function
1625
1626
  uint32_t field_length= current_field->pack_length(); /** @TODO This isn't always correct...check varchar diffs. */
1627
1628
  bool old_value_is_null= current_field->is_null_in_record(old_record);
1629
  bool new_value_is_null= current_field->is_null_in_record(new_record);
1630
1631
  bool isUpdated= false;
1632
  if (old_value_is_null != new_value_is_null)
1633
  {
1634
    if ((old_value_is_null) && (! new_value_is_null)) /* old value is NULL, new value is non NULL */
1635
    {
1636
      isUpdated= true;
1637
    }
1638
    else if ((! old_value_is_null) && (new_value_is_null)) /* old value is non NULL, new value is NULL */
1639
    {
1640
      isUpdated= true;
1641
    }
1642
  }
1643
1644
  if (! isUpdated)
1645
  {
1646
    if (memcmp(old_ptr, new_ptr, field_length) != 0)
1647
    {
1648
      isUpdated= true;
1649
    }
1650
  }
1651
  return isUpdated;
1652
}  
1653
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
1654
message::Statement &TransactionServices::getDeleteStatement(Session& session,
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1655
                                                            Table &table,
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1656
                                                            uint32_t *next_segment_id)
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1657
{
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1658
  message::Statement *statement= session.getStatementMessage();
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1659
  message::Transaction *transaction= NULL;
1662.3.1 by Joe Daly
fix a problem with multiple tables being updated in the same transaction these should go into seperate records
1660
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1661
  /*
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1662
   * If statement is NULL, this is a new statement.
1663
   * If statement is NOT NULL, this a continuation of the same statement.
1664
   * This is because autocommitOrRollback() finalizes the statement so that
1665
   * we guarantee only one Statement message per statement (i.e., we no longer
1666
   * share a single GPB message for multiple statements).
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1667
   */
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1668
  if (statement == NULL)
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1669
  {
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1670
    transaction= getActiveTransactionMessage(session);
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1671
    
1672
    if (static_cast<size_t>(transaction->ByteSize()) >= 
2132.3.1 by Andrew Hutchings
Make transaction_message_threshold a read-only global variable instead of a per-session variable
1673
        transaction_message_threshold)
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1674
    {
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1675
      transaction= segmentTransactionMessage(session, transaction);
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1676
    }
1677
    
1678
    statement= transaction->add_statement();
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1679
    setDeleteHeader(*statement, session, table);
1680
    session.setStatementMessage(statement);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1681
  }
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1682
  else
1662.3.1 by Joe Daly
fix a problem with multiple tables being updated in the same transaction these should go into seperate records
1683
  {
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1684
    transaction= getActiveTransactionMessage(session);
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1685
    
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1686
    /*
1687
     * If we've passed our threshold for the statement size (possible for
1688
     * a bulk insert), we'll finalize the Statement and Transaction (doing
1689
     * the Transaction will keep it from getting huge).
1690
     */
1802.14.1 by Joseph Daly
add variable for gpb size
1691
    if (static_cast<size_t>(transaction->ByteSize()) >= 
2132.3.1 by Andrew Hutchings
Make transaction_message_threshold a read-only global variable instead of a per-session variable
1692
        transaction_message_threshold)
1662.3.1 by Joe Daly
fix a problem with multiple tables being updated in the same transaction these should go into seperate records
1693
    {
1780.1.1 by David Shrewsbury
Set transaction ID properly on large, multi-Transaction message transactions. Also add bulk load tests.
1694
      /* Remember the transaction ID so we can re-use it */
1695
      uint64_t trx_id= transaction->transaction_context().transaction_id();
2069.3.1 by David Shrewsbury
Add segment info to Transaction message and re-record tests.
1696
      uint32_t seg_id= transaction->segment_id();
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1697
      
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1698
      message::DeleteData *current_data= statement->mutable_delete_data();
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1699
      
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1700
      /* Caller should use this value when adding a new record */
1701
      *next_segment_id= current_data->segment_id() + 1;
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1702
      
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1703
      current_data->set_end_segment(false);
2069.3.1 by David Shrewsbury
Add segment info to Transaction message and re-record tests.
1704
      transaction->set_end_segment(false);
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1705
      
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1706
      /* 
1707
       * Send the trx message to replicators after finalizing the 
1708
       * statement and transaction. This will also set the Transaction
1709
       * and Statement objects in Session to NULL.
1710
       */
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1711
      commitTransactionMessage(session);
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1712
      
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1713
      /*
1714
       * Statement and Transaction should now be NULL, so new ones will get
1715
       * created. We reuse the transaction id since we are segmenting
1716
       * one transaction.
1717
       */
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1718
      transaction= getActiveTransactionMessage(session, false);
1780.1.1 by David Shrewsbury
Set transaction ID properly on large, multi-Transaction message transactions. Also add bulk load tests.
1719
      assert(transaction != NULL);
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1720
      
1721
      statement= transaction->add_statement();
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1722
      setDeleteHeader(*statement, session, table);
1723
      session.setStatementMessage(statement);
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1724
      
1780.1.1 by David Shrewsbury
Set transaction ID properly on large, multi-Transaction message transactions. Also add bulk load tests.
1725
      /* Set the transaction ID to match the previous messages */
1726
      transaction->mutable_transaction_context()->set_transaction_id(trx_id);
2069.3.1 by David Shrewsbury
Add segment info to Transaction message and re-record tests.
1727
      transaction->set_segment_id(seg_id + 1);
1728
      transaction->set_end_segment(true);
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1729
    }
1730
    else
1731
    {
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1732
      /*
1733
       * Continuation of the same statement. Carry forward the existing
1734
       * segment id.
1735
       */
1736
      const message::DeleteData &current_data= statement->delete_data();
1737
      *next_segment_id= current_data.segment_id();
1662.3.1 by Joe Daly
fix a problem with multiple tables being updated in the same transaction these should go into seperate records
1738
    }
1739
  }
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1740
  
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1741
  return *statement;
1742
}
1743
1744
void TransactionServices::setDeleteHeader(message::Statement &statement,
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
1745
                                          const Session& session,
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1746
                                          Table &table)
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1747
{
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1748
  initStatementMessage(statement, message::Statement::DELETE, session);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1749
1750
  /* 
1751
   * Now we construct the specialized DeleteHeader message inside
1752
   * the generalized message::Statement container...
1753
   */
1754
  message::DeleteHeader *header= statement.mutable_delete_header();
1755
  message::TableMetadata *table_metadata= header->mutable_table_metadata();
1756
2385.1.5 by Olaf van der Spek
Refactor
1757
  table_metadata->set_schema_name(table.getShare()->getSchemaName());
1758
  table_metadata->set_table_name(table.getShare()->getTableName());
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1759
1760
  Field *current_field;
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1761
  Field **table_fields= table.getFields();
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1762
1763
  message::FieldMetadata *field_metadata;
1764
1765
  while ((current_field= *table_fields++) != NULL) 
1766
  {
1767
    /* 
1768
     * Add the WHERE clause values now...for now, this means the
1769
     * primary key field value.  Replication only supports tables
1770
     * with a primary key.
1771
     */
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1772
    if (table.getShare()->fieldInPrimaryKey(current_field))
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1773
    {
1774
      field_metadata= header->add_key_field_metadata();
1775
      field_metadata->set_name(current_field->field_name);
1776
      field_metadata->set_type(message::internalFieldTypeToFieldProtoType(current_field->type()));
1777
    }
1778
  }
1779
}
1780
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
1781
void TransactionServices::deleteRecord(Session& session,
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1782
                                       Table &table,
1783
                                       bool use_update_record)
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1784
{
2318.6.73 by Olaf van der Spek
Refactor
1785
  if (! ReplicationServices::isActive())
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1786
    return;
1787
2187.7.5 by Brian Aker
Merge in modifications such that we check both schema and table for
1788
  if (not table.getShare()->is_replicated())
2154.3.1 by David Shrewsbury
Add mechanism to have list of schemas that will never reach replication stream.
1789
    return;
1790
1746.1.1 by David Shrewsbury
Fix uninitialized variable.
1791
  uint32_t next_segment_id= 1;
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1792
  message::Statement &statement= getDeleteStatement(session, table, &next_segment_id);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1793
1794
  message::DeleteData *data= statement.mutable_delete_data();
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1795
  data->set_segment_id(next_segment_id);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1796
  data->set_end_segment(true);
1797
  message::DeleteRecord *record= data->add_record();
1798
1799
  Field *current_field;
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1800
  Field **table_fields= table.getFields();
1801
  String *string_value= new (session.mem_root) String(TransactionServices::DEFAULT_RECORD_SIZE);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1802
  string_value->set_charset(system_charset_info);
1803
1804
  while ((current_field= *table_fields++) != NULL) 
1805
  {
1667.3.5 by Joe Daly
fix up spacing again
1806
    /* 
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1807
     * Add the WHERE clause values now...for now, this means the
1808
     * primary key field value.  Replication only supports tables
1809
     * with a primary key.
1810
     */
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1811
    if (table.getShare()->fieldInPrimaryKey(current_field))
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1812
    {
1730.5.1 by David Shrewsbury
Use the update record, not insert record, when record DELETE operations during REPLACE.
1813
      if (use_update_record)
1814
      {
1815
        /*
1816
         * Temporarily point to the update record to get its value.
1817
         * This is pretty much a hack in order to get the PK value from
1818
         * the update record rather than the insert record. Field::val_str()
1819
         * should not change anything in Field::ptr, so this should be safe.
1820
         * We are careful not to change anything in old_ptr.
1821
         */
1822
        const unsigned char *old_ptr= current_field->ptr;
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1823
        current_field->ptr= table.getUpdateRecord() + static_cast<ptrdiff_t>(old_ptr - table.getInsertRecord());
1996.2.1 by Brian Aker
uuid type code.
1824
        string_value= current_field->val_str_internal(string_value);
1730.5.1 by David Shrewsbury
Use the update record, not insert record, when record DELETE operations during REPLACE.
1825
        current_field->ptr= const_cast<unsigned char *>(old_ptr);
1826
      }
1827
      else
1828
      {
1996.2.1 by Brian Aker
uuid type code.
1829
        string_value= current_field->val_str_internal(string_value);
1730.5.1 by David Shrewsbury
Use the update record, not insert record, when record DELETE operations during REPLACE.
1830
        /**
1831
         * @TODO Store optional old record value in the before data member
1832
         */
1833
      }
1667.3.2 by Joe Daly
add a working test case, and more fixes so the test case works
1834
      record->add_key_value(string_value->c_ptr(), string_value->length());
1835
      string_value->free();
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1836
    }
1837
  }
1838
}
1839
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
1840
void TransactionServices::createTable(Session& session,
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1841
                                      const message::Table &table)
1842
{
2318.6.73 by Olaf van der Spek
Refactor
1843
  if (not ReplicationServices::isActive())
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1844
    return;
2154.3.1 by David Shrewsbury
Add mechanism to have list of schemas that will never reach replication stream.
1845
2187.7.5 by Brian Aker
Merge in modifications such that we check both schema and table for
1846
  if (not message::is_replicated(table))
2154.3.1 by David Shrewsbury
Add mechanism to have list of schemas that will never reach replication stream.
1847
    return;
1848
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1849
  message::Transaction *transaction= getActiveTransactionMessage(session);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1850
  message::Statement *statement= transaction->add_statement();
1851
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1852
  initStatementMessage(*statement, message::Statement::CREATE_TABLE, session);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1853
1854
  /* 
1855
   * Construct the specialized CreateTableStatement message and attach
1856
   * it to the generic Statement message
1857
   */
1858
  message::CreateTableStatement *create_table_statement= statement->mutable_create_table_statement();
1859
  message::Table *new_table_message= create_table_statement->mutable_table();
1860
  *new_table_message= table;
1861
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1862
  finalizeStatementMessage(*statement, session);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1863
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1864
  finalizeTransactionMessage(*transaction, session);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1865
  
2318.6.73 by Olaf van der Spek
Refactor
1866
  (void) ReplicationServices::pushTransactionMessage(session, *transaction);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1867
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1868
  cleanupTransactionMessage(transaction, session);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1869
1870
}
1871
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
1872
void TransactionServices::createSchema(Session& session,
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1873
                                       const message::Schema &schema)
1874
{
2318.6.73 by Olaf van der Spek
Refactor
1875
  if (! ReplicationServices::isActive())
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1876
    return;
2154.3.1 by David Shrewsbury
Add mechanism to have list of schemas that will never reach replication stream.
1877
2187.7.5 by Brian Aker
Merge in modifications such that we check both schema and table for
1878
  if (not message::is_replicated(schema))
2154.3.1 by David Shrewsbury
Add mechanism to have list of schemas that will never reach replication stream.
1879
    return;
1880
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1881
  message::Transaction *transaction= getActiveTransactionMessage(session);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1882
  message::Statement *statement= transaction->add_statement();
1883
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1884
  initStatementMessage(*statement, message::Statement::CREATE_SCHEMA, session);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1885
1886
  /* 
1887
   * Construct the specialized CreateSchemaStatement message and attach
1888
   * it to the generic Statement message
1889
   */
1890
  message::CreateSchemaStatement *create_schema_statement= statement->mutable_create_schema_statement();
1891
  message::Schema *new_schema_message= create_schema_statement->mutable_schema();
1892
  *new_schema_message= schema;
1893
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1894
  finalizeStatementMessage(*statement, session);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1895
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1896
  finalizeTransactionMessage(*transaction, session);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1897
  
2318.6.73 by Olaf van der Spek
Refactor
1898
  (void) ReplicationServices::pushTransactionMessage(session, *transaction);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1899
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1900
  cleanupTransactionMessage(transaction, session);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1901
1902
}
1903
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
1904
void TransactionServices::dropSchema(Session& session,
2246.4.9 by Olaf van der Spek
Remove const_reference and reference from identifier::Schema
1905
                                     const identifier::Schema& identifier,
2172.3.1 by Brian Aker
Merge in my patch for having some schema/table not replicated.
1906
                                     message::schema::const_reference schema)
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1907
{
2318.6.73 by Olaf van der Spek
Refactor
1908
  if (not ReplicationServices::isActive())
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1909
    return;
2154.3.1 by David Shrewsbury
Add mechanism to have list of schemas that will never reach replication stream.
1910
2187.7.5 by Brian Aker
Merge in modifications such that we check both schema and table for
1911
  if (not message::is_replicated(schema))
2154.3.1 by David Shrewsbury
Add mechanism to have list of schemas that will never reach replication stream.
1912
    return;
1913
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1914
  message::Transaction *transaction= getActiveTransactionMessage(session);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1915
  message::Statement *statement= transaction->add_statement();
1916
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1917
  initStatementMessage(*statement, message::Statement::DROP_SCHEMA, session);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1918
1919
  /* 
1920
   * Construct the specialized DropSchemaStatement message and attach
1921
   * it to the generic Statement message
1922
   */
1923
  message::DropSchemaStatement *drop_schema_statement= statement->mutable_drop_schema_statement();
1924
2052 by Brian Aker
Fix additional member of trans services to handle identifier.
1925
  drop_schema_statement->set_schema_name(identifier.getSchemaName());
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1926
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1927
  finalizeStatementMessage(*statement, session);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1928
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1929
  finalizeTransactionMessage(*transaction, session);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1930
  
2318.6.73 by Olaf van der Spek
Refactor
1931
  (void) ReplicationServices::pushTransactionMessage(session, *transaction);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1932
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1933
  cleanupTransactionMessage(transaction, session);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1934
}
1935
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
1936
void TransactionServices::alterSchema(Session& session,
2159.2.6 by Brian Aker
Finalize interface for schema.
1937
                                      const message::Schema &old_schema,
2078.1.1 by David Shrewsbury
Push ALTER SCHEMA through replication stream as proper GPB message instead of RAW_SQL.
1938
                                      const message::Schema &new_schema)
1939
{
2318.6.73 by Olaf van der Spek
Refactor
1940
  if (! ReplicationServices::isActive())
2078.1.1 by David Shrewsbury
Push ALTER SCHEMA through replication stream as proper GPB message instead of RAW_SQL.
1941
    return;
2154.3.1 by David Shrewsbury
Add mechanism to have list of schemas that will never reach replication stream.
1942
2187.7.5 by Brian Aker
Merge in modifications such that we check both schema and table for
1943
  if (not message::is_replicated(old_schema))
2154.3.1 by David Shrewsbury
Add mechanism to have list of schemas that will never reach replication stream.
1944
    return;
1945
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1946
  message::Transaction *transaction= getActiveTransactionMessage(session);
2078.1.1 by David Shrewsbury
Push ALTER SCHEMA through replication stream as proper GPB message instead of RAW_SQL.
1947
  message::Statement *statement= transaction->add_statement();
1948
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1949
  initStatementMessage(*statement, message::Statement::ALTER_SCHEMA, session);
2078.1.1 by David Shrewsbury
Push ALTER SCHEMA through replication stream as proper GPB message instead of RAW_SQL.
1950
1951
  /* 
1952
   * Construct the specialized AlterSchemaStatement message and attach
1953
   * it to the generic Statement message
1954
   */
1955
  message::AlterSchemaStatement *alter_schema_statement= statement->mutable_alter_schema_statement();
1956
1957
  message::Schema *before= alter_schema_statement->mutable_before();
1958
  message::Schema *after= alter_schema_statement->mutable_after();
1959
2159.2.6 by Brian Aker
Finalize interface for schema.
1960
  *before= old_schema;
2078.1.1 by David Shrewsbury
Push ALTER SCHEMA through replication stream as proper GPB message instead of RAW_SQL.
1961
  *after= new_schema;
1962
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1963
  finalizeStatementMessage(*statement, session);
2078.1.1 by David Shrewsbury
Push ALTER SCHEMA through replication stream as proper GPB message instead of RAW_SQL.
1964
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1965
  finalizeTransactionMessage(*transaction, session);
2078.1.1 by David Shrewsbury
Push ALTER SCHEMA through replication stream as proper GPB message instead of RAW_SQL.
1966
  
2318.6.73 by Olaf van der Spek
Refactor
1967
  (void) ReplicationServices::pushTransactionMessage(session, *transaction);
2078.1.1 by David Shrewsbury
Push ALTER SCHEMA through replication stream as proper GPB message instead of RAW_SQL.
1968
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1969
  cleanupTransactionMessage(transaction, session);
2078.1.1 by David Shrewsbury
Push ALTER SCHEMA through replication stream as proper GPB message instead of RAW_SQL.
1970
}
1971
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
1972
void TransactionServices::dropTable(Session& session,
2246.4.10 by Olaf van der Spek
Remove const_reference and reference from identifier::Table
1973
                                    const identifier::Table& identifier,
2168.3.2 by Brian Aker
CREATE TABLE/SCHEMA now allow you to add REPLICATION to the list of items
1974
                                    message::table::const_reference table,
2048.1.1 by David Shrewsbury
Re-add IF EXISTS support back in to transaction log so we can drop tables on master that are not on the slave.
1975
                                    bool if_exists)
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1976
{
2318.6.73 by Olaf van der Spek
Refactor
1977
  if (! ReplicationServices::isActive())
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1978
    return;
2154.3.1 by David Shrewsbury
Add mechanism to have list of schemas that will never reach replication stream.
1979
2187.7.5 by Brian Aker
Merge in modifications such that we check both schema and table for
1980
  if (not message::is_replicated(table))
2154.3.1 by David Shrewsbury
Add mechanism to have list of schemas that will never reach replication stream.
1981
    return;
1982
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1983
  message::Transaction *transaction= getActiveTransactionMessage(session);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1984
  message::Statement *statement= transaction->add_statement();
1985
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1986
  initStatementMessage(*statement, message::Statement::DROP_TABLE, session);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1987
1988
  /* 
1989
   * Construct the specialized DropTableStatement message and attach
1990
   * it to the generic Statement message
1991
   */
1992
  message::DropTableStatement *drop_table_statement= statement->mutable_drop_table_statement();
1993
2048.1.1 by David Shrewsbury
Re-add IF EXISTS support back in to transaction log so we can drop tables on master that are not on the slave.
1994
  drop_table_statement->set_if_exists_clause(if_exists);
1995
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1996
  message::TableMetadata *table_metadata= drop_table_statement->mutable_table_metadata();
1997
2168.3.2 by Brian Aker
CREATE TABLE/SCHEMA now allow you to add REPLICATION to the list of items
1998
  table_metadata->set_schema_name(identifier.getSchemaName());
1999
  table_metadata->set_table_name(identifier.getTableName());
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
2000
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
2001
  finalizeStatementMessage(*statement, session);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
2002
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
2003
  finalizeTransactionMessage(*transaction, session);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
2004
  
2318.6.73 by Olaf van der Spek
Refactor
2005
  (void) ReplicationServices::pushTransactionMessage(session, *transaction);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
2006
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
2007
  cleanupTransactionMessage(transaction, session);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
2008
}
2009
2318.6.61 by Olaf van der Spek
Refactor
2010
void TransactionServices::truncateTable(Session& session, Table &table)
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
2011
{
2318.6.73 by Olaf van der Spek
Refactor
2012
  if (! ReplicationServices::isActive())
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
2013
    return;
2154.3.1 by David Shrewsbury
Add mechanism to have list of schemas that will never reach replication stream.
2014
2187.7.5 by Brian Aker
Merge in modifications such that we check both schema and table for
2015
  if (not table.getShare()->is_replicated())
2154.3.1 by David Shrewsbury
Add mechanism to have list of schemas that will never reach replication stream.
2016
    return;
2017
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
2018
  message::Transaction *transaction= getActiveTransactionMessage(session);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
2019
  message::Statement *statement= transaction->add_statement();
2020
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
2021
  initStatementMessage(*statement, message::Statement::TRUNCATE_TABLE, session);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
2022
2023
  /* 
2024
   * Construct the specialized TruncateTableStatement message and attach
2025
   * it to the generic Statement message
2026
   */
2027
  message::TruncateTableStatement *truncate_statement= statement->mutable_truncate_table_statement();
2028
  message::TableMetadata *table_metadata= truncate_statement->mutable_table_metadata();
2029
2385.1.5 by Olaf van der Spek
Refactor
2030
  table_metadata->set_schema_name(table.getShare()->getSchemaName());
2031
  table_metadata->set_table_name(table.getShare()->getTableName());
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
2032
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
2033
  finalizeStatementMessage(*statement, session);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
2034
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
2035
  finalizeTransactionMessage(*transaction, session);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
2036
  
2318.6.73 by Olaf van der Spek
Refactor
2037
  (void) ReplicationServices::pushTransactionMessage(session, *transaction);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
2038
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
2039
  cleanupTransactionMessage(transaction, session);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
2040
}
2041
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
2042
void TransactionServices::rawStatement(Session& session,
2211.2.1 by David Shrewsbury
Add raw_sql_schema member to Statement protobuf definition and set it in ALTER TABLE code path to current value associated with Session executing it.
2043
                                       const string &query,
2044
                                       const string &schema)
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
2045
{
2318.6.73 by Olaf van der Spek
Refactor
2046
  if (! ReplicationServices::isActive())
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
2047
    return;
1926.3.1 by Joseph Daly
merge changes to fix duplicate trx ids for raw sql 674588
2048
 
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
2049
  message::Transaction *transaction= getActiveTransactionMessage(session);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
2050
  message::Statement *statement= transaction->add_statement();
2051
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
2052
  initStatementMessage(*statement, message::Statement::RAW_SQL, session);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
2053
  statement->set_sql(query);
2211.2.2 by David Shrewsbury
Output USE from statement transform code for RAW_SQL with an identified schema. Set schema name from Session for RENAME.
2054
  if (not schema.empty())
2055
    statement->set_raw_sql_schema(schema);
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
2056
  finalizeStatementMessage(*statement, session);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
2057
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
2058
  finalizeTransactionMessage(*transaction, session);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
2059
  
2318.6.73 by Olaf van der Spek
Refactor
2060
  (void) ReplicationServices::pushTransactionMessage(session, *transaction);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
2061
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
2062
  cleanupTransactionMessage(transaction, session);
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
2063
}
2064
2302.1.4 by Olaf van der Spek
Refactor
2065
int TransactionServices::sendEvent(Session& session, const message::Event &event)
1819.4.1 by David Shrewsbury
Add server startup and shutdown events to the replication stream.
2066
{
2318.6.73 by Olaf van der Spek
Refactor
2067
  if (not ReplicationServices::isActive())
1819.4.1 by David Shrewsbury
Add server startup and shutdown events to the replication stream.
2068
    return 0;
2302.1.4 by Olaf van der Spek
Refactor
2069
  message::Transaction transaction;
1819.4.1 by David Shrewsbury
Add server startup and shutdown events to the replication stream.
2070
2071
  // set server id, start timestamp
2302.1.4 by Olaf van der Spek
Refactor
2072
  initTransactionMessage(transaction, session, true);
1819.4.1 by David Shrewsbury
Add server startup and shutdown events to the replication stream.
2073
2074
  // set end timestamp
2302.1.4 by Olaf van der Spek
Refactor
2075
  finalizeTransactionMessage(transaction, session);
2076
2077
  message::Event *trx_event= transaction.mutable_event();
1819.4.1 by David Shrewsbury
Add server startup and shutdown events to the replication stream.
2078
  trx_event->CopyFrom(event);
2318.6.73 by Olaf van der Spek
Refactor
2079
  plugin::ReplicationReturnCode result= ReplicationServices::pushTransactionMessage(session, transaction);
2302.1.4 by Olaf van der Spek
Refactor
2080
  return result;
1819.4.1 by David Shrewsbury
Add server startup and shutdown events to the replication stream.
2081
}
2082
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
2083
bool TransactionServices::sendStartupEvent(Session& session)
1819.4.1 by David Shrewsbury
Add server startup and shutdown events to the replication stream.
2084
{
2085
  message::Event event;
2086
  event.set_type(message::Event::STARTUP);
2302.1.4 by Olaf van der Spek
Refactor
2087
  return not sendEvent(session, event);
1819.4.1 by David Shrewsbury
Add server startup and shutdown events to the replication stream.
2088
}
2089
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
2090
bool TransactionServices::sendShutdownEvent(Session& session)
1819.4.1 by David Shrewsbury
Add server startup and shutdown events to the replication stream.
2091
{
2092
  message::Event event;
2093
  event.set_type(message::Event::SHUTDOWN);
2302.1.4 by Olaf van der Spek
Refactor
2094
  return not sendEvent(session, event);
1819.4.1 by David Shrewsbury
Add server startup and shutdown events to the replication stream.
2095
}
2096
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
2097
} /* namespace drizzled */