提交 47cf69ad authored 作者: Noel Grandin's avatar Noel Grandin 提交者: GitHub

Merge pull request #631 from plus33/master

Fixed issue #497: TO_DATE reports invalid date format for correct format
...@@ -21,6 +21,8 @@ Change Log ...@@ -21,6 +21,8 @@ Change Log
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul> <ul>
<li>Issue #497: Fix TO_DATE in cases of 'inline' text. E.g. the "T" and "Z" in to_date('2017-04-21T00:00:00Z', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')
</li>
<li>Fix bug in MySQL/ORACLE-syntax silently corrupting the modified column in cases of setting the 'NULL'- or 'NOT NULL'-constraint. E.g. alter table T modify C NULL; <li>Fix bug in MySQL/ORACLE-syntax silently corrupting the modified column in cases of setting the 'NULL'- or 'NOT NULL'-constraint. E.g. alter table T modify C NULL;
</li> </li>
<li>Issue #570: MySQL compatibility for ALTER TABLE .. DROP INDEX <li>Issue #570: MySQL compatibility for ALTER TABLE .. DROP INDEX
......
...@@ -9695,7 +9695,7 @@ Test http://mysql-je.sourceforge.net/ ...@@ -9695,7 +9695,7 @@ Test http://mysql-je.sourceforge.net/
H2 Console: the webclient could support more features like phpMyAdmin. H2 Console: the webclient could support more features like phpMyAdmin.
@roadmap_1080_li @roadmap_1080_li
Support Oracle functions: TO_DATE, TO_NUMBER. Support Oracle functions: TO_NUMBER.
@roadmap_1081_li @roadmap_1081_li
Work on the Java to C converter. Work on the Java to C converter.
......
...@@ -9695,7 +9695,7 @@ H2 コンソール アプリケーション ...@@ -9695,7 +9695,7 @@ H2 コンソール アプリケーション
#H2 Console: the webclient could support more features like phpMyAdmin. #H2 Console: the webclient could support more features like phpMyAdmin.
@roadmap_1080_li @roadmap_1080_li
#Support Oracle functions: TO_DATE, TO_NUMBER. #Support Oracle functions: TO_NUMBER.
@roadmap_1081_li @roadmap_1081_li
#Work on the Java to C converter. #Work on the Java to C converter.
......
...@@ -3230,7 +3230,7 @@ roadmap_1076_li=Functional tables should accept parameters from other tables (se ...@@ -3230,7 +3230,7 @@ roadmap_1076_li=Functional tables should accept parameters from other tables (se
roadmap_1077_li=Custom class loader to reload functions on demand. roadmap_1077_li=Custom class loader to reload functions on demand.
roadmap_1078_li=Test http\://mysql-je.sourceforge.net/ roadmap_1078_li=Test http\://mysql-je.sourceforge.net/
roadmap_1079_li=H2 Console\: the webclient could support more features like phpMyAdmin. roadmap_1079_li=H2 Console\: the webclient could support more features like phpMyAdmin.
roadmap_1080_li=Support Oracle functions\: TO_DATE, TO_NUMBER. roadmap_1080_li=Support Oracle functions\: TO_NUMBER.
roadmap_1081_li=Work on the Java to C converter. roadmap_1081_li=Work on the Java to C converter.
roadmap_1082_li=The HELP information schema can be directly exposed in the Console. roadmap_1082_li=The HELP information schema can be directly exposed in the Console.
roadmap_1083_li=Maybe use the 0x1234 notation for binary fields, see MS SQL Server. roadmap_1083_li=Maybe use the 0x1234 notation for binary fields, see MS SQL Server.
......
...@@ -6,11 +6,13 @@ ...@@ -6,11 +6,13 @@
package org.h2.util; package org.h2.util;
import static java.lang.String.format; import static java.lang.String.format;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Calendar; import java.util.Calendar;
import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.GregorianCalendar; import java.util.GregorianCalendar;
import java.util.HashMap; import java.util.HashMap;
...@@ -20,6 +22,7 @@ import java.util.Map; ...@@ -20,6 +22,7 @@ import java.util.Map;
import java.util.TimeZone; import java.util.TimeZone;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.message.DbException; import org.h2.message.DbException;
...@@ -29,6 +32,11 @@ import org.h2.message.DbException; ...@@ -29,6 +32,11 @@ import org.h2.message.DbException;
*/ */
class ToDateTokenizer { class ToDateTokenizer {
/**
* The pattern for a number.
*/
static final Pattern PATTERN_INLINE = Pattern.compile("(\"[^\"]*\")");
/** /**
* The pattern for a number. * The pattern for a number.
*/ */
...@@ -103,6 +111,11 @@ class ToDateTokenizer { ...@@ -103,6 +111,11 @@ class ToDateTokenizer {
*/ */
static final TimeParslet PARSLET_TIME = new TimeParslet(); static final TimeParslet PARSLET_TIME = new TimeParslet();
/**
* The inline parslet. E.g. 'YYYY-MM-DD"T"HH24:MI:SS"Z"' where "T" and "Z" are inlined
*/
static final InlineParslet PARSLET_INLINE = new InlineParslet();
/** /**
* The number of milliseconds in a day. * The number of milliseconds in a day.
*/ */
...@@ -472,6 +485,27 @@ class ToDateTokenizer { ...@@ -472,6 +485,27 @@ class ToDateTokenizer {
} }
} }
/**
* Parslet responsible for parsing year parameter
*/
static class InlineParslet implements ToDateParslet {
@Override
public void parse(ToDateParser params, FormatTokenEnum formatTokenEnum, String formatTokenStr) {
String inputFragmentStr = null;
switch (formatTokenEnum) {
case INLINE:
inputFragmentStr = formatTokenStr.replace("\"", "");
break;
default:
throw new IllegalArgumentException(format(
"%s: Internal Error. Unhandled case: %s", this.getClass()
.getSimpleName(), formatTokenEnum));
}
params.remove(inputFragmentStr, formatTokenStr);
}
}
/** /**
* Match the pattern, or if not possible throw an exception. * Match the pattern, or if not possible throw an exception.
* *
...@@ -610,10 +644,11 @@ class ToDateTokenizer { ...@@ -610,10 +644,11 @@ class ToDateTokenizer {
D(PARSLET_DAY), D(PARSLET_DAY),
// NOT supported yet - // NOT supported yet -
// Julian day; the number of days since Jan 1, 4712 BC. // Julian day; the number of days since Jan 1, 4712 BC.
J(PARSLET_DAY); J(PARSLET_DAY),
// Inline text e.g. to_date('2017-04-21T00:00:00Z', 'YYYY-MM-DD"T"HH24:MI:SS"Z"') where "T" and "Z" are inlined
INLINE(PARSLET_INLINE, PATTERN_INLINE);
private static final List<FormatTokenEnum> EMPTY_LIST = private static final List<FormatTokenEnum> EMPTY_LIST = Collections.emptyList();
new ArrayList<>(0);
private static final Map<Character, List<FormatTokenEnum>> CACHE = private static final Map<Character, List<FormatTokenEnum>> CACHE =
new HashMap<>(FormatTokenEnum.values().length); new HashMap<>(FormatTokenEnum.values().length);
...@@ -656,7 +691,14 @@ class ToDateTokenizer { ...@@ -656,7 +691,14 @@ class ToDateTokenizer {
} }
if (formatStr != null && formatStr.length() > 0) { if (formatStr != null && formatStr.length() > 0) {
Character key = Character.toUpperCase(formatStr.charAt(0)); Character key = Character.toUpperCase(formatStr.charAt(0));
result = CACHE.get(key); switch (key) {
case '"':
result = new ArrayList<FormatTokenEnum>();
result.add(INLINE);
break;
default:
result = CACHE.get(key);
}
} }
if (result == null) { if (result == null) {
result = EMPTY_LIST; result = EMPTY_LIST;
......
...@@ -1309,6 +1309,8 @@ public class TestFunctions extends TestBase implements AggregateFunction { ...@@ -1309,6 +1309,8 @@ public class TestFunctions extends TestBase implements AggregateFunction {
Date date = null; Date date = null;
date = new SimpleDateFormat("yyyy-MM-dd").parse("1979-11-12"); date = new SimpleDateFormat("yyyy-MM-dd").parse("1979-11-12");
assertEquals(date, ToDateParser.toDate("1979-11-12T00:00:00Z", "YYYY-MM-DD\"T\"HH24:MI:SS\"Z\""));
assertEquals(date, ToDateParser.toDate("1979*foo*1112", "YYYY\"*foo*\"MM\"\"DD"));
assertEquals(date, ToDateParser.toDate("1979-11-12", "YYYY-MM-DD")); assertEquals(date, ToDateParser.toDate("1979-11-12", "YYYY-MM-DD"));
assertEquals(date, ToDateParser.toDate("1979/11/12", "YYYY/MM/DD")); assertEquals(date, ToDateParser.toDate("1979/11/12", "YYYY/MM/DD"));
assertEquals(date, ToDateParser.toDate("1979,11,12", "YYYY,MM,DD")); assertEquals(date, ToDateParser.toDate("1979,11,12", "YYYY,MM,DD"));
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论