提交 f2759786 authored 作者: noelgrandin's avatar noelgrandin

Add Oracle-compatible TRANSLATE function, patch by Eric Chatellier.

上级 93430bf7
......@@ -3361,6 +3361,14 @@ Oracle-compatible TO_CHAR function that can format a timestamp, a number, or tex
CALL TO_CHAR(TIMESTAMP '2010-01-01 00:00:00', 'DD MON, YYYY')
"
"Functions (String)","TRANSLATE","
TRANSLATE(value , searchString, replacementString]])
","
Oracle-compatible TRANSLATE function that replaces a sequence of characters in a string with another set of characters.
","
CALL TRANSLATE('Hello world', 'eo', 'EO')
"
"Functions (Time and Date)","CURRENT_DATE","
{ CURRENT_DATE [ () ] | CURDATE() | SYSDATE | TODAY }
","
......
......@@ -46,6 +46,7 @@ Change Log
<h2>Next Version (unreleased)</h2>
<ul><li>Support the data type "DATETIME2" as an alias for "DATETIME", for MS SQL Server compatibility.
</li><li>Add Oracle-compatible TRANSLATE function, patch by Eric Chatellier.
</li></ul>
<h2>Version 1.3.176 (2014-04-05)</h2>
......
......@@ -7,6 +7,7 @@
package org.h2.expression;
import static org.h2.util.ToChar.toChar;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
......@@ -94,7 +95,7 @@ public class Function extends Expression implements FunctionCall {
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, CONCAT_WS = 92, TO_CHAR = 93;
LPAD = 91, CONCAT_WS = 92, TO_CHAR = 93, TRANSLATE = 94;
public static final int CURDATE = 100, CURTIME = 101, DATE_ADD = 102,
DATE_DIFF = 103, DAY_NAME = 104, DAY_OF_MONTH = 105,
......@@ -299,6 +300,7 @@ public class Function extends Expression implements FunctionCall {
addFunction("RPAD", RPAD, VAR_ARGS, Value.STRING);
addFunction("LPAD", LPAD, VAR_ARGS, Value.STRING);
addFunction("TO_CHAR", TO_CHAR, VAR_ARGS, Value.STRING);
addFunction("TRANSLATE", TRANSLATE, 3, Value.STRING);
// date
addFunctionNotDeterministic("CURRENT_DATE", CURRENT_DATE,
......@@ -1401,6 +1403,14 @@ public class Function extends Expression implements FunctionCall {
database.getMode().treatEmptyStringsAsNull);
}
break;
case TRANSLATE: {
String matching = v1.getString();
String replacement = v2.getString();
result = ValueString.get(
translate(v0.getString(), matching, replacement),
database.getMode().treatEmptyStringsAsNull);
break;
}
case H2VERSION:
result = ValueString.get(Constants.getVersion(),
database.getMode().treatEmptyStringsAsNull);
......@@ -1910,6 +1920,39 @@ public class Function extends Expression implements FunctionCall {
return e;
}
/** This is the org.apache.commons.lang3.StringUtils
* #replaceChars(String, String, String) implementation
*/
private static String translate(String str, String searchChars, String replaceChars) {
if (str == null || str.length() == 0 || searchChars == null || searchChars.length() == 0) {
return str;
}
if (replaceChars == null) {
replaceChars = ""; // EMPTY
}
boolean modified = false;
int replaceCharsLength = replaceChars.length();
int strLength = str.length();
StringBuilder buf = new StringBuilder(strLength);
for (int i = 0; i < strLength; i++) {
char ch = str.charAt(i);
int index = searchChars.indexOf(ch);
if (index >= 0) {
modified = true;
if (index < replaceCharsLength) {
buf.append(replaceChars.charAt(index));
}
} else {
buf.append(ch);
}
}
if (modified) {
return buf.toString();
}
return str;
}
private static double roundmagic(double d) {
if ((d < 0.0000000000001) && (d > -0.0000000000001)) {
return 0.0;
......
......@@ -92,6 +92,7 @@ public class TestFunctions extends TestBase implements AggregateFunction {
testToCharFromDateTime();
testToCharFromNumber();
testToCharFromText();
testTranslate();
// TODO
// testCachingOfDeterministicFunctionAlias();
......@@ -1162,6 +1163,47 @@ public class TestFunctions extends TestBase implements AggregateFunction {
conn.close();
}
private void testTranslate() throws SQLException {
Connection conn = getConnection("functions");
Statement stat = conn.createStatement();
String createSQL = "CREATE TABLE testTranslate(id BIGINT, " +
"txt1 varchar);";
stat.execute(createSQL);
stat.execute("insert into testTranslate(id, txt1) " +
"values(1, 'test1')");
stat.execute("insert into testTranslate(id, txt1) " +
"values(2, null)");
stat.execute("insert into testTranslate(id, txt1) " +
"values(3, '')");
stat.execute("insert into testTranslate(id, txt1) " +
"values(4, 'caps')");
String query = "SELECT translate(txt1, 'p', 'r') " +
"FROM testTranslate order by id asc";
ResultSet rs = stat.executeQuery(query);
rs.next();
String actual = rs.getString(1);
assertEquals("test1", actual);
rs.next();
actual = rs.getString(1);
assertNull(actual);
rs.next();
actual = rs.getString(1);
assertEquals("", actual);
rs.next();
actual = rs.getString(1);
assertEquals("cars", actual);
rs.close();
rs = stat.executeQuery("select translate(null,null,null)");
rs.next();
assertNull(rs.getObject(1));
stat.execute("drop table testTranslate");
conn.close();
}
private void testToCharFromDateTime() throws SQLException {
deleteDb("functions");
Connection conn = getConnection("functions");
......
......@@ -753,6 +753,6 @@ fmrn fmxxx fmday fml syyyy tzd nov iyy iyyy fmc fmb fmxx tzr btc yyfxyy scc syea
overwrote though randomize readability datagram rsync mongodb divides crypto
predicted prediction wojtek hops jurczyk cbtree predict vast assumption upside
adjusted lastly sgtatham cleaning gillet prevented
angus bernd macdonald eckenfels granting moreover exponential transferring
angus bernd chatellier macdonald eckenfels granting moreover exponential transferring
dedup megabyte breadth traversal affine tucc jentsch yyyymmdd vertica graf
mutate
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论