From 087ac651ba8360d7f9566430bade9b1a4eed6297 Mon Sep 17 00:00:00 2001 From: abomb4 Date: Sun, 19 Jun 2022 18:42:55 +0800 Subject: [PATCH 1/7] =?UTF-8?q?=E5=9C=A8=20DB2=20=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=20INTERVAL=20=E8=A1=A8=E8=BE=BE=E5=BC=8F=E8=BE=93?= =?UTF-8?q?=E5=87=BA=E6=97=B6=EF=BC=8C=E5=B0=86=20VALUE=20=E7=94=A8?= =?UTF-8?q?=E6=8B=AC=E5=8F=B7=E5=8C=85=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dialect/db2/visitor/DB2OutputVisitor.java | 2 + .../db2/visitor/DB2OutputVisitorTest.java | 59 +++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 src/test/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2OutputVisitorTest.java diff --git a/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2OutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2OutputVisitor.java index 1ab61522cf..7c4f370fa7 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2OutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2OutputVisitor.java @@ -153,7 +153,9 @@ public class DB2OutputVisitor extends SQLASTOutputVisitor implements DB2ASTVisit public boolean visit(SQLIntervalExpr x) { SQLExpr value = x.getValue(); + print('('); value.accept(this); + print(')'); SQLIntervalUnit unit = x.getUnit(); if (unit != null) { diff --git a/src/test/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2OutputVisitorTest.java b/src/test/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2OutputVisitorTest.java new file mode 100644 index 0000000000..4bc7833c59 --- /dev/null +++ b/src/test/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2OutputVisitorTest.java @@ -0,0 +1,59 @@ +package com.alibaba.druid.sql.dialect.db2.visitor; + +import com.alibaba.druid.DbType; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.parser.SQLParserUtils; +import com.alibaba.druid.sql.parser.SQLStatementParser; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Arrays; +import java.util.List; + +/** + * @author abomb4 2022-06-19 + */ +public class DB2OutputVisitorTest { + + @Test + public void test() { + + List testCases = Arrays.asList( + new TestCase("interval 表达式应该带括号 select", + "SELECT A, B, C FROM D WHERE C < CURRENT TIMESTAMP + (10 * 60) SECONDS", + "SELECT A, B, C FROM D WHERE C < CURRENT TIMESTAMP + (10 * 60) SECONDS"), + new TestCase("interval 表达式应该带括号 insert", + "INSERT INTO TEST VALUES (1, CURRENT TIMESTAMP + ((10 + 60) SECONDS))", + "INSERT INTO TEST VALUES (1, CURRENT TIMESTAMP + (10 + 60) SECONDS)"), + new TestCase("interval 表达式应该带括号 update", + "UPDATE test SET created = CURRENT TIMESTAMP + 10 SECONDS WHERE created < CURRENT TIMESTAMP + (10 * 60) SECONDS", + "UPDATE test SET created = CURRENT TIMESTAMP + (10) SECONDS WHERE created < CURRENT TIMESTAMP + (10 * 60) SECONDS") + ); + + for (TestCase testCase : testCases) { + SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(testCase.origin, DbType.db2); + StringBuilder builder = new StringBuilder(); + DB2OutputVisitor visitor = new DB2OutputVisitor(builder); + visitor.setUppCase(false); + visitor.setPrettyFormat(false); + visitor.setParameterized(false); + SQLStatement stmt = parser.parseStatement(); + stmt.accept(visitor); + String result = builder.toString(); + Assert.assertEquals(testCase.name, testCase.expected, result); + } + System.out.println("DB2 Interval test ok."); + } + + private static class TestCase { + String name; + String origin; + String expected; + + public TestCase(String name, String origin, String expected) { + this.name = name; + this.origin = origin; + this.expected = expected; + } + } +} From af2d60c844a4969e9401aa439cf3b13ba2083298 Mon Sep 17 00:00:00 2001 From: kanlon Date: Thu, 28 Jul 2022 23:03:49 +0800 Subject: [PATCH 2/7] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E8=A7=A3=E6=9E=90?= =?UTF-8?q?sql=E6=9D=A1=E4=BB=B6=E4=B8=BAglobal=20in=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=EF=BC=8C=E8=A1=A5=E5=85=85Clickhouse=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E6=95=B0=E6=8D=AE=E5=BA=93=E7=B1=BB=E5=9E=8B=E7=9A=84?= =?UTF-8?q?=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/alibaba/druid/sql/parser/SQLParserUtils.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLParserUtils.java b/src/main/java/com/alibaba/druid/sql/parser/SQLParserUtils.java index 4aa671aa98..a56ccbbb17 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLParserUtils.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLParserUtils.java @@ -26,6 +26,8 @@ import com.alibaba.druid.sql.dialect.ads.parser.AdsStatementParser; import com.alibaba.druid.sql.dialect.antspark.parser.AntsparkLexer; import com.alibaba.druid.sql.dialect.antspark.parser.AntsparkStatementParser; import com.alibaba.druid.sql.dialect.blink.parser.BlinkStatementParser; +import com.alibaba.druid.sql.dialect.clickhouse.parser.ClickhouseExprParser; +import com.alibaba.druid.sql.dialect.clickhouse.parser.ClickhouseLexer; import com.alibaba.druid.sql.dialect.clickhouse.parser.ClickhouseStatementParser; import com.alibaba.druid.sql.dialect.db2.ast.stmt.DB2SelectQueryBlock; import com.alibaba.druid.sql.dialect.db2.parser.DB2ExprParser; @@ -180,6 +182,8 @@ public class SQLParserUtils { return new PrestoExprParser(sql, features); case hive: return new HiveExprParser(sql, features); + case clickhouse: + return new ClickhouseExprParser(sql, features); default: return new SQLExprParser(sql, dbType, features); } @@ -221,6 +225,8 @@ public class SQLParserUtils { return new PrestoLexer(sql); case antspark: return new AntsparkLexer(sql); + case clickhouse: + return new ClickhouseLexer(sql); default: return new Lexer(sql, null, dbType); } @@ -735,6 +741,9 @@ public class SQLParserUtils { case mysql: exprParser = new MySqlExprParser(lexer); break; + case clickhouse: + exprParser = new ClickhouseExprParser(lexer); + break; default: exprParser = new SQLExprParser(lexer); break; From 7e6857313b0994a5020246a11c10867c19308018 Mon Sep 17 00:00:00 2001 From: "shaojin.wensj" Date: Wed, 10 Aug 2022 10:56:13 +0800 Subject: [PATCH 3/7] improved opds sql support --- src/main/java/com/alibaba/druid/sql/parser/Lexer.java | 4 ++-- .../com/alibaba/druid/sql/parser/SQLParserUtils.java | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/alibaba/druid/sql/parser/Lexer.java b/src/main/java/com/alibaba/druid/sql/parser/Lexer.java index 8505a8b395..98728455ae 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/Lexer.java +++ b/src/main/java/com/alibaba/druid/sql/parser/Lexer.java @@ -2255,7 +2255,7 @@ public class Lexer { boolean ident = false; for (; ; ) { ch = charAt(++pos); - if (isEOF()) { + if (isEOF() || ch == ';' || ch == ';') { pos--; bufPos--; break; @@ -2287,7 +2287,7 @@ public class Lexer { this.ch = charAt(pos); if (dbType == DbType.odps) { - while (isIdentifierChar(this.ch)) { + while (isIdentifierChar(this.ch) && ch != ';') { ++pos; bufPos++; this.ch = charAt(pos); diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLParserUtils.java b/src/main/java/com/alibaba/druid/sql/parser/SQLParserUtils.java index 4aa671aa98..0c7e7b5d88 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLParserUtils.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLParserUtils.java @@ -517,6 +517,17 @@ public class SQLParserUtils { if (lexer.identifierEquals("pai") || lexer.identifierEquals("jar")) { return Collections.singletonList(sql); } + + if (dbType == DbType.odps) { + switch (lexer.token) { + case IF: + case VARIANT: + case WHILE: + return Collections.singletonList(sql); + default: + break; + } + } } List list = new ArrayList(); From 8fc230d3234950af44fc291b8421764ffa0372c6 Mon Sep 17 00:00:00 2001 From: "shaojin.wensj" Date: Thu, 11 Aug 2022 19:29:16 +0800 Subject: [PATCH 4/7] SQLUtils add callback function acceptBinaryOpExpr --- .../java/com/alibaba/druid/sql/SQLUtils.java | 57 +++++++++++++++++-- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/alibaba/druid/sql/SQLUtils.java b/src/main/java/com/alibaba/druid/sql/SQLUtils.java index 0430067468..9374c41a16 100644 --- a/src/main/java/com/alibaba/druid/sql/SQLUtils.java +++ b/src/main/java/com/alibaba/druid/sql/SQLUtils.java @@ -36,6 +36,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlSelectIntoStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement; import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlOutputVisitor; import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor; +import com.alibaba.druid.sql.dialect.odps.visitor.OdpsASTVisitorAdapter; import com.alibaba.druid.sql.dialect.odps.visitor.OdpsOutputVisitor; import com.alibaba.druid.sql.dialect.odps.visitor.OdpsSchemaStatVisitor; import com.alibaba.druid.sql.dialect.oracle.visitor.OracleOutputVisitor; @@ -48,10 +49,7 @@ import com.alibaba.druid.sql.dialect.sqlserver.visitor.SQLServerOutputVisitor; import com.alibaba.druid.sql.dialect.sqlserver.visitor.SQLServerSchemaStatVisitor; import com.alibaba.druid.sql.parser.*; import com.alibaba.druid.sql.repository.SchemaRepository; -import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor; -import com.alibaba.druid.sql.visitor.SQLASTVisitorAdapter; -import com.alibaba.druid.sql.visitor.SchemaStatVisitor; -import com.alibaba.druid.sql.visitor.VisitorFeature; +import com.alibaba.druid.sql.visitor.*; import com.alibaba.druid.support.logging.Log; import com.alibaba.druid.support.logging.LogFactory; import com.alibaba.druid.util.*; @@ -62,6 +60,8 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.TimeZone; +import java.util.function.Consumer; +import java.util.function.Predicate; public class SQLUtils { public static final Charset UTF8 = Charset.forName("UTF-8"); @@ -792,6 +792,55 @@ public class SQLUtils { return addSelectItem(selectSql, expr, alias, false, dbType); } + public static void acceptBooleanOr(String sql, DbType dbType, Consumer consumer) { + acceptBinaryOpExpr(sql, dbType, consumer, e -> e.getOperator() == SQLBinaryOperator.BooleanOr); + } + + public static void acceptBinaryOpExpr(String sql, DbType dbType, Consumer consumer, Predicate filter) { + if (sql == null || sql.isEmpty()) { + return; + } + + List stmtList = new ArrayList<>(); + + try { + SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType, SQLParserFeature.EnableMultiUnion, SQLParserFeature.KeepComments, SQLParserFeature.EnableSQLBinaryOpExprGroup); + parser.parseStatementList(stmtList, -1, null); + } catch (Exception ignored) { + return; + } + + SQLASTVisitor visitor; + switch (dbType) { + case odps: + visitor = new OdpsASTVisitorAdapter() { + @Override + public boolean visit(SQLBinaryOpExprGroup x) { + if (filter == null || filter.test(x)) { + consumer.accept(x); + } + return super.visit(x); + } + }; + break; + default: + visitor = new SQLASTVisitorAdapter() { + @Override + public boolean visit(SQLBinaryOpExprGroup x) { + if (filter == null || filter.test(x)) { + consumer.accept(x); + } + return super.visit(x); + } + }; + break; + } + + for (SQLStatement stmt : stmtList) { + stmt.accept(visitor); + } + } + public static String addSelectItem(String selectSql, String expr, String alias, boolean first, DbType dbType) { List stmtList = parseStatements(selectSql, dbType); From 3d777c0b76e9a14b5e91fe034ab21f51422c35c0 Mon Sep 17 00:00:00 2001 From: "shaojin.wensj" Date: Mon, 22 Aug 2022 16:28:19 +0800 Subject: [PATCH 5/7] bug fix for db2 sql output --- .../sql/dialect/db2/visitor/DB2OutputVisitor.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2OutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2OutputVisitor.java index 7c4f370fa7..61aa313244 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2OutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2OutputVisitor.java @@ -19,9 +19,7 @@ import com.alibaba.druid.DbType; import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.ast.SQLPartitionBy; -import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator; -import com.alibaba.druid.sql.ast.expr.SQLIntervalExpr; -import com.alibaba.druid.sql.ast.expr.SQLIntervalUnit; +import com.alibaba.druid.sql.ast.expr.*; import com.alibaba.druid.sql.ast.statement.SQLAlterTableAddColumn; import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; @@ -153,9 +151,13 @@ public class DB2OutputVisitor extends SQLASTOutputVisitor implements DB2ASTVisit public boolean visit(SQLIntervalExpr x) { SQLExpr value = x.getValue(); - print('('); - value.accept(this); - print(')'); + if (value instanceof SQLLiteralExpr || value instanceof SQLName || value instanceof SQLVariantRefExpr) { + value.accept(this); + } else { + print('('); + value.accept(this); + print(')'); + } SQLIntervalUnit unit = x.getUnit(); if (unit != null) { From f183c10e3009fc6f8b1c6dd5e587aeec18d60bc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BD=97=E5=8B=87?= Date: Sat, 9 Jul 2022 08:09:43 +0800 Subject: [PATCH 6/7] =?UTF-8?q?=E4=BB=8Eurl=E5=88=A4=E6=96=AD=E5=8D=8E?= =?UTF-8?q?=E4=B8=BAgaussdb=E7=B1=BB=E5=88=AB=EF=BC=8C=E5=88=A4=E6=96=AD?= =?UTF-8?q?=E6=9D=A1=E4=BB=B6=E4=BB=8E=E5=8D=8E=E4=B8=BA=E5=AE=98=E6=96=B9?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E8=8E=B7=E5=BE=97=EF=BC=8C=E4=B9=9F=E5=9C=A8?= =?UTF-8?q?=E5=AE=9E=E9=99=85=E4=BD=BF=E7=94=A8=E4=B8=AD=E7=94=A8=E8=BF=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/alibaba/druid/util/JdbcUtils.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/alibaba/druid/util/JdbcUtils.java b/src/main/java/com/alibaba/druid/util/JdbcUtils.java index 72cb6e9715..61d61b3cfb 100644 --- a/src/main/java/com/alibaba/druid/util/JdbcUtils.java +++ b/src/main/java/com/alibaba/druid/util/JdbcUtils.java @@ -637,6 +637,8 @@ public final class JdbcUtils implements JdbcConstants { return DbType.highgo; } else if (rawUrl.startsWith("jdbc:pivotal:greenplum:") || rawUrl.startsWith("jdbc:datadirect:greenplum:")) { return DbType.greenplum; + } else if (rawUrl.startsWith("jdbc:gaussdb:") || rawUrl.startsWith("jdbc:dws:iam:")) { + return DbType.gaussdb; } else { return null; } From 8b682090324adf5b8e2ab0d10cd647e54dcee85a Mon Sep 17 00:00:00 2001 From: "shaojin.wensj" Date: Sat, 27 Aug 2022 18:47:57 +0800 Subject: [PATCH 7/7] DruidDataSource support config connectTimeout & socketTimeout --- .../alibaba/druid/mock/MockConnection.java | 5 +- .../druid/pool/DruidAbstractDataSource.java | 80 ++++++++++++++++++- .../alibaba/druid/pool/DruidDataSource.java | 6 +- 3 files changed, 86 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/alibaba/druid/mock/MockConnection.java b/src/main/java/com/alibaba/druid/mock/MockConnection.java index 9c8f655a27..fbd2bb2b4e 100644 --- a/src/main/java/com/alibaba/druid/mock/MockConnection.java +++ b/src/main/java/com/alibaba/druid/mock/MockConnection.java @@ -37,6 +37,7 @@ public class MockConnection extends ConnectionBase implements Connection { private final long createdTimeMillis = System.currentTimeMillis(); private long lastActiveTimeMillis = System.currentTimeMillis(); + private int networkTimeout; private SQLException error; @@ -455,11 +456,11 @@ public class MockConnection extends ConnectionBase implements Connection { } public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException { - throw new SQLFeatureNotSupportedException(); + this.networkTimeout = milliseconds; } public int getNetworkTimeout() throws SQLException { - throw new SQLFeatureNotSupportedException(); + return networkTimeout; } @Override diff --git a/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java index 6cde51a8bd..43c075b498 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java +++ b/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java @@ -43,6 +43,7 @@ import java.io.Serializable; import java.sql.*; import java.util.*; import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.Executor; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; import java.util.concurrent.atomic.AtomicLongFieldUpdater; @@ -70,6 +71,8 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements public static final long DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS = 60 * 1000L; public static final long DEFAULT_TIME_BETWEEN_CONNECT_ERROR_MILLIS = 500; public static final int DEFAULT_NUM_TESTS_PER_EVICTION_RUN = 3; + public static final int DEFAULT_TIME_CONNECT_TIMEOUT_MILLIS = 10_000; + public static final int DEFAULT_TIME_SOCKET_TIMEOUT_MILLIS = 10_000; public static final long DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS = 1000L * 60L * 30L; public static final long DEFAULT_MAX_EVICTABLE_IDLE_TIME_MILLIS = 1000L * 60L * 60L * 7; @@ -119,8 +122,11 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements protected Driver driver; - protected volatile int queryTimeout; - protected volatile int transactionQueryTimeout; + protected volatile int connectTimeout = DEFAULT_TIME_CONNECT_TIMEOUT_MILLIS; // milliSeconds + protected volatile int socketTimeout = DEFAULT_TIME_SOCKET_TIMEOUT_MILLIS; // milliSeconds + + protected volatile int queryTimeout; // seconds + protected volatile int transactionQueryTimeout; // seconds protected long createTimespan; @@ -251,6 +257,8 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements protected volatile long failContinuousTimeMillis; protected ScheduledExecutorService destroyScheduler; protected ScheduledExecutorService createScheduler; + protected Executor netTimeoutExecutor; + protected volatile boolean netTimeoutError; static final AtomicLongFieldUpdater failContinuousTimeMillisUpdater = AtomicLongFieldUpdater.newUpdater(DruidAbstractDataSource.class, "failContinuousTimeMillis"); static final AtomicIntegerFieldUpdater failContinuousUpdater = AtomicIntegerFieldUpdater.newUpdater(DruidAbstractDataSource.class, "failContinuous"); @@ -995,6 +1003,38 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements this.queryTimeout = seconds; } + /** + * + * @since 1.2.12 + */ + public int getConnectTimeout() { + return connectTimeout; + } + + /** + * + * @since 1.2.12 + */ + public void setConnectTimeout(int milliSeconds) { + this.connectTimeout = milliSeconds; + } + + /** + * + * @since 1.2.12 + */ + public int getSocketTimeout() { + return socketTimeout; + } + + /** + * + * @since 1.2.12 + */ + public void setSocketTimeout(int milliSeconds) { + this.socketTimeout = milliSeconds; + } + public String getName() { if (name != null) { return name; @@ -1691,6 +1731,17 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements physicalConnectProperties.put("password", password); } + if (connectTimeout > 0) { + if (isMySql) { + physicalConnectProperties.put("connectTimeout", connectTimeout); + } else if (isOracle) { + physicalConnectProperties.put("oracle.net.CONNECT_TIMEOUT", connectTimeout); + } else if (driver != null && "org.postgresql.Driver".equals(driver.getClass().getName())) { + physicalConnectProperties.put("loginTimeout", connectTimeout); + physicalConnectProperties.put("socketTimeout", connectTimeout); + } + } + Connection conn = null; long connectStartNanos = System.nanoTime(); @@ -1716,6 +1767,16 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements initPhysicalConnection(conn, variables, globalVariables); initedNanos = System.nanoTime(); + if (socketTimeout > 0 && !netTimeoutError) { + try { + conn.setNetworkTimeout(netTimeoutExecutor, socketTimeout); + } catch (SQLFeatureNotSupportedException | AbstractMethodError e) { + netTimeoutError = true; + } catch (Exception ignored) { + // ignored + } + } + validateConnection(conn); validatedNanos = System.nanoTime(); @@ -2225,4 +2286,19 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements return globalVairiables; } } + + class SynchronousExecutor implements Executor { + @Override + public void execute(Runnable command) { + try { + command.run(); + } catch (AbstractMethodError error) { + netTimeoutError = true; + } catch (Exception ignored) { + if (LOG.isDebugEnabled()) { + LOG.debug("failed to execute command " + command); + } + } + } + } } diff --git a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java index 4eb62baf21..ce54dad024 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java +++ b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java @@ -866,6 +866,8 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat initCheck(); + this.netTimeoutExecutor = new SynchronousExecutor(); + initExceptionSorter(); initValidConnectionChecker(); validationQueryCheck(); @@ -1221,7 +1223,9 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat } else if (dbType == DbType.db2) { db2ValidationQueryCheck(); } else if (dbType == DbType.mysql - || JdbcUtils.MYSQL_DRIVER_6.equals(this.driverClass)) { + || JdbcUtils.MYSQL_DRIVER.equals(this.driverClass) + || JdbcUtils.MYSQL_DRIVER_6.equals(this.driverClass) + ) { isMySql = true; }