Unverified 提交 edf9f2d7 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov 提交者: GitHub

Merge pull request #1296 from katzyn/misc

Assorted minor changes
......@@ -2308,39 +2308,25 @@ public class Parser {
private Query parseSelectUnion() {
int start = lastParseIndex;
Query command = parseSelectSub();
return parseSelectUnionExtension(command, start, false);
}
private Query parseSelectUnionExtension(Query command, int start,
boolean unionOnly) {
while (true) {
for (;;) {
SelectUnion.UnionType type;
if (readIf(UNION)) {
SelectUnion union = new SelectUnion(session, command);
if (readIf(ALL)) {
union.setUnionType(SelectUnion.UnionType.UNION_ALL);
type = SelectUnion.UnionType.UNION_ALL;
} else {
readIf(DISTINCT);
union.setUnionType(SelectUnion.UnionType.UNION);
}
union.setRight(parseSelectSub());
command = union;
} else if (readIf(MINUS) || readIf(EXCEPT)) {
SelectUnion union = new SelectUnion(session, command);
union.setUnionType(SelectUnion.UnionType.EXCEPT);
union.setRight(parseSelectSub());
command = union;
type = SelectUnion.UnionType.UNION;
}
} else if (readIf(EXCEPT) || readIf(MINUS)) {
type = SelectUnion.UnionType.EXCEPT;
} else if (readIf(INTERSECT)) {
SelectUnion union = new SelectUnion(session, command);
union.setUnionType(SelectUnion.UnionType.INTERSECT);
union.setRight(parseSelectSub());
command = union;
type = SelectUnion.UnionType.INTERSECT;
} else {
break;
}
command = new SelectUnion(session, type, command, parseSelectSub());
}
if (!unionOnly) {
parseEndOfQuery(command);
}
parseEndOfQuery(command);
setSQL(command, null, start);
return command;
}
......
......@@ -61,7 +61,7 @@ public class SelectUnion extends Query {
INTERSECT
}
private UnionType unionType;
private final UnionType unionType;
/**
* The left hand side of the union (the first subquery).
......@@ -71,7 +71,7 @@ public class SelectUnion extends Query {
/**
* The right hand side of the union (the second subquery).
*/
Query right;
final Query right;
private ArrayList<Expression> expressions;
private Expression[] expressionArray;
......@@ -80,9 +80,11 @@ public class SelectUnion extends Query {
private boolean isPrepared, checkInit;
private boolean isForUpdate;
public SelectUnion(Session session, Query query) {
public SelectUnion(Session session, UnionType unionType, Query query, Query right) {
super(session);
this.unionType = unionType;
this.left = query;
this.right = right;
}
@Override
......@@ -96,18 +98,10 @@ public class SelectUnion extends Query {
right.prepareJoinBatch();
}
public void setUnionType(UnionType type) {
this.unionType = type;
}
public UnionType getUnionType() {
return unionType;
}
public void setRight(Query select) {
right = select;
}
public Query getLeft() {
return left;
}
......
......@@ -252,7 +252,7 @@ public class Function extends Expression implements FunctionCall {
addFunction("OCTET_LENGTH", OCTET_LENGTH, 1, Value.LONG);
addFunction("RAWTOHEX", RAWTOHEX, 1, Value.STRING);
addFunction("REPEAT", REPEAT, 2, Value.STRING);
addFunction("REPLACE", REPLACE, VAR_ARGS, Value.STRING, false, true,true);
addFunctionWithNull("REPLACE", REPLACE, VAR_ARGS, Value.STRING);
addFunction("RIGHT", RIGHT, 2, Value.STRING);
addFunction("RTRIM", RTRIM, VAR_ARGS, Value.STRING);
addFunction("SOUNDEX", SOUNDEX, 1, Value.STRING);
......@@ -421,8 +421,7 @@ public class Function extends Expression implements FunctionCall {
VAR_ARGS, Value.LONG);
addFunction("ARRAY_GET", ARRAY_GET,
2, Value.NULL);
addFunction("ARRAY_CONTAINS", ARRAY_CONTAINS,
2, Value.BOOLEAN, false, true, true);
addFunctionWithNull("ARRAY_CONTAINS", ARRAY_CONTAINS, 2, Value.BOOLEAN);
addFunction("CSVREAD", CSVREAD,
VAR_ARGS, Value.RESULT_SET, false, false, false);
addFunction("CSVWRITE", CSVWRITE,
......@@ -514,17 +513,6 @@ public class Function extends Expression implements FunctionCall {
addFunction(name, type, parameterCount, returnDataType, false, true, true);
}
/**
* Get the function info object for this function, or null if there is no
* such function.
*
* @param name the function name
* @return the function info
*/
private static FunctionInfo getFunctionInfo(String name) {
return FUNCTIONS.get(name);
}
/**
* Get an instance of the given function for this database.
* If no function with this name is found, null is returned.
......@@ -538,7 +526,7 @@ public class Function extends Expression implements FunctionCall {
// if not yet converted to uppercase, do it now
name = StringUtils.toUpperEnglish(name);
}
FunctionInfo info = getFunctionInfo(name);
FunctionInfo info = FUNCTIONS.get(name);
if (info == null) {
return null;
}
......@@ -914,7 +902,7 @@ public class Function extends Expression implements FunctionCall {
if (v0 == ValueNull.INSTANCE) {
result = getNullOrValue(session, args, values, 1);
}
result = convertResult(result);
result = result.convertTo(dataType, -1, database.getMode());
break;
}
case CASEWHEN: {
......@@ -1079,10 +1067,6 @@ public class Function extends Expression implements FunctionCall {
return result;
}
private Value convertResult(Value v) {
return v.convertTo(dataType, -1, database.getMode());
}
private static boolean cancelStatement(Session session, int targetSessionId) {
session.getUser().checkAdmin();
Session[] sessions = session.getDatabase().getSessions(false);
......
......@@ -79,10 +79,6 @@ public class LocalDateTimeUtils {
* {@code java.time.LocalDate#of(int, int, int)} or {@code null}.
*/
private static final Method LOCAL_DATE_OF_YEAR_MONTH_DAY;
/**
* {@code java.time.LocalDate#parse(CharSequence)} or {@code null}.
*/
private static final Method LOCAL_DATE_PARSE;
/**
* {@code java.time.LocalDate#getYear()} or {@code null}.
*/
......@@ -113,11 +109,6 @@ public class LocalDateTimeUtils {
*/
private static final Method TIMESTAMP_TO_INSTANT;
/**
* {@code java.time.LocalTime#parse(CharSequence)} or {@code null}.
*/
private static final Method LOCAL_TIME_PARSE;
/**
* {@code java.time.LocalDateTime#plusNanos(long)} or {@code null}.
*/
......@@ -130,10 +121,6 @@ public class LocalDateTimeUtils {
* {@code java.time.LocalDateTime#toLocalTime()} or {@code null}.
*/
private static final Method LOCAL_DATE_TIME_TO_LOCAL_TIME;
/**
* {@code java.time.LocalDateTime#parse(CharSequence)} or {@code null}.
*/
private static final Method LOCAL_DATE_TIME_PARSE;
/**
* {@code java.time.ZoneOffset#ofTotalSeconds(int)} or {@code null}.
......@@ -145,10 +132,6 @@ public class LocalDateTimeUtils {
* {@code null}.
*/
private static final Method OFFSET_DATE_TIME_OF_LOCAL_DATE_TIME_ZONE_OFFSET;
/**
* {@code java.time.OffsetDateTime#parse(CharSequence)} or {@code null}.
*/
private static final Method OFFSET_DATE_TIME_PARSE;
/**
* {@code java.time.OffsetDateTime#toLocalDateTime()} or {@code null}.
*/
......@@ -183,8 +166,6 @@ public class LocalDateTimeUtils {
LOCAL_DATE_OF_YEAR_MONTH_DAY = getMethod(LOCAL_DATE, "of",
int.class, int.class, int.class);
LOCAL_DATE_PARSE = getMethod(LOCAL_DATE, "parse",
CharSequence.class);
LOCAL_DATE_GET_YEAR = getMethod(LOCAL_DATE, "getYear");
LOCAL_DATE_GET_MONTH_VALUE = getMethod(LOCAL_DATE, "getMonthValue");
LOCAL_DATE_GET_DAY_OF_MONTH = getMethod(LOCAL_DATE, "getDayOfMonth");
......@@ -194,12 +175,9 @@ public class LocalDateTimeUtils {
INSTANT_GET_NANO = getMethod(INSTANT, "getNano");
TIMESTAMP_TO_INSTANT = getMethod(Timestamp.class, "toInstant");
LOCAL_TIME_PARSE = getMethod(LOCAL_TIME, "parse", CharSequence.class);
LOCAL_DATE_TIME_PLUS_NANOS = getMethod(LOCAL_DATE_TIME, "plusNanos", long.class);
LOCAL_DATE_TIME_TO_LOCAL_DATE = getMethod(LOCAL_DATE_TIME, "toLocalDate");
LOCAL_DATE_TIME_TO_LOCAL_TIME = getMethod(LOCAL_DATE_TIME, "toLocalTime");
LOCAL_DATE_TIME_PARSE = getMethod(LOCAL_DATE_TIME, "parse", CharSequence.class);
ZONE_OFFSET_OF_TOTAL_SECONDS = getMethod(ZONE_OFFSET, "ofTotalSeconds", int.class);
......@@ -207,14 +185,12 @@ public class LocalDateTimeUtils {
OFFSET_DATE_TIME_GET_OFFSET = getMethod(OFFSET_DATE_TIME, "getOffset");
OFFSET_DATE_TIME_OF_LOCAL_DATE_TIME_ZONE_OFFSET = getMethod(
OFFSET_DATE_TIME, "of", LOCAL_DATE_TIME, ZONE_OFFSET);
OFFSET_DATE_TIME_PARSE = getMethod(OFFSET_DATE_TIME, "parse", CharSequence.class);
ZONE_OFFSET_GET_TOTAL_SECONDS = getMethod(ZONE_OFFSET, "getTotalSeconds");
} else {
LOCAL_TIME_OF_NANO = null;
LOCAL_TIME_TO_NANO = null;
LOCAL_DATE_OF_YEAR_MONTH_DAY = null;
LOCAL_DATE_PARSE = null;
LOCAL_DATE_GET_YEAR = null;
LOCAL_DATE_GET_MONTH_VALUE = null;
LOCAL_DATE_GET_DAY_OF_MONTH = null;
......@@ -222,16 +198,13 @@ public class LocalDateTimeUtils {
INSTANT_GET_EPOCH_SECOND = null;
INSTANT_GET_NANO = null;
TIMESTAMP_TO_INSTANT = null;
LOCAL_TIME_PARSE = null;
LOCAL_DATE_TIME_PLUS_NANOS = null;
LOCAL_DATE_TIME_TO_LOCAL_DATE = null;
LOCAL_DATE_TIME_TO_LOCAL_TIME = null;
LOCAL_DATE_TIME_PARSE = null;
ZONE_OFFSET_OF_TOTAL_SECONDS = null;
OFFSET_DATE_TIME_TO_LOCAL_DATE_TIME = null;
OFFSET_DATE_TIME_GET_OFFSET = null;
OFFSET_DATE_TIME_OF_LOCAL_DATE_TIME_ZONE_OFFSET = null;
OFFSET_DATE_TIME_PARSE = null;
ZONE_OFFSET_GET_TOTAL_SECONDS = null;
}
}
......@@ -252,62 +225,6 @@ public class LocalDateTimeUtils {
return IS_JAVA8_DATE_API_PRESENT;
}
/**
* Parses an ISO date string into a java.time.LocalDate.
*
* @param text the ISO date string
* @return the java.time.LocalDate instance
*/
public static Object parseLocalDate(CharSequence text) {
try {
return LOCAL_DATE_PARSE.invoke(null, text);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new IllegalArgumentException("error when parsing text '" + text + "'", e);
}
}
/**
* Parses an ISO time string into a java.time.LocalTime.
*
* @param text the ISO time string
* @return the java.time.LocalTime instance
*/
public static Object parseLocalTime(CharSequence text) {
try {
return LOCAL_TIME_PARSE.invoke(null, text);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new IllegalArgumentException("error when parsing text '" + text + "'", e);
}
}
/**
* Parses an ISO date string into a java.time.LocalDateTime.
*
* @param text the ISO date string
* @return the java.time.LocalDateTime instance
*/
public static Object parseLocalDateTime(CharSequence text) {
try {
return LOCAL_DATE_TIME_PARSE.invoke(null, text);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new IllegalArgumentException("error when parsing text '" + text + "'", e);
}
}
/**
* Parses an ISO date string into a java.time.OffsetDateTime.
*
* @param text the ISO date string
* @return the java.time.OffsetDateTime instance
*/
public static Object parseOffsetDateTime(CharSequence text) {
try {
return OFFSET_DATE_TIME_PARSE.invoke(null, text);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new IllegalArgumentException("error when parsing text '" + text + "'", e);
}
}
private static Class<?> tryGetClass(String className) {
try {
return Class.forName(className);
......
......@@ -32,6 +32,7 @@ import java.util.UUID;
import org.h2.api.ErrorCode;
import org.h2.api.Trigger;
import org.h2.engine.SysProperties;
import org.h2.message.DbException;
import org.h2.test.TestBase;
import org.h2.test.TestDb;
import org.h2.util.LocalDateTimeUtils;
......@@ -44,6 +45,44 @@ public class TestPreparedStatement extends TestDb {
private static final int LOB_SIZE = 4000, LOB_SIZE_BIG = 512 * 1024;
/**
* {@code java.time.LocalDate#parse(CharSequence)} or {@code null}.
*/
private static final Method LOCAL_DATE_PARSE;
/**
* {@code java.time.LocalTime#parse(CharSequence)} or {@code null}.
*/
private static final Method LOCAL_TIME_PARSE;
/**
* {@code java.time.LocalDateTime#parse(CharSequence)} or {@code null}.
*/
private static final Method LOCAL_DATE_TIME_PARSE;
/**
* {@code java.time.OffsetDateTime#parse(CharSequence)} or {@code null}.
*/
private static final Method OFFSET_DATE_TIME_PARSE;
static {
if (LocalDateTimeUtils.isJava8DateApiPresent()) {
try {
LOCAL_DATE_PARSE = LocalDateTimeUtils.LOCAL_DATE.getMethod("parse", CharSequence.class);
LOCAL_TIME_PARSE = LocalDateTimeUtils.LOCAL_TIME.getMethod("parse", CharSequence.class);
LOCAL_DATE_TIME_PARSE = LocalDateTimeUtils.LOCAL_DATE_TIME.getMethod("parse", CharSequence.class);
OFFSET_DATE_TIME_PARSE = LocalDateTimeUtils.OFFSET_DATE_TIME.getMethod("parse", CharSequence.class);
} catch (NoSuchMethodException e) {
throw DbException.convert(e);
}
} else {
LOCAL_DATE_PARSE = null;
LOCAL_TIME_PARSE = null;
LOCAL_DATE_TIME_PARSE = null;
OFFSET_DATE_TIME_PARSE = null;
}
}
/**
* Run just this test.
*
......@@ -53,6 +92,62 @@ public class TestPreparedStatement extends TestDb {
TestBase.createCaller().init().test();
}
/**
* Parses an ISO date string into a java.time.LocalDate.
*
* @param text the ISO date string
* @return the java.time.LocalDate instance
*/
public static Object parseLocalDate(CharSequence text) {
try {
return LOCAL_DATE_PARSE.invoke(null, text);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new IllegalArgumentException("error when parsing text '" + text + "'", e);
}
}
/**
* Parses an ISO time string into a java.time.LocalTime.
*
* @param text the ISO time string
* @return the java.time.LocalTime instance
*/
public static Object parseLocalTime(CharSequence text) {
try {
return LOCAL_TIME_PARSE.invoke(null, text);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new IllegalArgumentException("error when parsing text '" + text + "'", e);
}
}
/**
* Parses an ISO date string into a java.time.LocalDateTime.
*
* @param text the ISO date string
* @return the java.time.LocalDateTime instance
*/
public static Object parseLocalDateTime(CharSequence text) {
try {
return LOCAL_DATE_TIME_PARSE.invoke(null, text);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new IllegalArgumentException("error when parsing text '" + text + "'", e);
}
}
/**
* Parses an ISO date string into a java.time.OffsetDateTime.
*
* @param text the ISO date string
* @return the java.time.OffsetDateTime instance
*/
public static Object parseOffsetDateTime(CharSequence text) {
try {
return OFFSET_DATE_TIME_PARSE.invoke(null, text);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new IllegalArgumentException("error when parsing text '" + text + "'", e);
}
}
@Override
public void test() throws Exception {
deleteDb("preparedStatement");
......@@ -643,14 +738,14 @@ public class TestPreparedStatement extends TestDb {
return;
}
PreparedStatement prep = conn.prepareStatement("SELECT ?");
Object localDate = LocalDateTimeUtils.parseLocalDate("2001-02-03");
Object localDate = parseLocalDate("2001-02-03");
prep.setObject(1, localDate);
ResultSet rs = prep.executeQuery();
rs.next();
Object localDate2 = rs.getObject(1, LocalDateTimeUtils.LOCAL_DATE);
assertEquals(localDate, localDate2);
rs.close();
localDate = LocalDateTimeUtils.parseLocalDate("-0509-01-01");
localDate = parseLocalDate("-0509-01-01");
prep.setObject(1, localDate);
rs = prep.executeQuery();
rs.next();
......@@ -665,31 +760,31 @@ public class TestPreparedStatement extends TestDb {
rs = prep.executeQuery();
rs.next();
localDate2 = rs.getObject(1, LocalDateTimeUtils.LOCAL_DATE);
assertEquals(LocalDateTimeUtils.parseLocalDate("1500-03-01"), localDate2);
assertEquals(parseLocalDate("1500-03-01"), localDate2);
rs.close();
prep.setString(1, "1400-02-29");
rs = prep.executeQuery();
rs.next();
localDate2 = rs.getObject(1, LocalDateTimeUtils.LOCAL_DATE);
assertEquals(LocalDateTimeUtils.parseLocalDate("1400-03-01"), localDate2);
assertEquals(parseLocalDate("1400-03-01"), localDate2);
rs.close();
prep.setString(1, "1300-02-29");
rs = prep.executeQuery();
rs.next();
localDate2 = rs.getObject(1, LocalDateTimeUtils.LOCAL_DATE);
assertEquals(LocalDateTimeUtils.parseLocalDate("1300-03-01"), localDate2);
assertEquals(parseLocalDate("1300-03-01"), localDate2);
rs.close();
prep.setString(1, "-0100-02-29");
rs = prep.executeQuery();
rs.next();
localDate2 = rs.getObject(1, LocalDateTimeUtils.LOCAL_DATE);
assertEquals(LocalDateTimeUtils.parseLocalDate("-0100-03-01"), localDate2);
assertEquals(parseLocalDate("-0100-03-01"), localDate2);
rs.close();
/*
* Check that date that doesn't exist in traditional calendar can be set and
* read with LocalDate and can be read with getDate() as a next date.
*/
localDate = LocalDateTimeUtils.parseLocalDate("1582-10-05");
localDate = parseLocalDate("1582-10-05");
prep.setObject(1, localDate);
rs = prep.executeQuery();
rs.next();
......@@ -718,14 +813,14 @@ public class TestPreparedStatement extends TestDb {
return;
}
PreparedStatement prep = conn.prepareStatement("SELECT ?");
Object localTime = LocalDateTimeUtils.parseLocalTime("04:05:06");
Object localTime = parseLocalTime("04:05:06");
prep.setObject(1, localTime);
ResultSet rs = prep.executeQuery();
rs.next();
Object localTime2 = rs.getObject(1, LocalDateTimeUtils.LOCAL_TIME);
assertEquals(localTime, localTime2);
rs.close();
localTime = LocalDateTimeUtils.parseLocalTime("04:05:06.123456789");
localTime = parseLocalTime("04:05:06.123456789");
prep.setObject(1, localTime);
rs = prep.executeQuery();
rs.next();
......@@ -739,7 +834,7 @@ public class TestPreparedStatement extends TestDb {
return;
}
PreparedStatement prep = conn.prepareStatement("SELECT ?");
Object localDateTime = LocalDateTimeUtils.parseLocalDateTime("2001-02-03T04:05:06");
Object localDateTime = parseLocalDateTime("2001-02-03T04:05:06");
prep.setObject(1, localDateTime);
ResultSet rs = prep.executeQuery();
rs.next();
......@@ -753,8 +848,7 @@ public class TestPreparedStatement extends TestDb {
return;
}
PreparedStatement prep = conn.prepareStatement("SELECT ?");
Object offsetDateTime = LocalDateTimeUtils
.parseOffsetDateTime("2001-02-03T04:05:06+02:30");
Object offsetDateTime = parseOffsetDateTime("2001-02-03T04:05:06+02:30");
prep.setObject(1, offsetDateTime);
ResultSet rs = prep.executeQuery();
rs.next();
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论