mirror of https://github.com/alibaba/druid.git
Compare commits
3 Commits
4e73f73b64
...
c7b42ee51a
Author | SHA1 | Date |
---|---|---|
|
c7b42ee51a | |
|
c8b12f0701 | |
|
c737d2a602 |
|
@ -148,6 +148,7 @@ public class DruidDataSource extends DruidAbstractDataSource
|
|||
private boolean asyncInit;
|
||||
protected boolean killWhenSocketReadTimeout;
|
||||
protected boolean checkExecuteTime;
|
||||
protected boolean closeConnOnFatalError = true;
|
||||
|
||||
private static List<Filter> autoFilters;
|
||||
private boolean loadSpifilterSkip;
|
||||
|
@ -186,6 +187,14 @@ public class DruidDataSource extends DruidAbstractDataSource
|
|||
this.asyncInit = asyncInit;
|
||||
}
|
||||
|
||||
public boolean isCloseConnOnFatalError() {
|
||||
return closeConnOnFatalError;
|
||||
}
|
||||
|
||||
public void setCloseConnOnFatalError(boolean closeConnOnFatalError) {
|
||||
this.closeConnOnFatalError = closeConnOnFatalError;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void configFromPropety(Properties properties) {
|
||||
configFromPropeties(properties);
|
||||
|
@ -1797,7 +1806,7 @@ public class DruidDataSource extends DruidAbstractDataSource
|
|||
ReentrantLock fatalErrorCountLock = hasHolderDataSource ? holder.getDataSource().lock : conn.lock;
|
||||
fatalErrorCountLock.lock();
|
||||
try {
|
||||
if ((!conn.closed) && !conn.disable) {
|
||||
if ((!conn.closed) && !conn.disable && isCloseConnOnFatalError()) {
|
||||
conn.disable(error);
|
||||
requireDiscard = true;
|
||||
}
|
||||
|
|
|
@ -29,16 +29,30 @@ public class SQLVariantRefExpr extends SQLExprImpl {
|
|||
|
||||
private boolean global;
|
||||
private boolean session;
|
||||
private boolean templateParameter;
|
||||
private boolean hasPrefixComma;
|
||||
|
||||
private int index = -1;
|
||||
|
||||
public SQLVariantRefExpr(String name) {
|
||||
this.name = name;
|
||||
if (name.startsWith("${") && name.endsWith("}")) {
|
||||
this.templateParameter = true;
|
||||
} else {
|
||||
this.templateParameter = false;
|
||||
}
|
||||
this.hasPrefixComma = true;
|
||||
}
|
||||
|
||||
public SQLVariantRefExpr(String name, SQLObject parent) {
|
||||
this.name = name;
|
||||
this.parent = parent;
|
||||
if (name.startsWith("${") && name.endsWith("}")) {
|
||||
this.templateParameter = true;
|
||||
} else {
|
||||
this.templateParameter = false;
|
||||
}
|
||||
this.hasPrefixComma = true;
|
||||
}
|
||||
|
||||
public SQLVariantRefExpr(String name, boolean global) {
|
||||
|
@ -70,6 +84,22 @@ public class SQLVariantRefExpr extends SQLExprImpl {
|
|||
this.name = name;
|
||||
}
|
||||
|
||||
public boolean isTemplateParameter() {
|
||||
return templateParameter;
|
||||
}
|
||||
|
||||
public void setTemplateParameter(boolean templateParameter) {
|
||||
this.templateParameter = templateParameter;
|
||||
}
|
||||
|
||||
public boolean isHasPrefixComma() {
|
||||
return hasPrefixComma;
|
||||
}
|
||||
|
||||
public void setHasPrefixComma(boolean hasPrefixComma) {
|
||||
this.hasPrefixComma = hasPrefixComma;
|
||||
}
|
||||
|
||||
public void output(StringBuilder buf) {
|
||||
buf.append(this.name);
|
||||
}
|
||||
|
|
|
@ -2278,7 +2278,7 @@ public class Lexer {
|
|||
if (ch != ':' && ch != '#' && ch != '$' && !(ch == '@' && dialectFeatureEnabled(ScanVariableAt))) {
|
||||
throw new ParserException("illegal variable. " + info());
|
||||
}
|
||||
|
||||
boolean templateParameter = false;
|
||||
mark = pos;
|
||||
bufPos = 1;
|
||||
char ch;
|
||||
|
@ -2296,13 +2296,14 @@ public class Lexer {
|
|||
boolean ident = false;
|
||||
for (; ; ) {
|
||||
ch = charAt(++pos);
|
||||
if (isEOF() || ch == ';' || ch == ';' || ch == '\r' || ch == '\n') {
|
||||
if (isEOF() || (templateParameter && (ch == ';' || ch == ';' || ch == '\r'))) {
|
||||
pos--;
|
||||
bufPos--;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ch == '}' && !ident) {
|
||||
templateParameter = false;
|
||||
if (isIdentifierChar(charAt(pos + 1))) {
|
||||
bufPos++;
|
||||
ident = true;
|
||||
|
@ -2313,6 +2314,7 @@ public class Lexer {
|
|||
|
||||
if (ident && ch == '$') {
|
||||
if (charAt(pos + 1) == '{') {
|
||||
templateParameter = true;
|
||||
bufPos++;
|
||||
ident = false;
|
||||
continue;
|
||||
|
@ -2323,7 +2325,7 @@ public class Lexer {
|
|||
if (isWhitespace(ch)) {
|
||||
pos--;
|
||||
break;
|
||||
} else if (ch == ',' || ch == ')' || ch == '(' || ch == ';') {
|
||||
} else if (ch == ',' || ch == ')' || ch == '(') {
|
||||
pos--;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -2927,8 +2927,7 @@ public class SQLExprParser extends SQLParser {
|
|||
SQLSelectOrderByItem item = parseSelectOrderByItem();
|
||||
item.setParent(parent);
|
||||
items.add(item);
|
||||
while (lexer.token == Token.COMMA) {
|
||||
lexer.nextToken();
|
||||
while (lexer.nextIf(Token.COMMA) || (item.getExpr() instanceof SQLVariantRefExpr && lexer.token == IDENTIFIER)) {
|
||||
item = parseSelectOrderByItem();
|
||||
item.setParent(parent);
|
||||
items.add(item);
|
||||
|
@ -3532,9 +3531,14 @@ public class SQLExprParser extends SQLParser {
|
|||
SQLBinaryOperator operator = andRestGetAndOperator();
|
||||
|
||||
expr = new SQLBinaryOpExpr(expr, operator, rightExp, dbType);
|
||||
} else if (token == VARIANT) {
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Blank, new SQLVariantRefExpr(lexer.stringVal()), dbType);
|
||||
} else if (token == Token.VARIANT) {
|
||||
String value = lexer.stringVal();
|
||||
lexer.nextToken();
|
||||
SQLExpr variantExpr = new SQLVariantRefExpr(value);
|
||||
if (lexer.token == Token.IN) {
|
||||
variantExpr = inRest(variantExpr);
|
||||
}
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Blank, variantExpr, dbType);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
@ -3622,6 +3626,14 @@ public class SQLExprParser extends SQLParser {
|
|||
SQLBinaryOperator op = orRestGetOrOperator();
|
||||
|
||||
expr = new SQLBinaryOpExpr(expr, op, rightExp, dbType);
|
||||
} else if (lexer.token == Token.VARIANT) {
|
||||
String value = lexer.stringVal();
|
||||
lexer.nextToken();
|
||||
SQLExpr variantExpr = new SQLVariantRefExpr(value);
|
||||
if (lexer.token == Token.IN) {
|
||||
variantExpr = inRest(variantExpr);
|
||||
}
|
||||
expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Blank, variantExpr, dbType);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
@ -5954,46 +5966,47 @@ public class SQLExprParser extends SQLParser {
|
|||
|
||||
String alias;
|
||||
List<String> aliasList = null;
|
||||
switch (lexer.token) {
|
||||
case FULL:
|
||||
case TABLESPACE:
|
||||
alias = lexer.stringVal();
|
||||
lexer.nextToken();
|
||||
break;
|
||||
case AS:
|
||||
lexer.nextTokenAlias();
|
||||
if (lexer.token == Token.LITERAL_INT) {
|
||||
alias = '"' + lexer.stringVal() + '"';
|
||||
if (expr instanceof SQLVariantRefExpr && ((SQLVariantRefExpr) expr).isTemplateParameter() && lexer.token != AS) {
|
||||
alias = null;
|
||||
} else {
|
||||
switch (lexer.token) {
|
||||
case FULL:
|
||||
case TABLESPACE:
|
||||
alias = lexer.stringVal();
|
||||
lexer.nextToken();
|
||||
} else if (lexer.token == Token.LPAREN) {
|
||||
lexer.nextToken();
|
||||
aliasList = new ArrayList<String>();
|
||||
|
||||
for (; ; ) {
|
||||
String stringVal = lexer.stringVal();
|
||||
break;
|
||||
case AS:
|
||||
lexer.nextTokenAlias();
|
||||
if (lexer.token == Token.LITERAL_INT) {
|
||||
alias = '"' + lexer.stringVal() + '"';
|
||||
lexer.nextToken();
|
||||
|
||||
aliasList.add(stringVal);
|
||||
|
||||
if (lexer.token() == Token.COMMA) {
|
||||
} else if (lexer.token == Token.LPAREN) {
|
||||
lexer.nextToken();
|
||||
aliasList = new ArrayList<String>();
|
||||
for (; ; ) {
|
||||
String stringVal = lexer.stringVal();
|
||||
lexer.nextToken();
|
||||
continue;
|
||||
aliasList.add(stringVal);
|
||||
if (lexer.token() == Token.COMMA) {
|
||||
lexer.nextToken();
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
accept(Token.RPAREN);
|
||||
accept(Token.RPAREN);
|
||||
|
||||
alias = null;
|
||||
} else {
|
||||
alias = alias();
|
||||
}
|
||||
break;
|
||||
case EOF:
|
||||
alias = null;
|
||||
} else {
|
||||
alias = alias();
|
||||
}
|
||||
break;
|
||||
case EOF:
|
||||
alias = null;
|
||||
break;
|
||||
default:
|
||||
alias = as();
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
alias = as();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (alias == null && isEnabled(SQLParserFeature.SelectItemGenerateAlias)
|
||||
|
|
|
@ -1123,11 +1123,16 @@ public class SQLSelectParser extends SQLParser {
|
|||
|
||||
protected void parseSelectList(SQLSelectQueryBlock queryBlock) {
|
||||
final List<SQLSelectItem> selectList = queryBlock.getSelectList();
|
||||
boolean hasComma = true;
|
||||
for (; ; ) {
|
||||
final SQLSelectItem selectItem = this.exprParser.parseSelectItem();
|
||||
selectList.add(selectItem);
|
||||
selectItem.setParent(queryBlock);
|
||||
|
||||
if (!hasComma && selectItem.getExpr() instanceof SQLVariantRefExpr) {
|
||||
SQLVariantRefExpr sqlVariantRefExpr = (SQLVariantRefExpr) selectItem.getExpr();
|
||||
sqlVariantRefExpr.setHasPrefixComma(false);
|
||||
hasComma = true;
|
||||
}
|
||||
//https://github.com/alibaba/druid/issues/5708
|
||||
if (lexer.hasComment()
|
||||
&& lexer.isKeepComments()
|
||||
|
@ -1137,7 +1142,14 @@ public class SQLSelectParser extends SQLParser {
|
|||
}
|
||||
|
||||
if (lexer.token != Token.COMMA) {
|
||||
break;
|
||||
if (lexer.token == Token.VARIANT) {
|
||||
hasComma = false;
|
||||
continue;
|
||||
} else if (selectItem.getExpr() instanceof SQLVariantRefExpr && ((SQLVariantRefExpr) selectItem.getExpr()).isTemplateParameter() && lexer.token != Token.FROM) {
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int line = lexer.line;
|
||||
|
|
|
@ -222,11 +222,11 @@ public class SQLStatementParser extends SQLParser {
|
|||
case SELECT: {
|
||||
MySqlHintStatement hintStatement = null;
|
||||
if (i == 1
|
||||
&& statementList.size() > 0
|
||||
&& !statementList.isEmpty()
|
||||
&& statementList.get(statementList.size() - i) instanceof MySqlHintStatement) {
|
||||
hintStatement = (MySqlHintStatement) statementList.get(statementList.size() - i);
|
||||
} else if (i > 0 && dialectFeatureEnabled(ParseStatementListSelectUnsupportedSyntax) && !semi
|
||||
&& !(statementList.size() > 0 && statementList.get(statementList.size() - i).isAfterSemi())
|
||||
&& !(!statementList.isEmpty() && statementList.size() - i >= 0 && statementList.get(statementList.size() - i).isAfterSemi())
|
||||
) {
|
||||
throw new ParserException("syntax error. " + lexer.info());
|
||||
}
|
||||
|
|
|
@ -586,8 +586,11 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
|||
lineItemCount = 0;
|
||||
println();
|
||||
}
|
||||
|
||||
print0(", ");
|
||||
if (selectItem.getExpr() instanceof SQLVariantRefExpr && !((SQLVariantRefExpr) selectItem.getExpr()).isHasPrefixComma()) {
|
||||
print0(" ");
|
||||
} else {
|
||||
print0(", ");
|
||||
}
|
||||
}
|
||||
|
||||
if (selectItem.getClass() == SQLSelectItem.class) {
|
||||
|
|
|
@ -338,5 +338,6 @@ public class DruidDataSourceUtils {
|
|||
trySetIntProperty(properties, "druid.socketTimeout", druidDataSource::setSocketTimeout);
|
||||
trySetIntProperty(properties, "druid.transactionQueryTimeout", druidDataSource::setTransactionQueryTimeout);
|
||||
trySetIntProperty(properties, "druid.loginTimeout", druidDataSource::setLoginTimeout);
|
||||
trySetBooleanProperty(properties, "druid.closeConnOnFatalError", druidDataSource::setCloseConnOnFatalError);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -396,6 +396,8 @@ public class DruidDataSourceUtilsTest extends TestCase {
|
|||
properties.put("druid.disableException", druidDisableException);
|
||||
String druidInstanceKey = "@lizongbo";
|
||||
properties.put("druid.instanceKey", druidInstanceKey);
|
||||
String druidCloseConnOnFatalError = "false";
|
||||
properties.put("druid.closeConnOnFatalError", druidCloseConnOnFatalError);
|
||||
|
||||
DruidDataSource dataSource = new DruidDataSource();
|
||||
dataSource.configFromPropeties(properties);
|
||||
|
@ -455,6 +457,7 @@ public class DruidDataSourceUtilsTest extends TestCase {
|
|||
assertEquals(druidKillWhenSocketReadTimeout, String.valueOf(dataSource.isKillWhenSocketReadTimeout()));
|
||||
//assertEquals(druidCheckExecuteTime, String.valueOf(dataSource.isCheckExecuteTime()));
|
||||
//assertEquals(druidLoadSpifilterSkip, String.valueOf(dataSource.isLoadSpifilterSkip()));
|
||||
assertEquals(druidCloseConnOnFatalError, String.valueOf(dataSource.isCloseConnOnFatalError()));
|
||||
}
|
||||
|
||||
public void testGenTestCode() {
|
||||
|
|
|
@ -9,6 +9,57 @@ select ${if(len(a)=0,' 1=1 ',"c")}, ${if(len(a)=0,' 1=1 ',"c")} from b
|
|||
SELECT ${if(len(a)=0,' 1=1 ',"c")}, ${if(len(a)=0,' 1=1 ',"c")}
|
||||
FROM b
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
select a from test where 1=1 ${if(a=1, "and b","and c")} in d
|
||||
--------------------
|
||||
SELECT a
|
||||
FROM test
|
||||
WHERE 1 = 1 ${if(a=1, "and b","and c")} IN (d)
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
select a from test where 1=1
|
||||
and (
|
||||
a.report_item_code in ('${gFinReportItem}') or a.report_item_code ='B002'
|
||||
${if(find('E069',gFinReportItem)>0," or (c.yn_offset_report = 'Y' and a.report_item_code ='E06802') "," ")}
|
||||
)
|
||||
--------------------
|
||||
SELECT a
|
||||
FROM test
|
||||
WHERE 1 = 1
|
||||
AND (a.report_item_code IN ('${gFinReportItem}')
|
||||
OR a.report_item_code = 'B002' ${if(find('E069',gFinReportItem)>0," or (c.yn_offset_report = 'Y' and a.report_item_code ='E06802') "," ")})
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
select ${if(len(a)=0,' 1=1 ',"c")}, ${if(len(a)=0,' 1=1 ',"c")} from b
|
||||
--------------------
|
||||
SELECT ${if(len(a)=0,' 1=1 ',"c")}, ${if(len(a)=0,' 1=1 ',"c")}
|
||||
FROM b
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
select b.merge_region_code as region_code,b.merge_region_name as region_name,b.govern_region_area_union as region_area_subtotal
|
||||
${if(gRegionAreaLevel='合并营运区',",b.govern_region_area_union as region_area_code,b.govern_region_area_union as region_area_name",",b.region_area_code as region_area_code,b.region_area_name as region_area_name")}
|
||||
-- ${if(len(gQtrMonth)=5,"/*","")}
|
||||
,sum(case when a.stat_date = ${gQtrMonth} then a.period_loc_amt else 0 end) as bq_amt
|
||||
from b
|
||||
--------------------
|
||||
SELECT b.merge_region_code AS region_code, b.merge_region_name AS region_name, b.govern_region_area_union AS region_area_subtotal ${if(gRegionAreaLevel='合并营运区',",b.govern_region_area_union as region_area_code,b.govern_region_area_union as region_area_name",",b.region_area_code as region_area_code,b.region_area_name as region_area_name")} -- ${if(len(gQtrMonth)=5,"/*","")}
|
||||
, sum(CASE
|
||||
WHEN a.stat_date = ${gQtrMonth} THEN a.period_loc_amt
|
||||
ELSE 0
|
||||
END) AS bq_amt
|
||||
FROM b
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
select
|
||||
${if(gGyzy_hz=='G'," buyer_name as buyer_name, "," syr as buyer_name, ")}
|
||||
substringUTF8(buyer_name,1,positionUTF8(buyer_name,'(')-1) as tg
|
||||
from a
|
||||
--------------------
|
||||
SELECT ${if(gGyzy_hz=='G'," buyer_name as buyer_name, "," syr as buyer_name, ")}
|
||||
, substringUTF8(buyer_name, 1, positionUTF8(buyer_name, '(') - 1) AS tg
|
||||
FROM a
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
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
|
||||
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")}
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
--test
|
||||
select a from b
|
||||
--------------------
|
||||
|
|
Loading…
Reference in New Issue