~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
1336.2.3 by Jay Pipes
Merge trunk and resolve
1306
  string schema_name;
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1307
  (void) table.getShare()->getSchemaName(schema_name);
1336.2.3 by Jay Pipes
Merge trunk and resolve
1308
  string table_name;
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1309
  (void) table.getShare()->getTableName(table_name);
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
1336.2.3 by Jay Pipes
Merge trunk and resolve
1311
  table_metadata->set_schema_name(schema_name.c_str(), schema_name.length());
1312
  table_metadata->set_table_name(table_name.c_str(), table_name.length());
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.
1313
1314
  Field *current_field;
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1315
  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.
1316
1317
  message::FieldMetadata *field_metadata;
1318
1319
  /* 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.
1320
  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.
1321
1322
  while ((current_field= *table_fields++) != NULL) 
1323
  {
1324
    field_metadata= header->add_field_metadata();
1325
    field_metadata->set_name(current_field->field_name);
1326
    field_metadata->set_type(message::internalFieldTypeToFieldProtoType(current_field->type()));
1327
  }
1328
}
1329
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
1330
bool TransactionServices::insertRecord(Session& session,
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1331
                                       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.
1332
{
2318.6.73 by Olaf van der Spek
Refactor
1333
  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.
1334
    return false;
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1335
2187.7.5 by Brian Aker
Merge in modifications such that we check both schema and table for
1336
  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.
1337
    return false;
1338
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.
1339
  /**
1340
   * We do this check here because we don't want to even create a 
1341
   * statement if there isn't a primary key on the table...
1342
   *
1343
   * @todo
1344
   *
1345
   * Multi-column primary keys are handled how exactly?
1346
   */
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1347
  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.
1348
  {
1349
    my_error(ER_NO_PRIMARY_KEY_ON_REPLICATED_TABLE, MYF(0));
1350
    return true;
1351
  }
1352
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1353
  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.
1354
  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.
1355
1356
  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.
1357
  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.
1358
  data->set_end_segment(true);
1359
  message::InsertRecord *record= data->add_record();
1360
1361
  Field *current_field;
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1362
  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.
1363
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1364
  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.
1365
  string_value->set_charset(system_charset_info);
1366
1367
  /* 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.
1368
  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.
1369
1370
  while ((current_field= *table_fields++) != NULL) 
1371
  {
1667.3.6 by Joe Daly
bug 594873 fix null handling in enum in the transaction log
1372
    if (current_field->is_null())
1373
    {
1374
      record->add_is_null(true);
1667.3.7 by Joe Daly
merge trunk
1375
      record->add_insert_value("", 0);
1667.3.6 by Joe Daly
bug 594873 fix null handling in enum in the transaction log
1376
    } 
1377
    else 
1378
    {
1996.2.1 by Brian Aker
uuid type code.
1379
      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
1380
      record->add_is_null(false);
1381
      record->add_insert_value(string_value->c_ptr(), string_value->length());
1382
      string_value->free();
1383
    }
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
  }
1385
  return false;
1386
}
1387
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
1388
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.
1389
                                                            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.
1390
                                                            const unsigned char *old_record, 
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1391
                                                            const unsigned char *new_record,
1392
                                                            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.
1393
{
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1394
  message::Statement *statement= session.getStatementMessage();
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1395
  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
1396
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 is NULL, this is a new statement.
1399
   * If statement is NOT NULL, this a continuation of the same statement.
1400
   * This is because autocommitOrRollback() finalizes the statement so that
1401
   * we guarantee only one Statement message per statement (i.e., we no longer
1402
   * 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.
1403
   */
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1404
  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.
1405
  {
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1406
    transaction= getActiveTransactionMessage(session);
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1407
    
1408
    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
1409
        transaction_message_threshold)
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1410
    {
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1411
      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.
1412
    }
1413
    
1414
    statement= transaction->add_statement();
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1415
    setUpdateHeader(*statement, session, table, old_record, new_record);
1416
    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.
1417
  }
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1418
  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
1419
  {
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1420
    transaction= getActiveTransactionMessage(session);
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1421
    
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1422
    /*
1423
     * If we've passed our threshold for the statement size (possible for
1424
     * a bulk insert), we'll finalize the Statement and Transaction (doing
1425
     * the Transaction will keep it from getting huge).
1426
     */
1802.14.1 by Joseph Daly
add variable for gpb size
1427
    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
1428
        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
1429
    {
1780.1.1 by David Shrewsbury
Set transaction ID properly on large, multi-Transaction message transactions. Also add bulk load tests.
1430
      /* Remember the transaction ID so we can re-use it */
1431
      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.
1432
      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.
1433
      
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1434
      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.
1435
      
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1436
      /* Caller should use this value when adding a new record */
1437
      *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.
1438
      
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1439
      current_data->set_end_segment(false);
2069.3.1 by David Shrewsbury
Add segment info to Transaction message and re-record tests.
1440
      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.
1441
      
1442
      /* 
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1443
       * Send the trx message to replicators after finalizing the 
1444
       * statement and transaction. This will also set the Transaction
1445
       * and Statement objects in Session to NULL.
1446
       */
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1447
      commitTransactionMessage(session);
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1448
      
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1449
      /*
1450
       * Statement and Transaction should now be NULL, so new ones will get
1451
       * created. We reuse the transaction id since we are segmenting
1452
       * one transaction.
1453
       */
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1454
      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.
1455
      assert(transaction != NULL);
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1456
      
1457
      statement= transaction->add_statement();
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1458
      setUpdateHeader(*statement, session, table, old_record, new_record);
1459
      session.setStatementMessage(statement);
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1460
      
1780.1.1 by David Shrewsbury
Set transaction ID properly on large, multi-Transaction message transactions. Also add bulk load tests.
1461
      /* Set the transaction ID to match the previous messages */
1462
      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.
1463
      transaction->set_segment_id(seg_id + 1);
1464
      transaction->set_end_segment(true);
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1465
    }
1466
    else
1467
    {
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1468
      /*
1469
       * Continuation of the same statement. Carry forward the existing
1470
       * segment id.
1471
       */
1472
      const message::UpdateData &current_data= statement->update_data();
1473
      *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
1474
    }
1475
  }
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1476
  
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
  return *statement;
1478
}
1479
1480
void TransactionServices::setUpdateHeader(message::Statement &statement,
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
1481
                                          const Session& session,
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1482
                                          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.
1483
                                          const unsigned char *old_record, 
1484
                                          const unsigned char *new_record)
1485
{
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1486
  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.
1487
1488
  /* 
1489
   * Now we construct the specialized UpdateHeader message inside
1490
   * the generalized message::Statement container...
1491
   */
1492
  /* Set up the update header */
1493
  message::UpdateHeader *header= statement.mutable_update_header();
1494
  message::TableMetadata *table_metadata= header->mutable_table_metadata();
1495
1336.2.3 by Jay Pipes
Merge trunk and resolve
1496
  string schema_name;
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1497
  (void) table.getShare()->getSchemaName(schema_name);
1336.2.3 by Jay Pipes
Merge trunk and resolve
1498
  string table_name;
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1499
  (void) table.getShare()->getTableName(table_name);
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
1336.2.3 by Jay Pipes
Merge trunk and resolve
1501
  table_metadata->set_schema_name(schema_name.c_str(), schema_name.length());
1502
  table_metadata->set_table_name(table_name.c_str(), table_name.length());
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.
1503
1504
  Field *current_field;
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1505
  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.
1506
1507
  message::FieldMetadata *field_metadata;
1508
1509
  /* 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.
1510
  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.
1511
1512
  while ((current_field= *table_fields++) != NULL) 
1513
  {
1514
    /*
1515
     * We add the "key field metadata" -- i.e. the fields which is
1516
     * the primary key for the table.
1517
     */
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1518
    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.
1519
    {
1520
      field_metadata= header->add_key_field_metadata();
1521
      field_metadata->set_name(current_field->field_name);
1522
      field_metadata->set_type(message::internalFieldTypeToFieldProtoType(current_field->type()));
1523
    }
1524
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1525
    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.
1526
    {
1527
      /* Field is changed from old to new */
1528
      field_metadata= header->add_set_field_metadata();
1529
      field_metadata->set_name(current_field->field_name);
1530
      field_metadata->set_type(message::internalFieldTypeToFieldProtoType(current_field->type()));
1531
    }
1532
  }
1533
}
2154.3.1 by David Shrewsbury
Add mechanism to have list of schemas that will never reach replication stream.
1534
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
1535
void TransactionServices::updateRecord(Session& session,
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1536
                                       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.
1537
                                       const unsigned char *old_record, 
1538
                                       const unsigned char *new_record)
1539
{
2318.6.73 by Olaf van der Spek
Refactor
1540
  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.
1541
    return;
1542
2187.7.5 by Brian Aker
Merge in modifications such that we check both schema and table for
1543
  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.
1544
    return;
1545
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1546
  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.
1547
  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.
1548
1549
  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.
1550
  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.
1551
  data->set_end_segment(true);
1552
  message::UpdateRecord *record= data->add_record();
1553
1554
  Field *current_field;
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1555
  Field **table_fields= table.getFields();
1556
  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.
1557
  string_value->set_charset(system_charset_info);
1558
1559
  while ((current_field= *table_fields++) != NULL) 
1560
  {
1561
    /*
1562
     * Here, we add the SET field values.  We used to do this in the setUpdateHeader() method, 
1563
     * but then realized that an UPDATE statement could potentially have different values for
1564
     * the SET field.  For instance, imagine this SQL scenario:
1565
     *
1566
     * CREATE TABLE t1 (id INT NOT NULL PRIMARY KEY, count INT NOT NULL);
1567
     * INSERT INTO t1 (id, counter) VALUES (1,1),(2,2),(3,3);
1568
     * UPDATE t1 SET counter = counter + 1 WHERE id IN (1,2);
1569
     *
1570
     * We will generate two UpdateRecord messages with different set_value byte arrays.
1571
     */
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1572
    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.
1573
    {
1574
      /* Store the original "read bit" for this field */
1575
      bool is_read_set= current_field->isReadSet();
1576
1577
      /* 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.
1578
      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.
1579
1580
      /* Read the string value of this field's contents */
1996.2.1 by Brian Aker
uuid type code.
1581
      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.
1582
1583
      /* 
1584
       * Reset the read bit after reading field to its original state.  This 
1585
       * prevents the field from being included in the WHERE clause
1586
       */
1587
      current_field->setReadSet(is_read_set);
1588
1667.3.6 by Joe Daly
bug 594873 fix null handling in enum in the transaction log
1589
      if (current_field->is_null())
1590
      {
1591
        record->add_is_null(true);
1667.3.7 by Joe Daly
merge trunk
1592
        record->add_after_value("", 0);
1667.3.6 by Joe Daly
bug 594873 fix null handling in enum in the transaction log
1593
      }
1594
      else
1595
      {
1596
        record->add_is_null(false);
1597
        record->add_after_value(string_value->c_ptr(), string_value->length());
1598
      }
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.
1599
      string_value->free();
1600
    }
1601
1602
    /* 
1603
     * Add the WHERE clause values now...for now, this means the
1604
     * primary key field value.  Replication only supports tables
1605
     * with a primary key.
1606
     */
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1607
    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.
1608
    {
1609
      /**
1610
       * To say the below is ugly is an understatement. But it works.
1611
       * 
1612
       * @todo Move this crap into a real Record API.
1613
       */
1996.2.1 by Brian Aker
uuid type code.
1614
      string_value= current_field->val_str_internal(string_value,
1615
                                                    old_record + 
1616
                                                    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.
1617
      record->add_key_value(string_value->c_ptr(), string_value->length());
1618
      string_value->free();
1619
    }
1620
1621
  }
1622
}
1623
1795.2.2 by Joseph Daly
add test and add isFieldUpdated function
1624
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.
1625
                                         Table &table,
1795.2.2 by Joseph Daly
add test and add isFieldUpdated function
1626
                                         const unsigned char *old_record,
1627
                                         const unsigned char *new_record)
1628
{
1629
  /*
1630
   * The below really should be moved into the Field API and Record API.  But for now
1631
   * we do this crazy pointer fiddling to figure out if the current field
1632
   * has been updated in the supplied record raw byte pointers.
1633
   */
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1634
  const unsigned char *old_ptr= (const unsigned char *) old_record + (ptrdiff_t) (current_field->ptr - table.getInsertRecord());
1635
  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
1636
1637
  uint32_t field_length= current_field->pack_length(); /** @TODO This isn't always correct...check varchar diffs. */
1638
1639
  bool old_value_is_null= current_field->is_null_in_record(old_record);
1640
  bool new_value_is_null= current_field->is_null_in_record(new_record);
1641
1642
  bool isUpdated= false;
1643
  if (old_value_is_null != new_value_is_null)
1644
  {
1645
    if ((old_value_is_null) && (! new_value_is_null)) /* old value is NULL, new value is non NULL */
1646
    {
1647
      isUpdated= true;
1648
    }
1649
    else if ((! old_value_is_null) && (new_value_is_null)) /* old value is non NULL, new value is NULL */
1650
    {
1651
      isUpdated= true;
1652
    }
1653
  }
1654
1655
  if (! isUpdated)
1656
  {
1657
    if (memcmp(old_ptr, new_ptr, field_length) != 0)
1658
    {
1659
      isUpdated= true;
1660
    }
1661
  }
1662
  return isUpdated;
1663
}  
1664
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
1665
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.
1666
                                                            Table &table,
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1667
                                                            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.
1668
{
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1669
  message::Statement *statement= session.getStatementMessage();
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1670
  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
1671
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.
1672
  /*
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1673
   * If statement is NULL, this is a new statement.
1674
   * If statement is NOT NULL, this a continuation of the same statement.
1675
   * This is because autocommitOrRollback() finalizes the statement so that
1676
   * we guarantee only one Statement message per statement (i.e., we no longer
1677
   * 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.
1678
   */
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1679
  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.
1680
  {
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1681
    transaction= getActiveTransactionMessage(session);
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1682
    
1683
    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
1684
        transaction_message_threshold)
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1685
    {
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1686
      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.
1687
    }
1688
    
1689
    statement= transaction->add_statement();
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1690
    setDeleteHeader(*statement, session, table);
1691
    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.
1692
  }
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1693
  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
1694
  {
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1695
    transaction= getActiveTransactionMessage(session);
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1696
    
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1697
    /*
1698
     * If we've passed our threshold for the statement size (possible for
1699
     * a bulk insert), we'll finalize the Statement and Transaction (doing
1700
     * the Transaction will keep it from getting huge).
1701
     */
1802.14.1 by Joseph Daly
add variable for gpb size
1702
    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
1703
        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
1704
    {
1780.1.1 by David Shrewsbury
Set transaction ID properly on large, multi-Transaction message transactions. Also add bulk load tests.
1705
      /* Remember the transaction ID so we can re-use it */
1706
      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.
1707
      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.
1708
      
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1709
      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.
1710
      
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1711
      /* Caller should use this value when adding a new record */
1712
      *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.
1713
      
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1714
      current_data->set_end_segment(false);
2069.3.1 by David Shrewsbury
Add segment info to Transaction message and re-record tests.
1715
      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.
1716
      
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1717
      /* 
1718
       * Send the trx message to replicators after finalizing the 
1719
       * statement and transaction. This will also set the Transaction
1720
       * and Statement objects in Session to NULL.
1721
       */
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1722
      commitTransactionMessage(session);
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1723
      
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1724
      /*
1725
       * Statement and Transaction should now be NULL, so new ones will get
1726
       * created. We reuse the transaction id since we are segmenting
1727
       * one transaction.
1728
       */
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1729
      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.
1730
      assert(transaction != NULL);
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1731
      
1732
      statement= transaction->add_statement();
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1733
      setDeleteHeader(*statement, session, table);
1734
      session.setStatementMessage(statement);
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1735
      
1780.1.1 by David Shrewsbury
Set transaction ID properly on large, multi-Transaction message transactions. Also add bulk load tests.
1736
      /* Set the transaction ID to match the previous messages */
1737
      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.
1738
      transaction->set_segment_id(seg_id + 1);
1739
      transaction->set_end_segment(true);
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1740
    }
1741
    else
1742
    {
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1743
      /*
1744
       * Continuation of the same statement. Carry forward the existing
1745
       * segment id.
1746
       */
1747
      const message::DeleteData &current_data= statement->delete_data();
1748
      *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
1749
    }
1750
  }
2069.3.3 by David Shrewsbury
Actually use segment info in Transaction message. Cleanup TransactionServices::getXYZStatement() method to a simpler form.
1751
  
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.
1752
  return *statement;
1753
}
1754
1755
void TransactionServices::setDeleteHeader(message::Statement &statement,
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
1756
                                          const Session& session,
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1757
                                          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.
1758
{
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1759
  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.
1760
1761
  /* 
1762
   * Now we construct the specialized DeleteHeader message inside
1763
   * the generalized message::Statement container...
1764
   */
1765
  message::DeleteHeader *header= statement.mutable_delete_header();
1766
  message::TableMetadata *table_metadata= header->mutable_table_metadata();
1767
1336.2.3 by Jay Pipes
Merge trunk and resolve
1768
  string schema_name;
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1769
  (void) table.getShare()->getSchemaName(schema_name);
1336.2.3 by Jay Pipes
Merge trunk and resolve
1770
  string table_name;
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1771
  (void) table.getShare()->getTableName(table_name);
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.
1772
1336.2.3 by Jay Pipes
Merge trunk and resolve
1773
  table_metadata->set_schema_name(schema_name.c_str(), schema_name.length());
1774
  table_metadata->set_table_name(table_name.c_str(), table_name.length());
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.
1775
1776
  Field *current_field;
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1777
  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.
1778
1779
  message::FieldMetadata *field_metadata;
1780
1781
  while ((current_field= *table_fields++) != NULL) 
1782
  {
1783
    /* 
1784
     * Add the WHERE clause values now...for now, this means the
1785
     * primary key field value.  Replication only supports tables
1786
     * with a primary key.
1787
     */
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1788
    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.
1789
    {
1790
      field_metadata= header->add_key_field_metadata();
1791
      field_metadata->set_name(current_field->field_name);
1792
      field_metadata->set_type(message::internalFieldTypeToFieldProtoType(current_field->type()));
1793
    }
1794
  }
1795
}
1796
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
1797
void TransactionServices::deleteRecord(Session& session,
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1798
                                       Table &table,
1799
                                       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.
1800
{
2318.6.73 by Olaf van der Spek
Refactor
1801
  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.
1802
    return;
1803
2187.7.5 by Brian Aker
Merge in modifications such that we check both schema and table for
1804
  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.
1805
    return;
1806
1746.1.1 by David Shrewsbury
Fix uninitialized variable.
1807
  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.
1808
  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.
1809
1810
  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.
1811
  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.
1812
  data->set_end_segment(true);
1813
  message::DeleteRecord *record= data->add_record();
1814
1815
  Field *current_field;
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1816
  Field **table_fields= table.getFields();
1817
  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.
1818
  string_value->set_charset(system_charset_info);
1819
1820
  while ((current_field= *table_fields++) != NULL) 
1821
  {
1667.3.5 by Joe Daly
fix up spacing again
1822
    /* 
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.
1823
     * Add the WHERE clause values now...for now, this means the
1824
     * primary key field value.  Replication only supports tables
1825
     * with a primary key.
1826
     */
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1827
    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.
1828
    {
1730.5.1 by David Shrewsbury
Use the update record, not insert record, when record DELETE operations during REPLACE.
1829
      if (use_update_record)
1830
      {
1831
        /*
1832
         * Temporarily point to the update record to get its value.
1833
         * This is pretty much a hack in order to get the PK value from
1834
         * the update record rather than the insert record. Field::val_str()
1835
         * should not change anything in Field::ptr, so this should be safe.
1836
         * We are careful not to change anything in old_ptr.
1837
         */
1838
        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.
1839
        current_field->ptr= table.getUpdateRecord() + static_cast<ptrdiff_t>(old_ptr - table.getInsertRecord());
1996.2.1 by Brian Aker
uuid type code.
1840
        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.
1841
        current_field->ptr= const_cast<unsigned char *>(old_ptr);
1842
      }
1843
      else
1844
      {
1996.2.1 by Brian Aker
uuid type code.
1845
        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.
1846
        /**
1847
         * @TODO Store optional old record value in the before data member
1848
         */
1849
      }
1667.3.2 by Joe Daly
add a working test case, and more fixes so the test case works
1850
      record->add_key_value(string_value->c_ptr(), string_value->length());
1851
      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.
1852
    }
1853
  }
1854
}
1855
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
1856
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.
1857
                                      const message::Table &table)
1858
{
2318.6.73 by Olaf van der Spek
Refactor
1859
  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.
1860
    return;
2154.3.1 by David Shrewsbury
Add mechanism to have list of schemas that will never reach replication stream.
1861
2187.7.5 by Brian Aker
Merge in modifications such that we check both schema and table for
1862
  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.
1863
    return;
1864
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1865
  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.
1866
  message::Statement *statement= transaction->add_statement();
1867
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1868
  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.
1869
1870
  /* 
1871
   * Construct the specialized CreateTableStatement message and attach
1872
   * it to the generic Statement message
1873
   */
1874
  message::CreateTableStatement *create_table_statement= statement->mutable_create_table_statement();
1875
  message::Table *new_table_message= create_table_statement->mutable_table();
1876
  *new_table_message= table;
1877
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1878
  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.
1879
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1880
  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.
1881
  
2318.6.73 by Olaf van der Spek
Refactor
1882
  (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.
1883
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1884
  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.
1885
1886
}
1887
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
1888
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.
1889
                                       const message::Schema &schema)
1890
{
2318.6.73 by Olaf van der Spek
Refactor
1891
  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.
1892
    return;
2154.3.1 by David Shrewsbury
Add mechanism to have list of schemas that will never reach replication stream.
1893
2187.7.5 by Brian Aker
Merge in modifications such that we check both schema and table for
1894
  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.
1895
    return;
1896
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1897
  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.
1898
  message::Statement *statement= transaction->add_statement();
1899
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1900
  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.
1901
1902
  /* 
1903
   * Construct the specialized CreateSchemaStatement message and attach
1904
   * it to the generic Statement message
1905
   */
1906
  message::CreateSchemaStatement *create_schema_statement= statement->mutable_create_schema_statement();
1907
  message::Schema *new_schema_message= create_schema_statement->mutable_schema();
1908
  *new_schema_message= schema;
1909
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1910
  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.
1911
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1912
  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.
1913
  
2318.6.73 by Olaf van der Spek
Refactor
1914
  (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.
1915
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1916
  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.
1917
1918
}
1919
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
1920
void TransactionServices::dropSchema(Session& session,
2246.4.9 by Olaf van der Spek
Remove const_reference and reference from identifier::Schema
1921
                                     const identifier::Schema& identifier,
2172.3.1 by Brian Aker
Merge in my patch for having some schema/table not replicated.
1922
                                     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.
1923
{
2318.6.73 by Olaf van der Spek
Refactor
1924
  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.
1925
    return;
2154.3.1 by David Shrewsbury
Add mechanism to have list of schemas that will never reach replication stream.
1926
2187.7.5 by Brian Aker
Merge in modifications such that we check both schema and table for
1927
  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.
1928
    return;
1929
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1930
  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.
1931
  message::Statement *statement= transaction->add_statement();
1932
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1933
  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.
1934
1935
  /* 
1936
   * Construct the specialized DropSchemaStatement message and attach
1937
   * it to the generic Statement message
1938
   */
1939
  message::DropSchemaStatement *drop_schema_statement= statement->mutable_drop_schema_statement();
1940
2052 by Brian Aker
Fix additional member of trans services to handle identifier.
1941
  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.
1942
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1943
  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.
1944
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1945
  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.
1946
  
2318.6.73 by Olaf van der Spek
Refactor
1947
  (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.
1948
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1949
  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.
1950
}
1951
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
1952
void TransactionServices::alterSchema(Session& session,
2159.2.6 by Brian Aker
Finalize interface for schema.
1953
                                      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.
1954
                                      const message::Schema &new_schema)
1955
{
2318.6.73 by Olaf van der Spek
Refactor
1956
  if (! ReplicationServices::isActive())
2078.1.1 by David Shrewsbury
Push ALTER SCHEMA through replication stream as proper GPB message instead of RAW_SQL.
1957
    return;
2154.3.1 by David Shrewsbury
Add mechanism to have list of schemas that will never reach replication stream.
1958
2187.7.5 by Brian Aker
Merge in modifications such that we check both schema and table for
1959
  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.
1960
    return;
1961
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1962
  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.
1963
  message::Statement *statement= transaction->add_statement();
1964
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1965
  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.
1966
1967
  /* 
1968
   * Construct the specialized AlterSchemaStatement message and attach
1969
   * it to the generic Statement message
1970
   */
1971
  message::AlterSchemaStatement *alter_schema_statement= statement->mutable_alter_schema_statement();
1972
1973
  message::Schema *before= alter_schema_statement->mutable_before();
1974
  message::Schema *after= alter_schema_statement->mutable_after();
1975
2159.2.6 by Brian Aker
Finalize interface for schema.
1976
  *before= old_schema;
2078.1.1 by David Shrewsbury
Push ALTER SCHEMA through replication stream as proper GPB message instead of RAW_SQL.
1977
  *after= new_schema;
1978
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1979
  finalizeStatementMessage(*statement, session);
2078.1.1 by David Shrewsbury
Push ALTER SCHEMA through replication stream as proper GPB message instead of RAW_SQL.
1980
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1981
  finalizeTransactionMessage(*transaction, session);
2078.1.1 by David Shrewsbury
Push ALTER SCHEMA through replication stream as proper GPB message instead of RAW_SQL.
1982
  
2318.6.73 by Olaf van der Spek
Refactor
1983
  (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.
1984
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1985
  cleanupTransactionMessage(transaction, session);
2078.1.1 by David Shrewsbury
Push ALTER SCHEMA through replication stream as proper GPB message instead of RAW_SQL.
1986
}
1987
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
1988
void TransactionServices::dropTable(Session& session,
2246.4.10 by Olaf van der Spek
Remove const_reference and reference from identifier::Table
1989
                                    const identifier::Table& identifier,
2168.3.2 by Brian Aker
CREATE TABLE/SCHEMA now allow you to add REPLICATION to the list of items
1990
                                    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.
1991
                                    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.
1992
{
2318.6.73 by Olaf van der Spek
Refactor
1993
  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.
1994
    return;
2154.3.1 by David Shrewsbury
Add mechanism to have list of schemas that will never reach replication stream.
1995
2187.7.5 by Brian Aker
Merge in modifications such that we check both schema and table for
1996
  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.
1997
    return;
1998
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
1999
  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.
2000
  message::Statement *statement= transaction->add_statement();
2001
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
2002
  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.
2003
2004
  /* 
2005
   * Construct the specialized DropTableStatement message and attach
2006
   * it to the generic Statement message
2007
   */
2008
  message::DropTableStatement *drop_table_statement= statement->mutable_drop_table_statement();
2009
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.
2010
  drop_table_statement->set_if_exists_clause(if_exists);
2011
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.
2012
  message::TableMetadata *table_metadata= drop_table_statement->mutable_table_metadata();
2013
2168.3.2 by Brian Aker
CREATE TABLE/SCHEMA now allow you to add REPLICATION to the list of items
2014
  table_metadata->set_schema_name(identifier.getSchemaName());
2015
  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.
2016
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
2017
  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.
2018
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
2019
  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.
2020
  
2318.6.73 by Olaf van der Spek
Refactor
2021
  (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.
2022
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
2023
  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.
2024
}
2025
2318.6.61 by Olaf van der Spek
Refactor
2026
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.
2027
{
2318.6.73 by Olaf van der Spek
Refactor
2028
  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.
2029
    return;
2154.3.1 by David Shrewsbury
Add mechanism to have list of schemas that will never reach replication stream.
2030
2187.7.5 by Brian Aker
Merge in modifications such that we check both schema and table for
2031
  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.
2032
    return;
2033
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
2034
  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.
2035
  message::Statement *statement= transaction->add_statement();
2036
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
2037
  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.
2038
2039
  /* 
2040
   * Construct the specialized TruncateTableStatement message and attach
2041
   * it to the generic Statement message
2042
   */
2043
  message::TruncateTableStatement *truncate_statement= statement->mutable_truncate_table_statement();
2044
  message::TableMetadata *table_metadata= truncate_statement->mutable_table_metadata();
2045
1336.2.3 by Jay Pipes
Merge trunk and resolve
2046
  string schema_name;
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
2047
  (void) table.getShare()->getSchemaName(schema_name);
2168.3.2 by Brian Aker
CREATE TABLE/SCHEMA now allow you to add REPLICATION to the list of items
2048
1336.2.3 by Jay Pipes
Merge trunk and resolve
2049
  string table_name;
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
2050
  (void) table.getShare()->getTableName(table_name);
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.
2051
1336.2.3 by Jay Pipes
Merge trunk and resolve
2052
  table_metadata->set_schema_name(schema_name.c_str(), schema_name.length());
2053
  table_metadata->set_table_name(table_name.c_str(), table_name.length());
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.
2054
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
2055
  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.
2056
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
2057
  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.
2058
  
2318.6.73 by Olaf van der Spek
Refactor
2059
  (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.
2060
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
2061
  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.
2062
}
2063
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
2064
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.
2065
                                       const string &query,
2066
                                       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.
2067
{
2318.6.73 by Olaf van der Spek
Refactor
2068
  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.
2069
    return;
1926.3.1 by Joseph Daly
merge changes to fix duplicate trx ids for raw sql 674588
2070
 
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
2071
  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.
2072
  message::Statement *statement= transaction->add_statement();
2073
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
2074
  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.
2075
  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.
2076
  if (not schema.empty())
2077
    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.
2078
  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.
2079
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
2080
  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.
2081
  
2318.6.73 by Olaf van der Spek
Refactor
2082
  (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.
2083
2096.2.1 by David Shrewsbury
Initial change to use references to Session in TransactionServices methods rather than pointers.
2084
  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.
2085
}
2086
2302.1.4 by Olaf van der Spek
Refactor
2087
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.
2088
{
2318.6.73 by Olaf van der Spek
Refactor
2089
  if (not ReplicationServices::isActive())
1819.4.1 by David Shrewsbury
Add server startup and shutdown events to the replication stream.
2090
    return 0;
2302.1.4 by Olaf van der Spek
Refactor
2091
  message::Transaction transaction;
1819.4.1 by David Shrewsbury
Add server startup and shutdown events to the replication stream.
2092
2093
  // set server id, start timestamp
2302.1.4 by Olaf van der Spek
Refactor
2094
  initTransactionMessage(transaction, session, true);
1819.4.1 by David Shrewsbury
Add server startup and shutdown events to the replication stream.
2095
2096
  // set end timestamp
2302.1.4 by Olaf van der Spek
Refactor
2097
  finalizeTransactionMessage(transaction, session);
2098
2099
  message::Event *trx_event= transaction.mutable_event();
1819.4.1 by David Shrewsbury
Add server startup and shutdown events to the replication stream.
2100
  trx_event->CopyFrom(event);
2318.6.73 by Olaf van der Spek
Refactor
2101
  plugin::ReplicationReturnCode result= ReplicationServices::pushTransactionMessage(session, transaction);
2302.1.4 by Olaf van der Spek
Refactor
2102
  return result;
1819.4.1 by David Shrewsbury
Add server startup and shutdown events to the replication stream.
2103
}
2104
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
2105
bool TransactionServices::sendStartupEvent(Session& session)
1819.4.1 by David Shrewsbury
Add server startup and shutdown events to the replication stream.
2106
{
2107
  message::Event event;
2108
  event.set_type(message::Event::STARTUP);
2302.1.4 by Olaf van der Spek
Refactor
2109
  return not sendEvent(session, event);
1819.4.1 by David Shrewsbury
Add server startup and shutdown events to the replication stream.
2110
}
2111
2246.4.11 by Olaf van der Spek
Remove const_reference and reference from identifier::User
2112
bool TransactionServices::sendShutdownEvent(Session& session)
1819.4.1 by David Shrewsbury
Add server startup and shutdown events to the replication stream.
2113
{
2114
  message::Event event;
2115
  event.set_type(message::Event::SHUTDOWN);
2302.1.4 by Olaf van der Spek
Refactor
2116
  return not sendEvent(session, event);
1819.4.1 by David Shrewsbury
Add server startup and shutdown events to the replication stream.
2117
}
2118
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
2119
} /* namespace drizzled */