Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
13af88a2
提交
13af88a2
authored
7月 06, 2007
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
--no commit message
--no commit message
上级
7eb40855
显示空白字符变更
内嵌
并排
正在显示
3 个修改的文件
包含
1025 行增加
和
0 行删除
+1025
-0
PgServer.java
h2/src/main/org/h2/server/pg/PgServer.java
+181
-0
PgServerThread.java
h2/src/main/org/h2/server/pg/PgServerThread.java
+762
-0
pg_catalog.sql
h2/src/main/org/h2/server/pg/pg_catalog.sql
+82
-0
没有找到文件。
h2/src/main/org/h2/server/pg/PgServer.java
0 → 100644
浏览文件 @
13af88a2
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
server
.
pg
;
import
java.io.IOException
;
import
java.net.InetAddress
;
import
java.net.ServerSocket
;
import
java.net.Socket
;
import
java.sql.SQLException
;
import
java.util.ArrayList
;
import
java.util.HashSet
;
import
org.h2.server.Service
;
import
org.h2.util.MathUtils
;
import
org.h2.util.NetUtils
;
/**
* @author Thomas
*/
public
class
PgServer
implements
Service
{
// public static final int DEFAULT_PORT = 5433; // also in the docs
public
static
final
int
DEFAULT_PORT
=
5435
;
// also in the docs
private
int
port
=
PgServer
.
DEFAULT_PORT
;
private
boolean
stop
;
private
boolean
log
;
private
ServerSocket
serverSocket
;
private
HashSet
running
=
new
HashSet
();
private
String
baseDir
;
private
String
url
;
private
boolean
allowOthers
;
private
boolean
ifExists
;
public
static
void
main
(
String
[]
args
)
throws
Exception
{
PgServer
app
=
new
PgServer
();
app
.
init
(
args
);
app
.
start
();
app
.
listen
();
}
boolean
getLog
()
{
return
log
;
}
void
log
(
String
s
)
{
if
(
log
)
{
System
.
out
.
println
(
s
);
}
}
synchronized
void
remove
(
PgServerThread
t
)
{
running
.
remove
(
t
);
}
void
logError
(
Exception
e
)
{
if
(
log
)
{
e
.
printStackTrace
();
}
}
public
void
init
(
String
[]
args
)
throws
Exception
{
port
=
DEFAULT_PORT
;
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
{
String
a
=
args
[
i
];
if
(
a
.
equals
(
"-log"
))
{
log
=
Boolean
.
valueOf
(
args
[++
i
]).
booleanValue
();
}
else
if
(
a
.
equals
(
"-pgPort"
))
{
port
=
MathUtils
.
decodeInt
(
args
[++
i
]);
}
else
if
(
a
.
equals
(
"-baseDir"
))
{
baseDir
=
args
[++
i
];
}
else
if
(
a
.
equals
(
"-pgAllowOthers"
))
{
allowOthers
=
Boolean
.
valueOf
(
args
[++
i
]).
booleanValue
();
}
else
if
(
a
.
equals
(
"-ifExists"
))
{
ifExists
=
Boolean
.
valueOf
(
args
[++
i
]).
booleanValue
();
}
}
org
.
h2
.
Driver
.
load
();
url
=
"odbc://localhost:"
+
port
;
}
public
String
getURL
()
{
return
url
;
}
boolean
allow
(
Socket
socket
)
{
if
(
allowOthers
)
{
return
true
;
}
return
NetUtils
.
isLoopbackAddress
(
socket
);
}
public
void
start
()
throws
SQLException
{
serverSocket
=
NetUtils
.
createServerSocket
(
port
,
false
);
}
public
void
listen
()
{
String
threadName
=
Thread
.
currentThread
().
getName
();
try
{
while
(!
stop
)
{
Socket
s
=
serverSocket
.
accept
();
if
(!
allow
(
s
))
{
log
(
"Connection not allowed"
);
s
.
close
();
}
else
{
PgServerThread
c
=
new
PgServerThread
(
s
,
this
);
running
.
add
(
c
);
c
.
setProcessId
(
running
.
size
());
Thread
thread
=
new
Thread
(
c
);
thread
.
setName
(
threadName
+
" thread"
);
c
.
setThread
(
thread
);
thread
.
start
();
}
}
}
catch
(
Exception
e
)
{
if
(!
stop
)
{
e
.
printStackTrace
();
}
}
}
public
void
stop
()
{
// TODO server: share code between web and tcp servers
if
(!
stop
)
{
stop
=
true
;
if
(
serverSocket
!=
null
)
{
try
{
serverSocket
.
close
();
}
catch
(
IOException
e
)
{
// TODO log exception
e
.
printStackTrace
();
}
serverSocket
=
null
;
}
}
// TODO server: using a boolean 'now' argument? a timeout?
ArrayList
list
=
new
ArrayList
(
running
);
for
(
int
i
=
0
;
i
<
list
.
size
();
i
++)
{
PgServerThread
c
=
(
PgServerThread
)
list
.
get
(
i
);
c
.
close
();
try
{
c
.
getThread
().
join
(
100
);
}
catch
(
Exception
e
)
{
// TODO log exception
e
.
printStackTrace
();
}
}
}
public
boolean
isRunning
()
{
if
(
serverSocket
==
null
)
{
return
false
;
}
try
{
Socket
s
=
NetUtils
.
createSocket
(
InetAddress
.
getLocalHost
(),
serverSocket
.
getLocalPort
(),
false
);
s
.
close
();
return
true
;
}
catch
(
Exception
e
)
{
return
false
;
}
}
public
String
getBaseDir
()
{
return
baseDir
;
}
public
boolean
getAllowOthers
()
{
return
allowOthers
;
}
public
String
getType
()
{
return
"PG"
;
}
public
boolean
getIfExists
()
{
return
ifExists
;
}
}
h2/src/main/org/h2/server/pg/PgServerThread.java
0 → 100644
浏览文件 @
13af88a2
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
server
.
pg
;
import
java.io.BufferedReader
;
import
java.io.ByteArrayInputStream
;
import
java.io.ByteArrayOutputStream
;
import
java.io.DataInputStream
;
import
java.io.DataOutputStream
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.InputStreamReader
;
import
java.io.OutputStream
;
import
java.io.Reader
;
import
java.net.Socket
;
import
java.sql.Connection
;
import
java.sql.DriverManager
;
import
java.sql.ParameterMetaData
;
import
java.sql.PreparedStatement
;
import
java.sql.ResultSet
;
import
java.sql.ResultSetMetaData
;
import
java.sql.SQLException
;
import
java.sql.Statement
;
import
java.sql.Types
;
import
java.util.HashMap
;
import
org.h2.util.JdbcUtils
;
import
org.h2.util.ScriptReader
;
/**
* @author Thomas
*/
/*
SELECT NULL AS TABLE_CAT, n.nspname AS TABLE_SCHEM,
c.relname AS TABLE_NAME,
CASE n.nspname LIKE 'pg\\_%' OR n.nspname = 'information_schema' WHEN true THEN
CASE WHEN n.nspname = 'pg_catalog' OR n.nspname = 'information_schema' THEN
CASE c.relkind
WHEN 'r' THEN 'SYSTEM TABLE'
WHEN 'v' THEN 'SYSTEM VIEW'
WHEN 'i' THEN 'SYSTEM INDEX'
ELSE NULL
END
WHEN n.nspname = 'pg_toast' THEN
CASE c.relkind
WHEN 'r' THEN 'SYSTEM TOAST TABLE'
WHEN 'i' THEN 'SYSTEM TOAST INDEX'
ELSE NULL
END
ELSE
CASE c.relkind
WHEN 'r' THEN 'TEMPORARY TABLE'
WHEN 'i' THEN 'TEMPORARY INDEX'
ELSE NULL
END
END
WHEN false THEN
CASE c.relkind
WHEN 'r' THEN 'TABLE'
WHEN 'i' THEN 'INDEX'
WHEN 'S' THEN 'SEQUENCE'
WHEN 'v' THEN 'VIEW'
ELSE NULL
END
ELSE NULL
END AS TABLE_TYPE,
d.description AS REMARKS
FROM pg_catalog.pg_namespace n,
pg_catalog.pg_class c
LEFT JOIN pg_catalog.pg_description d ON (c.oid = d.objoid AND d.objsubid = 0)
LEFT JOIN pg_catalog.pg_class dc ON (d.classoid=dc.oid AND dc.relname='pg_class')
LEFT JOIN pg_catalog.pg_namespace dn ON (dn.oid=dc.relnamespace AND dn.nspname='pg_catalog')
WHERE c.relnamespace = n.oid
AND n.nspname LIKE 'INFORMATION_SCHEMA'
AND (false OR ( c.relkind = 'r' AND n.nspname NOT LIKE 'pg\\_%' AND n.nspname <> 'information_schema' )
OR ( c.relkind = 'r' AND (n.nspname = 'pg_catalog' OR n.nspname = 'information_schema') )
OR ( c.relkind = 'v' AND n.nspname <> 'pg_catalog' AND n.nspname <> 'information_schema' )
OR ( c.relkind = 'v' AND (n.nspname = 'pg_catalog' OR n.nspname = 'information_schema') ) )
ORDER BY TABLE_TYPE,TABLE_SCHEM,TABLE_NAME
*/
public
class
PgServerThread
implements
Runnable
{
private
static
final
int
TYPE_STRING
=
Types
.
VARCHAR
;
private
PgServer
server
;
private
Socket
socket
;
private
Connection
conn
;
private
boolean
stop
;
private
DataInputStream
dataInRaw
;
private
DataInputStream
dataIn
;
private
OutputStream
out
;
private
int
messageType
;
private
ByteArrayOutputStream
outBuffer
;
private
DataOutputStream
dataOut
;
private
Thread
thread
;
private
boolean
initDone
;
private
String
userName
;
private
String
databaseName
;
private
int
processId
;
private
String
clientEncoding
;
private
String
dateStyle
;
private
HashMap
prepared
=
new
HashMap
();
private
HashMap
portals
=
new
HashMap
();
PgServerThread
(
Socket
socket
,
PgServer
server
)
{
this
.
server
=
server
;
this
.
socket
=
socket
;
}
public
void
run
()
{
try
{
server
.
log
(
"Connect"
);
InputStream
ins
=
socket
.
getInputStream
();
out
=
socket
.
getOutputStream
();
dataInRaw
=
new
DataInputStream
(
ins
);
while
(!
stop
)
{
process
();
out
.
flush
();
}
server
.
log
(
"Disconnect"
);
close
();
}
catch
(
Exception
e
)
{
int
testing
;
e
.
printStackTrace
();
server
.
logError
(
e
);
}
}
private
void
println
(
String
s
)
{
System
.
out
.
println
(
s
);
}
private
String
readString
()
throws
IOException
{
StringBuffer
buff
=
new
StringBuffer
();
while
(
true
)
{
int
x
=
dataIn
.
read
();
if
(
x
<=
0
)
{
break
;
}
buff
.
append
((
char
)
x
);
}
return
buff
.
toString
();
}
private
int
readInt
()
throws
IOException
{
return
dataIn
.
readInt
();
}
private
int
readShort
()
throws
IOException
{
return
dataIn
.
readShort
();
}
private
byte
readByte
()
throws
IOException
{
return
dataIn
.
readByte
();
}
private
void
readFully
(
byte
[]
buff
)
throws
IOException
{
dataIn
.
readFully
(
buff
);
}
private
void
error
(
String
message
,
Exception
e
)
{
int
todoDisable
;
System
.
out
.
println
(
"ERROR: "
+
message
);
if
(
e
!=
null
)
{
e
.
printStackTrace
();
}
}
private
void
process
()
throws
IOException
{
int
x
;
if
(
initDone
)
{
x
=
dataInRaw
.
read
();
if
(
x
<
0
)
{
stop
=
true
;
return
;
}
}
else
{
x
=
0
;
}
int
len
=
dataInRaw
.
readInt
();
len
-=
4
;
byte
[]
data
=
new
byte
[
len
];
dataInRaw
.
readFully
(
data
,
0
,
len
);
dataIn
=
new
DataInputStream
(
new
ByteArrayInputStream
(
data
,
0
,
len
));
switch
(
x
)
{
case
0
:
// println("Init");
int
version
=
readInt
();
if
(
version
==
80877102
)
{
println
(
"CancelRequest"
);
println
(
" pid: "
+
readInt
());
println
(
" key: "
+
readInt
());
error
(
"CancelRequest"
,
null
);
}
else
if
(
version
==
80877103
)
{
println
(
"SSLRequest"
);
error
(
"SSLRequest"
,
null
);
}
else
{
// println("StartupMessage");
// println(" version " + version + " (" + (version >> 16) + "." + (version & 0xff) + ")");
while
(
true
)
{
String
param
=
readString
();
if
(
param
.
length
()
==
0
)
{
break
;
}
String
value
=
readString
();
if
(
"user"
.
equals
(
param
))
{
this
.
userName
=
value
;
}
else
if
(
"database"
.
equals
(
param
))
{
this
.
databaseName
=
value
;
}
else
if
(
"client_encoding"
.
equals
(
param
))
{
clientEncoding
=
value
;
}
else
if
(
"DateStyle"
.
equals
(
param
))
{
dateStyle
=
value
;
}
// println(" param " + param + "=" + value);
}
sendAuthenticationCleartextPassword
();
initDone
=
true
;
}
break
;
case
'p'
:
{
// println("PasswordMessage");
String
password
=
readString
();
// println(" password: " + password);
try
{
conn
=
DriverManager
.
getConnection
(
"jdbc:h2:"
+
databaseName
,
userName
,
password
);
initDb
();
sendAuthenticationOk
();
}
catch
(
SQLException
e
)
{
e
.
printStackTrace
();
stop
=
true
;
}
break
;
}
case
'P'
:
{
// println("Parse");
Prepared
p
=
new
Prepared
();
p
.
name
=
readString
();
p
.
sql
=
getSQL
(
readString
());
println
(
p
.
sql
+
";"
);
int
count
=
readShort
();
p
.
paramType
=
new
int
[
count
];
for
(
int
i
=
0
;
i
<
count
;
i
++)
{
p
.
paramType
[
i
]
=
readInt
();
}
try
{
p
.
prep
=
conn
.
prepareStatement
(
p
.
sql
);
prepared
.
put
(
p
.
name
,
p
);
sendParseComplete
();
}
catch
(
SQLException
e
)
{
sendErrorResponse
(
e
);
}
break
;
}
case
'B'
:
{
// println("Bind");
Portal
portal
=
new
Portal
();
portal
.
name
=
readString
();
String
prepName
=
readString
();
Prepared
prep
=
(
Prepared
)
prepared
.
get
(
prepName
);
if
(
prep
==
null
)
{
sendErrorResponse
(
"Portal not found"
);
break
;
}
portal
.
sql
=
prep
.
sql
;
portal
.
prep
=
prep
.
prep
;
portals
.
put
(
portal
.
name
,
portal
);
int
formatCodeCount
=
readShort
();
int
[]
formatCodes
=
new
int
[
formatCodeCount
];
for
(
int
i
=
0
;
i
<
formatCodeCount
;
i
++)
{
formatCodes
[
i
]
=
readShort
();
}
int
paramCount
=
readShort
();
for
(
int
i
=
0
;
i
<
paramCount
;
i
++)
{
int
paramLen
=
readInt
();
byte
[]
d2
=
new
byte
[
paramLen
];
readFully
(
d2
);
try
{
setParameter
(
portal
.
prep
,
i
,
d2
,
formatCodes
);
}
catch
(
SQLException
e
)
{
sendErrorResponse
(
e
);
}
}
int
resultCodeCount
=
readShort
();
portal
.
resultColumnFormat
=
new
int
[
resultCodeCount
];
for
(
int
i
=
0
;
i
<
resultCodeCount
;
i
++)
{
portal
.
resultColumnFormat
[
i
]
=
readShort
();
}
sendBindComplete
();
break
;
}
case
'D'
:
{
// println("Describe");
char
type
=
(
char
)
readByte
();
String
name
=
readString
();
PreparedStatement
prep
;
if
(
type
==
'S'
)
{
Prepared
p
=
(
Prepared
)
prepared
.
get
(
name
);
if
(
p
==
null
)
{
sendErrorResponse
(
"Prepared not found: "
+
name
);
}
prep
=
p
.
prep
;
sendParameterDescription
(
prep
);
}
else
if
(
type
==
'P'
)
{
Portal
p
=
(
Portal
)
portals
.
get
(
name
);
if
(
p
==
null
)
{
sendErrorResponse
(
"Portal not found: "
+
name
);
}
prep
=
p
.
prep
;
try
{
ResultSetMetaData
meta
=
prep
.
getMetaData
();
sendRowDescription
(
meta
);
}
catch
(
SQLException
e
)
{
sendErrorResponse
(
e
);
}
}
else
{
error
(
"expected S or P, got "
+
type
,
null
);
sendErrorResponse
(
"expected S or P"
);
}
break
;
}
case
'E'
:
{
// println("Execute");
String
name
=
readString
();
Portal
p
=
(
Portal
)
portals
.
get
(
name
);
if
(
p
==
null
)
{
sendErrorResponse
(
"Portal not found: "
+
name
);
break
;
}
int
maxRows
=
readShort
();
PreparedStatement
prep
=
p
.
prep
;
try
{
prep
.
setMaxRows
(
maxRows
);
boolean
result
=
prep
.
execute
();
if
(
result
)
{
try
{
ResultSet
rs
=
prep
.
getResultSet
();
ResultSetMetaData
meta
=
rs
.
getMetaData
();
sendRowDescription
(
meta
);
while
(
rs
.
next
())
{
sendDataRow
(
p
.
resultColumnFormat
,
rs
);
}
sendCommandComplete
(
p
.
sql
,
0
);
}
catch
(
SQLException
e
)
{
sendErrorResponse
(
e
);
}
}
else
{
sendCommandComplete
(
p
.
sql
,
prep
.
getUpdateCount
());
}
}
catch
(
SQLException
e
)
{
sendErrorResponse
(
e
);
}
break
;
}
case
'S'
:
{
// println("Sync");
sendReadyForQuery
(
'I'
);
break
;
}
case
'Q'
:
{
// println("Query");
String
query
=
readString
();
if
(
query
.
startsWith
(
"select oid, typbasetype from pg_type where typname ="
))
{
query
=
"select oid, typbasetype from pg_catalog.pg_type WHERE 1=0"
;
}
else
if
(
query
.
startsWith
(
"select current_schema()"
))
{
query
=
"CALL SCHEMA()"
;
}
else
if
(
query
.
startsWith
(
"show max_identifier_length"
))
{
query
=
"CALL 63"
;
}
try
{
Statement
stat
=
conn
.
createStatement
();
boolean
result
=
stat
.
execute
(
query
);
if
(
result
)
{
ResultSet
rs
=
stat
.
getResultSet
();
sendResultSet
(
rs
);
}
else
{
int
testing
;
System
.
out
.
println
(
"not a query"
);
// todo
}
}
catch
(
SQLException
e
)
{
e
.
printStackTrace
();
}
break
;
}
case
'X'
:
{
close
();
break
;
}
default
:
error
(
"Unsupported: "
+
x
+
" ("
+
(
char
)
x
+
")"
,
null
);
break
;
}
}
private
String
getSQL
(
String
s
)
{
if
(
s
.
indexOf
(
'$'
)
>
0
)
{
int
todoDontReplaceInQuoted
;
s
=
s
.
replace
(
'$'
,
'?'
);
}
return
s
;
}
private
void
sendCommandComplete
(
String
sql
,
int
updateCount
)
throws
IOException
{
startMessage
(
'C'
);
sql
=
sql
.
trim
().
toUpperCase
();
// TODO remove remarks at the beginning
String
tag
;
if
(
sql
.
startsWith
(
"INSERT"
))
{
tag
=
"INSERT 0 "
+
updateCount
;
}
else
if
(
sql
.
startsWith
(
"DELETE"
))
{
tag
=
"DELETE "
+
updateCount
;
}
else
if
(
sql
.
startsWith
(
"UPDATE"
))
{
tag
=
"UPDATE "
+
updateCount
;
}
else
if
(
sql
.
startsWith
(
"SELECT"
)
||
sql
.
startsWith
(
"CALL"
))
{
tag
=
"SELECT"
;
}
else
{
error
(
"check command tag: "
+
sql
,
null
);
tag
=
"UPDATE "
+
updateCount
;
}
writeString
(
tag
);
sendMessage
();
}
private
void
sendDataRow
(
int
[]
formatCodes
,
ResultSet
rs
)
throws
IOException
{
try
{
int
columns
=
rs
.
getMetaData
().
getColumnCount
();
String
[]
values
=
new
String
[
columns
];
for
(
int
i
=
0
;
i
<
columns
;
i
++)
{
values
[
i
]
=
rs
.
getString
(
i
+
1
);
}
startMessage
(
'D'
);
writeShort
(
columns
);
for
(
int
i
=
0
;
i
<
columns
;
i
++)
{
String
s
=
values
[
i
];
if
(
s
==
null
)
{
writeInt
(-
1
);
}
else
{
// TODO write Binary data
byte
[]
d2
=
s
.
getBytes
(
getEncoding
());
writeInt
(
d2
.
length
);
write
(
d2
);
}
}
sendMessage
();
}
catch
(
SQLException
e
)
{
sendErrorResponse
(
e
);
}
}
private
String
getEncoding
()
{
if
(
clientEncoding
.
equals
(
"UNICODE"
))
{
return
"UTF-8"
;
}
return
clientEncoding
;
}
private
void
setParameter
(
PreparedStatement
prep
,
int
i
,
byte
[]
d2
,
int
[]
formatCodes
)
throws
SQLException
{
boolean
text
=
(
i
>=
formatCodes
.
length
)
||
(
formatCodes
[
i
]
==
0
);
String
s
;
try
{
if
(
text
)
{
s
=
new
String
(
d2
,
getEncoding
());
}
else
{
int
testing
;
System
.
out
.
println
(
"binary format!"
);
s
=
new
String
(
d2
,
getEncoding
());
}
}
catch
(
Exception
e
)
{
error
(
"conversion error"
,
e
);
s
=
null
;
}
prep
.
setString
(
i
+
1
,
s
);
}
private
void
sendErrorResponse
(
SQLException
e
)
throws
IOException
{
error
(
"SQLException"
,
e
);
startMessage
(
'E'
);
write
(
'S'
);
writeString
(
"ERROR"
);
write
(
'C'
);
writeString
(
e
.
getSQLState
());
write
(
'M'
);
writeString
(
e
.
getMessage
());
write
(
'D'
);
writeString
(
e
.
toString
());
sendMessage
();
}
private
void
sendParameterDescription
(
PreparedStatement
prep
)
throws
IOException
{
try
{
ParameterMetaData
meta
=
prep
.
getParameterMetaData
();
int
count
=
meta
.
getParameterCount
();
startMessage
(
't'
);
writeShort
(
count
);
for
(
int
i
=
0
;
i
<
count
;
i
++)
{
writeInt
(
TYPE_STRING
);
}
sendMessage
();
}
catch
(
SQLException
e
)
{
sendErrorResponse
(
e
);
}
}
private
void
sendNoData
()
throws
IOException
{
startMessage
(
'n'
);
sendMessage
();
}
private
void
sendRowDescription
(
ResultSetMetaData
meta
)
throws
IOException
{
try
{
if
(
meta
==
null
)
{
sendNoData
();
}
else
{
int
columns
=
meta
.
getColumnCount
();
int
[]
types
=
new
int
[
columns
];
String
[]
names
=
new
String
[
columns
];
for
(
int
i
=
0
;
i
<
columns
;
i
++)
{
names
[
i
]
=
meta
.
getColumnName
(
i
+
1
);
types
[
i
]
=
meta
.
getColumnType
(
i
+
1
);
}
startMessage
(
'T'
);
writeShort
(
columns
);
for
(
int
i
=
0
;
i
<
columns
;
i
++)
{
writeString
(
names
[
i
]);
writeInt
(
0
);
// object ID
writeShort
(
0
);
// attribute number of the column
writeInt
(
getType
(
types
[
i
]));
// data type
writeShort
(
getTypeSize
(
types
[
i
]));
// pg_type.typlen
writeInt
(
getModifier
(
types
[
i
]));
// pg_attribute.atttypmod
writeShort
(
0
);
// text
}
sendMessage
();
}
}
catch
(
SQLException
e
)
{
sendErrorResponse
(
e
);
}
}
private
int
getType
(
int
type
)
{
switch
(
type
)
{
case
Types
.
VARCHAR
:
return
19
;
}
return
type
;
}
private
int
getTypeSize
(
int
type
)
{
switch
(
type
)
{
case
Types
.
VARCHAR
:
return
255
;
}
return
type
;
}
private
int
getModifier
(
int
type
)
{
return
-
1
;
}
private
void
sendErrorResponse
(
String
message
)
throws
IOException
{
error
(
"Exception: "
+
message
,
null
);
startMessage
(
'E'
);
write
(
'S'
);
writeString
(
"ERROR"
);
write
(
'C'
);
writeString
(
"08P01"
);
// PROTOCOL VIOLATION
write
(
'M'
);
writeString
(
message
);
sendMessage
();
}
private
void
sendParseComplete
()
throws
IOException
{
startMessage
(
'1'
);
sendMessage
();
}
private
void
sendBindComplete
()
throws
IOException
{
startMessage
(
'2'
);
sendMessage
();
}
private
void
initDb
()
throws
SQLException
{
Statement
stat
=
conn
.
createStatement
();
Reader
r
=
new
InputStreamReader
(
getClass
().
getResourceAsStream
(
"pg_catalog.sql"
));
r
=
new
BufferedReader
(
r
);
ScriptReader
reader
=
new
ScriptReader
(
r
);
while
(
true
)
{
String
sql
=
reader
.
readStatement
();
if
(
sql
==
null
)
{
break
;
}
stat
.
execute
(
sql
);
}
}
private
void
sendResultSet
(
ResultSet
rs
)
throws
SQLException
,
IOException
{
ResultSetMetaData
meta
=
rs
.
getMetaData
();
int
columnCount
=
meta
.
getColumnCount
();
//
startMessage
(
'T'
);
writeShort
(
columnCount
);
for
(
int
i
=
0
;
i
<
columnCount
;
i
++)
{
writeString
(
meta
.
getColumnName
(
i
+
1
));
writeInt
(
0
);
// table id
writeShort
(
0
);
// column id
writeInt
(
0
);
// data type id
writeShort
(
26
);
// data type size (see pg_type.typlen)
writeInt
(
4
);
// type modifier (see pg_attribute.atttypmod)
writeShort
(
0
);
// format code 0=text, 1=binary
}
sendMessage
();
while
(
rs
.
next
())
{
// DataRow
startMessage
(
'D'
);
writeShort
(
columnCount
);
for
(
int
i
=
0
;
i
<
columnCount
;
i
++)
{
String
v
=
rs
.
getString
(
i
+
1
);
if
(
v
==
null
)
{
writeInt
(-
1
);
}
else
{
byte
[]
data
=
v
.
getBytes
();
writeInt
(
data
.
length
);
write
(
data
);
}
}
sendMessage
();
}
// CommandComplete
startMessage
(
'C'
);
writeString
(
"SELECT"
);
sendMessage
();
sendReadyForQuery
(
'I'
);
}
public
void
close
()
{
try
{
stop
=
true
;
JdbcUtils
.
closeSilently
(
conn
);
socket
.
close
();
server
.
log
(
"Close"
);
}
catch
(
Exception
e
)
{
server
.
logError
(
e
);
}
conn
=
null
;
socket
=
null
;
server
.
remove
(
this
);
}
private
void
sendAuthenticationCleartextPassword
()
throws
IOException
{
startMessage
(
'R'
);
writeInt
(
3
);
sendMessage
();
}
private
void
sendAuthenticationOk
()
throws
IOException
{
startMessage
(
'R'
);
writeInt
(
0
);
sendMessage
();
sendParameterStatus
(
"client_encoding"
,
clientEncoding
);
sendParameterStatus
(
"DateStyle"
,
dateStyle
);
sendParameterStatus
(
"integer_datetimes"
,
"off"
);
sendParameterStatus
(
"is_superuser"
,
"off"
);
sendParameterStatus
(
"server_encoding"
,
"SQL_ASCII"
);
sendParameterStatus
(
"server_version"
,
"8.1.4"
);
sendParameterStatus
(
"session_authorization"
,
userName
);
sendParameterStatus
(
"standard_conforming_strings"
,
"off"
);
sendParameterStatus
(
"TimeZone"
,
"CET"
);
// TODO
sendBackendKeyData
();
sendReadyForQuery
(
'I'
);
}
private
void
sendReadyForQuery
(
char
c
)
throws
IOException
{
startMessage
(
'Z'
);
write
((
byte
)
c
);
sendMessage
();
}
private
void
sendBackendKeyData
()
throws
IOException
{
startMessage
(
'K'
);
writeInt
(
processId
);
writeInt
(
processId
);
sendMessage
();
}
private
void
writeString
(
String
s
)
throws
IOException
{
write
(
s
.
getBytes
(
"UTF-8"
));
write
(
0
);
}
private
void
writeInt
(
int
i
)
throws
IOException
{
dataOut
.
writeInt
(
i
);
}
private
void
writeShort
(
int
i
)
throws
IOException
{
dataOut
.
writeShort
(
i
);
}
private
void
write
(
byte
[]
data
)
throws
IOException
{
dataOut
.
write
(
data
);
}
private
void
write
(
int
b
)
throws
IOException
{
dataOut
.
write
(
b
);
}
private
void
startMessage
(
int
messageType
)
{
this
.
messageType
=
messageType
;
outBuffer
=
new
ByteArrayOutputStream
();
dataOut
=
new
DataOutputStream
(
outBuffer
);
}
private
void
sendMessage
()
throws
IOException
{
dataOut
.
flush
();
byte
[]
buff
=
outBuffer
.
toByteArray
();
int
len
=
buff
.
length
;
dataOut
=
new
DataOutputStream
(
out
);
dataOut
.
write
(
messageType
);
dataOut
.
writeInt
(
len
+
4
);
dataOut
.
write
(
buff
);
dataOut
.
flush
();
}
private
void
sendParameterStatus
(
String
param
,
String
value
)
throws
IOException
{
startMessage
(
'S'
);
writeString
(
param
);
writeString
(
value
);
sendMessage
();
}
public
void
setThread
(
Thread
thread
)
{
this
.
thread
=
thread
;
}
public
Thread
getThread
()
{
return
thread
;
}
public
void
setProcessId
(
int
id
)
{
this
.
processId
=
id
;
}
private
static
class
Prepared
{
String
name
;
String
sql
;
PreparedStatement
prep
;
int
[]
paramType
;
}
private
static
class
Portal
{
String
name
;
String
sql
;
int
[]
resultColumnFormat
;
PreparedStatement
prep
;
}
}
h2/src/main/org/h2/server/pg/pg_catalog.sql
0 → 100644
浏览文件 @
13af88a2
drop
schema
if
exists
pg_catalog
;
create
schema
pg_catalog
;
create
view
pg_catalog
.
pg_type
(
oid
,
typlen
,
typbasetype
,
typname
,
typnamespace
)
as
select
data_type
oid
,
precision
,
data_type
,
cast
(
type_name
as
varchar_ignorecase
)
typbasetype
,
select
id
from
information_schema
.
schemata
where
schema_name
=
'PG_CATALOG'
from
information_schema
.
type_info
union
select
1111
,
64
,
1111
,
'name'
,
select
id
from
information_schema
.
schemata
where
schema_name
=
'PG_CATALOG'
from
dual
;
create
view
pg_catalog
.
pg_namespace
(
oid
,
nspname
)
as
select
id
,
cast
(
schema_name
as
varchar_ignorecase
)
from
information_schema
.
schemata
;
create
view
pg_catalog
.
pg_class
(
oid
,
relname
,
relnamespace
,
relkind
)
as
select
id
,
cast
(
table_name
as
varchar_ignorecase
),
(
select
id
from
information_schema
.
schemata
where
schema_name
=
table_schema
),
case
table_type
when
'TABLE'
then
'r'
else
'v'
end
from
information_schema
.
tables
;
create
view
pg_catalog
.
pg_description
(
objoid
,
objsubid
,
classoid
,
description
)
as
select
id
,
0
,
-
1
,
cast
(
''
as
varchar_ignorecase
)
from
information_schema
.
tables
where
1
=
0
;
create
view
pg_catalog
.
pg_attrdef
(
oid
,
adsrc
,
adrelid
,
adnum
)
as
select
id
,
0
,
0
,
0
from
information_schema
.
tables
where
1
=
0
;
create
view
pg_catalog
.
pg_attribute
(
oid
,
attname
,
atttypid
,
attnotnull
,
atttypmod
,
attlen
,
attnum
,
attrelid
,
attisdropped
)
as
select
t
.
id
*
10000
+
ordinal_position
,
column_name
,
data_type
,
false
,
-
1
,
numeric_precision
,
ordinal_position
,
t
.
id
,
false
from
information_schema
.
tables
t
,
information_schema
.
columns
c
where
t
.
table_name
=
c
.
table_name
and
t
.
table_schema
=
c
.
table_schema
;
SELECT
NULL
AS
TABLE_CAT
,
n
.
nspname
AS
TABLE_SCHEM
,
ct
.
relname
AS
TABLE_NAME
,
NOT
i
.
indisunique
AS
NON_UNIQUE
,
NULL
AS
INDEX_QUALIFIER
,
ci
.
relname
AS
INDEX_NAME
,
CASE
i
.
indisclustered
WHEN
true
THEN
1
ELSE
CASE
am
.
amname
WHEN
'hash'
THEN
2
ELSE
3
END
END
AS
TYPE
,
a
.
attnum
AS
ORDINAL_POSITION
,
CASE
i
.
indexprs
WHEN
null
THEN
a
.
attname
ELSE
pg_get_indexdef
(
ci
.
oid
,
a
.
attnum
,
false
)
END
AS
COLUMN_NAME
,
NULL
AS
ASC_OR_DESC
,
ci
.
reltuples
AS
CARDINALITY
,
ci
.
relpages
AS
PAGES
,
NULL
AS
FILTER_CONDITION
FROM
pg_catalog
.
pg_namespace
n
,
pg_catalog
.
pg_class
ct
,
pg_catalog
.
pg_class
ci
,
pg_catalog
.
pg_attribute
a
,
pg_catalog
.
pg_am
am
,
pg_catalog
.
pg_index
i
WHERE
ct
.
oid
=
i
.
indrelid
AND
ci
.
oid
=
i
.
indexrelid
AND
a
.
attrelid
=
ci
.
oid
AND
ci
.
relam
=
am
.
oid
AND
n
.
oid
=
ct
.
relnamespace
AND
n
.
nspname
=
'PUBLIC'
AND
ct
.
relname
=
'TEST'
ORDER
BY
NON_UNIQUE
,
TYPE
,
INDEX_NAME
,
ORDINAL_POSITION
;
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论