提交 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
<h2>Next Version (unreleased)</h2>
<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>
<li>Issue #570: MySQL compatibility for ALTER TABLE .. DROP INDEX
......
......@@ -9695,7 +9695,7 @@ Test http://mysql-je.sourceforge.net/
H2 Console: the webclient could support more features like phpMyAdmin.
@roadmap_1080_li
Support Oracle functions: TO_DATE, TO_NUMBER.
Support Oracle functions: TO_NUMBER.
@roadmap_1081_li
Work on the Java to C converter.
......
......@@ -9695,7 +9695,7 @@ H2 コンソール アプリケーション
#H2 Console: the webclient could support more features like phpMyAdmin.
@roadmap_1080_li
#Support Oracle functions: TO_DATE, TO_NUMBER.
#Support Oracle functions: TO_NUMBER.
@roadmap_1081_li
#Work on the Java to C converter.
......
......@@ -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_1078_li=Test http\://mysql-je.sourceforge.net/
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_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.
......
......@@ -6,11 +6,13 @@
package org.h2.util;
import static java.lang.String.format;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
......@@ -20,6 +22,7 @@ import java.util.Map;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.h2.api.ErrorCode;
import org.h2.message.DbException;
......@@ -29,6 +32,11 @@ import org.h2.message.DbException;
*/
class ToDateTokenizer {
/**
* The pattern for a number.
*/
static final Pattern PATTERN_INLINE = Pattern.compile("(\"[^\"]*\")");
/**
* The pattern for a number.
*/
......@@ -103,6 +111,11 @@ class ToDateTokenizer {
*/
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.
*/
......@@ -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.
*
......@@ -610,10 +644,11 @@ class ToDateTokenizer {
D(PARSLET_DAY),
// NOT supported yet -
// 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 =
new ArrayList<>(0);
private static final List<FormatTokenEnum> EMPTY_LIST = Collections.emptyList();
private static final Map<Character, List<FormatTokenEnum>> CACHE =
new HashMap<>(FormatTokenEnum.values().length);
......@@ -656,8 +691,15 @@ class ToDateTokenizer {
}
if (formatStr != null && formatStr.length() > 0) {
Character key = Character.toUpperCase(formatStr.charAt(0));
switch (key) {
case '"':
result = new ArrayList<FormatTokenEnum>();
result.add(INLINE);
break;
default:
result = CACHE.get(key);
}
}
if (result == null) {
result = EMPTY_LIST;
}
......
......@@ -1309,6 +1309,8 @@ public class TestFunctions extends TestBase implements AggregateFunction {
Date date = null;
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"));
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论