Compare commits

...

13 Commits

Author SHA1 Message Date
dependabot[bot] 5544d8fc82
Merge 0ad73c260b into 88d90f1434 2025-07-20 21:43:49 +00:00
wenshao 88d90f1434 1.2.27-SNAPSHOT
Java CI / Test JDK ${{ matrix.java }}, ${{ matrix.os }} (11, ubuntu-latest) (push) Waiting to run Details
Java CI / Test JDK ${{ matrix.java }}, ${{ matrix.os }} (17, ubuntu-latest) (push) Waiting to run Details
Java CI / Test JDK ${{ matrix.java }}, ${{ matrix.os }} (21, ubuntu-latest) (push) Waiting to run Details
Java CI / Test JDK ${{ matrix.java }}, ${{ matrix.os }} (8, ubuntu-latest) (push) Waiting to run Details
2025-07-21 05:43:34 +08:00
wenshao dac24c674e 1.2.26 release 2025-07-21 05:42:11 +08:00
wenshao 96a47b7369 improved for urlUserPassword changed 2025-07-20 14:15:57 +08:00
wenshao 2e788bde25 userPassword Version 2025-07-19 10:40:20 +08:00
wenshao b5169b4264 remove useUnfairLock 2025-07-19 10:05:15 +08:00
林枸 9d3135c65b Support pg parse interval week.
Java CI / Test JDK ${{ matrix.java }}, ${{ matrix.os }} (11, ubuntu-latest) (push) Has been cancelled Details
Java CI / Test JDK ${{ matrix.java }}, ${{ matrix.os }} (17, ubuntu-latest) (push) Has been cancelled Details
Java CI / Test JDK ${{ matrix.java }}, ${{ matrix.os }} (21, ubuntu-latest) (push) Has been cancelled Details
Java CI / Test JDK ${{ matrix.java }}, ${{ matrix.os }} (8, ubuntu-latest) (push) Has been cancelled Details
2025-07-18 17:43:51 +08:00
林枸 2e6bb735fb Add method clone miss param. 2025-07-18 16:27:05 +08:00
林枸 a179bb9750 Modify parser of multiline comment with depth. 2025-07-18 16:22:22 +08:00
Gladys-111 7629916024
Fix multiline problem (#6485)
Java CI / Test JDK ${{ matrix.java }}, ${{ matrix.os }} (11, ubuntu-latest) (push) Has been cancelled Details
Java CI / Test JDK ${{ matrix.java }}, ${{ matrix.os }} (17, ubuntu-latest) (push) Has been cancelled Details
Java CI / Test JDK ${{ matrix.java }}, ${{ matrix.os }} (21, ubuntu-latest) (push) Has been cancelled Details
Java CI / Test JDK ${{ matrix.java }}, ${{ matrix.os }} (8, ubuntu-latest) (push) Has been cancelled Details
2025-07-17 09:38:13 +08:00
林枸 0444f4f532 FiSupport group by alias parser and eqeq default parser.
Java CI / Test JDK ${{ matrix.java }}, ${{ matrix.os }} (11, ubuntu-latest) (push) Waiting to run Details
Java CI / Test JDK ${{ matrix.java }}, ${{ matrix.os }} (17, ubuntu-latest) (push) Waiting to run Details
Java CI / Test JDK ${{ matrix.java }}, ${{ matrix.os }} (21, ubuntu-latest) (push) Waiting to run Details
Java CI / Test JDK ${{ matrix.java }}, ${{ matrix.os }} (8, ubuntu-latest) (push) Waiting to run Details
2025-07-16 17:53:41 +08:00
林枸 ac484261c0 Fix multiline comment parse issue.
Java CI / Test JDK ${{ matrix.java }}, ${{ matrix.os }} (11, ubuntu-latest) (push) Has been cancelled Details
Java CI / Test JDK ${{ matrix.java }}, ${{ matrix.os }} (17, ubuntu-latest) (push) Has been cancelled Details
Java CI / Test JDK ${{ matrix.java }}, ${{ matrix.os }} (21, ubuntu-latest) (push) Has been cancelled Details
Java CI / Test JDK ${{ matrix.java }}, ${{ matrix.os }} (8, ubuntu-latest) (push) Has been cancelled Details
2025-07-15 11:13:48 +08:00
dependabot[bot] 0ad73c260b
Bump com.h2database:h2 from 1.4.199 to 2.2.220 in /core
Bumps [com.h2database:h2](https://github.com/h2database/h2database) from 1.4.199 to 2.2.220.
- [Release notes](https://github.com/h2database/h2database/releases)
- [Commits](https://github.com/h2database/h2database/compare/version-1.4.199...version-2.2.220)

---
updated-dependencies:
- dependency-name: com.h2database:h2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-09 13:39:46 +00:00
25 changed files with 520 additions and 76 deletions

View File

@ -4,7 +4,7 @@
<parent>
<groupId>com.alibaba</groupId>
<artifactId>druid-parent</artifactId>
<version>1.2.26-SNAPSHOT</version>
<version>1.2.27-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>druid</artifactId>
@ -276,7 +276,7 @@
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.199</version>
<version>2.2.220</version>
<scope>provided</scope>
</dependency>

View File

@ -18,7 +18,7 @@ package com.alibaba.druid;
public final class VERSION {
public static final int MajorVersion = 1;
public static final int MinorVersion = 2;
public static final int RevisionVersion = 24;
public static final int RevisionVersion = 27;
public static String getVersionNumber() {
return VERSION.MajorVersion + "." + VERSION.MinorVersion + "." + VERSION.RevisionVersion;

View File

@ -187,20 +187,23 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
protected volatile long cachedPreparedStatementCount;
protected volatile long cachedPreparedStatementDeleteCount;
protected volatile long cachedPreparedStatementMissCount;
protected volatile long userPasswordVersion;
private volatile FilterChainImpl filterChain;
static final AtomicLongFieldUpdater<DruidAbstractDataSource> errorCountUpdater = AtomicLongFieldUpdater.newUpdater(DruidAbstractDataSource.class, "errorCount");
static final AtomicLongFieldUpdater<DruidAbstractDataSource> dupCloseCountUpdater = AtomicLongFieldUpdater.newUpdater(DruidAbstractDataSource.class, "dupCloseCount");
static final AtomicLongFieldUpdater<DruidAbstractDataSource> startTransactionCountUpdater = AtomicLongFieldUpdater.newUpdater(DruidAbstractDataSource.class, "startTransactionCount");
static final AtomicLongFieldUpdater<DruidAbstractDataSource> commitCountUpdater = AtomicLongFieldUpdater.newUpdater(DruidAbstractDataSource.class, "commitCount");
static final AtomicLongFieldUpdater<DruidAbstractDataSource> rollbackCountUpdater = AtomicLongFieldUpdater.newUpdater(DruidAbstractDataSource.class, "rollbackCount");
static final AtomicLongFieldUpdater<DruidAbstractDataSource> cachedPreparedStatementHitCountUpdater = AtomicLongFieldUpdater.newUpdater(DruidAbstractDataSource.class, "cachedPreparedStatementHitCount");
static final AtomicLongFieldUpdater<DruidAbstractDataSource> preparedStatementCountUpdater = AtomicLongFieldUpdater.newUpdater(DruidAbstractDataSource.class, "preparedStatementCount");
static final AtomicLongFieldUpdater<DruidAbstractDataSource> closedPreparedStatementCountUpdater = AtomicLongFieldUpdater.newUpdater(DruidAbstractDataSource.class, "closedPreparedStatementCount");
static final AtomicLongFieldUpdater<DruidAbstractDataSource> cachedPreparedStatementCountUpdater = AtomicLongFieldUpdater.newUpdater(DruidAbstractDataSource.class, "cachedPreparedStatementCount");
static final AtomicLongFieldUpdater<DruidAbstractDataSource> cachedPreparedStatementDeleteCountUpdater = AtomicLongFieldUpdater.newUpdater(DruidAbstractDataSource.class, "cachedPreparedStatementDeleteCount");
static final AtomicLongFieldUpdater<DruidAbstractDataSource> cachedPreparedStatementMissCountUpdater = AtomicLongFieldUpdater.newUpdater(DruidAbstractDataSource.class, "cachedPreparedStatementMissCount");
static final AtomicLongFieldUpdater<DruidAbstractDataSource>
errorCountUpdater = AtomicLongFieldUpdater.newUpdater(DruidAbstractDataSource.class, "errorCount"),
dupCloseCountUpdater = AtomicLongFieldUpdater.newUpdater(DruidAbstractDataSource.class, "dupCloseCount"),
startTransactionCountUpdater = AtomicLongFieldUpdater.newUpdater(DruidAbstractDataSource.class, "startTransactionCount"),
commitCountUpdater = AtomicLongFieldUpdater.newUpdater(DruidAbstractDataSource.class, "commitCount"),
rollbackCountUpdater = AtomicLongFieldUpdater.newUpdater(DruidAbstractDataSource.class, "rollbackCount"),
cachedPreparedStatementHitCountUpdater = AtomicLongFieldUpdater.newUpdater(DruidAbstractDataSource.class, "cachedPreparedStatementHitCount"),
preparedStatementCountUpdater = AtomicLongFieldUpdater.newUpdater(DruidAbstractDataSource.class, "preparedStatementCount"),
closedPreparedStatementCountUpdater = AtomicLongFieldUpdater.newUpdater(DruidAbstractDataSource.class, "closedPreparedStatementCount"),
cachedPreparedStatementCountUpdater = AtomicLongFieldUpdater.newUpdater(DruidAbstractDataSource.class, "cachedPreparedStatementCount"),
cachedPreparedStatementDeleteCountUpdater = AtomicLongFieldUpdater.newUpdater(DruidAbstractDataSource.class, "cachedPreparedStatementDeleteCount"),
cachedPreparedStatementMissCountUpdater = AtomicLongFieldUpdater.newUpdater(DruidAbstractDataSource.class, "cachedPreparedStatementMissCount"),
userPasswordVersionUpdater = AtomicLongFieldUpdater.newUpdater(DruidAbstractDataSource.class, "userPasswordVersion");
protected static final AtomicReferenceFieldUpdater<DruidAbstractDataSource, FilterChainImpl> filterChainUpdater
= AtomicReferenceFieldUpdater.newUpdater(DruidAbstractDataSource.class, FilterChainImpl.class, "filterChain");
@ -256,7 +259,6 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
static final AtomicLongFieldUpdater<DruidAbstractDataSource> destroyCountUpdater = AtomicLongFieldUpdater.newUpdater(DruidAbstractDataSource.class, "destroyCount");
static final AtomicLongFieldUpdater<DruidAbstractDataSource> createStartNanosUpdater = AtomicLongFieldUpdater.newUpdater(DruidAbstractDataSource.class, "createStartNanos");
private Boolean useUnfairLock = true;
private boolean useLocalSessionState = true;
private boolean keepConnectionUnderlyingTransactionIsolation;
@ -382,8 +384,6 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
this.lock = new ReentrantLock(!useUnfairLock);
this.notEmpty = this.lock.newCondition();
this.empty = this.lock.newCondition();
this.useUnfairLock = useUnfairLock;
}
} finally {
lock.unlock();
@ -519,6 +519,14 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
cachedPreparedStatementMissCountUpdater.incrementAndGet(this);
}
protected void incrementUserPasswordVersion() {
userPasswordVersionUpdater.incrementAndGet(this);
}
protected long getUserPasswordVersion() {
return userPasswordVersionUpdater.get(this);
}
public long getCachedPreparedStatementMissCount() {
return cachedPreparedStatementMissCount;
}

View File

@ -85,6 +85,7 @@ public final class DruidConnectionHolder {
final ReentrantLock lock = new ReentrantLock();
protected String initSchema;
protected Socket socket;
protected final long userPasswordVersion;
volatile FilterChainImpl filterChain;
@ -116,6 +117,7 @@ public final class DruidConnectionHolder {
this.createNanoSpan = connectNanoSpan;
this.variables = variables;
this.globalVariables = globalVariables;
this.userPasswordVersion = dataSource.getUserPasswordVersion();
this.connectTimeMillis = System.currentTimeMillis();
this.lastActiveTimeMillis = connectTimeMillis;
@ -468,4 +470,7 @@ public final class DruidConnectionHolder {
return buf.toString();
}
public long getUserPasswordVersion() {
return userPasswordVersion;
}
}

View File

@ -234,8 +234,8 @@ public class DruidDataSource extends DruidAbstractDataSource
lock.lock();
try {
urlUserPasswordChanged = (url != null && !this.jdbcUrl.equals(url))
|| (username != null && !this.username.equals(username))
|| (password != null && !this.password.equals(password));
|| (username != null && !username.equals(this.username))
|| (password != null && !password.equals(this.password));
String connectUser = username != null ? username : this.username;
if (username != null) {
@ -266,19 +266,22 @@ public class DruidDataSource extends DruidAbstractDataSource
lock.lock();
try {
if (url != null && !this.jdbcUrl.equals(url)) {
this.jdbcUrl = url; // direct set url, ignore init check
LOG.info("jdbcUrl changed");
}
if (urlUserPasswordChanged) {
if (url != null && !url.equals(this.jdbcUrl)) {
this.jdbcUrl = url; // direct set url, ignore init check
LOG.info("jdbcUrl changed");
}
if (username != null && !this.username.equals(username)) {
this.username = username; // direct set, ignore init check
LOG.info("username changed");
}
if (username != null && !username.equals(this.username)) {
this.username = username; // direct set, ignore init check
LOG.info("username changed");
}
if (password != null && !this.password.equals(password)) {
this.password = password; // direct set, ignore init check
LOG.info("password changed");
if (password != null && !password.equals(this.password)) {
this.password = password; // direct set, ignore init check
LOG.info("password changed");
}
incrementUserPasswordVersion();
}
{
@ -305,32 +308,46 @@ public class DruidDataSource extends DruidAbstractDataSource
}
DruidDataSourceUtils.configFromProperties(this, properties);
if (urlUserPasswordChanged) {
for (int i = poolingCount - 1; i >= 0; i--) {
DruidConnectionHolder connection = connections[i];
JdbcUtils.close(connection.conn);
destroyCountUpdater.incrementAndGet(this);
connections[i] = null;
}
poolingCount = 0;
emptySignal();
}
} finally {
lock.unlock();
}
int minIdle = this.minIdle;
for (int i = 0; i < minIdle; ++i) {
// check need fill
lock.lock();
int replaceCount = 0;
// replace older version urlUserPassword Connection
while ((hasOlderVersionUrlUserPasswordConnection())) {
try {
if (activeCount + poolingCount >= minIdle) {
PhysicalConnectionInfo phyConnInfo = createPhysicalConnection();
boolean result = false;
lock.lock();
try {
for (int i = poolingCount - 1; i >= 0; i--) {
if (connections[i].getUserPasswordVersion() < userPasswordVersion) {
connections[i] = new DruidConnectionHolder(DruidDataSource.this, phyConnInfo);
result = true;
replaceCount++;
break;
}
}
} finally {
lock.unlock();
}
if (!result) {
JdbcUtils.close(phyConnInfo.getPhysicalConnection());
LOG.info("replace older version urlUserPassword failed.");
break;
}
} finally {
lock.unlock();
} catch (SQLException e) {
LOG.error("fill init connection error", e);
}
}
if (replaceCount > 0) {
LOG.info("replace older version urlUserPassword Connection : " + replaceCount);
}
while ((isLowWaterLevel())) {
try {
PhysicalConnectionInfo physicalConnection = createPhysicalConnection();
@ -345,6 +362,30 @@ public class DruidDataSource extends DruidAbstractDataSource
}
}
private boolean hasOlderVersionUrlUserPasswordConnection() {
lock.lock();
try {
long userPasswordVersion = this.userPasswordVersion;
for (int i = 0; i < poolingCount; i++) {
if (connections[i].getUserPasswordVersion() < userPasswordVersion) {
return true;
}
}
} finally {
lock.unlock();
}
return false;
}
private boolean isLowWaterLevel() {
lock.lock();
try {
return activeCount + poolingCount < minIdle;
} finally {
lock.unlock();
}
}
public boolean isKillWhenSocketReadTimeout() {
return killWhenSocketReadTimeout;
}
@ -1915,7 +1956,8 @@ public class DruidDataSource extends DruidAbstractDataSource
return;
}
if (phyMaxUseCount > 0 && holder.useCount >= phyMaxUseCount) {
if ((phyMaxUseCount > 0 && holder.useCount >= phyMaxUseCount)
|| holder.userPasswordVersion < getUserPasswordVersion()) {
discardConnection(holder);
return;
}
@ -1975,6 +2017,7 @@ public class DruidDataSource extends DruidAbstractDataSource
}
}
boolean full = false;
lock.lock();
try {
if (holder.active) {
@ -1985,13 +2028,20 @@ public class DruidDataSource extends DruidAbstractDataSource
result = putLast(holder, currentTimeMillis);
recycleCount++;
if (!result) {
full = poolingCount + activeCount >= maxActive;
}
} finally {
lock.unlock();
}
if (!result) {
JdbcUtils.close(holder.conn);
LOG.info("connection recycle failed.");
String msg = "connection recycle failed.";
if (full) {
msg += " pool is full";
}
LOG.info(msg);
}
} catch (Throwable e) {
holder.clearStatementCache();
@ -2442,7 +2492,7 @@ public class DruidDataSource extends DruidAbstractDataSource
}
protected boolean put(PhysicalConnectionInfo physicalConnectionInfo) {
DruidConnectionHolder holder = null;
DruidConnectionHolder holder;
try {
holder = new DruidConnectionHolder(DruidDataSource.this, physicalConnectionInfo);
} catch (SQLException ex) {

View File

@ -91,6 +91,7 @@ public enum SQLBinaryOperator {
RegExp("REGEXP", 110),
NotRegExp("NOT REGEXP", 110),
Equality("=", 110),
EqEq("==", 110),
BitwiseNot("!", 130),
Concat("||", 140),

View File

@ -42,26 +42,31 @@ public class SQLMethodInvokeExpr extends SQLExprImpl implements SQLReplaceable,
protected transient SQLDataType resolvedReturnDataType;
public SQLMethodInvokeExpr() {
this.removeBrackets = false;
}
public SQLMethodInvokeExpr(String methodName) {
this.methodName = methodName;
this.removeBrackets = false;
}
public SQLMethodInvokeExpr(SQLIdentifierExpr methodName) {
this.methodName = methodName.name;
this.methodNameHashCode64 = methodName.hashCode64;
this.setSource(methodName.getSourceLine(), methodName.getSourceColumn());
this.removeBrackets = false;
}
public SQLMethodInvokeExpr(String methodName, long methodNameHashCode64) {
this.methodName = methodName;
this.methodNameHashCode64 = methodNameHashCode64;
this.removeBrackets = false;
}
public SQLMethodInvokeExpr(String methodName, SQLExpr owner) {
this.methodName = methodName;
setOwner(owner);
this.removeBrackets = false;
}
public SQLMethodInvokeExpr(String methodName, SQLExpr owner, SQLExpr... params) {
@ -70,6 +75,7 @@ public class SQLMethodInvokeExpr extends SQLExprImpl implements SQLReplaceable,
for (SQLExpr param : params) {
this.addArgument(param);
}
this.removeBrackets = false;
}
public SQLMethodInvokeExpr(String methodName, SQLExpr owner, List<SQLExpr> params) {
@ -78,6 +84,7 @@ public class SQLMethodInvokeExpr extends SQLExprImpl implements SQLReplaceable,
for (SQLExpr param : params) {
this.addArgument(param);
}
this.removeBrackets = false;
}
public long methodNameHashCode64() {
@ -386,6 +393,7 @@ public class SQLMethodInvokeExpr extends SQLExprImpl implements SQLReplaceable,
x.putAttribute(key, value);
}
}
x.setRemoveBrackets(removeBrackets);
}
@Override

View File

@ -39,6 +39,7 @@ public class CKLexer extends Lexer {
map.put("FINAL", Token.FINAL);
map.put("TTL", Token.TTL);
map.put("CODEC", Token.CODEC);
map.remove("ANY");
return new Keywords(map);
}

View File

@ -5,11 +5,18 @@ import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.statement.SQLAssignItem;
import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
import com.alibaba.druid.sql.ast.statement.SQLWithSubqueryClause;
import com.alibaba.druid.sql.dialect.clickhouse.ast.CKSelectQueryBlock;
import com.alibaba.druid.sql.parser.*;
import com.alibaba.druid.sql.parser.Lexer;
import com.alibaba.druid.sql.parser.SQLExprParser;
import com.alibaba.druid.sql.parser.SQLSelectListCache;
import com.alibaba.druid.sql.parser.SQLSelectParser;
import com.alibaba.druid.sql.parser.Token;
import com.alibaba.druid.util.FnvHash;
import java.util.List;
public class CKSelectParser
extends SQLSelectParser {
public CKSelectParser(Lexer lexer) {
@ -85,12 +92,29 @@ public class CKSelectParser
@Override
public void parseFrom(SQLSelectQueryBlock queryBlock) {
super.parseFrom(queryBlock);
if (lexer.token() == Token.FINAL) {
lexer.nextToken();
((CKSelectQueryBlock) queryBlock).setFinal(true);
List<String> comments = null;
if (lexer.hasComment() && lexer.isKeepComments()) {
comments = lexer.readAndResetComments();
}
if (lexer.nextIf(Token.FROM)) {
SQLTableSource from = parseTableSource();
if (comments != null) {
from.addBeforeComment(comments);
}
queryBlock.setFrom(from);
} else {
((CKSelectQueryBlock) queryBlock).setFinal(false);
if (comments != null) {
queryBlock.addAfterComment(comments);
}
}
if (lexer.nextIf(Token.FINAL)) {
if (queryBlock instanceof CKSelectQueryBlock) {
((CKSelectQueryBlock) queryBlock).setFinal(true);
}
}
}

View File

@ -8,7 +8,9 @@ import com.alibaba.druid.sql.dialect.clickhouse.ast.CKCreateTableStatement;
import com.alibaba.druid.sql.dialect.clickhouse.ast.CKSelectQueryBlock;
import com.alibaba.druid.sql.dialect.clickhouse.ast.ClickhouseColumnCodec;
import com.alibaba.druid.sql.dialect.clickhouse.ast.ClickhouseColumnTTL;
import com.alibaba.druid.sql.parser.CharTypes;
import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor;
import com.alibaba.druid.sql.visitor.VisitorFeature;
import com.alibaba.druid.util.StringUtils;
import java.util.List;
@ -230,6 +232,55 @@ public class CKOutputVisitor extends SQLASTOutputVisitor implements CKASTVisitor
return false;
}
@Override
public void printComment(String comment) {
if (comment == null) {
return;
}
if (isEnabled(VisitorFeature.OutputSkipMultilineComment) && comment.startsWith("/*")) {
return;
}
if (isEnabled(VisitorFeature.OutputSkipSingleLineComment)
&& (comment.startsWith("-") || comment.startsWith("#"))) {
return;
}
if (comment.startsWith("--")
&& comment.length() > 2
&& comment.charAt(2) != ' '
&& comment.charAt(2) != '-') {
print0("-- ");
print0(comment.substring(2));
} else if (comment.startsWith("#")
&& comment.length() > 1
&& comment.charAt(1) != ' '
&& comment.charAt(1) != '#') {
print0("# ");
print0(comment.substring(1));
} else if (comment.startsWith("/*")) {
println();
print0(comment);
} else if (comment.startsWith("--")) {
print0(comment);
}
char first = '\0';
for (int i = 0; i < comment.length(); i++) {
char c = comment.charAt(i);
if (CharTypes.isWhitespace(c)) {
continue;
}
first = c;
break;
}
if (first == '-' || first == '#') {
endLineComment = true;
}
}
@Override
protected void printAfterFetch(SQLSelectQueryBlock queryBlock) {
if (queryBlock instanceof CKSelectQueryBlock) {
@ -274,6 +325,19 @@ public class CKOutputVisitor extends SQLASTOutputVisitor implements CKASTVisitor
@Override
protected void printFrom(SQLSelectQueryBlock x) {
SQLTableSource from = x.getFrom();
if (from == null) {
return;
}
List<String> beforeComments = from.getBeforeCommentsDirect();
if (beforeComments != null) {
for (String comment : beforeComments) {
println();
print0(comment);
}
}
super.printFrom(x);
if (x instanceof CKSelectQueryBlock && ((CKSelectQueryBlock) x).isFinal()) {
print0(ucase ? " FINAL" : " final");

View File

@ -3,7 +3,14 @@ package com.alibaba.druid.sql.dialect.hologres.visitor;
import com.alibaba.druid.DbType;
import com.alibaba.druid.sql.ast.SQLPartitionBy;
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
import com.alibaba.druid.sql.dialect.clickhouse.ast.CKSelectQueryBlock;
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGOutputVisitor;
import com.alibaba.druid.sql.parser.CharTypes;
import com.alibaba.druid.sql.visitor.VisitorFeature;
import java.util.List;
public class HologresOutputVisitor extends PGOutputVisitor {
public HologresOutputVisitor(StringBuilder appender, boolean parameterized) {
@ -27,4 +34,74 @@ public class HologresOutputVisitor extends PGOutputVisitor {
print0(ucase ? "PARTITION BY " : "partition by ");
partitionBy.accept(this);
}
@Override
protected void printFrom(SQLSelectQueryBlock x) {
SQLTableSource from = x.getFrom();
if (from == null) {
return;
}
List<String> beforeComments = from.getBeforeCommentsDirect();
if (beforeComments != null) {
for (String comment : beforeComments) {
println();
print0(comment);
}
}
super.printFrom(x);
if (x instanceof CKSelectQueryBlock && ((CKSelectQueryBlock) x).isFinal()) {
print0(ucase ? " FINAL" : " final");
}
}
@Override
public void printComment(String comment) {
if (comment == null) {
return;
}
if (isEnabled(VisitorFeature.OutputSkipMultilineComment) && comment.startsWith("/*")) {
return;
}
if (isEnabled(VisitorFeature.OutputSkipSingleLineComment)
&& (comment.startsWith("-") || comment.startsWith("#"))) {
return;
}
if (comment.startsWith("--")
&& comment.length() > 2
&& comment.charAt(2) != ' '
&& comment.charAt(2) != '-') {
print0("-- ");
print0(comment.substring(2));
} else if (comment.startsWith("#")
&& comment.length() > 1
&& comment.charAt(1) != ' '
&& comment.charAt(1) != '#') {
print0("# ");
print0(comment.substring(1));
} else if (comment.startsWith("/*")) {
println();
print0(comment);
} else if (comment.startsWith("--")) {
print0(comment);
}
char first = '\0';
for (int i = 0; i < comment.length(); i++) {
char c = comment.charAt(i);
if (CharTypes.isWhitespace(c)) {
continue;
}
first = c;
break;
}
if (first == '-' || first == '#') {
endLineComment = true;
}
}
}

View File

@ -353,6 +353,9 @@ public class PGExprParser extends SQLExprParser {
} else if (lexer.identifierEquals(FnvHash.Constants.SECOND)) {
lexer.nextToken();
intervalExpr.setUnit(SQLIntervalUnit.SECOND);
} else if (lexer.identifierEquals(FnvHash.Constants.WEEK)) {
lexer.nextToken();
intervalExpr.setUnit(SQLIntervalUnit.WEEK);
}
return intervalExpr;

View File

@ -2520,17 +2520,25 @@ public class Lexer {
if (ch == '/' && charAt(pos + 1) == '*') {
scanChar();
scanChar();
if (ch == '!' || ch == '+') {
scanChar();
++depth;
}
++depth;
}
if (ch == '*' && charAt(pos + 1) == '/') {
scanChar();
scanChar();
if (0 == --depth) {
break;
int curPos = pos;
boolean terminated = true;
// If '*/' has leading '--' in the same line, just skip it. For example '-- xxxx */'.
while (curPos > 0 && charAt(curPos) != '\n') {
if (charAt(curPos) == '-' && (curPos + 1) < text.length() && charAt(curPos + 1) == '-') {
terminated = false;
}
curPos--;
}
if (terminated) {
scanChar();
scanChar();
if (0 == --depth) {
break;
}
}
}

View File

@ -3657,7 +3657,8 @@ public class SQLExprParser extends SQLParser {
}
protected SQLExpr relationalRestEqeq(SQLExpr expr) {
return expr;
lexer.nextToken();
return new SQLBinaryOpExpr(expr, SQLBinaryOperator.EqEq, expr());
}
protected SQLExpr relationalRestTilde(SQLExpr expr) {

View File

@ -1100,6 +1100,10 @@ public class SQLSelectParser extends SQLParser {
} else {
item = this.exprParser.expr();
}
if (lexer.nextIf(Token.AS)) {
item = new SQLAliasedExpr(item, lexer.stringVal);
lexer.nextToken();
}
if (dialectFeatureEnabled(GroupByItemOrder)) {
if (lexer.token == Token.DESC) {

View File

@ -105,7 +105,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
protected transient int lines;
private TimeZone timeZone;
private boolean endLineComment;
protected boolean endLineComment;
protected SQLDialect dialect;

View File

@ -0,0 +1,97 @@
package com.alibaba.druid.bvt.pool;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidPooledConnection;
import junit.framework.TestCase;
import org.junit.Assert;
import java.sql.Connection;
import java.util.Properties;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 这个场景测试initialSize > maxActive
*
* @author wenshao [szujobs@hotmail.com]
*/
public class UserPasswordVersionTest extends TestCase {
private DruidDataSource dataSource;
protected void setUp() throws Exception {
dataSource = new DruidDataSource();
dataSource.setUrl("jdbc:mock:xxx");
dataSource.setUsername("u0");
dataSource.setPassword("p0");
dataSource.setTestOnBorrow(false);
dataSource.setMaxActive(30);
dataSource.setMaxWait(30);
dataSource.setInitialSize(1);
dataSource.setMinIdle(3);
dataSource.init();
}
protected void tearDown() throws Exception {
dataSource.close();
}
public void test_maxWait() throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(10);
final CountDownLatch latch0 = new CountDownLatch(1);
executor.submit(
() -> {
try {
DruidPooledConnection[] connections = new DruidPooledConnection[10];
for (int i = 0; i < connections.length; i++) {
connections[i] = dataSource.getConnection();
}
for (int i = 0; i < connections.length; i++) {
connections[i].close();
}
assertEquals(connections.length, dataSource.getPoolingCount());
} catch (Exception e) {
e.printStackTrace();
} finally {
latch0.countDown();
}
}
);
latch0.await();
DruidPooledConnection conn = dataSource.getConnection();
assertEquals(0, conn.getConnectionHolder().getUserPasswordVersion());
final CountDownLatch latch1 = new CountDownLatch(1);
executor.submit(() -> {
try {
Properties properties = new Properties();
properties.put("druid.username", "u1");
properties.put("druid.password", "p1");
dataSource.configFromProperties(properties);
} catch (Exception e) {
e.printStackTrace();
} finally {
latch1.countDown();
}
});
latch1.await();
assertEquals(9, dataSource.getPoolingCount());
assertEquals(1, dataSource.getActiveCount());
conn.close();
assertEquals(9, dataSource.getPoolingCount());
assertEquals(0, dataSource.getActiveCount());
DruidPooledConnection conn1 = dataSource.getConnection();
assertEquals(1, conn1.getConnectionHolder().getUserPasswordVersion());
conn1.close();
assertEquals(9, dataSource.getPoolingCount());
assertEquals(0, dataSource.getActiveCount());
}
}

View File

@ -1,3 +1,24 @@
select
/*
/*
xxx
*/
*/ a from test
--------------------
SELECT a
FROM test
------------------------------------------------------------------------------------------------------------------------
select if(a=='G', b, c) from test
--------------------
SELECT if(a == 'G', b, c)
FROM test
------------------------------------------------------------------------------------------------------------------------
select a, b, count(1) from test group by a as c, b as d
--------------------
SELECT a, b, count(1)
FROM test
GROUP BY a AS c, b AS d
------------------------------------------------------------------------------------------------------------------------
select c from b where c=1 ${if(len(a)=0,'and 1=1',"and a>0")} ${if(len(a)=0,'and 1=1',"and a>0")}
--------------------
SELECT c

View File

@ -0,0 +1,33 @@
/*
this is comment 1
this is comment 2
*/
select 1
--------------------
/*
this is comment 1
this is comment 2
*/
SELECT 1
------------------------------------------------------------------------------------------------------------------------
/* this is comment 1 */
select 1
--------------------
/* this is comment 1 */
SELECT 1
------------------------------------------------------------------------------------------------------------------------
select a /* xxxx
xxx
xxxx*/ from test
--------------------
SELECT a
/* xxxx
xxx
xxxx*/
FROM test
------------------------------------------------------------------------------------------------------------------------
select a /* xxxxxxxx*/ from test
--------------------
SELECT a
/* xxxxxxxx*/
FROM test

View File

@ -1,3 +1,37 @@
select cast(($0 + interval $1 week) as date)
--------------------
SELECT CAST(($0 + INTERVAL '$1' WEEK) AS date)
------------------------------------------------------------------------------------------------------------------------
select a from test
-- origin
-- ${if(gFinPeriod="季度","/*","")}
-- origin end
-- new
/*
-- new end
where 1=1
-- origin
-- ${if(gFinPeriod="季度","","*/")}
-- origin end
-- new
*/
--new end
--------------------
SELECT a
FROM test -- origin
-- ${if(gFinPeriod="季度","/*","")}
-- origin end
-- new
/*
-- new end
where 1=1
-- origin
-- ${if(gFinPeriod="季度","","*/")}
-- origin end
-- new
*/
-- new end
------------------------------------------------------------------------------------------------------------------------
SELECT sum(ret_amount) AS '应收金额'
FROM test.test
GROUP BY a ORDER BY '应收金额' DESC;

View File

@ -34,7 +34,7 @@
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.26-SNAPSHOT</version>
<version>1.2.27-SNAPSHOT</version>
</dependency>
<!-- Spring and Spring Boot dependencies -->
<dependency>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>com.alibaba</groupId>
<artifactId>druid-parent</artifactId>
<version>1.2.26-SNAPSHOT</version>
<version>1.2.27-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>druid-spring-boot-3-starter</artifactId>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>com.alibaba</groupId>
<artifactId>druid-parent</artifactId>
<version>1.2.26-SNAPSHOT</version>
<version>1.2.27-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>druid-spring-boot-starter</artifactId>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>com.alibaba</groupId>
<artifactId>druid-parent</artifactId>
<version>1.2.26-SNAPSHOT</version>
<version>1.2.27-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>com.alibaba</groupId>

15
pom.xml
View File

@ -6,7 +6,7 @@
<groupId>com.alibaba</groupId>
<artifactId>druid-parent</artifactId>
<version>1.2.26-SNAPSHOT</version>
<version>1.2.27-SNAPSHOT</version>
<name>${project.artifactId}</name>
<description>A JDBC datasource implementation.</description>
<packaging>pom</packaging>
@ -80,10 +80,6 @@
</developers>
<distributionManagement>
<repository>
<id>central</id>
<url>https://central.sonatype.org/service/local/staging/deploy/maven2/</url>
</repository>
<snapshotRepository>
<id>central</id>
<url>https://central.sonatype.com/repository/maven-snapshots/</url>
@ -176,6 +172,15 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.sonatype.central</groupId>
<artifactId>central-publishing-maven-plugin</artifactId>
<version>0.8.0</version>
<extensions>true</extensions>
<configuration>
<publishingServerId>central</publishingServerId>
</configuration>
</plugin>
</plugins>
<pluginManagement>
<plugins>