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

MySQL compatibility: support for CONCAT_WS.

上级 497e6f14
......@@ -2885,6 +2885,15 @@ This method returns a string.
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","
DIFFERENCE(string, string)
","
......
......@@ -18,7 +18,9 @@ Change Log
<h1>Change Log</h1>
<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!
</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
......
......@@ -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,
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,
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,
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 {
// same as CHAR_LENGTH
addFunction("CHARACTER_LENGTH", CHAR_LENGTH, 1, Value.INT);
addFunctionWithNull("CONCAT", CONCAT, VAR_ARGS, Value.STRING);
addFunctionWithNull("CONCAT_WS", CONCAT_WS, VAR_ARGS, Value.STRING);
addFunction("DIFFERENCE", DIFFERENCE, 2, Value.INT);
addFunction("HEXTORAW", HEXTORAW, 1, Value.STRING);
addFunctionWithNull("INSERT", INSERT, 4, Value.STRING);
......@@ -571,9 +573,16 @@ public class Function extends Expression implements FunctionCall {
case OCTET_LENGTH:
result = ValueLong.get(2 * length(v0));
break;
case CONCAT_WS:
case CONCAT: {
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);
if (v == ValueNull.INSTANCE) {
continue;
......@@ -581,7 +590,17 @@ public class Function extends Expression implements FunctionCall {
if (result == ValueNull.INSTANCE) {
result = v;
} 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;
......@@ -1683,6 +1702,7 @@ public class Function extends Expression implements FunctionCall {
break;
case CASE:
case CONCAT:
case CONCAT_WS:
case CSVWRITE:
min = 2;
break;
......
......@@ -1015,6 +1015,10 @@ Returns the character that represents the ASCII value."
CONCAT(string, string [,...])
","
Combines strings."
"Functions (String)","CONCAT_WS","
CONCAT_WS(string, string, string [,...])
","
Combines strings with separator."
"Functions (String)","DIFFERENCE","
DIFFERENCE(string, string)
","
......
......@@ -74,6 +74,7 @@ public class TestFunctions extends TestBase implements AggregateFunction {
testFileRead();
testValue();
testNvl2();
testConcatWs();
deleteDb("functions");
FileUtils.deleteRecursive(TEMP_DIR, true);
}
......@@ -148,6 +149,45 @@ public class TestFunctions extends TestBase implements AggregateFunction {
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 {
Connection conn = getConnection("functions");
Statement stat = conn.createStatement();
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论