提交 397d3126 authored 作者: noelgrandin's avatar noelgrandin

Issue 528: Add Oracle-compatible TO_CHAR function, patch by Daniel Gredler.

上级 46188bab
......@@ -3346,6 +3346,14 @@ This method returns a string.
CALL XMLTEXT('test')
"
"Functions (String)","TO_CHAR","
TO_CHAR(value [, format[, nlsParam]])
","
Oracle-compatible TO_CHAR function that can format a timestamp, a number, or text.
","
CALL TO_CHAR(TIMESTAMP '2010-01-01 00:00:00', 'DD MON, YYYY')
"
"Functions (Time and Date)","CURRENT_DATE","
{ CURRENT_DATE [ () ] | CURDATE() | SYSDATE | TODAY }
","
......
......@@ -44,6 +44,7 @@ Change Log
</li><li>Slightly reduce the memory cost of View metadata.
</li><li>Extend support of "GRANT ALTER ANY SCHEMA TO &lt;user&gt;" to allow grantee ability to manipulate tables
</li><li>Issue 532: Javadoc for ErrorCode.ROLES_AND_RIGHT_CANNOT_BE_MIXED looks wrong
</li><li>Issue 528: Add Oracle-compatible TO_CHAR function, patch by Daniel Gredler.
</li></ul>
<h2>Version 1.3.174 (2013-10-19)</h2>
......
......@@ -72,7 +72,6 @@ See also <a href="build.html#providing_patches">Providing Patches</a>.
</li><li>Store all temp files in the temp directory.
</li><li>Don't use temp files, specially not deleteOnExit (bug 4513817: File.deleteOnExit consumes memory).
Also to allow opening client / server (remote) connections when using LOBs.
</li><li>Sequence: add features [NO] MINVALUE, MAXVALUE, CYCLE.
</li><li>Make DDL (Data Definition) operations transactional.
</li><li>Deferred integrity checking (DEFERRABLE INITIALLY DEFERRED).
</li><li>Groovy Stored Procedures: http://groovy.codehaus.org/GSQL
......@@ -122,7 +121,7 @@ See also <a href="build.html#providing_patches">Providing Patches</a>.
</li><li>Custom class loader to reload functions on demand.
</li><li>Test http://mysql-je.sourceforge.net/
</li><li>H2 Console: the webclient could support more features like phpMyAdmin.
</li><li>Support Oracle functions: TRUNC, NVL2, TO_CHAR, TO_DATE, TO_NUMBER.
</li><li>Support Oracle functions: TO_DATE, TO_NUMBER.
</li><li>Work on the Java to C converter.
</li><li>The HELP information schema can be directly exposed in the Console.
</li><li>Maybe use the 0x1234 notation for binary fields, see MS SQL Server.
......
......@@ -488,6 +488,13 @@ public class ErrorCode {
*/
public static final int SEQUENCE_ATTRIBUTES_INVALID = 90009;
/**
* The error with code <code>90010</code> is thrown when
* trying to format a timestamp or number using TO_CHAR
* with an invalid format.
*/
public static final int INVALID_TO_CHAR_FORMAT = 90010;
/**
* The error with code <code>22007</code> is thrown when
* a text can not be converted to a date, time, or timestamp constant.
......@@ -1884,7 +1891,7 @@ public class ErrorCode {
public static final int JAVA_OBJECT_SERIALIZER_CHANGE_WITH_DATA_TABLE = 90141;
// next are 90010, 90011, 90021, 90039,
// next are 90011, 90021, 90039,
// 90051, 90056, 90110, 90122, 90142
private ErrorCode() {
......
......@@ -6,6 +6,7 @@
*/
package org.h2.expression;
import static org.h2.util.ToChar.toChar;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
......@@ -85,7 +86,7 @@ public class Function extends Expression implements FunctionCall {
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,
CONCAT_WS = 92;
CONCAT_WS = 92, TO_CHAR = 93;
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,
......@@ -280,6 +281,7 @@ public class Function extends Expression implements FunctionCall {
addFunction("REGEXP_REPLACE", REGEXP_REPLACE, 3, Value.STRING);
addFunction("RPAD", RPAD, VAR_ARGS, Value.STRING);
addFunction("LPAD", LPAD, VAR_ARGS, Value.STRING);
addFunction("TO_CHAR", TO_CHAR, VAR_ARGS, Value.STRING);
// date
addFunctionNotDeterministic("CURRENT_DATE", CURRENT_DATE, 0, Value.DATE);
......@@ -1191,6 +1193,25 @@ public class Function extends Expression implements FunctionCall {
case LPAD:
result = ValueString.get(StringUtils.pad(v0.getString(), v1.getInt(), v2 == null ? null : v2.getString(), false), database.getMode().treatEmptyStringsAsNull);
break;
case TO_CHAR:
switch(v0.getType()){
case Value.TIME:
case Value.DATE:
case Value.TIMESTAMP:
result = ValueString.get(toChar(v0.getTimestamp(), v1 == null ? null : v1.getString(), v2 == null ? null : v2.getString()), database.getMode().treatEmptyStringsAsNull);
break;
case Value.SHORT:
case Value.INT:
case Value.LONG:
case Value.DECIMAL:
case Value.DOUBLE:
case Value.FLOAT:
result = ValueString.get(toChar(v0.getBigDecimal(), v1 == null ? null : v1.getString(), v2 == null ? null : v2.getString()), database.getMode().treatEmptyStringsAsNull);
break;
default:
result = ValueString.get(v0.getString(), database.getMode().treatEmptyStringsAsNull);
}
break;
case H2VERSION:
result = ValueString.get(Constants.getVersion(), database.getMode().treatEmptyStringsAsNull);
break;
......@@ -1777,6 +1798,10 @@ public class Function extends Expression implements FunctionCall {
min = 1;
max = 2;
break;
case TO_CHAR:
min = 1;
max = 3;
break;
case REPLACE:
case LOCATE:
case INSTR:
......
......@@ -37,6 +37,7 @@
90007=The object is already closed
90008=Invalid value {0} for parameter {1}
90009=Unable to create or alter sequence {0} because of invalid attributes (start value {1}, min value {2}, max value {3}, increment {4})
90010=Invalid TO_CHAR format {0}
90012=Parameter {0} is not set
90013=Database {0} not found
90014=Error parsing {0}
......
......@@ -1183,6 +1183,10 @@ Returns the XML declaration."
XMLTEXT(valueString [, escapeNewlineBoolean])
","
Creates an XML text element."
"Functions (String)","TO_CHAR","
TO_CHAR(value [, format[, nlsParam]])
","
Oracle-compatible TO_CHAR function that can format a timestamp, a number, or text."
"Functions (Time and Date)","CURRENT_DATE","
{ CURRENT_DATE [ () ] | CURDATE() | SYSDATE | TODAY }
","
......
差异被折叠。
......@@ -712,6 +712,8 @@ public abstract class TestBase {
} else if (expected == null || actual == null) {
fail("Expected: " + expected + " Actual: " + actual + " " + message);
} else if (!expected.equals(actual)) {
int al = expected.length();
int bl = actual.length();
for (int i = 0; i < expected.length(); i++) {
String s = expected.substring(0, i);
if (!actual.startsWith(s)) {
......@@ -719,8 +721,6 @@ public abstract class TestBase {
break;
}
}
int al = expected.length();
int bl = actual.length();
if (al > 4000) {
expected = expected.substring(0, 4000);
}
......@@ -970,6 +970,22 @@ public abstract class TestBase {
}
}
/**
* Check that executing the specified query results in the specified error.
*
* @param expectedErrorMessage the expected error message
* @param stat the statement
* @param sql the SQL statement to execute
*/
protected void assertThrows(String expectedErrorMessage, Statement stat, String sql) {
try {
stat.executeQuery(sql);
fail("Expected error: " + expectedErrorMessage);
} catch (SQLException e) {
assertTrue(e.getMessage().startsWith(expectedErrorMessage));
}
}
/**
* Check if the result set meta data is correct.
*
......
......@@ -743,4 +743,8 @@ lives pauses allocates kicks introduction straightforward getenv
ordinate tweaking fetching rfe yates cookie btrfs cookies
nocycle nomaxvalue nominvalue cycling proceed prospective exhausted contingent
validities hang degenerates freezes emulation gredler cemo koc blanked
reverting blanked jump
\ No newline at end of file
reverting blanked jump capitalization capitalize symbol symbols verbatim
closest resultant savings designator numeral numerals lowercased uppercased
casing epoch century abbreviation scientific circuit emulates blanks substrings
thai tme fmrn fmxxx fmday fml syyyy nov iyy iyyy syear scc fmc fmb fmxx tzr tzd
btc mcmlxxix xliv mdcclxxvi ccxxxviii xii cxlix yyfxyy
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论