Skip to content

Commit

Permalink
add Date32 support (#375)
Browse files Browse the repository at this point in the history
Co-authored-by: Neng Liu <[email protected]>
  • Loading branch information
liuneng1994 and Neng Liu authored Sep 28, 2021
1 parent 0ca2e83 commit f99ab4e
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import com.github.housepower.client.NativeContext;
import com.github.housepower.data.type.DataTypeDate;
import com.github.housepower.data.type.DataTypeDate32;
import com.github.housepower.data.type.DataTypeFloat32;
import com.github.housepower.data.type.DataTypeFloat64;
import com.github.housepower.data.type.DataTypeIPv4;
Expand Down Expand Up @@ -127,6 +128,7 @@ public class DataTypeFactory {
registerType(creators, new DataTypeUInt64());

registerType(creators, new DataTypeDate());
registerType(creators, new DataTypeDate32());
return creators;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.github.housepower.data.type;

import com.github.housepower.data.IDataType;
import com.github.housepower.misc.SQLLexer;
import com.github.housepower.misc.Validate;
import com.github.housepower.serde.BinaryDeserializer;
import com.github.housepower.serde.BinarySerializer;

import java.io.IOException;
import java.sql.Date;
import java.sql.SQLException;
import java.sql.Types;
import java.time.LocalDate;

public class DataTypeDate32 implements IDataType<LocalDate, Date> {

// First day of Date32
private static final LocalDate DEFAULT_VALUE = LocalDate.of(1925, 1, 1);

public DataTypeDate32() {
}

@Override
public String name() {
return "Date32";
}

@Override
public int sqlTypeId() {
return Types.DATE;
}

@Override
public LocalDate defaultValue() {
return DEFAULT_VALUE;
}

@Override
public Class<LocalDate> javaType() {
return LocalDate.class;
}

@Override
public Class<Date> jdbcJavaType() {
return Date.class;
}

@Override
public int getPrecision() {
return 10;
}

@Override
public int getScale() {
return 0;
}

@Override
public void serializeBinary(LocalDate data, BinarySerializer serializer) throws SQLException, IOException {
long epochDay = data.toEpochDay();
serializer.writeInt((int) epochDay);
}

@Override
public LocalDate deserializeBinary(BinaryDeserializer deserializer) throws IOException {
int epochDay = deserializer.readInt();
return LocalDate.ofEpochDay(epochDay);
}

@Override
public String[] getAliases() {
return new String[0];
}

@Override
public LocalDate deserializeText(SQLLexer lexer) throws SQLException {
Validate.isTrue(lexer.character() == '\'');
int year = lexer.numberLiteral().intValue();
Validate.isTrue(lexer.character() == '-');
int month = lexer.numberLiteral().intValue();
Validate.isTrue(lexer.character() == '-');
int day = lexer.numberLiteral().intValue();
Validate.isTrue(lexer.character() == '\'');

return LocalDate.of(year, month, day);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import com.github.housepower.data.IColumn;
import com.github.housepower.data.IDataType;
import com.github.housepower.data.type.DataTypeDate;
import com.github.housepower.data.type.DataTypeDate32;
import com.github.housepower.data.type.DataTypeFloat32;
import com.github.housepower.data.type.DataTypeFloat64;
import com.github.housepower.data.type.DataTypeInt16;
Expand Down Expand Up @@ -236,6 +237,13 @@ private Object convertToCkDataType(IDataType<?, ?> type, Object obj) throws Clic
if (obj instanceof LocalDate)
return obj;
}

if (type instanceof DataTypeDate32) {
if (obj instanceof java.util.Date)
return ((Date) obj).toLocalDate();
if (obj instanceof LocalDate)
return obj;
}
// TODO support
// 1. other Java8 time, i.e. OffsetDateTime, Instant
// 2. unix timestamp, but in second or millisecond?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,7 @@ public abstract class AbstractITest implements Serializable {
protected static final ZoneId SERVER_TZ = ZoneId.of("UTC");
protected static final String DRIVER_CLASS_NAME = "com.github.housepower.jdbc.ClickHouseDriver";

// ClickHouse support gRPC from v21.1.2.15-stable 2021-01-18
// link: https://github.com/ClickHouse/ClickHouse/blob/master/CHANGELOG.md#clickhouse-release-v211215-stable-2021-01-18
public static final String CLICKHOUSE_IMAGE = SystemUtil.loadProp("CLICKHOUSE_IMAGE", "yandex/clickhouse-server:21.3");
public static final String CLICKHOUSE_IMAGE = System.getProperty("CLICKHOUSE_IMAGE", "yandex/clickhouse-server:21.9");

protected static final String CLICKHOUSE_USER = SystemUtil.loadProp("CLICKHOUSE_USER", "default");
protected static final String CLICKHOUSE_PASSWORD = SystemUtil.loadProp("CLICKHOUSE_PASSWORD", "");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@

import org.junit.jupiter.api.Test;

import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;

import static org.junit.jupiter.api.Assertions.*;

Expand Down Expand Up @@ -128,6 +131,41 @@ public void successfullyDoubleColumn() throws Exception {
});
}

@Test
public void successfullyDate32Column() throws Exception {
withNewConnection(connect -> {
Statement statement = connect.createStatement();
ResultSet rs = statement.executeQuery("SELECT toDate32('1955-01-01') AS value, toTypeName(value)");

assertTrue(rs.next());
assertEquals(Date.valueOf("1955-01-01"), rs.getDate(1));
assertEquals("Date32", rs.getString(2));
});

withNewConnection(connection -> {
try (Statement statement = connection.createStatement()) {

statement.executeQuery("DROP TABLE IF EXISTS test");
statement.executeQuery("CREATE TABLE test(a Date32)ENGINE=Memory");

try (PreparedStatement ps = connection.prepareStatement("INSERT INTO test VALUES(?)")) {
ps.setDate(1, Date.valueOf("1955-01-01"));
assertEquals(1, ps.executeUpdate());
}

try (PreparedStatement ps = connection.prepareStatement("SELECT * FROM test WHERE a = toDate32(?)")) {
ps.setDate(1, Date.valueOf("1955-01-01"));
try (ResultSet rs = ps.executeQuery()) {
assertTrue(rs.next());
assertEquals(Date.valueOf("1955-01-01"), rs.getDate(1));
assertFalse(rs.next());
}
}
statement.executeQuery("DROP TABLE IF EXISTS test");
}
});
}

@Test
public void successfullyUUIDColumn() throws Exception {
withStatement(statement -> {
Expand All @@ -142,7 +180,7 @@ public void successfullyUUIDColumn() throws Exception {
public void successfullyMetadata() throws Exception {
withStatement(statement -> {
ResultSet rs = statement.executeQuery(
"SELECT number as a1, toString(number) as a2, now() as a3, today() as a4 from numbers(1)");
"SELECT number as a1, toString(number) as a2, now() as a3, today() as a4, toDate32(today()) as a5 from numbers(1)");

assertTrue(rs.next());
ResultSetMetaData metaData = rs.getMetaData();
Expand All @@ -161,6 +199,10 @@ public void successfullyMetadata() throws Exception {
assertEquals("a4", metaData.getColumnName(4));
assertEquals("Date", metaData.getColumnTypeName(4));
assertEquals("java.sql.Date", metaData.getColumnClassName(4));

assertEquals("a5", metaData.getColumnName(5));
assertEquals("Date32", metaData.getColumnTypeName(5));
assertEquals("java.sql.Date", metaData.getColumnClassName(5));
});
}

Expand Down

0 comments on commit f99ab4e

Please sign in to comment.