From 603d4f1ab4a1bb0f838dc1f5e25eeb89e5c896d7 Mon Sep 17 00:00:00 2001 From: karimGl Date: Tue, 19 Nov 2024 19:42:33 +0100 Subject: [PATCH] feat(action): sql client can handle blob (tested with h2 and oracle) --- chutney/action-impl/pom.xml | 14 ++ .../action/sql/core/SqlClient.java | 22 +- .../action/sql/SqlActionTest.java | 2 +- .../action/sql/core/SqlClientTest.java | 207 +++++++++++------- .../create_users.sql} | 7 + .../src/test/resources/db/h2/create_types.sql | 41 ++++ .../test/resources/db/oracle/create_types.sql | 40 ++++ .../src/test/resources/db/oracle/init.sh | 9 + .../src/test/resources/db/sql/create_db.sql | 33 --- .../resources/db/sql/insert_allsqltypes.sql | 25 --- 10 files changed, 255 insertions(+), 145 deletions(-) rename chutney/action-impl/src/test/resources/db/{sql/insert_users.sql => common/create_users.sql} (70%) create mode 100644 chutney/action-impl/src/test/resources/db/h2/create_types.sql create mode 100644 chutney/action-impl/src/test/resources/db/oracle/create_types.sql create mode 100644 chutney/action-impl/src/test/resources/db/oracle/init.sh delete mode 100644 chutney/action-impl/src/test/resources/db/sql/create_db.sql delete mode 100644 chutney/action-impl/src/test/resources/db/sql/insert_allsqltypes.sql diff --git a/chutney/action-impl/pom.xml b/chutney/action-impl/pom.xml index c82567440..033f144e4 100644 --- a/chutney/action-impl/pom.xml +++ b/chutney/action-impl/pom.xml @@ -26,6 +26,9 @@ repo + + 23.6.0.24.10 + @@ -300,6 +303,17 @@ selenium test + + org.testcontainers + oracle-free + test + + + com.oracle.database.jdbc + ojdbc11 + ${ojdbc11.version} + test + com.h2database h2 diff --git a/chutney/action-impl/src/main/java/com/chutneytesting/action/sql/core/SqlClient.java b/chutney/action-impl/src/main/java/com/chutneytesting/action/sql/core/SqlClient.java index a512b8f7e..156e16826 100644 --- a/chutney/action-impl/src/main/java/com/chutneytesting/action/sql/core/SqlClient.java +++ b/chutney/action-impl/src/main/java/com/chutneytesting/action/sql/core/SqlClient.java @@ -32,13 +32,16 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.Optional; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class SqlClient { private final HikariDataSource dataSource; private final int maxFetchSize; + private static final Logger LOGGER = LoggerFactory.getLogger(SqlClient.class); + public SqlClient(HikariDataSource dataSource, int maxFetchSize) { this.dataSource = dataSource; @@ -141,10 +144,10 @@ private static Object boxed(ResultSet rs, int i) throws SQLException { return o; } if (o instanceof Blob) { - return new String(readBlob((Blob) o)); + return readBlob((Blob) o); } - return Optional.ofNullable(rs.getString(i)).orElse("null"); + return String.valueOf(rs.getString(i)); } private static boolean isJDBCNumericType(Class type) { @@ -167,17 +170,24 @@ private static boolean isJDBCDateType(Class type) { type.equals(Duration.class); // INTERVAL } - private static byte[] readBlob(Blob blob) throws SQLException { + private static String readBlob(Blob blob) { try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); InputStream inputStream = blob.getBinaryStream()) { byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); } - return outputStream.toByteArray(); - } catch (IOException e) { + return outputStream.toString(); + } catch (IOException | SQLException e) { throw new RuntimeException(e); } + finally { + try { + blob.free(); // (JDBC 4.0+) + } catch (SQLException e) { + LOGGER.warn("Failed to free Blob resources: {}", e.getMessage()); + } + } } } diff --git a/chutney/action-impl/src/test/java/com/chutneytesting/action/sql/SqlActionTest.java b/chutney/action-impl/src/test/java/com/chutneytesting/action/sql/SqlActionTest.java index a488c97b4..8b53d3cd1 100644 --- a/chutney/action-impl/src/test/java/com/chutneytesting/action/sql/SqlActionTest.java +++ b/chutney/action-impl/src/test/java/com/chutneytesting/action/sql/SqlActionTest.java @@ -53,7 +53,7 @@ public void setUp() { .setType(EmbeddedDatabaseType.H2) .setScriptEncoding("UTF-8") .ignoreFailedDrops(true) - .addScripts("db/sql/create_db.sql", "db/sql/insert_users.sql") + .addScripts("db/common/create_users.sql") .build(); } diff --git a/chutney/action-impl/src/test/java/com/chutneytesting/action/sql/core/SqlClientTest.java b/chutney/action-impl/src/test/java/com/chutneytesting/action/sql/core/SqlClientTest.java index cf26a3630..52f7ed41d 100644 --- a/chutney/action-impl/src/test/java/com/chutneytesting/action/sql/core/SqlClientTest.java +++ b/chutney/action-impl/src/test/java/com/chutneytesting/action/sql/core/SqlClientTest.java @@ -19,111 +19,158 @@ import java.sql.SQLException; import java.sql.Time; import java.sql.Timestamp; -import java.util.Collections; import java.util.List; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.mockito.MockedStatic; import org.mockito.Mockito; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; +import org.testcontainers.oracle.OracleContainer; +import org.testcontainers.utility.MountableFile; public class SqlClientTest { - private static final String DB_NAME = "test_" + SqlClientTest.class; - private final Target sqlTarget = TestTarget.TestTargetBuilder.builder() - .withTargetId("sql") - .withUrl("jdbc:h2:mem") - .withProperty("jdbcUrl", "jdbc:h2:mem:" + DB_NAME) - .withProperty("user", "sa") - .build(); - - @BeforeEach - public void setUp() { - new EmbeddedDatabaseBuilder() - .setName(DB_NAME) - .setType(EmbeddedDatabaseType.H2) - .setScriptEncoding("UTF-8") - .ignoreFailedDrops(true) - .addScripts("db/sql/create_db.sql", "db/sql/insert_users.sql", "db/sql/insert_allsqltypes.sql") - .build(); - } + @Nested + class H2SqlClientTest extends AllTests { + @BeforeAll + static void beforeAll() { + sqlTarget = TestTarget.TestTargetBuilder.builder() + .withTargetId("sql") + .withUrl("jdbc:h2:mem") + .withProperty("jdbcUrl", "jdbc:h2:mem:" + DB_NAME) + .withProperty("user", "sa") + .build(); + } - @Test - public void should_return_headers_and_rows_on_select_query() throws SQLException { - Column c0 = new Column("ID", 0); - Column c1 = new Column("NAME", 1); - Column c2 = new Column("EMAIL", 2); + @BeforeEach + public void setUp() { + new EmbeddedDatabaseBuilder() + .setName(DB_NAME) + .setType(EmbeddedDatabaseType.H2) + .setScriptEncoding("UTF-8") + .ignoreFailedDrops(true) + .addScripts("db/common/create_users.sql", "db/h2/create_types.sql") + .build(); + } - Row firstTuple = new Row(List.of(new Cell(c0, 1), new Cell(c1, "laitue"), new Cell(c2, "laitue@fake.com"))); - Row secondTuple = new Row(List.of(new Cell(c0, 2), new Cell(c1, "carotte"), new Cell(c2, "kakarot@fake.db"))); - Row thirdTuple = new Row(List.of(new Cell(c0, 3), new Cell(c1, "tomate"), new Cell(c2, "null"))); + } - SqlClient sqlClient = new DefaultSqlClientFactory().create(sqlTarget); - Records actual = sqlClient.execute("select * from users"); + @Nested + class OracleSqlClientTest extends AllTests { + private static OracleContainer oracle = new OracleContainer("gvenzl/oracle-free:23.4-slim-faststart") + .withDatabaseName("testDB") + .withUsername("testUser") + .withPassword("testPassword") + .withCopyFileToContainer(MountableFile.forClasspathResource("db/oracle/init.sh"), "/container-entrypoint-initdb.d/init.sh") + .withCopyFileToContainer(MountableFile.forClasspathResource("db/oracle/create_types.sql"), "/sql/create_types.sql") + .withCopyFileToContainer(MountableFile.forClasspathResource("db/common/create_users.sql"), "/sql/create_users.sql"); + + @BeforeAll + static void beforeAll() { + oracle.start(); + String address = oracle.getHost(); + Integer port = oracle.getFirstMappedPort(); + sqlTarget = TestTarget.TestTargetBuilder.builder() + .withTargetId("sql") + .withUrl("jdbc:oracle:thin:@" + address + ":" + port + "/testDB") + .withProperty("user", "testUser") + .withProperty("password", "testPassword") + .build(); + } - assertThat(actual.getHeaders()).containsOnly("ID", "NAME", "EMAIL"); - assertThat(actual.records).containsExactly(firstTuple, secondTuple, thirdTuple); + @AfterAll + static void afterAll() { + oracle.stop(); + } } - @Test - public void should_return_affected_rows_on_update_queries() throws SQLException { - SqlClient sqlClient = new DefaultSqlClientFactory().create(sqlTarget); - Records records = sqlClient.execute("UPDATE USERS SET NAME = 'toto' WHERE ID = 1"); + abstract static class AllTests { + protected static final String DB_NAME = "test_" + SqlClientTest.class; + protected static Target sqlTarget; - assertThat(records.affectedRows).isEqualTo(1); - } - @Test - public void should_return_count_on_count_queries() throws SQLException { - Column c0 = new Column("TOTAL", 0); - Row expectedTuple = new Row(Collections.singletonList(new Cell(c0, 3L))); + @Test + public void should_return_headers_and_rows_on_select_query() throws SQLException { - SqlClient sqlClient = new DefaultSqlClientFactory().create(sqlTarget); - Records actual = sqlClient.execute("SELECT COUNT(*) as total FROM USERS"); + SqlClient sqlClient = new DefaultSqlClientFactory().create(sqlTarget); + Records actual = sqlClient.execute("select * from users where ID = 1"); + + assertThat(actual.getHeaders()).containsOnly("ID", "NAME", "EMAIL"); + assertThat(actual.records).hasSize(1); + assertThat(actual.records.get(0)).isNotNull(); + List firstRowCells = actual.records.get(0).cells; + assertThat(firstRowCells).hasSize(3); + assertThat(firstRowCells.get(0).column.name).isEqualTo("ID"); + assertThat(((Number) firstRowCells.get(0).value).intValue()).isEqualTo(1); + assertThat(firstRowCells.get(1).column.name).isEqualTo("NAME"); + assertThat(firstRowCells.get(1).value).isEqualTo("laitue"); + assertThat(firstRowCells.get(2).column.name).isEqualTo("EMAIL"); + assertThat(firstRowCells.get(2).value).isEqualTo("laitue@fake.com"); + } - assertThat(actual.records).containsExactly(expectedTuple); - } + @Test + public void should_return_affected_rows_on_update_queries() throws SQLException { + SqlClient sqlClient = new DefaultSqlClientFactory().create(sqlTarget); + Records records = sqlClient.execute("UPDATE USERS SET NAME = 'toto' WHERE ID = 1"); - @Test - public void should_retrieve_columns_as_string_but_for_date_and_numeric_sql_datatypes() throws SQLException { - SqlClient sqlClient = new DefaultSqlClientFactory().create(sqlTarget); - Records actual = sqlClient.execute("select * from allsqltypes"); - - Row firstRow = actual.rows().get(0); - assertThat(firstRow.get("COL_BOOLEAN")).isInstanceOf(Boolean.class); - assertThat(firstRow.get("COL_TINYINT")).isInstanceOf(Integer.class); - assertThat(firstRow.get("COL_SMALLINT")).isInstanceOf(Integer.class); - assertThat(firstRow.get("COL_MEDIUMINT")).isInstanceOf(Integer.class); - assertThat(firstRow.get("COL_INTEGER")).isInstanceOf(Integer.class); - assertThat(firstRow.get("COL_BIGINT")).isInstanceOf(Long.class); - assertThat(firstRow.get("COL_FLOAT")).isInstanceOf(Float.class); - assertThat(firstRow.get("COL_DOUBLE")).isInstanceOf(Double.class); - assertThat(firstRow.get("COL_DECIMAL")).isInstanceOf(BigDecimal.class); - assertThat(firstRow.get("COL_DECIMAL")).isInstanceOf(BigDecimal.class); - assertThat(firstRow.get("COL_DATE")).isInstanceOf(Date.class); - assertThat(firstRow.get("COL_TIME")).isInstanceOf(Time.class); - assertThat(firstRow.get("COL_TIMESTAMP")).isInstanceOf(Timestamp.class); - assertThat(firstRow.get("COL_CHAR")).isInstanceOf(String.class); - assertThat(firstRow.get("COL_VARCHAR")).isInstanceOf(String.class); - // INTERVAL SQL types : cf. SqlClient.StatementConverter#isJDBCDateType(Class) - assertThat(firstRow.get("COL_INTERVAL_YEAR")).isInstanceOf(String.class); - assertThat(firstRow.get("COL_INTERVAL_SECOND")).isInstanceOf(String.class); - } + assertThat(records.affectedRows).isEqualTo(1); + } - @Test - public void should_prevent_out_of_memory() { - try (MockedStatic chutneyMemoryInfoMockedStatic = Mockito.mockStatic(ChutneyMemoryInfo.class)) { - chutneyMemoryInfoMockedStatic.when(ChutneyMemoryInfo::hasEnoughAvailableMemory).thenReturn(true, true, false); - chutneyMemoryInfoMockedStatic.when(ChutneyMemoryInfo::usedMemory).thenReturn(42L * 1024 * 1024); - chutneyMemoryInfoMockedStatic.when(ChutneyMemoryInfo::maxMemory).thenReturn(1337L * 1024 * 1024); + @Test + public void should_return_count_on_count_queries() throws SQLException { SqlClient sqlClient = new DefaultSqlClientFactory().create(sqlTarget); + Records actual = sqlClient.execute("SELECT COUNT(*) as total FROM USERS"); + + assertThat(actual.records).hasSize(1); + assertThat(actual.records.get(0)).isNotNull(); + assertThat(actual.records.get(0).cells).hasSize(1); + assertThat(actual.records.get(0).cells.get(0)).isNotNull(); + Number count = (Number) actual.records.get(0).cells.get(0).value; + assertThat(count.intValue()).isEqualTo(3); + assertThat(actual.records.get(0).cells.get(0).column.name).isEqualTo("TOTAL"); + } + + @Test + public void should_retrieve_columns_as_expected_datatypes() throws SQLException { + SqlClient sqlClient = new DefaultSqlClientFactory().create(sqlTarget); + Records actual = sqlClient.execute("select * from allsqltypes"); + + Row firstRow = actual.rows().get(0); + assertThat(firstRow.get("COL_BOOLEAN")).isInstanceOf(Boolean.class); + assertThat(firstRow.get("COL_INTEGER")).isInstanceOfAny(Integer.class, BigDecimal.class); + assertThat(firstRow.get("COL_FLOAT")).isInstanceOf(Float.class); + assertThat(firstRow.get("COL_DOUBLE")).isInstanceOf(Double.class); + assertThat(firstRow.get("COL_DECIMAL")).isInstanceOf(BigDecimal.class); + assertThat(firstRow.get("COL_DATE")).isInstanceOfAny(Date.class, Timestamp.class); + assertThat(firstRow.get("COL_TIME")).isInstanceOfAny(Time.class, String.class); + assertThat(firstRow.get("COL_TIMESTAMP")).isInstanceOfAny(Timestamp.class, String.class); + assertThat(firstRow.get("COL_CHAR")).isInstanceOf(String.class); + assertThat(firstRow.get("COL_VARCHAR")).isInstanceOf(String.class); + assertThat(firstRow.get("COL_INTERVAL_YEAR")).isInstanceOf(String.class); + assertThat(firstRow.get("COL_INTERVAL_SECOND")).isInstanceOf(String.class); + assertThat(firstRow.get("COL_BLOB")).isInstanceOf(String.class); + assertThat(firstRow.get("COL_BLOB")).isEqualTo("Chutney is a funny tool."); + } + + @Test + public void should_prevent_out_of_memory() { + try (MockedStatic chutneyMemoryInfoMockedStatic = Mockito.mockStatic(ChutneyMemoryInfo.class)) { + chutneyMemoryInfoMockedStatic.when(ChutneyMemoryInfo::hasEnoughAvailableMemory).thenReturn(true, true, false); + chutneyMemoryInfoMockedStatic.when(ChutneyMemoryInfo::usedMemory).thenReturn(42L * 1024 * 1024); + chutneyMemoryInfoMockedStatic.when(ChutneyMemoryInfo::maxMemory).thenReturn(1337L * 1024 * 1024); + + SqlClient sqlClient = new DefaultSqlClientFactory().create(sqlTarget); - Exception exception = assertThrows(NotEnoughMemoryException.class, () -> sqlClient.execute("select * from users")); - assertThat(exception.getMessage()).isEqualTo("Running step was stopped to prevent application crash. 42MB memory used of 1337MB max.\n" + - "Current step may not be the cause.\n" + - "Query fetched 2 rows"); + Exception exception = assertThrows(NotEnoughMemoryException.class, () -> sqlClient.execute("select * from users")); + assertThat(exception.getMessage()).isEqualTo("Running step was stopped to prevent application crash. 42MB memory used of 1337MB max.\n" + + "Current step may not be the cause.\n" + + "Query fetched 2 rows"); + } } } } diff --git a/chutney/action-impl/src/test/resources/db/sql/insert_users.sql b/chutney/action-impl/src/test/resources/db/common/create_users.sql similarity index 70% rename from chutney/action-impl/src/test/resources/db/sql/insert_users.sql rename to chutney/action-impl/src/test/resources/db/common/create_users.sql index 3d69a1300..3aa7b573a 100644 --- a/chutney/action-impl/src/test/resources/db/sql/insert_users.sql +++ b/chutney/action-impl/src/test/resources/db/common/create_users.sql @@ -4,6 +4,13 @@ * SPDX-License-Identifier: Apache-2.0 * */ +DROP TABLE users; + +CREATE TABLE users ( + id INTEGER PRIMARY KEY, + name VARCHAR(30), + email VARCHAR(50) +); INSERT INTO users VALUES (1, 'laitue', 'laitue@fake.com'); INSERT INTO users VALUES (2, 'carotte', 'kakarot@fake.db'); diff --git a/chutney/action-impl/src/test/resources/db/h2/create_types.sql b/chutney/action-impl/src/test/resources/db/h2/create_types.sql new file mode 100644 index 000000000..41eb48589 --- /dev/null +++ b/chutney/action-impl/src/test/resources/db/h2/create_types.sql @@ -0,0 +1,41 @@ +/* + * SPDX-FileCopyrightText: 2017-2024 Enedis + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +CREATE TABLE IF NOT EXISTS allsqltypes ( + col_boolean BIT, + col_smallint SMALLINT, + col_integer INTEGER, + col_float REAL, + col_double DOUBLE, + col_decimal DECIMAL(20,4), + col_date DATE, + col_time TIME, + col_timestamp TIMESTAMP, + col_interval_year INTERVAL YEAR, + col_interval_second INTERVAL SECOND, + col_char CHAR, + col_varchar VARCHAR, + col_blob BLOB +); + + +INSERT INTO allsqltypes VALUES ( + 1, + 66, + 66666666, + 666.666, + 66666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666.666, + 6666666666.6666, + '1966-06-06', + '06:16:16', + '1966-06-06 06:16:16', + INTERVAL '66' YEAR, + INTERVAL '6' SECOND, + 'H', + 'H HHH', + CAST(X'436875746e657920697320612066756e6e7920746f6f6c2e' AS BLOB) + ); diff --git a/chutney/action-impl/src/test/resources/db/oracle/create_types.sql b/chutney/action-impl/src/test/resources/db/oracle/create_types.sql new file mode 100644 index 000000000..cd8dd1a5f --- /dev/null +++ b/chutney/action-impl/src/test/resources/db/oracle/create_types.sql @@ -0,0 +1,40 @@ +/* + * SPDX-FileCopyrightText: 2017-2024 Enedis + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +CREATE TABLE allsqltypes ( + col_boolean BOOLEAN, + col_smallint SMALLINT, + col_integer INTEGER, + col_float BINARY_FLOAT, + col_double BINARY_DOUBLE, + col_decimal NUMBER(20, 4), + col_date DATE, + col_time TIMESTAMP, + col_timestamp TIMESTAMP, + col_interval_year INTERVAL YEAR TO MONTH, + col_interval_second INTERVAL DAY TO SECOND, + col_char CHAR(1), + col_varchar VARCHAR2(255), + col_blob BLOB +); + +INSERT INTO allsqltypes VALUES ( + 1, + 66666, + 66666666, + 666.666, + 66666666666666666666666666666666666666666666666666666666666666666666666666666666666.666, + 6666666666.6666, + to_date('1966-06-06', 'YYYY-MM-DD'), + to_timestamp('1966-06-06 06:16:16', 'YYYY-MM-DD HH24:MI:SS'), + to_date('1966-06-06 06:16:16', 'YYYY-MM-DD HH24:MI:SS'), + INTERVAL '66' YEAR, + INTERVAL '6' SECOND, + 'H', + 'H HHH', + '436875746e657920697320612066756e6e7920746f6f6c2e' +); diff --git a/chutney/action-impl/src/test/resources/db/oracle/init.sh b/chutney/action-impl/src/test/resources/db/oracle/init.sh new file mode 100644 index 000000000..5aa500ffe --- /dev/null +++ b/chutney/action-impl/src/test/resources/db/oracle/init.sh @@ -0,0 +1,9 @@ +# +# SPDX-FileCopyrightText: 2017-2024 Enedis +# +# SPDX-License-Identifier: Apache-2.0 +# +# + +sqlplus -s testUser/testPassword@//localhost/testDB @/sql/create_users.sql +sqlplus -s testUser/testPassword@//localhost/testDB @/sql/create_types.sql diff --git a/chutney/action-impl/src/test/resources/db/sql/create_db.sql b/chutney/action-impl/src/test/resources/db/sql/create_db.sql deleted file mode 100644 index ca3e9ef6d..000000000 --- a/chutney/action-impl/src/test/resources/db/sql/create_db.sql +++ /dev/null @@ -1,33 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2017-2024 Enedis - * - * SPDX-License-Identifier: Apache-2.0 - * - */ - -DROP TABLE users; - -CREATE TABLE IF NOT EXISTS users ( - id INTEGER PRIMARY KEY, - name VARCHAR(30), - email VARCHAR(50) -); - -CREATE TABLE IF NOT EXISTS allsqltypes ( - col_boolean BIT, - col_tinyint TINYINT, - col_smallint SMALLINT, - col_mediumint MEDIUMINT, - col_integer INTEGER, - col_bigint BIGINT, - col_float REAL, - col_double DOUBLE, - col_decimal DECIMAL(20,4), - col_date DATE, - col_time TIME, - col_timestamp TIMESTAMP, - col_interval_year INTERVAL YEAR, - col_interval_second INTERVAL SECOND, - col_char CHAR, - col_varchar VARCHAR -); diff --git a/chutney/action-impl/src/test/resources/db/sql/insert_allsqltypes.sql b/chutney/action-impl/src/test/resources/db/sql/insert_allsqltypes.sql deleted file mode 100644 index 95929c287..000000000 --- a/chutney/action-impl/src/test/resources/db/sql/insert_allsqltypes.sql +++ /dev/null @@ -1,25 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2017-2024 Enedis - * - * SPDX-License-Identifier: Apache-2.0 - * - */ - -INSERT INTO allsqltypes VALUES ( - 1, - 66, - 666, - 66666, - 66666666, - 6666666666, - 666.666, - 66666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666.666, - 6666666666.6666, - '1966-06-06', - '06:16:16', - '1966-06-06 06:16:16', - INTERVAL '66' YEAR, - INTERVAL '6' SECOND, - 'H', - 'H HHH' -);