17
17
18
18
package com .mysql .clusterj .jdbc ;
19
19
20
+ import com .mysql .clusterj .ClusterJFatalInternalException ;
20
21
import com .mysql .clusterj .ClusterJHelper ;
21
22
import com .mysql .clusterj .ClusterJUserException ;
23
+ import com .mysql .clusterj .LockMode ;
22
24
import com .mysql .clusterj .SessionFactory ;
23
25
import com .mysql .clusterj .core .query .QueryDomainTypeImpl ;
24
26
import com .mysql .clusterj .core .spi .SessionSPI ;
28
30
import com .mysql .clusterj .core .util .LoggerFactoryService ;
29
31
import com .mysql .jdbc .Connection ;
30
32
import com .mysql .jdbc .ResultSetInternalMethods ;
33
+ import com .mysql .jdbc .ServerPreparedStatement ;
31
34
import com .mysql .jdbc .Statement ;
35
+ import com .mysql .jdbc .ServerPreparedStatement .BatchedBindValues ;
36
+ import com .mysql .jdbc .ServerPreparedStatement .BindValue ;
32
37
import com .mysql .clusterj .jdbc .antlr .ANTLRNoCaseStringStream ;
33
38
import com .mysql .clusterj .jdbc .antlr .MySQL51Parser ;
34
39
import com .mysql .clusterj .jdbc .antlr .MySQL51Lexer ;
40
45
import com .mysql .clusterj .query .Predicate ;
41
46
42
47
import com .mysql .clusterj .jdbc .SQLExecutor .Executor ;
48
+
49
+ import java .io .InputStream ;
43
50
import java .sql .SQLException ;
44
51
import java .sql .Savepoint ;
45
52
import java .util .ArrayList ;
@@ -244,29 +251,45 @@ public ResultSetInternalMethods postProcess(String sql, Statement statement,
244
251
public ResultSetInternalMethods preProcess (String sql , Statement statement ,
245
252
Connection connection ) throws SQLException {
246
253
assertReady ();
254
+ if (logger .isDebugEnabled () && statement != null )
255
+ logger .debug (statement .getClass ().getName () + ": " + sql );
247
256
if (statement instanceof com .mysql .jdbc .PreparedStatement ) {
248
257
com .mysql .jdbc .PreparedStatement preparedStatement =
249
258
(com .mysql .jdbc .PreparedStatement )statement ;
250
259
// key must be interned because we are using IdentityHashMap
251
- String preparedSql = preparedStatement .getPreparedSql ().intern ();
260
+ // TODO: in case of DELETE, the SQL has already been rewritten at this point,
261
+ // and the original SQL is gone
262
+ // so the key in the table is the rewritten DELETE SQL -- not what we want at all
263
+ String nonRewrittenSql = preparedStatement .getNonRewrittenSql ();
264
+ String internedSql = nonRewrittenSql .intern ();
265
+
252
266
// see if we have a parsed version of this query
253
267
Executor sQLExecutor = null ;
254
268
synchronized (parsedSqlMap ) {
255
- sQLExecutor = parsedSqlMap .get (preparedSql );
269
+ sQLExecutor = parsedSqlMap .get (internedSql );
256
270
}
257
271
// if no cached SQLExecutor, create it, which might take some time
258
272
if (sQLExecutor == null ) {
259
- sQLExecutor = createSQLExecutor (preparedSql );
273
+ sQLExecutor = createSQLExecutor (internedSql );
260
274
if (sQLExecutor != null ) {
261
275
// multiple thread might have created a SQLExecutor but it's ok
262
276
synchronized (parsedSqlMap ) {
263
- parsedSqlMap .put (preparedSql , sQLExecutor );
277
+ parsedSqlMap .put (internedSql , sQLExecutor );
264
278
}
265
279
}
266
280
}
267
- return sQLExecutor .execute (this , preparedStatement .getParameterBindings ());
281
+ try {
282
+ return sQLExecutor .execute (this , preparedStatement );
283
+ } catch (Throwable t ) {
284
+ t .printStackTrace ();
285
+ return null ;
286
+ }
287
+ } else {
288
+ if (logger .isDebugEnabled () && statement != null )
289
+ logger .debug (statement .getClass ().getName () + " is not instanceof com.mysql.jdbc.PreparedStatement" );
290
+ // not a prepared statement; won't execute this
291
+ return null ;
268
292
}
269
- return null ;
270
293
}
271
294
272
295
/**
@@ -323,6 +346,14 @@ private Executor createSQLExecutor(String preparedSql) {
323
346
result = new SQLExecutor .Noop ();
324
347
break ;
325
348
}
349
+ boolean forUpdate = null != (CommonTree )root .getFirstChildWithType (MySQL51Parser .FOR );
350
+ boolean lockShared = null != (CommonTree )root .getFirstChildWithType (MySQL51Parser .LOCK );
351
+ LockMode lockMode = LockMode .READ_COMMITTED ;
352
+ if (forUpdate ) {
353
+ lockMode = LockMode .EXCLUSIVE ;
354
+ } else if (lockShared ) {
355
+ lockMode = LockMode .SHARED ;
356
+ }
326
357
getSession ();
327
358
dictionary = session .getDictionary ();
328
359
domainTypeHandler = getDomainTypeHandler (tableName , dictionary );
@@ -343,14 +374,15 @@ private Executor createSQLExecutor(String preparedSql) {
343
374
queryDomainType = (QueryDomainTypeImpl <?>) session .createQueryDomainType (domainTypeHandler );
344
375
if (whereNode == null ) {
345
376
// no where clause (select all rows)
346
- result = new SQLExecutor .Select (domainTypeHandler , columnNames , queryDomainType );
377
+ result = new SQLExecutor .Select (domainTypeHandler , columnNames , queryDomainType , lockMode );
347
378
} else {
348
379
// create a predicate from the tree
349
380
Predicate predicate = whereNode .getPredicate (queryDomainType );
350
381
if (predicate != null ) {
351
382
// where clause that can be executed by clusterj
352
383
queryDomainType .where (predicate );
353
- result = new SQLExecutor .Select (domainTypeHandler , columnNames , queryDomainType );
384
+ int numberOfParameters = whereNode .getNumberOfParameters ();
385
+ result = new SQLExecutor .Select (domainTypeHandler , columnNames , queryDomainType , lockMode , numberOfParameters );
354
386
whereType = "clusterj" ;
355
387
} else {
356
388
// where clause that cannot be executed by clusterj
@@ -461,7 +493,7 @@ private CommonTree parse(String preparedSql) {
461
493
lexer .setErrorListener (new QueuingErrorListener (lexer ));
462
494
tokens .getTokens ();
463
495
if (lexer .getErrorListener ().hasErrors ()) {
464
- logger .warn (local .message ("ERR_Lexing_SQ " ,preparedSql ));
496
+ logger .warn (local .message ("ERR_Lexing_SQL " ,preparedSql ));
465
497
return result ;
466
498
}
467
499
PlaceholderNode .resetId ();
0 commit comments