提交 3cef1bc3 authored 作者: Thomas Mueller's avatar Thomas Mueller

MySQL compatibility: support for CONCAT_WS.

上级 497e6f14
...@@ -2885,6 +2885,15 @@ This method returns a string. ...@@ -2885,6 +2885,15 @@ This method returns a string.
CONCAT(NAME, '!') CONCAT(NAME, '!')
" "
"Functions (String)","CONCAT_WS","
CONCAT_WS(separatorString, string, string [,...])
","
Combines strings with separator.
This method returns a string.
","
CONCAT_WS(',', NAME, '!')
"
"Functions (String)","DIFFERENCE"," "Functions (String)","DIFFERENCE","
DIFFERENCE(string, string) DIFFERENCE(string, string)
"," ","
......
...@@ -18,7 +18,9 @@ Change Log ...@@ -18,7 +18,9 @@ Change Log
<h1>Change Log</h1> <h1>Change Log</h1>
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul><li>PostgreSQL compatibility: support for EXTRACT(WEEK FROM dateColumn). <ul><li>MySQL compatibility: support for CONCAT_WS.
Thanks a lot to litailang for the patch!
</li><li>PostgreSQL compatibility: support for EXTRACT(WEEK FROM dateColumn).
Thanks to Prashant Bhat for the patch! Thanks to Prashant Bhat for the patch!
</li><li>Fix for a bug where we would sometimes use the wrong unique constraint to validate foreign key constraints. </li><li>Fix for a bug where we would sometimes use the wrong unique constraint to validate foreign key constraints.
</li><li>Support BOM at the beginning of files for the RUNSCRIPT command </li><li>Support BOM at the beginning of files for the RUNSCRIPT command
......
...@@ -81,7 +81,8 @@ public class Function extends Expression implements FunctionCall { ...@@ -81,7 +81,8 @@ public class Function extends Expression implements FunctionCall {
OCTET_LENGTH = 64, RAWTOHEX = 65, REPEAT = 66, REPLACE = 67, RIGHT = 68, RTRIM = 69, SOUNDEX = 70, OCTET_LENGTH = 64, RAWTOHEX = 65, REPEAT = 66, REPLACE = 67, RIGHT = 68, RTRIM = 69, SOUNDEX = 70,
SPACE = 71, SUBSTR = 72, SUBSTRING = 73, UCASE = 74, LOWER = 75, UPPER = 76, POSITION = 77, TRIM = 78, SPACE = 71, SUBSTR = 72, SUBSTRING = 73, UCASE = 74, LOWER = 75, UPPER = 76, POSITION = 77, TRIM = 78,
STRINGENCODE = 79, STRINGDECODE = 80, STRINGTOUTF8 = 81, UTF8TOSTRING = 82, XMLATTR = 83, XMLNODE = 84, STRINGENCODE = 79, STRINGDECODE = 80, STRINGTOUTF8 = 81, UTF8TOSTRING = 82, XMLATTR = 83, XMLNODE = 84,
XMLCOMMENT = 85, XMLCDATA = 86, XMLSTARTDOC = 87, XMLTEXT = 88, REGEXP_REPLACE = 89, RPAD = 90, LPAD = 91; XMLCOMMENT = 85, XMLCDATA = 86, XMLSTARTDOC = 87, XMLTEXT = 88, REGEXP_REPLACE = 89, RPAD = 90, LPAD = 91,
CONCAT_WS = 92;
public static final int CURDATE = 100, CURTIME = 101, DATE_ADD = 102, DATE_DIFF = 103, DAY_NAME = 104, public static final int CURDATE = 100, CURTIME = 101, DATE_ADD = 102, DATE_DIFF = 103, DAY_NAME = 104,
DAY_OF_MONTH = 105, DAY_OF_WEEK = 106, DAY_OF_YEAR = 107, HOUR = 108, MINUTE = 109, MONTH = 110, MONTH_NAME = 111, DAY_OF_MONTH = 105, DAY_OF_WEEK = 106, DAY_OF_YEAR = 107, HOUR = 108, MINUTE = 109, MONTH = 110, MONTH_NAME = 111,
...@@ -222,6 +223,7 @@ public class Function extends Expression implements FunctionCall { ...@@ -222,6 +223,7 @@ public class Function extends Expression implements FunctionCall {
// same as CHAR_LENGTH // same as CHAR_LENGTH
addFunction("CHARACTER_LENGTH", CHAR_LENGTH, 1, Value.INT); addFunction("CHARACTER_LENGTH", CHAR_LENGTH, 1, Value.INT);
addFunctionWithNull("CONCAT", CONCAT, VAR_ARGS, Value.STRING); addFunctionWithNull("CONCAT", CONCAT, VAR_ARGS, Value.STRING);
addFunctionWithNull("CONCAT_WS", CONCAT_WS, VAR_ARGS, Value.STRING);
addFunction("DIFFERENCE", DIFFERENCE, 2, Value.INT); addFunction("DIFFERENCE", DIFFERENCE, 2, Value.INT);
addFunction("HEXTORAW", HEXTORAW, 1, Value.STRING); addFunction("HEXTORAW", HEXTORAW, 1, Value.STRING);
addFunctionWithNull("INSERT", INSERT, 4, Value.STRING); addFunctionWithNull("INSERT", INSERT, 4, Value.STRING);
...@@ -571,9 +573,16 @@ public class Function extends Expression implements FunctionCall { ...@@ -571,9 +573,16 @@ public class Function extends Expression implements FunctionCall {
case OCTET_LENGTH: case OCTET_LENGTH:
result = ValueLong.get(2 * length(v0)); result = ValueLong.get(2 * length(v0));
break; break;
case CONCAT_WS:
case CONCAT: { case CONCAT: {
result = ValueNull.INSTANCE; result = ValueNull.INSTANCE;
for (int i = 0; i < args.length; i++) { int start = 0;
String separator = "";
if (info.type == CONCAT_WS) {
start = 1;
separator = getNullOrValue(session, args, values, 0).getString();
}
for (int i = start; i < args.length; i++) {
Value v = getNullOrValue(session, args, values, i); Value v = getNullOrValue(session, args, values, i);
if (v == ValueNull.INSTANCE) { if (v == ValueNull.INSTANCE) {
continue; continue;
...@@ -581,7 +590,17 @@ public class Function extends Expression implements FunctionCall { ...@@ -581,7 +590,17 @@ public class Function extends Expression implements FunctionCall {
if (result == ValueNull.INSTANCE) { if (result == ValueNull.INSTANCE) {
result = v; result = v;
} else { } else {
result = ValueString.get(result.getString().concat(v.getString())); String tmp = v.getString();
if (!StringUtils.isNullOrEmpty(separator)
&& !StringUtils.isNullOrEmpty(tmp)) {
tmp = separator.concat(tmp);
}
result = ValueString.get(result.getString().concat(tmp));
}
}
if (info.type == CONCAT_WS) {
if (separator != null && result == ValueNull.INSTANCE) {
result = ValueString.get("");
} }
} }
break; break;
...@@ -1683,6 +1702,7 @@ public class Function extends Expression implements FunctionCall { ...@@ -1683,6 +1702,7 @@ public class Function extends Expression implements FunctionCall {
break; break;
case CASE: case CASE:
case CONCAT: case CONCAT:
case CONCAT_WS:
case CSVWRITE: case CSVWRITE:
min = 2; min = 2;
break; break;
......
...@@ -1015,6 +1015,10 @@ Returns the character that represents the ASCII value." ...@@ -1015,6 +1015,10 @@ Returns the character that represents the ASCII value."
CONCAT(string, string [,...]) CONCAT(string, string [,...])
"," ","
Combines strings." Combines strings."
"Functions (String)","CONCAT_WS","
CONCAT_WS(string, string, string [,...])
","
Combines strings with separator."
"Functions (String)","DIFFERENCE"," "Functions (String)","DIFFERENCE","
DIFFERENCE(string, string) DIFFERENCE(string, string)
"," ","
......
...@@ -74,6 +74,7 @@ public class TestFunctions extends TestBase implements AggregateFunction { ...@@ -74,6 +74,7 @@ public class TestFunctions extends TestBase implements AggregateFunction {
testFileRead(); testFileRead();
testValue(); testValue();
testNvl2(); testNvl2();
testConcatWs();
deleteDb("functions"); deleteDb("functions");
FileUtils.deleteRecursive(TEMP_DIR, true); FileUtils.deleteRecursive(TEMP_DIR, true);
} }
...@@ -148,6 +149,45 @@ public class TestFunctions extends TestBase implements AggregateFunction { ...@@ -148,6 +149,45 @@ public class TestFunctions extends TestBase implements AggregateFunction {
conn.close(); conn.close();
} }
private void testConcatWs() throws SQLException {
Connection conn = getConnection("functions");
Statement stat = conn.createStatement();
String createSQL = "CREATE TABLE testConcat(id BIGINT, txt1 varchar, txt2 varchar, txt3 varchar);";
stat.execute(createSQL);
stat.execute("insert into testConcat(id, txt1, txt2, txt3) values(1, 'test1', 'test2', 'test3')");
stat.execute("insert into testConcat(id, txt1, txt2, txt3) values(2, 'test1', 'test2', null)");
stat.execute("insert into testConcat(id, txt1, txt2, txt3) values(3, 'test1', null, null)");
stat.execute("insert into testConcat(id, txt1, txt2, txt3) values(4, null, 'test2', null)");
stat.execute("insert into testConcat(id, txt1, txt2, txt3) values(5, null, null, null)");
String query = "SELECT concat_ws('_',txt1, txt2, txt3), txt1 FROM testConcat order by id asc";
ResultSet rs = stat.executeQuery(query);
rs.next();
String actual = rs.getString(1);
assertEquals("test1_test2_test3", actual);
rs.next();
actual = rs.getString(1);
assertEquals("test1_test2", actual);
rs.next();
actual = rs.getString(1);
assertEquals("test1", actual);
rs.next();
actual = rs.getString(1);
assertEquals("test2", actual);
rs.next();
actual = rs.getString(1);
assertEquals("", actual);
rs.close();
rs = stat.executeQuery("select concat_ws(null,null,null)");
rs.next();
assertNull(rs.getObject(1));
stat.execute("drop table testConcat");
conn.close();
}
private void testValue() throws SQLException { private void testValue() throws SQLException {
Connection conn = getConnection("functions"); Connection conn = getConnection("functions");
Statement stat = conn.createStatement(); Statement stat = conn.createStatement();
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论