diff --git a/contrib/dolphin/input/b_proto_jdbc.source b/contrib/dolphin/input/b_proto_jdbc.source index edaecf7eb1369651820806202ad6210e2c0f3803..0631c54ec2bc166257961aca7116028164047270 100644 --- a/contrib/dolphin/input/b_proto_jdbc.source +++ b/contrib/dolphin/input/b_proto_jdbc.source @@ -37,6 +37,8 @@ select * from t3; \! @abs_bindir@/../jre/bin/java -cp $CLASSPATH:@abs_builddir@/proto_jdbc/class/mysql-connector-java-5.1.47.jar:@abs_builddir@/proto_jdbc/class/. MySQLJdbcTinyInt1IsBitTest localhost $dp db_jdbc proto_user Gauss@123 +\! @abs_bindir@/../jre/bin/java -cp $CLASSPATH:@abs_builddir@/proto_jdbc/class/mysql-connector-java-5.1.47.jar:@abs_builddir@/proto_jdbc/class/. MySQLJdbcTypeCanBeNullTest localhost $dp db_jdbc proto_user Gauss@123 + \! @abs_bindir@/../jre/bin/java -cp $CLASSPATH:@abs_builddir@/proto_jdbc/class/mysql-connector-java-5.1.47.jar:@abs_builddir@/proto_jdbc/class/. MySQLJdbcAutoCommitTest localhost $dp db_jdbc proto_user Gauss@123 select relname from pg_class where relname like '%autocommit_test%' order by relname; diff --git a/contrib/dolphin/input/b_proto_jdbc_8_0_28.source b/contrib/dolphin/input/b_proto_jdbc_8_0_28.source index 606ab924798c669e91ff3cba4c815262976e2567..fa99a334fa14d6e9dcaf7f28d82b13b2844c9724 100644 --- a/contrib/dolphin/input/b_proto_jdbc_8_0_28.source +++ b/contrib/dolphin/input/b_proto_jdbc_8_0_28.source @@ -101,6 +101,8 @@ select * from autocommit_test6; \! @abs_bindir@/../jre/bin/java -cp $CLASSPATH:@abs_builddir@/proto_jdbc/class/mysql-connector-java-8.0.28.jar:@abs_builddir@/proto_jdbc/class/. MySQLJdbcTinyInt1IsBitTest localhost $dp db_jdbc proto_user Gauss@123 +\! @abs_bindir@/../jre/bin/java -cp $CLASSPATH:@abs_builddir@/proto_jdbc/class/mysql-connector-java-8.0.28.jar:@abs_builddir@/proto_jdbc/class/. MySQLJdbcTypeCanBeNullTest localhost $dp db_jdbc proto_user Gauss@123 + RESET ROLE; DROP USER IF EXISTS proto_user CASCADE; diff --git a/contrib/dolphin/output/b_proto_jdbc.source b/contrib/dolphin/output/b_proto_jdbc.source index 493a8d116e81a7e4e06ff7e0f8500d2f2e451287..d3ca36c3fc5543621405791f225f5bda9ea26c9a 100644 --- a/contrib/dolphin/output/b_proto_jdbc.source +++ b/contrib/dolphin/output/b_proto_jdbc.source @@ -443,6 +443,15 @@ true 1 false 0 +\! @abs_bindir@/../jre/bin/java -cp $CLASSPATH:@abs_builddir@/proto_jdbc/class/mysql-connector-java-5.1.47.jar:@abs_builddir@/proto_jdbc/class/. MySQLJdbcTypeCanBeNullTest localhost $dp db_jdbc proto_user Gauss@123 +id +1 +create_time +2025-04-25 17:00:00.0 +update_time +null +remark +test \! @abs_bindir@/../jre/bin/java -cp $CLASSPATH:@abs_builddir@/proto_jdbc/class/mysql-connector-java-5.1.47.jar:@abs_builddir@/proto_jdbc/class/. MySQLJdbcAutoCommitTest localhost $dp db_jdbc proto_user Gauss@123 select relname from pg_class where relname like '%autocommit_test%' order by relname; relname diff --git a/contrib/dolphin/output/b_proto_jdbc_8_0_28.source b/contrib/dolphin/output/b_proto_jdbc_8_0_28.source index 4802caf4772352c9ac5fa804e60cc85cde99b335..c2470faac6e49f6573e91228ac0bfa2a5696cf54 100644 --- a/contrib/dolphin/output/b_proto_jdbc_8_0_28.source +++ b/contrib/dolphin/output/b_proto_jdbc_8_0_28.source @@ -456,6 +456,15 @@ true 1 false 0 +\! @abs_bindir@/../jre/bin/java -cp $CLASSPATH:@abs_builddir@/proto_jdbc/class/mysql-connector-java-8.0.28.jar:@abs_builddir@/proto_jdbc/class/. MySQLJdbcTypeCanBeNullTest localhost $dp db_jdbc proto_user Gauss@123 +id +1 +create_time +2025-04-25 17:00:00 +update_time +null +remark +test RESET ROLE; DROP USER IF EXISTS proto_user CASCADE; \! rm @abs_builddir@/proto_jdbc/class/*.class \ No newline at end of file diff --git a/contrib/dolphin/plugin_protocol/printtup.cpp b/contrib/dolphin/plugin_protocol/printtup.cpp index 1dc078670c56decada01df36ae5726b555f4a43a..c5090f89f77b3a04401e25004b4b667d74906f32 100644 --- a/contrib/dolphin/plugin_protocol/printtup.cpp +++ b/contrib/dolphin/plugin_protocol/printtup.cpp @@ -249,6 +249,11 @@ static void convertBitsToBytes(char* bitStr, StringInfo buf) } } +static bool typeCanSendNull(Oid typid) +{ + return typid == TIMESTAMPOID; +} + static void send_textproto(TupleTableSlot *slot, DR_printtup *myState, int natts, StringInfo buf) { /* @@ -261,7 +266,11 @@ static void send_textproto(TupleTableSlot *slot, DR_printtup *myState, int natts char *outputstr = NULL; if (slot->tts_isnull[i] || slot->tts_tupleDescriptor->attrs[i].attisdropped) { - dq_append_string_lenenc(buf, ""); + if (typeCanSendNull(slot->tts_tupleDescriptor->attrs[i].atttypid)) { + dq_append_string_lenenc(buf, NULL); + } else { + dq_append_string_lenenc(buf, ""); + } continue; } diff --git a/contrib/dolphin/proto_jdbc/class/MySQLJdbcTypeCanBeNullTest.java b/contrib/dolphin/proto_jdbc/class/MySQLJdbcTypeCanBeNullTest.java new file mode 100644 index 0000000000000000000000000000000000000000..06515e5e1989c7b63456ff578fe148b63583e108 --- /dev/null +++ b/contrib/dolphin/proto_jdbc/class/MySQLJdbcTypeCanBeNullTest.java @@ -0,0 +1,86 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.PreparedStatement; +import java.sql.Statement; +import java.util.Properties; +import java.sql.SQLException; + +public class MySQLJdbcTypeCanBeNullTest { + private static String host; + private static String port = "3307"; + private static String dbname; + private static String user; + private static String password; + private static String jar_version = "old"; + private static String url_jdbc; + + public static void main(String[] args) throws Exception { + if (args.length >= 5) { + host = args[0]; + port = args[1]; + dbname = args[2]; + user = args[3]; + password = args[4]; + if (args.length == 6) { + jar_version = args[5]; + } + } + + Properties info = new Properties(); + info.setProperty("HOST", host); + info.setProperty("PORT", port); + info.setProperty("DBNAME", dbname); + info.setProperty("user", user); + info.setProperty("password", password); + + if (jar_version.equals("new")) { + url_jdbc = "jdbc:mysql://?serverTimezone=UTC"; + } else { + url_jdbc = "jdbc:mysql://?serverTimezone=UTC&useSSL=false"; + } + + try (Connection connection = DriverManager + .getConnection(url_jdbc, info); + Statement stmt = connection.createStatement()) { + try { + stmt.execute("drop table if exists zz_sys_ops_package3;"); + stmt.execute("CREATE TABLE IF NOT EXISTS zz_sys_ops_package3 ( id int NOT NULL AUTO_INCREMENT COMMENT 'id', create_time datetime NOT NULL COMMENT '添加时间', update_time datetime(0) COMMENT '.新时间', remark varchar(512) DEFAULT NULL COMMENT '备注', PRIMARY KEY (id) ) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8;"); + stmt.execute("insert into zz_sys_ops_package3 values(1,'2025-04-25 17:00:00',null,'test');"); + ResultSet rs = stmt.executeQuery("select * from zz_sys_ops_package3;"); + while (rs.next()) { + System.out.println(rs.getMetaData().getColumnName(1)); + System.out.println(rs.getString(1)); + System.out.println(rs.getMetaData().getColumnName(2)); + System.out.println(rs.getString(2)); + System.out.println(rs.getMetaData().getColumnName(3)); + System.out.println(rs.getString(3)); + System.out.println(rs.getMetaData().getColumnName(4)); + System.out.println(rs.getString(4)); + } + rs.close(); + } catch (SQLException e) { + System.out.println("execute failed:" + e.getMessage()); + } + stmt.close(); + connection.close(); + } + } +} \ No newline at end of file