Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
c7348c0d
Unverified
提交
c7348c0d
authored
7 年前
作者:
Noel Grandin
提交者:
GitHub
7 年前
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #849 from katzyn/pgserver
Encode date and time in fast and proper way in PgServerThread
上级
9098cb27
fe6b465d
隐藏空白字符变更
内嵌
并排
正在显示
4 个修改的文件
包含
97 行增加
和
123 行删除
+97
-123
JdbcResultSet.java
h2/src/main/org/h2/jdbc/JdbcResultSet.java
+8
-1
PgServerThread.java
h2/src/main/org/h2/server/pg/PgServerThread.java
+60
-119
DateTimeUtils.java
h2/src/main/org/h2/util/DateTimeUtils.java
+23
-0
TestPgServer.java
h2/src/test/org/h2/test/unit/TestPgServer.java
+6
-3
没有找到文件。
h2/src/main/org/h2/jdbc/JdbcResultSet.java
浏览文件 @
c7348c0d
...
...
@@ -3222,7 +3222,14 @@ public class JdbcResultSet extends TraceObject implements ResultSet, JdbcResultS
}
}
private
Value
get
(
int
columnIndex
)
{
/**
* INTERNAL
*
* @param columnIndex
* index of a column
* @return internal representation of the value in the specified column
*/
public
Value
get
(
int
columnIndex
)
{
checkColumnIndex
(
columnIndex
);
checkOnValidRow
();
Value
[]
list
;
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/server/pg/PgServerThread.java
浏览文件 @
c7348c0d
...
...
@@ -20,35 +20,38 @@ import java.net.Socket;
import
java.nio.charset.Charset
;
import
java.nio.charset.StandardCharsets
;
import
java.sql.Connection
;
import
java.sql.Date
;
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.Time
;
import
java.sql.Timestamp
;
import
java.sql.Types
;
import
java.util.HashMap
;
import
java.util.HashSet
;
import
java.util.Properties
;
import
java.util.TimeZone
;
import
org.h2.command.CommandInterface
;
import
org.h2.engine.ConnectionInfo
;
import
org.h2.engine.SysProperties
;
import
org.h2.jdbc.JdbcConnection
;
import
org.h2.jdbc.JdbcPreparedStatement
;
import
org.h2.jdbc.JdbcResultSet
;
import
org.h2.jdbc.JdbcStatement
;
import
org.h2.message.DbException
;
import
org.h2.mvstore.DataUtils
;
import
org.h2.util.DateTimeUtils
;
import
org.h2.util.JdbcUtils
;
import
org.h2.util.MathUtils
;
import
org.h2.util.ScriptReader
;
import
org.h2.util.StringUtils
;
import
org.h2.util.Utils
;
import
org.h2.value.CaseInsensitiveMap
;
import
org.h2.value.Value
;
import
org.h2.value.ValueDate
;
import
org.h2.value.ValueNull
;
import
org.h2.value.ValueTime
;
import
org.h2.value.ValueTimestamp
;
/**
* One server thread is opened for each client.
...
...
@@ -527,153 +530,91 @@ public class PgServerThread implements Runnable {
sendMessage
();
}
private
static
long
toPostgreSeconds
(
long
millis
)
{
// TODO handle Julian/Gregorian transitions
return
millis
/
1000
-
946684800L
;
private
static
long
toPostgreDays
(
long
dateValue
)
{
return
DateTimeUtils
.
prolepticGregorianAbsoluteDayFromDateValue
(
dateValue
)
-
10_957
;
}
private
void
writeDataColumn
(
ResultSet
rs
,
int
column
,
int
pgType
,
boolean
text
)
throws
Exception
{
Value
v
=
((
JdbcResultSet
)
rs
).
get
(
column
);
if
(
v
==
ValueNull
.
INSTANCE
)
{
writeInt
(-
1
);
return
;
}
if
(
text
)
{
// plain text
switch
(
pgType
)
{
case
PgServer
.
PG_TYPE_BOOL
:
{
boolean
b
=
rs
.
getBoolean
(
column
);
if
(
rs
.
wasNull
())
{
writeInt
(-
1
);
}
else
{
writeInt
(
1
);
dataOut
.
writeByte
(
b
?
't'
:
'f'
);
}
case
PgServer
.
PG_TYPE_BOOL
:
writeInt
(
1
);
dataOut
.
writeByte
(
v
.
getBoolean
()
?
't'
:
'f'
);
break
;
}
default
:
String
s
=
rs
.
getString
(
column
);
if
(
s
==
null
)
{
writeInt
(-
1
);
}
else
{
byte
[]
data
=
s
.
getBytes
(
getEncoding
());
writeInt
(
data
.
length
);
write
(
data
);
}
byte
[]
data
=
v
.
getString
().
getBytes
(
getEncoding
());
writeInt
(
data
.
length
);
write
(
data
);
}
}
else
{
// binary
switch
(
pgType
)
{
case
PgServer
.
PG_TYPE_INT2
:
{
short
s
=
rs
.
getShort
(
column
);
if
(
rs
.
wasNull
())
{
writeInt
(-
1
);
}
else
{
writeInt
(
2
);
writeShort
(
s
);
}
case
PgServer
.
PG_TYPE_INT2
:
writeInt
(
2
);
writeShort
(
v
.
getShort
());
break
;
}
case
PgServer
.
PG_TYPE_INT4
:
{
int
i
=
rs
.
getInt
(
column
);
if
(
rs
.
wasNull
())
{
writeInt
(-
1
);
}
else
{
writeInt
(
4
);
writeInt
(
i
);
}
case
PgServer
.
PG_TYPE_INT4
:
writeInt
(
4
);
writeInt
(
v
.
getInt
());
break
;
}
case
PgServer
.
PG_TYPE_INT8
:
{
long
l
=
rs
.
getLong
(
column
);
if
(
rs
.
wasNull
())
{
writeInt
(-
1
);
}
else
{
writeInt
(
8
);
dataOut
.
writeLong
(
l
);
}
case
PgServer
.
PG_TYPE_INT8
:
writeInt
(
8
);
dataOut
.
writeLong
(
v
.
getLong
());
break
;
}
case
PgServer
.
PG_TYPE_FLOAT4
:
{
float
f
=
rs
.
getFloat
(
column
);
if
(
rs
.
wasNull
())
{
writeInt
(-
1
);
}
else
{
writeInt
(
4
);
dataOut
.
writeFloat
(
f
);
}
case
PgServer
.
PG_TYPE_FLOAT4
:
writeInt
(
4
);
dataOut
.
writeFloat
(
v
.
getFloat
());
break
;
}
case
PgServer
.
PG_TYPE_FLOAT8
:
{
double
d
=
rs
.
getDouble
(
column
);
if
(
rs
.
wasNull
())
{
writeInt
(-
1
);
}
else
{
writeInt
(
8
);
dataOut
.
writeDouble
(
d
);
}
case
PgServer
.
PG_TYPE_FLOAT8
:
writeInt
(
8
);
dataOut
.
writeDouble
(
v
.
getDouble
());
break
;
}
case
PgServer
.
PG_TYPE_BYTEA
:
{
byte
[]
data
=
rs
.
getBytes
(
column
);
if
(
data
==
null
)
{
writeInt
(-
1
);
}
else
{
writeInt
(
data
.
length
);
write
(
data
);
}
byte
[]
data
=
v
.
getBytesNoCopy
();
writeInt
(
data
.
length
);
write
(
data
);
break
;
}
case
PgServer
.
PG_TYPE_DATE
:
{
Date
d
=
rs
.
getDate
(
column
);
if
(
d
==
null
)
{
writeInt
(-
1
);
}
else
{
writeInt
(
4
);
long
millis
=
d
.
getTime
();
millis
+=
TimeZone
.
getDefault
().
getOffset
(
millis
);
writeInt
((
int
)
(
toPostgreSeconds
(
millis
)
/
86400
));
}
ValueDate
d
=
(
ValueDate
)
v
.
convertTo
(
Value
.
DATE
);
writeInt
(
4
);
writeInt
((
int
)
(
toPostgreDays
(
d
.
getDateValue
())));
break
;
}
case
PgServer
.
PG_TYPE_TIME
:
{
Time
t
=
rs
.
getTime
(
column
);
if
(
t
==
null
)
{
writeInt
(-
1
);
ValueTime
t
=
(
ValueTime
)
v
.
convertTo
(
Value
.
TIME
);
writeInt
(
8
);
long
m
=
t
.
getNanos
();
if
(
INTEGER_DATE_TYPES
)
{
// long format
m
/=
1_000
;
}
else
{
writeInt
(
8
);
long
m
=
t
.
getTime
();
m
+=
TimeZone
.
getDefault
().
getOffset
(
m
);
if
(
INTEGER_DATE_TYPES
)
{
// long format
m
*=
1000
;
}
else
{
// double format
m
/=
1000
;
m
=
Double
.
doubleToLongBits
(
m
);
}
dataOut
.
writeLong
(
m
);
// double format
m
=
Double
.
doubleToLongBits
(
m
*
0.000_000_001
);
}
dataOut
.
writeLong
(
m
);
break
;
}
case
PgServer
.
PG_TYPE_TIMESTAMP_NO_TMZONE
:
{
Timestamp
t
=
rs
.
getTimestamp
(
column
);
if
(
t
==
null
)
{
writeInt
(-
1
);
ValueTimestamp
t
=
(
ValueTimestamp
)
v
.
convertTo
(
Value
.
TIMESTAMP
);
writeInt
(
8
);
long
m
=
toPostgreDays
(
t
.
getDateValue
())
*
86_400
;
long
nanos
=
t
.
getTimeNanos
();
if
(
INTEGER_DATE_TYPES
)
{
// long format
m
=
m
*
1_000_000
+
nanos
/
1_000
;
}
else
{
writeInt
(
8
);
long
m
=
t
.
getTime
();
m
+=
TimeZone
.
getDefault
().
getOffset
(
m
);
m
=
toPostgreSeconds
(
m
);
int
nanos
=
t
.
getNanos
();
if
(
m
<
0
&&
nanos
!=
0
)
{
m
--;
}
if
(
INTEGER_DATE_TYPES
)
{
// long format
m
=
m
*
1000000
+
nanos
/
1000
;
}
else
{
// double format
m
=
Double
.
doubleToLongBits
(
m
+
nanos
*
0.000000001
);
}
dataOut
.
writeLong
(
m
);
// double format
m
=
Double
.
doubleToLongBits
(
m
+
nanos
*
0.000_000_001
);
}
dataOut
.
writeLong
(
m
);
break
;
}
default
:
throw
new
IllegalStateException
(
"output binary format is undefined"
);
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/util/DateTimeUtils.java
浏览文件 @
c7348c0d
...
...
@@ -1120,6 +1120,29 @@ public class DateTimeUtils {
return
a
;
}
/**
* Calculate the absolute day from an encoded date value in proleptic Gregorian
* calendar.
*
* @param dateValue the date value
* @return the absolute day in proleptic Gregorian calendar
*/
public
static
long
prolepticGregorianAbsoluteDayFromDateValue
(
long
dateValue
)
{
long
y
=
yearFromDateValue
(
dateValue
);
int
m
=
monthFromDateValue
(
dateValue
);
int
d
=
dayFromDateValue
(
dateValue
);
if
(
m
<=
2
)
{
y
--;
m
+=
12
;
}
long
a
=
((
y
*
2922L
)
>>
3
)
+
DAYS_OFFSET
[
m
-
3
]
+
d
-
719484
;
if
(
y
<
1901
||
y
>
2099
)
{
// Slow mode
a
+=
(
y
/
400
)
-
(
y
/
100
)
+
15
;
}
return
a
;
}
/**
* Calculate the encoded date value from an absolute day.
*
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/unit/TestPgServer.java
浏览文件 @
c7348c0d
...
...
@@ -487,13 +487,16 @@ public class TestPgServer extends TestBase {
Date
[]
dates
=
{
null
,
Date
.
valueOf
(
"2017-02-20"
),
Date
.
valueOf
(
"1970-01-01"
),
Date
.
valueOf
(
"1969-12-31"
),
Date
.
valueOf
(
"1940-01-10"
),
Date
.
valueOf
(
"1950-11-10"
)
};
Date
.
valueOf
(
"1940-01-10"
),
Date
.
valueOf
(
"1950-11-10"
),
Date
.
valueOf
(
"1500-01-01"
)};
Time
[]
times
=
{
null
,
Time
.
valueOf
(
"14:15:16"
),
Time
.
valueOf
(
"00:00:00"
),
Time
.
valueOf
(
"23:59:59"
),
Time
.
valueOf
(
"00:10:59"
),
Time
.
valueOf
(
"08:30:42"
)
};
Time
.
valueOf
(
"00:10:59"
),
Time
.
valueOf
(
"08:30:42"
),
Time
.
valueOf
(
"10:00:00"
)};
Timestamp
[]
timestamps
=
{
null
,
Timestamp
.
valueOf
(
"2017-02-20 14:15:16.763"
),
Timestamp
.
valueOf
(
"1970-01-01 00:00:00"
),
Timestamp
.
valueOf
(
"1969-12-31 23:59:59"
),
Timestamp
.
valueOf
(
"1940-01-10 00:10:59"
),
Timestamp
.
valueOf
(
"1950-11-10 08:30:42.12"
)
};
Timestamp
.
valueOf
(
"1940-01-10 00:10:59"
),
Timestamp
.
valueOf
(
"1950-11-10 08:30:42.12"
),
Timestamp
.
valueOf
(
"1500-01-01 10:00:10"
)};
int
count
=
dates
.
length
;
PreparedStatement
ps
=
conn
.
prepareStatement
(
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论