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

Merge pull request #1370 from katzyn/function

Add NEWID() as alias to RANDOM_UUID() in SQL Server compatibility mode
...@@ -28,6 +28,8 @@ import org.h2.engine.Database; ...@@ -28,6 +28,8 @@ import org.h2.engine.Database;
import org.h2.engine.Mode; import org.h2.engine.Mode;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.mode.FunctionsMSSQLServer;
import org.h2.mode.FunctionsMySQL;
import org.h2.schema.Schema; import org.h2.schema.Schema;
import org.h2.schema.Sequence; import org.h2.schema.Sequence;
import org.h2.security.BlockCipher; import org.h2.security.BlockCipher;
...@@ -143,7 +145,7 @@ public class Function extends Expression implements FunctionCall { ...@@ -143,7 +145,7 @@ public class Function extends Expression implements FunctionCall {
public static final int ROW_NUMBER = 300; public static final int ROW_NUMBER = 300;
private static final int VAR_ARGS = -1; protected static final int VAR_ARGS = -1;
private static final long PRECISION_UNKNOWN = -1; private static final long PRECISION_UNKNOWN = -1;
private static final HashMap<String, FunctionInfo> FUNCTIONS = new HashMap<>(256); private static final HashMap<String, FunctionInfo> FUNCTIONS = new HashMap<>(256);
...@@ -151,11 +153,13 @@ public class Function extends Expression implements FunctionCall { ...@@ -151,11 +153,13 @@ public class Function extends Expression implements FunctionCall {
protected Expression[] args; protected Expression[] args;
private final FunctionInfo info; protected final FunctionInfo info;
private ArrayList<Expression> varArgs; private ArrayList<Expression> varArgs;
private int dataType, scale; protected int dataType;
private long precision = PRECISION_UNKNOWN;
private int displaySize; protected int scale;
protected long precision = PRECISION_UNKNOWN;
protected int displaySize;
private final Database database; private final Database database;
static { static {
...@@ -239,12 +243,8 @@ public class Function extends Expression implements FunctionCall { ...@@ -239,12 +243,8 @@ public class Function extends Expression implements FunctionCall {
addFunction("LCASE", LCASE, 1, Value.STRING); addFunction("LCASE", LCASE, 1, Value.STRING);
addFunction("LEFT", LEFT, 2, Value.STRING); addFunction("LEFT", LEFT, 2, Value.STRING);
addFunction("LENGTH", LENGTH, 1, Value.LONG); addFunction("LENGTH", LENGTH, 1, Value.LONG);
// alias for MSSQLServer
addFunction("LEN", LENGTH, 1, Value.LONG);
// 2 or 3 arguments // 2 or 3 arguments
addFunction("LOCATE", LOCATE, VAR_ARGS, Value.INT); addFunction("LOCATE", LOCATE, VAR_ARGS, Value.INT);
// alias for MSSQLServer
addFunction("CHARINDEX", LOCATE, VAR_ARGS, Value.INT);
// same as LOCATE with 2 arguments // same as LOCATE with 2 arguments
addFunction("POSITION", LOCATE, 2, Value.INT); addFunction("POSITION", LOCATE, 2, Value.INT);
addFunction("INSTR", INSTR, VAR_ARGS, Value.INT); addFunction("INSTR", INSTR, VAR_ARGS, Value.INT);
...@@ -292,9 +292,6 @@ public class Function extends Expression implements FunctionCall { ...@@ -292,9 +292,6 @@ public class Function extends Expression implements FunctionCall {
addFunction("TO_TIMESTAMP", TO_TIMESTAMP, VAR_ARGS, Value.TIMESTAMP); addFunction("TO_TIMESTAMP", TO_TIMESTAMP, VAR_ARGS, Value.TIMESTAMP);
addFunction("ADD_MONTHS", ADD_MONTHS, 2, Value.TIMESTAMP); addFunction("ADD_MONTHS", ADD_MONTHS, 2, Value.TIMESTAMP);
addFunction("TO_TIMESTAMP_TZ", TO_TIMESTAMP_TZ, VAR_ARGS, Value.TIMESTAMP_TZ); addFunction("TO_TIMESTAMP_TZ", TO_TIMESTAMP_TZ, VAR_ARGS, Value.TIMESTAMP_TZ);
// alias for MSSQLServer
addFunctionNotDeterministic("GETDATE", CURDATE,
0, Value.DATE);
addFunctionNotDeterministic("CURRENT_TIME", CURRENT_TIME, addFunctionNotDeterministic("CURRENT_TIME", CURRENT_TIME,
VAR_ARGS, Value.TIME); VAR_ARGS, Value.TIME);
addFunctionNotDeterministic("LOCALTIME", CURRENT_TIME, addFunctionNotDeterministic("LOCALTIME", CURRENT_TIME,
...@@ -474,7 +471,13 @@ public class Function extends Expression implements FunctionCall { ...@@ -474,7 +471,13 @@ public class Function extends Expression implements FunctionCall {
addFunction("VALUES", VALUES, 1, Value.NULL, false, true, false); addFunction("VALUES", VALUES, 1, Value.NULL, false, true, false);
} }
protected Function(Database database, FunctionInfo info) { /**
* Creates a new instance of function.
*
* @param database database
* @param info function information
*/
public Function(Database database, FunctionInfo info) {
this.database = database; this.database = database;
this.info = info; this.info = info;
if (info.parameterCount == VAR_ARGS) { if (info.parameterCount == VAR_ARGS) {
...@@ -487,15 +490,8 @@ public class Function extends Expression implements FunctionCall { ...@@ -487,15 +490,8 @@ public class Function extends Expression implements FunctionCall {
private static void addFunction(String name, int type, int parameterCount, private static void addFunction(String name, int type, int parameterCount,
int returnDataType, boolean nullIfParameterIsNull, boolean deterministic, int returnDataType, boolean nullIfParameterIsNull, boolean deterministic,
boolean bufferResultSetToLocalTemp) { boolean bufferResultSetToLocalTemp) {
FunctionInfo info = new FunctionInfo(); FUNCTIONS.put(name, new FunctionInfo(name, type, parameterCount, returnDataType, nullIfParameterIsNull,
info.name = name; deterministic, bufferResultSetToLocalTemp));
info.type = type;
info.parameterCount = parameterCount;
info.returnDataType = returnDataType;
info.nullIfParameterIsNull = nullIfParameterIsNull;
info.deterministic = deterministic;
info.bufferResultSetToLocalTemp = bufferResultSetToLocalTemp;
FUNCTIONS.put(name, info);
} }
private static void addFunctionNotDeterministic(String name, int type, private static void addFunctionNotDeterministic(String name, int type,
...@@ -528,8 +524,15 @@ public class Function extends Expression implements FunctionCall { ...@@ -528,8 +524,15 @@ public class Function extends Expression implements FunctionCall {
} }
FunctionInfo info = FUNCTIONS.get(name); FunctionInfo info = FUNCTIONS.get(name);
if (info == null) { if (info == null) {
switch (database.getMode().getEnum()) {
case MSSQLServer:
return FunctionsMSSQLServer.getFunction(database, name);
case MySQL:
return FunctionsMySQL.getFunction(database, name);
default:
return null; return null;
} }
}
switch (info.type) { switch (info.type) {
case TABLE: case TABLE:
case TABLE_DISTINCT: case TABLE_DISTINCT:
...@@ -539,6 +542,16 @@ public class Function extends Expression implements FunctionCall { ...@@ -539,6 +542,16 @@ public class Function extends Expression implements FunctionCall {
} }
} }
/**
* Returns function information for the specified function name.
*
* @param upperName the function name in upper case
* @return the function information or {@code null}
*/
public static FunctionInfo getFunctionInfo(String upperName) {
return FUNCTIONS.get(upperName);
}
/** /**
* Set the parameter expression at the given index. * Set the parameter expression at the given index.
* *
...@@ -1090,7 +1103,7 @@ public class Function extends Expression implements FunctionCall { ...@@ -1090,7 +1103,7 @@ public class Function extends Expression implements FunctionCall {
return table.getDiskSpaceUsed(); return table.getDiskSpaceUsed();
} }
private static Value getNullOrValue(Session session, Expression[] args, protected static Value getNullOrValue(Session session, Expression[] args,
Value[] values, int i) { Value[] values, int i) {
if (i >= args.length) { if (i >= args.length) {
return null; return null;
...@@ -1106,7 +1119,7 @@ public class Function extends Expression implements FunctionCall { ...@@ -1106,7 +1119,7 @@ public class Function extends Expression implements FunctionCall {
return v; return v;
} }
private Value getValueWithArgs(Session session, Expression[] args) { protected Value getValueWithArgs(Session session, Expression[] args) {
Value[] values = new Value[args.length]; Value[] values = new Value[args.length];
if (info.nullIfParameterIsNull) { if (info.nullIfParameterIsNull) {
for (int i = 0; i < args.length; i++) { for (int i = 0; i < args.length; i++) {
......
...@@ -8,41 +8,91 @@ package org.h2.expression; ...@@ -8,41 +8,91 @@ package org.h2.expression;
/** /**
* This class contains information about a built-in function. * This class contains information about a built-in function.
*/ */
class FunctionInfo { public final class FunctionInfo {
/** /**
* The name of the function. * The name of the function.
*/ */
String name; public final String name;
/** /**
* The function type. * The function type.
*/ */
int type; public final int type;
/** /**
* The data type of the return value. * The number of parameters.
*/ */
int returnDataType; final int parameterCount;
/** /**
* The number of parameters. * The data type of the return value.
*/ */
int parameterCount; public final int returnDataType;
/** /**
* If the result of the function is NULL if any of the parameters is NULL. * If the result of the function is NULL if any of the parameters is NULL.
*/ */
boolean nullIfParameterIsNull; final boolean nullIfParameterIsNull;
/** /**
* If this function always returns the same value for the same parameters. * If this function always returns the same value for the same parameters.
*/ */
boolean deterministic; public final boolean deterministic;
/** /**
* Should the return value ResultSet be buffered in a local temporary file? * Should the return value ResultSet be buffered in a local temporary file?
*/ */
boolean bufferResultSetToLocalTemp = true; final boolean bufferResultSetToLocalTemp;
/**
* Creates new instance of built-in function information.
*
* @param name
* the name of the function
* @param type
* the function type
* @param parameterCount
* the number of parameters
* @param returnDataType
* the data type of the return value
* @param nullIfParameterIsNull
* if the result of the function is NULL if any of the parameters
* is NULL
* @param deterministic
* if this function always returns the same value for the same
* parameters
* @param bufferResultSetToLocalTemp
* should the return value ResultSet be buffered in a local
* temporary file?
*/
public FunctionInfo(String name, int type, int parameterCount, int returnDataType, boolean nullIfParameterIsNull,
boolean deterministic, boolean bufferResultSetToLocalTemp) {
this.name = name;
this.type = type;
this.parameterCount = parameterCount;
this.returnDataType = returnDataType;
this.nullIfParameterIsNull = nullIfParameterIsNull;
this.deterministic = deterministic;
this.bufferResultSetToLocalTemp = bufferResultSetToLocalTemp;
}
/**
* Creates a copy of built-in function information with a different name.
*
* @param source
* the source information
* @param name
* the new name
*/
public FunctionInfo(FunctionInfo source, String name) {
this.name = name;
type = source.type;
returnDataType = source.returnDataType;
parameterCount = source.parameterCount;
nullIfParameterIsNull = source.nullIfParameterIsNull;
deterministic = source.deterministic;
bufferResultSetToLocalTemp = source.bufferResultSetToLocalTemp;
}
} }
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.mode;
import java.util.HashMap;
import org.h2.engine.Database;
import org.h2.expression.Function;
import org.h2.expression.FunctionInfo;
/**
* Base class for mode-specific functions.
*/
abstract class FunctionsBase extends Function {
FunctionsBase(Database database, FunctionInfo info) {
super(database, info);
}
/**
* Copy a standard function to a mode functions with a different name.
*
* @param functions
* mode functions
* @param stdName
* the name of the standard function
* @param newName
* the name of the mode-specific function
*/
static void copyFunction(HashMap<String, FunctionInfo> functions, String stdName, String newName) {
functions.put(newName, new FunctionInfo(Function.getFunctionInfo(stdName), newName));
}
}
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.mode;
import java.util.HashMap;
import org.h2.engine.Database;
import org.h2.expression.Function;
import org.h2.expression.FunctionInfo;
/**
* Functions for {@link org.h2.engine.Mode.ModeEnum#MSSQLServer} compatibility
* mode.
*/
public final class FunctionsMSSQLServer extends FunctionsBase {
private static final HashMap<String, FunctionInfo> FUNCTIONS = new HashMap<>();
static {
copyFunction(FUNCTIONS, "LOCATE", "CHARINDEX");
copyFunction(FUNCTIONS, "CURRENT_DATE", "GETDATE");
copyFunction(FUNCTIONS, "LENGTH", "LEN");
copyFunction(FUNCTIONS, "RANDOM_UUID", "NEWID");
}
/**
* Returns mode-specific function for a given name, or {@code null}.
*
* @param database
* the database
* @param upperName
* the upper-case name of a function
* @return the function with specified name or {@code null}
*/
public static Function getFunction(Database database, String upperName) {
FunctionInfo info = FUNCTIONS.get(upperName);
return info != null ? new Function(database, info) : null;
}
private FunctionsMSSQLServer(Database database, FunctionInfo info) {
super(database, info);
}
}
...@@ -5,14 +5,24 @@ ...@@ -5,14 +5,24 @@
*/ */
package org.h2.mode; package org.h2.mode;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.Locale; import java.util.Locale;
import org.h2.api.ErrorCode;
import org.h2.engine.Database;
import org.h2.engine.Session;
import org.h2.expression.Expression;
import org.h2.expression.Function;
import org.h2.expression.FunctionInfo;
import org.h2.expression.ValueExpression;
import org.h2.message.DbException;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
import org.h2.value.DataType;
import org.h2.value.Value;
import org.h2.value.ValueInt;
import org.h2.value.ValueString;
/** /**
* This class implements some MySQL-specific functions. * This class implements some MySQL-specific functions.
...@@ -20,7 +30,20 @@ import org.h2.util.StringUtils; ...@@ -20,7 +30,20 @@ import org.h2.util.StringUtils;
* @author Jason Brittain * @author Jason Brittain
* @author Thomas Mueller * @author Thomas Mueller
*/ */
public class FunctionsMySQL { public class FunctionsMySQL extends FunctionsBase {
private static final int UNIX_TIMESTAMP = 1001, FROM_UNIXTIME = 1002, DATE = 1003;
private static final HashMap<String, FunctionInfo> FUNCTIONS = new HashMap<>();
static {
FUNCTIONS.put("UNIX_TIMESTAMP", new FunctionInfo("UNIX_TIMESTAMP", UNIX_TIMESTAMP,
VAR_ARGS, Value.INT, false, false, false));
FUNCTIONS.put("FROM_UNIXTIME", new FunctionInfo("FROM_UNIXTIME", FROM_UNIXTIME,
VAR_ARGS, Value.STRING, false, true, false));
FUNCTIONS.put("DATE", new FunctionInfo("DATE", DATE,
1, Value.DATE, false, true, false));
}
/** /**
* The date format of a MySQL formatted date/time. * The date format of a MySQL formatted date/time.
...@@ -60,27 +83,6 @@ public class FunctionsMySQL { ...@@ -60,27 +83,6 @@ public class FunctionsMySQL {
"%%", "%", "%%", "%",
}; };
/**
* Register the functionality in the database.
* Nothing happens if the functions are already registered.
*
* @param conn the connection
*/
public static void register(Connection conn) throws SQLException {
String[] init = {
"UNIX_TIMESTAMP", "unixTimestamp",
"FROM_UNIXTIME", "fromUnixTime",
"DATE", "date",
};
Statement stat = conn.createStatement();
for (int i = 0; i < init.length; i += 2) {
String alias = init[i], method = init[i + 1];
stat.execute(
"CREATE ALIAS IF NOT EXISTS " + alias +
" FOR \"" + FunctionsMySQL.class.getName() + "." + method + "\"");
}
}
/** /**
* Get the seconds since 1970-01-01 00:00:00 UTC. * Get the seconds since 1970-01-01 00:00:00 UTC.
* See * See
...@@ -140,24 +142,104 @@ public class FunctionsMySQL { ...@@ -140,24 +142,104 @@ public class FunctionsMySQL {
} }
/** /**
* See * Returns mode-specific function for a given name, or {@code null}.
* http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_date
* This function is dependent on the exact formatting of the MySQL date/time
* string.
* *
* @param dateTime The date/time String from which to extract just the date * @param database
* part. * the database
* @return the date part of the given date/time String argument. * @param upperName
* the upper-case name of a function
* @return the function with specified name or {@code null}
*/ */
public static String date(String dateTime) { public static Function getFunction(Database database, String upperName) {
if (dateTime == null) { FunctionInfo info = FUNCTIONS.get(upperName);
return null; return info != null ? new FunctionsMySQL(database, info) : null;
}
FunctionsMySQL(Database database, FunctionInfo info) {
super(database, info);
}
@Override
protected void checkParameterCount(int len) {
int min, max;
switch (info.type) {
case UNIX_TIMESTAMP:
min = 0;
max = 2;
break;
case FROM_UNIXTIME:
min = 1;
max = 2;
break;
case DATE:
min = 1;
max = 1;
break;
default:
DbException.throwInternalError("type=" + info.type);
return;
}
if (len < min || len > max) {
throw DbException.get(ErrorCode.INVALID_PARAMETER_COUNT_2, info.name, min + ".." + max);
}
}
@Override
public Expression optimize(Session session) {
boolean allConst = info.deterministic;
for (int i = 0; i < args.length; i++) {
Expression e = args[i];
if (e == null) {
continue;
}
e = e.optimize(session);
args[i] = e;
if (!e.isConstant()) {
allConst = false;
}
}
if (allConst) {
return ValueExpression.get(getValue(session));
}
dataType = info.returnDataType;
DataType dt = DataType.getDataType(dataType);
precision = dt.defaultPrecision;
scale = dt.defaultScale;
displaySize = dt.defaultDisplaySize;
return this;
}
@Override
protected Value getValueWithArgs(Session session, Expression[] args) {
Value[] values = new Value[args.length];
Value v0 = getNullOrValue(session, args, values, 0);
Value v1 = getNullOrValue(session, args, values, 1);
Value result;
switch (info.type) {
case UNIX_TIMESTAMP:
result = ValueInt.get(v0 == null ? unixTimestamp() : unixTimestamp(v0.getTimestamp()));
break;
case FROM_UNIXTIME:
result = ValueString.get(
v1 == null ? fromUnixTime(v0.getInt()) : fromUnixTime(v0.getInt(), v1.getString()));
break;
case DATE:
switch (v0.getType()) {
case Value.DATE:
result = v0;
break;
default:
v0 = v0.convertTo(Value.TIMESTAMP);
//$FALL-THROUGH$
case Value.TIMESTAMP:
case Value.TIMESTAMP_TZ:
result = v0.convertTo(Value.DATE);
} }
int index = dateTime.indexOf(' '); break;
if (index != -1) { default:
return dateTime.substring(0, index); throw DbException.throwInternalError("type=" + info.type);
} }
return dateTime; return result;
} }
} }
...@@ -307,7 +307,6 @@ public class TestCompatibility extends TestDb { ...@@ -307,7 +307,6 @@ public class TestCompatibility extends TestDb {
stat.execute("DROP TABLE IF EXISTS TEST"); stat.execute("DROP TABLE IF EXISTS TEST");
stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)"); stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)");
stat.execute("INSERT INTO TEST VALUES(1, 'Hello'), (2, 'World')"); stat.execute("INSERT INTO TEST VALUES(1, 'Hello'), (2, 'World')");
org.h2.mode.FunctionsMySQL.register(conn);
assertResult("0", stat, "SELECT UNIX_TIMESTAMP('1970-01-01 00:00:00Z')"); assertResult("0", stat, "SELECT UNIX_TIMESTAMP('1970-01-01 00:00:00Z')");
assertResult("1196418619", stat, assertResult("1196418619", stat,
"SELECT UNIX_TIMESTAMP('2007-11-30 10:30:19Z')"); "SELECT UNIX_TIMESTAMP('2007-11-30 10:30:19Z')");
......
...@@ -2,3 +2,21 @@ ...@@ -2,3 +2,21 @@
-- and the EPL 1.0 (http://h2database.com/html/license.html). -- and the EPL 1.0 (http://h2database.com/html/license.html).
-- Initial Developer: H2 Group -- Initial Developer: H2 Group
-- --
SELECT LENGTH(CAST(RANDOM_UUID() AS VARCHAR));
>> 36
SELECT RANDOM_UUID() = RANDOM_UUID();
>> FALSE
SELECT NEWID();
> exception FUNCTION_NOT_FOUND_1
SET MODE MSSQLServer;
> ok
SELECT LENGTH(CAST(NEWID() AS VARCHAR));
>> 36
SET MODE Regular;
> ok
...@@ -9,8 +9,23 @@ create memory table test(id int primary key, name varchar(255)); ...@@ -9,8 +9,23 @@ create memory table test(id int primary key, name varchar(255));
insert into test values(1, 'Hello'); insert into test values(1, 'Hello');
> update count: 1 > update count: 1
select length(null) en, len(null) en2, length('This has 17 chars') e_17, len('MSSQLServer uses the len keyword') e_32 from test; select length(null) en, length('This has 17 chars') e_17 from test;
> EN EN2 E_17 E_32 > EN E_17
> ---- ---- ---- ---- > ---- ----
> null null 17 32 > null 17
> rows: 1 > rows: 1
SELECT LEN(NULL);
> exception FUNCTION_NOT_FOUND_1
SET MODE MSSQLServer;
> ok
select len(null) en, len('MSSQLServer uses the len keyword') e_32 from test;
> EN E_32
> ---- ----
> null 32
> rows: 1
SET MODE Regular;
> ok
\ No newline at end of file
...@@ -20,3 +20,18 @@ select locate('World', 'Hello World') e7, locate('hi', 'abchihihi', 2) e3 from t ...@@ -20,3 +20,18 @@ select locate('World', 'Hello World') e7, locate('hi', 'abchihihi', 2) e3 from t
> -- -- > -- --
> 7 4 > 7 4
> rows: 1 > rows: 1
SELECT CHARINDEX('test', 'test');
> exception FUNCTION_NOT_FOUND_1
SET MODE MSSQLServer;
> ok
select charindex('World', 'Hello World') e7, charindex('hi', 'abchihihi', 2) e3 from test;
> E7 E3
> -- --
> 7 4
> rows: 1
SET MODE Regular;
> ok
...@@ -14,3 +14,15 @@ select length(curdate()) c1, length(current_date()) c2, substring(curdate(), 5, ...@@ -14,3 +14,15 @@ select length(curdate()) c1, length(current_date()) c2, substring(curdate(), 5,
> -- -- -- > -- -- --
> 10 10 - > 10 10 -
> rows: 1 > rows: 1
SELECT GETDATE();
> exception FUNCTION_NOT_FOUND_1
SET MODE MSSQLServer;
> ok
SELECT CURRENT_DATE = GETDATE();
>> TRUE
SET MODE Regular;
> ok
\ No newline at end of file
...@@ -524,7 +524,6 @@ public class Build extends BuildBase { ...@@ -524,7 +524,6 @@ public class Build extends BuildBase {
exclude("temp/org/h2/jcr/*"). exclude("temp/org/h2/jcr/*").
exclude("temp/org/h2/java/*"). exclude("temp/org/h2/java/*").
exclude("temp/org/h2/jcr/*"). exclude("temp/org/h2/jcr/*").
exclude("temp/org/h2/mode/*").
exclude("temp/org/h2/samples/*"). exclude("temp/org/h2/samples/*").
exclude("temp/org/h2/server/ftp/*"). exclude("temp/org/h2/server/ftp/*").
exclude("temp/org/h2/test/*"). exclude("temp/org/h2/test/*").
...@@ -594,7 +593,6 @@ public class Build extends BuildBase { ...@@ -594,7 +593,6 @@ public class Build extends BuildBase {
exclude("temp/org/h2/jcr/*"). exclude("temp/org/h2/jcr/*").
exclude("temp/org/h2/java/*"). exclude("temp/org/h2/java/*").
exclude("temp/org/h2/jcr/*"). exclude("temp/org/h2/jcr/*").
exclude("temp/org/h2/mode/*").
exclude("temp/org/h2/samples/*"). exclude("temp/org/h2/samples/*").
exclude("temp/org/h2/server/ftp/*"). exclude("temp/org/h2/server/ftp/*").
exclude("temp/org/h2/test/*"). exclude("temp/org/h2/test/*").
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论