diff --git a/.travis.yml b/.travis.yml
index ef2c288661..d4ecfc7776 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -8,3 +8,7 @@ after_success:
branches:
except:
- appveyor
+
+cache:
+ directories:
+ - $HOME/.m2
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000000..179cd9e25d
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,2 @@
+Alibaba Druid
+Copyright 1999-2021 Alibaba Group Holding Ltd.
diff --git a/license.txt b/license.txt
index 52d99a66dd..8f71f43fee 100644
--- a/license.txt
+++ b/license.txt
@@ -1,13 +1,202 @@
-Copyright 1999-2018 Alibaba Group Holding Ltd.
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
- http://www.apache.org/licenses/LICENSE-2.0
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "{}"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright {yyyy} {name of copyright owner}
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
diff --git a/pom.xml b/pom.xml
index 22012b4a9d..479043dc5b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
4.0.0
com.alibaba
druid
- 1.2.7_preview_05
+ 1.2.7_preview_28
jar
druid
A JDBC datasource implementation.
@@ -509,7 +509,7 @@
com.aliyun.odps
odps-sdk-udf
- 0.17.3
+ 0.37.10-public
provided
true
@@ -722,6 +722,12 @@
4.2.0
test
+
+ com.alibaba
+ druid
+ 1.2.5
+ compile
+
-
+
diff --git a/src/main/java/com/alibaba/druid/DbType.java b/src/main/java/com/alibaba/druid/DbType.java
index e0acfb840b..744e067aab 100644
--- a/src/main/java/com/alibaba/druid/DbType.java
+++ b/src/main/java/com/alibaba/druid/DbType.java
@@ -47,6 +47,14 @@ public enum DbType {
mock (1 << 34),
sybase (1 << 35),
highgo (1 << 36),
+ /**
+ * 非常成熟的开源mpp数据库
+ */
+ greenplum (1 << 37),
+ /**
+ * 华为的mpp数据库
+ */
+ gaussdb (1 << 38),
ingres (0),
diff --git a/src/main/java/com/alibaba/druid/VERSION.java b/src/main/java/com/alibaba/druid/VERSION.java
index e146d3763c..0d16ea3e57 100644
--- a/src/main/java/com/alibaba/druid/VERSION.java
+++ b/src/main/java/com/alibaba/druid/VERSION.java
@@ -19,7 +19,7 @@ public final class VERSION {
public final static int MajorVersion = 1;
public final static int MinorVersion = 2;
- public final static int RevisionVersion = 5;
+ public final static int RevisionVersion = 7;
public static String getVersionNumber() {
return VERSION.MajorVersion + "." + VERSION.MinorVersion + "." + VERSION.RevisionVersion;
diff --git a/src/main/java/com/alibaba/druid/filter/logging/LogFilter.java b/src/main/java/com/alibaba/druid/filter/logging/LogFilter.java
index fc9d68b001..031f3ace0c 100644
--- a/src/main/java/com/alibaba/druid/filter/logging/LogFilter.java
+++ b/src/main/java/com/alibaba/druid/filter/logging/LogFilter.java
@@ -90,6 +90,10 @@ public LogFilter(){
}
public void configFromProperties(Properties properties) {
+ if (properties == null) {
+ return;
+ }
+
{
String prop = properties.getProperty("druid.log.conn");
if ("false".equals(prop)) {
@@ -932,6 +936,17 @@ public void preparedStatement_clearParameters(FilterChain chain, PreparedStateme
chain.preparedStatement_clearParameters(statement);
}
+ @Override
+ public void statement_clearBatch(FilterChain chain, StatementProxy statement)
+ throws SQLException {
+
+ if (isStatementParameterClearLogEnable()) {
+ statementLog("{conn-" + statement.getConnectionProxy().getId() + ", stmt-" + statement.getId()
+ + "} clearBatch. ");
+ }
+ chain.statement_clearBatch(statement);
+ }
+
@Override
public boolean isWrapperFor(Class> iface) {
return iface == this.getClass() || iface == LogFilter.class;
diff --git a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java
index a2cdb95119..3396febb21 100644
--- a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java
+++ b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java
@@ -1718,6 +1718,24 @@ private DruidPooledConnection getConnectionInternal(long maxWait) throws SQLExce
if (holder == null) {
long waitNanos = waitNanosLocal.get();
+ final long activeCount;
+ final long maxActive;
+ final long creatingCount;
+ final long createStartNanos;
+ final long createErrorCount;
+ final Throwable createError;
+ try {
+ lock.lock();
+ activeCount = this.activeCount;
+ maxActive = this.maxActive;
+ creatingCount = this.creatingCount;
+ createStartNanos = this.createStartNanos;
+ createErrorCount = this.createErrorCount;
+ createError = this.createError;
+ } finally {
+ lock.unlock();
+ }
+
StringBuilder buf = new StringBuilder(128);
buf.append("wait millis ")//
.append(waitNanos / (1000 * 1000))//
@@ -1751,7 +1769,7 @@ private DruidPooledConnection getConnectionInternal(long maxWait) throws SQLExce
String errorMessage = buf.toString();
- if (this.createError != null) {
+ if (createError != null) {
throw new GetConnectionTimeoutException(errorMessage, createError);
} else {
throw new GetConnectionTimeoutException(errorMessage);
@@ -1864,7 +1882,9 @@ protected final void handleFatalError(DruidPooledConnection conn, SQLException e
this.discardConnection(holder);
}
- LOG.error("discard connection", error);
+
+ // holder.
+ LOG.error("{conn-" + holder.getConnectionId() + "} discard", error);
}
/**
@@ -2510,10 +2530,10 @@ protected boolean put(PhysicalConnectionInfo physicalConnectionInfo) {
return false;
}
- return put(holder, physicalConnectionInfo.createTaskId);
+ return put(holder, physicalConnectionInfo.createTaskId, false);
}
- private boolean put(DruidConnectionHolder holder, long createTaskId) {
+ private boolean put(DruidConnectionHolder holder, long createTaskId, boolean checkExists) {
lock.lock();
try {
if (this.closing || this.closed) {
@@ -2526,6 +2546,15 @@ private boolean put(DruidConnectionHolder holder, long createTaskId) {
}
return false;
}
+
+ if (checkExists) {
+ for (int i = 0; i < poolingCount; i++) {
+ if (connections[i] == holder) {
+ return false;
+ }
+ }
+ }
+
connections[poolingCount] = holder;
incrementPoolingCount();
@@ -3189,7 +3218,7 @@ public void shrink(boolean checkTime, boolean keepAlive) {
boolean discard = !validate;
if (validate) {
holer.lastKeepTimeMillis = System.currentTimeMillis();
- boolean putOk = put(holer, 0L);
+ boolean putOk = put(holer, 0L, true);
if (!putOk) {
discard = true;
}
diff --git a/src/main/java/com/alibaba/druid/pool/DruidDataSourceStatLoggerImpl.java b/src/main/java/com/alibaba/druid/pool/DruidDataSourceStatLoggerImpl.java
index dc365a34d9..0c0b42e7d0 100644
--- a/src/main/java/com/alibaba/druid/pool/DruidDataSourceStatLoggerImpl.java
+++ b/src/main/java/com/alibaba/druid/pool/DruidDataSourceStatLoggerImpl.java
@@ -46,6 +46,10 @@ public DruidDataSourceStatLoggerImpl(){
*/
@Override
public void configFromProperties(Properties properties) {
+ if (properties == null) {
+ return;
+ }
+
String property = properties.getProperty("druid.stat.loggerName");
if (property != null && property.length() > 0) {
setLoggerName(property);
diff --git a/src/main/java/com/alibaba/druid/pool/DruidPooledConnection.java b/src/main/java/com/alibaba/druid/pool/DruidPooledConnection.java
index c974141429..35f4db3fc9 100644
--- a/src/main/java/com/alibaba/druid/pool/DruidPooledConnection.java
+++ b/src/main/java/com/alibaba/druid/pool/DruidPooledConnection.java
@@ -167,6 +167,17 @@ public void closePoolableStatement(DruidPooledPreparedStatement stmt) throws SQL
LOG.error("clear parameter error", ex);
}
+
+ try {
+ rawStatement.clearBatch();
+ } catch (SQLException ex) {
+ this.handleException(ex, null);
+ if (rawStatement.getConnection().isClosed()) {
+ return;
+ }
+
+ LOG.error("clear batch error", ex);
+ }
}
PreparedStatementHolder stmtHolder = stmt.getPreparedStatementHolder();
diff --git a/src/main/java/com/alibaba/druid/pool/vendor/MySqlValidConnectionChecker.java b/src/main/java/com/alibaba/druid/pool/vendor/MySqlValidConnectionChecker.java
index a22e627e4c..5faa3d9f36 100644
--- a/src/main/java/com/alibaba/druid/pool/vendor/MySqlValidConnectionChecker.java
+++ b/src/main/java/com/alibaba/druid/pool/vendor/MySqlValidConnectionChecker.java
@@ -68,6 +68,10 @@ public MySqlValidConnectionChecker(){
@Override
public void configFromProperties(Properties properties) {
+ if (properties == null) {
+ return;
+ }
+
String property = properties.getProperty("druid.mysql.usePingMethod");
if ("true".equals(property)) {
setUsePingMethod(true);
diff --git a/src/main/java/com/alibaba/druid/pool/vendor/OceanBaseOracleExceptionSorter.java b/src/main/java/com/alibaba/druid/pool/vendor/OceanBaseOracleExceptionSorter.java
index 6cdeac49be..dcc67d18ac 100644
--- a/src/main/java/com/alibaba/druid/pool/vendor/OceanBaseOracleExceptionSorter.java
+++ b/src/main/java/com/alibaba/druid/pool/vendor/OceanBaseOracleExceptionSorter.java
@@ -22,6 +22,10 @@ public OceanBaseOracleExceptionSorter() {
}
public void configFromProperties(Properties properties) {
+ if (properties == null) {
+ return;
+ }
+
String property = properties.getProperty("druid.oracle.fatalErrorCodes");
if (property != null) {
String[] items = property.split("\\,");
diff --git a/src/main/java/com/alibaba/druid/pool/vendor/OracleExceptionSorter.java b/src/main/java/com/alibaba/druid/pool/vendor/OracleExceptionSorter.java
index 5c2e73964d..ba4e803969 100644
--- a/src/main/java/com/alibaba/druid/pool/vendor/OracleExceptionSorter.java
+++ b/src/main/java/com/alibaba/druid/pool/vendor/OracleExceptionSorter.java
@@ -42,6 +42,10 @@ public OracleExceptionSorter(){
}
public void configFromProperties(Properties properties) {
+ if (properties == null) {
+ return;
+ }
+
String property = properties.getProperty("druid.oracle.fatalErrorCodes");
if (property != null) {
String[] items = property.split("\\,");
diff --git a/src/main/java/com/alibaba/druid/pool/vendor/OracleValidConnectionChecker.java b/src/main/java/com/alibaba/druid/pool/vendor/OracleValidConnectionChecker.java
index c3138fa947..60435e1943 100644
--- a/src/main/java/com/alibaba/druid/pool/vendor/OracleValidConnectionChecker.java
+++ b/src/main/java/com/alibaba/druid/pool/vendor/OracleValidConnectionChecker.java
@@ -42,6 +42,10 @@ public OracleValidConnectionChecker(){
@Override
public void configFromProperties(Properties properties) {
+ if (properties == null) {
+ return;
+ }
+
String property = properties.getProperty("druid.oracle.pingTimeout");
if (property != null && property.length() > 0) {
int value = Integer.parseInt(property);
diff --git a/src/main/java/com/alibaba/druid/sql/ast/SQLArrayDataType.java b/src/main/java/com/alibaba/druid/sql/ast/SQLArrayDataType.java
index 52add94a4d..acc0860a70 100644
--- a/src/main/java/com/alibaba/druid/sql/ast/SQLArrayDataType.java
+++ b/src/main/java/com/alibaba/druid/sql/ast/SQLArrayDataType.java
@@ -67,7 +67,7 @@ public void setWithLocalTimeZone(boolean value) {
@Override
public void setDbType(DbType dbType) {
- dbType = dbType;
+ this.dbType = dbType;
}
@Override
diff --git a/src/main/java/com/alibaba/druid/sql/ast/SQLMapDataType.java b/src/main/java/com/alibaba/druid/sql/ast/SQLMapDataType.java
index ad8348bc04..c276bf2799 100644
--- a/src/main/java/com/alibaba/druid/sql/ast/SQLMapDataType.java
+++ b/src/main/java/com/alibaba/druid/sql/ast/SQLMapDataType.java
@@ -73,7 +73,7 @@ public void setWithLocalTimeZone(boolean value) {
@Override
public void setDbType(DbType dbType) {
- dbType = dbType;
+ this.dbType = dbType;
}
@Override
diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLShowVariantsStatement.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLShowVariantsStatement.java
index 142039ca35..4e4c860ca0 100644
--- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLShowVariantsStatement.java
+++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLShowVariantsStatement.java
@@ -19,7 +19,7 @@
import com.alibaba.druid.sql.ast.SQLStatementImpl;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
-public class SQLShowVariantsStatement extends SQLStatementImpl {
+public class SQLShowVariantsStatement extends SQLStatementImpl implements SQLShowStatement {
private boolean global = false;
private boolean session = false;
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 7b17e2b3fc..065a7ed499 100644
--- a/src/main/java/com/alibaba/druid/sql/parser/Lexer.java
+++ b/src/main/java/com/alibaba/druid/sql/parser/Lexer.java
@@ -779,6 +779,8 @@ public final SQLType scanSQLType() {
return SQLType.SHOW_FUNCTIONS;
} else if (identifierEquals(FnvHash.Constants.ROLES)) {
return SQLType.SHOW_ROLES;
+ } else if (identifierEquals(FnvHash.Constants.ROLE)) {
+ return SQLType.SHOW_ROLE;
} else if (identifierEquals(FnvHash.Constants.LABEL)) {
return SQLType.SHOW_LABEL;
} else if (identifierEquals(FnvHash.Constants.GRANTS)) {
@@ -836,6 +838,8 @@ public final SQLType scanSQLType() {
return SQLType.LIST_TABLES;
} else if (identifierEquals(FnvHash.Constants.ROLES)) {
return SQLType.LIST_ROLES;
+ } else if (identifierEquals(FnvHash.Constants.TEMPORARY)) {
+ return SQLType.LIST_TEMPORARY_OUTPUT;
} else if (identifierEquals("TENANT")) {
nextToken();
if (identifierEquals(FnvHash.Constants.ROLES)) {
@@ -1151,6 +1155,49 @@ public final void nextTokenForSet() {
nextToken();
}
+ public final boolean skipToNextLine(int startPosition) {
+ for (int i = 0; ; ++i) {
+ int pos = startPosition + i;
+ char ch = charAt(pos);
+ if (ch == '\n') {
+ this.pos = pos;
+ this.ch = charAt(this.pos);
+ return true;
+ }
+
+ if (ch == EOI) {
+ this.pos = pos;
+ break;
+ }
+ }
+
+ return false;
+ }
+
+ public final boolean skipToNextLineOrParameter(int startPosition) {
+ for (int i = 0; ; ++i) {
+ int pos = startPosition + i;
+ char ch = charAt(pos);
+ if (ch == '\n') {
+ this.pos = pos;
+ this.ch = charAt(this.pos);
+ return true;
+ }
+ if (ch == '$' && charAt(pos + 1) == '{') {
+ this.pos = pos;
+ this.ch = charAt(this.pos);
+ return true;
+ }
+
+ if (ch == EOI) {
+ this.pos = pos;
+ break;
+ }
+ }
+
+ return false;
+ }
+
public final void nextToken() {
startPos = pos;
bufPos = 0;
@@ -2198,25 +2245,10 @@ public void scanVariable() {
pos++;
bufPos++;
- boolean ident = false;
for (;;) {
ch = charAt(++pos);
- if (isEOF()) {
- pos--;
- bufPos--;
- break;
- }
-
- if (ch == '}' && !ident) {
- if (isIdentifierChar(charAt(pos + 1))) {
- bufPos++;
- ident = true;
- continue;
- }
- break;
- }
- if (ident && isWhitespace(ch)) {
+ if (ch == '}') {
break;
}
@@ -2224,7 +2256,7 @@ public void scanVariable() {
continue;
}
- if (ch != '}' && !ident) {
+ if (ch != '}') {
throw new ParserException("syntax error. " + info());
}
++pos;
@@ -2241,7 +2273,7 @@ public void scanVariable() {
}
stringVal = addSymbol();
- token = ident ? IDENTIFIER : Token.VARIANT;
+ token = Token.VARIANT;
return;
} else if (c1 == '$' && charAt(pos + 2) == '{') {
pos += 2;
@@ -2804,30 +2836,12 @@ public void scanNumber() {
&& !(ch == 'b' && bufPos == 1 && charAt(pos - 1) == '0' && dbType != DbType.odps)
) {
bufPos++;
- boolean brace = false;
for (;;) {
char c0 = ch;
ch = charAt(++pos);
- if (isEOF()) {
- break;
- }
-
if (!isIdentifierChar(ch)) {
- if (ch == '{' && charAt(pos - 1) == '$' && !brace) {
- bufPos++;
- brace = true;
- continue;
- }
-
- if (ch == '}' && brace) {
- bufPos++;
- brace = false;
- continue;
- }
-
- if ((ch == '(' || ch == ')')
- && c0 > 256) {
+ if (ch == '(' || ch == ')' && c0 > 256) {
bufPos++;
continue;
}
diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java
index bbcfeabe52..97bdbee9bb 100644
--- a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java
+++ b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java
@@ -3806,11 +3806,20 @@ public SQLExpr relationalRest(SQLExpr expr) {
return expr;
}
break;
- case RLIKE:
+ case RLIKE: {
+ Lexer.SavePoint mark = lexer.mark();
lexer.nextToken();
- rightExp = bitOr();
- expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.RLike, rightExp, getDbType());
+ switch (lexer.token) {
+ case COMMA:
+ lexer.reset(mark);
+ break;
+ default:
+ rightExp = bitOr();
+ expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.RLike, rightExp, getDbType());
+ break;
+ }
break;
+ }
case IDENTIFIER:
long hash = lexer.hash_lower;
if (hash == FnvHash.Constants.SOUNDS) {
diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLParser.java
index 4faa9f6231..240116fdab 100644
--- a/src/main/java/com/alibaba/druid/sql/parser/SQLParser.java
+++ b/src/main/java/com/alibaba/druid/sql/parser/SQLParser.java
@@ -197,7 +197,7 @@ protected String tableAlias(boolean must) {
|| lexer.identifierEquals(FnvHash.Constants.ANTI)
|| lexer.identifierEquals(FnvHash.Constants.SEMI)) {
lexer.reset(mark);
- break;
+ return null;
} else {
return strVal;
}
@@ -550,6 +550,7 @@ protected String as() {
case TO:
case REFERENCES:
case LIKE:
+ case RLIKE:
case NULL:
case RIGHT:
case LEFT:
diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java
index ba7955e115..92687a2f62 100644
--- a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java
+++ b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java
@@ -4735,7 +4735,7 @@ public SQLStatement parseStatement( final boolean tryBest) {
this.parseStatementList(list, 1, null);
if (tryBest) {
if (lexer.token != Token.EOF) {
- throw new ParserException("sql syntax error, no terminated. " + lexer.token);
+ throw new ParserException("sql syntax error, no terminated. " + lexer.info());
}
}
return list.get(0);
diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLType.java b/src/main/java/com/alibaba/druid/sql/parser/SQLType.java
index 0e54316c70..c664af6f5a 100644
--- a/src/main/java/com/alibaba/druid/sql/parser/SQLType.java
+++ b/src/main/java/com/alibaba/druid/sql/parser/SQLType.java
@@ -32,6 +32,7 @@ public enum SQLType {
SHOW_PARTITIONS,
SHOW_CATALOGS,
SHOW_FUNCTIONS,
+ SHOW_ROLE,
SHOW_ROLES,
SHOW_PACKAGE,
SHOW_PACKAGES,
@@ -58,6 +59,7 @@ public enum SQLType {
LIST_TENANT_ROLES,
LIST_TRUSTEDPROJECTS,
LIST_ACCOUNTPROVIDERS,
+ LIST_TEMPORARY_OUTPUT,
WHO, // for analyticdb
GRANT,
REVOKE,
diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java
index ea775afec8..4d23ea5b25 100644
--- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java
+++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java
@@ -6511,7 +6511,7 @@ public boolean visit(SQLAlterViewRenameStatement x) {
}
SQLName changeOwnerTo = x.getChangeOwnerTo();
- if (changeOwnerTo != null) {
+ if (to != null) {
print0(ucase ? " CHANGEOWNER TO " : " changeowner to ");
printExpr(changeOwnerTo);
}
diff --git a/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java b/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java
index a0e7a261ed..35c8d24917 100644
--- a/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java
+++ b/src/main/java/com/alibaba/druid/stat/JdbcSqlStat.java
@@ -1057,7 +1057,7 @@ public void addResultSetHoldTimeNano(long nano) {
public void addResultSetHoldTimeNano(long statementExecuteNano, long resultHoldTimeNano) {
resultSetHoldTimeNanoUpdater.addAndGet(this, resultHoldTimeNano);
executeAndResultSetHoldTimeUpdater.addAndGet(this, statementExecuteNano + resultHoldTimeNano);
- executeAndResultHoldTimeHistogramRecord((statementExecuteNano + resultHoldTimeNano) / 1000 / 1000);
+ executeAndResultHoldTimeHistogramRecord(statementExecuteNano + resultHoldTimeNano);
updateCount_0_1_Updater.incrementAndGet(this);
}
diff --git a/src/main/java/com/alibaba/druid/support/http/StatViewServlet.java b/src/main/java/com/alibaba/druid/support/http/StatViewServlet.java
index fff7186679..7d3a88e7e8 100644
--- a/src/main/java/com/alibaba/druid/support/http/StatViewServlet.java
+++ b/src/main/java/com/alibaba/druid/support/http/StatViewServlet.java
@@ -152,7 +152,7 @@ private String getJmxResult(MBeanServerConnection connetion, String url) throws
}
/**
- * 程序首先判断是否存在jmx连接地址,如果不存在,则直接调用本地的duird服务; 如果存在,则调用远程jmx服务。在进行jmx通信,首先判断一下jmx连接是否已经建立成功,如果已经
+ * 程序首先判断是否存在jmx连接地址,如果不存在,则直接调用本地的druid服务; 如果存在,则调用远程jmx服务。在进行jmx通信,首先判断一下jmx连接是否已经建立成功,如果已经
* 建立成功,则直接进行通信,如果之前没有成功建立,则会尝试重新建立一遍。.
*
* @param url 要连接的服务地址
diff --git a/src/main/java/com/alibaba/druid/support/opds/udf/SqlTypeUDF.java b/src/main/java/com/alibaba/druid/support/opds/udf/SqlTypeUDF.java
index 732f78dfc9..3f8fdeda3d 100644
--- a/src/main/java/com/alibaba/druid/support/opds/udf/SqlTypeUDF.java
+++ b/src/main/java/com/alibaba/druid/support/opds/udf/SqlTypeUDF.java
@@ -6,7 +6,6 @@
import com.alibaba.druid.sql.ast.statement.*;
import com.alibaba.druid.sql.dialect.hive.ast.HiveInsertStatement;
import com.alibaba.druid.sql.dialect.hive.ast.HiveMultiInsertStatement;
-import com.alibaba.druid.sql.dialect.hive.stmt.HiveLoadDataStatement;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsDeclareVariableStatement;
import com.alibaba.druid.sql.dialect.odps.ast.OdpsQueryAliasStatement;
import com.alibaba.druid.sql.parser.*;
@@ -98,8 +97,6 @@ static SQLType getStmtSqlType(SQLStatement stmt, SQLType sqlType) {
? SQLType.INSERT_OVERWRITE_VALUES
: SQLType.INSERT_INTO_VALUES;
}
- } else if (stmt instanceof HiveLoadDataStatement) {
- sqlType = SQLType.LOAD;
} else if (stmt instanceof SQLUpdateStatement) {
sqlType = SQLType.UPDATE;
} else if (stmt instanceof SQLDeleteStatement) {
diff --git a/src/main/java/com/alibaba/druid/util/JdbcConstants.java b/src/main/java/com/alibaba/druid/util/JdbcConstants.java
index 38536581ae..bcd372a351 100644
--- a/src/main/java/com/alibaba/druid/util/JdbcConstants.java
+++ b/src/main/java/com/alibaba/druid/util/JdbcConstants.java
@@ -136,4 +136,9 @@ public interface JdbcConstants {
*/
DbType POLARDB = DbType.polardb;
String POLARDB_DRIVER = "com.aliyun.polardb.Driver";
+ /**
+ * GreenPlum
+ */
+ DbType GREENPLUM = DbType.greenplum;
+ String GREENPLUM_DRIVER = "com.pivotal.jdbc.GreenplumDriver";
}
diff --git a/src/main/java/com/alibaba/druid/util/JdbcUtils.java b/src/main/java/com/alibaba/druid/util/JdbcUtils.java
index b3cd10b9ed..16e87cc278 100644
--- a/src/main/java/com/alibaba/druid/util/JdbcUtils.java
+++ b/src/main/java/com/alibaba/druid/util/JdbcUtils.java
@@ -632,6 +632,8 @@ public static DbType getDbTypeRaw(String rawUrl, String driverClassName) {
return DbType.polardb;
} else if (rawUrl.startsWith("jdbc:highgo:")) {
return DbType.highgo;
+ } else if (rawUrl.startsWith("jdbc:pivotal:greenplum:")||rawUrl.startsWith("jdbc:datadirect:greenplum:")) {
+ return DbType.greenplum;
} else {
return null;
}
@@ -965,6 +967,8 @@ public static boolean isPgsqlDbType(DbType dbType) {
case postgresql:
case edb:
case polardb:
+ case greenplum:
+ case gaussdb:
return true;
default:
return false;
diff --git a/src/main/java/com/alibaba/druid/wall/WallFilter.java b/src/main/java/com/alibaba/druid/wall/WallFilter.java
index 28ef84203e..53b09e4a87 100644
--- a/src/main/java/com/alibaba/druid/wall/WallFilter.java
+++ b/src/main/java/com/alibaba/druid/wall/WallFilter.java
@@ -162,6 +162,8 @@ public synchronized void init(DataSourceProxy dataSource) {
case postgresql:
case edb:
case polardb:
+ case greenplum:
+ case gaussdb:
if (config == null) {
config = new WallConfig(PGWallProvider.DEFAULT_CONFIG_DIR);
}
diff --git a/src/main/java/com/alibaba/druid/wall/WallProviderStatLoggerImpl.java b/src/main/java/com/alibaba/druid/wall/WallProviderStatLoggerImpl.java
index 093b82f18f..5609408ec0 100644
--- a/src/main/java/com/alibaba/druid/wall/WallProviderStatLoggerImpl.java
+++ b/src/main/java/com/alibaba/druid/wall/WallProviderStatLoggerImpl.java
@@ -30,6 +30,10 @@ public class WallProviderStatLoggerImpl extends WallProviderStatLoggerAdapter im
@Override
public void configFromProperties(Properties properties) {
+ if (properties == null) {
+ return;
+ }
+
String property = properties.getProperty("druid.stat.loggerName");
if (property != null && property.length() > 0) {
setLoggerName(property);
diff --git a/src/test/java/com/alibaba/druid/bvt/bug/Issue4253.java b/src/test/java/com/alibaba/druid/bvt/bug/Issue4253.java
index d6738ae8a8..3e636218f7 100644
--- a/src/test/java/com/alibaba/druid/bvt/bug/Issue4253.java
+++ b/src/test/java/com/alibaba/druid/bvt/bug/Issue4253.java
@@ -19,7 +19,7 @@ public class Issue4253 extends TestCase {
private final DbType dbType = JdbcConstants.ORACLE;
public void test_for_issue() throws Exception {
- InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("bvt/parser/oracle-63.txt");
+ InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("bvt/parser/oracle-62.txt");
Reader reader = new InputStreamReader(is, StandardCharsets.UTF_8);
String input = Utils.read(reader);
JdbcUtils.close(reader);
@@ -28,7 +28,9 @@ public void test_for_issue() throws Exception {
try {
parser.parseStatement(true);
} catch (Exception ex) {
+ ex.printStackTrace();
error = ex;
+ error.printStackTrace();
}
assertNull(error);
}
diff --git a/src/test/java/com/alibaba/druid/bvt/pool/Issue4316.java b/src/test/java/com/alibaba/druid/bvt/pool/Issue4316.java
new file mode 100644
index 0000000000..cda4a2ef3c
--- /dev/null
+++ b/src/test/java/com/alibaba/druid/bvt/pool/Issue4316.java
@@ -0,0 +1,35 @@
+package com.alibaba.druid.bvt.pool;
+
+import com.alibaba.druid.pool.DruidDataSource;
+import com.alibaba.druid.pool.DruidPooledConnection;
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+
+public class Issue4316 {
+ @Test
+ public void test_0() throws Exception {
+// DruidDataSource druidDataSource = new DruidDataSource();
+// druidDataSource.setUsername("");
+// druidDataSource.setPassword("");
+// druidDataSource.setUrl("jdbc:mock:xxx");
+// druidDataSource.setValidationQuery("select 1");
+// druidDataSource.setMinEvictableIdleTimeMillis(100000);
+// druidDataSource.setMaxEvictableIdleTimeMillis(DruidDataSource.DEFAULT_MAX_EVICTABLE_IDLE_TIME_MILLIS);
+// druidDataSource.setKeepAliveBetweenTimeMillis(120000);
+// druidDataSource.setMinIdle(2);
+// druidDataSource.setTimeBetweenEvictionRunsMillis(70000);
+// druidDataSource.setKeepAlive(true);
+// DruidPooledConnection connection1 = druidDataSource.getConnection();
+// DruidPooledConnection connection2 = druidDataSource.getConnection();
+// connection2.close();
+// Thread.sleep(95000);
+// connection1.close();
+// Thread.sleep(140000);
+// DruidPooledConnection connection3 = druidDataSource.getConnection();
+// DruidPooledConnection connection4 = druidDataSource.getConnection();
+// assertFalse(connection3.getConnectionHolder() == connection4.getConnectionHolder());
+// connection3.close();
+// connection4.close();
+ }
+}
diff --git a/src/test/java/com/alibaba/druid/bvt/pool/exception/OracleExceptionSorterTest_setSavepointWithName.java b/src/test/java/com/alibaba/druid/bvt/pool/exception/OracleExceptionSorterTest_setSavepointWithName.java
index 1a2c655acc..863b25a968 100644
--- a/src/test/java/com/alibaba/druid/bvt/pool/exception/OracleExceptionSorterTest_setSavepointWithName.java
+++ b/src/test/java/com/alibaba/druid/bvt/pool/exception/OracleExceptionSorterTest_setSavepointWithName.java
@@ -21,7 +21,7 @@ public class OracleExceptionSorterTest_setSavepointWithName extends TestCase {
private DruidDataSource dataSource;
protected void setUp() throws Exception {
- Assert.assertEquals(0, JdbcStatManager.getInstance().getSqlList().size());
+ assertEquals(0, JdbcStatManager.getInstance().getSqlList().size());
dataSource = new DruidDataSource();
@@ -29,6 +29,7 @@ protected void setUp() throws Exception {
dataSource.setDriver(new OracleMockDriver());
dataSource.setUrl("jdbc:mock:xxx");
+ dataSource.setFilters("log4j");
dataSource.setPoolPreparedStatements(true);
dataSource.setMaxOpenPreparedStatements(100);
}
@@ -47,14 +48,14 @@ public void test_connect() throws Exception {
pstmt.close();
conn.close();
- Assert.assertEquals(0, dataSource.getActiveCount());
- Assert.assertEquals(1, dataSource.getPoolingCount());
- Assert.assertEquals(1, dataSource.getCreateCount());
+ assertEquals(0, dataSource.getActiveCount());
+ assertEquals(1, dataSource.getPoolingCount());
+ assertEquals(1, dataSource.getCreateCount());
}
DruidPooledConnection conn = dataSource.getConnection();
MockConnection mockConn = conn.unwrap(MockConnection.class);
- Assert.assertNotNull(mockConn);
+ assertNotNull(mockConn);
SQLException exception = new SQLException("xx", "xxx", 28);
mockConn.setError(exception);
@@ -65,7 +66,7 @@ public void test_connect() throws Exception {
} catch (Exception ex) {
setError = ex;
}
- Assert.assertNotNull(setError);
+ assertNotNull(setError);
conn.close();
@@ -73,9 +74,9 @@ public void test_connect() throws Exception {
Connection conn2 = dataSource.getConnection();
conn2.close();
}
- Assert.assertEquals(0, dataSource.getActiveCount());
- Assert.assertEquals(1, dataSource.getPoolingCount());
- Assert.assertEquals(2, dataSource.getCreateCount());
+ assertEquals(0, dataSource.getActiveCount());
+ assertTrue(dataSource.getPoolingCount() >= 1);
+ assertTrue(dataSource.getCreateCount() >= 2);
}
}
diff --git a/src/test/java/com/alibaba/druid/bvt/proxy/filter/GlobalStatTest0.java b/src/test/java/com/alibaba/druid/bvt/proxy/filter/GlobalStatTest0.java
index 5c93aaf04a..fb959b3ec8 100644
--- a/src/test/java/com/alibaba/druid/bvt/proxy/filter/GlobalStatTest0.java
+++ b/src/test/java/com/alibaba/druid/bvt/proxy/filter/GlobalStatTest0.java
@@ -78,7 +78,7 @@ public void test_execute() throws Exception {
List