Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
2ae9a839
提交
2ae9a839
authored
5月 01, 2010
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Functions now reside within a schema.
上级
8e3b97cb
隐藏空白字符变更
内嵌
并排
正在显示
17 个修改的文件
包含
249 行增加
和
90 行删除
+249
-90
changelog.html
h2/src/docsrc/html/changelog.html
+9
-1
features.html
h2/src/docsrc/html/features.html
+3
-2
roadmap.html
h2/src/docsrc/html/roadmap.html
+1
-1
Parser.java
h2/src/main/org/h2/command/Parser.java
+72
-28
CreateAggregate.java
h2/src/main/org/h2/command/ddl/CreateAggregate.java
+7
-1
CreateFunctionAlias.java
h2/src/main/org/h2/command/ddl/CreateFunctionAlias.java
+16
-9
DropDatabase.java
h2/src/main/org/h2/command/ddl/DropDatabase.java
+1
-1
DropFunctionAlias.java
h2/src/main/org/h2/command/ddl/DropFunctionAlias.java
+6
-5
SetComment.java
h2/src/main/org/h2/command/ddl/SetComment.java
+1
-2
ScriptCommand.java
h2/src/main/org/h2/command/dml/ScriptCommand.java
+3
-4
SysProperties.java
h2/src/main/org/h2/constant/SysProperties.java
+9
-0
Database.java
h2/src/main/org/h2/engine/Database.java
+0
-18
FunctionAlias.java
h2/src/main/org/h2/engine/FunctionAlias.java
+21
-9
Schema.java
h2/src/main/org/h2/schema/Schema.java
+33
-2
MetaTable.java
h2/src/main/org/h2/table/MetaTable.java
+6
-4
TestAll.java
h2/src/test/org/h2/test/TestAll.java
+2
-2
TestFunctions.java
h2/src/test/org/h2/test/db/TestFunctions.java
+59
-1
没有找到文件。
h2/src/docsrc/html/changelog.html
浏览文件 @
2ae9a839
...
...
@@ -18,7 +18,15 @@ Change Log
<h1>
Change Log
</h1>
<h2>
Next Version (unreleased)
</h2>
<ul><li>
Cluster: after a cluster node failed, the second cluster node can now be re-created
<ul><li>
New system property h2.functionsInSchema (default is false).
If enabled, the SCRIPT statement always includes the schema name in the CREATE ALIAS statement
(even if the schema is PUBLIC). This is not backward compatible with H2 versions 1.2.134 and older.
</li><li>
Functions: it is no longer required to add a space after a comma in the parameter list.
Example: CREATE ALIAS PARSE_INT FOR "java.lang.Integer.parseInt(java.lang.String,int)"
</li><li>
Functions now reside within a schema, similar to sequences.
If you do create such functions in schemas other than PUBLIC, then the database
can not be opened with older versions of H2.
</li><li>
Cluster: after a cluster node failed, the second cluster node can now be re-created
and started without having to stop the first cluster node, and without having to stop
running applications. To do that, append ;AUTO_RECONNECT=TRUE to the database URL.
</li><li>
SET EXCLUSIVE now supports 0 (disable), 1 (enable), and 2 (enable and close all other connections).
...
...
h2/src/docsrc/html/features.html
浏览文件 @
2ae9a839
...
...
@@ -1445,8 +1445,9 @@ The settings in the URL override the settings passed as a separate parameter.
In addition to the built-in functions, this database supports user-defined Java functions.
In this database, Java functions can be used as stored procedures as well.
A function must be declared (registered) before it can be used.
A functions can be defined using source code, or as a reference to
a compiled class that is available in the classpath.
A function can be defined using source code, or as a reference to
a compiled class that is available in the classpath. By default, the
function aliases are stored in the current schema.
</p>
<h3>
Referencing a Compiled Method
</h3>
...
...
h2/src/docsrc/html/roadmap.html
浏览文件 @
2ae9a839
...
...
@@ -25,6 +25,7 @@ See also <a href="build.html#providing_patches">Providing Patches</a>.
<h2>
Version 1.3.x: Planned Changes
</h2>
<ul><li>
Lob storage: enable the system property h2.lobInDatabase by default.
</li><li>
Automatic ANALYZE: set the system property h2.analyzeAuto to 2000.
</li><li>
Enable h2.functionsInSchema.
</li></ul>
<h2>
Priority 1
</h2>
...
...
@@ -254,7 +255,6 @@ See also <a href="build.html#providing_patches">Providing Patches</a>.
</li><li>
Native search: support "phrase search", wildcard search (* and ?), case-insensitive search, boolean operators, and grouping
</li><li>
Improve documentation of access rights
</li><li>
Support ENUM data type (see MySQL, PostgreSQL, MS SQL Server, maybe others)
</li><li>
Support a schema name for Java functions
</li><li>
Remember the user defined data type (domain) of a column
</li><li>
Support Jackcess (MS Access databases)
</li><li>
Built-in methods to write large objects (BLOB and CLOB): FILE_WRITE('test.txt', 'Hello World')
...
...
h2/src/main/org/h2/command/Parser.java
浏览文件 @
2ae9a839
...
...
@@ -313,7 +313,7 @@ public class Parser {
}
else
if
(
readIf
(
"CREATE"
))
{
c
=
parseCreate
();
}
else
if
(
readIf
(
"CALL"
))
{
c
=
parse
r
Call
();
c
=
parseCall
();
}
else
if
(
readIf
(
"CHECKPOINT"
))
{
c
=
parseCheckpoint
();
}
else
if
(
readIf
(
"COMMENT"
))
{
...
...
@@ -420,7 +420,7 @@ public class Parser {
case
'v'
:
case
'V'
:
if
(
readIf
(
"VALUES"
))
{
c
=
parse
r
Call
();
c
=
parseCall
();
}
break
;
case
'w'
:
...
...
@@ -980,6 +980,7 @@ public class Parser {
}
}
else
{
String
tableName
=
readIdentifierWithSchema
(
null
);
Schema
schema
=
getSchema
();
if
(
readIf
(
"("
))
{
Schema
mainSchema
=
database
.
getSchema
(
Constants
.
SCHEMA_MAIN
);
if
(
equalsToken
(
tableName
,
RangeTable
.
NAME
))
{
...
...
@@ -989,7 +990,7 @@ public class Parser {
read
(
")"
);
table
=
new
RangeTable
(
mainSchema
,
min
,
max
);
}
else
{
Expression
func
=
readFunction
(
tableName
);
Expression
func
=
readFunction
(
schema
,
tableName
);
if
(!(
func
instanceof
FunctionCall
))
{
throw
getSyntaxError
();
}
...
...
@@ -1163,8 +1164,9 @@ public class Parser {
return
command
;
}
else
if
(
readIf
(
"ALIAS"
))
{
boolean
ifExists
=
readIfExists
(
false
);
DropFunctionAlias
command
=
new
DropFunctionAlias
(
session
);
command
.
setAliasName
(
readUniqueIdentifier
());
String
aliasName
=
readIdentifierWithSchema
();
DropFunctionAlias
command
=
new
DropFunctionAlias
(
session
,
getSchema
());
command
.
setAliasName
(
aliasName
);
ifExists
=
readIfExists
(
ifExists
);
command
.
setIfExists
(
ifExists
);
return
command
;
...
...
@@ -1934,10 +1936,15 @@ public class Parser {
return
orderList
;
}
private
JavaFunction
readJavaFunction
(
String
name
)
{
FunctionAlias
functionAlias
=
database
.
findFunctionAlias
(
name
);
private
JavaFunction
readJavaFunction
(
Schema
schema
,
String
functionName
)
{
FunctionAlias
functionAlias
=
null
;
if
(
schema
!=
null
)
{
functionAlias
=
schema
.
findFunction
(
functionName
);
}
else
{
functionAlias
=
findFunctionAlias
(
session
.
getCurrentSchemaName
(),
functionName
);
}
if
(
functionAlias
==
null
)
{
throw
DbException
.
get
(
ErrorCode
.
FUNCTION_NOT_FOUND_1
,
n
ame
);
throw
DbException
.
get
(
ErrorCode
.
FUNCTION_NOT_FOUND_1
,
functionN
ame
);
}
Expression
[]
args
;
ArrayList
<
Expression
>
argList
=
New
.
arrayList
();
...
...
@@ -1967,7 +1974,10 @@ public class Parser {
return
agg
;
}
private
Expression
readFunction
(
String
name
)
{
private
Expression
readFunction
(
Schema
schema
,
String
name
)
{
if
(
schema
!=
null
)
{
return
readJavaFunction
(
schema
,
name
);
}
int
agg
=
Aggregate
.
getAggregateType
(
name
);
if
(
agg
>=
0
)
{
return
readAggregate
(
agg
);
...
...
@@ -1978,7 +1988,7 @@ public class Parser {
if
(
aggregate
!=
null
)
{
return
readJavaAggregate
(
aggregate
);
}
return
readJavaFunction
(
name
);
return
readJavaFunction
(
n
ull
,
n
ame
);
}
switch
(
function
.
getFunctionType
())
{
case
Function
.
CAST
:
{
...
...
@@ -2145,7 +2155,13 @@ public class Parser {
return
expr
;
}
String
name
=
readColumnIdentifier
();
if
(
readIf
(
"."
))
{
Schema
s
=
database
.
findSchema
(
objectName
);
if
(
s
!=
null
&&
readIf
(
"("
))
{
// only if the token before the dot is a valid schema name,
// otherwise the old style Oracle outer join doesn't work:
// t.x = t2.x(+)
return
readFunction
(
s
,
name
);
}
else
if
(
readIf
(
"."
))
{
String
schema
=
objectName
;
objectName
=
name
;
expr
=
readWildcardOrSequenceValue
(
schema
,
objectName
);
...
...
@@ -2153,7 +2169,15 @@ public class Parser {
return
expr
;
}
name
=
readColumnIdentifier
();
if
(
readIf
(
"."
))
{
if
(
readIf
(
"("
))
{
String
databaseName
=
schema
;
if
(!
equalsToken
(
database
.
getShortName
(),
databaseName
))
{
throw
DbException
.
get
(
ErrorCode
.
DATABASE_NOT_FOUND_1
,
databaseName
);
}
schema
=
objectName
;
objectName
=
name
;
return
readFunction
(
database
.
getSchema
(
schema
),
name
);
}
else
if
(
readIf
(
"."
))
{
String
databaseName
=
schema
;
if
(!
equalsToken
(
database
.
getShortName
(),
databaseName
))
{
throw
DbException
.
get
(
ErrorCode
.
DATABASE_NOT_FOUND_1
,
databaseName
);
...
...
@@ -2239,7 +2263,7 @@ public class Parser {
if
(
currentTokenQuoted
)
{
read
();
if
(
readIf
(
"("
))
{
r
=
readFunction
(
name
);
r
=
readFunction
(
n
ull
,
n
ame
);
}
else
if
(
readIf
(
"."
))
{
r
=
readTermObjectDot
(
name
);
}
else
{
...
...
@@ -2264,7 +2288,7 @@ public class Parser {
r
=
readWhen
(
left
);
}
}
else
if
(
readIf
(
"("
))
{
r
=
readFunction
(
name
);
r
=
readFunction
(
n
ull
,
n
ame
);
}
else
if
(
equalsToken
(
"CURRENT_USER"
,
name
))
{
r
=
readFunctionWithoutParameters
(
"USER"
);
}
else
if
(
equalsToken
(
"CURRENT"
,
name
))
{
...
...
@@ -3655,7 +3679,7 @@ public class Parser {
return
command
;
}
private
Call
parse
r
Call
()
{
private
Call
parseCall
()
{
Call
command
=
new
Call
(
session
);
currentPrepared
=
command
;
command
.
setExpression
(
readExpression
());
...
...
@@ -3734,11 +3758,12 @@ public class Parser {
boolean
ifNotExists
=
readIfNoExists
();
CreateAggregate
command
=
new
CreateAggregate
(
session
);
command
.
setForce
(
force
);
String
name
=
read
UniqueIdentifier
();
String
name
=
read
IdentifierWithSchema
();
if
(
isKeyword
(
name
)
||
Function
.
getFunction
(
database
,
name
)
!=
null
||
Aggregate
.
getAggregateType
(
name
)
>=
0
)
{
throw
DbException
.
get
(
ErrorCode
.
FUNCTION_ALIAS_ALREADY_EXISTS_1
,
name
);
}
command
.
setName
(
name
);
command
.
setSchema
(
getSchema
());
command
.
setIfNotExists
(
ifNotExists
);
read
(
"FOR"
);
command
.
setJavaClassMethod
(
readUniqueIdentifier
());
...
...
@@ -3849,13 +3874,13 @@ public class Parser {
private
CreateFunctionAlias
parseCreateFunctionAlias
(
boolean
force
)
{
boolean
ifNotExists
=
readIfNoExists
();
CreateFunctionAlias
command
=
new
CreateFunctionAlias
(
session
);
command
.
setForce
(
force
);
String
name
=
readUniqueIdentifier
();
if
(
isKeyword
(
name
)
||
Function
.
getFunction
(
database
,
name
)
!=
null
||
Aggregate
.
getAggregateType
(
name
)
>=
0
)
{
throw
DbException
.
get
(
ErrorCode
.
FUNCTION_ALIAS_ALREADY_EXISTS_1
,
name
);
String
aliasName
=
readIdentifierWithSchema
();
if
(
isKeyword
(
aliasName
)
||
Function
.
getFunction
(
database
,
aliasName
)
!=
null
||
Aggregate
.
getAggregateType
(
aliasName
)
>=
0
)
{
throw
DbException
.
get
(
ErrorCode
.
FUNCTION_ALIAS_ALREADY_EXISTS_1
,
aliasName
);
}
command
.
setAliasName
(
name
);
CreateFunctionAlias
command
=
new
CreateFunctionAlias
(
session
,
getSchema
());
command
.
setForce
(
force
);
command
.
setAliasName
(
aliasName
);
command
.
setIfNotExists
(
ifNotExists
);
command
.
setDeterministic
(
readIf
(
"DETERMINISTIC"
));
if
(
readIf
(
"AS"
))
{
...
...
@@ -4357,24 +4382,43 @@ public class Parser {
throw
DbException
.
get
(
ErrorCode
.
TABLE_OR_VIEW_NOT_FOUND_1
,
tableName
);
}
private
FunctionAlias
findFunctionAlias
(
String
schema
,
String
aliasName
)
{
FunctionAlias
functionAlias
=
database
.
getSchema
(
schema
).
findFunction
(
aliasName
);
if
(
functionAlias
!=
null
)
{
return
functionAlias
;
}
String
[]
schemaNames
=
session
.
getSchemaSearchPath
();
if
(
schemaNames
!=
null
)
{
for
(
String
n
:
schemaNames
)
{
functionAlias
=
database
.
getSchema
(
n
).
findFunction
(
aliasName
);
if
(
functionAlias
!=
null
)
{
return
functionAlias
;
}
}
}
return
null
;
}
private
Sequence
findSequence
(
String
schema
,
String
sequenceName
)
{
Sequence
sequence
=
database
.
getSchema
(
schema
).
findSequence
(
sequenceName
);
if
(
sequence
!=
null
)
{
return
sequence
;
}
String
[]
schemaNames
=
session
.
getSchemaSearchPath
();
for
(
int
i
=
0
;
schemaNames
!=
null
&&
i
<
schemaNames
.
length
;
i
++)
{
Schema
s
=
database
.
getSchema
(
schemaNames
[
i
]);
sequence
=
s
.
findSequence
(
sequenceName
);
if
(
sequence
!=
null
)
{
return
sequence
;
if
(
schemaNames
!=
null
)
{
for
(
String
n
:
schemaNames
)
{
sequence
=
database
.
getSchema
(
n
).
findSequence
(
sequenceName
);
if
(
sequence
!=
null
)
{
return
sequence
;
}
}
}
return
null
;
}
private
Sequence
readSequence
()
{
// same algorithm
than
readTableOrView
// same algorithm
as
readTableOrView
String
sequenceName
=
readIdentifierWithSchema
(
null
);
if
(
schemaName
!=
null
)
{
return
getSchema
().
getSequence
(
sequenceName
);
...
...
h2/src/main/org/h2/command/ddl/CreateAggregate.java
浏览文件 @
2ae9a839
...
...
@@ -11,6 +11,7 @@ import org.h2.engine.Database;
import
org.h2.engine.Session
;
import
org.h2.engine.UserAggregate
;
import
org.h2.message.DbException
;
import
org.h2.schema.Schema
;
/**
* This class represents the statement
...
...
@@ -18,6 +19,7 @@ import org.h2.message.DbException;
*/
public
class
CreateAggregate
extends
DefineCommand
{
private
Schema
schema
;
private
String
name
;
private
String
javaClassMethod
;
private
boolean
ifNotExists
;
...
...
@@ -31,7 +33,7 @@ public class CreateAggregate extends DefineCommand {
session
.
commit
(
true
);
session
.
getUser
().
checkAdmin
();
Database
db
=
session
.
getDatabase
();
if
(
db
.
findAggregate
(
name
)
!=
null
||
db
.
findFunctionAlias
(
name
)
!=
null
)
{
if
(
db
.
findAggregate
(
name
)
!=
null
||
schema
.
findFunction
(
name
)
!=
null
)
{
if
(!
ifNotExists
)
{
throw
DbException
.
get
(
ErrorCode
.
FUNCTION_ALIAS_ALREADY_EXISTS_1
,
name
);
}
...
...
@@ -43,6 +45,10 @@ public class CreateAggregate extends DefineCommand {
return
0
;
}
public
void
setSchema
(
Schema
schema
)
{
this
.
schema
=
schema
;
}
public
void
setName
(
String
name
)
{
this
.
name
=
name
;
}
...
...
h2/src/main/org/h2/command/ddl/CreateFunctionAlias.java
浏览文件 @
2ae9a839
...
...
@@ -11,12 +11,14 @@ import org.h2.engine.Database;
import
org.h2.engine.FunctionAlias
;
import
org.h2.engine.Session
;
import
org.h2.message.DbException
;
import
org.h2.schema.Schema
;
import
org.h2.util.StringUtils
;
/**
* This class represents the statement
* CREATE ALIAS
*/
public
class
CreateFunctionAlias
extends
Define
Command
{
public
class
CreateFunctionAlias
extends
Schema
Command
{
private
String
aliasName
;
private
String
javaClassMethod
;
...
...
@@ -25,15 +27,15 @@ public class CreateFunctionAlias extends DefineCommand {
private
boolean
force
;
private
String
source
;
public
CreateFunctionAlias
(
Session
session
)
{
super
(
session
);
public
CreateFunctionAlias
(
Session
session
,
Schema
schema
)
{
super
(
session
,
schema
);
}
public
int
update
()
{
session
.
commit
(
true
);
session
.
getUser
().
checkAdmin
();
Database
db
=
session
.
getDatabase
();
if
(
db
.
findFunctionAlias
(
aliasName
)
!=
null
)
{
if
(
getSchema
().
findFunction
(
aliasName
)
!=
null
)
{
if
(!
ifNotExists
)
{
throw
DbException
.
get
(
ErrorCode
.
FUNCTION_ALIAS_ALREADY_EXISTS_1
,
aliasName
);
}
...
...
@@ -41,12 +43,12 @@ public class CreateFunctionAlias extends DefineCommand {
int
id
=
getObjectId
();
FunctionAlias
functionAlias
;
if
(
javaClassMethod
!=
null
)
{
functionAlias
=
FunctionAlias
.
newInstance
(
db
,
id
,
aliasName
,
javaClassMethod
,
force
);
functionAlias
=
FunctionAlias
.
newInstance
(
getSchema
()
,
id
,
aliasName
,
javaClassMethod
,
force
);
}
else
{
functionAlias
=
FunctionAlias
.
newInstanceFromSource
(
db
,
id
,
aliasName
,
source
,
force
);
functionAlias
=
FunctionAlias
.
newInstanceFromSource
(
getSchema
()
,
id
,
aliasName
,
source
,
force
);
}
functionAlias
.
setDeterministic
(
deterministic
);
db
.
add
Database
Object
(
session
,
functionAlias
);
db
.
add
Schema
Object
(
session
,
functionAlias
);
}
return
0
;
}
...
...
@@ -55,8 +57,13 @@ public class CreateFunctionAlias extends DefineCommand {
this
.
aliasName
=
name
;
}
public
void
setJavaClassMethod
(
String
string
)
{
this
.
javaClassMethod
=
string
;
/**
* Set the qualified method name after removing whitespaces.
*
* @param method the qualified method name
*/
public
void
setJavaClassMethod
(
String
method
)
{
this
.
javaClassMethod
=
StringUtils
.
replaceAll
(
method
,
" "
,
""
);
}
public
void
setIfNotExists
(
boolean
ifNotExists
)
{
...
...
h2/src/main/org/h2/command/ddl/DropDatabase.java
浏览文件 @
2ae9a839
...
...
@@ -74,6 +74,7 @@ public class DropDatabase extends DefineCommand {
list
.
addAll
(
db
.
getAllSchemaObjects
(
DbObject
.
CONSTRAINT
));
list
.
addAll
(
db
.
getAllSchemaObjects
(
DbObject
.
TRIGGER
));
list
.
addAll
(
db
.
getAllSchemaObjects
(
DbObject
.
CONSTANT
));
list
.
addAll
(
db
.
getAllSchemaObjects
(
DbObject
.
FUNCTION_ALIAS
));
for
(
SchemaObject
obj
:
list
)
{
if
(
obj
.
isHidden
())
{
continue
;
...
...
@@ -94,7 +95,6 @@ public class DropDatabase extends DefineCommand {
}
ArrayList
<
DbObject
>
dbObjects
=
New
.
arrayList
();
dbObjects
.
addAll
(
db
.
getAllRights
());
dbObjects
.
addAll
(
db
.
getAllFunctionAliases
());
dbObjects
.
addAll
(
db
.
getAllAggregates
());
dbObjects
.
addAll
(
db
.
getAllUserDataTypes
());
for
(
DbObject
obj
:
dbObjects
)
{
...
...
h2/src/main/org/h2/command/ddl/DropFunctionAlias.java
浏览文件 @
2ae9a839
...
...
@@ -11,31 +11,32 @@ import org.h2.engine.Database;
import
org.h2.engine.FunctionAlias
;
import
org.h2.engine.Session
;
import
org.h2.message.DbException
;
import
org.h2.schema.Schema
;
/**
* This class represents the statement
* DROP ALIAS
*/
public
class
DropFunctionAlias
extends
Define
Command
{
public
class
DropFunctionAlias
extends
Schema
Command
{
private
String
aliasName
;
private
boolean
ifExists
;
public
DropFunctionAlias
(
Session
session
)
{
super
(
session
);
public
DropFunctionAlias
(
Session
session
,
Schema
schema
)
{
super
(
session
,
schema
);
}
public
int
update
()
{
session
.
getUser
().
checkAdmin
();
session
.
commit
(
true
);
Database
db
=
session
.
getDatabase
();
FunctionAlias
functionAlias
=
db
.
findFunctionAlias
(
aliasName
);
FunctionAlias
functionAlias
=
getSchema
().
findFunction
(
aliasName
);
if
(
functionAlias
==
null
)
{
if
(!
ifExists
)
{
throw
DbException
.
get
(
ErrorCode
.
FUNCTION_ALIAS_NOT_FOUND_1
,
aliasName
);
}
}
else
{
db
.
removeDatabase
Object
(
session
,
functionAlias
);
db
.
removeSchema
Object
(
session
,
functionAlias
);
}
return
0
;
}
...
...
h2/src/main/org/h2/command/ddl/SetComment.java
浏览文件 @
2ae9a839
...
...
@@ -49,8 +49,7 @@ public class SetComment extends DefineCommand {
object
=
db
.
getSchema
(
schemaName
).
getConstraint
(
objectName
);
break
;
case
DbObject
.
FUNCTION_ALIAS
:
schemaName
=
null
;
object
=
db
.
findFunctionAlias
(
objectName
);
object
=
db
.
getSchema
(
schemaName
).
findFunction
(
objectName
);
errorCode
=
ErrorCode
.
FUNCTION_ALIAS_NOT_FOUND_1
;
break
;
case
DbObject
.
INDEX
:
...
...
h2/src/main/org/h2/command/dml/ScriptCommand.java
浏览文件 @
2ae9a839
...
...
@@ -24,7 +24,6 @@ import org.h2.engine.Comment;
import
org.h2.engine.Constants
;
import
org.h2.engine.Database
;
import
org.h2.engine.DbObject
;
import
org.h2.engine.FunctionAlias
;
import
org.h2.engine.Right
;
import
org.h2.engine.Role
;
import
org.h2.engine.Session
;
...
...
@@ -159,11 +158,11 @@ public class ScriptCommand extends ScriptBase {
Constant
constant
=
(
Constant
)
obj
;
add
(
constant
.
getCreateSQL
(),
false
);
}
for
(
FunctionAlias
alias
:
db
.
getAllFunctionAliases
(
))
{
for
(
SchemaObject
obj
:
db
.
getAllSchemaObjects
(
DbObject
.
FUNCTION_ALIAS
))
{
if
(
drop
)
{
add
(
alias
.
getDropSQL
(),
false
);
add
(
obj
.
getDropSQL
(),
false
);
}
add
(
alias
.
getCreateSQL
(),
false
);
add
(
obj
.
getCreateSQL
(),
false
);
}
for
(
UserAggregate
agg
:
db
.
getAllAggregates
())
{
if
(
drop
)
{
...
...
h2/src/main/org/h2/constant/SysProperties.java
浏览文件 @
2ae9a839
...
...
@@ -260,6 +260,15 @@ public class SysProperties {
*/
public
static
final
int
ESTIMATED_FUNCTION_TABLE_ROWS
=
getIntSetting
(
"h2.estimatedFunctionTableRows"
,
1000
);
/**
* System property <code>h2.functionsInSchema</code> (default:
* false).<br />
* If set, all functions are stored in a schema. Specially, the SCRIPT statement
* will always include the schema name in the CREATE ALIAS statement.
* This is not backward compatible with H2 versions 1.2.134 and older.
*/
public
static
final
boolean
FUNCTIONS_IN_SCHEMA
=
getBooleanSetting
(
"h2.functionsInSchema"
,
false
);
/**
* System property <code>h2.identifiersToUpper</code> (default: true).<br />
* Unquoted identifiers in SQL statements are case insensitive and converted
...
...
h2/src/main/org/h2/engine/Database.java
浏览文件 @
2ae9a839
...
...
@@ -94,7 +94,6 @@ public class Database implements DataHandler {
private
final
HashMap
<
String
,
Setting
>
settings
=
New
.
hashMap
();
private
final
HashMap
<
String
,
Schema
>
schemas
=
New
.
hashMap
();
private
final
HashMap
<
String
,
Right
>
rights
=
New
.
hashMap
();
private
final
HashMap
<
String
,
FunctionAlias
>
functionAliases
=
New
.
hashMap
();
private
final
HashMap
<
String
,
UserDataType
>
userDataTypes
=
New
.
hashMap
();
private
final
HashMap
<
String
,
UserAggregate
>
aggregates
=
New
.
hashMap
();
private
final
HashMap
<
String
,
Comment
>
comments
=
New
.
hashMap
();
...
...
@@ -759,9 +758,6 @@ public class Database implements DataHandler {
case
DbObject
.
RIGHT
:
result
=
rights
;
break
;
case
DbObject
.
FUNCTION_ALIAS
:
result
=
functionAliases
;
break
;
case
DbObject
.
SCHEMA
:
result
=
schemas
;
break
;
...
...
@@ -846,16 +842,6 @@ public class Database implements DataHandler {
return
comments
.
get
(
key
);
}
/**
* Get the user defined function if it exists, or null if not.
*
* @param name the name of the user defined function
* @return the function or null
*/
public
FunctionAlias
findFunctionAlias
(
String
name
)
{
return
functionAliases
.
get
(
name
);
}
/**
* Get the role if it exists, or null if not.
*
...
...
@@ -1219,10 +1205,6 @@ public class Database implements DataHandler {
return
New
.
arrayList
(
comments
.
values
());
}
public
ArrayList
<
FunctionAlias
>
getAllFunctionAliases
()
{
return
New
.
arrayList
(
functionAliases
.
values
());
}
public
int
getAllowLiterals
()
{
if
(
starting
)
{
return
Constants
.
ALLOW_LITERALS_ALL
;
...
...
h2/src/main/org/h2/engine/FunctionAlias.java
浏览文件 @
2ae9a839
...
...
@@ -19,12 +19,14 @@ import org.h2.constant.SysProperties;
import
org.h2.expression.Expression
;
import
org.h2.message.DbException
;
import
org.h2.message.Trace
;
import
org.h2.schema.Schema
;
import
org.h2.schema.SchemaObjectBase
;
import
org.h2.table.Table
;
import
org.h2.util.Utils
;
import
org.h2.util.New
;
import
org.h2.util.SourceCompiler
;
import
org.h2.util.StatementBuilder
;
import
org.h2.util.StringUtils
;
import
org.h2.util.Utils
;
import
org.h2.value.DataType
;
import
org.h2.value.Value
;
import
org.h2.value.ValueNull
;
...
...
@@ -35,7 +37,7 @@ import org.h2.value.ValueNull;
* @author Thomas Mueller
* @author Gary Tong
*/
public
class
FunctionAlias
extends
Db
ObjectBase
{
public
class
FunctionAlias
extends
Schema
ObjectBase
{
private
String
className
;
private
String
methodName
;
...
...
@@ -43,8 +45,8 @@ public class FunctionAlias extends DbObjectBase {
private
JavaMethod
[]
javaMethods
;
private
boolean
deterministic
;
private
FunctionAlias
(
Database
db
,
int
id
,
String
name
)
{
init
DbObjectBase
(
db
,
id
,
name
,
Trace
.
FUNCTION
);
private
FunctionAlias
(
Schema
schema
,
int
id
,
String
name
)
{
init
SchemaObjectBase
(
schema
,
id
,
name
,
Trace
.
FUNCTION
);
}
/**
...
...
@@ -57,8 +59,8 @@ public class FunctionAlias extends DbObjectBase {
* @param force create the object even if the class or method does not exist
* @return the database object
*/
public
static
FunctionAlias
newInstance
(
Database
db
,
int
id
,
String
name
,
String
javaClassMethod
,
boolean
force
)
{
FunctionAlias
alias
=
new
FunctionAlias
(
db
,
id
,
name
);
public
static
FunctionAlias
newInstance
(
Schema
schema
,
int
id
,
String
name
,
String
javaClassMethod
,
boolean
force
)
{
FunctionAlias
alias
=
new
FunctionAlias
(
schema
,
id
,
name
);
int
paren
=
javaClassMethod
.
indexOf
(
'('
);
int
lastDot
=
javaClassMethod
.
lastIndexOf
(
'.'
,
paren
<
0
?
javaClassMethod
.
length
()
:
paren
);
if
(
lastDot
<
0
)
{
...
...
@@ -80,8 +82,8 @@ public class FunctionAlias extends DbObjectBase {
* @param force create the object even if the class or method does not exist
* @return the database object
*/
public
static
FunctionAlias
newInstanceFromSource
(
Database
db
,
int
id
,
String
name
,
String
source
,
boolean
force
)
{
FunctionAlias
alias
=
new
FunctionAlias
(
db
,
id
,
name
);
public
static
FunctionAlias
newInstanceFromSource
(
Schema
schema
,
int
id
,
String
name
,
String
source
,
boolean
force
)
{
FunctionAlias
alias
=
new
FunctionAlias
(
schema
,
id
,
name
);
alias
.
source
=
source
;
alias
.
init
(
force
);
return
alias
;
...
...
@@ -167,7 +169,9 @@ public class FunctionAlias extends DbObjectBase {
StatementBuilder
buff
=
new
StatementBuilder
(
m
.
getName
());
buff
.
append
(
'('
);
for
(
Class
<
?
>
p
:
m
.
getParameterTypes
())
{
buff
.
appendExceptFirst
(
", "
);
// do not use a space here, because spaces are removed
// in CreateFunctionAlias.setJavaClassMethod()
buff
.
appendExceptFirst
(
","
);
if
(
p
.
isArray
())
{
buff
.
append
(
p
.
getComponentType
().
getName
()).
append
(
"[]"
);
}
else
{
...
...
@@ -185,6 +189,14 @@ public class FunctionAlias extends DbObjectBase {
return
"DROP ALIAS IF EXISTS "
+
getSQL
();
}
public
String
getSQL
()
{
// TODO can remove this method once FUNCTIONS_IN_SCHEMA is enabled
if
(
SysProperties
.
FUNCTIONS_IN_SCHEMA
||
!
getSchema
().
getName
().
equals
(
Constants
.
SCHEMA_MAIN
))
{
return
super
.
getSQL
();
}
return
Parser
.
quoteIdentifier
(
getName
());
}
public
String
getCreateSQL
()
{
StringBuilder
buff
=
new
StringBuilder
(
"CREATE FORCE ALIAS "
);
buff
.
append
(
getSQL
());
...
...
h2/src/main/org/h2/schema/Schema.java
浏览文件 @
2ae9a839
...
...
@@ -17,6 +17,7 @@ import org.h2.constraint.Constraint;
import
org.h2.engine.Database
;
import
org.h2.engine.DbObject
;
import
org.h2.engine.DbObjectBase
;
import
org.h2.engine.FunctionAlias
;
import
org.h2.engine.Session
;
import
org.h2.engine.User
;
import
org.h2.index.Index
;
...
...
@@ -43,6 +44,7 @@ public class Schema extends DbObjectBase {
private
HashMap
<
String
,
TriggerObject
>
triggers
=
New
.
hashMap
();
private
HashMap
<
String
,
Constraint
>
constraints
=
New
.
hashMap
();
private
HashMap
<
String
,
Constant
>
constants
=
New
.
hashMap
();
private
HashMap
<
String
,
FunctionAlias
>
functions
=
New
.
hashMap
();
/**
* The set of returned unique names that are not yet stored. It is used to
...
...
@@ -121,6 +123,10 @@ public class Schema extends DbObjectBase {
Constant
obj
=
(
Constant
)
constants
.
values
().
toArray
()[
0
];
database
.
removeSchemaObject
(
session
,
obj
);
}
while
(
functions
!=
null
&&
functions
.
size
()
>
0
)
{
FunctionAlias
obj
=
(
FunctionAlias
)
functions
.
values
().
toArray
()[
0
];
database
.
removeSchemaObject
(
session
,
obj
);
}
database
.
removeMeta
(
session
,
getId
());
owner
=
null
;
invalidate
();
...
...
@@ -161,6 +167,9 @@ public class Schema extends DbObjectBase {
case
DbObject
.
CONSTANT
:
result
=
constants
;
break
;
case
DbObject
.
FUNCTION_ALIAS
:
result
=
functions
;
break
;
default
:
throw
DbException
.
throwInternalError
(
"type="
+
type
);
}
...
...
@@ -169,6 +178,8 @@ public class Schema extends DbObjectBase {
/**
* Add an object to this schema.
* This method must not be called within CreateSchemaObject;
* use Database.addSchemaObject() instead
*
* @param obj the object to add
*/
...
...
@@ -291,6 +302,17 @@ public class Schema extends DbObjectBase {
public
Constant
findConstant
(
String
constantName
)
{
return
constants
.
get
(
constantName
);
}
/**
* Try to find a user defined function with this name. This method returns
* null if no object with this name exists.
*
* @param functionAlias the object name
* @return the object or null
*/
public
FunctionAlias
findFunction
(
String
functionAlias
)
{
return
functions
.
get
(
functionAlias
);
}
/**
* Release a unique object name.
...
...
@@ -449,7 +471,7 @@ public class Schema extends DbObjectBase {
* Get all objects of the given type.
*
* @param type the object type
* @return a
(possible empty) list of all objects
* @return a (possible empty) list of all objects
*/
public
ArrayList
<
SchemaObject
>
getAll
(
int
type
)
{
HashMap
<
String
,
SchemaObject
>
map
=
getMap
(
type
);
...
...
@@ -459,11 +481,20 @@ public class Schema extends DbObjectBase {
/**
* Get all tables and views.
*
* @return a
(possible empty) list of all objects
* @return a (possible empty) list of all objects
*/
public
ArrayList
<
Table
>
getAllTablesAndViews
()
{
return
New
.
arrayList
(
tablesAndViews
.
values
());
}
/**
* Get all functions.
*
* @return a (possible empty) list of all objects
*/
public
ArrayList
<
FunctionAlias
>
getAllFunctionAliases
()
{
return
New
.
arrayList
(
functions
.
values
());
}
/**
* Remove an object from this schema.
...
...
h2/src/main/org/h2/table/MetaTable.java
浏览文件 @
2ae9a839
...
...
@@ -1061,7 +1061,8 @@ public class MetaTable extends Table {
break
;
}
case
FUNCTION_ALIASES:
{
for
(
FunctionAlias
alias
:
database
.
getAllFunctionAliases
())
{
for
(
SchemaObject
aliasAsSchemaObject
:
database
.
getAllSchemaObjects
(
DbObject
.
FUNCTION_ALIAS
))
{
FunctionAlias
alias
=
(
FunctionAlias
)
aliasAsSchemaObject
;
for
(
FunctionAlias
.
JavaMethod
method
:
alias
.
getJavaMethods
())
{
int
returnsResult
=
method
.
getDataType
()
==
Value
.
NULL
?
DatabaseMetaData
.
procedureNoResult
:
DatabaseMetaData
.
procedureReturnsResult
;
...
...
@@ -1069,7 +1070,7 @@ public class MetaTable extends Table {
// ALIAS_CATALOG
catalog
,
// ALIAS_SCHEMA
Constants
.
SCHEMA_MAIN
,
alias
.
getSchema
().
getName
()
,
// ALIAS_NAME
identifier
(
alias
.
getName
()),
// JAVA_CLASS
...
...
@@ -1119,7 +1120,8 @@ public class MetaTable extends Table {
break
;
}
case
FUNCTION_COLUMNS:
{
for
(
FunctionAlias
alias
:
database
.
getAllFunctionAliases
())
{
for
(
SchemaObject
aliasAsSchemaObject
:
database
.
getAllSchemaObjects
(
DbObject
.
FUNCTION_ALIAS
))
{
FunctionAlias
alias
=
(
FunctionAlias
)
aliasAsSchemaObject
;
for
(
FunctionAlias
.
JavaMethod
method
:
alias
.
getJavaMethods
())
{
Class
<
?
>[]
columnList
=
method
.
getColumnClasses
();
for
(
int
k
=
0
;
k
<
columnList
.
length
;
k
++)
{
...
...
@@ -1132,7 +1134,7 @@ public class MetaTable extends Table {
// ALIAS_CATALOG
catalog
,
// ALIAS_SCHEMA
Constants
.
SCHEMA_MAIN
,
alias
.
getSchema
().
getName
()
,
// ALIAS_NAME
identifier
(
alias
.
getName
()),
// JAVA_CLASS
...
...
h2/src/test/org/h2/test/TestAll.java
浏览文件 @
2ae9a839
...
...
@@ -292,8 +292,8 @@ java org.h2.test.TestAll timer
int
testing
;
System
.
setProperty
(
"h2.lobInDatabase"
,
"true"
);
System
.
setProperty
(
"h2.analyzeAuto"
,
"100"
);
//
System.setProperty("h2.lobInDatabase", "true");
//
System.setProperty("h2.analyzeAuto", "100");
/*
...
...
h2/src/test/org/h2/test/db/TestFunctions.java
浏览文件 @
2ae9a839
...
...
@@ -51,6 +51,8 @@ public class TestFunctions extends TestBase implements AggregateFunction {
testSource
();
testDynamicArgumentAndReturn
();
testUUID
();
testWhiteSpacesInParameters
();
testSchemaSearchPath
();
testDeterministic
();
testTransactionId
();
testPrecision
();
...
...
@@ -90,6 +92,9 @@ public class TestFunctions extends TestBase implements AggregateFunction {
ResultSet
rs
;
stat
.
execute
(
"create force alias sayHi as 'String test(String name) {\n"
+
"return \"Hello \" + name;\n}'"
);
rs
=
stat
.
executeQuery
(
"SELECT ALIAS_NAME FROM INFORMATION_SCHEMA.FUNCTION_ALIASES"
);
rs
.
next
();
assertEquals
(
"SAY"
+
"HI"
,
rs
.
getString
(
1
));
rs
=
stat
.
executeQuery
(
"call sayHi('Joe')"
);
rs
.
next
();
assertEquals
(
"Hello Joe"
,
rs
.
getString
(
1
));
...
...
@@ -157,7 +162,8 @@ public class TestFunctions extends TestBase implements AggregateFunction {
rs
.
next
();
assertEquals
(
0
,
rs
.
getInt
(
1
));
stat
.
execute
(
"drop alias getCount"
);
rs
=
stat
.
executeQuery
(
"SELECT * FROM INFORMATION_SCHEMA.FUNCTION_ALIASES WHERE UPPER(ALIAS_NAME) = 'GETCOUNT'"
);
assertEquals
(
false
,
rs
.
next
());
stat
.
execute
(
"create alias reverse deterministic for \""
+
getClass
().
getName
()+
".reverse\""
);
rs
=
stat
.
executeQuery
(
"select reverse(x) from system_range(700, 700)"
);
rs
.
next
();
...
...
@@ -467,6 +473,58 @@ public class TestFunctions extends TestBase implements AggregateFunction {
conn
.
close
();
}
/**
* White spaces in javaMethodDescriptors are deleted during
* CreateFunctionAlias, and all further processing is normalized.
*/
private
void
testWhiteSpacesInParameters
()
throws
SQLException
{
deleteDb
(
"functions"
);
Connection
conn
=
getConnection
(
"functions"
);
Statement
stat
=
conn
.
createStatement
();
// with white space
stat
.
execute
(
"CREATE ALIAS PARSE_INT2 FOR \"java.lang.Integer.parseInt(java.lang.String, int)\""
);
ResultSet
rs
;
rs
=
stat
.
executeQuery
(
"CALL PARSE_INT2('473', 10)"
);
rs
.
next
();
assertEquals
(
473
,
rs
.
getInt
(
1
));
stat
.
execute
(
"DROP ALIAS PARSE_INT2"
);
// without white space
stat
.
execute
(
"CREATE ALIAS PARSE_INT2 FOR \"java.lang.Integer.parseInt(java.lang.String,int)\""
);
stat
.
execute
(
"DROP ALIAS PARSE_INT2"
);
}
private
void
testSchemaSearchPath
()
throws
SQLException
{
deleteDb
(
"functions"
);
Connection
conn
=
getConnection
(
"functions"
);
Statement
stat
=
conn
.
createStatement
();
ResultSet
rs
;
stat
.
execute
(
"CREATE SCHEMA TEST"
);
stat
.
execute
(
"SET SCHEMA TEST"
);
stat
.
execute
(
"CREATE ALIAS PARSE_INT2 FOR \"java.lang.Integer.parseInt(java.lang.String, int)\";"
);
rs
=
stat
.
executeQuery
(
"SELECT ALIAS_NAME FROM INFORMATION_SCHEMA.FUNCTION_ALIASES WHERE ALIAS_SCHEMA ='TEST'"
);
rs
.
next
();
assertEquals
(
"PARSE_INT2"
,
rs
.
getString
(
1
));
stat
.
execute
(
"DROP ALIAS PARSE_INT2"
);
stat
.
execute
(
"SET SCHEMA PUBLIC"
);
stat
.
execute
(
"CREATE ALIAS TEST.PARSE_INT2 FOR \"java.lang.Integer.parseInt(java.lang.String, int)\";"
);
stat
.
execute
(
"SET SCHEMA_SEARCH_PATH PUBLIC, TEST"
);
rs
=
stat
.
executeQuery
(
"CALL PARSE_INT2('-FF', 16)"
);
rs
.
next
();
assertEquals
(-
255
,
rs
.
getInt
(
1
));
rs
=
stat
.
executeQuery
(
"SELECT ALIAS_NAME FROM INFORMATION_SCHEMA.FUNCTION_ALIASES WHERE ALIAS_SCHEMA ='TEST'"
);
rs
.
next
();
assertEquals
(
"PARSE_INT2"
,
rs
.
getString
(
1
));
rs
=
stat
.
executeQuery
(
"CALL TEST.PARSE_INT2('-2147483648', 10)"
);
rs
.
next
();
assertEquals
(-
2147483648
,
rs
.
getInt
(
1
));
rs
=
stat
.
executeQuery
(
"CALL FUNCTIONS.TEST.PARSE_INT2('-2147483648', 10)"
);
rs
.
next
();
assertEquals
(-
2147483648
,
rs
.
getInt
(
1
));
conn
.
close
();
}
private
void
assertCallResult
(
String
expected
,
Statement
stat
,
String
sql
)
throws
SQLException
{
ResultSet
rs
=
stat
.
executeQuery
(
"CALL "
+
sql
);
rs
.
next
();
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论